1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä
2021-11-16 14:26:13 +02:00
31 changed files with 352 additions and 82 deletions

View File

@ -32,8 +32,8 @@ COUNT(*)=8
# Note: We only look for 00 because the 5c only served as an escape # Note: We only look for 00 because the 5c only served as an escape
# in parsing. # in parsing.
# #
# MYSQL_DUMP test tb --hex-blob | grep INSERT > MYSQL_TMP_DIR/dump.sql # MYSQL_DUMP test tb --hex-blob > MYSQL_TMP_DIR/dump.sql
FOUND 10 /00/ in dump.sql FOUND 8 /\([0-9]+,0x([1-9][0-9])*00([1-9][0-9])*\)/ in dump.sql
# #
# Ensure data consistency on mysqlbinlog replay # Ensure data consistency on mysqlbinlog replay
# #

View File

@ -114,9 +114,9 @@ SELECT COUNT(*)=8 from tb;
--echo # Note: We only look for 00 because the 5c only served as an escape --echo # Note: We only look for 00 because the 5c only served as an escape
--echo # in parsing. --echo # in parsing.
--echo # --echo #
--echo # MYSQL_DUMP test tb --hex-blob | grep INSERT > MYSQL_TMP_DIR/dump.sql --echo # MYSQL_DUMP test tb --hex-blob > MYSQL_TMP_DIR/dump.sql
--exec $MYSQL_DUMP test tb --hex-blob | grep INSERT > $MYSQL_TMP_DIR/dump.sql --exec $MYSQL_DUMP test tb --hex-blob > $MYSQL_TMP_DIR/dump.sql
--let SEARCH_PATTERN= 00 --let SEARCH_PATTERN= \([0-9]+,0x([1-9][0-9])*00([1-9][0-9])*\)
--let SEARCH_FILE= $MYSQL_TMP_DIR/dump.sql --let SEARCH_FILE= $MYSQL_TMP_DIR/dump.sql
--source include/search_pattern_in_file.inc --source include/search_pattern_in_file.inc

View File

@ -25,6 +25,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB; CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB;
INSERT INTO t1(f1) VALUES(1);
SET DEBUG_DBUG="+d,create_index_fail"; SET DEBUG_DBUG="+d,create_index_fail";
SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal"; SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal";
ALTER TABLE t1 ADD COLUMN f3 INT AS (f1) VIRTUAL, ADD INDEX(f2, f3); ALTER TABLE t1 ADD COLUMN f3 INT AS (f1) VIRTUAL, ADD INDEX(f2, f3);
@ -33,6 +34,7 @@ SET DEBUG_SYNC="now WAIT_FOR con1_go";
BEGIN; BEGIN;
SELECT * FROM t1; SELECT * FROM t1;
f1 f2 f1 f2
1 1
SET DEBUG_SYNC="now SIGNAL alter_signal"; SET DEBUG_SYNC="now SIGNAL alter_signal";
connection default; connection default;
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
@ -47,6 +49,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB; CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB;
INSERT INTO t1(f1) VALUES(1);
SET DEBUG_DBUG="+d,create_index_fail"; SET DEBUG_DBUG="+d,create_index_fail";
SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal"; SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal";
ALTER TABLE t1 ADD INDEX(f2); ALTER TABLE t1 ADD INDEX(f2);

View File

@ -29,6 +29,7 @@ DROP TABLE t1;
# new_vcol_info in index when rollback of alter happens # new_vcol_info in index when rollback of alter happens
CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB; CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB;
INSERT INTO t1(f1) VALUES(1);
SET DEBUG_DBUG="+d,create_index_fail"; SET DEBUG_DBUG="+d,create_index_fail";
SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal"; SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal";
SEND ALTER TABLE t1 ADD COLUMN f3 INT AS (f1) VIRTUAL, ADD INDEX(f2, f3); SEND ALTER TABLE t1 ADD COLUMN f3 INT AS (f1) VIRTUAL, ADD INDEX(f2, f3);
@ -47,6 +48,7 @@ SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB; CREATE TABLE t1(f1 INT, f2 INT AS (f1) VIRTUAL)ENGINE=InnoDB;
INSERT INTO t1(f1) VALUES(1);
SET DEBUG_DBUG="+d,create_index_fail"; SET DEBUG_DBUG="+d,create_index_fail";
SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal"; SET DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con1_go WAIT_FOR alter_signal";
send ALTER TABLE t1 ADD INDEX(f2); send ALTER TABLE t1 ADD INDEX(f2);

View File

@ -34,6 +34,7 @@ CREATE TABLE t1(f1 INT, f2 INT,
PRIMARY KEY(f1, f2), PRIMARY KEY(f1, f2),
UNIQUE INDEX uidx2 (f1, f2), UNIQUE INDEX uidx2 (f1, f2),
UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB; UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB;
INSERT INTO t1 VALUES(2, 2);
ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 DROP PRIMARY KEY;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
@ -66,6 +67,7 @@ test.t1 check status OK
DROP TABLE t1; DROP TABLE t1;
SET SQL_MODE= strict_trans_tables; SET SQL_MODE= strict_trans_tables;
CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB; CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done';
ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL; ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL;
connection con1; connection con1;

View File

@ -80,6 +80,7 @@ SET DEBUG_SYNC='RESET';
# #
CREATE TABLE t1 (f VARCHAR(8) CHARACTER SET latin1 COLLATE latin1_swedish_ci) CREATE TABLE t1 (f VARCHAR(8) CHARACTER SET latin1 COLLATE latin1_swedish_ci)
ENGINE=InnoDB; ENGINE=InnoDB;
INSERT INTO t1 VALUES('ZERO');
connection con1; connection con1;
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done'; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
ALTER TABLE t1 MODIFY f VARCHAR(256) COLLATE latin1_german2_ci NOT NULL; ALTER TABLE t1 MODIFY f VARCHAR(256) COLLATE latin1_german2_ci NOT NULL;
@ -96,5 +97,6 @@ ALTER TABLE t1 CHANGE f eins VARCHAR(257) COLLATE latin1_german1_ci NOT NULL,
ALGORITHM=INSTANT; ALGORITHM=INSTANT;
SELECT * FROM t1; SELECT * FROM t1;
eins eins
ZERO
one one
DROP TABLE t1; DROP TABLE t1;

View File

@ -4,6 +4,7 @@
# #
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (c CHAR(2) NOT NULL) ENGINE=InnoDB; CREATE TABLE t1 (c CHAR(2) NOT NULL) ENGINE=InnoDB;
INSERT INTO t1 VALUES('cd');
connect con1,localhost,root,,; connect con1,localhost,root,,;
BEGIN; BEGIN;
INSERT INTO t0 VALUES(1); INSERT INTO t0 VALUES(1);
@ -21,6 +22,7 @@ ERROR 23000: Duplicate entry 'a' for key 'PRIMARY'
SET DEBUG_SYNC='RESET'; SET DEBUG_SYNC='RESET';
SELECT * FROM t1; SELECT * FROM t1;
c c
cd
ab ab
ac ac
DROP TABLE t0,t1; DROP TABLE t0,t1;

View File

@ -1,5 +1,6 @@
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES(100, 100);
connect con1,localhost,root,,test; connect con1,localhost,root,,test;
BEGIN; BEGIN;
INSERT INTO t0 SET pk=1; INSERT INTO t0 SET pk=1;

View File

@ -61,7 +61,7 @@ connect con1,localhost,root,,;
BEGIN; BEGIN;
DELETE FROM mysql.innodb_table_stats; DELETE FROM mysql.innodb_table_stats;
connect con2,localhost,root,,; connect con2,localhost,root,,;
SET DEBUG_SYNC='inplace_after_index_build SIGNAL blocked WAIT_FOR ever'; SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL blocked WAIT_FOR ever';
ALTER TABLE t1 FORCE; ALTER TABLE t1 FORCE;
connection default; connection default;
SET DEBUG_SYNC='now WAIT_FOR blocked'; SET DEBUG_SYNC='now WAIT_FOR blocked';

View File

@ -81,6 +81,7 @@ COUNT(k1) k2 k3
drop table t1; drop table t1;
create table t1(k1 int auto_increment primary key, create table t1(k1 int auto_increment primary key,
k2 char(200),k3 char(200))engine=innodb; k2 char(200),k3 char(200))engine=innodb;
INSERT INTO t1 VALUES(1, "test", "test");
SET DEBUG_SYNC= 'row_merge_after_scan SET DEBUG_SYNC= 'row_merge_after_scan
SIGNAL opened WAIT_FOR flushed'; SIGNAL opened WAIT_FOR flushed';
ALTER TABLE t1 FORCE, ADD COLUMN k4 int; ALTER TABLE t1 FORCE, ADD COLUMN k4 int;
@ -100,6 +101,7 @@ SELECT COUNT(k1),k2,k3 FROM t1 GROUP BY k2,k3;
COUNT(k1) k2 k3 COUNT(k1) k2 k3
480 aaa bbb 480 aaa bbb
480 aaaa bbbb 480 aaaa bbbb
1 test test
disconnect con1; disconnect con1;
connection default; connection default;
show create table t1; show create table t1;
@ -109,7 +111,7 @@ t1 CREATE TABLE `t1` (
`k2` char(200) DEFAULT NULL, `k2` char(200) DEFAULT NULL,
`k3` char(200) DEFAULT NULL, `k3` char(200) DEFAULT NULL,
PRIMARY KEY (`k1`) PRIMARY KEY (`k1`)
) ENGINE=InnoDB AUTO_INCREMENT=1023 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=1024 DEFAULT CHARSET=latin1
drop table t1; drop table t1;
drop table t480; drop table t480;
# #
@ -117,6 +119,7 @@ drop table t480;
# in online table rebuild # in online table rebuild
# #
CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB; CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 VALUES(2, 2);
connect con1,localhost,root,,test; connect con1,localhost,root,,test;
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
ALTER TABLE t1 DROP j, FORCE; ALTER TABLE t1 DROP j, FORCE;

View File

@ -509,6 +509,7 @@ DROP TABLE t1;
# MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE # MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE
# #
CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB; CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB;
INSERT INTO t1 VALUES('foo');
SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done'; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done';
ALTER TABLE t1 ADD UNIQUE(c); ALTER TABLE t1 ADD UNIQUE(c);
connection con1; connection con1;

View File

@ -171,6 +171,7 @@ connect stop_purge,localhost,root;
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connect ddl,localhost,root,,test; connect ddl,localhost,root,,test;
DELETE FROM t1; DELETE FROM t1;
INSERT INTO t1 VALUES(1, 2);
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged';
ALTER TABLE t1 FORCE; ALTER TABLE t1 FORCE;
connection default; connection default;
@ -449,6 +450,7 @@ DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(a INT NOT NULL, b INT, c INT, d INT, e INT, f INT, g INT, h INT, i TEXT) (a INT NOT NULL, b INT, c INT, d INT, e INT, f INT, g INT, h INT, i TEXT)
ENGINE=InnoDB; ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 2, 3, 4, 5, 6, 7, 8, "test");
ALTER TABLE t1 MODIFY a INT NULL; ALTER TABLE t1 MODIFY a INT NULL;
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL alter WAIT_FOR go'; SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL alter WAIT_FOR go';
ALTER TABLE t1 ADD PRIMARY KEY (a); ALTER TABLE t1 ADD PRIMARY KEY (a);
@ -462,6 +464,7 @@ connection default;
disconnect con1; disconnect con1;
SELECT * FROM t1; SELECT * FROM t1;
a b c d e f g h i a b c d e f g h i
1 2 3 4 5 6 7 8 test
DROP TABLE t1; DROP TABLE t1;
SET DEBUG_SYNC=RESET; SET DEBUG_SYNC=RESET;
# End of 10.4 tests # End of 10.4 tests

View File

@ -24,6 +24,7 @@ CREATE TABLE t1(f1 INT, f2 INT,
PRIMARY KEY(f1, f2), PRIMARY KEY(f1, f2),
UNIQUE INDEX uidx2 (f1, f2), UNIQUE INDEX uidx2 (f1, f2),
UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB; UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB;
INSERT INTO t1 VALUES(2, 2);
ALTER TABLE t1 DROP PRIMARY KEY; ALTER TABLE t1 DROP PRIMARY KEY;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter
@ -42,6 +43,7 @@ DROP TABLE t1;
SET SQL_MODE= strict_trans_tables; SET SQL_MODE= strict_trans_tables;
CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB; CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done';
--send ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL --send ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL
connection con1; connection con1;

View File

@ -75,7 +75,7 @@ SET DEBUG_SYNC='RESET';
--echo # --echo #
CREATE TABLE t1 (f VARCHAR(8) CHARACTER SET latin1 COLLATE latin1_swedish_ci) CREATE TABLE t1 (f VARCHAR(8) CHARACTER SET latin1 COLLATE latin1_swedish_ci)
ENGINE=InnoDB; ENGINE=InnoDB;
INSERT INTO t1 VALUES('ZERO');
connection con1; connection con1;
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done'; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
send ALTER TABLE t1 MODIFY f VARCHAR(256) COLLATE latin1_german2_ci NOT NULL; send ALTER TABLE t1 MODIFY f VARCHAR(256) COLLATE latin1_german2_ci NOT NULL;

View File

@ -9,6 +9,7 @@
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (c CHAR(2) NOT NULL) ENGINE=InnoDB; CREATE TABLE t1 (c CHAR(2) NOT NULL) ENGINE=InnoDB;
INSERT INTO t1 VALUES('cd');
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
BEGIN; BEGIN;

View File

@ -4,6 +4,7 @@
CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t0 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES(100, 100);
--connect (con1,localhost,root,,test) --connect (con1,localhost,root,,test)
BEGIN; BEGIN;

View File

@ -80,7 +80,7 @@ BEGIN;
DELETE FROM mysql.innodb_table_stats; DELETE FROM mysql.innodb_table_stats;
connect (con2,localhost,root,,); connect (con2,localhost,root,,);
SET DEBUG_SYNC='inplace_after_index_build SIGNAL blocked WAIT_FOR ever'; SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL blocked WAIT_FOR ever';
send ALTER TABLE t1 FORCE; send ALTER TABLE t1 FORCE;
connection default; connection default;

View File

@ -96,6 +96,7 @@ drop table t1;
# Log file creation failure. # Log file creation failure.
create table t1(k1 int auto_increment primary key, create table t1(k1 int auto_increment primary key,
k2 char(200),k3 char(200))engine=innodb; k2 char(200),k3 char(200))engine=innodb;
INSERT INTO t1 VALUES(1, "test", "test");
SET DEBUG_SYNC= 'row_merge_after_scan SET DEBUG_SYNC= 'row_merge_after_scan
SIGNAL opened WAIT_FOR flushed'; SIGNAL opened WAIT_FOR flushed';
send ALTER TABLE t1 FORCE, ADD COLUMN k4 int; send ALTER TABLE t1 FORCE, ADD COLUMN k4 int;
@ -122,6 +123,7 @@ drop table t480;
--echo # --echo #
CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB; CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 VALUES(2, 2);
--connect (con1,localhost,root,,test) --connect (con1,localhost,root,,test)
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
--send --send

View File

@ -477,6 +477,7 @@ DROP TABLE t1;
--echo # MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE --echo # MDEV-13205 assertion !dict_index_is_online_ddl(index) upon ALTER TABLE
--echo # --echo #
CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB; CREATE TABLE t1 (c VARCHAR(64)) ENGINE=InnoDB;
INSERT INTO t1 VALUES('foo');
SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done'; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL t1u_created WAIT_FOR dup_done';
send ALTER TABLE t1 ADD UNIQUE(c); send ALTER TABLE t1 ADD UNIQUE(c);

View File

@ -186,6 +186,7 @@ connect stop_purge,localhost,root;
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connect ddl,localhost,root,,test; connect ddl,localhost,root,,test;
DELETE FROM t1; DELETE FROM t1;
INSERT INTO t1 VALUES(1, 2);
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged'; SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged';
send ALTER TABLE t1 FORCE; send ALTER TABLE t1 FORCE;
connection default; connection default;
@ -519,7 +520,7 @@ DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(a INT NOT NULL, b INT, c INT, d INT, e INT, f INT, g INT, h INT, i TEXT) (a INT NOT NULL, b INT, c INT, d INT, e INT, f INT, g INT, h INT, i TEXT)
ENGINE=InnoDB; ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 2, 3, 4, 5, 6, 7, 8, "test");
ALTER TABLE t1 MODIFY a INT NULL; ALTER TABLE t1 MODIFY a INT NULL;
SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL alter WAIT_FOR go'; SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL alter WAIT_FOR go';

View File

@ -30,6 +30,7 @@ DROP TABLE t2, t1;
# MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
# #
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB; CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "test", "test_1");
connect con1,localhost,root,,test; connect con1,localhost,root,,test;
SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter"; SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter";
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2'; SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';
@ -39,6 +40,7 @@ SET DEBUG_SYNC='now WAIT_FOR s2';
START TRANSACTION; START TRANSACTION;
SELECT * FROM t1; SELECT * FROM t1;
a b c a b c
1 test test_1
SET DEBUG_SYNC='now SIGNAL g2'; SET DEBUG_SYNC='now SIGNAL g2';
connection con1; connection con1;
ERROR HY000: Out of memory. ERROR HY000: Out of memory.

View File

@ -59,6 +59,7 @@ DROP TABLE t2, t1;
--echo # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX --echo # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
--echo # --echo #
CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB; CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "test", "test_1");
connect(con1,localhost,root,,test); connect(con1,localhost,root,,test);
SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter"; SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter";
SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2'; SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2';

View File

@ -2579,6 +2579,9 @@ public:
/** true when InnoDB should abort the alter when table is not empty */ /** true when InnoDB should abort the alter when table is not empty */
bool error_if_not_empty; bool error_if_not_empty;
/** True when DDL should avoid downgrading the MDL */
bool mdl_exclusive_after_prepare= false;
Alter_inplace_info(HA_CREATE_INFO *create_info_arg, Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
Alter_info *alter_info_arg, Alter_info *alter_info_arg,
KEY *key_info_arg, uint key_count_arg, KEY *key_info_arg, uint key_count_arg,

View File

@ -18,6 +18,14 @@
#include "sql_string.h" #include "sql_string.h"
#include "my_json_writer.h" #include "my_json_writer.h"
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
bool Json_writer::named_item_expected() const
{
return named_items_expectation.size()
&& named_items_expectation.back();
}
#endif
void Json_writer::append_indent() void Json_writer::append_indent()
{ {
if (!document_start) if (!document_start)
@ -26,9 +34,21 @@ void Json_writer::append_indent()
output.append(' '); output.append(' ');
} }
inline void Json_writer::on_start_object()
{
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
if(!fmt_helper.is_making_writer_calls())
{
VALIDITY_ASSERT(got_name == named_item_expected());
named_items_expectation.push_back(true);
}
#endif
fmt_helper.on_start_object();
}
void Json_writer::start_object() void Json_writer::start_object()
{ {
fmt_helper.on_start_object(); on_start_object();
if (!element_started) if (!element_started)
start_element(); start_element();
@ -38,10 +58,22 @@ void Json_writer::start_object()
first_child=true; first_child=true;
element_started= false; element_started= false;
document_start= false; document_start= false;
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
got_name= false;
#endif
} }
void Json_writer::start_array() void Json_writer::start_array()
{ {
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
if(!fmt_helper.is_making_writer_calls())
{
VALIDITY_ASSERT(got_name == named_item_expected());
named_items_expectation.push_back(false);
got_name= false;
}
#endif
if (fmt_helper.on_start_array()) if (fmt_helper.on_start_array())
return; return;
@ -58,6 +90,12 @@ void Json_writer::start_array()
void Json_writer::end_object() void Json_writer::end_object()
{ {
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
VALIDITY_ASSERT(named_item_expected());
named_items_expectation.pop_back();
VALIDITY_ASSERT(!got_name);
got_name= false;
#endif
indent_level-=INDENT_SIZE; indent_level-=INDENT_SIZE;
if (!first_child) if (!first_child)
append_indent(); append_indent();
@ -68,6 +106,11 @@ void Json_writer::end_object()
void Json_writer::end_array() void Json_writer::end_array()
{ {
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
VALIDITY_ASSERT(!named_item_expected());
named_items_expectation.pop_back();
got_name= false;
#endif
if (fmt_helper.on_end_array()) if (fmt_helper.on_end_array())
return; return;
indent_level-=INDENT_SIZE; indent_level-=INDENT_SIZE;
@ -80,9 +123,13 @@ void Json_writer::end_array()
Json_writer& Json_writer::add_member(const char *name) Json_writer& Json_writer::add_member(const char *name)
{ {
size_t len= strlen(name); size_t len= strlen(name);
if (fmt_helper.on_add_member(name, len)) return add_member(name, len);
return *this; // handled }
Json_writer& Json_writer::add_member(const char *name, size_t len)
{
if (!fmt_helper.on_add_member(name, len))
{
// assert that we are in an object // assert that we are in an object
DBUG_ASSERT(!element_started); DBUG_ASSERT(!element_started);
start_element(); start_element();
@ -90,21 +137,11 @@ Json_writer& Json_writer::add_member(const char *name)
output.append('"'); output.append('"');
output.append(name, len); output.append(name, len);
output.append("\": ", 3); output.append("\": ", 3);
return *this;
} }
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
Json_writer& Json_writer::add_member(const char *name, size_t len) if (!fmt_helper.is_making_writer_calls())
{ got_name= true;
if (fmt_helper.on_add_member(name, len)) #endif
return *this; // handled
// assert that we are in an object
DBUG_ASSERT(!element_started);
start_element();
output.append('"');
output.append(name, len);
output.append("\": ");
return *this; return *this;
} }
@ -200,7 +237,14 @@ void Json_writer::add_null()
void Json_writer::add_unquoted_str(const char* str) void Json_writer::add_unquoted_str(const char* str)
{ {
size_t len= strlen(str); size_t len= strlen(str);
if (fmt_helper.on_add_str(str, len)) add_unquoted_str(str, len);
}
void Json_writer::add_unquoted_str(const char* str, size_t len)
{
VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() ||
got_name == named_item_expected());
if (on_add_str(str, len))
return; return;
if (!element_started) if (!element_started)
@ -210,31 +254,19 @@ void Json_writer::add_unquoted_str(const char* str)
element_started= false; element_started= false;
} }
void Json_writer::add_unquoted_str(const char* str, size_t len) inline bool Json_writer::on_add_str(const char *str, size_t num_bytes)
{ {
if (fmt_helper.on_add_str(str, len)) #if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
return; got_name= false;
#endif
if (!element_started) bool helped= fmt_helper.on_add_str(str, num_bytes);
start_element(); return helped;
output.append(str, len);
element_started= false;
} }
void Json_writer::add_str(const char *str) void Json_writer::add_str(const char *str)
{ {
size_t len= strlen(str); size_t len= strlen(str);
if (fmt_helper.on_add_str(str, len)) add_str(str, len);
return;
if (!element_started)
start_element();
output.append('"');
output.append(str, len);
output.append('"');
element_started= false;
} }
/* /*
@ -243,7 +275,9 @@ void Json_writer::add_str(const char *str)
void Json_writer::add_str(const char* str, size_t num_bytes) void Json_writer::add_str(const char* str, size_t num_bytes)
{ {
if (fmt_helper.on_add_str(str, num_bytes)) VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() ||
got_name == named_item_expected());
if (on_add_str(str, num_bytes))
return; return;
if (!element_started) if (!element_started)

View File

@ -17,9 +17,19 @@
#define JSON_WRITER_INCLUDED #define JSON_WRITER_INCLUDED
#include "my_base.h" #include "my_base.h"
#include "sql_select.h"
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) || defined ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
#include <vector> #include <vector>
#endif
#ifdef JSON_WRITER_UNIT_TEST
#include "sql_string.h"
// Also, mock objects are defined in my_json_writer-t.cc
#define VALIDITY_ASSERT(x) if (!(x)) this->invalid_json= true;
#else
#include "sql_select.h"
#define VALIDITY_ASSERT(x) DBUG_ASSERT(x)
#endif
class Opt_trace_stmt; class Opt_trace_stmt;
class Opt_trace_context; class Opt_trace_context;
@ -99,6 +109,15 @@ public:
bool on_add_str(const char *str, size_t num_bytes); bool on_add_str(const char *str, size_t num_bytes);
/*
Returns true if the helper is flushing its buffer and is probably
making calls back to its Json_writer. (The Json_writer uses this
function to avoid re-doing the processing that it has already done
before making a call to fmt_helper)
*/
bool is_making_writer_calls() const { return state == DISABLED; }
private:
void flush_on_one_line(); void flush_on_one_line();
void disable_and_flush(); void disable_and_flush();
}; };
@ -185,6 +204,25 @@ private:
class Json_writer class Json_writer
{ {
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
/*
In debug mode, Json_writer will fail and assertion if one attempts to
produce an invalid JSON document (e.g. JSON array having named elements).
*/
std::vector<bool> named_items_expectation;
bool named_item_expected() const;
bool got_name;
#ifdef JSON_WRITER_UNIT_TEST
public:
// When compiled for unit test, creating invalid JSON will set this to true
// instead of an assertion.
bool invalid_json= false;
#endif
#endif
public: public:
/* Add a member. We must be in an object. */ /* Add a member. We must be in an object. */
Json_writer& add_member(const char *name); Json_writer& add_member(const char *name);
@ -208,6 +246,10 @@ public:
private: private:
void add_unquoted_str(const char* val); void add_unquoted_str(const char* val);
void add_unquoted_str(const char* val, size_t len); void add_unquoted_str(const char* val, size_t len);
bool on_add_str(const char *str, size_t num_bytes);
void on_start_object();
public: public:
/* Start a child object */ /* Start a child object */
void start_object(); void start_object();
@ -225,6 +267,9 @@ public:
size_t get_truncated_bytes() { return output.get_truncated_bytes(); } size_t get_truncated_bytes() { return output.get_truncated_bytes(); }
Json_writer() : Json_writer() :
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
got_name(false),
#endif
indent_level(0), document_start(true), element_started(false), indent_level(0), document_start(true), element_started(false),
first_child(true) first_child(true)
{ {
@ -312,6 +357,9 @@ public:
/* A common base for Json_writer_object and Json_writer_array */ /* A common base for Json_writer_object and Json_writer_array */
class Json_writer_struct class Json_writer_struct
{ {
Json_writer_struct(const Json_writer_struct&)= delete;
Json_writer_struct& operator=(const Json_writer_struct&)= delete;
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
static thread_local std::vector<bool> named_items_expectation; static thread_local std::vector<bool> named_items_expectation;
#endif #endif
@ -372,24 +420,18 @@ private:
my_writer->add_member(name); my_writer->add_member(name);
} }
public: public:
explicit Json_writer_object(THD *thd) explicit Json_writer_object(THD* thd, const char *str= nullptr)
: Json_writer_struct(thd, true)
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(!named_item_expected());
#endif
if (unlikely(my_writer))
my_writer->start_object();
}
explicit Json_writer_object(THD* thd, const char *str)
: Json_writer_struct(thd, true) : Json_writer_struct(thd, true)
{ {
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(named_item_expected()); DBUG_ASSERT(named_item_expected());
#endif #endif
if (unlikely(my_writer)) if (unlikely(my_writer))
my_writer->add_member(str).start_object(); {
if (str)
my_writer->add_member(str);
my_writer->start_object();
}
} }
~Json_writer_object() ~Json_writer_object()

View File

@ -370,7 +370,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
double read_time); double read_time);
static static
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
double read_time); double read_time, bool named_trace= false);
static static
TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
TRP_INDEX_MERGE *imerge_trp, TRP_INDEX_MERGE *imerge_trp,
@ -5085,7 +5085,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
static static
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
double read_time) double read_time, bool named_trace)
{ {
SEL_TREE **ptree; SEL_TREE **ptree;
TRP_INDEX_MERGE *imerge_trp= NULL; TRP_INDEX_MERGE *imerge_trp= NULL;
@ -5133,7 +5133,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
n_child_scans))) n_child_scans)))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
Json_writer_object trace_best_disjunct(thd); const char* trace_best_disjunct_obj_name= named_trace ? "best_disjunct_quick" : nullptr;
Json_writer_object trace_best_disjunct(thd, trace_best_disjunct_obj_name);
Json_writer_array to_merge(thd, "indexes_to_merge"); Json_writer_array to_merge(thd, "indexes_to_merge");
/* /*
Collect best 'range' scan for each of disjuncts, and, while doing so, Collect best 'range' scan for each of disjuncts, and, while doing so,
@ -5489,7 +5490,7 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
DBUG_ASSERT(imerge->trees_next>imerge->trees); DBUG_ASSERT(imerge->trees_next>imerge->trees);
if (imerge->trees_next-imerge->trees > 1) if (imerge->trees_next-imerge->trees > 1)
trp= get_best_disjunct_quick(param, imerge, read_time); trp= get_best_disjunct_quick(param, imerge, read_time, true);
else else
{ {
/* /*
@ -5677,7 +5678,7 @@ void print_keyparts(THD *thd, KEY *key, uint key_parts)
DBUG_ASSERT(thd->trace_started()); DBUG_ASSERT(thd->trace_started());
KEY_PART_INFO *part= key->key_part; KEY_PART_INFO *part= key->key_part;
Json_writer_array keyparts= Json_writer_array(thd, "keyparts"); Json_writer_array keyparts(thd, "keyparts");
for(uint i= 0; i < key_parts; i++, part++) for(uint i= 0; i < key_parts; i++, part++)
keyparts.add(part->field->field_name); keyparts.add(part->field->field_name);
} }

View File

@ -3827,9 +3827,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
Json_writer_array semijoin_plan(thd, "join_order"); Json_writer_array semijoin_plan(thd, "join_order");
for (i= first + sjm->tables; i <= tablenr; i++) for (i= first + sjm->tables; i <= tablenr; i++)
{ {
Json_writer_object trace_one_table(thd);
if (unlikely(thd->trace_started())) if (unlikely(thd->trace_started()))
{ {
Json_writer_object trace_one_table(thd);
trace_one_table.add_table_name(join->best_positions[i].table); trace_one_table.add_table_name(join->best_positions[i].table);
} }
best_access_path(join, join->best_positions[i].table, rem_tables, best_access_path(join, join->best_positions[i].table, rem_tables,
@ -3866,9 +3866,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
Json_writer_array semijoin_plan(thd, "join_order"); Json_writer_array semijoin_plan(thd, "join_order");
for (idx= first; idx <= tablenr; idx++) for (idx= first; idx <= tablenr; idx++)
{ {
Json_writer_object trace_one_table(thd);
if (unlikely(thd->trace_started())) if (unlikely(thd->trace_started()))
{ {
Json_writer_object trace_one_table(thd);
trace_one_table.add_table_name(join->best_positions[idx].table); trace_one_table.add_table_name(join->best_positions[idx].table);
} }
if (join->best_positions[idx].use_join_buffer) if (join->best_positions[idx].use_join_buffer)
@ -3905,9 +3905,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
Json_writer_array semijoin_plan(thd, "join_order"); Json_writer_array semijoin_plan(thd, "join_order");
for (idx= first; idx <= tablenr; idx++) for (idx= first; idx <= tablenr; idx++)
{ {
Json_writer_object trace_one_table(thd);
if (unlikely(thd->trace_started())) if (unlikely(thd->trace_started()))
{ {
Json_writer_object trace_one_table(thd);
trace_one_table.add_table_name(join->best_positions[idx].table); trace_one_table.add_table_name(join->best_positions[idx].table);
} }
if (join->best_positions[idx].use_join_buffer || (idx == first)) if (join->best_positions[idx].use_join_buffer || (idx == first))

View File

@ -8001,7 +8001,8 @@ static bool mysql_inplace_alter_table(THD *thd,
lock for prepare phase under LOCK TABLES in the same way as when lock for prepare phase under LOCK TABLES in the same way as when
exclusive lock is required for duration of the whole statement. exclusive lock is required for duration of the whole statement.
*/ */
if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK || if (!ha_alter_info->mdl_exclusive_after_prepare &&
(inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK ||
((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK ||
inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || inplace_supported == HA_ALTER_INPLACE_COPY_LOCK ||
inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK || inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK ||
@ -8009,7 +8010,7 @@ static bool mysql_inplace_alter_table(THD *thd,
inplace_supported == HA_ALTER_INPLACE_INSTANT) && inplace_supported == HA_ALTER_INPLACE_INSTANT) &&
(thd->locked_tables_mode == LTM_LOCK_TABLES || (thd->locked_tables_mode == LTM_LOCK_TABLES ||
thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) ||
alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE) alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE))
{ {
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto cleanup; goto cleanup;

View File

@ -1913,9 +1913,14 @@ innobase_fts_check_doc_id_col(
/** Check whether the table is empty. /** Check whether the table is empty.
@param[in] table table to be checked @param[in] table table to be checked
@param[in] ignore_delete_marked Ignore the delete marked
flag record
@return true if table is empty */ @return true if table is empty */
static bool innobase_table_is_empty(const dict_table_t *table) static bool innobase_table_is_empty(const dict_table_t *table,
bool ignore_delete_marked=true)
{ {
if (!table->space)
return false;
dict_index_t *clust_index= dict_table_get_first_index(table); dict_index_t *clust_index= dict_table_get_first_index(table);
mtr_t mtr; mtr_t mtr;
btr_pcur_t pcur; btr_pcur_t pcur;
@ -1953,12 +1958,16 @@ next_page:
} }
rec= page_cur_get_rec(cur); rec= page_cur_get_rec(cur);
if (rec_get_deleted_flag(rec, dict_table_is_comp(table))); if (rec_get_deleted_flag(rec, dict_table_is_comp(table)))
else if (!page_rec_is_supremum(rec))
{ {
if (ignore_delete_marked)
goto scan_leaf;
non_empty:
mtr.commit(); mtr.commit();
return false; return false;
} }
else if (!page_rec_is_supremum(rec))
goto non_empty;
else else
{ {
next_page= true; next_page= true;
@ -6764,6 +6773,7 @@ wrong_column_name:
DBUG_ASSERT(num_fts_index <= 1); DBUG_ASSERT(num_fts_index <= 1);
DBUG_ASSERT(!ctx->online || num_fts_index == 0); DBUG_ASSERT(!ctx->online || num_fts_index == 0);
DBUG_ASSERT(!ctx->online DBUG_ASSERT(!ctx->online
|| !ha_alter_info->mdl_exclusive_after_prepare
|| ctx->add_autoinc == ULINT_UNDEFINED); || ctx->add_autoinc == ULINT_UNDEFINED);
DBUG_ASSERT(!ctx->online DBUG_ASSERT(!ctx->online
|| !innobase_need_rebuild(ha_alter_info, old_table) || !innobase_need_rebuild(ha_alter_info, old_table)
@ -7582,6 +7592,20 @@ ha_innobase::prepare_inplace_alter_table(
DBUG_RETURN(false); DBUG_RETURN(false);
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->part_info == NULL) {
#endif
/* Ignore the MDL downgrade when table is empty.
This optimization is disabled for partition table. */
ha_alter_info->mdl_exclusive_after_prepare =
innobase_table_is_empty(m_prebuilt->table, false);
if (ha_alter_info->online
&& ha_alter_info->mdl_exclusive_after_prepare) {
ha_alter_info->online = false;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
}
#endif
indexed_table = m_prebuilt->table; indexed_table = m_prebuilt->table;
/* ALTER TABLE will not implicitly move a table from a single-table /* ALTER TABLE will not implicitly move a table from a single-table
@ -8366,7 +8390,9 @@ ha_innobase::inplace_alter_table(
DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter"); DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter");
if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)) { /* Ignore the inplace alter phase when table is empty */
if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)
|| ha_alter_info->mdl_exclusive_after_prepare) {
ok_exit: ok_exit:
DEBUG_SYNC(m_user_thd, "innodb_after_inplace_alter_table"); DEBUG_SYNC(m_user_thd, "innodb_after_inplace_alter_table");
DBUG_RETURN(false); DBUG_RETURN(false);

View File

@ -36,3 +36,8 @@ ADD_EXECUTABLE(mf_iocache-t mf_iocache-t.cc ../../sql/mf_iocache_encr.cc)
TARGET_LINK_LIBRARIES(mf_iocache-t mysys mytap mysys_ssl) TARGET_LINK_LIBRARIES(mf_iocache-t mysys mytap mysys_ssl)
ADD_DEPENDENCIES(mf_iocache-t GenError) ADD_DEPENDENCIES(mf_iocache-t GenError)
MY_ADD_TEST(mf_iocache) MY_ADD_TEST(mf_iocache)
# Json writer needs String which needs sql library
ADD_EXECUTABLE(my_json_writer-t my_json_writer-t.cc dummy_builtins.cc)
TARGET_LINK_LIBRARIES(my_json_writer-t sql mytap)
MY_ADD_TEST(my_json_writer)

View File

@ -0,0 +1,128 @@
/*
Copyright (c) 2021, MariaDB Corporation.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include <my_global.h>
#include <my_pthread.h>
#include <my_sys.h>
#include <stdio.h>
#include <tap.h>
/*
Unit tests for class Json_writer. At the moment there are only tests for the
"Fail an assertion if one attempts to produce invalid JSON" feature.
*/
struct TABLE;
struct JOIN_TAB;
class Json_writer;
/* Several fake objects */
class Opt_trace
{
public:
void enable_tracing_if_required() {}
void disable_tracing_if_required() {}
Json_writer *get_current_json() { return nullptr; }
};
class THD
{
public:
Opt_trace opt_trace;
};
#define JSON_WRITER_UNIT_TEST
#include "../sql/my_json_writer.h"
#include "../sql/my_json_writer.cc"
int main(int args, char **argv)
{
plan(NO_PLAN);
diag("Testing Json_writer checks");
{
Json_writer w;
w.start_object();
w.add_member("foo");
w.end_object();
ok(w.invalid_json, "Started a name but didn't add a value");
}
{
Json_writer w;
w.start_object();
w.add_ull(123);
ok(w.invalid_json, "Unnamed value in an object");
}
{
Json_writer w;
w.start_array();
w.add_member("bebebe").add_ull(345);
ok(w.invalid_json, "Named member in array");
}
{
Json_writer w;
w.start_object();
w.start_array();
ok(w.invalid_json, "Unnamed array in an object");
}
{
Json_writer w;
w.start_object();
w.start_object();
ok(w.invalid_json, "Unnamed object in an object");
}
{
Json_writer w;
w.start_array();
w.add_member("zzz");
w.start_object();
ok(w.invalid_json, "Named object in an array");
}
{
Json_writer w;
w.start_array();
w.add_member("zzz");
w.start_array();
ok(w.invalid_json, "Named array in an array");
}
{
Json_writer w;
w.start_array();
w.end_object();
ok(w.invalid_json, "JSON object end of array");
}
{
Json_writer w;
w.start_object();
w.end_array();
ok(w.invalid_json, "JSON array end of object");
}
diag("Done");
return exit_status();
}