Merge 10.2 into 10.3
This commit is contained in:
commit
a3539bbb2a
@ -949,6 +949,8 @@ pthread_handler_t connection_thread(void *arg)
|
||||
|
||||
end_thread:
|
||||
cn->query_done= 1;
|
||||
mysql_close(cn->mysql);
|
||||
cn->mysql= 0;
|
||||
mysql_thread_end();
|
||||
pthread_exit(0);
|
||||
return 0;
|
||||
|
@ -2175,6 +2175,66 @@ t1 CREATE TABLE `t1` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-15308
|
||||
# Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed
|
||||
# in ha_innodb::prepare_inplace_alter_table
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP INDEX `fk`; check that it exists
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP FOREIGN KEY `fk`; check that it exists
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP INDEX `fk`; check that it exists
|
||||
Note 1091 Can't DROP COLUMN `c`; check that it exists
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.0 tests
|
||||
#
|
||||
#
|
||||
|
@ -1803,6 +1803,37 @@ ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-15308
|
||||
--echo # Assertion `ha_alter_info->alter_info->drop_list.elements > 0' failed
|
||||
--echo # in ha_innodb::prepare_inplace_alter_table
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN b;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN b;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, KEY(c)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP COLUMN c;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT, c INT, KEY c1(c)) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP FOREIGN KEY IF EXISTS fk, DROP INDEX c1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB;
|
||||
ALTER TABLE t1 DROP INDEX IF EXISTS fk, DROP COLUMN IF EXISTS c;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.0 tests
|
||||
--echo #
|
||||
|
@ -809,10 +809,9 @@ LOAD INDEX INTO CACHE t3;
|
||||
Table Op Msg_type Msg_text
|
||||
mysqltest_db1.t3 preload_keys status OK
|
||||
#
|
||||
# RENAME (doesn't work for temporary tables, thus should fail).
|
||||
# RENAME should work for temporary tables
|
||||
#
|
||||
RENAME TABLE t3 TO t3_1;
|
||||
ERROR 42000: INSERT, CREATE command denied to user 'mysqltest_u1'@'localhost' for table 't3_1'
|
||||
#
|
||||
# HANDLER OPEN/READ/CLOSE.
|
||||
#
|
||||
|
@ -873,9 +873,8 @@ CACHE INDEX t3 IN keycache1;
|
||||
LOAD INDEX INTO CACHE t3;
|
||||
|
||||
--echo #
|
||||
--echo # RENAME (doesn't work for temporary tables, thus should fail).
|
||||
--echo # RENAME should work for temporary tables
|
||||
--echo #
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
RENAME TABLE t3 TO t3_1;
|
||||
|
||||
--echo #
|
||||
|
@ -78,3 +78,69 @@ ERROR HY000: 'test.v1' is not of type 'BASE TABLE'
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
End of 5.0 tests
|
||||
CREATE OR REPLACE TABLE t1 (a INT);
|
||||
CREATE OR REPLACE TABLE t2 (a INT);
|
||||
CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT);
|
||||
CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT);
|
||||
rename table t1 to t2;
|
||||
ERROR 42S01: Table 't2' already exists
|
||||
rename table t1 to tmp, tmp to t2;
|
||||
ERROR 42S01: Table 't2' already exists
|
||||
rename table t1_tmp to t2_tmp;
|
||||
ERROR 42S01: Table 't2_tmp' already exists
|
||||
rename table t1_tmp to tmp, tmp to t2_tmp;
|
||||
ERROR 42S01: Table 't2_tmp' already exists
|
||||
show create table t1_tmp;
|
||||
Table Create Table
|
||||
t1_tmp CREATE TEMPORARY TABLE `t1_tmp` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
show create table t2_tmp;
|
||||
Table Create Table
|
||||
t2_tmp CREATE TEMPORARY TABLE `t2_tmp` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
rename table t1 to t1_tmp;
|
||||
rename table t2_tmp to t2;
|
||||
rename table t2 to tmp, tmp to t2;
|
||||
rename table t1_tmp to tmp, tmp to t1_tmp;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1_tmp
|
||||
t2
|
||||
SHOW CREATE TABLE t1_tmp;
|
||||
Table Create Table
|
||||
t1_tmp CREATE TEMPORARY TABLE `t1_tmp` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1_tmp;
|
||||
SHOW CREATE TABLE t1_tmp;
|
||||
Table Create Table
|
||||
t1_tmp CREATE TABLE `t1_tmp` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1_tmp;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TEMPORARY TABLE `t2` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t2;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t2;
|
||||
CREATE TABLE t1 (a INT);
|
||||
insert into t1 values (1);
|
||||
CREATE TEMPORARY TABLE t1 (b INT);
|
||||
insert into t1 values (2);
|
||||
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||
select * from tmp;
|
||||
b
|
||||
2
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
drop table tmp,t2;
|
||||
|
@ -95,3 +95,49 @@ drop table t1;
|
||||
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
#
|
||||
# Test of rename with temporary tables
|
||||
#
|
||||
|
||||
CREATE OR REPLACE TABLE t1 (a INT);
|
||||
CREATE OR REPLACE TABLE t2 (a INT);
|
||||
CREATE OR REPLACE TEMPORARY TABLE t1_tmp (b INT);
|
||||
CREATE OR REPLACE TEMPORARY TABLE t2_tmp (b INT);
|
||||
|
||||
# Can't rename table over another one
|
||||
--error ER_TABLE_EXISTS_ERROR
|
||||
rename table t1 to t2;
|
||||
--error ER_TABLE_EXISTS_ERROR
|
||||
rename table t1 to tmp, tmp to t2;
|
||||
--error ER_TABLE_EXISTS_ERROR
|
||||
rename table t1_tmp to t2_tmp;
|
||||
--error ER_TABLE_EXISTS_ERROR
|
||||
rename table t1_tmp to tmp, tmp to t2_tmp;
|
||||
|
||||
show create table t1_tmp;
|
||||
show create table t2_tmp;
|
||||
|
||||
# The following should work
|
||||
rename table t1 to t1_tmp;
|
||||
rename table t2_tmp to t2;
|
||||
rename table t2 to tmp, tmp to t2;
|
||||
rename table t1_tmp to tmp, tmp to t1_tmp;
|
||||
show tables;
|
||||
SHOW CREATE TABLE t1_tmp;
|
||||
drop table t1_tmp;
|
||||
SHOW CREATE TABLE t1_tmp;
|
||||
drop table t1_tmp;
|
||||
SHOW CREATE TABLE t2;
|
||||
drop table t2;
|
||||
SHOW CREATE TABLE t2;
|
||||
drop table t2;
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
insert into t1 values (1);
|
||||
CREATE TEMPORARY TABLE t1 (b INT);
|
||||
insert into t1 values (2);
|
||||
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||
select * from tmp;
|
||||
select * from t2;
|
||||
drop table tmp,t2;
|
||||
|
||||
|
11
mysql-test/main/statistics_close.result
Normal file
11
mysql-test/main/statistics_close.result
Normal file
@ -0,0 +1,11 @@
|
||||
CREATE TABLE t1 (i int);
|
||||
connect con1,localhost,root,,test;
|
||||
RENAME TABLE t1 TO t2;
|
||||
connection default;
|
||||
FLUSH TABLES;
|
||||
connection con1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 'test.t1'
|
18
mysql-test/main/statistics_close.test
Normal file
18
mysql-test/main/statistics_close.test
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# MDEV-16123 ASAN heap-use-after-free handler::ha_index_or_rnd_end
|
||||
# MDEV-13828 Segmentation fault on RENAME TABLE
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (i int);
|
||||
--connect (con1,localhost,root,,test)
|
||||
--send
|
||||
RENAME TABLE t1 TO t2;
|
||||
--connection default
|
||||
FLUSH TABLES;
|
||||
--connection con1
|
||||
--reap
|
||||
|
||||
# Cleanup
|
||||
--disconnect con1
|
||||
--connection default
|
||||
DROP TABLE IF EXISTS t1, t2;
|
@ -2345,7 +2345,18 @@ CREATE TABLE t1 (i INT);
|
||||
insert into t2 value (2);
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2,t3;
|
||||
End of 10.1 tests.
|
||||
#
|
||||
# MDEV-16093
|
||||
# Assertion `global_status_var.global_memory_used == 0' failed or
|
||||
# bytes lost after inserting into table with non-null blob and trigger
|
||||
#
|
||||
CREATE TABLE t1 (b BLOB NOT NULL);
|
||||
CREATE TRIGGER tr BEFORE UPDATE ON t1 FOR EACH ROW BEGIN END;
|
||||
INSERT INTO t1 VALUES ('foo');
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.1 tests.
|
||||
#
|
||||
create table t1 (i int);
|
||||
create trigger tr1 after insert on t1 for each row set @a=@a+1;
|
||||
create trigger tr2 after insert on t1 for each row set @a=@a+1;
|
||||
|
@ -2665,8 +2665,20 @@ insert into t2 value (2);
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-16093
|
||||
--echo # Assertion `global_status_var.global_memory_used == 0' failed or
|
||||
--echo # bytes lost after inserting into table with non-null blob and trigger
|
||||
--echo #
|
||||
|
||||
--echo End of 10.1 tests.
|
||||
CREATE TABLE t1 (b BLOB NOT NULL);
|
||||
CREATE TRIGGER tr BEFORE UPDATE ON t1 FOR EACH ROW BEGIN END;
|
||||
INSERT INTO t1 VALUES ('foo');
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.1 tests.
|
||||
--echo #
|
||||
|
||||
#
|
||||
# MDEV-10915 Count number of executed triggers
|
||||
|
@ -18,6 +18,7 @@
|
||||
# - with annotated events, default checksums and minimal binlog row image
|
||||
#
|
||||
|
||||
--source include/have_partition.inc
|
||||
--source encryption_algorithms.inc
|
||||
--source include/have_innodb.inc
|
||||
--enable_connect_log
|
||||
|
@ -9,6 +9,7 @@
|
||||
# relay logs and binary logs are encrypted on slave.
|
||||
#
|
||||
|
||||
--source include/have_partition.inc
|
||||
--source encryption_algorithms.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
--partition
|
37
mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
Normal file
37
mysql-test/suite/galera/r/galera_encrypt_tmp_files.result
Normal file
@ -0,0 +1,37 @@
|
||||
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||
VARIABLE_VALUE = 'Synced'
|
||||
1
|
||||
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
VARIABLE_VALUE = 2
|
||||
1
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
connection node_2;
|
||||
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||
VARIABLE_VALUE = 'Synced'
|
||||
1
|
||||
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
VARIABLE_VALUE = 2
|
||||
1
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
COUNT(*) = 1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
connection node_1;
|
||||
CREATE TABLE `t1` (
|
||||
`col1` int(11) NOT NULL,
|
||||
`col2` varchar(64) NOT NULL DEFAULT '',
|
||||
`col3` varchar(32) NOT NULL DEFAULT '0',
|
||||
`col4` varchar(64) NOT NULL DEFAULT '',
|
||||
`col5` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col6` int(11) NOT NULL DEFAULT '0',
|
||||
`col7` varchar(64) NOT NULL DEFAULT '',
|
||||
`col8` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col9` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col10` text NOT NULL,
|
||||
`col11` varchar(255) NOT NULL DEFAULT '',
|
||||
`col12` tinyint(4) NOT NULL DEFAULT '1'
|
||||
) ;
|
||||
create table t2 (test int);
|
||||
insert into t2 values (1);
|
||||
drop table t1,t2;
|
8
mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
Normal file
8
mysql-test/suite/galera/t/galera_encrypt_tmp_files.cnf
Normal file
@ -0,0 +1,8 @@
|
||||
!include ../galera_2nodes.cnf
|
||||
[mysqld]
|
||||
|
||||
encrypt-tmp-files = 1
|
||||
plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO
|
||||
file-key-management
|
||||
loose-file-key-management-filename= @ENV.MYSQL_TEST_DIR/std_data/keys.txt
|
||||
log-bin
|
57
mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
Normal file
57
mysql-test/suite/galera/t/galera_encrypt_tmp_files.test
Normal file
@ -0,0 +1,57 @@
|
||||
# This file tests that mariadb cluster should not crash when encrypt_tmp_file
|
||||
# is enabled
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
--connection node_2
|
||||
SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
|
||||
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--connection node_1
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`col1` int(11) NOT NULL,
|
||||
`col2` varchar(64) NOT NULL DEFAULT '',
|
||||
`col3` varchar(32) NOT NULL DEFAULT '0',
|
||||
`col4` varchar(64) NOT NULL DEFAULT '',
|
||||
`col5` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col6` int(11) NOT NULL DEFAULT '0',
|
||||
`col7` varchar(64) NOT NULL DEFAULT '',
|
||||
`col8` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col9` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`col10` text NOT NULL,
|
||||
`col11` varchar(255) NOT NULL DEFAULT '',
|
||||
`col12` tinyint(4) NOT NULL DEFAULT '1'
|
||||
) ;
|
||||
|
||||
#Although we just need $counter >= 907 for IO_CACHE to use
|
||||
#encrypted temp file. Just on safe side I am using $counter
|
||||
# = 1100
|
||||
--disable_query_log
|
||||
--let $counter=1100
|
||||
--let $query= (1,'test','test','test',0,0,'-1',0,0,'','',-1)
|
||||
while($counter)
|
||||
{
|
||||
--let $query= $query ,(1,'test','test','test',0,0,'-1',0,0,'','',-1)
|
||||
--dec $counter
|
||||
}
|
||||
--let $query= INSERT INTO t1 values $query ;
|
||||
--eval $query
|
||||
--enable_query_log
|
||||
#INSERT INTO `t1` VALUE
|
||||
|
||||
create table t2 (test int);
|
||||
insert into t2 values (1);
|
||||
|
||||
drop table t1,t2;
|
@ -4,6 +4,7 @@
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_perfschema.inc
|
||||
|
||||
# Save original auto_increment_offset values.
|
||||
--let $node_1=node_1
|
||||
|
@ -100,6 +100,17 @@ f2
|
||||
unlock tables;
|
||||
DROP TABLE t1,t2,tmp;
|
||||
#
|
||||
# MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt
|
||||
#
|
||||
CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria;
|
||||
INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2);
|
||||
LOCK TABLE t1 WRITE;
|
||||
ALTER TABLE t1 ADD UNIQUE KEY (f1);
|
||||
ERROR 23000: Duplicate entry 'foo' for key 'f1'
|
||||
ALTER TABLE t1 ADD KEY (f2);
|
||||
DROP TABLE t1;
|
||||
# End of 10.2 tests
|
||||
#
|
||||
# MDEV-14669 Assertion `file->trn == trn' failed in ha_maria::start_stmt
|
||||
#
|
||||
CREATE TABLE t1 (i INT) ENGINE=Aria;
|
||||
|
@ -106,6 +106,20 @@ select * from t2;
|
||||
unlock tables;
|
||||
DROP TABLE t1,t2,tmp;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10378 Assertion `trn' failed in virtual int ha_maria::start_stmt
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (f1 VARCHAR(3), f2 INT, pk INT, PRIMARY KEY (pk)) ENGINE=Aria;
|
||||
INSERT INTO t1 VALUES ('foo',10,1), ('foo',1,2);
|
||||
LOCK TABLE t1 WRITE;
|
||||
--error ER_DUP_ENTRY
|
||||
ALTER TABLE t1 ADD UNIQUE KEY (f1);
|
||||
ALTER TABLE t1 ADD KEY (f2);
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 10.2 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-14669 Assertion `file->trn == trn' failed in ha_maria::start_stmt
|
||||
--echo #
|
||||
|
1
mysql-test/suite/mariabackup/lock_ddl_per_table.opt
Normal file
1
mysql-test/suite/mariabackup/lock_ddl_per_table.opt
Normal file
@ -0,0 +1 @@
|
||||
--loose-partition
|
@ -1,4 +1,5 @@
|
||||
--source include/have_debug.inc
|
||||
--source include/have_partition.inc
|
||||
|
||||
CREATE TABLE t(i INT) ENGINE INNODB;
|
||||
INSERT INTO t VALUES(1);
|
||||
|
@ -1 +0,0 @@
|
||||
--partition
|
@ -1,3 +1,4 @@
|
||||
--source include/have_partition.inc
|
||||
let $targetdir=$MYSQLTEST_VARDIR/backup;
|
||||
mkdir $targetdir;
|
||||
mkdir $MYSQLTEST_VARDIR/partitdata;
|
||||
|
@ -1 +1 @@
|
||||
--innodb --loose-changed_page_bitmaps --innodb-sys-tables --partition
|
||||
--innodb --loose-changed_page_bitmaps --innodb-sys-tables
|
||||
|
10
mysql-test/suite/perfschema/r/partition.result
Normal file
10
mysql-test/suite/perfschema/r/partition.result
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# MDEV-10679
|
||||
# Server crashes in in mysql_create_frm_image upon query from
|
||||
# performance schema in ps-protocol mode
|
||||
#
|
||||
CREATE TABLE t1 (i INT);
|
||||
ALTER TABLE t1 ADD PARTITION (PARTITION p VALUES LESS THAN (1));
|
||||
ERROR HY000: Partition management on a not partitioned table is not possible
|
||||
SELECT * FROM performance_schema.events_stages_summary_by_user_by_event_name;
|
||||
DROP TABLE t1;
|
16
mysql-test/suite/perfschema/t/partition.test
Normal file
16
mysql-test/suite/perfschema/t/partition.test
Normal file
@ -0,0 +1,16 @@
|
||||
--source include/have_perfschema.inc
|
||||
--source include/have_partition.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10679
|
||||
--echo # Server crashes in in mysql_create_frm_image upon query from
|
||||
--echo # performance schema in ps-protocol mode
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
--error ER_PARTITION_MGMT_ON_NONPARTITIONED
|
||||
ALTER TABLE t1 ADD PARTITION (PARTITION p VALUES LESS THAN (1));
|
||||
--disable_result_log
|
||||
SELECT * FROM performance_schema.events_stages_summary_by_user_by_event_name;
|
||||
--enable_result_log
|
||||
DROP TABLE t1;
|
36
mysql-test/suite/rpl/r/rename.result
Normal file
36
mysql-test/suite/rpl/r/rename.result
Normal file
@ -0,0 +1,36 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after
|
||||
# half-failed RENAME
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TEMPORARY TABLE t1 (b INT);
|
||||
RENAME TABLE t1 TO tmp, tmp TO t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TEMPORARY TABLE `t1` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
CREATE VIEW v AS SELECT * FROM t1;
|
||||
ERROR HY000: View's SELECT refers to a temporary table 't1'
|
||||
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||
SHOW CREATE TABLE tmp;
|
||||
Table Create Table
|
||||
tmp CREATE TEMPORARY TABLE `tmp` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
CREATE VIEW v AS SELECT * FROM tmp;
|
||||
ERROR HY000: View's SELECT refers to a temporary table 'tmp'
|
||||
CREATE VIEW v AS SELECT * FROM t2;
|
||||
connection slave;
|
||||
connection master;
|
||||
DROP VIEW v;
|
||||
DROP TABLE tmp;
|
||||
DROP TABLE t2;
|
||||
include/rpl_end.inc
|
33
mysql-test/suite/rpl/t/rename.test
Normal file
33
mysql-test/suite/rpl/t/rename.test
Normal file
@ -0,0 +1,33 @@
|
||||
--source include/have_binlog_format_mixed.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after
|
||||
--echo # half-failed RENAME
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TEMPORARY TABLE t1 (b INT);
|
||||
RENAME TABLE t1 TO tmp, tmp TO t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_VIEW_SELECT_TMPTABLE
|
||||
CREATE VIEW v AS SELECT * FROM t1;
|
||||
|
||||
RENAME TABLE t1 TO tmp, t1 TO t2;
|
||||
SHOW CREATE TABLE tmp;
|
||||
SHOW CREATE TABLE t2;
|
||||
--error ER_VIEW_SELECT_TMPTABLE
|
||||
CREATE VIEW v AS SELECT * FROM tmp;
|
||||
CREATE VIEW v AS SELECT * FROM t2;
|
||||
|
||||
--sync_slave_with_master
|
||||
|
||||
# Cleanup
|
||||
|
||||
--connection master
|
||||
|
||||
DROP VIEW v;
|
||||
DROP TABLE tmp;
|
||||
DROP TABLE t2;
|
||||
|
||||
--source include/rpl_end.inc
|
70
mysql-test/suite/vcol/r/binlog.result
Normal file
70
mysql-test/suite/vcol/r/binlog.result
Normal file
@ -0,0 +1,70 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
CREATE TABLE t1 (
|
||||
pk SERIAL,
|
||||
vcol_date DATE AS (col_date) PERSISTENT,
|
||||
vcol_int INT AS (col_int) VIRTUAL,
|
||||
vcol_year YEAR AS (col_year) PERSISTENT,
|
||||
vcol_blob BLOB AS (col_blob) VIRTUAL,
|
||||
col_date DATE,
|
||||
col_int INT NULL,
|
||||
col_blob BLOB NULL,
|
||||
col_year YEAR,
|
||||
PRIMARY KEY(pk)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO t1 (col_date,col_int,col_blob,col_year) VALUES ('2010-04-24',5,'foo',1981);
|
||||
SET SQL_MODE='';
|
||||
set binlog_row_image="FULL";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1982 FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'vcol_date' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_int' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_year' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' ignored
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1982
|
||||
connection slave;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1982
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set binlog_row_image="MINIMAL";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1983 FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'vcol_date' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_int' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_year' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' ignored
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1983
|
||||
connection slave;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1983
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set @@binlog_row_image="NOBLOB";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1984 FROM t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'vcol_date' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_int' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_year' in table 't1' ignored
|
||||
Warning 1906 The value specified for generated column 'vcol_blob' in table 't1' ignored
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1984
|
||||
connection slave;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
col_date col_int col_blob col_year
|
||||
2010-04-24 5 foo 1984
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set @@binlog_row_image=default;
|
||||
DROP TABLE t1;
|
||||
include/rpl_end.inc
|
361
mysql-test/suite/vcol/r/update_binlog.result
Normal file
361
mysql-test/suite/vcol/r/update_binlog.result
Normal file
@ -0,0 +1,361 @@
|
||||
set binlog_row_image="FULL";
|
||||
set @@default_storage_engine="myisam";
|
||||
create table t1 (a int, b int as (a+1), c int as (b+1) stored);
|
||||
insert t1 set a=1;
|
||||
select * from t1;
|
||||
a b c
|
||||
1 2 3
|
||||
update t1 set a=2;
|
||||
select * from t1;
|
||||
a b c
|
||||
2 3 4
|
||||
drop table t1;
|
||||
create table t1 (a int, c int as(a), p varchar(20) as(y), y char(20), index (p,c));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
|
||||
`p` varchar(20) GENERATED ALWAYS AS (`y`) VIRTUAL,
|
||||
`y` char(20) DEFAULT NULL,
|
||||
KEY `p` (`p`,`c`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
insert into t1 (a,y) values(1, "yyy");
|
||||
update t1 set a = 100 where a = 1;
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
d varchar(5000) generated always as (b) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
i varchar(5000) generated always as (b) virtual,
|
||||
d varchar(5000) generated always as (i) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
|
||||
insert t1 (a,b) values ('a', 1);
|
||||
replace t1 set a = 'a',b =1;
|
||||
insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
|
||||
select * from t1;
|
||||
a b c
|
||||
b 2 b
|
||||
drop table t1;
|
||||
create table t (a int primary key, b int, c int as (b), index (c));
|
||||
insert t (a,b) values (9,0);
|
||||
create table t2 select * from t;
|
||||
update t, t2 set t.b=10 where t.a=t2.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c
|
||||
9 10 10
|
||||
drop table t, t2;
|
||||
create table t1 (a int, b int, c int, d int, e int);
|
||||
insert t1 values (1,2,3,4,5), (1,2,3,4,5);
|
||||
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
||||
create table t (a int primary key,
|
||||
b int, c blob as (b), index (c(57)),
|
||||
d blob, e blob as (d), index (e(57)))
|
||||
replace select * from t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'c' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'e' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'c' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'e' in table 't' ignored
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
1 2 2 4 4
|
||||
update t set a=10, b=1, d=1;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 1 1 1 1
|
||||
replace t (a,b,d) values (10,2,2);
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 2 2 2 2
|
||||
insert t(a,b,d) values (10) on duplicate key update b=3;
|
||||
ERROR 21S01: Column count doesn't match value count at row 1
|
||||
insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 3 3 3 3
|
||||
replace t (a,b,d) select 10,4,4;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 4 4 4 4
|
||||
insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 5 5 5 5
|
||||
replace delayed t (a,b,d) values (10,6,6);
|
||||
flush tables;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 6 6 6 6
|
||||
insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
|
||||
flush tables;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 7 7 7 7
|
||||
load data infile 'MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 8 8 8 8
|
||||
update t set a=11, b=9, d=9 where a>5;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 9 9 9 9
|
||||
create table t2 select * from t;
|
||||
update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 10 10 10 10
|
||||
update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 11 11 11 11
|
||||
drop table t, t1, t2;
|
||||
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
|
||||
insert into t (f1,f2) values (1,1),(2,2);
|
||||
create view v as
|
||||
select a2.f1, a2.f2, a1.f3
|
||||
from t a1, t a2
|
||||
where a2.f3 <> 0
|
||||
with local check option;
|
||||
update v set f3 = 52;
|
||||
drop view v;
|
||||
drop table t;
|
||||
set binlog_row_image="MINIMAL";
|
||||
create table t1 (a int, b int as (a+1), c int as (b+1) stored);
|
||||
insert t1 set a=1;
|
||||
select * from t1;
|
||||
a b c
|
||||
1 2 3
|
||||
update t1 set a=2;
|
||||
select * from t1;
|
||||
a b c
|
||||
2 3 4
|
||||
drop table t1;
|
||||
create table t1 (a int, c int as(a), p varchar(20) as(y), y char(20), index (p,c));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`c` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL,
|
||||
`p` varchar(20) GENERATED ALWAYS AS (`y`) VIRTUAL,
|
||||
`y` char(20) DEFAULT NULL,
|
||||
KEY `p` (`p`,`c`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
insert into t1 (a,y) values(1, "yyy");
|
||||
update t1 set a = 100 where a = 1;
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
d varchar(5000) generated always as (b) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
a varchar(10000),
|
||||
b varchar(3000),
|
||||
c varchar(14000) generated always as (concat(a,b)) virtual,
|
||||
i varchar(5000) generated always as (b) virtual,
|
||||
d varchar(5000) generated always as (i) virtual,
|
||||
e int(11) generated always as (10) virtual,
|
||||
h int(11) not null primary key,
|
||||
index(c(100), d(20)));
|
||||
insert t1 (a,b,h) values (repeat('g', 10000), repeat('x', 2800), 1);
|
||||
update t1 set a = repeat(cast(1 as char), 2000);
|
||||
drop table t1;
|
||||
create table t1(a blob not null, b int, c varbinary (10) generated always as (a) virtual, unique (c(9)));
|
||||
insert t1 (a,b) values ('a', 1);
|
||||
replace t1 set a = 'a',b =1;
|
||||
insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
|
||||
select * from t1;
|
||||
a b c
|
||||
b 2 b
|
||||
drop table t1;
|
||||
create table t (a int primary key, b int, c int as (b), index (c));
|
||||
insert t (a,b) values (9,0);
|
||||
create table t2 select * from t;
|
||||
update t, t2 set t.b=10 where t.a=t2.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c
|
||||
9 10 10
|
||||
drop table t, t2;
|
||||
create table t1 (a int, b int, c int, d int, e int);
|
||||
insert t1 values (1,2,3,4,5), (1,2,3,4,5);
|
||||
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
||||
create table t (a int primary key,
|
||||
b int, c blob as (b), index (c(57)),
|
||||
d blob, e blob as (d), index (e(57)))
|
||||
replace select * from t1;
|
||||
Warnings:
|
||||
Warning 1906 The value specified for generated column 'c' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'e' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'c' in table 't' ignored
|
||||
Warning 1906 The value specified for generated column 'e' in table 't' ignored
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
1 2 2 4 4
|
||||
update t set a=10, b=1, d=1;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 1 1 1 1
|
||||
replace t (a,b,d) values (10,2,2);
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 2 2 2 2
|
||||
insert t(a,b,d) values (10) on duplicate key update b=3;
|
||||
ERROR 21S01: Column count doesn't match value count at row 1
|
||||
insert t(a,b,d) values (10,2,2) on duplicate key update b=3, d=3;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 3 3 3 3
|
||||
replace t (a,b,d) select 10,4,4;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 4 4 4 4
|
||||
insert t(a,b,d) select 10,4,4 on duplicate key update b=5, d=5;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 5 5 5 5
|
||||
replace delayed t (a,b,d) values (10,6,6);
|
||||
flush tables;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 6 6 6 6
|
||||
insert delayed t(a,b,d) values (10,6,6) on duplicate key update b=7, d=7;
|
||||
flush tables;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 7 7 7 7
|
||||
load data infile 'MYSQLTEST_VARDIR/tmp/vblobs.txt' replace into table t;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
10 8 8 8 8
|
||||
update t set a=11, b=9, d=9 where a>5;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 9 9 9 9
|
||||
create table t2 select * from t;
|
||||
update t, t2 set t.b=10, t.d=10 where t.a=t2.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 10 10 10 10
|
||||
update t, t tt set t.b=11, tt.d=11 where t.a=tt.a;
|
||||
check table t;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t check status OK
|
||||
select * from t;
|
||||
a b c d e
|
||||
11 11 11 11 11
|
||||
drop table t, t1, t2;
|
||||
create table t (f1 int, f2 int, f3 int as (f1*2) virtual, key(f3,f2));
|
||||
insert into t (f1,f2) values (1,1),(2,2);
|
||||
create view v as
|
||||
select a2.f1, a2.f2, a1.f3
|
||||
from t a1, t a2
|
||||
where a2.f3 <> 0
|
||||
with local check option;
|
||||
update v set f3 = 52;
|
||||
drop view v;
|
||||
drop table t;
|
55
mysql-test/suite/vcol/t/binlog.test
Normal file
55
mysql-test/suite/vcol/t/binlog.test
Normal file
@ -0,0 +1,55 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
#
|
||||
# MDEV-15243
|
||||
# Server crashes in in Field_blob::pack upon REPLACE into view with virtual
|
||||
# columns with binlog enabled
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
pk SERIAL,
|
||||
vcol_date DATE AS (col_date) PERSISTENT,
|
||||
vcol_int INT AS (col_int) VIRTUAL,
|
||||
vcol_year YEAR AS (col_year) PERSISTENT,
|
||||
vcol_blob BLOB AS (col_blob) VIRTUAL,
|
||||
col_date DATE,
|
||||
col_int INT NULL,
|
||||
col_blob BLOB NULL,
|
||||
col_year YEAR,
|
||||
PRIMARY KEY(pk)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO t1 (col_date,col_int,col_blob,col_year) VALUES ('2010-04-24',5,'foo',1981);
|
||||
SET SQL_MODE='';
|
||||
|
||||
set binlog_row_image="FULL";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1982 FROM t1;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
sync_slave_with_master;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set binlog_row_image="MINIMAL";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1983 FROM t1;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
sync_slave_with_master;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set @@binlog_row_image="NOBLOB";
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
REPLACE INTO v1 SELECT pk, vcol_date, vcol_int, vcol_year, vcol_blob, col_date, col_int, col_blob, 1984 FROM t1;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
sync_slave_with_master;
|
||||
select col_date,col_int,col_blob,col_year from v1;
|
||||
connection master;
|
||||
DROP VIEW v1;
|
||||
set @@binlog_row_image=default;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--source include/rpl_end.inc
|
14
mysql-test/suite/vcol/t/update_binlog.test
Normal file
14
mysql-test/suite/vcol/t/update_binlog.test
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# Check that vcol update works with binlog enabled
|
||||
#
|
||||
|
||||
--source include/have_binlog_format_row.inc
|
||||
|
||||
set binlog_row_image="FULL";
|
||||
set @@default_storage_engine="myisam";
|
||||
|
||||
--source update.test
|
||||
|
||||
set binlog_row_image="MINIMAL";
|
||||
|
||||
--source update.test
|
@ -3662,7 +3662,7 @@ public:
|
||||
DBUG_ASSERT(number < UINT_MAX32);
|
||||
store_length(ptr, packlength, (uint32)number);
|
||||
}
|
||||
inline uint32 get_length(uint row_offset= 0) const
|
||||
inline uint32 get_length(my_ptrdiff_t row_offset= 0) const
|
||||
{ return get_length(ptr+row_offset, this->packlength); }
|
||||
uint32 get_length(const uchar *ptr, uint packlength) const;
|
||||
uint32 get_length(const uchar *ptr_arg) const
|
||||
|
@ -49,8 +49,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
||||
|
||||
if (pos_in_file == info->end_of_file)
|
||||
{
|
||||
info->read_pos= info->read_end= info->buffer;
|
||||
info->pos_in_file= pos_in_file;
|
||||
/* reading past EOF should not empty the cache */
|
||||
info->read_pos= info->read_end;
|
||||
info->error= 0;
|
||||
DBUG_RETURN(MY_TEST(Count));
|
||||
}
|
||||
|
@ -2192,7 +2192,8 @@ static void mysqld_exit(int exit_code)
|
||||
if (opt_endinfo && global_status_var.global_memory_used)
|
||||
fprintf(stderr, "Warning: Memory not freed: %ld\n",
|
||||
(long) global_status_var.global_memory_used);
|
||||
if (!opt_debugging && !my_disable_leak_check && exit_code == 0)
|
||||
if (!opt_debugging && !my_disable_leak_check && exit_code == 0 &&
|
||||
debug_assert_on_not_freed_memory)
|
||||
{
|
||||
#ifdef SAFEMALLOC
|
||||
sf_report_leaked_memory(0);
|
||||
|
@ -430,7 +430,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
HA_CHECK_OPT* check_opt,
|
||||
const char *operator_name,
|
||||
thr_lock_type lock_type,
|
||||
bool open_for_modify,
|
||||
bool org_open_for_modify,
|
||||
bool repair_table_use_frm,
|
||||
uint extra_open_options,
|
||||
int (*prepare_func)(THD *, TABLE_LIST *,
|
||||
@ -497,6 +497,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
bool fatal_error=0;
|
||||
bool open_error;
|
||||
bool collect_eis= FALSE;
|
||||
bool open_for_modify= org_open_for_modify;
|
||||
|
||||
DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
|
||||
strxmov(table_name, db, ".", table->table_name.str, NullS);
|
||||
@ -1164,7 +1165,7 @@ send_result_message:
|
||||
}
|
||||
}
|
||||
/* Error path, a admin command failed. */
|
||||
if (thd->transaction_rollback_request)
|
||||
if (thd->transaction_rollback_request || fatal_error)
|
||||
{
|
||||
/*
|
||||
Unlikely, but transaction rollback was requested by one of storage
|
||||
@ -1220,7 +1221,9 @@ err:
|
||||
}
|
||||
close_thread_tables(thd); // Shouldn't be needed
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
err2:
|
||||
#endif
|
||||
thd->resume_subsequent_commits(suspended_wfc);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
@ -402,8 +402,8 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
|
||||
- For temporary MERGE tables we do not track if their child tables are
|
||||
base or temporary. As result we can't guarantee that privilege check
|
||||
which was done in presence of temporary child will stay relevant later
|
||||
as this temporary table might be removed.
|
||||
which was done in presence of temporary child will stay relevant
|
||||
later as this temporary table might be removed.
|
||||
|
||||
If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for
|
||||
the underlying *base* tables, it would create a security breach as in
|
||||
@ -443,6 +443,9 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
create_info.data_file_name= create_info.index_file_name= NULL;
|
||||
|
||||
thd->prepare_logs_for_admin_command();
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if ((!thd->is_current_stmt_binlog_format_row() ||
|
||||
|
@ -1481,15 +1481,15 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/* Set all [named] partitions as used. */
|
||||
static int set_partitions_as_used(TABLE_LIST *tl, TABLE *t)
|
||||
{
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (t->part_info)
|
||||
return t->file->change_partitions_to_open(tl->partition_names);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@ -1535,7 +1535,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
|
||||
MDL_ticket *mdl_ticket;
|
||||
TABLE_SHARE *share;
|
||||
uint gts_flags;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
int part_names_error=0;
|
||||
#endif
|
||||
DBUG_ENTER("open_table");
|
||||
|
||||
/*
|
||||
@ -1633,7 +1635,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
|
||||
table= best_table;
|
||||
table->query_id= thd->query_id;
|
||||
DBUG_PRINT("info",("Using locked table"));
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
part_names_error= set_partitions_as_used(table_list, table);
|
||||
#endif
|
||||
goto reset;
|
||||
}
|
||||
/*
|
||||
@ -1918,7 +1922,9 @@ retry_share:
|
||||
{
|
||||
DBUG_ASSERT(table->file != NULL);
|
||||
MYSQL_REBIND_TABLE(table->file);
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
part_names_error= set_partitions_as_used(table_list, table);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6686,7 +6686,8 @@ int THD::binlog_write_row(TABLE* table, bool is_trans,
|
||||
Pack records into format for transfer. We are allocating more
|
||||
memory than needed, but that doesn't matter.
|
||||
*/
|
||||
Row_data_memory memory(table, max_row_length(table, record));
|
||||
Row_data_memory memory(table, max_row_length(table, table->rpl_write_set,
|
||||
record));
|
||||
if (!memory.has_memory())
|
||||
return HA_ERR_OUT_OF_MEM;
|
||||
|
||||
@ -6723,8 +6724,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
|
||||
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
|
||||
((WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()));
|
||||
|
||||
size_t const before_maxlen = max_row_length(table, before_record);
|
||||
size_t const after_maxlen = max_row_length(table, after_record);
|
||||
size_t const before_maxlen= max_row_length(table, table->read_set,
|
||||
before_record);
|
||||
size_t const after_maxlen= max_row_length(table, table->rpl_write_set,
|
||||
after_record);
|
||||
|
||||
Row_data_memory row_data(table, before_maxlen, after_maxlen);
|
||||
if (!row_data.has_memory())
|
||||
@ -6800,7 +6803,8 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
|
||||
Pack records into format for transfer. We are allocating more
|
||||
memory than needed, but that doesn't matter.
|
||||
*/
|
||||
Row_data_memory memory(table, max_row_length(table, record));
|
||||
Row_data_memory memory(table, max_row_length(table, table->read_set,
|
||||
record));
|
||||
if (unlikely(!memory.has_memory()))
|
||||
return HA_ERR_OUT_OF_MEM;
|
||||
|
||||
@ -6839,15 +6843,17 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Remove from read_set spurious columns. The write_set has been
|
||||
handled before in table->mark_columns_needed_for_update.
|
||||
*/
|
||||
|
||||
void THD::binlog_prepare_row_images(TABLE *table)
|
||||
{
|
||||
DBUG_ENTER("THD::binlog_prepare_row_images");
|
||||
/**
|
||||
Remove from read_set spurious columns. The write_set has been
|
||||
handled before in table->mark_columns_needed_for_update.
|
||||
*/
|
||||
|
||||
DBUG_PRINT_BITSET("debug", "table->read_set (before preparing): %s", table->read_set);
|
||||
DBUG_PRINT_BITSET("debug", "table->read_set (before preparing): %s",
|
||||
table->read_set);
|
||||
THD *thd= table->in_use;
|
||||
|
||||
/**
|
||||
@ -6865,7 +6871,7 @@ void THD::binlog_prepare_row_images(TABLE *table)
|
||||
*/
|
||||
DBUG_ASSERT(table->read_set != &table->tmp_set);
|
||||
|
||||
switch(thd->variables.binlog_row_image)
|
||||
switch (thd->variables.binlog_row_image)
|
||||
{
|
||||
case BINLOG_ROW_IMAGE_MINIMAL:
|
||||
/* MINIMAL: Mark only PK */
|
||||
@ -6895,7 +6901,8 @@ void THD::binlog_prepare_row_images(TABLE *table)
|
||||
table->write_set);
|
||||
}
|
||||
|
||||
DBUG_PRINT_BITSET("debug", "table->read_set (after preparing): %s", table->read_set);
|
||||
DBUG_PRINT_BITSET("debug", "table->read_set (after preparing): %s",
|
||||
table->read_set);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -4568,6 +4568,12 @@ public:
|
||||
|
||||
/* Members related to temporary tables. */
|
||||
public:
|
||||
/* Opened table states. */
|
||||
enum Temporary_table_state {
|
||||
TMP_TABLE_IN_USE,
|
||||
TMP_TABLE_NOT_IN_USE,
|
||||
TMP_TABLE_ANY
|
||||
};
|
||||
bool has_thd_temporary_tables();
|
||||
|
||||
TABLE *create_and_open_tmp_table(handlerton *hton,
|
||||
@ -4578,8 +4584,10 @@ public:
|
||||
bool open_in_engine,
|
||||
bool open_internal_tables);
|
||||
|
||||
TABLE *find_temporary_table(const char *db, const char *table_name);
|
||||
TABLE *find_temporary_table(const TABLE_LIST *tl);
|
||||
TABLE *find_temporary_table(const char *db, const char *table_name,
|
||||
Temporary_table_state state= TMP_TABLE_IN_USE);
|
||||
TABLE *find_temporary_table(const TABLE_LIST *tl,
|
||||
Temporary_table_state state= TMP_TABLE_IN_USE);
|
||||
|
||||
TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key,
|
||||
uint key_length);
|
||||
@ -4606,13 +4614,6 @@ private:
|
||||
/* Whether a lock has been acquired? */
|
||||
bool m_tmp_tables_locked;
|
||||
|
||||
/* Opened table states. */
|
||||
enum Temporary_table_state {
|
||||
TMP_TABLE_IN_USE,
|
||||
TMP_TABLE_NOT_IN_USE,
|
||||
TMP_TABLE_ANY
|
||||
};
|
||||
|
||||
bool has_temporary_tables();
|
||||
uint create_tmp_table_def_key(char *key, const char *db,
|
||||
const char *table_name);
|
||||
|
@ -195,13 +195,14 @@ static void mysql_ha_close_childs(THD *thd, TABLE_LIST *current_table_list,
|
||||
|
||||
static void mysql_ha_close_table(SQL_HANDLER *handler)
|
||||
{
|
||||
DBUG_ENTER("mysql_ha_close_table");
|
||||
THD *thd= handler->thd;
|
||||
TABLE *table= handler->table;
|
||||
TABLE_LIST *current_table_list= NULL, *next_global;
|
||||
|
||||
/* check if table was already closed */
|
||||
if (!table)
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if ((next_global= table->file->get_next_global_for_child()))
|
||||
current_table_list= next_global->parent_l;
|
||||
@ -232,6 +233,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler)
|
||||
}
|
||||
my_free(handler->lock);
|
||||
handler->init();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -775,6 +775,8 @@ void init_update_queries(void)
|
||||
There are other statements that deal with temporary tables and open
|
||||
them, but which are not listed here. The thing is that the order of
|
||||
pre-opening temporary tables for those statements is somewhat custom.
|
||||
|
||||
Note that SQLCOM_RENAME_TABLE should not be in this list!
|
||||
*/
|
||||
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
||||
@ -789,7 +791,6 @@ void init_update_queries(void)
|
||||
sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
|
||||
sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
|
||||
@ -3237,10 +3238,6 @@ mysql_execute_command(THD *thd)
|
||||
#endif
|
||||
DBUG_ENTER("mysql_execute_command");
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0;
|
||||
#endif
|
||||
|
||||
DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt);
|
||||
/*
|
||||
Each statement or replication event which might produce deadlock
|
||||
@ -4100,6 +4097,7 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0;
|
||||
{
|
||||
partition_info *part_info= thd->lex->part_info;
|
||||
if (part_info && !(part_info= part_info->get_clone(thd)))
|
||||
@ -6594,6 +6592,60 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find out if a table is a temporary table
|
||||
|
||||
A table is a temporary table if it's a temporary table or
|
||||
there has been before a temporary table that has been renamed
|
||||
to the current name.
|
||||
|
||||
Some examples:
|
||||
A->B B is a temporary table if and only if A is a temp.
|
||||
A->B, B->C Second B is temp if A is temp
|
||||
A->B, A->C Second A can't be temp as if A was temp then B is temp
|
||||
and Second A can only be a normal table. C is also not temp
|
||||
*/
|
||||
|
||||
static TABLE *find_temporary_table_for_rename(THD *thd,
|
||||
TABLE_LIST *first_table,
|
||||
TABLE_LIST *cur_table)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
TABLE *res= 0;
|
||||
bool found= 0;
|
||||
DBUG_ENTER("find_temporary_table_for_rename");
|
||||
|
||||
/* Find last instance when cur_table is in TO part */
|
||||
for (table= first_table;
|
||||
table != cur_table;
|
||||
table= table->next_local->next_local)
|
||||
{
|
||||
TABLE_LIST *next= table->next_local;
|
||||
|
||||
if (!strcmp(table->get_db_name(), cur_table->get_db_name()) &&
|
||||
!strcmp(table->get_table_name(), cur_table->get_table_name()))
|
||||
{
|
||||
/* Table was moved away, can't be same as 'table' */
|
||||
found= 1;
|
||||
res= 0; // Table can't be a temporary table
|
||||
}
|
||||
if (!strcmp(next->get_db_name(), cur_table->get_db_name()) &&
|
||||
!strcmp(next->get_table_name(), cur_table->get_table_name()))
|
||||
{
|
||||
/*
|
||||
Table has matching name with new name of this table. cur_table should
|
||||
have same temporary type as this table.
|
||||
*/
|
||||
found= 1;
|
||||
res= table->table;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
res= thd->find_temporary_table(table, THD::TMP_TABLE_ANY);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
|
||||
TABLE_LIST *all_tables)
|
||||
{
|
||||
@ -6610,13 +6662,19 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table,
|
||||
&table->next_local->grant.m_internal,
|
||||
0, 0))
|
||||
return 1;
|
||||
|
||||
/* check if these are refering to temporary tables */
|
||||
table->table= find_temporary_table_for_rename(thd, first_table, table);
|
||||
table->next_local->table= table->table;
|
||||
|
||||
TABLE_LIST old_list, new_list;
|
||||
/*
|
||||
we do not need initialize old_list and new_list because we will
|
||||
come table[0] and table->next[0] there
|
||||
copy table[0] and table->next[0] there
|
||||
*/
|
||||
old_list= table[0];
|
||||
new_list= table->next_local[0];
|
||||
|
||||
if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) ||
|
||||
(!test_all_bits(table->next_local->grant.privilege,
|
||||
INSERT_ACL | CREATE_ACL) &&
|
||||
|
@ -223,7 +223,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
|
||||
new_alias= (lower_case_table_names == 2) ? &new_table->alias :
|
||||
&new_table->table_name;
|
||||
|
||||
if (is_temporary_table(new_table))
|
||||
if (thd->find_temporary_table(new_table, THD::TMP_TABLE_ANY))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias->str);
|
||||
DBUG_RETURN(1); // This can't be skipped
|
||||
|
@ -1517,7 +1517,8 @@ public:
|
||||
|
||||
~Stat_table_write_iter()
|
||||
{
|
||||
cleanup();
|
||||
/* Ensure that cleanup has been run */
|
||||
DBUG_ASSERT(rowid_buf == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -240,8 +240,17 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs)
|
||||
{
|
||||
if (alloc(arg_length))
|
||||
return TRUE;
|
||||
DBUG_ASSERT(arg_length <= UINT_MAX32);
|
||||
if ((str_length=(uint32)arg_length))
|
||||
DBUG_ASSERT(arg_length < UINT_MAX32);
|
||||
if (Ptr == str && arg_length == uint32(str_length))
|
||||
{
|
||||
/*
|
||||
This can happen in some cases. This code is here mainly to avoid
|
||||
warnings from valgrind, but can also be an indication of error.
|
||||
*/
|
||||
DBUG_PRINT("warning", ("Copying string on itself: %p %zu",
|
||||
str, arg_length));
|
||||
}
|
||||
else if ((str_length=uint32(arg_length)))
|
||||
memcpy(Ptr,str,arg_length);
|
||||
Ptr[arg_length]=0;
|
||||
str_charset=cs;
|
||||
|
@ -6095,10 +6095,28 @@ drop_create_field:
|
||||
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
||||
Alter_drop *drop;
|
||||
bool remove_drop;
|
||||
ulonglong left_flags= 0;
|
||||
while ((drop= drop_it++))
|
||||
{
|
||||
ulonglong cur_flag= 0;
|
||||
switch (drop->type) {
|
||||
case Alter_drop::COLUMN:
|
||||
cur_flag= ALTER_PARSER_DROP_COLUMN;
|
||||
break;
|
||||
case Alter_drop::FOREIGN_KEY:
|
||||
cur_flag= ALTER_DROP_FOREIGN_KEY;
|
||||
break;
|
||||
case Alter_drop::KEY:
|
||||
cur_flag= ALTER_DROP_INDEX;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!drop->drop_if_exists)
|
||||
{
|
||||
left_flags|= cur_flag;
|
||||
continue;
|
||||
}
|
||||
remove_drop= TRUE;
|
||||
if (drop->type == Alter_drop::COLUMN)
|
||||
{
|
||||
@ -6190,12 +6208,15 @@ drop_create_field:
|
||||
ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY),
|
||||
drop->type_name(), drop->name);
|
||||
drop_it.remove();
|
||||
if (alter_info->drop_list.is_empty())
|
||||
alter_info->flags&= ~(ALTER_PARSER_DROP_COLUMN |
|
||||
ALTER_DROP_INDEX |
|
||||
ALTER_DROP_FOREIGN_KEY);
|
||||
}
|
||||
else
|
||||
left_flags|= cur_flag;
|
||||
}
|
||||
/* Reset state to what's left in drop list */
|
||||
alter_info->flags&= ~(ALTER_PARSER_DROP_COLUMN |
|
||||
ALTER_DROP_INDEX |
|
||||
ALTER_DROP_FOREIGN_KEY);
|
||||
alter_info->flags|= left_flags;
|
||||
}
|
||||
|
||||
/* ALTER TABLE ADD KEY IF NOT EXISTS */
|
||||
@ -6309,8 +6330,9 @@ remove_key:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
DBUG_ASSERT(thd->work_part_info == 0);
|
||||
partition_info *tab_part_info= table->part_info;
|
||||
thd->work_part_info= thd->lex->part_info;
|
||||
if (tab_part_info)
|
||||
@ -9017,6 +9039,10 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
||||
{
|
||||
DBUG_ENTER("mysql_alter_table");
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0; // Used by partitioning
|
||||
#endif
|
||||
|
||||
/*
|
||||
Check if we attempt to alter mysql.slow_log or
|
||||
mysql.general_log table and return an error if
|
||||
|
@ -624,6 +624,7 @@ end:
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build stmt_query to write it in the bin-log, the statement to write in
|
||||
the trigger file and the trigger definer.
|
||||
@ -1191,6 +1192,12 @@ Table_triggers_list::~Table_triggers_list()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free blobs used in insert */
|
||||
if (record0_field)
|
||||
for (Field **fld_ptr= record0_field; *fld_ptr; fld_ptr++)
|
||||
(*fld_ptr)->free();
|
||||
|
||||
if (record1_field)
|
||||
for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++)
|
||||
delete *fld_ptr;
|
||||
|
92
sql/table.cc
92
sql/table.cc
@ -2770,6 +2770,9 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
|
||||
goto ret;
|
||||
|
||||
thd->lex->create_info.db_type= hton;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0; // For partitioning
|
||||
#endif
|
||||
|
||||
if (tabledef_version.str)
|
||||
thd->lex->create_info.tabledef_version= tabledef_version;
|
||||
@ -6682,6 +6685,12 @@ void TABLE::mark_columns_per_binlog_row_image()
|
||||
DBUG_ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
/*
|
||||
We have to ensure that all virtual columns that are part of read set
|
||||
are calculated.
|
||||
*/
|
||||
if (vcol_set)
|
||||
bitmap_union(vcol_set, read_set);
|
||||
file->column_bitmaps_signal();
|
||||
}
|
||||
|
||||
@ -6723,7 +6732,8 @@ bool TABLE::mark_virtual_col(Field *field)
|
||||
/*
|
||||
@brief Mark virtual columns for update/insert commands
|
||||
|
||||
@param insert_fl <-> virtual columns are marked for insert command
|
||||
@param insert_fl true if virtual columns are marked for insert command
|
||||
For the moment this is not used, may be used in future.
|
||||
|
||||
@details
|
||||
The function marks virtual columns used in a update/insert commands
|
||||
@ -6748,7 +6758,8 @@ bool TABLE::mark_virtual_col(Field *field)
|
||||
be added to read_set either.
|
||||
*/
|
||||
|
||||
bool TABLE::mark_virtual_columns_for_write(bool insert_fl)
|
||||
bool TABLE::mark_virtual_columns_for_write(bool insert_fl
|
||||
__attribute__((unused)))
|
||||
{
|
||||
Field **vfield_ptr, *tmp_vfield;
|
||||
bool bitmap_updated= false;
|
||||
@ -6758,35 +6769,13 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl)
|
||||
{
|
||||
tmp_vfield= *vfield_ptr;
|
||||
if (bitmap_is_set(write_set, tmp_vfield->field_index))
|
||||
bitmap_updated= mark_virtual_col(tmp_vfield);
|
||||
bitmap_updated|= mark_virtual_col(tmp_vfield);
|
||||
else if (tmp_vfield->vcol_info->stored_in_db ||
|
||||
(tmp_vfield->flags & (PART_KEY_FLAG | FIELD_IN_PART_FUNC_FLAG)))
|
||||
{
|
||||
if (insert_fl)
|
||||
{
|
||||
bitmap_set_bit(write_set, tmp_vfield->field_index);
|
||||
mark_virtual_col(tmp_vfield);
|
||||
bitmap_updated= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MY_BITMAP *save_read_set= read_set, *save_vcol_set= vcol_set;
|
||||
Item *vcol_item= tmp_vfield->vcol_info->expr;
|
||||
DBUG_ASSERT(vcol_item);
|
||||
bitmap_clear_all(&tmp_set);
|
||||
read_set= vcol_set= &tmp_set;
|
||||
vcol_item->walk(&Item::register_field_in_read_map, 1, 0);
|
||||
read_set= save_read_set;
|
||||
vcol_set= save_vcol_set;
|
||||
if (bitmap_is_overlapping(&tmp_set, write_set))
|
||||
{
|
||||
bitmap_set_bit(write_set, tmp_vfield->field_index);
|
||||
bitmap_set_bit(vcol_set, tmp_vfield->field_index);
|
||||
bitmap_union(read_set, &tmp_set);
|
||||
bitmap_union(vcol_set, &tmp_set);
|
||||
bitmap_updated= true;
|
||||
}
|
||||
}
|
||||
bitmap_set_bit(write_set, tmp_vfield->field_index);
|
||||
mark_virtual_col(tmp_vfield);
|
||||
bitmap_updated= true;
|
||||
}
|
||||
}
|
||||
if (bitmap_updated)
|
||||
@ -7432,8 +7421,8 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and
|
||||
create tbl->force_index_join instead.
|
||||
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified)
|
||||
and create tbl->force_index_join instead.
|
||||
Then use the correct force_index_XX instead of the global one.
|
||||
*/
|
||||
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
|
||||
@ -7463,21 +7452,27 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
|
||||
}
|
||||
|
||||
|
||||
size_t max_row_length(TABLE *table, const uchar *data)
|
||||
size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data)
|
||||
{
|
||||
TABLE_SHARE *table_s= table->s;
|
||||
size_t length= table_s->reclength + 2 * table_s->fields;
|
||||
uint *const beg= table_s->blob_field;
|
||||
uint *const end= beg + table_s->blob_fields;
|
||||
my_ptrdiff_t const rec_offset= (my_ptrdiff_t) (data - table->record[0]);
|
||||
DBUG_ENTER("max_row_length");
|
||||
|
||||
for (uint *ptr= beg ; ptr != end ; ++ptr)
|
||||
{
|
||||
Field_blob* const blob= (Field_blob*) table->field[*ptr];
|
||||
length+= blob->get_length((const uchar*)
|
||||
(data + blob->offset(table->record[0]))) +
|
||||
HA_KEY_BLOB_LENGTH;
|
||||
Field * const field= table->field[*ptr];
|
||||
if (bitmap_is_set(cols, field->field_index) &&
|
||||
!field->is_null(rec_offset))
|
||||
{
|
||||
Field_blob * const blob= (Field_blob*) field;
|
||||
length+= blob->get_length(rec_offset) + 8; /* max blob store length */
|
||||
}
|
||||
}
|
||||
return length;
|
||||
DBUG_PRINT("exit", ("length: %lld", (longlong) length));
|
||||
DBUG_RETURN(length);
|
||||
}
|
||||
|
||||
|
||||
@ -7592,7 +7587,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
|
||||
Query_arena backup_arena;
|
||||
Turn_errors_to_warnings_handler Suppress_errors;
|
||||
int error;
|
||||
bool handler_pushed= 0;
|
||||
bool handler_pushed= 0, update_all_columns= 1;
|
||||
DBUG_ASSERT(vfield);
|
||||
|
||||
if (h->keyread_enabled())
|
||||
@ -7609,6 +7604,16 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
|
||||
in_use->push_internal_handler(&Suppress_errors);
|
||||
handler_pushed= 1;
|
||||
}
|
||||
else if (update_mode == VCOL_UPDATE_FOR_REPLACE &&
|
||||
in_use->is_current_stmt_binlog_format_row() &&
|
||||
in_use->variables.binlog_row_image != BINLOG_ROW_IMAGE_MINIMAL)
|
||||
{
|
||||
/*
|
||||
If we are doing a replace with not minimal binary logging, we have to
|
||||
calculate all virtual columns.
|
||||
*/
|
||||
update_all_columns= 1;
|
||||
}
|
||||
|
||||
/* Iterate over virtual fields in the table */
|
||||
for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
|
||||
@ -7621,8 +7626,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
|
||||
bool update= 0, swap_values= 0;
|
||||
switch (update_mode) {
|
||||
case VCOL_UPDATE_FOR_READ:
|
||||
update= !vcol_info->stored_in_db
|
||||
&& bitmap_is_set(vcol_set, vf->field_index);
|
||||
update= (!vcol_info->stored_in_db &&
|
||||
bitmap_is_set(vcol_set, vf->field_index));
|
||||
swap_values= 1;
|
||||
break;
|
||||
case VCOL_UPDATE_FOR_DELETE:
|
||||
@ -7630,8 +7635,9 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
|
||||
update= bitmap_is_set(vcol_set, vf->field_index);
|
||||
break;
|
||||
case VCOL_UPDATE_FOR_REPLACE:
|
||||
update= !vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG)
|
||||
&& bitmap_is_set(vcol_set, vf->field_index);
|
||||
update= ((!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) &&
|
||||
bitmap_is_set(vcol_set, vf->field_index)) ||
|
||||
update_all_columns);
|
||||
if (update && (vf->flags & BLOB_FLAG))
|
||||
{
|
||||
/*
|
||||
@ -7648,8 +7654,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
|
||||
case VCOL_UPDATE_INDEXED:
|
||||
case VCOL_UPDATE_INDEXED_FOR_UPDATE:
|
||||
/* Read indexed fields that was not updated in VCOL_UPDATE_FOR_READ */
|
||||
update= !vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) &&
|
||||
bitmap_is_set(vcol_set, vf->field_index);
|
||||
update= (!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) &&
|
||||
!bitmap_is_set(vcol_set, vf->field_index));
|
||||
swap_values= 1;
|
||||
break;
|
||||
}
|
||||
|
@ -2879,7 +2879,7 @@ enum get_table_share_flags {
|
||||
GTS_FORCE_DISCOVERY = 16
|
||||
};
|
||||
|
||||
size_t max_row_length(TABLE *table, const uchar *data);
|
||||
size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data);
|
||||
|
||||
void init_mdl_requests(TABLE_LIST *table_list);
|
||||
|
||||
|
@ -112,12 +112,14 @@ TABLE *THD::create_and_open_tmp_table(handlerton *hton,
|
||||
|
||||
@param db [IN] Database name
|
||||
@param table_name [IN] Table name
|
||||
@param state [IN] State of temp table to open
|
||||
|
||||
@return Success Pointer to first used table instance.
|
||||
Failure NULL
|
||||
*/
|
||||
TABLE *THD::find_temporary_table(const char *db,
|
||||
const char *table_name)
|
||||
const char *table_name,
|
||||
Temporary_table_state state)
|
||||
{
|
||||
DBUG_ENTER("THD::find_temporary_table");
|
||||
|
||||
@ -134,7 +136,7 @@ TABLE *THD::find_temporary_table(const char *db,
|
||||
key_length= create_tmp_table_def_key(key, db, table_name);
|
||||
|
||||
locked= lock_temporary_tables();
|
||||
table = find_temporary_table(key, key_length, TMP_TABLE_IN_USE);
|
||||
table= find_temporary_table(key, key_length, state);
|
||||
if (locked)
|
||||
{
|
||||
DBUG_ASSERT(m_tmp_tables_locked);
|
||||
@ -153,16 +155,12 @@ TABLE *THD::find_temporary_table(const char *db,
|
||||
@return Success Pointer to first used table instance.
|
||||
Failure NULL
|
||||
*/
|
||||
TABLE *THD::find_temporary_table(const TABLE_LIST *tl)
|
||||
TABLE *THD::find_temporary_table(const TABLE_LIST *tl,
|
||||
Temporary_table_state state)
|
||||
{
|
||||
DBUG_ENTER("THD::find_temporary_table");
|
||||
|
||||
if (!has_temporary_tables())
|
||||
{
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name());
|
||||
TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name(),
|
||||
state);
|
||||
DBUG_RETURN(table);
|
||||
}
|
||||
|
||||
|
@ -898,18 +898,19 @@ int ha_archive::real_write_row(uchar *buf, azio_stream *writer)
|
||||
the bytes required for the length in the header.
|
||||
*/
|
||||
|
||||
uint32 ha_archive::max_row_length(const uchar *buf)
|
||||
uint32 ha_archive::max_row_length(const uchar *record)
|
||||
{
|
||||
uint32 length= (uint32)(table->s->reclength + table->s->fields*2);
|
||||
length+= ARCHIVE_ROW_HEADER_SIZE;
|
||||
my_ptrdiff_t const rec_offset= record - table->record[0];
|
||||
|
||||
uint *ptr, *end;
|
||||
for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
|
||||
ptr != end ;
|
||||
ptr++)
|
||||
{
|
||||
if (!table->field[*ptr]->is_null())
|
||||
length += 2 + ((Field_blob*)table->field[*ptr])->get_length();
|
||||
if (!table->field[*ptr]->is_null(rec_offset))
|
||||
length += 2 + ((Field_blob*)table->field[*ptr])->get_length(rec_offset);
|
||||
}
|
||||
|
||||
return length;
|
||||
@ -919,10 +920,9 @@ uint32 ha_archive::max_row_length(const uchar *buf)
|
||||
unsigned int ha_archive::pack_row(uchar *record, azio_stream *writer)
|
||||
{
|
||||
uchar *ptr;
|
||||
|
||||
my_ptrdiff_t const rec_offset= record - table->record[0];
|
||||
DBUG_ENTER("ha_archive::pack_row");
|
||||
|
||||
|
||||
if (fix_rec_buff(max_row_length(record)))
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
|
||||
|
||||
@ -936,7 +936,7 @@ unsigned int ha_archive::pack_row(uchar *record, azio_stream *writer)
|
||||
|
||||
for (Field **field=table->field ; *field ; field++)
|
||||
{
|
||||
if (!((*field)->is_null()))
|
||||
if (!((*field)->is_null(rec_offset)))
|
||||
ptr= (*field)->pack(ptr, record + (*field)->offset(record));
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1145,7 @@ retry:
|
||||
#endif
|
||||
ut_ad(btr_search_enabled);
|
||||
|
||||
ut_ad(block->page.id.space() == index->table->space->id);
|
||||
ut_ad(block->page.id.space() == index->table->space_id);
|
||||
ut_a(index_id == index->id);
|
||||
ut_a(!dict_index_is_ibuf(index));
|
||||
#ifdef UNIV_DEBUG
|
||||
@ -1271,9 +1271,8 @@ cleanup:
|
||||
ut_free(folds);
|
||||
}
|
||||
|
||||
/** Drop any adaptive hash index entries that may point to an index
|
||||
page that may be in the buffer pool, when a page is evicted from the
|
||||
buffer pool or freed in a file segment.
|
||||
/** Drop possible adaptive hash index entries when a page is evicted
|
||||
from the buffer pool or freed in a file, or the index is being dropped.
|
||||
@param[in] page_id page id */
|
||||
void btr_search_drop_page_hash_when_freed(const page_id_t& page_id)
|
||||
{
|
||||
@ -2056,7 +2055,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
|
||||
|
||||
ut_a(!dict_index_is_ibuf(block->index));
|
||||
ut_ad(block->page.id.space()
|
||||
== block->index->table->space->id);
|
||||
== block->index->table->space_id);
|
||||
|
||||
page_index_id = btr_page_get_index_id(block->frame);
|
||||
|
||||
|
@ -225,24 +225,17 @@ particular space id.
|
||||
@param[in] count number of entries in array */
|
||||
static
|
||||
void
|
||||
buf_LRU_drop_page_hash_batch(
|
||||
ulint space_id,
|
||||
const ulint* arr,
|
||||
ulint count)
|
||||
buf_LRU_drop_page_hash_batch(ulint space_id, const ulint* arr, ulint count)
|
||||
{
|
||||
ut_ad(count <= BUF_LRU_DROP_SEARCH_SIZE);
|
||||
|
||||
for (ulint i = 0; i < count; ++i, ++arr) {
|
||||
for (const ulint* const end = arr + count; arr != end; ) {
|
||||
/* While our only caller
|
||||
buf_LRU_drop_page_hash_for_tablespace()
|
||||
is being executed for DROP TABLE or similar,
|
||||
the table cannot be evicted from the buffer pool.
|
||||
Note: this should not be executed for DROP TABLESPACE,
|
||||
because DROP TABLESPACE would be refused if tables existed
|
||||
in the tablespace, and a previous DROP TABLE would have
|
||||
already removed the AHI entries. */
|
||||
the table cannot be evicted from the buffer pool. */
|
||||
btr_search_drop_page_hash_when_freed(
|
||||
page_id_t(space_id, *arr));
|
||||
page_id_t(space_id, *arr++));
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,6 +352,28 @@ next_page:
|
||||
buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
|
||||
ut_free(page_arr);
|
||||
}
|
||||
|
||||
/** Drop the adaptive hash index for a tablespace.
|
||||
@param[in,out] table table */
|
||||
void buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table)
|
||||
{
|
||||
for (dict_index_t* index = dict_table_get_first_index(table);
|
||||
index != NULL;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
if (btr_search_info_get_ref_count(btr_search_get_info(index),
|
||||
index)) {
|
||||
goto drop_ahi;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
drop_ahi:
|
||||
ulint id = table->space_id;
|
||||
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||
buf_LRU_drop_page_hash_for_tablespace(buf_pool_from_array(i),
|
||||
id);
|
||||
}
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/******************************************************************//**
|
||||
@ -682,26 +697,13 @@ buf_flush_dirty_pages(
|
||||
@param[in] id tablespace identifier
|
||||
@param[in] observer flush observer,
|
||||
or NULL if nothing is to be written */
|
||||
void
|
||||
buf_LRU_flush_or_remove_pages(
|
||||
ulint id,
|
||||
FlushObserver* observer
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
, bool drop_ahi /*!< whether to drop the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
)
|
||||
void buf_LRU_flush_or_remove_pages(ulint id, FlushObserver* observer)
|
||||
{
|
||||
/* Pages in the system tablespace must never be discarded. */
|
||||
ut_ad(id || observer);
|
||||
|
||||
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||
buf_pool_t* buf_pool = buf_pool_from_array(i);
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
if (drop_ahi) {
|
||||
buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
|
||||
}
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
buf_flush_dirty_pages(buf_pool, id, observer);
|
||||
buf_flush_dirty_pages(buf_pool_from_array(i), id, observer);
|
||||
}
|
||||
|
||||
if (observer && !observer->is_interrupted()) {
|
||||
|
@ -1623,11 +1623,7 @@ dict_table_rename_in_cache(
|
||||
return(DB_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
fil_delete_tablespace(table->space->id
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
, true
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
);
|
||||
fil_delete_tablespace(table->space_id);
|
||||
|
||||
/* Delete any temp file hanging around. */
|
||||
if (os_file_status(filepath, &exists, &ftype)
|
||||
@ -2593,28 +2589,13 @@ dict_index_remove_from_cache_low(
|
||||
zero. See also: dict_table_can_be_evicted() */
|
||||
|
||||
do {
|
||||
ulint ref_count = btr_search_info_get_ref_count(info, index);
|
||||
|
||||
if (ref_count == 0) {
|
||||
if (!btr_search_info_get_ref_count(info, index)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sleep for 10ms before trying again. */
|
||||
os_thread_sleep(10000);
|
||||
++retries;
|
||||
buf_LRU_drop_page_hash_for_tablespace(table);
|
||||
|
||||
if (retries % 500 == 0) {
|
||||
/* No luck after 5 seconds of wait. */
|
||||
ib::error() << "Waited for " << retries / 100
|
||||
<< " secs for hash index"
|
||||
" ref_count (" << ref_count << ") to drop to 0."
|
||||
" index: " << index->name
|
||||
<< " table: " << table->name;
|
||||
}
|
||||
|
||||
/* To avoid a hang here we commit suicide if the
|
||||
ref_count doesn't drop to zero in 600 seconds. */
|
||||
ut_a(retries < 60000);
|
||||
ut_a(++retries < 10000);
|
||||
} while (srv_shutdown_state == SRV_SHUTDOWN_NONE || !lru_evict);
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
|
@ -2698,11 +2698,7 @@ fil_delete_tablespace(
|
||||
To deal with potential read requests, we will check the
|
||||
::stop_new_ops flag in fil_io(). */
|
||||
|
||||
buf_LRU_flush_or_remove_pages(id, NULL
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
, drop_ahi
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
);
|
||||
buf_LRU_flush_or_remove_pages(id, NULL);
|
||||
|
||||
/* If it is a delete then also delete any generated files, otherwise
|
||||
when we drop the database the remove directory will fail. */
|
||||
|
@ -119,11 +119,9 @@ btr_search_move_or_delete_hash_entries(
|
||||
i.e.: it is in state BUF_BLOCK_REMOVE_HASH */
|
||||
void btr_search_drop_page_hash_index(buf_block_t* block);
|
||||
|
||||
/** Drop any adaptive hash index entries that may point to an index
|
||||
page that may be in the buffer pool, when a page is evicted from the
|
||||
buffer pool or freed in a file segment.
|
||||
@param[in] page_id page id
|
||||
@param[in] page_size page size */
|
||||
/** Drop possible adaptive hash index entries when a page is evicted
|
||||
from the buffer pool or freed in a file, or the index is being dropped.
|
||||
@param[in] page_id page id */
|
||||
void btr_search_drop_page_hash_when_freed(const page_id_t& page_id);
|
||||
|
||||
/** Updates the page hash index when a single record is inserted on a page.
|
||||
|
@ -51,18 +51,20 @@ These are low-level functions
|
||||
/** Minimum LRU list length for which the LRU_old pointer is defined */
|
||||
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
struct dict_table_t;
|
||||
/** Drop the adaptive hash index for a tablespace.
|
||||
@param[in,out] table table */
|
||||
void buf_LRU_drop_page_hash_for_tablespace(dict_table_t* table);
|
||||
#else
|
||||
# define buf_LRU_drop_page_hash_for_tablespace(table)
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
|
||||
/** Empty the flush list for all pages belonging to a tablespace.
|
||||
@param[in] id tablespace identifier
|
||||
@param[in,out] observer flush observer,
|
||||
or NULL if nothing is to be written */
|
||||
void
|
||||
buf_LRU_flush_or_remove_pages(
|
||||
ulint id,
|
||||
FlushObserver* observer
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
, bool drop_ahi = false /*!< whether to drop the adaptive hash index */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
);
|
||||
void buf_LRU_flush_or_remove_pages(ulint id, FlushObserver* observer);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
/********************************************************************//**
|
||||
|
@ -62,7 +62,9 @@ struct crypt_info_t {
|
||||
static crypt_info_t info;
|
||||
|
||||
/** Crypt info when upgrading from 10.1 */
|
||||
static crypt_info_t infos[5];
|
||||
static crypt_info_t infos[5 * 2];
|
||||
/** First unused slot in infos[] */
|
||||
static size_t infos_used;
|
||||
|
||||
/*********************************************************************//**
|
||||
Get a log block's start lsn.
|
||||
@ -80,28 +82,6 @@ log_block_get_start_lsn(
|
||||
return start_lsn;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Get crypt info from checkpoint.
|
||||
@return a crypt info or NULL if not present. */
|
||||
static
|
||||
const crypt_info_t*
|
||||
get_crypt_info(ulint checkpoint_no)
|
||||
{
|
||||
/* a log block only stores 4-bytes of checkpoint no */
|
||||
checkpoint_no &= 0xFFFFFFFF;
|
||||
for (unsigned i = 0; i < 5; i++) {
|
||||
const crypt_info_t* it = &infos[i];
|
||||
|
||||
if (it->key_version && it->checkpoint_no == checkpoint_no) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
/* If checkpoint contains more than one key and we did not
|
||||
find the correct one use the first one. */
|
||||
return infos;
|
||||
}
|
||||
|
||||
/** Encrypt or decrypt log blocks.
|
||||
@param[in,out] buf log blocks to encrypt or decrypt
|
||||
@param[in] lsn log sequence number of the start of the buffer
|
||||
@ -166,9 +146,7 @@ log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt)
|
||||
@param[in,out] info encryption key
|
||||
@param[in] upgrade whether to use the key in MariaDB 10.1 format
|
||||
@return whether the operation was successful */
|
||||
static
|
||||
bool
|
||||
init_crypt_key(crypt_info_t* info, bool upgrade = false)
|
||||
static bool init_crypt_key(crypt_info_t* info, bool upgrade = false)
|
||||
{
|
||||
byte mysqld_key[MY_AES_MAX_KEY_LENGTH];
|
||||
uint keylen = sizeof mysqld_key;
|
||||
@ -253,8 +231,20 @@ log_crypt_101_read_checkpoint(const byte* buf)
|
||||
const size_t n = *buf++ == 2 ? std::min(unsigned(*buf++), 5U) : 0;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
struct crypt_info_t& info = infos[i];
|
||||
info.checkpoint_no = mach_read_from_4(buf);
|
||||
struct crypt_info_t& info = infos[infos_used];
|
||||
unsigned checkpoint_no = mach_read_from_4(buf);
|
||||
for (size_t j = 0; j < infos_used; j++) {
|
||||
if (infos[j].checkpoint_no == checkpoint_no) {
|
||||
/* Do not overwrite an existing slot. */
|
||||
goto next_slot;
|
||||
}
|
||||
}
|
||||
if (infos_used >= UT_ARR_SIZE(infos)) {
|
||||
ut_ad(!"too many checkpoint pages");
|
||||
goto next_slot;
|
||||
}
|
||||
infos_used++;
|
||||
info.checkpoint_no = checkpoint_no;
|
||||
info.key_version = mach_read_from_4(buf + 4);
|
||||
memcpy(info.crypt_msg.bytes, buf + 8, sizeof info.crypt_msg);
|
||||
memcpy(info.crypt_nonce.bytes, buf + 24,
|
||||
@ -263,6 +253,7 @@ log_crypt_101_read_checkpoint(const byte* buf)
|
||||
if (!init_crypt_key(&info, true)) {
|
||||
return false;
|
||||
}
|
||||
next_slot:
|
||||
buf += 4 + 4 + 2 * MY_AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
@ -278,13 +269,19 @@ log_crypt_101_read_block(byte* buf)
|
||||
{
|
||||
ut_ad(log_block_calc_checksum_format_0(buf)
|
||||
!= log_block_get_checksum(buf));
|
||||
const crypt_info_t* info = get_crypt_info(
|
||||
log_block_get_checkpoint_no(buf));
|
||||
|
||||
if (!info || info->key_version == 0) {
|
||||
return false;
|
||||
const uint32_t checkpoint_no
|
||||
= uint32_t(log_block_get_checkpoint_no(buf));
|
||||
const crypt_info_t* info = infos;
|
||||
for (const crypt_info_t* const end = info + infos_used; info < end;
|
||||
info++) {
|
||||
if (info->key_version
|
||||
&& info->checkpoint_no == checkpoint_no) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
found:
|
||||
byte dst[OS_FILE_LOG_BLOCK_SIZE];
|
||||
uint dst_len;
|
||||
byte aes_ctr_iv[MY_AES_BLOCK_SIZE];
|
||||
@ -313,9 +310,7 @@ log_crypt_101_read_block(byte* buf)
|
||||
LOG_DEFAULT_ENCRYPTION_KEY,
|
||||
info->key_version);
|
||||
|
||||
if (rc != MY_AES_OK || dst_len != src_len
|
||||
|| log_block_calc_checksum_format_0(dst)
|
||||
!= log_block_get_checksum(dst)) {
|
||||
if (rc != MY_AES_OK || dst_len != src_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ Created 2012-02-08 by Sunny Bains.
|
||||
|
||||
#include "row0import.h"
|
||||
#include "btr0pcur.h"
|
||||
#include "btr0sea.h"
|
||||
#include "que0que.h"
|
||||
#include "dict0boot.h"
|
||||
#include "ibuf0ibuf.h"
|
||||
@ -3870,6 +3871,17 @@ row_import_for_mysql(
|
||||
return(row_import_cleanup(prebuilt, trx, err));
|
||||
}
|
||||
|
||||
/* On DISCARD TABLESPACE, we did not drop any adaptive hash
|
||||
index entries. If we replaced the discarded tablespace with a
|
||||
smaller one here, there could still be some adaptive hash
|
||||
index entries that point to cached garbage pages in the buffer
|
||||
pool, because PageConverter::operator() only evicted those
|
||||
pages that were replaced by the imported pages. We must
|
||||
discard all remaining adaptive hash index entries, because the
|
||||
adaptive hash index must be a subset of the table contents;
|
||||
false positives are not tolerated. */
|
||||
buf_LRU_drop_page_hash_for_tablespace(table);
|
||||
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
/* If the table is stored in a remote tablespace, we need to
|
||||
|
@ -3151,11 +3151,7 @@ row_discard_tablespace(
|
||||
}
|
||||
|
||||
/* Discard the physical file that is used for the tablespace. */
|
||||
err = fil_delete_tablespace(table->space_id
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
, true
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
);
|
||||
err = fil_delete_tablespace(table->space_id);
|
||||
switch (err) {
|
||||
case DB_IO_ERROR:
|
||||
ib::warn() << "ALTER TABLE " << table->name
|
||||
@ -3706,6 +3702,21 @@ defer:
|
||||
rw_lock_x_unlock(dict_index_get_lock(index));
|
||||
}
|
||||
|
||||
if (table->space_id != TRX_SYS_SPACE) {
|
||||
/* On DISCARD TABLESPACE, we would not drop the
|
||||
adaptive hash index entries. If the tablespace is
|
||||
missing here, delete-marking the record in SYS_INDEXES
|
||||
would not free any pages in the buffer pool. Thus,
|
||||
dict_index_remove_from_cache() would hang due to
|
||||
adaptive hash index entries existing in the buffer
|
||||
pool. To prevent this hang, and also to guarantee
|
||||
that btr_search_drop_page_hash_when_freed() will avoid
|
||||
calling btr_search_drop_page_hash_index() while we
|
||||
hold the InnoDB dictionary lock, we will drop any
|
||||
adaptive hash index entries upfront. */
|
||||
buf_LRU_drop_page_hash_for_tablespace(table);
|
||||
}
|
||||
|
||||
/* Deleting a row from SYS_INDEXES table will invoke
|
||||
dict_drop_index_tree(). */
|
||||
info = pars_info_create();
|
||||
|
@ -37,6 +37,7 @@ C_MODE_START
|
||||
#include "ma_checkpoint.h"
|
||||
#include "ma_recovery.h"
|
||||
C_MODE_END
|
||||
#include "ma_trnman.h"
|
||||
|
||||
//#include "sql_priv.h"
|
||||
#include "protocol.h"
|
||||
@ -1394,7 +1395,8 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
|
||||
}
|
||||
|
||||
/* Reset trn, that may have been set by repair */
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
if (old_trn && old_trn != file->trn)
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
thd_proc_info(thd, old_proc_info);
|
||||
thd_progress_end(thd);
|
||||
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
|
||||
@ -1528,7 +1530,8 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
|
||||
error=maria_zerofill(param, file, share->open_file_name.str);
|
||||
|
||||
/* Reset trn, that may have been set by repair */
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
if (old_trn && old_trn != file->trn)
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
|
||||
if (!error)
|
||||
{
|
||||
@ -1771,7 +1774,8 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
|
||||
maria_lock_database(file, F_UNLCK);
|
||||
|
||||
/* Reset trn, that may have been set by repair */
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
if (old_trn && old_trn != file->trn)
|
||||
_ma_set_trn_for_table(file, old_trn);
|
||||
error= error ? HA_ADMIN_FAILED :
|
||||
(optimize_done ?
|
||||
(write_log_record_for_repair(param, file) ? HA_ADMIN_FAILED :
|
||||
@ -2591,9 +2595,12 @@ int ha_maria::extra(enum ha_extra_function operation)
|
||||
without calling commit/rollback in between. If file->trn is not set
|
||||
we can't remove file->share from the transaction list in the extra() call.
|
||||
|
||||
We also ensure that we set file->trn to 0 if THD_TRN is 0 as in
|
||||
this case we have already freed the trn. This can happen when one
|
||||
implicit_commit() is called as part of alter table.
|
||||
In current code we don't have to do this for HA_EXTRA_PREPARE_FOR_RENAME
|
||||
as this is only used the intermediate table used by ALTER TABLE which
|
||||
is not part of the transaction (it's not in the TRN list). Better to
|
||||
keep this for now, to not break anything in a stable release.
|
||||
When HA_EXTRA_PREPARE_FOR_RENAME is not handled below, we can change
|
||||
the warnings in _ma_remove_table_from_trnman() to asserts.
|
||||
|
||||
table->in_use is not set in the case this is a done as part of closefrm()
|
||||
as part of drop table.
|
||||
@ -2606,7 +2613,7 @@ int ha_maria::extra(enum ha_extra_function operation)
|
||||
{
|
||||
THD *thd= table->in_use;
|
||||
TRN *trn= THD_TRN;
|
||||
_ma_set_trn_for_table(file, trn);
|
||||
_ma_set_tmp_trn_for_table(file, trn);
|
||||
}
|
||||
DBUG_ASSERT(file->s->base.born_transactional || file->trn == 0 ||
|
||||
file->trn == &dummy_transaction_object);
|
||||
@ -2722,6 +2729,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
||||
if (file->trn)
|
||||
{
|
||||
/* This can only happen with tables created with clone() */
|
||||
DBUG_PRINT("info",("file->trn: %p", file->trn));
|
||||
trnman_increment_locked_tables(file->trn);
|
||||
}
|
||||
|
||||
@ -2742,7 +2750,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
||||
}
|
||||
else
|
||||
{
|
||||
TRN *trn= THD_TRN;
|
||||
TRN *trn= (file->trn != &dummy_transaction_object ? file->trn : 0);
|
||||
/* End of transaction */
|
||||
|
||||
/*
|
||||
@ -2757,8 +2765,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
||||
*/
|
||||
if (_ma_reenable_logging_for_table(file, TRUE))
|
||||
DBUG_RETURN(1);
|
||||
/** @todo zero file->trn also in commit and rollback */
|
||||
_ma_set_trn_for_table(file, NULL); // Safety
|
||||
_ma_reset_trn_for_table(file);
|
||||
/*
|
||||
Ensure that file->state points to the current number of rows. This
|
||||
is needed if someone calls maria_info() without first doing an
|
||||
@ -2814,13 +2821,6 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
|
||||
DBUG_ASSERT(lock_type != TL_UNLOCK);
|
||||
DBUG_ASSERT(file->trn == trn);
|
||||
|
||||
/*
|
||||
If there was an implicit commit under this LOCK TABLES by a previous
|
||||
statement (like a DDL), at least if that previous statement was about a
|
||||
different ha_maria than 'this' then this->file->trn is a stale
|
||||
pointer. We fix it:
|
||||
*/
|
||||
_ma_set_trn_for_table(file, trn);
|
||||
/*
|
||||
As external_lock() was already called, don't increment locked_tables.
|
||||
Note that we call the function below possibly several times when
|
||||
@ -2845,6 +2845,23 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reset THD_TRN and all file->trn related to the transaction
|
||||
This is needed as some calls, like extra() or external_lock() may access
|
||||
it before next transaction is started
|
||||
*/
|
||||
|
||||
static void reset_thd_trn(THD *thd, MARIA_HA *first_table)
|
||||
{
|
||||
DBUG_ENTER("reset_thd_trn");
|
||||
THD_TRN= NULL;
|
||||
for (MARIA_HA *table= first_table; table ;
|
||||
table= table->trn_next)
|
||||
_ma_reset_trn_for_table(table);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Performs an implicit commit of the Maria transaction and creates a new
|
||||
one.
|
||||
@ -2868,10 +2885,10 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
||||
TRN *trn;
|
||||
int error;
|
||||
uint locked_tables;
|
||||
DYNAMIC_ARRAY used_tables;
|
||||
extern my_bool plugins_are_initialized;
|
||||
|
||||
MARIA_HA *used_tables, *trn_next;
|
||||
DBUG_ENTER("ha_maria::implicit_commit");
|
||||
|
||||
if (!maria_hton || !plugins_are_initialized || !(trn= THD_TRN))
|
||||
DBUG_RETURN(0);
|
||||
if (!new_trn && (thd->locked_tables_mode == LTM_LOCK_TABLES ||
|
||||
@ -2889,48 +2906,16 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
||||
|
||||
locked_tables= trnman_has_locked_tables(trn);
|
||||
|
||||
if (new_trn && trn && trn->used_tables)
|
||||
{
|
||||
MARIA_USED_TABLES *tables;
|
||||
/*
|
||||
Save locked tables so that we can move them to another transaction
|
||||
We are using a dynamic array as locked_tables in some cases can be
|
||||
smaller than the used_tables list (for example when the server does
|
||||
early unlock of tables.
|
||||
*/
|
||||
|
||||
my_init_dynamic_array2(&used_tables, sizeof(MARIA_SHARE*), (void*) 0,
|
||||
locked_tables, 8, MYF(MY_THREAD_SPECIFIC));
|
||||
for (tables= (MARIA_USED_TABLES*) trn->used_tables;
|
||||
tables;
|
||||
tables= tables->next)
|
||||
{
|
||||
if (tables->share->base.born_transactional)
|
||||
{
|
||||
if (insert_dynamic(&used_tables, (uchar*) &tables->share))
|
||||
{
|
||||
error= HA_ERR_OUT_OF_MEM;
|
||||
goto end_and_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
bzero(&used_tables, sizeof(used_tables));
|
||||
|
||||
used_tables= (MARIA_HA*) trn->used_instances;
|
||||
error= 0;
|
||||
if (unlikely(ma_commit(trn)))
|
||||
error= 1;
|
||||
if (!new_trn)
|
||||
{
|
||||
/*
|
||||
To be extra safe, we should also reset file->trn for all open
|
||||
tables as some calls, like extra() may access it. We take care
|
||||
of this in extra() by resetting file->trn if THD_TRN is 0.
|
||||
*/
|
||||
THD_TRN= NULL;
|
||||
reset_thd_trn(thd, used_tables);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
We need to create a new transaction and put it in THD_TRN. Indeed,
|
||||
tables may be under LOCK TABLES, and so they will start the next
|
||||
@ -2940,8 +2925,9 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
||||
THD_TRN= trn;
|
||||
if (unlikely(trn == NULL))
|
||||
{
|
||||
reset_thd_trn(thd, used_tables);
|
||||
error= HA_ERR_OUT_OF_MEM;
|
||||
goto end_and_free;
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
Move all locked tables to the new transaction
|
||||
@ -2951,35 +2937,25 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
|
||||
in check table, we use the table without calling start_stmt().
|
||||
*/
|
||||
|
||||
uint i;
|
||||
for (i= 0 ; i < used_tables.elements ; i++)
|
||||
for (MARIA_HA *handler= used_tables; handler ;
|
||||
handler= trn_next)
|
||||
{
|
||||
MARIA_SHARE *share;
|
||||
LIST *handlers;
|
||||
trn_next= handler->trn_next;
|
||||
DBUG_ASSERT(handler->s->base.born_transactional);
|
||||
|
||||
share= *(dynamic_element(&used_tables, i, MARIA_SHARE**));
|
||||
/* Find table instances that was used in this transaction */
|
||||
for (handlers= share->open_list; handlers; handlers= handlers->next)
|
||||
/* If handler uses versioning */
|
||||
if (handler->s->lock_key_trees)
|
||||
{
|
||||
MARIA_HA *handler= (MARIA_HA*) handlers->data;
|
||||
if (handler->external_ref &&
|
||||
((TABLE*) handler->external_ref)->in_use == thd)
|
||||
{
|
||||
_ma_set_trn_for_table(handler, trn);
|
||||
/* If handler uses versioning */
|
||||
if (handler->s->lock_key_trees)
|
||||
{
|
||||
if (_ma_setup_live_state(handler))
|
||||
error= HA_ERR_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
/* _ma_set_trn_for_table() will be called indirectly */
|
||||
if (_ma_setup_live_state(handler))
|
||||
error= HA_ERR_OUT_OF_MEM;
|
||||
}
|
||||
else
|
||||
_ma_set_trn_for_table(handler, trn);
|
||||
}
|
||||
/* This is just a commit, tables stay locked if they were: */
|
||||
trnman_reset_locked_tables(trn, locked_tables);
|
||||
|
||||
end_and_free:
|
||||
delete_dynamic(&used_tables);
|
||||
end:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@ -3359,10 +3335,10 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)),
|
||||
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
|
||||
|
||||
/* statement or transaction ? */
|
||||
if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
|
||||
if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
|
||||
!all)
|
||||
DBUG_RETURN(0); // end of statement
|
||||
DBUG_PRINT("info", ("THD_TRN set to 0x0"));
|
||||
THD_TRN= 0;
|
||||
reset_thd_trn(thd, (MARIA_HA*) trn->used_instances);
|
||||
DBUG_RETURN(ma_commit(trn)); // end of transaction
|
||||
}
|
||||
|
||||
@ -3379,8 +3355,7 @@ static int maria_rollback(handlerton *hton __attribute__ ((unused)),
|
||||
trnman_rollback_statement(trn);
|
||||
DBUG_RETURN(0); // end of statement
|
||||
}
|
||||
DBUG_PRINT("info", ("THD_TRN set to 0x0"));
|
||||
THD_TRN= 0;
|
||||
reset_thd_trn(thd, (MARIA_HA*) trn->used_instances);
|
||||
DBUG_RETURN(trnman_rollback_trn(trn) ?
|
||||
HA_ERR_OUT_OF_MEM : 0); // end of transaction
|
||||
}
|
||||
|
@ -195,6 +195,7 @@ public:
|
||||
private:
|
||||
DsMrr_impl ds_mrr;
|
||||
friend ICP_RESULT index_cond_func_maria(void *arg);
|
||||
friend void reset_thd_trn(THD *thd);
|
||||
};
|
||||
|
||||
#endif /* HA_MARIA_INCLUDED */
|
||||
|
@ -271,6 +271,7 @@
|
||||
#include "maria_def.h"
|
||||
#include "ma_blockrec.h"
|
||||
#include "trnman.h"
|
||||
#include "ma_trnman.h"
|
||||
#include "ma_key_recover.h"
|
||||
#include "ma_recovery_util.h"
|
||||
#include <lf.h>
|
||||
@ -7525,7 +7526,7 @@ void maria_ignore_trids(MARIA_HA *info)
|
||||
if (info->s->base.born_transactional)
|
||||
{
|
||||
if (!info->trn)
|
||||
_ma_set_trn_for_table(info, &dummy_transaction_object);
|
||||
_ma_set_tmp_trn_for_table(info, &dummy_transaction_object);
|
||||
/* Ignore transaction id when row is read */
|
||||
info->trn->min_read_from= ~(TrID) 0;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ int maria_close(register MARIA_HA *info)
|
||||
|
||||
/* Check that we have unlocked key delete-links properly */
|
||||
DBUG_ASSERT(info->key_del_used == 0);
|
||||
/* Check that file is not part of any uncommited transactions */
|
||||
DBUG_ASSERT(info->trn == 0 || info->trn == &dummy_transaction_object);
|
||||
|
||||
if (share->reopen == 1)
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "maria_def.h"
|
||||
#include "trnman.h"
|
||||
#include "ma_trnman.h"
|
||||
|
||||
/**
|
||||
writes a COMMIT record to log and commits transaction in memory
|
||||
@ -43,9 +44,9 @@ int ma_commit(TRN *trn)
|
||||
COMMIT record) and this is not an issue as
|
||||
* transaction's updates were not made visible to other transactions
|
||||
* "commit ok" was not sent to client
|
||||
Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before COMMIT
|
||||
record), which is ok too. All in all it means that "trn committed" is not
|
||||
100% equal to "COMMIT record written".
|
||||
Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before
|
||||
COMMIT record), which is ok too. All in all it means that "trn committed"
|
||||
is not 100% equal to "COMMIT record written".
|
||||
- if COMMIT record is written after trnman_commit_trn():
|
||||
if crash happens between the two, trn will be rolled back which is an
|
||||
issue (transaction's updates were made visible to other transactions).
|
||||
@ -93,7 +94,12 @@ int ma_commit(TRN *trn)
|
||||
|
||||
int maria_commit(MARIA_HA *info)
|
||||
{
|
||||
return info->s->now_transactional ? ma_commit(info->trn) : 0;
|
||||
TRN *trn;
|
||||
if (!info->s->now_transactional)
|
||||
return 0;
|
||||
trn= info->trn;
|
||||
info->trn= 0; /* checked in maria_close() */
|
||||
return ma_commit(trn);
|
||||
}
|
||||
|
||||
|
||||
@ -120,10 +126,7 @@ int maria_begin(MARIA_HA *info)
|
||||
TRN *trn= trnman_new_trn(0);
|
||||
if (unlikely(!trn))
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||
|
||||
DBUG_PRINT("info", ("TRN set to %p", trn));
|
||||
_ma_set_trn_for_table(info, trn);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
||||
_ma_decrement_open_count(info, 0);
|
||||
if (info->trn)
|
||||
{
|
||||
_ma_remove_table_from_trnman(share, info->trn);
|
||||
_ma_remove_table_from_trnman(info);
|
||||
/* Ensure we don't point to the deleted data in trn */
|
||||
info->state= info->state_start= &share->state.state;
|
||||
}
|
||||
@ -409,7 +409,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
||||
if (info->trn)
|
||||
{
|
||||
mysql_mutex_lock(&share->intern_lock);
|
||||
_ma_remove_table_from_trnman(share, info->trn);
|
||||
_ma_remove_table_from_trnman(info);
|
||||
/* Ensure we don't point to the deleted data in trn */
|
||||
info->state= info->state_start= &share->state.state;
|
||||
mysql_mutex_unlock(&share->intern_lock);
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "ma_sp_defs.h"
|
||||
#include "ma_rt_index.h"
|
||||
#include "ma_blockrec.h"
|
||||
#include "trnman.h"
|
||||
#include "ma_trnman.h"
|
||||
#include <m_ctype.h>
|
||||
#include "ma_crypt.h"
|
||||
|
||||
@ -184,7 +186,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
|
||||
if (!share->base.born_transactional) /* For transactional ones ... */
|
||||
{
|
||||
/* ... force crash if no trn given */
|
||||
_ma_set_trn_for_table(&info, &dummy_transaction_object);
|
||||
_ma_set_tmp_trn_for_table(&info, &dummy_transaction_object);
|
||||
info.state= &share->state.state; /* Change global values by default */
|
||||
}
|
||||
else
|
||||
|
@ -66,7 +66,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
trn= info->trn;
|
||||
for (tables= (MARIA_USED_TABLES*) info->trn->used_tables;
|
||||
for (tables= (MARIA_USED_TABLES*) trn->used_tables;
|
||||
tables;
|
||||
tables= tables->next)
|
||||
{
|
||||
@ -551,6 +551,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
||||
my_free(tables);
|
||||
}
|
||||
trn->used_tables= 0;
|
||||
trn->used_instances= 0;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -565,18 +566,25 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
||||
share->internal_lock must be locked when function is called
|
||||
*/
|
||||
|
||||
void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
|
||||
void _ma_remove_table_from_trnman(MARIA_HA *info)
|
||||
{
|
||||
MARIA_SHARE *share= info->s;
|
||||
TRN *trn= info->trn;
|
||||
MARIA_USED_TABLES *tables, **prev;
|
||||
MARIA_HA *handler, **prev_file;
|
||||
DBUG_ENTER("_ma_remove_table_from_trnman");
|
||||
DBUG_PRINT("enter", ("trn: %p used_tables: %p share: %p in_trans: %d",
|
||||
trn, trn->used_tables, share, share->in_trans));
|
||||
|
||||
mysql_mutex_assert_owner(&share->intern_lock);
|
||||
|
||||
if (trn == &dummy_transaction_object)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables, tables= *prev;
|
||||
tables;
|
||||
tables= *prev)
|
||||
/* First remove share from used_tables */
|
||||
for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables;
|
||||
(tables= *prev);
|
||||
prev= &tables->next)
|
||||
{
|
||||
if (tables->share == share)
|
||||
{
|
||||
@ -585,8 +593,36 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
|
||||
my_free(tables);
|
||||
break;
|
||||
}
|
||||
prev= &tables->next;
|
||||
}
|
||||
if (tables != 0)
|
||||
{
|
||||
/*
|
||||
This can only happens in case of rename of intermediate table as
|
||||
part of alter table
|
||||
*/
|
||||
DBUG_PRINT("warning", ("share: %p where not in used_tables_list", share));
|
||||
}
|
||||
|
||||
/* unlink table from used_instances */
|
||||
for (prev_file= (MARIA_HA**) &trn->used_instances;
|
||||
(handler= *prev_file);
|
||||
prev_file= &handler->trn_next)
|
||||
{
|
||||
if (handler == info)
|
||||
{
|
||||
*prev_file= info->trn_next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handler != 0)
|
||||
{
|
||||
/*
|
||||
This can only happens in case of rename of intermediate table as
|
||||
part of alter table
|
||||
*/
|
||||
DBUG_PRINT("warning", ("table: %p where not in used_instances", info));
|
||||
}
|
||||
info->trn= 0; /* Not part of trans anymore */
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -84,5 +84,5 @@ my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
|
||||
my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
|
||||
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share,
|
||||
my_bool all);
|
||||
void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn);
|
||||
void _ma_remove_table_from_trnman(MARIA_HA *info);
|
||||
void _ma_reset_history(struct st_maria_share *share);
|
||||
|
65
storage/maria/ma_trnman.h
Normal file
65
storage/maria/ma_trnman.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifndef _ma_trnman_h
|
||||
#define _ma_trnman_h
|
||||
|
||||
/**
|
||||
Sets table's trn and prints debug information
|
||||
Links table into used_instances if new_trn is not 0
|
||||
|
||||
@param tbl MARIA_HA of table
|
||||
@param newtrn what to put into tbl->trn
|
||||
*/
|
||||
|
||||
static inline void _ma_set_trn_for_table(MARIA_HA *tbl, TRN *newtrn)
|
||||
{
|
||||
DBUG_PRINT("info",("table: %p trn: %p -> %p",
|
||||
tbl, tbl->trn, newtrn));
|
||||
|
||||
/* check that we are not calling this twice in a row */
|
||||
DBUG_ASSERT(newtrn->used_instances != (void*) tbl);
|
||||
|
||||
tbl->trn= newtrn;
|
||||
/* Link into used list */
|
||||
tbl->trn_next= (MARIA_HA*) newtrn->used_instances;
|
||||
newtrn->used_instances= tbl;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Same as _ma_set_trn_for_table(), but don't link table into used_instance list
|
||||
Used when we want to temporary set trn for a table in extra()
|
||||
*/
|
||||
|
||||
static inline void _ma_set_tmp_trn_for_table(MARIA_HA *tbl, TRN *newtrn)
|
||||
{
|
||||
DBUG_PRINT("info",("table: %p trn: %p -> %p",
|
||||
tbl, tbl->trn, newtrn));
|
||||
tbl->trn= newtrn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reset TRN in table
|
||||
*/
|
||||
|
||||
static inline void _ma_reset_trn_for_table(MARIA_HA *tbl)
|
||||
{
|
||||
DBUG_PRINT("info",("table: %p trn: %p -> NULL", tbl, tbl->trn));
|
||||
tbl->trn= 0;
|
||||
}
|
||||
|
||||
#endif /* _ma_trnman_h */
|
@ -602,6 +602,7 @@ struct st_maria_handler
|
||||
{
|
||||
MARIA_SHARE *s; /* Shared between open:s */
|
||||
struct st_ma_transaction *trn; /* Pointer to active transaction */
|
||||
struct st_maria_handler *trn_next;
|
||||
MARIA_STATUS_INFO *state, state_save;
|
||||
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
|
||||
MARIA_USED_TABLES *used_tables;
|
||||
@ -862,19 +863,6 @@ struct st_maria_handler
|
||||
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
||||
#define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID)
|
||||
|
||||
/**
|
||||
Sets table's trn and prints debug information
|
||||
@param tbl MARIA_HA of table
|
||||
@param newtrn what to put into tbl->trn
|
||||
@note cast of newtrn is because %p of NULL gives warning (NULL is int)
|
||||
*/
|
||||
#define _ma_set_trn_for_table(tbl, newtrn) do { \
|
||||
DBUG_PRINT("info",("table: %p trn: %p -> %p", \
|
||||
(tbl), (tbl)->trn, (void *)(newtrn))); \
|
||||
(tbl)->trn= (newtrn); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
||||
/* Don't use to small record-blocks */
|
||||
#define MARIA_EXTEND_BLOCK_LENGTH 20
|
||||
|
@ -357,6 +357,7 @@ TRN *trnman_new_trn(WT_THD *wt)
|
||||
trn->commit_trid= MAX_TRID;
|
||||
trn->rec_lsn= trn->undo_lsn= trn->first_undo_lsn= 0;
|
||||
trn->used_tables= 0;
|
||||
trn->used_instances= 0;
|
||||
|
||||
trn->locked_tables= 0;
|
||||
trn->flags= 0;
|
||||
|
@ -46,7 +46,8 @@ struct st_ma_transaction
|
||||
LF_PINS *pins;
|
||||
WT_THD *wt;
|
||||
mysql_mutex_t state_lock;
|
||||
void *used_tables; /**< Tables used by transaction */
|
||||
void *used_tables; /**< Table shares used by transaction */
|
||||
void *used_instances; /* table files used by transaction */
|
||||
TRN *next, *prev;
|
||||
TrID trid, min_read_from, commit_trid;
|
||||
LSN rec_lsn, undo_lsn;
|
||||
|
@ -22,5 +22,5 @@ let SEARCH_PATTERN= RocksDB: Compatibility check against existing database optio
|
||||
--enable_reconnect
|
||||
--exec echo "restart" > $restart_file
|
||||
--source include/wait_until_connected_again.inc
|
||||
--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i '/hello=world/d' {}"
|
||||
--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i'' -e '/hello=world/d' {}"
|
||||
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
|
||||
|
@ -188,10 +188,76 @@ void mdev9044()
|
||||
close_cached_file(&info);
|
||||
}
|
||||
|
||||
/* 2 Reads (with my_b_fill) in cache makes second read to fail */
|
||||
void mdev10259()
|
||||
{
|
||||
int res;
|
||||
uchar buf[200];
|
||||
memset(buf, FILL, sizeof(buf));
|
||||
|
||||
diag("MDEV-10259- mysqld crash with certain statement length and order with"
|
||||
" Galera and encrypt-tmp-files=1");
|
||||
|
||||
init_io_cache_encryption();
|
||||
|
||||
res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0);
|
||||
ok(res == 0, "open_cached_file" INFO_TAIL);
|
||||
|
||||
res= my_b_write(&info, buf, sizeof(buf));
|
||||
ok(res == 0 && info.pos_in_file == 0, "200 write" INFO_TAIL);
|
||||
|
||||
res= my_b_flush_io_cache(&info, 1);
|
||||
ok(res == 0, "flush" INFO_TAIL);
|
||||
|
||||
my_off_t saved_pos= my_b_tell(&info);
|
||||
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 200, "fill" INFO_TAIL);
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 0, "fill" INFO_TAIL);
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 0, "fill" INFO_TAIL);
|
||||
|
||||
res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0);
|
||||
ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
|
||||
|
||||
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||
|
||||
ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200");
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 0, "fill" INFO_TAIL);
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 0, "fill" INFO_TAIL);
|
||||
|
||||
res= my_b_fill(&info);
|
||||
ok(res == 0, "fill" INFO_TAIL);
|
||||
|
||||
res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0);
|
||||
ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL);
|
||||
|
||||
res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0);
|
||||
ok(res == 0, "reinit READ_CACHE" INFO_TAIL);
|
||||
|
||||
ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200");
|
||||
|
||||
res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf));
|
||||
ok(res == 0 && info.pos_in_file == 0, "large read" INFO_TAIL);
|
||||
|
||||
close_cached_file(&info);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc __attribute__((unused)),char *argv[])
|
||||
{
|
||||
MY_INIT(argv[0]);
|
||||
plan(29);
|
||||
plan(46);
|
||||
|
||||
/* temp files with and without encryption */
|
||||
encrypt_tmp_files= 1;
|
||||
@ -203,6 +269,10 @@ int main(int argc __attribute__((unused)),char *argv[])
|
||||
/* regression tests */
|
||||
mdev9044();
|
||||
|
||||
encrypt_tmp_files= 1;
|
||||
mdev10259();
|
||||
encrypt_tmp_files= 0;
|
||||
|
||||
my_end(0);
|
||||
return exit_status();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user