diff --git a/packages/mysql-parser/README.md b/packages/mysql-parser/README.md index 8fcbf512c..72547801a 100644 --- a/packages/mysql-parser/README.md +++ b/packages/mysql-parser/README.md @@ -93,6 +93,8 @@ This requires `bash`, `git`, and `php`. It performs the following steps: 2. Extract SQL queries from the MySQL test files. 3. Store the queries under `data/mysql-server-query-corpus/mysql-latest.csv`. +A query that runs in SQL modes that affect the lexer has them in a second column. + ## Tests and benchmarks To run lexer and parser tests and benchmarks, use: diff --git a/packages/mysql-parser/data/mysql-server-query-corpus/mysql-latest.csv b/packages/mysql-parser/data/mysql-server-query-corpus/mysql-latest.csv index e1520837a..8a2e83474 100644 --- a/packages/mysql-parser/data/mysql-server-query-corpus/mysql-latest.csv +++ b/packages/mysql-parser/data/mysql-server-query-corpus/mysql-latest.csv @@ -1,6 +1,7 @@ "select schema_name from information_schema.schemata order by schema_name" "show tables in mysql where Tables_in_mysql != 'ndb_binlog_index'" "DROP TABLE IF EXISTS t1" +"DROP TABLE IF EXISTS t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET sql_mode = 'NO_ENGINE_SUBSTITUTION'" "CREATE TABLE t1 ( cont_nr int(11) NOT NULL auto_increment, @@ -60,6 +61,8 @@ KEY p_nr(p_nr,suffix) "INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','')" "SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie" "drop table t1" +"drop table t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop table t1",ANSI_QUOTES "CREATE TABLE t1 ( AUFNR varchar(12) NOT NULL default '', PLNFL varchar(6) NOT NULL default '', @@ -137,6 +140,7 @@ ORDER BY variable_name" "DROP TABLE global_vars" "call mtr.add_suppression(""The table 't1' is full"")" "drop table if exists t1" +"drop table if exists t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set global myisam_data_pointer_size=2" "CREATE TABLE t1 (a int auto_increment primary key not null, b longtext) ENGINE=MyISAM" "DELETE FROM t1 WHERE a=1 or a=5" @@ -156,6 +160,9 @@ ORDER BY variable_name" "KILL QUERY @thread_id" "SET DEBUG_SYNC= 'now SIGNAL cont'" "DROP TABLE t1" +"DROP TABLE t1",IGNORE_SPACE +"DROP TABLE t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE t1",NO_BACKSLASH_ESCAPES "SET DEBUG_SYNC= 'RESET'" "DROP SCHEMA IF EXISTS test_i_s" "CREATE SCHEMA test_i_s" @@ -178,6 +185,7 @@ ORDER BY variable_name" "set debug_sync='now WAIT_FOR parked'" "set debug_sync='now SIGNAL go'" "select * from t1" +"select * from t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "drop table t2" "select * from t2" "rename table t1 to t3" @@ -197,6 +205,8 @@ ORDER BY variable_name" "LOCK TABLES t1 READ, t2 WRITE" "ALTER TABLE t2 RENAME TO t3" "SELECT * FROM t1" +"SELECT * FROM t1",NO_BACKSLASH_ESCAPES +"SELECT * FROM t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "INSERT INTO t3 values (1)" "LOCK TABLES t1 READ, t3 WRITE, t3 AS a WRITE, t3 AS b READ" "ALTER TABLE t3 RENAME TO t4" @@ -238,6 +248,7 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME like '#sql%'" "SHOW EXTENDED TABLES FROM test" "SHOW EXTENDED FULL TABLES FROM test" "drop table if exists t1, t2" +"drop table if exists t1, t2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (n1 int, n2 int, n3 int, key (n1, n2, n3), key (n2, n3, n1), @@ -336,7 +347,9 @@ KEY (Host) "INSERT INTO t1 VALUES ('localhost','root'),('localhost','')" "ALTER TABLE t1 RENAME t2" "DROP TABLE t2" +"DROP TABLE t2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (a int)" +"create table t1 (a int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 ( a varchar(10) not null primary key ) engine=myisam" "create table t2 ( a varchar(10) not null primary key ) engine=merge union=(t1)" "flush tables" @@ -359,6 +372,9 @@ KEY (Host) "alter table t1 change a a text character set cp1251" "delete from t1" "show create table t1" +"show create table t1",ANSI_QUOTES +"show create table t1",IGNORE_SPACE +"show create table t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "alter table t1 DEFAULT CHARACTER SET latin1" "alter table t1 CONVERT TO CHARACTER SET latin1" "alter table t1 DEFAULT CHARACTER SET cp1251" @@ -368,6 +384,9 @@ default charset latin1 collate latin1_general_cs" "CREATE TABLE t1 (a int PRIMARY KEY, b INT UNIQUE)" "ALTER TABLE t1 DROP PRIMARY KEY" "SHOW CREATE TABLE t1" +"SHOW CREATE TABLE t1",IGNORE_SPACE +"SHOW CREATE TABLE t1",ANSI_QUOTES +"SHOW CREATE TABLE t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (a int, b int, key(a))" "insert into t1 values (1,1), (2,2)" "alter table t1 drop key a" @@ -789,6 +808,8 @@ COMMIT "alter table t1 algorithm=inplace, rename key kkkk to k, alter column i set default 100" "alter table t2 algorithm=inplace, rename key kkkk to k, alter column i set default 100" "drop table t1, t2" +"drop table t1, t2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop table t1, t2",ANSI_QUOTES "create table t1 (i int, key k(i)) engine=innodb" "alter table t1 algorithm=copy, rename key kk to kkk" "create table t1 ( a int, b int, c int, d int, @@ -838,6 +859,7 @@ ON I.INDEX_ID = F.INDEX_ID AND I.TABLE_ID = T.TABLE_ID WHERE T.NAME = 'test/t1' ORDER BY I.NAME, F.NAME" "SET @orig_sql_mode = @@sql_mode" "SET sql_mode= ''" +"SET sql_mode= ''",ANSI_QUOTES "CREATE TABLE t1(fld1 VARCHAR(767), KEY a(fld1)) charset latin1 ENGINE= INNODB ROW_FORMAT=COMPACT" "ALTER TABLE t1 CHANGE fld1 fld1 VARCHAR(768), ALGORITHM= INPLACE" @@ -870,6 +892,7 @@ ENGINE=INNODB" "CREATE TABLE t (i int) TABLESPACE s ENGINE InnoDB" "ALTER TABLE t TABLESPACE s" "DROP TABLE t" +"DROP TABLE t","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP TABLESPACE s" "CREATE TABLE t1 (f1 INT)" "ALTER TABLE t1 CHARACTER SET utf8mb3, CHARACTER SET utf8mb3" @@ -945,6 +968,7 @@ KEY nameloc (name(64)) "CREATE TABLE t2 (fk INT, FOREIGN KEY (fk) REFERENCES t1 (pk)) ENGINE=InnoDB" "ALTER TABLE t2 ADD COLUMN j INT, RENAME TO t3, ALGORITHM=INPLACE" "SHOW CREATE TABLE t3" +"SHOW CREATE TABLE t3",IGNORE_SPACE "CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=0" "ALTER TABLE t1 ADD COLUMN j INT, RENAME TO t4, ALGORITHM=INPLACE" "SELECT trigger_name, event_object_schema, event_object_table, action_statement @@ -988,6 +1012,7 @@ ST_PointFromText('POINT(10 10)'))" "INSERT INTO t1 VALUES(1,'abcd',1.234)" "CREATE TABLE t2(a INT, b VARCHAR(30), c FLOAT) ENGINE=MyIsam" "SHOW CREATE TABLE t2" +"SHOW CREATE TABLE t2",IGNORE_SPACE "INSERT INTO t2 VALUES(1,'abcd',1.234)" "ALTER TABLE t1 RENAME COLUMN a TO a" "ALTER TABLE t1 RENAME COLUMN a TO m" @@ -1069,6 +1094,7 @@ ADD COLUMN d DATE GENERATED ALWAYS AS (NULL) VIRTUAL NOT NULL" "ALTER TABLE t1 CONVERT TO CHARACTER SET utf16 COLLATE utf16_turkish_ci, DEFAULT CHARACTER SET utf16 COLLATE utf16_slovak_ci" "SET SQL_MODE=''" +"SET SQL_MODE=''",IGNORE_SPACE "CREATE TABLE t1 SELECT 100000000000000000000000000000000000000000000000000000000000000001 AS c1" "ALTER TABLE t1 ADD INDEX (c1)" "SET SQL_MODE=default" @@ -1110,6 +1136,7 @@ fld3 INT GENERATED ALWAYS AS (-fld1) STORED)" "SELECT LENGTH(my_t2_fld1) FROM t2" "SELECT LENGTH(my_t3_fld1) FROM t3" "DROP TABLE t1, t2, t3" +"DROP TABLE t1, t2, t3",IGNORE_SPACE "SET GLOBAL max_allowed_packet=default" "CREATE TABLE t1(c1 VARCHAR(512) CHARSET SWE7)" "ALTER TABLE t1 MODIFY COLUMN c1 VARCHAR(512) CHARSET BINARY, @@ -1428,10 +1455,13 @@ INDEX b (b) ('a7', 'b7', POINT(0, 0))" "SHOW INDEXES FROM t2" "set @@sql_mode=""ANSI""" +"select @@sql_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select @@sql_mode" -"SELECT 'A' || 'B'" -"CREATE TABLE t1 (id INT, id2 int)" -"SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id" +"select @@sql_mode",ANSI_QUOTES +"SELECT 'A' || 'B'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (id INT, id2 int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @@SQL_MODE=""""","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@SQL_MODE=""""" "CALL mtr.add_suppression(""Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"")" "DROP TABLE if exists t1,t2,t3,t4,t5,t6" @@ -2934,6 +2964,7 @@ PRIMARY KEY USING HASH (dummyKey) ) engine=archive" "INSERT INTO t1 VALUES (NULL, ""red"")" "INSERT INTO t1 VALUES (NULL, ""yellow"")" "SET @org_mode=@@sql_mode" +"SET @org_mode=@@sql_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@sql_mode='NO_DIR_IN_CREATE'" "SELECT @@sql_mode" "set @@sql_mode=@org_mode" @@ -2963,6 +2994,7 @@ PRIMARY KEY USING HASH (dummyKey) ) engine=archive" "CREATE USER 'plug_user' IDENTIFIED WITH 'test_plugin_server' AS 'plug_user'" "GRANT REPLICATION SLAVE ON *.* TO plug_user" "FLUSH PRIVILEGES" +"FLUSH PRIVILEGES","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CHANGE REPLICATION SOURCE TO SOURCE_USER= 'plug_user', SOURCE_PASSWORD= 'plug_user', @@ -3119,6 +3151,7 @@ key (rowid), unique(val))" "CREATE TABLE t1 (pk INT AUTO_INCREMENT, PRIMARY KEY (pk))" "INSERT INTO t1 VALUES (NULL), (-1), (NULL)" "CREATE TABLE t1 (pk BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY (pk))" +"SHOW DATABASES" "create table t1(n int not null, key(n)) delay_key_write = 1" "select count(distinct n) from t1" "explain select count(distinct n) from t1" @@ -3454,7 +3487,9 @@ PRIMARY KEY (id,lang) "INSERT INTO t1 VALUES (32, 'en', 'yyyyyyy')" "SELECT * FROM t1 WHERE id=32" "USE test" +"USE test","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP TABLE IF EXISTS t1, t2" +"DROP TABLE IF EXISTS t1, t2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE t1 (c1 TINYBLOB, c2 BLOB, c3 MEDIUMBLOB, @@ -3500,8 +3535,12 @@ POINT(1, 1))" "SELECT * FROM t1 where (1 AND a)=1" "SELECT * FROM t1 where (1 AND a) IS NULL" "set sql_mode='high_not_precedence'" +"select * from t1 where not a between 2 and 3",HIGH_NOT_PRECEDENCE "select * from t1 where not a between 2 and 3" +"set sql_mode=default",HIGH_NOT_PRECEDENCE "set sql_mode=default" +"set sql_mode=default",ANSI_QUOTES +"set sql_mode=default","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select a, a is false, a is true, a is unknown from t1" "select a, a is not false, a is not true, a is not unknown from t1" "SET @a=0, @b=0" @@ -3753,6 +3792,7 @@ join t2 on t1.a=t2.c where b=11120436154190595086 order by d" "CREATE TABLE t1(a YEAR)" "SELECT 1 FROM t1 WHERE a=1 AND CASE 1 WHEN a THEN 1 ELSE 1 END" "set @@sql_mode=''" +"set @@sql_mode=''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE t1(c1 SET('','')CHARACTER SET ucs2) engine=innodb" "INSERT INTO t1 VALUES(990101.102)" "SELECT COALESCE(c1)FROM t1 ORDER BY 1" @@ -3819,6 +3859,7 @@ WHERE c >= 0" FROM t00 LEFT JOIN t01 USING(a) WHERE f(t01.a) >= 0" "DROP FUNCTION f" +"DROP FUNCTION f","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP VIEW v0, v1, v2" "DROP TABLE t00, t01" "CREATE TABLE t (i1 INT, @@ -4334,6 +4375,7 @@ WHERE (table3.col_char_key < table2.col_datetime_key)" "SET @invalid_datetime = '2000-02-31 00:00:00.000000'" "SET @bad_datetime = 'YYYY-MM-DD HH:MM:SS.ffffff'" "SET SQL_MODE=DEFAULT" +"SET SQL_MODE=DEFAULT","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT CAST('0000-00-00' AS DATE) AS d1, CAST(@zero_date AS DATE) AS d2, CAST('0000-00-00 00:00:00.000000' AS DATETIME(6)) AS dt1, @@ -4444,6 +4486,7 @@ AND a = (SELECT 1 FROM t)" "CREATE FUNCTION f7 ( a NCHAR ) RETURNS INT RETURN 1" "CREATE FUNCTION f8 ( a NVARCHAR(1) ) RETURNS INT RETURN 1" "DROP FUNCTION f1" +"DROP FUNCTION f1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION f2" "DROP FUNCTION f3" "DROP FUNCTION f4" @@ -4575,6 +4618,7 @@ val varchar(32) NOT NULL) collate utf8mb4_sv_0900_ai_ci" "Create view v1 as Select * from t1" "Check Table v1,t2" "drop view v1" +"drop view v1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "LOCK TABLE t1 WRITE" "SET lock_wait_timeout= 1" "CREATE TABLE t1(i INT)" @@ -4790,6 +4834,17 @@ f2 int, CHECK(f2 BETWEEN 100 AND 450))" "CREATE PROCEDURE proc() SELECT 1" "DROP PROCEDURE proc" "SET @v = 10" +"CREATE TABLE t1 ( +c1 BIT(7) CHECK(c1 < B'1111100'), +c2 BOOLEAN CHECK(c2 > 0), +c3 TINYINT CHECK(c3 > 10), +c4 SMALLINT CHECK(c4 > 10), +c5 MEDIUMINT CHECK(c5 > 10), +c6 INT CHECK(c6 > 10), +c7 BIGINT CHECK(c7 > 10), +c8 DECIMAL(6,2) CHECK(c8 > 10.1), +c9 FLOAT(6,2) CHECK(c9 > 10.1), +c10 DOUBLE(6,2) CHECK(c10 > 10.1))" "INSERT INTO t1(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10) VALUES(B'1111000',1,11,11,11,11,11,10.2,10.2,10.2)" "CREATE TABLE t1(c1 CHAR(1) CHECK(c1 > 'a'), @@ -5137,12 +5192,14 @@ MODIFY COLUMN col timestamp" "REPLACE INTO tst(id, col) VALUES (2, '2019-05-20 12:12:12')" "CREATE TABLE tmp(id INT, col TIMESTAMP)" "INSERT INTO tmp VALUES(3, '2019-05-06 12:12:12')" +"ALTER TABLE tst MODIFY COLUMN scol timestamp ON UPDATE CURRENT_TIMESTAMP" "CREATE TABLE tst1 (id INT, col timestamp DEFAULT('2019-05-21 12:12:12'))" "SHOW CREATE TABLE tst1" "INSERT INTO tst1(id) VALUES(1)" "DELETE FROM tst1" "ALTER TABLE tst MODIFY COLUMN scol datetime DEFAULT(CURRENT_TIMESTAMP()), MODIFY COLUMN col datetime" +"ALTER TABLE tst MODIFY COLUMN scol datetime ON UPDATE CURRENT_TIMESTAMP" "ALTER TABLE tst1 MODIFY COLUMN col datetime DEFAULT('2019-05-21 12:12:12')" "DROP TABLE tmp, tst, tst1" "SET TIME_ZONE=DEFAULT" @@ -5236,6 +5293,7 @@ ADD CONSTRAINT t1_chk_1 CHECK (f11 < 10)" "SELECT @@global.default_tmp_storage_engine" "SELECT @@session.default_tmp_storage_engine" "CREATE TEMPORARY TABLE t1(a INT)" +"CREATE TEMPORARY TABLE t1(a INT)",IGNORE_SPACE "CREATE TABLE t2(i INT) ENGINE=MYISAM" "CHECK TABLE t2 FOR UPGRADE" "ALTER TABLE t2 CHANGE COLUMN i j INT, ALGORITHM=INPLACE" @@ -5579,10 +5637,13 @@ END" "ALTER TABLE t1 ADD COLUMN c11 INTEGER COMMENT 'ABCDEfghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdABCDEfghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdABCDEfghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd'" "set sql_mode='TRADITIONAL'" "set sql_mode=''" +"set sql_mode=''",PIPES_AS_CONCAT +"set sql_mode=''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "ALTER TABLE t1 ADD COLUMN c12 CHAR(100) COMMENT 'ABCDefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd'" "create table t1 (c1 VARCHAR(10) NOT NULL COMMENT 'Abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd', c2 INTEGER COMMENT 'aBcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdaBcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd',c3 INTEGER COMMENT '012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', c4 INTEGER, c5 INTEGER, c6 INTEGER, c7 INTEGER, INDEX i1 (c1) COMMENT 'i1 comment',INDEX i2(c2) ) COMMENT='ABCDEFGHIJabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd'" "SET sql_mode=''" +"SET sql_mode=''",NO_BACKSLASH_ESCAPES "CREATE TABLE t1_toupg (c1 INT, c2 VARCHAR(10) COMMENT '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234') COMMENT='abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcde'" @@ -5847,8 +5908,11 @@ END" "CREATE PROCEDURE p2() DELETE FROM temp_t2" "SELECT f2()" "CALL p2()" +"CALL p2()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE p1" +"DROP PROCEDURE p1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE p2" +"DROP PROCEDURE p2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE VIEW v1 AS SELECT a FROM t1" "LOCK TABLE t1 READ" "DROP TABLE temp_t2, t1" @@ -5861,6 +5925,7 @@ BEGIN DECLARE only INT DEFAULT 1; END" "CALL p1()" +"CALL p1()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "XA START 'test1'" "XA END 'test1'" "XA PREPARE 'test1'" @@ -5875,6 +5940,7 @@ SET SESSION TRANSACTION READ ONLY; RETURN 1; END" "SELECT f1()" +"SELECT f1()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1() RETURNS INT BEGIN SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY; @@ -6125,6 +6191,7 @@ FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE" "SET @save_optimizer_switch= @@optimizer_switch" "SET @@optimizer_switch= 'semijoin=off'" "CREATE TABLE t1 (a INT)" +"CREATE TABLE t1 (a INT)",IGNORE_SPACE "CREATE TABLE t2 (b INT)" "INSERT INTO t2 VALUES (1), (2), (3)" "SELECT * FROM t1 WHERE a IN (SELECT * FROM ( @@ -6174,6 +6241,7 @@ WHERE user='must_change' and host = 'localhost'" "DROP USER must_change@localhost" "CREATE USER wl6587@localhost IDENTIFIED BY 'wl6587'" "ALTER USER wl6587@localhost PASSWORD EXPIRE" +"DROP USER wl6587@localhost" "SHOW STATUS LIKE 'Aborted_connects'" "CREATE USER 'new1'@'localhost'" "DROP USER 'new1'@'localhost'" @@ -6989,6 +7057,7 @@ return 0" "drop view имя_вью_кодировке_утф8_длиной_больше_чем_42" "drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48" "drop function if exists f1" +"drop function if exists f1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE IF NOT EXISTS sp1() BEGIN END" "CREATE FUNCTION IF NOT EXISTS sf1() RETURNS INT DETERMINISTIC return 0" "DROP FUNCTION sf1" @@ -7004,6 +7073,7 @@ return 0" "INSERT INTO t3 VALUES (0)" "SET sql_mode = TRADITIONAL" "SET sql_mode = ''" +"SET sql_mode = ''",NO_BACKSLASH_ESCAPES "create table `about:text` ( _id int not null auto_increment, `about:text` varchar(255) not null default '', @@ -9171,6 +9241,7 @@ name varchar(64) "CREATE INDEX i1 ON t1 (s1)" "CREATE TABLE t1 ENGINE=FALCON AS SELECT repeat('a', 5) AS s1 LIMIT 0" "SET sql_mode=DEFAULT" +"SET sql_mode=DEFAULT",PIPES_AS_CONCAT "CREATE TABLE t1 ENGINE=MARIA AS SELECT repeat('a', 5) AS s1 LIMIT 0" "CREATE TABLE t2(colours SET('red','blue','yellow'))CHARACTER SET latin2 COLLATE latin2_czech_cs" @@ -15272,6 +15343,7 @@ WHERE SCHEMA_NAME = 's'" "UPDATE mysql.schemata SET options = 'abc' WHERE name = 's'" "SELECT options FROM mysql.schemata WHERE name = 's'" "DROP SCHEMA s" +"DROP SCHEMA s",ANSI_QUOTES "CREATE TABLE time_zone(f1 INT PRIMARY KEY) ENGINE=MyISAM" "INSERT INTO time_zone VALUES (10)" "SET SESSION DEBUG=""+d,simulate_kill_query_on_open_table""" @@ -16898,6 +16970,7 @@ INDEX(a), INDEX(b), INDEX(c)) engine=myisam" "CREATE DATABASE wl7766" "USE wl7766" "SET @@session.session_track_schema=ON" +"SET @@session.session_track_schema=ON","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@session.session_track_system_variables='*'" "SET @@session.session_track_state_change=ON" "CREATE PROCEDURE t1_sel() @@ -17091,9 +17164,11 @@ end" "drop procedure if exists p" "drop function if exists f" "set sql_mode=pipes_as_concat" +"select 2 || 3",PIPES_AS_CONCAT "select 2 || 3" +"select 2 or 3",PIPES_AS_CONCAT "select 2 or 3" -"select concat(2,3)" +"select concat(2,3)",PIPES_AS_CONCAT "create table t1 (v varchar(10) binary)" "create table t1 (v varchar(10) character set latin1 binary)" "create table t1 (v varchar(10) binary character set latin1)" @@ -18604,6 +18679,7 @@ ON dtaa.c or w""" "INSERT INTO t1 VALUES (123)" "SELECT * FROM t1 LEFT JOIN ( SELECT 1 FROM t1 ) d1 ON TRUE ORDER BY a" "SET sql_mode=""""" +"SET sql_mode=""""","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT ( SELECT 1 FROM ( SELECT avg(1) FROM t1 @@ -18701,6 +18777,8 @@ FROM t0 AS a0" "ANALYZE TABLE t0, t1" "SET optimizer_switch=""derived_merge=off,derived_condition_pushdown=on""" "set sql_mode=""""" +"set sql_mode=""""",ANSI_QUOTES +"set sql_mode=""""","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @p1 = 3" "DROP PREPARE p" "SET @p1 = 1" @@ -19231,6 +19309,7 @@ ON *.* FROM normal_user" "DROP TRIGGER trig1" "CREATE USER dummy" "DROP USER u1" +"DROP USER u1",NO_BACKSLASH_ESCAPES "RENAME USER dummy to u1" "DROP USER normal_user, power_user" "CREATE USER ABC" @@ -19572,6 +19651,8 @@ default NULL)" "SELECT DISTINCT fruit_id, fruit_name INTO OUTFILE '../../tmp/data1.tmp' FROM t1 WHERE fruit_name = 'APPLE'" "LOAD DATA INFILE '../../tmp/data1.tmp' INTO TABLE t2" +"SELECT DISTINCT @v19:= fruit_id, @v20:= fruit_name INTO OUTFILE +'../../tmp/data2.tmp' FROM t1 WHERE fruit_name = 'APPLE'" "LOAD DATA INFILE '../../tmp/data2.tmp' INTO TABLE t2" "SELECT @v19, @v20" "INSERT INTO t1 VALUES('A'), (0)" @@ -19766,8 +19847,8 @@ from t1 t1_outer" `$$$` int, id$$$ int, 1$ int, `$$` int, _$ int, b$$lit$$ int)" "select `$1`, `$$$`,`$$id`, '$someli$teral' from t where t.`$id` = 0" "SET sql_mode = sys.LIST_ADD(@@sql_mode, 'ANSI_QUOTES')" -"select ""$id2"", ""$$$"" from t where t.""$id"" = 0" -"SET sql_mode = sys.LIST_DROP(@@sql_mode, 'ANSI_QUOTES')" +"select ""$id2"", ""$$$"" from t where t.""$id"" = 0",ANSI_QUOTES +"SET sql_mode = sys.LIST_DROP(@@sql_mode, 'ANSI_QUOTES')",ANSI_QUOTES "select * from t where t.`$id` = 0 or `$id2` = 0 or b$$lit$$ = 0" "select id+$id+$id from t" "create view $view as select id, $id2 from t" @@ -20062,6 +20143,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 )" "set debug='d,bug19656296'" "SET debug= DEFAULT" "set sql_mode='traditional'" +"set sql_mode='traditional'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0)))" "INSERT INTO t1 VALUES(2),(3)" "CREATE TABLE t1( a INT )" @@ -20079,6 +20161,7 @@ return 2; end" "show status like 'Com_insert'" "drop function f1" +"drop function f1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "drop function f2" "CREATE TABLE t1(c1 BINARY(10), c2 BINARY(10), c3 BINARY(10), PRIMARY KEY(c1,c2,c3))" @@ -20357,23 +20440,27 @@ NOW() + INTERVAL 1 SECOND ON COMPLETION NOT PRESERVE DO SELECT 1" "create event e_55 on schedule at 20000101000000 do drop table t" "show events" "set global event_scheduler= on" +"set global event_scheduler= on","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set @old_sql_mode:=@@sql_mode" "set sql_mode=ansi" -"select get_lock('test_bug16407', 60)" +"select get_lock('test_bug16407', 60)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create event e_16407 on schedule every 60 second do begin select get_lock('test_bug16407', 60); -end" +end","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select /*1*/ user, host, db, info from information_schema.processlist -where state = 'User lock' and info = 'select get_lock(\'test_bug16407\', 60)'" -"select release_lock('test_bug16407')" +where state = 'User lock' and info = 'select get_lock(\'test_bug16407\', 60)'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select release_lock('test_bug16407')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set global event_scheduler= off","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set global event_scheduler= off" +"select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name" "alter event e_16407 do select 1" "drop event e_16407" "set sql_mode=""ansi""" -"select get_lock('ee_16407_2', 60)" -"set global event_scheduler= 1" +"select get_lock('ee_16407_2', 60)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set global event_scheduler= 1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set sql_mode=""traditional""","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set sql_mode=""traditional""" "create table events_smode_test(ev_name char(10), a date)" "create event ee_16407_2 on schedule every 60 second do @@ -20406,7 +20493,7 @@ where state = 'User lock' and info = 'select get_lock(\'ee_16407_2\', 60)'" "drop event ee_16407_4" "delete from events_test.events_smode_test" "set sql_mode='ansi'" -"select get_lock('ee_16407_5', 60)" +"select get_lock('ee_16407_5', 60)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create procedure ee_16407_5_pendant() begin insert into events_test.events_smode_test values('ee_16407_5','2001-02-29'); end" "create procedure ee_16407_6_pendant() begin insert into events_test.events_smode_test values('ee_16407_6','2004-02-29'); end" "create event ee_16407_5 on schedule every 60 second do @@ -20435,6 +20522,7 @@ where state = 'User lock' and info = 'select get_lock(\'ee_16407_5\', 60)'" "delete from mysql.user where User like 'mysqltest_%'" "delete from mysql.db where User like 'mysqltest_%'" "flush privileges" +"flush privileges","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create user mysqltest_user1@localhost" "create database mysqltest_db1" "grant event on events_test.* to mysqltest_user1@localhost" @@ -20900,6 +20988,12 @@ ON COMPLETION PRESERVE ENABLE DO INSERT INTO s.modes VALUES (now(), @@SESSION.sql_mode, @@GLOBAL.sql_mode)" +"CREATE EVENT s.ev +ON SCHEDULE EVERY 1 SECOND +ON COMPLETION PRESERVE +ENABLE +DO +INSERT INTO s.modes VALUES (now(), @@SESSION.sql_mode, @@GLOBAL.sql_mode)",ANSI_QUOTES "SELECT data FROM performance_schema.error_log WHERE error_code=@err_code @@ -20912,14 +21006,15 @@ AND logged>@pfs_errlog_latest LIMIT 3" "SET @@GLOBAL.sql_mode = 'ANSI_QUOTES'" "TRUNCATE s.modes" +"TRUNCATE s.modes",ANSI_QUOTES "DROP EVENT s.ev" "SET @@SESSION.sql_mode = 'ANSI_QUOTES'" "SELECT data FROM performance_schema.error_log WHERE error_code=@err_code -ORDER BY logged DESC LIMIT 1" -"SET @@GLOBAL.sql_mode = DEFAULT" -"SET @@global.debug=""-d,log_event_query_string""" +ORDER BY logged DESC LIMIT 1",ANSI_QUOTES +"SET @@GLOBAL.sql_mode = DEFAULT",ANSI_QUOTES +"SET @@global.debug=""-d,log_event_query_string""",ANSI_QUOTES "CREATE DATABASE events_conn1_test2" "CREATE TABLE events_test.fill_it1(test_name varchar(20), occur datetime)" "CREATE TABLE events_test.fill_it2(test_name varchar(20), occur datetime)" @@ -23237,6 +23332,7 @@ SELECT * FROM t2" "DROP USER user6@localhost" "DROP USER user7@localhost" "DROP PROCEDURE p3" +"DROP PROCEDURE p3","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP DATABASE wl8910db" "CREATE TABLE t1 ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY @@ -25064,6 +25160,7 @@ dt2 DATETIME(6))" "EXPLAIN SELECT * FROM (SELECT UNCOMPRESSED_LENGTH(c1) FROM t1) AS s" "SELECT UNCOMPRESS( CAST( 0 AS BINARY(5) ) )" "DROP PROCEDURE IF EXISTS p1" +"DROP PROCEDURE IF EXISTS p1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL )" "INSERT INTO t1 VALUES (1413006,'idlfmv'), (1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd')" @@ -25722,8 +25819,11 @@ IS NULL" "SELECT statement_digest( ""LOCK TABLE t1 READ"" ) IS NULL" "SET sql_mode = 'PIPES_AS_CONCAT'" "SELECT statement_digest( "" CREATE ALGORITHM = MERGE VIEW v1 AS "" || -""SELECT a FROM ( SELECT a1 FROM v2 ) AS SELECT1"" )" +""SELECT a FROM ( SELECT a1 FROM v2 ) AS SELECT1"" )",PIPES_AS_CONCAT +"SET sql_mode = DEFAULT",PIPES_AS_CONCAT +"SET sql_mode = DEFAULT",NO_BACKSLASH_ESCAPES "SET sql_mode = DEFAULT" +"SET sql_mode = DEFAULT","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "TRUNCATE TABLE performance_schema.events_statements_summary_by_digest" "SELECT DIGEST_TEXT FROM performance_schema.events_statements_summary_by_digest @@ -27447,7 +27547,7 @@ _utf8mb4'abc' LIKE _utf8mb4'a\\bc' ESCAPE _utf8mb4'' AS col2, _latin1'abc' LIKE _latin1'a\\bc' ESCAPE _ascii'' AS col3" "SET sql_mode = CONCAT(@@sql_mode, ',NO_BACKSLASH_ESCAPES')" "SELECT _latin1'a\bc' LIKE _latin1'a\%' AS col1, -_utf8mb4'a\bc' LIKE _utf8mb4'a\%' AS col2" +_utf8mb4'a\bc' LIKE _utf8mb4'a\%' AS col2",NO_BACKSLASH_ESCAPES "CREATE TABLE t1(c1 VARCHAR(20) NOT NULL)" "INSERT INTO t1 VALUES ('100'), ('abc\\d')" "SELECT * FROM t1 WHERE c1 LIKE c1" @@ -28008,6 +28108,7 @@ VALUES ('1.2.3.4', '1.2.3.4', '1.2.3.4', '1.2.3.4')" start_ts DATETIME, end_ts DATETIME, start_cached INTEGER, end_cached INTEGER)" "CREATE TABLE t1 (f1 BIGINT)" +"CREATE TABLE t1 (f1 BIGINT)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT @aux1 AS ""Expect 1""" "DROP TEMPORARY TABLE t_history" "create table t1 select INET_ATON('255.255.0.1') as `a`" @@ -29918,6 +30019,7 @@ GROUP BY field1 WITH ROLLUP "SELECT _utf8mb4 'ss' = _utf8mb3 'ß' AS c" "SELECT _utf8mb3 'ß' = _utf8mb4 'ss' AS c" "SET @@sql_mode=''" +"SET @@sql_mode=''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DO SPACE(SHA(UUID_SHORT()))" "SET @@sql_mode = default" "CREATE TABLE t1 ( @@ -31590,6 +31692,7 @@ DROP TABLE t1, t2, t3; end " "call p1()" +"call p1()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE t(f1 INT)" "PREPARE stmt1 FROM 'CREATE TABLE t1(f1 INT, f2 INT)'" "PREPARE stmt2 FROM 'CREATE TABLE t2 AS SELECT * FROM t'" @@ -32064,6 +32167,7 @@ WHERE event_name LIKE '%COND_open' INTO @first_wait_id" "SET DEBUG_SYNC= 'get_share_after_destroy HIT_LIMIT 1'" "SET DEBUG_SYNC= 'now WAIT_FOR del_TB1'" "SET DEBUG_SYNC= 'now WAIT_FOR open_TB2'" +"SET SESSION debug= '-d,set_open_table_err'" "DROP TABLE tb" "SET DEBUG_SYNC= 'get_share_before_open SIGNAL open_TB1 \ WAIT_FOR cont_TB1 HIT_LIMIT 2'" @@ -34752,6 +34856,7 @@ SPATIAL KEY coord (geom) "set sql_mode=ansi_quotes" "set sql_quote_show_create=0" "set sql_mode=""ansi_quotes""" +"set sql_quote_show_create=1",ANSI_QUOTES "set sql_quote_show_create=1" "revoke all privileges, grant option from drop_user@localhost" "show grants for drop_user@localhost" @@ -34856,6 +34961,7 @@ drop_user4@localhost" "create table mysqltest_2.t1 select 1 c, 2 s" "create table mysqltest_2.t2 select 1 d, 2 t" "create user mysqltest_3@localhost" +"create user mysqltest_3@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost" "grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost" "grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost" @@ -35019,6 +35125,7 @@ INDEX(`int_field`) "GRANT DROP ON mysqltest1.t1 TO mysqltest_1@localhost" "GRANT ALTER ON mysqltest1.t1 TO mysqltest_1@localhost" "GRANT INSERT, CREATE ON mysqltest1.t1 TO mysqltest_1@localhost" +"GRANT INSERT, SELECT, CREATE, ALTER, DROP ON mysqltest1.t2 TO mysqltest_1@localhost" "DROP TABLE mysqltest1.t2" "RENAME TABLE t2 TO t1" "ALTER TABLE t2 RENAME TO t1" @@ -35287,7 +35394,6 @@ END ;" "CREATE DATABASE secret" "CREATE USER 'untrusted'@localhost" "GRANT USAGE ON *.* TO 'untrusted'@localhost" -"SHOW DATABASES" "DROP USER 'untrusted'@localhost" "DROP DATABASE secret" "CREATE USER foo@'127.0.0.1'" @@ -35308,7 +35414,9 @@ END ;" "SELECT password_lifetime FROM mysql.user where user='wl7131'" "UPDATE mysql.user SET password_last_changed = (now() - INTERVAL 5 DAY) where user='wl7131'" "ALTER USER 'wl7131' PASSWORD EXPIRE DEFAULT" +"SET GLOBAL default_password_lifetime = 0" "ALTER USER 'wl7131' PASSWORD EXPIRE INTERVAL 4 DAY" +"SET GLOBAL default_password_lifetime = @saved_value" "ALTER USER 'wl7131' PASSWORD EXPIRE INTERVAL 6 DAY" "select password_lifetime from mysql.user where user='wl7131'" "CREATE USER 'wl7131'" @@ -35680,6 +35788,7 @@ END" "grant all privileges on `my\_1`.* to mysqltest_1@localhost with grant option" "grant create user on *.* to mysqltest_1@localhost" "create user mysqltest_2@localhost" +"create user mysqltest_2@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "grant select on `my\_1`.* to mysqltest_2@localhost" "grant update on mysql.* to mysqltest_1@localhost" "grant select on `my\_1`.* to mysqltest_3@localhost" @@ -35713,54 +35822,56 @@ mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7" "delete from mysql.user where user like 'mysqltest\_1'" "delete from mysql.db where user like 'mysqltest\_1'" "set sql_mode='ANSI'" +"create table t1(c1 int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1(c1 int)" -"create table t2(c1 int, c2 int)" -"create user 'mysqltest_1'" -"create user 'mysqltest_2' identified by 'Mysqltest-2'" -"grant select on *.* to 'mysqltest_2'" -"grant insert on test.* to 'mysqltest_2'" -"grant update on test.t1 to 'mysqltest_2'" -"grant update (c2) on test.t2 to 'mysqltest_2'" -"select host,user,length(authentication_string) from mysql.user where user like 'mysqltest_%' order by host,user,authentication_string" -"select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user" -"select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name" -"select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name" -"show grants for 'mysqltest_1'" -"show grants for 'mysqltest_2'" -"drop user 'mysqltest_1'" -"rename user 'mysqltest_2' to 'mysqltest_1'" -"insert into mysql.db set user='mysqltest_1', db='%', host='%'" -"select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,user" -"insert into mysql.tables_priv set host='%', db='test', user='mysqltest_1', table_name='t1'" -"select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' order by host,db,user,table_name" -"insert into mysql.columns_priv set host='%', db='test', user='mysqltest_1', table_name='t1', column_name='c1'" -"select host,db,user,table_name,column_name from mysql.columns_priv where user = 'mysqltest_1' order by host,db,user,table_name,column_name" -"create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'" -"drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'" -"create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by 'haha'" -"rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'" -"drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'" -"create user 'mysqltest_1a', 'mysqltest_3a'" -"drop user 'mysqltest_1a', 'mysqltest_3a'" -"drop user 'mysqltest_2'" -"create user '%@b'@'b'" -"show grants for '%@b'@'b'" -"grant select on mysql.* to '%@b'@'b'" -"rename user '%@b'@'b' to '%@a'@'a'" -"show grants for '%@a'@'a'" -"drop user '%@a'@'a'" -"grant create user on *.* to mysqltest_2@localhost" +"create table t2(c1 int, c2 int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user 'mysqltest_1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user 'mysqltest_2' identified by 'Mysqltest-2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant select on *.* to 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant insert on test.* to 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant update on test.t1 to 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant update (c2) on test.t2 to 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,user,length(authentication_string) from mysql.user where user like 'mysqltest_%' order by host,user,authentication_string","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"show grants for 'mysqltest_1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"show grants for 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user 'mysqltest_1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"rename user 'mysqltest_2' to 'mysqltest_1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into mysql.db set user='mysqltest_1', db='%', host='%'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,user","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into mysql.tables_priv set host='%', db='test', user='mysqltest_1', table_name='t1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' order by host,db,user,table_name","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into mysql.columns_priv set host='%', db='test', user='mysqltest_1', table_name='t1', column_name='c1'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select host,db,user,table_name,column_name from mysql.columns_priv where user = 'mysqltest_1' order by host,db,user,table_name,column_name","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by 'haha'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user 'mysqltest_1a', 'mysqltest_3a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user 'mysqltest_1a', 'mysqltest_3a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user 'mysqltest_2'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create user '%@b'@'b'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"show grants for '%@b'@'b'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant select on mysql.* to '%@b'@'b'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"rename user '%@b'@'b' to '%@a'@'a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"show grants for '%@a'@'a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user '%@a'@'a'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"grant create user on *.* to mysqltest_2@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create user mysqltest_A@'%'" "rename user mysqltest_A@'%' to mysqltest_B@'%'" "drop user mysqltest_B@'%'" +"drop user mysqltest_2@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "drop user mysqltest_2@localhost" -"grant INSERT,DELETE,UPDATE on mysql.* to mysqltest_3@localhost" +"grant INSERT,DELETE,UPDATE on mysql.* to mysqltest_3@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "show grants" "insert ignore into mysql.user set host='%', user='mysqltest_B'" "rename user mysqltest_B@'%' to mysqltest_C@'%'" "drop user mysqltest_C@'%'" "drop user mysqltest_A@'%'" -"drop user mysqltest_3@localhost" +"drop user mysqltest_3@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create user mysqltest_1@'127.0.0.0/255.0.0.0'" "create table mysqltest_1.t1 (i int)" "insert into mysqltest_1.t1 values (1),(2),(3)" @@ -35820,6 +35931,7 @@ BEGIN DECLARE v INT; SELECT s1 FROM t2 INTO v; RETURN v; END" "DROP TABLE db1.t1, db1.t2" "DROP USER mysqltest1@localhost" "USE mysql" +"USE mysql","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT LEFT(CURRENT_USER(),INSTR(CURRENT_USER(),'@')-1) INTO @u" "SELECT MID(CURRENT_USER(),INSTR(CURRENT_USER(),'@')+1) INTO @h" "SELECT authentication_string FROM user WHERE user=@u AND host=@h INTO @pwd" @@ -37019,6 +37131,7 @@ WHERE user='unlocked_user' and host = 'localhost'" WHERE user='unlocked_user' and host = 'localhost'" "UPDATE mysql.user SET account_locked='y' WHERE user='unlocked_user' and host = 'localhost'" +"ALTER USER unlocked_user@localhost ACCOUNT UNLOCK" "SELECT account_locked FROM mysql.user WHERE user = 'unlocked_user' and host = 'localhost'" "ALTER USER unlocked_user@localhost ACCOUNT LOCK" @@ -37896,10 +38009,13 @@ FROM t1 LEFT JOIN t2 ON t1.id=t2.id GROUP BY comment" "select sql_buffer_result max(f1) is null from t1" "select sql_buffer_result max(f1)+1 from t1" "SELECT a FROM t1 GROUP BY 'a'" +"SELECT a FROM t1 GROUP BY 'a'",ANSI_QUOTES "SELECT a FROM t1 GROUP BY ""a""" +"SELECT a FROM t1 GROUP BY ""a""",ANSI_QUOTES "SELECT a FROM t1 GROUP BY `a`" +"SELECT a FROM t1 GROUP BY `a`",ANSI_QUOTES "set sql_mode=ANSI_QUOTES" -"set sql_mode=DEFAULT" +"set sql_mode=DEFAULT",ANSI_QUOTES "SELECT a FROM t1 HAVING 'a' > 1" "SELECT a FROM t1 HAVING ""a"" > 1" "SELECT a FROM t1 HAVING `a` > 1" @@ -37970,6 +38086,7 @@ FROM t1 AS t1_outer GROUP BY t1_outer.b" "SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) FROM t1 AS t1_outer" "SET SQL_MODE = ''" +"SET SQL_MODE = ''",ANSI_QUOTES "SELECT 1 FROM t1 as t1_outer WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1)" "SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0" @@ -42934,6 +43051,7 @@ OWNER 'some_user_name')" "SET GLOBAL DEBUG = '+d, vio_peer_addr_fake_ipv4, getaddrinfo_fake_good_ipv4'" "CREATE USER 'rick'@'192.0.2.4'" "SET GLOBAL DEBUG = '+d, getnameinfo_fake_max_length_plus_1'" +"SET GLOBAL DEBUG = '-d, getnameinfo_fake_max_length_plus_1'" "SET GLOBAL DEBUG = '+d, getnameinfo_fake_max_length'" "SHOW VARIABLES LIKE 'performance_schema'" "SELECT host FROM performance_schema.hosts WHERE host LIKE 'aaaa%'" @@ -43712,6 +43830,7 @@ de DECIMAL(10,2), j INT GENERATED ALWAYS AS (42+i)) ENGINE=MYISAM" "IMPORT TABLE FROM 'test/t1*.sdi'" "SET SESSION debug= '+d,sdi_import_commit_fail'" "SET SESSION debug= '-d,sdi_import_commit_fail'" +"CREATE TABLE t1 (i int) ENGINE=MYISAM" "CREATE TABLE t2 (i int) ENGINE=MYISAM" "CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPACT" "CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=DYNAMIC" @@ -44238,6 +44357,7 @@ where table_name='v1' or table_name='v2'" "select concat(@a, table_name), @a, table_name from information_schema.tables where table_schema = 'test' order by table_name" "DROP FUNCTION IF EXISTS f1" +"DROP FUNCTION IF EXISTS f1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() SET @a= 1" "CREATE FUNCTION f1() RETURNS INT RETURN @a + 1" "CREATE USER mysql_bug20230@localhost" @@ -48129,6 +48249,7 @@ select @a:= A.a + 10*(B.a + 10*C.a), @a, 'filler' from t1 A, t1 B, t1 C" "SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a" "SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a" "DROP TABLE IF EXISTS t1,t2" +"DROP TABLE IF EXISTS t1,t2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE t3 (a INT, INDEX (a))" "CREATE TABLE t4 (a INT)" "CREATE TABLE t5 (a INT)" @@ -51803,6 +51924,7 @@ END WHILE source_heartbeat_period; END" "call p2()" +"call p2()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP TABLE IF EXISTS t1, t2, t3" "DROP FUNCTION IF EXISTS MY_KILL" "CREATE FUNCTION MY_KILL(tid INT) RETURNS INT @@ -52926,14 +53048,19 @@ LINES TERMINATED BY '\n' (c1, c2)" "SET @OLD_SQL_MODE=@@SESSION.SQL_MODE" "CREATE TABLE t1 (id INT, val1 CHAR(3))" "SET sql_mode = 'NO_BACKSLASH_ESCAPES'" +"INSERT INTO t1 (id, val1) VALUES (1, '\aa')",NO_BACKSLASH_ESCAPES "INSERT INTO t1 (id, val1) VALUES (1, '\aa')" "CREATE TABLE t1 (id INT PRIMARY KEY, val1 CHAR(4))" "INSERT INTO t1 (id, val1) VALUES (5, '\ttab')" "INSERT INTO t1 (id, val1) VALUES (4, '\\r')" -"INSERT INTO t1 (id, val1) VALUES (3, '\tx')" +"INSERT INTO t1 (id, val1) VALUES (3, '\tx')",NO_BACKSLASH_ESCAPES +"SELECT 'before' AS t, id, val1, hex(val1) FROM t1 UNION +SELECT 'after' AS t, id, val1, hex(val1) FROM t2 ORDER BY id,t DESC",NO_BACKSLASH_ESCAPES "SELECT 'before' AS t, id, val1, hex(val1) FROM t1 UNION SELECT 'after' AS t, id, val1, hex(val1) FROM t2 ORDER BY id,t DESC" +"TRUNCATE t2",NO_BACKSLASH_ESCAPES "TRUNCATE t2" +"set session sql_mode=@OLD_SQL_MODE",NO_BACKSLASH_ESCAPES "set session sql_mode=@OLD_SQL_MODE" "select load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A)" "SET character_set_filesystem=binary" @@ -53011,6 +53138,7 @@ vbcol CHAR(2) AS (substr(b,2,2)) VIRTUAL, vbidxcol CHAR(3) AS (substr(b,1,3)) VIRTUAL ) " +"DROP TABLE ibstd_03" "select load_file(""/proc/uptime"")" "SET @old_net_buffer_length = @@global.net_buffer_length" "SET @old_max_allowed_packet= @@global.max_allowed_packet" @@ -55230,6 +55358,7 @@ from information_schema.tables where table_schema='test' and table_name='t2'" "SET DEBUG_SYNC= 'now SIGNAL blocked'" "CREATE TABLE db1.t1 (a INT)" "CREATE TABLE test.t2 (a INT)" +"DROP TABLE test.t2" "FLUSH TABLE WITH READ LOCK" "DROP TABLE IF EXISTS t1, t2, m1" "CREATE TABLE t1(a INT) engine=MyISAM" @@ -57352,6 +57481,7 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'" "select ""Test 'go' command(vertical output) \G"" as ""_""" "select ""Test 'go' command \g"" as ""_""" "create table t1(a int, b varchar(255), c int)" +"create table t17583 (a int)" "insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)" "insert into t17583 select a from t17583" "select count(*) from t17583" @@ -57359,13 +57489,15 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'" "DROP DATABASE init_command_db_2" "create table t1 (a char(5))" "insert into t1 values ('\0b\0')" +"CREATE DATABASE connected_db" "USE connected_db" "DROP DATABASE connected_db" -"CREATE DATABASE connected_db" "SHOW TABLES IN connected_db" "SHOW TABLES IN test" "SHOW TABLES IN test1" -"DROP TABLE test.t2" +"CREATE USER bug21464621 IDENTIFIED BY 'password' PASSWORD EXPIRE" +"DROP USER bug21464621" +"TRUNCATE TABLE mysql.help_topic" "SELECT COUNT(*) = 0 FROM mysql.help_topic" "SELECT COUNT(*) != 0 FROM mysql.help_topic" "SET @old_general_log_file = @@global.general_log_file" @@ -57376,7 +57508,9 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'" "drop procedure if exists nicesp" "drop trigger if exists t1_empty" "drop trigger if exists t1_bi" +"CREATE USER test_user1" "CREATE USER test_user2" +"DROP USER test_user1, test_user2" "CREATE USER user_name_len_26_012345678@localhost" "DROP USER user_name_len_25_01234567@localhost,user_name_len_26_012345678@localhost" "CREATE USER 'test#user1'@'localhost'" @@ -57409,6 +57543,7 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'" "DROP TABLE b34303841" "CREATE USER native_password_user IDENTIFIED WITH mysql_native_password BY 'abcd'" "CREATE USER regular_user" +"DROP USER native_password_user, regular_user" "SELECT COUNT(*) AS must_be_zero_for_test FROM performance_schema.session_connect_attrs WHERE attr_name IN ('os_user', 'os_sudouser') AND PROCESSLIST_ID=CONNECTION_ID()" "CREATE USER u1@localhost IDENTIFIED BY 'secret' REQUIRE SSL" "CREATE DATABASE test_zone" @@ -57418,11 +57553,11 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'" "CREATE TABLE time_zone_name as SELECT * FROM mysql.time_zone_name WHERE 1 = 0" "CREATE TABLE time_zone_transition as SELECT * FROM mysql.time_zone_transition WHERE 1 = 0" "CREATE TABLE time_zone_transition_type as SELECT * FROM mysql.time_zone_transition_type WHERE 1 = 0" +"DROP DATABASE test_zone" "SELECT (count(*) > 0) FROM time_zone" "SELECT (count(*) > 0) FROM time_zone_name" "SELECT (count(*) > 0) FROM time_zone_transition" "SELECT (count(*) > 0) FROM time_zone_transition_type" -"DROP DATABASE test_zone" "SHOW GRANTS FOR ""mysql.session""@localhost" "REVOKE SESSION_VARIABLES_ADMIN ON *.* FROM ""mysql.session""@localhost" "CREATE USER u1,u2" @@ -57613,6 +57748,7 @@ end; "SELECT COUNT(*) AS `BUG#28293_expect_3` FROM patch WHERE a LIKE '%Query%'" "DROP TABLE patch" "set timestamp= default" +"SET BINLOG_FORMAT='ROW'" "CREATE USER untrusted@localhost" "GRANT SELECT ON mysqltest1.* TO untrusted@localhost" "SHOW GRANTS FOR untrusted@localhost" @@ -57630,10 +57766,6 @@ end; "CREATE TABLE t1(id int)" "SET GLOBAL SERVER_ID = 2" "BINLOG ' -RaNlZRMBAAAAMAAAAG0DAAAAAG8AAAAAAAEABHRlc3QAAnQxAAEDAAEBAQAg5VHP -RaNlZR4BAAAAKAAAAJUDAAAAAG8AAAAAAAEAAgAB/wACAAAAczmjEA== -'" -"BINLOG ' YKFlZQ8BAAAAegAAAH4AAAABAAQAOC4zLjAtZGVidWcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABgoWVlEwANAAgAAAAABAAEAAAAYgAEGggAAAAICAgCAAAACgoKKioAEjQA CigAAcmi5+o= @@ -57646,11 +57778,8 @@ YKNlZR4BAAAAKAAAANMEAAAAAG8AAAAAAAEAAgAB/wADAAAA50UVkQ== 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADgJ1hHEzgNAAgAEgAEBAQEEgAATwAEGggICAg= '" -"BINLOG ' -jKNlZRMBAAAAMAAAAOkFAAAAAG8AAAAAAAEABHRlc3QAAnQxAAEDAAEBAQCwxzWH -jKNlZR4BAAAAKAAAABEGAAAAAG8AAAAAAAEAAgAB/wAFAAAAVI7NfA== -'" "CREATE TABLE t1(s INT)" +"CREATE TABLE T1(s INT)" "SET @a= 10" "INSERT INTO T1 VALUES(@a)" "SET @org_concurrent_insert= @@global.concurrent_insert" @@ -57687,6 +57816,7 @@ ENGINE=INNODB STATS_PERSISTENT=0""" "DROP PREPARE drop_stmt" "create view v1 as select * from information_schema.routines" "check table v1, information_schema.routines" +"DROP DATABASE IF EXISTS b12688860_db" "CREATE DATABASE b12688860_db" "DROP DATABASE b12688860_db" "CREATE USER 'user_with_length_32_abcdefghijkl'@'localhost'" @@ -58829,7 +58959,7 @@ ST_AsText(g) FROM t1" `pho""\ne` VARCHAR(15), ""created'_'at"" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ""updated'_'at"" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -)" +)",ANSI_QUOTES "CREATE TABLE ""prod'ucts"" ( ""product`_`id"" INT AUTO_INCREMENT PRIMARY KEY, ""product'_`name"" VARCHAR(100) NOT NULL, @@ -58839,7 +58969,7 @@ ST_AsText(g) FROM t1" `created'_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated""_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX (""product'_`name"") -)" +)",ANSI_QUOTES "CREATE TABLE ""orders"" ( ""order_id"" INT AUTO_INCREMENT PRIMARY KEY, ""customer_id"" INT NOT NULL, @@ -58848,7 +58978,7 @@ INDEX (""product'_`name"") ""total\n"" DECIMAL(10, 2) NOT NULL CHECK (""total\n"" >= 0), FOREIGN KEY (customer_id) REFERENCES ""custo`mers""(""customer'_id"") ON DELETE CASCADE, INDEX (order_date) -)" +)",ANSI_QUOTES "CREATE TABLE `'order'_'items'` ( `order'_'item_id` INT AUTO_INCREMENT PRIMARY KEY, `'order'_'id'` INT NOT NULL, @@ -58858,8 +58988,8 @@ INDEX (order_date) FOREIGN KEY (`'order'_'id'`) REFERENCES ""orders""(order_id) ON DELETE CASCADE, FOREIGN KEY (`product'_'id`) REFERENCES ""prod'ucts""(""product`_`id"") ON DELETE CASCADE, UNIQUE KEY (`'order'_'id'`, `product'_'id`) -)" -"SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'" +)",ANSI_QUOTES +"SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",ANSI_QUOTES "DROP DATABASE bug37607195" "SET @OLD_CONCURRENT_INSERT = @@GLOBAL.CONCURRENT_INSERT" "SET @@GLOBAL.CONCURRENT_INSERT = 0" @@ -58876,10 +59006,12 @@ UNIQUE KEY (`'order'_'id'`, `product'_'id`) "INSERT IGNORE INTO t1 VALUES ('-9e999999')" "CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT)" "INSERT INTO t1 VALUES (1.2345, 2.3456)" +"INSERT INTO t1 VALUES (1.2345, 2.3456)",ANSI_QUOTES "INSERT INTO t1 VALUES ('1.2345', 2.3456)" +"INSERT INTO t1 VALUES ('1.2345', 2.3456)",ANSI_QUOTES "INSERT INTO t1 VALUES (""1.2345"", 2.3456)" "SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI_QUOTES'" -"SET SQL_MODE=@OLD_SQL_MODE" +"SET SQL_MODE=@OLD_SQL_MODE",ANSI_QUOTES "CREATE TABLE t1(a int, b text, c varchar(3))" "INSERT INTO t1 VALUES (1, ""test"", ""tes""), (2, ""TEST"", ""TES"")" "CREATE TABLE t1 (`a""b""` char(2))" @@ -59239,6 +59371,7 @@ F_fe73f687e5bc5280214e0486b273a5f9 int)" "create table t2(a varchar(30) primary key, b int not null)" "create table t3(a varchar(30) primary key, b int not null)" "select '------ Testing with illegal table names ------' as test_sequence " +"select '------ Testing with illegal database names ------' as test_sequence " "create table t1 (a int(10))" "create table t2 (pk int primary key auto_increment, a int(10), b varchar(30), c datetime, d blob, e text)" @@ -59350,7 +59483,7 @@ end " BEGIN select sum(id) from t1 into a; END " -"create procedure `a'b` () select 1" +"create procedure `a'b` () select 1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION bug9056_func1" "DROP FUNCTION bug9056_func2" "DROP PROCEDURE bug9056_proc1" @@ -59393,8 +59526,8 @@ INSERT INTO `t2 test` SET a2 = NEW.a1; END " FOR EACH ROW BEGIN SET new.a = 0; -END" -"SET SQL_MODE = @old_sql_mode" +END",IGNORE_SPACE +"SET SQL_MODE = @old_sql_mode",IGNORE_SPACE "DROP TRIGGER tr1" "create table t1 (a binary(1), b blob)" "insert into t1 values ('','')" @@ -59455,6 +59588,8 @@ select 42 */" "select * from mysqldump_dba.v1" "select * from mysqldump_dbb.v1" "create table t1(a int, b varchar(34))" +"grant RELOAD on *.* to mysqltest_1@localhost" +"grant REPLICATION CLIENT on *.* to mysqltest_1@localhost" "create database mysqldump_myDB" "use mysqldump_myDB" "create user myDB_User@localhost" @@ -59490,6 +59625,7 @@ select 42 */" "grant all privileges on mysqldump_test_db.* to user1" "grant all privileges on mysqldump_test_db.* to user2" "create procedure mysqldump_test_db.sp1() select 'hello'" +"drop procedure sp1" "drop user user1" "drop user user2" "CREATE TABLE t1 (c1 INT, c2 LONGBLOB)" @@ -59642,7 +59778,6 @@ l DATETIME DEFAULT '2010-05-26 12:34:56' "DROP TABLE b12809202_db.t1" "DROP TABLE b12809202_db.t2" "DROP DATABASE b12809202_db" -"DROP DATABASE IF EXISTS b12688860_db" "CREATE DATABASE `a\\k`" "CREATE TABLE `a\\k`.t1(i INT)" "SHOW TABLES FROM `a\\k`" @@ -59720,6 +59855,9 @@ FROM information_schema.COLUMN_STATISTICS" "USE bug26171967" "INSERT INTO t1 VALUES (1000000), (1000001)" "DROP DATABASE bug26171967" +"CREATE TABLE t1(f1 INT INVISIBLE, f2 INT, +f3 INT AS (f1 + 10), f4 INT AS (f2 + 10) INVISIBLE, +f5 INT AS (f2 + 10) STORED INVISIBLE)" "CREATE TABLE t2(f1 INT, f2 INT INVISIBLE)" "INSERT INTO t1(f1, f2) VALUES (10, 20), (20, 30)" "INSERT INTO t2(f1, f2) VALUES (10, 20), (20, 30)" @@ -59878,8 +60016,8 @@ VALUES (111, 222, JSON_OBJECT('data', REPEAT('LotsOfData', 250000)))" "DROP DATABASE test_bug36248967" "CREATE TABLE mysqldump_test_db.t1 (a INT)" "CREATE EVENT mysqldump_test_db.replica_event ON SCHEDULE EVERY 3 SECOND DISABLE ON REPLICA DO SELECT 1" -"INSERT INTO mysqldump_test_db.t1 VALUES (1)" "SET @@GLOBAL.terminology_use_previous = BEFORE_8_0_26" +"INSERT INTO mysqldump_test_db.t1 VALUES (1)" "INSERT INTO mysqldump_test_db.t1 VALUES (2)" "INSERT INTO mysqldump_test_db.t1 VALUES (3)" "SET @old_concurrent_insert = @@global.concurrent_insert" @@ -61020,6 +61158,7 @@ ssl_user5@localhost" "SHOW STATUS LIKE 'Ssl_cipher'" "drop user ssl_user1@localhost, ssl_user2@localhost, ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost" +"DROP TABLE IF EXISTS thread_status" "CREATE EVENT event_status ON SCHEDULE AT NOW() ON COMPLETION NOT PRESERVE @@ -61033,6 +61172,7 @@ variable_name LIKE 'SSL_CALLBACK_CACHE_HITS'; END" "SELECT variable_name, variable_value FROM thread_status" "DROP TABLE thread_status" +"select 'is still running; no cipher request crashed the server' as result from dual" "CREATE USER bug42158@localhost REQUIRE X509" "GRANT SELECT ON test.* TO bug42158@localhost" "DROP USER bug42158@localhost" @@ -61591,12 +61731,14 @@ INDEX idx1(f2, f3), INDEX idx2(f3) "SELECT /*+ BKA(` quoted name тест`@`select#1`) */ 1 FROM t1" "DROP TABLE ` quoted name тест`" "SET SQL_MODE = 'ANSI_QUOTES'" -"CREATE TABLE "" quoted name тест"" (i INT)" +"SET SQL_MODE = 'ANSI_QUOTES'",IGNORE_SPACE +"CREATE TABLE "" quoted name тест"" (i INT)",ANSI_QUOTES +"SELECT /*+ BKA("" quoted name тест"") */ 1 FROM t1",ANSI_QUOTES "SELECT /*+ BKA("" quoted name тест"") */ 1 FROM t1" -"SELECT /*+ BKA("" quoted name тест""@""select#1"") */ 1 FROM t1" -"CREATE TABLE `test1``test2``` (i INT)" -"SELECT /*+ BKA(`test1``test2```) */ 1" -"SELECT /*+ BKA(""test1""""test2"""""") */ 1" +"SELECT /*+ BKA("" quoted name тест""@""select#1"") */ 1 FROM t1",ANSI_QUOTES +"CREATE TABLE `test1``test2``` (i INT)",ANSI_QUOTES +"SELECT /*+ BKA(`test1``test2```) */ 1",ANSI_QUOTES +"SELECT /*+ BKA(""test1""""test2"""""") */ 1",ANSI_QUOTES "DROP TABLE `test1``test2```" "EXPLAIN SELECT /*+ QB_NAME(`*`) */ 1" "EXPLAIN SELECT /*+ QB_NAME(`a*`) */ 1" @@ -63531,8 +63673,11 @@ FROM t3" "DROP TABLE t3, t4" "set SQL_MODE=''" "create table ADDDATE(a int)" +"create table ADDDATE(a int)",IGNORE_SPACE "drop table ADDDATE" +"drop table ADDDATE",IGNORE_SPACE "create table ADDDATE (a int)" +"create table ADDDATE (a int)",IGNORE_SPACE "create table BIT_AND (a int)" "drop table BIT_AND" "create table BIT_OR (a int)" @@ -63556,8 +63701,11 @@ FROM t3" "create table GROUP_CONCAT (a int)" "drop table GROUP_CONCAT" "create table GROUP_UNIQUE_USERS(a int)" +"create table GROUP_UNIQUE_USERS(a int)",IGNORE_SPACE "drop table GROUP_UNIQUE_USERS" +"drop table GROUP_UNIQUE_USERS",IGNORE_SPACE "create table GROUP_UNIQUE_USERS (a int)" +"create table GROUP_UNIQUE_USERS (a int)",IGNORE_SPACE "create table MAX (a int)" "drop table MAX" "create table MID (a int)" @@ -63569,8 +63717,11 @@ FROM t3" "create table POSITION (a int)" "drop table POSITION" "create table SESSION_USER(a int)" +"create table SESSION_USER(a int)",IGNORE_SPACE "drop table SESSION_USER" +"drop table SESSION_USER",IGNORE_SPACE "create table SESSION_USER (a int)" +"create table SESSION_USER (a int)",IGNORE_SPACE "create table STD (a int)" "drop table STD" "create table STDDEV (a int)" @@ -63580,8 +63731,11 @@ FROM t3" "create table STDDEV_SAMP (a int)" "drop table STDDEV_SAMP" "create table SUBDATE(a int)" +"create table SUBDATE(a int)",IGNORE_SPACE "drop table SUBDATE" +"drop table SUBDATE",IGNORE_SPACE "create table SUBDATE (a int)" +"create table SUBDATE (a int)",IGNORE_SPACE "create table SUBSTR (a int)" "drop table SUBSTR" "create table SUBSTRING (a int)" @@ -63591,13 +63745,19 @@ FROM t3" "create table SYSDATE (a int)" "drop table SYSDATE" "create table SYSTEM_USER(a int)" +"create table SYSTEM_USER(a int)",IGNORE_SPACE "drop table SYSTEM_USER" +"drop table SYSTEM_USER",IGNORE_SPACE "create table SYSTEM_USER (a int)" +"create table SYSTEM_USER (a int)",IGNORE_SPACE "create table TRIM (a int)" "drop table TRIM" "create table UNIQUE_USERS(a int)" +"create table UNIQUE_USERS(a int)",IGNORE_SPACE "drop table UNIQUE_USERS" +"drop table UNIQUE_USERS",IGNORE_SPACE "create table UNIQUE_USERS (a int)" +"create table UNIQUE_USERS (a int)",IGNORE_SPACE "create table VARIANCE (a int)" "drop table VARIANCE" "create table VAR_POP (a int)" @@ -63605,17 +63765,21 @@ FROM t3" "create table VAR_SAMP (a int)" "drop table VAR_SAMP" "set SQL_MODE='IGNORE_SPACE'" +"CREATE TABLE t1 (i INT KEY)",IGNORE_SPACE "CREATE TABLE t1 (i INT KEY)" -"CREATE TABLE t2 (i INT UNIQUE)" -"CREATE TABLE t3 (i INT UNIQUE KEY)" -"DROP TABLE IF EXISTS table_25930_a" -"DROP TABLE IF EXISTS table_25930_b" -"CREATE TABLE table_25930_a ( ""blah"" INT )" -"CREATE TABLE table_25930_b SELECT ""blah"" - 1 FROM table_25930_a" -"desc table_25930_b" -"DROP TABLE table_25930_a" -"DROP TABLE table_25930_b" +"CREATE TABLE t2 (i INT UNIQUE)",IGNORE_SPACE +"CREATE TABLE t3 (i INT UNIQUE KEY)",IGNORE_SPACE +"DROP TABLE IF EXISTS table_25930_a",IGNORE_SPACE +"DROP TABLE IF EXISTS table_25930_b",IGNORE_SPACE +"CREATE TABLE table_25930_a ( ""blah"" INT )",ANSI_QUOTES +"CREATE TABLE table_25930_b SELECT ""blah"" - 1 FROM table_25930_a",ANSI_QUOTES +"desc table_25930_b",ANSI_QUOTES +"DROP TABLE table_25930_a",ANSI_QUOTES +"DROP TABLE table_25930_b",ANSI_QUOTES +"SET @@sql_mode=@save_sql_mode",ANSI_QUOTES +"SET @@sql_mode=@save_sql_mode",IGNORE_SPACE "SET @@sql_mode=@save_sql_mode" +"SET @@sql_mode=@save_sql_mode",PIPES_AS_CONCAT "DROP PROCEDURE IF EXISTS p26030" "select ""non terminated""" "select ""terminated"";" @@ -64030,7 +64194,7 @@ o INT "ROLLBACK AND NO CHAIN NO RELEASE" "CREATE TABLE t1 (a INT PRIMARY KEY) PARTITION BY HASH (a) PARTITIONS 1" "SET sql_mode='IGNORE_SPACE'" -"SHOW COLUMNS FROM t1 WHERE FIELD='a'" +"SHOW COLUMNS FROM t1 WHERE FIELD='a'",IGNORE_SPACE "CREATE TEMPORARY TABLE admin (admin INT)" "DROP TABLE admin" "SELECT @@default_collation_for_utf8mb4" @@ -64049,6 +64213,7 @@ o INT "ALTER TABLE t3 CONVERT TO CHARACTER SET DEFAULT" "ALTER TABLE t3 CONVERT TO CHARACTER SET DEFAULT COLLATE utf8mb4_bin" "SET parser_max_mem_size = 10000000" +"SET parser_max_mem_size = default" "SELECT 1 AS PERSIST, 2 AS PERSIST_ONLY" "CREATE FUNCTION f1() RETURNS INT BEGIN @@ -64094,20 +64259,20 @@ END" ORDER BY b DESC LIMIT 2) ORDER BY c LIMIT 1" "SET sql_mode=(SELECT CONCAT(@@sql_mode, ',PIPES_AS_CONCAT'))" -"SELECT 'ab' LIKE 'a%', 'ab' LIKE 'a' || '%'" -"SELECT 'ab' NOT LIKE 'a%', 'ab' NOT LIKE 'a' || '%'" -"SELECT 'ab' LIKE 'ac', 'ab' LIKE 'a' || 'c'" -"SELECT 'ab' NOT LIKE 'ac', 'ab' NOT LIKE 'a' || 'c'" -"SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!' || '%' ESCAPE '!'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '!', 'a%' NOT LIKE 'a!' || '%' ESCAPE '!'" -"SELECT 'a%' LIKE 'a!%' ESCAPE '$', 'a%' LIKE 'a!' || '%' ESCAPE '$'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '$', 'a%' NOT LIKE 'a!' || '%' ESCAPE '$'" -"SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!%' ESCAPE '' || '!'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '!', 'a%' NOT LIKE 'a!%' ESCAPE '' || '!'" -"SELECT 'a%' LIKE 'a!%' ESCAPE '' || '$', 'a%' LIKE 'a!%' ESCAPE '' || '$'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '' || '$', 'a%' NOT LIKE 'a!%' ESCAPE '' || '$'" -"SELECT 1 ^ 100, 1 ^ '10' || '0'" -"SELECT -1 || '0'" +"SELECT 'ab' LIKE 'a%', 'ab' LIKE 'a' || '%'",PIPES_AS_CONCAT +"SELECT 'ab' NOT LIKE 'a%', 'ab' NOT LIKE 'a' || '%'",PIPES_AS_CONCAT +"SELECT 'ab' LIKE 'ac', 'ab' LIKE 'a' || 'c'",PIPES_AS_CONCAT +"SELECT 'ab' NOT LIKE 'ac', 'ab' NOT LIKE 'a' || 'c'",PIPES_AS_CONCAT +"SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!' || '%' ESCAPE '!'",PIPES_AS_CONCAT +"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '!', 'a%' NOT LIKE 'a!' || '%' ESCAPE '!'",PIPES_AS_CONCAT +"SELECT 'a%' LIKE 'a!%' ESCAPE '$', 'a%' LIKE 'a!' || '%' ESCAPE '$'",PIPES_AS_CONCAT +"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '$', 'a%' NOT LIKE 'a!' || '%' ESCAPE '$'",PIPES_AS_CONCAT +"SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!%' ESCAPE '' || '!'",PIPES_AS_CONCAT +"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '!', 'a%' NOT LIKE 'a!%' ESCAPE '' || '!'",PIPES_AS_CONCAT +"SELECT 'a%' LIKE 'a!%' ESCAPE '' || '$', 'a%' LIKE 'a!%' ESCAPE '' || '$'",PIPES_AS_CONCAT +"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '' || '$', 'a%' NOT LIKE 'a!%' ESCAPE '' || '$'",PIPES_AS_CONCAT +"SELECT 1 ^ 100, 1 ^ '10' || '0'",PIPES_AS_CONCAT +"SELECT -1 || '0'",PIPES_AS_CONCAT "SELECT 1 UNION SELECT 1 INTO @var" "(SELECT 1 UNION SELECT 1 INTO @var)" "SELECT 1 UNION SELECT 1 FROM DUAL INTO @var" @@ -64147,12 +64312,14 @@ ORDER BY c LIMIT 1" "DROP TABLE full" "CREATE TABLE `full`(i INT)" "SELECT * from `full`" +"SELECT * from `full`",ANSI_QUOTES "SELECT * from `full` AS full" "SELECT * from `full` AS `full`" "SELECT * from full" +"SELECT * from full",ANSI_QUOTES "SELECT * from full as full" "SELECT * from `full` full" -"SELECT * from ""full""" +"SELECT * from ""full""",ANSI_QUOTES "DROP TABLE `full`" "CREATE TABLE get_source_public_key(i INT)" "CREATE TABLE source_auto_position(i INT)" @@ -65472,12 +65639,16 @@ PARTITION p1 VALUES LESS THAN MAXVALUE( SUBPARTITION s2, SUBPARTITION s3 tablespace=""innodb_file_per_table"" ) -)" +)",ANSI_QUOTES +"SELECT partition_expression FROM information_schema.partitions +WHERE table_schema = 'test' AND table_name = 't1'",ANSI_QUOTES "SELECT partition_expression FROM information_schema.partitions WHERE table_schema = 'test' AND table_name = 't1'" -"SET @@SQL_MODE= DEFAULT" +"SET @@SQL_MODE= DEFAULT",ANSI_QUOTES "SET @@SQL_QUOTE_SHOW_CREATE= 0" "SET @@SQL_QUOTE_SHOW_CREATE= 1" +"CREATE TABLE t (a BIGINT NOT NULL) +PARTITION BY KEY(a) PARTITIONS 2" "SELECT 1 FROM t WHERE a = 0x8000000000000000" "CREATE TABLE t (a VARCHAR(10) NOT NULL,b INT,PRIMARY KEY (b)) ENGINE=INNODB PARTITION BY RANGE (b) @@ -66150,6 +66321,7 @@ PARTITION p3 VALUES LESS THAN MAXVALUE ) */" "SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning'" "SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL waiting_for_alter'" "SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table WAIT_FOR waiting_for_upgrade'" +"SET SESSION debug= ""-d,sleep_before_create_table_no_lock""" "CREATE TABLE t2 (a INTEGER, b INTEGER NOT NULL, @@ -66352,6 +66524,7 @@ PARTITION BY RANGE(YEAR(purchased)) DATA DIRECTORY = '/tmp/not-existing' INDEX DIRECTORY = '/tmp/not-existing')" "SET @@sql_mode= @org_mode" +"SET @@sql_mode= @org_mode",NO_BACKSLASH_ESCAPES "CREATE TABLE t1 (a INTEGER NOT NULL, PRIMARY KEY (a))" "CREATE TABLE t1 (a INTEGER NOT NULL, PRIMARY KEY (a)) PARTITION BY KEY (a) PARTITIONS 2" @@ -67788,6 +67961,7 @@ PARTITION p3 VALUES LESS THAN (10) "SET default_storage_engine=InnoDB" "SET SESSION innodb_strict_mode = ON" "SET GLOBAL innodb_file_per_table = ON" +"INSERT INTO t1 VALUES (1, ""red"")" "INSERT INTO t1 VALUES (2, ""green"")" "INSERT INTO t1 VALUES (3, ""blue"")" "RENAME TABLE t1 TO t11" @@ -70646,6 +70820,7 @@ myisam_stats_method=default" "GRANT ALL ON *.* TO 'bug28749668'@'%'" "SET PERSIST_ONLY skip_name_resolve=0" "DROP USER 'bug28749668'@'%'" +"SET PERSIST_ONLY replica_exec_mode = DEFAULT" "SELECT * FROM performance_schema.persisted_variables WHERE variable_name='replica_exec_mode'" "SELECT VARIABLE_NAME, VARIABLE_SOURCE FROM performance_schema.variables_info @@ -70811,6 +70986,7 @@ FROM performance_schema.variables_info WHERE VARIABLE_NAME IN 'innodb_fast_shutdown', 'innodb_default_row_format', 'innodb_flush_log_at_trx_commit')" "SELECT @@sort_buffer_size, @@max_connections, @@max_digest_length" "SELECT @@innodb_fast_shutdown, @@innodb_default_row_format, @@innodb_flush_log_at_trx_commit" +"set @a=repeat('A',2000)" "set @b=repeat('A',24000)" "SET GLOBAL init_connect=default" "CREATE USER bug25677422" @@ -71091,6 +71267,8 @@ ORDER BY COLUMN_NAME" "CREATE USER bug12610784@localhost" "SET PASSWORD FOR bug12610784@localhost = 'secret'" "DROP USER bug12610784@localhost" +"CREATE USER bug12818542@localhost +IDENTIFIED WITH 'test_plugin_server' AS 'bug12818542_dest'" "CREATE USER bug12818542_dest@localhost IDENTIFIED BY 'bug12818542_dest_passwd'" "GRANT PROXY ON bug12818542_dest@localhost TO bug12818542@localhost" @@ -71101,6 +71279,7 @@ IDENTIFIED BY 'bug12818542_dest_passwd'" "CREATE USER 'employee'@'localhost' IDENTIFIED BY 'passkey'" "GRANT PROXY ON 'employee'@'localhost' TO 'empl_external'@'localhost'" "ALTER USER employee@localhost PASSWORD EXPIRE" +"DROP USER 'empl_external'@'localhost', 'employee'@'localhost'" "CREATE USER bug20537246@localhost IDENTIFIED WITH 'cleartext_plugin_server' AS ''" "DROP USER bug20537246@localhost" @@ -71188,8 +71367,10 @@ User='mohit' AND Host='localhost'" "CALL mtr.add_suppression(""The plugin 'new_plugin_server' used to authenticate user 'new_user'@'%' is not loaded. Nobody can currently login using this account."")" "CREATE USER plug_user IDENTIFIED WITH test_plugin_server AS 'plug_dest'" -"RENAME USER plug_dest TO new_dest" "GRANT PROXY ON plug_dest TO plug_user" +"RENAME USER plug_dest TO new_dest" +"GRANT PROXY ON new_dest TO plug_user" +"DROP USER plug_user,new_dest" "RENAME USER plug_user TO new_user" "UPDATE mysql.user SET user='plug_user' WHERE user='new_user'" "DROP USER plug_dest,plug_user" @@ -71258,19 +71439,24 @@ IDENTIFIED WITH test_plugin_server AS 'plug_dest'" "GRANT ALL PRIVILEGES ON test_user_db.* TO ''@'localhost'" "GRANT PROXY ON qa_test_5_dest TO qa_test_5_user" "GRANT PROXY ON qa_test_5_dest TO ''@'localhost'" +"DROP USER qa_test_5_user" "DROP USER qa_test_5_dest" "DROP USER ''@'localhost'" "CREATE USER qa_test_6_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'" "CREATE USER qa_test_6_dest IDENTIFIED BY 'dest_passwd'" "GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_6_dest" "GRANT PROXY ON qa_test_6_dest TO qa_test_6_user" +"CREATE USER root IDENTIFIED WITH qa_auth_interface AS 'qa_test_6_dest'" "GRANT PROXY ON qa_test_6_dest TO root" +"REVOKE PROXY ON qa_test_6_dest FROM root" +"DROP USER qa_test_6_user" "DROP USER qa_test_6_dest" "DROP USER 'root'@'%'" "CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_11_dest'" "CREATE USER qa_test_11_dest IDENTIFIED BY 'dest_passwd'" "GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_11_dest" "GRANT PROXY ON qa_test_11_dest TO qa_test_11_user" +"DROP USER qa_test_11_user, qa_test_11_dest" "CREATE USER qa_test_11_user IDENTIFIED WITH qa_auth_server AS 'qa_test_11_dest'" "CREATE USER qa_test_11_dest identified by 'dest_passwd'" "call mtr.add_suppression("".*Password salt for user.*"")" @@ -71537,6 +71723,7 @@ PRIMARY KEY (id), UNIQUE KEY `name` (`name`))" "deallocate prepare stmt1 " "create table t1(a varchar(2), b varchar(3))" "prepare stmt1 from ""select a, b from t1 where (not (a='aa' and b < 'zzz'))""" +"prepare stmt1 from ""select 1 into @var""" "prepare stmt1 from ""create table t1 select 1 as i""" "prepare stmt1 from ""insert into t1 select i from t1""" "prepare stmt1 from 'select 1'" @@ -71878,6 +72065,7 @@ end" "select * from t1 order by 1" "prepare stmt from ""select * from t1 order by ?+1""" "set @a=0" +"set @a=0","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select * from t1 order by 1+1" "prepare stmt from ""repair table t1""" "prepare stmt from ""optimize table t1""" @@ -71962,6 +72150,8 @@ WHERE t1.i = ?""" "insert into t1 values (3,1), (1,2), (2,3)" "prepare stmt from ""create view v1 as select * from t1""" "show create view v1" +"show create view v1",ANSI_QUOTES +"show create view v1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "prepare stmt from ""create view v1 (c,d) as select a,b from t1""" "prepare stmt from ""create view v1 (c) as select b+1 from t1""" "prepare stmt from ""create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1""" @@ -72190,6 +72380,7 @@ END" "DROP PROCEDURE p_int" "DROP PROCEDURE p_decimal" "DROP PROCEDURE IF EXISTS p2" +"DROP PROCEDURE IF EXISTS p2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(OUT v1 CHAR(10)) SET v1 = 'test1'" "CREATE PROCEDURE p2(OUT v2 CHAR(10)) @@ -72723,6 +72914,7 @@ a int primary key, b char(10) "select '2' || '3' " "prepare stmt5 from ' select ''2'' || ''3'' ' " "execute stmt5" +"execute stmt5","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET sql_mode=ansi" "prepare stmt1 from ' flush local privileges ' " "prepare stmt1 from ' KILL 0 '" @@ -77652,6 +77844,7 @@ WHERE t1.x=t2.x AND (SELECT DISTINCT t3.x>0 FROM t2 AS t3)" "SELECT COUNT(*) FROM mysql.general_log WHERE argument LIKE ('%haha%')" "SELECT COUNT(*) FROM mysql.general_log WHERE argument LIKE ('%REDACTED%')" "SELECT argument FROM mysql.general_log WHERE argument LIKE ('SET%')" +"SELECT * FROM performance_schema.persisted_variables ORDER BY variable_name ASC" "SELECT @@global.partial_revokes" "SELECT @@global.auto_increment_increment" "SELECT @@global.back_log" @@ -77659,7 +77852,6 @@ WHERE t1.x=t2.x AND (SELECT DISTINCT t3.x>0 FROM t2 AS t3)" "SET PERSIST_ONLY auto_increment_increment=30" "SET PERSIST_ONLY back_log=200" "SET PERSIST_ONLY performance_schema_error_size=10000" -"SELECT * FROM performance_schema.persisted_variables ORDER BY variable_name ASC" "SET @global_saved_tmp = @@global.offline_mode" "SELECT COUNT(USER) FROM INFORMATION_SCHEMA.PROCESSLIST" "SHOW STATUS LIKE 'threads_connected'" @@ -77694,7 +77886,9 @@ WHERE t1.x=t2.x AND (SELECT DISTINCT t3.x>0 FROM t2 AS t3)" "SET DEBUG_SYNC='materialize_session_variable_array_THD_locked SIGNAL lock_thd_data_acquired'" "CALL mtr.add_suppression(""Source's UUID has changed, its old UUID is"")" "SELECT @@session.session_track_schema" +"SELECT @@session.session_track_schema","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT @@session.session_track_system_variables" +"SELECT @@session.session_track_system_variables","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT @@global.session_track_schema" "SELECT @@session.character_set_client, @@session.character_set_results, @@session.character_set_connection" "SET NAMES 'big5'" @@ -77708,6 +77902,7 @@ WHERE t1.x=t2.x AND (SELECT DISTINCT t3.x>0 FROM t2 AS t3)" "SET @@session.autocommit= ON" "SET @@session.autocommit=OFF, @@time_zone='SYSTEM'" "SELECT @@session.sql_mode" +"SELECT @@session.sql_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@session.session_track_system_variables='sql_mode'" "SET @sql_mode_saved= @@session.sql_mode" "SET @@session.sql_mode='traditional'" @@ -77727,9 +77922,9 @@ END;" "SHOW VARIABLES LIKE 'var1'" "SET @@session.session_track_system_variables='var1,sql_mode,var2'" "SET @@session.sql_mode='ANSI'" -"SET @@session.sql_mode=@@session.sql_mode" -"SET @@session.session_track_system_variables='session_track_system_variables'" -"SET @@session.session_track_schema=false" +"SET @@session.sql_mode=@@session.sql_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @@session.session_track_system_variables='session_track_system_variables'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @@session.session_track_schema=false","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@session.session_track_schema=OFF" "SET @@session.session_track_schema=@@global.session_track_schema" "SET @@session.session_track_system_variables='validate_password_policy,autocommit'" @@ -77928,6 +78123,7 @@ END" "SET @net_buffer_length= @@global.net_buffer_length" "SET GLOBAL max_allowed_packet= 1024" "SET GLOBAL net_buffer_length= 1024" +"SET GLOBAL max_allowed_packet= @max_allowed_packet" "SET GLOBAL net_buffer_length= @net_buffer_length" "SELECT 100" "drop table if exists t1aa,t2aa" @@ -77973,9 +78169,9 @@ c int not null comment 'int column', "SHOW CREATE TABLE `a.1`" "DROP TABLE `a.1`" "SET sql_mode= 'ANSI_QUOTES'" -"CREATE TABLE """"""a"" (i INT)" -"SHOW CREATE TABLE """"""a""" -"DROP TABLE """"""a""" +"CREATE TABLE """"""a"" (i INT)",ANSI_QUOTES +"SHOW CREATE TABLE """"""a""",ANSI_QUOTES +"DROP TABLE """"""a""",ANSI_QUOTES "SET sql_quote_show_create= OFF" "CREATE TABLE `table` (i INT)" "SHOW CREATE TABLE `table`" @@ -79244,6 +79440,7 @@ MESSAGE_TEXT = msg, MYSQL_ERRNO = 1012; end " "drop table t1 " +"drop table t1 ",IGNORE_SPACE "create table t1 (errno integer, msg varchar(128)) " "create trigger t1_ai after insert on t1 for each row begin @@ -79989,8 +80186,11 @@ END " "CALL p5()" "CALL p6()" "DROP PROCEDURE p4" +"DROP PROCEDURE p4","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE p5" +"DROP PROCEDURE p5","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE p6" +"DROP PROCEDURE p6","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RESIGNAL SET MESSAGE_TEXT = asdf; @@ -80708,6 +80908,7 @@ INDEX c1_idx (c1_idx) "SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC" "DELETE FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2" "DROP PROCEDURE IF EXISTS p3" +"DROP PROCEDURE IF EXISTS p3","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION IF EXISTS f3" "CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW @@ -81631,6 +81832,7 @@ end" "create procedure p_20906_a() SET @a=@a+1, @b=@b+1" "show procedure code p_20906_a" "set @b=1" +"set @b=1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "call p_20906_a()" "create procedure p_20906_b() SET @a=@a+1, @b=@b+1, @c=@c+1" "show procedure code p_20906_b" @@ -83449,7 +83651,6 @@ end" "call sp2()" "select 't2',a from t2" "call sp3()" -"drop procedure sp1" "drop procedure sp2" "drop procedure sp3" "create procedure sp1() @@ -83998,21 +84199,36 @@ RETURN 0" "DROP FUNCTION IF EXISTS sp_vars_check_ret4" "DROP FUNCTION IF EXISTS sp_vars_div_zero" "SET @@sql_mode = 'ansi'" +"CALL sp_vars_check_dflt()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CALL sp_vars_check_dflt()" +"CALL sp_vars_check_assignment()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CALL sp_vars_check_assignment()" +"SELECT sp_vars_check_ret1()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT sp_vars_check_ret1()" +"SELECT sp_vars_check_ret2()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT sp_vars_check_ret2()" +"SELECT sp_vars_check_ret3()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT sp_vars_check_ret3()" +"SELECT sp_vars_check_ret4()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT sp_vars_check_ret4()" +"SELECT sp_vars_div_zero()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT sp_vars_div_zero()" +"SET @@sql_mode = 'traditional'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET @@sql_mode = 'traditional'" "DROP PROCEDURE sp_vars_check_dflt" +"DROP PROCEDURE sp_vars_check_dflt","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE sp_vars_check_assignment" +"DROP PROCEDURE sp_vars_check_assignment","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION sp_vars_check_ret1" +"DROP FUNCTION sp_vars_check_ret1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION sp_vars_check_ret2" +"DROP FUNCTION sp_vars_check_ret2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION sp_vars_check_ret3" +"DROP FUNCTION sp_vars_check_ret3","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION sp_vars_check_ret4" +"DROP FUNCTION sp_vars_check_ret4","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP FUNCTION sp_vars_div_zero" +"DROP FUNCTION sp_vars_div_zero","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE v1 BIT; @@ -84042,8 +84258,8 @@ SELECT HEX(v7); SELECT HEX(v8); SELECT HEX(v9); SELECT HEX(v10); -END" -"CREATE TABLE t1(log_msg VARCHAR(1024))" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(log_msg VARCHAR(1024))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(arg VARCHAR(255)) BEGIN INSERT INTO t1 VALUES('p1: step1'); @@ -84135,7 +84351,7 @@ END; ELSE INSERT INTO t1 VALUES('p1: case4: ERROR'); END CASE; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p2() BEGIN DECLARE i TINYINT DEFAULT 3; @@ -84158,34 +84374,35 @@ END CASE; SET i = i - 1; END WHILE; -END" -"CALL p1(10)" -"CALL p1(20)" -"CREATE TABLE t1(col BIGINT UNSIGNED)" -"INSERT INTO t1 VALUE(18446744073709551614)" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(10)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(20)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(col BIGINT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUE(18446744073709551614)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(IN arg BIGINT UNSIGNED) BEGIN SELECT arg; SELECT * FROM t1; SELECT * FROM t1 WHERE col = arg; -END" -"CALL p1(18446744073709551614)" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(18446744073709551614)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(x VARCHAR(10), y CHAR(3)) READS SQL DATA BEGIN SELECT x, y; -END" -"CALL p1('alpha', 'abc')" -"CALL p1('alpha', 'abcdef')" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1('alpha', 'abc')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1('alpha', 'abcdef')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(x DATETIME) BEGIN CREATE TABLE t1 SELECT x; SHOW CREATE TABLE t1; DROP TABLE t1; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(NOW())","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CALL p1(NOW())" -"CALL p1('test')" -"CREATE TABLE t1(b BIT(1))" -"INSERT INTO t1(b) VALUES(b'0'), (b'1')" +"CALL p1('test')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(b BIT(1))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1(b) VALUES(b'0'), (b'1')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN SELECT HEX(b), @@ -84196,7 +84413,7 @@ b = 1, b = TRUE, b IS TRUE FROM t1; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p2() BEGIN DECLARE vb BIT(1); @@ -84219,23 +84436,23 @@ vb IS FALSE, vb = 1, vb = TRUE, vb IS TRUE; -END" -"DROP TABLE IF EXISTS table_12976_a" -"DROP TABLE IF EXISTS table_12976_b" -"DROP PROCEDURE IF EXISTS proc_12976_a" -"DROP PROCEDURE IF EXISTS proc_12976_b" -"CREATE TABLE table_12976_a (val bit(1))" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE IF EXISTS table_12976_a","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE IF EXISTS table_12976_b","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS proc_12976_a","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS proc_12976_b","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE table_12976_a (val bit(1))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE table_12976_b( appname varchar(15), emailperm bit not null default 1, -phoneperm bit not null default 0)" -"insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0')" +phoneperm bit not null default 0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE proc_12976_a() BEGIN declare localvar bit(1); SELECT val INTO localvar FROM table_12976_a; SELECT coalesce(localvar, 1)+1, coalesce(val, 1)+1 FROM table_12976_a; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE proc_12976_b( name varchar(15), out ep bit, @@ -84247,20 +84464,21 @@ SET msg = 'True'; ELSE SET msg = 'False'; END IF; -END" -"INSERT table_12976_a VALUES (0)" -"call proc_12976_a()" -"UPDATE table_12976_a set val=1" -"call proc_12976_b('A', @ep, @msg)" -"select @ep, @msg" -"call proc_12976_b('B', @ep, @msg)" -"DROP TABLE table_12976_a" -"DROP TABLE table_12976_b" -"DROP PROCEDURE proc_12976_a" -"DROP PROCEDURE proc_12976_b" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT table_12976_a VALUES (0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"call proc_12976_a()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"UPDATE table_12976_a set val=1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"call proc_12976_b('A', @ep, @msg)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select @ep, @msg","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"call proc_12976_b('B', @ep, @msg)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE table_12976_a","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE table_12976_b","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE proc_12976_a","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE proc_12976_b","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS p4","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP PROCEDURE IF EXISTS p4" -"DROP PROCEDURE IF EXISTS p5" -"DROP PROCEDURE IF EXISTS p6" +"DROP PROCEDURE IF EXISTS p5","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS p6","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE v TINYINT DEFAULT 1e200; @@ -84300,22 +84518,30 @@ DECLARE var DECIMAL(64,2); SET var = arg; SELECT var; -END" -"CALL p1(1929)" -"CALL p1(1929.00)" -"CALL p1(1929.003)" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(1929)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(1929.00)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(1929.003)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE FUNCTION f1(arg TINYINT UNSIGNED) RETURNS TINYINT +BEGIN +RETURN arg; +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1(arg TINYINT UNSIGNED) RETURNS TINYINT BEGIN RETURN arg; END" -"SELECT f1(-2500)" +"SELECT f1(-2500)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE FUNCTION f1(arg MEDIUMINT) RETURNS MEDIUMINT +BEGIN +RETURN arg; +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1(arg MEDIUMINT) RETURNS MEDIUMINT BEGIN RETURN arg; END" -"SELECT f1(8388699)" -"CREATE TABLE t1(col VARCHAR(255))" -"INSERT INTO t1(col) VALUES('Hello, world!')" +"SELECT f1(8388699)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(col VARCHAR(255))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1(col) VALUES('Hello, world!')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE sp_var INTEGER; @@ -84326,8 +84552,8 @@ SET @user_var = sp_var; SELECT sp_var; SELECT @user_var; -END" -"CREATE TABLE t1(txt VARCHAR(255))" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(txt VARCHAR(255))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1(arg VARCHAR(255)) RETURNS VARCHAR(255) BEGIN DECLARE v1 VARCHAR(255); @@ -84339,37 +84565,37 @@ SET v2 = CONCAT(LOWER(v1), UPPER(v1)); INSERT INTO t1 VALUES(v1), (v2); RETURN CONCAT(LOWER(arg), UPPER(arg)); -END" -"SELECT f1('_aBcDe_')" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT f1('_aBcDe_')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(arg ENUM('a', 'b')) BEGIN SELECT arg; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p2(arg ENUM('a', 'b')) BEGIN DECLARE var ENUM('c', 'd') DEFAULT arg; SHOW WARNINGS; SELECT arg, var; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1(arg ENUM('a', 'b')) RETURNS ENUM('c', 'd') BEGIN RETURN arg; -END" -"CALL p1('c')" -"CALL p2('a')" -"SELECT f1('a')" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1('c')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p2('a')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT f1('a')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(arg VARCHAR(255)) BEGIN SELECT CHARSET(arg); -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p2(arg VARCHAR(255) CHARACTER SET utf8mb3) BEGIN SELECT CHARSET(arg); -END" -"CALL p1('t')" -"CALL p1(_UTF8MB3 't')" -"CALL p2('t')" -"CALL p2(_LATIN1 't')" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1('t')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(_UTF8MB3 't')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p2('t')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p2(_LATIN1 't')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(arg1 BINARY(2), arg2 VARBINARY(2)) BEGIN DECLARE var1 BINARY(2) DEFAULT 0x41; @@ -84377,25 +84603,25 @@ DECLARE var2 VARBINARY(2) DEFAULT 0x42; SELECT HEX(arg1), HEX(arg2); SELECT HEX(var1), HEX(var2); -END" -"CALL p1(0x41, 0x42)" -"CREATE TABLE t1(col1 TINYINT, col2 TINYINT)" -"INSERT INTO t1 VALUES(1, 2), (11, 12)" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1(0x41, 0x42)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(col1 TINYINT, col2 TINYINT)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(1, 2), (11, 12)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(arg TINYINT) BEGIN SELECT arg; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1(x VARCHAR(50)) BEGIN SET x = SUBSTRING(x, 1, 3); SELECT x; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1(x VARCHAR(50)) RETURNS VARCHAR(50) BEGIN RETURN SUBSTRING(x, 1, 3); -END" -"CALL p1('abcdef')" -"SELECT f1('ABCDEF')" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL p1('abcdef')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT f1('ABCDEF')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE FUNCTION f1() RETURNS VARCHAR(2000) BEGIN DECLARE var VARCHAR(2000); @@ -84405,7 +84631,7 @@ SET var = CONCAT(var, 'abc'); SET var = CONCAT(var, ''); RETURN var; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE v_char VARCHAR(255); @@ -84420,9 +84646,9 @@ SET v_char = 'def'; SET v_text = concat(v_text, '|', v_char); SELECT v_text; -END" -"DROP PROCEDURE IF EXISTS bug27415_text_test" -"DROP PROCEDURE IF EXISTS bug27415_text_test2" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS bug27415_text_test","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE IF EXISTS bug27415_text_test2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE bug27415_text_test(entity_id_str_in text) BEGIN DECLARE str_remainder text; @@ -84432,7 +84658,7 @@ SET str_remainder = entity_id_str_in; select 'before substr', str_remainder; SET str_remainder = SUBSTRING(str_remainder, 3); select 'after substr', str_remainder; -END" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE bug27415_text_test2(entity_id_str_in text) BEGIN DECLARE str_remainder text; @@ -84442,11 +84668,11 @@ SET str_remainder2 = entity_id_str_in; select 'before substr', str_remainder2; SET str_remainder = SUBSTRING(str_remainder2, 3); select 'after substr', str_remainder; -END" -"CALL bug27415_text_test('a,b,c')" -"CALL bug27415_text_test2('a,b,c')" -"DROP PROCEDURE bug27415_text_test" -"DROP PROCEDURE bug27415_text_test2" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL bug27415_text_test('a,b,c')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL bug27415_text_test2('a,b,c')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE bug27415_text_test","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE bug27415_text_test2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create function f1() returns int begin if @a=1 then set @b='abc'; @@ -84454,33 +84680,33 @@ else set @b=1; end if; set @a=1; return 0; -end" -"insert into t1 (a) values (1), (2)" -"select f1(), @b from t1" -"set @b:='test'" +end","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into t1 (a) values (1), (2)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select f1(), @b from t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @b:='test'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE ctest() BEGIN DECLARE i CHAR(16); DECLARE j INT; SET i= 'string'; SET j= 1 + i; -END" -"CALL ctest()" -"DROP PROCEDURE ctest" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL ctest()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE ctest","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE vctest() BEGIN DECLARE i VARCHAR(16); DECLARE j INT; SET i= 'string'; SET j= 1 + i; -END" -"CALL vctest()" -"DROP PROCEDURE vctest" -"CREATE TABLE t (a INT PRIMARY KEY, b TEXT, FULLTEXT(b)) ENGINE=InnoDB" -"CREATE FUNCTION f() RETURNS TEXT RETURN @@GLOBAL.innodb_ft_aux_table" -"SELECT @@GLOBAL.innodb_ft_aux_table, f()" -"SET GLOBAL innodb_ft_aux_table=""test/t""" -"SET GLOBAL innodb_ft_aux_table= default" +END","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CALL vctest()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP PROCEDURE vctest","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t (a INT PRIMARY KEY, b TEXT, FULLTEXT(b)) ENGINE=InnoDB","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE FUNCTION f() RETURNS TEXT RETURN @@GLOBAL.innodb_ft_aux_table","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT @@GLOBAL.innodb_ft_aux_table, f()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET GLOBAL innodb_ft_aux_table=""test/t""","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET GLOBAL innodb_ft_aux_table= default","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 ( id char(16) not null default '', data int not null @@ -84848,8 +85074,10 @@ end" "insert into t1 values (""i4"", 77)" "drop procedure into_test4" "drop procedure if exists into_outfile" +"call into_outfile(""ofile"", 1)" "drop procedure into_outfile" "drop procedure if exists into_dumpfile" +"call into_dumpfile(""dfile"", 1)" "drop procedure into_dumpfile" "drop procedure if exists create_select" "create procedure create_select(x char(16), y int) @@ -85058,7 +85286,7 @@ comment 'Characteristics function test'" "drop function chistics" "insert into t1 values (""foo"", 1), (""bar"", 2), (""zip"", 3)" "set @@sql_mode = 'ANSI'" -"drop procedure if exists modes" +"drop procedure if exists modes","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create procedure modes(out c1 int, out c2 int) begin declare done int default 0; @@ -85076,8 +85304,10 @@ set c2 = c2 + 1; end if; until done end repeat; close c; -end" +end","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @@sql_mode = ''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set @@sql_mode = ''" +"set @@sql_mode = ''",ANSI_QUOTES "set sql_select_limit = 1" "call modes(@c1, @c2)" "set sql_select_limit = default" @@ -85327,6 +85557,7 @@ select (select s1 from t3) from t3" return 5" "select `foo` ()" "drop function `foo`" +"drop function `foo`",ANSI_QUOTES "drop function if exists t1max" "create function t1max() returns int begin @@ -86034,15 +86265,15 @@ end" comment 'Joe''s procedure' insert into `t1` values (""foo"", 1)" "set @@sql_mode = 'ANSI_QUOTES'" -"drop procedure if exists bug2564_2" +"drop procedure if exists bug2564_2",ANSI_QUOTES "create procedure bug2564_2() -insert into ""t1"" values ('foo', 1)" +insert into ""t1"" values ('foo', 1)",ANSI_QUOTES "drop function if exists bug2564_3" "create function bug2564_3(x int, y int) returns int return x || y" -"drop function if exists bug2564_4" +"drop function if exists bug2564_4","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create function bug2564_4(x int, y int) returns int -return x || y" +return x || y","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "show create procedure bug2564_1" "show create procedure bug2564_2" "show create function bug2564_3" @@ -87467,6 +87698,7 @@ end; end" "call bug5967(""a - stored procedure parameter"")" "drop procedure bug5967" +"drop procedure if exists bug13012" "call bug13012()" "drop procedure bug13012" "create procedure bug13012() @@ -88168,7 +88400,9 @@ FROM t3 LEFT JOIN v1 ON t3.t3_id = 0" "create function pi() returns varchar(50) return ""pie, my favorite desert.""" "SET SQL_MODE='IGNORE_SPACE'" +"select pi(), pi ()",IGNORE_SPACE "select pi(), pi ()" +"select test.pi(), test.pi ()",IGNORE_SPACE "select test.pi(), test.pi ()" "drop function pi" "drop function if exists test.database" @@ -88177,8 +88411,11 @@ return ""pie, my favorite desert.""" "create database nowhere" "use nowhere" "drop database nowhere" +"select database(), database ()",IGNORE_SPACE "select database(), database ()" +"select current_user(), current_user ()",IGNORE_SPACE "select current_user(), current_user ()" +"select sha2(""aaa"", 0), sha2 (""aaa"", 0)",IGNORE_SPACE "select sha2(""aaa"", 0), sha2 (""aaa"", 0)" "create function `database`() returns varchar(50) return ""Stored function database""" @@ -88186,8 +88423,11 @@ return ""Stored function database""" return ""Stored function current_user""" "create function sha2(x varchar(50), y integer) returns varchar(50) return ""Stored function sha2""" +"select test.database(), test.database ()",IGNORE_SPACE "select test.database(), test.database ()" +"select test.current_user(), test.current_user ()",IGNORE_SPACE "select test.current_user(), test.current_user ()" +"select test.sha2(""aaa"", 0), test.sha2 (""aaa"", 0)",IGNORE_SPACE "select test.sha2(""aaa"", 0), test.sha2 (""aaa"", 0)" "drop function test.database" "drop function test.current_user" @@ -89072,6 +89312,7 @@ SET @@default_storage_engine = DEFAULT" "SET @@default_storage_engine = InnoDB" "SET @@default_storage_engine = @default_storage_engine_saved" "SET @org_mode= @@sql_mode" +"SET @org_mode= @@sql_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE PROCEDURE p1() BEGIN DECLARE `v` TINYINT; @@ -89613,6 +89854,7 @@ END" "CREATE FUNCTION mIxEdCaSe() RETURNS INT RETURN 1" "SET DEBUG_SYNC='after_shared_lock_pname SIGNAL locked WAIT_FOR continue'" "SET DEBUG_SYNC='after_acquiring_mdl_lock_on_routine SIGNAL locked WAIT_FOR continue'" +"CREATE PROCEDURE mIxEdCaSe() BEGIN END" "drop procedure if exists bug8850" "create procedure bug8850() begin @@ -90368,18 +90610,22 @@ UNIQUE KEY `email` USING BTREE (`email`) ) ENGINE=HEAP CHARSET=latin1 ROW_FORMAT DYNAMIC" "set @@sql_mode=""""" "show variables like 'sql_mode'" +"show variables like 'sql_mode'",ANSI_QUOTES "set @@sql_mode=""ansi_quotes""" -"set session sql_mode = ''" +"set session sql_mode = ''",ANSI_QUOTES "create table t1 ( min_num dec(6,6) default .000001)" +"create table t1 ( min_num dec(6,6) default .000001)",IGNORE_SPACE "set session sql_mode = 'IGNORE_SPACE'" -"create table t1 ( min_num dec(6,6) default 0.000001)" -"set session sql_mode=ansi" +"create table t1 ( min_num dec(6,6) default 0.000001)",IGNORE_SPACE +"set session sql_mode=ansi",IGNORE_SPACE "create table t1 (f1 integer auto_increment primary key, -f2 timestamp not null default current_timestamp on update current_timestamp)" -"SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=''" +f2 timestamp not null default current_timestamp on update current_timestamp)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "show local variables like 'SQL_MODE'" +"show local variables like 'SQL_MODE'",NO_BACKSLASH_ESCAPES "CREATE TABLE t1 (p int not null auto_increment, a varchar(20), primary key(p)) charset latin1" +"CREATE TABLE t1 (p int not null auto_increment, a varchar(20), primary key(p)) charset latin1",NO_BACKSLASH_ESCAPES "INSERT t1 (a) VALUES ('\\'), ('\n'), @@ -90402,8 +90648,32 @@ f2 timestamp not null default current_timestamp on update current_timestamp)" ('\\\%'), ('\\\\%') " +"INSERT t1 (a) VALUES +('\\'), +('\n'), +('\b'), +('\r'), +('\t'), +('\x'), +('\a'), +('\aa'), +('\\a'), +('\\aa'), +('_'), +('\_'), +('\\_'), +('\\\_'), +('\\\\_'), +('%'), +('\%'), +('\\%'), +('\\\%'), +('\\\\%') +",NO_BACKSLASH_ESCAPES "SELECT p, hex(a) FROM t1" +"SELECT p, hex(a) FROM t1",NO_BACKSLASH_ESCAPES "delete from t1 where a in ('\n','\r','\t', '\b')" +"delete from t1 where a in ('\n','\r','\t', '\b')",NO_BACKSLASH_ESCAPES "select masks.p, masks.a as mask, @@ -90412,45 +90682,62 @@ from t1 as masks left join t1 as examples on examples.a LIKE masks.a order by masks.p, example" +"select +masks.p, +masks.a as mask, +examples.a as example +from +t1 as masks +left join t1 as examples on examples.a LIKE masks.a +order by masks.p, example",NO_BACKSLASH_ESCAPES "SET @@SQL_MODE='NO_BACKSLASH_ESCAPES'" +"SET @@SQL_MODE='NO_BACKSLASH_ESCAPES'",NO_BACKSLASH_ESCAPES +"SELECT 'a\\b', 'a\\\"b', 'a''\\b', 'a''\\\"b'",NO_BACKSLASH_ESCAPES "SELECT 'a\\b', 'a\\\"b', 'a''\\b', 'a''\\\"b'" +"SELECT ""a\\b"", ""a\\\'b"", ""a""""\\b"", ""a""""\\\'b""",NO_BACKSLASH_ESCAPES "SELECT ""a\\b"", ""a\\\'b"", ""a""""\\b"", ""a""""\\\'b""" +"SET @@SQL_MODE=''",NO_BACKSLASH_ESCAPES "SET @@SQL_MODE=''" +"SET @@SQL_MODE=''",ANSI_QUOTES "create function `foo` () returns int return 5" +"create function `foo` () returns int return 5",ANSI_QUOTES "show create function `foo`" +"show create function `foo`",ANSI_QUOTES "SET @@SQL_MODE='ANSI_QUOTES'" +"create view v2 as select a from t2 where a in (select a from v1)",ANSI_QUOTES "create view v2 as select a from t2 where a in (select a from v1)" +"drop view v2, v1",ANSI_QUOTES "drop view v2, v1" -"set sql_mode=2097152" -"set sql_mode=4194304" -"set sql_mode=32+(65536*4)" -"set sql_mode=PAD_CHAR_TO_FULL_LENGTH" +"set sql_mode=2097152",ANSI_QUOTES +"set sql_mode=4194304",ANSI_QUOTES +"set sql_mode=32+(65536*4)",ANSI_QUOTES +"set sql_mode=PAD_CHAR_TO_FULL_LENGTH",ANSI_QUOTES "create table t1 (a int auto_increment primary key, b char(5))" "insert into t1 (b) values('a'),('b\t'),('c ')" "select concat('x',b,'x') from t1" "set sql_mode=0" -"create user mysqltest_32753@localhost" -"set @OLD_SQL_MODE=@@SESSION.SQL_MODE" -"set session sql_mode='PAD_CHAR_TO_FULL_LENGTH'" -"drop user mysqltest_32753@localhost" -"SET @@sql_mode='traditional'" +"create user mysqltest_32753@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @OLD_SQL_MODE=@@SESSION.SQL_MODE","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set session sql_mode='PAD_CHAR_TO_FULL_LENGTH'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop user mysqltest_32753@localhost","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @@sql_mode='traditional'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SELECT @@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%'" -"CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'" -"CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'" -"CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20))" -"GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'" -"GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'" -"SET @OLD_SQL_MODE = @@SESSION.SQL_MODE" -"SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'" +"CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET @OLD_SQL_MODE = @@SESSION.SQL_MODE","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "DROP USER 'user_PCTFL'@'localhost'" "SET SESSION SQL_MODE = @OLD_SQL_MODE" -"DROP USER 'user_no_PCTFL'@'localhost'" -"SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'" -"SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'" -"SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'" -"DROP TABLE IF EXISTS test_table" -"DROP FUNCTION IF EXISTS test_function" -"CREATE TABLE test_table (c1 CHAR(50))" +"DROP USER 'user_no_PCTFL'@'localhost'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP TABLE IF EXISTS test_table","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"DROP FUNCTION IF EXISTS test_function","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE test_table (c1 CHAR(50))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "PREPARE insert_stmt FROM 'INSERT INTO test_table VALUES (?)'" "PREPARE update_stmt FROM 'UPDATE test_table SET c1= ? WHERE c1= ?'" "CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50) @@ -90460,6 +90747,13 @@ SELECT c1 INTO char_val FROM test_table WHERE c1=var; RETURN char_val; END " +"CREATE FUNCTION test_function(var CHAR(50)) RETURNS CHAR(50) +BEGIN +DECLARE char_val CHAR(50); +SELECT c1 INTO char_val FROM test_table WHERE c1=var; +RETURN char_val; +END +",NO_BACKSLASH_ESCAPES "SET @var1='abcd\'ef'" "SET @var2='abcd\"ef'" "SET @var3='abcd\bef'" @@ -90479,59 +90773,104 @@ END "SET @to_var8='wxyz\%ef'" "SET @to_var9='wxyz\_ef'" "EXECUTE insert_stmt USING @var1" +"EXECUTE insert_stmt USING @var1",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var2" +"EXECUTE insert_stmt USING @var2",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var3" +"EXECUTE insert_stmt USING @var3",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var4" +"EXECUTE insert_stmt USING @var4",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var5" +"EXECUTE insert_stmt USING @var5",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var6" +"EXECUTE insert_stmt USING @var6",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var7" +"EXECUTE insert_stmt USING @var7",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var8" +"EXECUTE insert_stmt USING @var8",NO_BACKSLASH_ESCAPES "EXECUTE insert_stmt USING @var9" +"EXECUTE insert_stmt USING @var9",NO_BACKSLASH_ESCAPES "SELECT * FROM test_table" +"SELECT * FROM test_table",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var1, @var1" +"EXECUTE update_stmt USING @to_var1, @var1",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var2, @var2" +"EXECUTE update_stmt USING @to_var2, @var2",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var3, @var3" +"EXECUTE update_stmt USING @to_var3, @var3",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var4, @var4" +"EXECUTE update_stmt USING @to_var4, @var4",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var5, @var5" +"EXECUTE update_stmt USING @to_var5, @var5",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var6, @var6" +"EXECUTE update_stmt USING @to_var6, @var6",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var7, @var7" +"EXECUTE update_stmt USING @to_var7, @var7",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var8, @var8" +"EXECUTE update_stmt USING @to_var8, @var8",NO_BACKSLASH_ESCAPES "EXECUTE update_stmt USING @to_var9, @var9" +"EXECUTE update_stmt USING @to_var9, @var9",NO_BACKSLASH_ESCAPES "select test_function(@to_var1)" +"select test_function(@to_var1)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var2)" +"SELECT test_function(@to_var2)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var3)" +"SELECT test_function(@to_var3)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var4)" +"SELECT test_function(@to_var4)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var5)" +"SELECT test_function(@to_var5)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var6)" +"SELECT test_function(@to_var6)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var7)" +"SELECT test_function(@to_var7)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var8)" +"SELECT test_function(@to_var8)",NO_BACKSLASH_ESCAPES "SELECT test_function(@to_var9)" +"SELECT test_function(@to_var9)",NO_BACKSLASH_ESCAPES "DELETE FROM test_table" "DROP FUNCTION test_function" +"DROP FUNCTION test_function",NO_BACKSLASH_ESCAPES "SET @@sql_mode='NO_BACKSLASH_ESCAPES'" -"DROP TABLE test_table" -"SET sql_mode= 'NO_ZERO_DATE'" +"DROP TABLE test_table",NO_BACKSLASH_ESCAPES +"SET sql_mode= 'NO_ZERO_DATE'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "SET sql_mode= 'NO_ZERO_IN_DATE'" "SET sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO'" "CREATE USER 'user\'s_12601974'@'localhost'" "DROP USER 'user\'s_12601974'@'localhost'" "CREATE USER 'user\"s_12601974'@'localhost'" +"CREATE USER 'user\"s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\"s_12601974'@'localhost'" +"DROP USER 'user\"s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\bs_12601974'@'localhost'" +"CREATE USER 'user\bs_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\bs_12601974'@'localhost'" +"DROP USER 'user\bs_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\ns_12601974'@'localhost'" +"CREATE USER 'user\ns_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\ns_12601974'@'localhost'" +"DROP USER 'user\ns_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\rs_12601974'@'localhost'" +"CREATE USER 'user\rs_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\rs_12601974'@'localhost'" +"DROP USER 'user\rs_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\ts_12601974'@'localhost'" +"CREATE USER 'user\ts_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\ts_12601974'@'localhost'" +"DROP USER 'user\ts_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\\s_12601974'@'localhost'" +"CREATE USER 'user\\s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\\s_12601974'@'localhost'" +"DROP USER 'user\\s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\%s_12601974'@'localhost'" +"CREATE USER 'user\%s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\%s_12601974'@'localhost'" +"DROP USER 'user\%s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "CREATE USER 'user\_s_12601974'@'localhost'" +"CREATE USER 'user\_s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES "DROP USER 'user\_s_12601974'@'localhost'" -"SELECT '\''" +"DROP USER 'user\_s_12601974'@'localhost'",NO_BACKSLASH_ESCAPES +"SELECT '\''","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "CREATE TABLE test(id INT, count DOUBLE)" "INSERT INTO test VALUES (1,0), (2,0)" "PREPARE stmt FROM 'UPDATE test SET count = count + 1 WHERE id = ?'" @@ -90582,6 +90921,7 @@ WHERE VARIABLE_NAME = 'Current_tls_ca' AND VARIABLE_VALUE = @orig_ssl_ca" "ALTER INSTANCE RELOAD TLS NO ROLLBACK ON ERROR" "SELECT COUNT(*) FROM performance_schema.session_status WHERE VARIABLE_NAME = 'Current_tls_ca' AND VARIABLE_VALUE = 'gizmo'" +"SET GLOBAL ssl_ca = @orig_ssl_ca" "SET @orig_ssl_cert= @@global.ssl_cert" "SET @orig_ssl_key= @@global.ssl_key" "SET @orig_ssl_capath= @@global.ssl_capath" @@ -90602,7 +90942,6 @@ VARIABLE_NAME IN 'Current_tls_ciphersuites', 'Current_tls_crl', 'Current_tls_crlpath') AND VARIABLE_VALUE != 'gizmo' ORDER BY VARIABLE_NAME" -"SET GLOBAL ssl_ca = @orig_ssl_ca" "SET GLOBAL ssl_cert = @orig_ssl_cert" "SET GLOBAL ssl_key = @orig_ssl_key" "SET GLOBAL ssl_capath = @orig_ssl_capath" @@ -90757,10 +91096,11 @@ END; "SET @binlog_handler_commit= IF(@@global.log_bin, 1, 0)" "SELECT (SELECT val FROM t1 WHERE id = 3) - (SELECT val FROM t1 WHERE id = 2) = 1 + @binlog_handler_commit" "set @@sql_mode='ansi,traditional'" -"CREATE TABLE t1 (col1 date)" -"INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29')" -"INSERT INTO t1 VALUES('0000-10-31')" -"set @@sql_mode='STRICT_ALL_TABLES'" +"set @@sql_mode='ansi,traditional'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 date)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES('0000-10-31')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @@sql_mode='STRICT_ALL_TABLES'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "INSERT INTO t1 VALUES('2004-01-03'),('2004-0-31')" "set @@sql_mode='STRICT_ALL_TABLES,NO_ZERO_IN_DATE'" "INSERT IGNORE INTO t1 VALUES('2004-0-29')" @@ -90768,8 +91108,10 @@ END; "INSERT IGNORE INTO t1 VALUES('0000-00-00')" "INSERT INTO t1 VALUES ('2004-0-30')" "set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES'" +"set @@sql_mode='STRICT_ALL_TABLES,ALLOW_INVALID_DATES'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "INSERT INTO t1 VALUES ('2004-2-30')" -"INSERT IGNORE INTO t1 VALUES('2004-02-29'),('2004-13-15'),('0000-00-00')" +"INSERT IGNORE INTO t1 VALUES('2004-02-29'),('2004-13-15'),('0000-00-00')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @@sql_mode='strict_trans_tables'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "set @@sql_mode='strict_trans_tables'" "CREATE TABLE t1 (col1 date) engine=myisam" "INSERT INTO t1 VALUES ('2004-1-2'), ('2004-13-31'),('2004-1-3')" @@ -90777,100 +91119,102 @@ END; "INSERT ignore INTO t1 VALUES('2003-02-30')" "INSERT ignore INTO t1 VALUES('2003-02-31')" "CREATE TABLE t1 (col1 date) engine=innodb" -"CREATE TABLE t1 (col1 datetime)" -"INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00')" -"INSERT INTO t1 VALUES('0000-10-31 15:30:00')" -"CREATE TABLE t1 (col1 timestamp)" +"CREATE TABLE t1 (col1 datetime)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES('0000-10-31 15:30:00')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 timestamp)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('0000-00-00 00:00:00')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "INSERT IGNORE INTO t1 VALUES('0000-00-00 00:00:00')" "INSERT INTO t1 VALUES('0000-00-00 00:00:00')" -"CREATE TABLE t1 (col1 date, col2 datetime, col3 timestamp)" -"INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'))" -"INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'))" -"INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'))" -"INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE))" -"INSERT INTO t1 (col2) VALUES (CAST('2004-10-15 10:15' AS DATETIME))" -"INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME))" -"INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE))" -"INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME))" -"INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE))" -"INSERT INTO t1 (col2) VALUES (CONVERT('2004-10-15 10:15',DATETIME))" -"INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME))" -"INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE))" -"INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME))" -"CREATE TABLE t1(col1 TINYINT, col2 TINYINT UNSIGNED)" -"INSERT INTO t1 VALUES(-128,0),(0,0),(127,255),('-128','0'),('0','0'),('127','255'),(-128.0,0.0),(0.0,0.0),(127.0,255.0)" -"SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 2" -"SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 1" -"set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'" +"CREATE TABLE t1 (col1 date, col2 datetime, col3 timestamp)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES (CAST('2004-10-15 10:15' AS DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES (CONVERT('2004-10-15 10:15',DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(col1 TINYINT, col2 TINYINT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-128,0),(0,0),(127,255),('-128','0'),('0','0'),('127','255'),(-128.0,0.0),(0.0,0.0),(127.0,255.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 2","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "INSERT INTO t1 values (1/0,1/0)" -"INSERT IGNORE INTO t1 (col1) VALUES ('2a')" -"INSERT IGNORE INTO t1 values (1/0,1/0)" -"set @@sql_mode='ansi'" -"INSERT IGNORE INTO t1 VALUES('-129','-1'),('128','256')" -"INSERT IGNORE INTO t1 VALUES(-129.0,-1.0),(128.0,256.0)" -"UPDATE IGNORE t1 SET col2=1/NULL where col1=0" -"CREATE TABLE t1(col1 SMALLINT, col2 SMALLINT UNSIGNED)" -"INSERT INTO t1 VALUES(-32768,0),(0,0),(32767,65535),('-32768','0'),('32767','65535'),(-32768.0,0.0),(32767.0,65535.0)" -"INSERT IGNORE INTO t1 VALUES(-32769,-1),(32768,65536)" -"INSERT IGNORE INTO t1 VALUES('-32769','-1'),('32768','65536')" -"INSERT IGNORE INTO t1 VALUES(-32769,-1.0),(32768.0,65536.0)" -"CREATE TABLE t1 (col1 MEDIUMINT, col2 MEDIUMINT UNSIGNED)" -"INSERT INTO t1 VALUES(-8388608,0),(0,0),(8388607,16777215),('-8388608','0'),('8388607','16777215'),(-8388608.0,0.0),(8388607.0,16777215.0)" -"INSERT IGNORE INTO t1 VALUES(-8388609,-1),(8388608,16777216)" -"INSERT IGNORE INTO t1 VALUES('-8388609','-1'),('8388608','16777216')" -"INSERT IGNORE INTO t1 VALUES(-8388609.0,-1.0),(8388608.0,16777216.0)" -"CREATE TABLE t1 (col1 INT, col2 INT UNSIGNED)" -"INSERT INTO t1 VALUES(-2147483648,0),(0,0),(2147483647,4294967295),('-2147483648','0'),('2147483647','4294967295'),(-2147483648.0,0.0),(2147483647.0,4294967295.0)" -"INSERT IGNORE INTO t1 values (-2147483649, -1),(2147643648,4294967296)" -"INSERT IGNORE INTO t1 values ('-2147483649', '-1'),('2147643648','4294967296')" -"INSERT IGNORE INTO t1 values (-2147483649.0, -1.0),(2147643648.0,4294967296.0)" -"CREATE TABLE t1 (col1 BIGINT, col2 BIGINT UNSIGNED)" -"INSERT INTO t1 VALUES(-9223372036854775808,0),(0,0),(9223372036854775807,18446744073709551615)" -"INSERT INTO t1 VALUES('-9223372036854775808','0'),('9223372036854775807','18446744073709551615')" -"INSERT INTO t1 VALUES(-9223372036854774000.0,0.0),(9223372036854775700.0,1844674407370954000.0)" -"INSERT IGNORE INTO t1 VALUES(-9223372036854775809,-1),(9223372036854775808,18446744073709551616)" -"INSERT IGNORE INTO t1 VALUES('-9223372036854775809','-1'),('9223372036854775808','18446744073709551616')" -"INSERT IGNORE INTO t1 VALUES(-9223372036854785809.0,-1.0),(9223372036854785808.0,18446744073709551616.0)" -"CREATE TABLE t1 (col1 NUMERIC(4,2))" -"INSERT INTO t1 VALUES (10.55),(10.5555),(0),(-10.55),(-10.5555),(11),(1e+01)" -"INSERT INTO t1 VALUES ('10.55'),('10.5555'),('-10.55'),('-10.5555'),('11'),('1e+01')" -"INSERT IGNORE INTO t1 values (1/0)" -"INSERT IGNORE INTO t1 VALUES(1000),(-1000)" -"INSERT IGNORE INTO t1 VALUES('1000'),('-1000')" -"INSERT IGNORE INTO t1 VALUES(1000.0),(-1000.0)" -"UPDATE IGNORE t1 SET col1=1/NULL where col1=0" -"CREATE TABLE t1 (col1 FLOAT, col2 FLOAT UNSIGNED)" -"INSERT INTO t1 VALUES (-1.1E-37,0),(+3.4E+38,+3.4E+38)" -"INSERT INTO t1 VALUES ('-1.1E-37',0),('+3.4E+38','+3.4E+38')" -"INSERT INTO t1 (col1) VALUES (3E-46)" -"INSERT IGNORE INTO t1 (col1) VALUES (1/0)" -"INSERT IGNORE INTO t1 VALUES (+3.4E+39,-3.4E+39)" -"INSERT IGNORE INTO t1 VALUES ('+3.4E+39','-3.4E+39')" -"CREATE TABLE t1 (col1 DOUBLE PRECISION, col2 DOUBLE PRECISION UNSIGNED)" -"INSERT INTO t1 VALUES (-2.2E-307,0),(2E-307,0),(+1.7E+308,+1.7E+308)" -"INSERT INTO t1 VALUES ('-2.2E-307',0),('-2E-307',0),('+1.7E+308','+1.7E+308')" -"INSERT INTO t1 (col1) VALUES (-2.2E-330)" -"INSERT IGNORE INTO t1 (col1) values (1/0)" -"INSERT IGNORE INTO t1 VALUES ('+2.0E+309','-2.0E+309')" -"CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6))" -"INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ')" -"INSERT INTO t1 (col2) VALUES ('hello ')" -"INSERT IGNORE INTO t1 VALUES ('hellobob', 'hellobob')" -"UPDATE IGNORE t1 SET col2 ='hellotrudy' WHERE col2 ='he'" -"CREATE TABLE t1 (col1 enum('red','blue','green'))" -"INSERT INTO t1 VALUES ('red'),('blue'),('green')" -"INSERT IGNORE INTO t1 VALUES ('yellow')" -"UPDATE IGNORE t1 SET col1 ='yellow' WHERE col1 ='blue'" -"CREATE TABLE t1 (col1 INT NOT NULL, col2 CHAR(5) NOT NULL, col3 DATE NOT NULL)" -"INSERT INTO t1 VALUES (100, 'hello', '2004-08-20')" -"INSERT INTO t1 (col1,col2,col3) VALUES (101, 'hell2', '2004-08-21')" -"INSERT IGNORE INTO t1 values (NULL,NULL,NULL)" -"CREATE TABLE t1 (col1 INT NOT NULL default 99, col2 CHAR(6) NOT NULL)" -"INSERT INTO t1 VALUES (1, 'hello')" -"INSERT INTO t1 (col2) VALUES ('hello2')" -"INSERT IGNORE INTO t1 values (NULL,NULL)" -"INSERT IGNORE INTO t1 (col1) values (3)" -"INSERT IGNORE INTO t1 () values ()" +"INSERT INTO t1 values (1/0,1/0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 (col1) VALUES ('2a')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (1/0,1/0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"set @@sql_mode='ansi'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('-129','-1'),('128','256')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-129.0,-1.0),(128.0,256.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"UPDATE IGNORE t1 SET col2=1/NULL where col1=0","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1(col1 SMALLINT, col2 SMALLINT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-32768,0),(0,0),(32767,65535),('-32768','0'),('32767','65535'),(-32768.0,0.0),(32767.0,65535.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-32769,-1),(32768,65536)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('-32769','-1'),('32768','65536')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-32769,-1.0),(32768.0,65536.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 MEDIUMINT, col2 MEDIUMINT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-8388608,0),(0,0),(8388607,16777215),('-8388608','0'),('8388607','16777215'),(-8388608.0,0.0),(8388607.0,16777215.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-8388609,-1),(8388608,16777216)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('-8388609','-1'),('8388608','16777216')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-8388609.0,-1.0),(8388608.0,16777216.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 INT, col2 INT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-2147483648,0),(0,0),(2147483647,4294967295),('-2147483648','0'),('2147483647','4294967295'),(-2147483648.0,0.0),(2147483647.0,4294967295.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (-2147483649, -1),(2147643648,4294967296)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values ('-2147483649', '-1'),('2147643648','4294967296')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (-2147483649.0, -1.0),(2147643648.0,4294967296.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 BIGINT, col2 BIGINT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-9223372036854775808,0),(0,0),(9223372036854775807,18446744073709551615)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES('-9223372036854775808','0'),('9223372036854775807','18446744073709551615')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES(-9223372036854774000.0,0.0),(9223372036854775700.0,1844674407370954000.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-9223372036854775809,-1),(9223372036854775808,18446744073709551616)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('-9223372036854775809','-1'),('9223372036854775808','18446744073709551616')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(-9223372036854785809.0,-1.0),(9223372036854785808.0,18446744073709551616.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 NUMERIC(4,2))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES (10.55),(10.5555),(0),(-10.55),(-10.5555),(11),(1e+01)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES ('10.55'),('10.5555'),('-10.55'),('-10.5555'),('11'),('1e+01')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (1/0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(1000),(-1000)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES('1000'),('-1000')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES(1000.0),(-1000.0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"UPDATE IGNORE t1 SET col1=1/NULL where col1=0","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 FLOAT, col2 FLOAT UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES (-1.1E-37,0),(+3.4E+38,+3.4E+38)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES ('-1.1E-37',0),('+3.4E+38','+3.4E+38')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES (3E-46)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 (col1) VALUES (1/0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES (+3.4E+39,-3.4E+39)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES ('+3.4E+39','-3.4E+39')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 DOUBLE PRECISION, col2 DOUBLE PRECISION UNSIGNED)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES (-2.2E-307,0),(2E-307,0),(+1.7E+308,+1.7E+308)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES ('-2.2E-307',0),('-2E-307',0),('+1.7E+308','+1.7E+308')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1) VALUES (-2.2E-330)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 (col1) values (1/0)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES ('+2.0E+309','-2.0E+309')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES ('hello ')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES ('hellobob', 'hellobob')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"UPDATE IGNORE t1 SET col2 ='hellotrudy' WHERE col2 ='he'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 enum('red','blue','green'))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES ('red'),('blue'),('green')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 VALUES ('yellow')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"UPDATE IGNORE t1 SET col1 ='yellow' WHERE col1 ='blue'","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 INT NOT NULL, col2 CHAR(5) NOT NULL, col3 DATE NOT NULL)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES (100, 'hello', '2004-08-20')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col1,col2,col3) VALUES (101, 'hell2', '2004-08-21')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (NULL,NULL,NULL)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"CREATE TABLE t1 (col1 INT NOT NULL default 99, col2 CHAR(6) NOT NULL)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 VALUES (1, 'hello')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO t1 (col2) VALUES ('hello2')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 values (NULL,NULL)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 (col1) values (3)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT IGNORE INTO t1 () values ()","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (charcol char(255), varcharcol varchar(255), binarycol binary(255), varbinarycol varbinary(255), tinytextcol tinytext, tinyblobcol tinyblob)" @@ -90922,6 +91266,7 @@ select'a'; insert into t1 values (200); end;" "create table t1 (date date not null)" "create table t2 select date from t1" "set @@sql_mode= @org_mode" +"set @@sql_mode= @org_mode","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (i int comment '123456789*123456789*123456789*123456789* @@ -92823,8 +93168,10 @@ WHERE EXISTS (VALUES ROW(1),ROW(2) LIMIT 1 OFFSET ?)'" "SELECT REVERSE(EXISTS(SELECT RAND() FROM t1))" "SET SESSION debug=@orig_debug" "SET DEBUG='+d,hash_semijoin_fail_in_setup'" +"SET DEBUG='-d,hash_semijoin_fail_in_setup'" "SET optimizer_switch = 'firstmatch=off,materialization=off'" "SET DEBUG='+d,create_duplicate_weedout_tmp_table_error'" +"SET DEBUG='-d,create_duplicate_weedout_tmp_table_error'" "CREATE TABLE t1( id INT, pad VARCHAR(60), @@ -93264,6 +93611,7 @@ KEY datetime_key (datetime_key) "create table t1 (a int not null) engine=myisam" "create table t1 (a int) engine=myisam select 42 a" "SET SESSION keep_files_on_create = TRUE" +"SET SESSION keep_files_on_create = FALSE" "CREATE TABLE t1 (a INT) ENGINE MYISAM" "SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE'" "CREATE TABLE schema1.t1 (a INT, b INT) ENGINE=MYISAM" @@ -95137,6 +95485,7 @@ where t1.a = t2.c and t2.d = (select max(d) from t2)" "DROP PROCEDURE timestamp_test" "call mtr.add_suppression(""Unable to get certificate"")" "call mtr.add_suppression('Failed to initialize TLS for channel: mysql_main')" +"CALL mtr.add_suppression(""Cannot create temporary merge file"")" "SET @@innodb_tmpdir= NULL" "CREATE TABLE test.t(a text)" "SET @transaction_read_only_save = @@transaction_read_only" @@ -95791,8 +96140,8 @@ end" "create trigger t1_bu before update on t1 for each row set new.col1= bug5893()" "drop function bug5893" "drop trigger t1_bu" -"create table t1 (""t1 column"" int)" -"create trigger t1_bi before insert on t1 for each row set new.""t1 column"" = 5" +"create table t1 (""t1 column"" int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create trigger t1_bi before insert on t1 for each row set new.""t1 column"" = 5","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create trigger t1_af after insert on t1 for each row set @a=10" "create table t1 (a date)" "create trigger t1_bi before insert on t1 for each row set new.a = '2004-01-00'" @@ -97905,7 +98254,8 @@ b VARCHAR(10) CHARSET latin1)" "SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6))" "create table t1 (da date default '1962-03-03 23:33:34', dt datetime default '1962-03-03')" "insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38')" -"insert into t1 set dt='2007-03-23 13:49:38',da=dt" +"insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38')","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"insert into t1 set dt='2007-03-23 13:49:38',da=dt","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (f1 date, f2 datetime, f3 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)" "insert into t1(f1) values(curdate())" "select curdate() < now(), f1 < now(), cast(f1 as date) < now() from t1" @@ -99037,15 +99387,15 @@ END" "select 1 / 1E-500" "select 1 / 0" "set sql_mode='ansi,traditional'" -"CREATE TABLE Sow6_2f (col1 NUMERIC(4,2))" -"INSERT INTO Sow6_2f VALUES (10.55)" -"INSERT INTO Sow6_2f VALUES (10.5555)" -"INSERT INTO Sow6_2f VALUES (-10.55)" -"INSERT INTO Sow6_2f VALUES (-10.5555)" -"INSERT INTO Sow6_2f VALUES (11)" -"SELECT MOD(col1,0) FROM Sow6_2f" -"drop table Sow6_2f" -"select 10.3330000000000/12.34500000" +"CREATE TABLE Sow6_2f (col1 NUMERIC(4,2))","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO Sow6_2f VALUES (10.55)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO Sow6_2f VALUES (10.5555)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO Sow6_2f VALUES (-10.55)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO Sow6_2f VALUES (-10.5555)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"INSERT INTO Sow6_2f VALUES (11)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"SELECT MOD(col1,0) FROM Sow6_2f","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"drop table Sow6_2f","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"select 10.3330000000000/12.34500000","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "select 0/0" "select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x" "select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x" @@ -105084,7 +105434,7 @@ b int unsigned "SET GLOBAL partial_revokes=OFF" "DROP USER foo@localhost, u1, foo3, foo2@localhost, foo4, redqueen@localhost" "CREATE USER u1 COMMENT 'Hello ""Smith""'" -"SET @@sql_mode = @org_sql_mode" +"SET @@sql_mode = @org_sql_mode",NO_BACKSLASH_ESCAPES "CREATE USER u1@localhost IDENTIFIED BY 'foo' COMMENT 'Not permitted to change this'" "GRANT SELECT ON *.* to u1@localhost" "CREATE USER u1@localhost IDENTIFIED BY 'foo',u2@localhost IDENTIFIED BY 'foo' COMMENT ""Works with partial restrictions""" @@ -106780,8 +107130,8 @@ a in (select a+2 from t1), a = all (select a from t1) from t1" "create view v1 (x) as select b from t1" "insert into v1 values (1)" "insert into t1 (b) values (2)" -"create table t1 (""a*b"" int)" -"create view v1 as select ""a*b"" from t1" +"create table t1 (""a*b"" int)","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" +"create view v1 as select ""a*b"" from t1","ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT" "create table t1 (t_column int)" "create view v1 as select 'a'" "select * from v1, t1" @@ -114226,7 +114576,7 @@ order by find_in_set(ln.n,eq.pivot_lines), ln.n; end -" +",PIPES_AS_CONCAT "call solver(""[[2,3,1], [5,-3,10], [6,0,12]]"", ""[7,21,28]"")" "call solver(""[[1,2,1,3], [1,0,1,1], [0,1,0,1], [1,3,1,4]]"", ""[1,3,-1,4]"")" "call solver(""[[1,2,1,3], [1,0,1,1], [0,1,0,1], [1,3,1,3]]"", ""[1,3,-1,4]"")" diff --git a/packages/mysql-parser/src/class-wp-mysql-lexer.php b/packages/mysql-parser/src/class-wp-mysql-lexer.php index 898c08050..3a3498968 100644 --- a/packages/mysql-parser/src/class-wp-mysql-lexer.php +++ b/packages/mysql-parser/src/class-wp-mysql-lexer.php @@ -76,6 +76,7 @@ class WP_MySQL_Lexer { const IDENT_QUOTED = 484; const TEXT_STRING = 827; const NCHAR_STRING = 611; + const DOLLAR_QUOTED_STRING_SYM = 1204; const UNDERSCORE_CHARSET = 852; const BIN_NUM = 292; const HEX_NUM = 474; @@ -802,7 +803,6 @@ private function read_next_token(): ?int { '~' => self::TILDE, '%' => self::PERCENT, '^' => self::CARET, - '?' => self::PARAM_MARKER, '{' => self::LEFT_BRACE, '}' => self::RIGHT_BRACE, '=' => self::EQ, @@ -954,8 +954,7 @@ private function read_next_token(): ?int { $type = $this->read_mysql_comment(); } else { $this->bytes_already_read += 2; - $this->read_comment_content(); - $type = self::COMMENT; + $type = $this->read_comment_content(); } } else { $this->bytes_already_read += 1; @@ -984,9 +983,17 @@ private function read_next_token(): ?int { // follows is emitted as its own token (see produce_at_variable()). $this->bytes_already_read += 1; $type = self::AT_SIGN; + } elseif ( '?' === $byte ) { + // A parameter marker can't precede a byte that can be part of an identifier. + if ( null !== $next_byte && ( strspn( $next_byte, self::IDENTIFIER_MASK ) > 0 || $next_byte > "\x7F" ) ) { + return null; // Invalid input. + } + $this->bytes_already_read += 1; + $type = self::PARAM_MARKER; } elseif ( '\\' === $byte ) { $this->bytes_already_read += 1; - if ( 'N' === $next_byte ) { + // MySQL 8.0.1 removed "\N" as a synonym for NULL. + if ( 'N' === $next_byte && $this->mysql_version < 80001 ) { $this->bytes_already_read += 1; $type = self::NULL_SYM; } else { @@ -1006,7 +1013,18 @@ private function read_next_token(): ?int { $type = self::NCHAR_STRING; } } elseif ( null === $byte ) { - $type = self::EOF; + // An unterminated version comment is invalid input. + $type = $this->in_mysql_comment ? null : self::EOF; + } elseif ( '$' === $byte ) { + $type = $this->read_identifier(); + + // From MySQL 8.1, a second "$" in the name ends the opening delimiter of + // dollar-quoted text. Without one, it's an identifier, such as "$a" or "$". + $name = $this->get_current_token_bytes(); + $tag_end = strpos( $name, '$', 1 ); + if ( false !== $tag_end && $this->mysql_version >= 80100 ) { + $type = $this->read_dollar_quoted_text( substr( $name, 0, $tag_end + 1 ) ); + } } else { $type = $this->read_identifier(); if ( self::IDENT === $type ) { @@ -1048,74 +1066,87 @@ private function get_current_token_bytes(): string { */ private function read_identifier(): ?int { $started_at = $this->bytes_already_read; - while ( true ) { - // First, let's try to parse an ASCII sequence. - $this->bytes_already_read += strspn( - $this->sql, - self::IDENTIFIER_MASK, - $this->bytes_already_read - ); - // Check if the following byte can be part of a multibyte character - // in the range of U+0080 to U+10FFFF before looking at further bytes. - // If it can't, bail out early to avoid unnecessary UTF-8 decoding. - // Identifiers are usually ASCII-only, so we can optimize for that. - $byte_1 = ord( - $this->sql[ $this->bytes_already_read ] ?? "\0" - ); - if ( $byte_1 < 0xC2 || $byte_1 > 0xF4 ) { - break; - } + // Identifiers are usually ASCII-only, so only enter the loop below when the + // byte after the ASCII sequence can start a multibyte character. With the + // tracing JIT, entering the loop for every identifier slows down the lexer. + $this->bytes_already_read += strspn( + $this->sql, + self::IDENTIFIER_MASK, + $this->bytes_already_read + ); + $byte_1 = ord( + $this->sql[ $this->bytes_already_read ] ?? "\0" + ); + if ( $byte_1 >= 0xC2 && $byte_1 <= 0xF4 ) { + while ( true ) { + // First, let's try to parse an ASCII sequence. + $this->bytes_already_read += strspn( + $this->sql, + self::IDENTIFIER_MASK, + $this->bytes_already_read + ); - // Look for a valid 2-byte UTF-8 symbol. Covers range U+0080 - U+07FF. - $byte_2 = ord( - $this->sql[ $this->bytes_already_read + 1 ] ?? "\0" - ); - if ( - $byte_1 <= 0xDF - && $byte_2 >= 0x80 && $byte_2 <= 0xBF - ) { - $this->bytes_already_read += 2; - continue; - } + // Check if the following byte can be part of a multibyte character + // in the range of U+0080 to U+10FFFF before looking at further bytes. + // If it can't, bail out early to avoid unnecessary UTF-8 decoding. + $byte_1 = ord( + $this->sql[ $this->bytes_already_read ] ?? "\0" + ); + if ( $byte_1 < 0xC2 || $byte_1 > 0xF4 ) { + break; + } - // Look for a valid 3-byte UTF-8 symbol in range U+0800 - U+FFFF. - $byte_3 = ord( - $this->sql[ $this->bytes_already_read + 2 ] ?? "\0" - ); - if ( - $byte_1 <= 0xEF - && $byte_2 >= 0x80 && $byte_2 <= 0xBF - && $byte_3 >= 0x80 && $byte_3 <= 0xBF - // Exclude surrogate range U+D800 to U+DFFF: - && ! ( 0xED === $byte_1 && $byte_2 >= 0xA0 ) - // Exclude overlong encodings: - && ! ( 0xE0 === $byte_1 && $byte_2 < 0xA0 ) - ) { - $this->bytes_already_read += 3; - continue; - } + // Look for a valid 2-byte UTF-8 symbol. Covers range U+0080 - U+07FF. + $byte_2 = ord( + $this->sql[ $this->bytes_already_read + 1 ] ?? "\0" + ); + if ( + $byte_1 <= 0xDF + && $byte_2 >= 0x80 && $byte_2 <= 0xBF + ) { + $this->bytes_already_read += 2; + continue; + } - // Look for a valid 4-byte UTF-8 symbol in range U+10000 - U+10FFFF. - $byte_4 = ord( - $this->sql[ $this->bytes_already_read + 3 ] ?? "\0" - ); - if ( - $byte_1 >= 0xF0 - && $byte_2 >= 0x80 && $byte_2 <= 0xBF - && $byte_3 >= 0x80 && $byte_3 <= 0xBF - && $byte_4 >= 0x80 && $byte_4 <= 0xBF - // Exclude overlong encodings: - && ! ( 0xF0 === $byte_1 && $byte_2 < 0x90 ) - // Exclude codepoints above U+10FFFF: - && ! ( 0xF4 === $byte_1 && $byte_2 > 0x8F ) - ) { - $this->bytes_already_read += 4; - continue; - } + // Look for a valid 3-byte UTF-8 symbol in range U+0800 - U+FFFF. + $byte_3 = ord( + $this->sql[ $this->bytes_already_read + 2 ] ?? "\0" + ); + if ( + $byte_1 <= 0xEF + && $byte_2 >= 0x80 && $byte_2 <= 0xBF + && $byte_3 >= 0x80 && $byte_3 <= 0xBF + // Exclude surrogate range U+D800 to U+DFFF: + && ! ( 0xED === $byte_1 && $byte_2 >= 0xA0 ) + // Exclude overlong encodings: + && ! ( 0xE0 === $byte_1 && $byte_2 < 0xA0 ) + ) { + $this->bytes_already_read += 3; + continue; + } - // Not a valid identifier character. - break; + // Look for a valid 4-byte UTF-8 symbol in range U+10000 - U+10FFFF. + $byte_4 = ord( + $this->sql[ $this->bytes_already_read + 3 ] ?? "\0" + ); + if ( + $byte_1 >= 0xF0 + && $byte_2 >= 0x80 && $byte_2 <= 0xBF + && $byte_3 >= 0x80 && $byte_3 <= 0xBF + && $byte_4 >= 0x80 && $byte_4 <= 0xBF + // Exclude overlong encodings: + && ! ( 0xF0 === $byte_1 && $byte_2 < 0x90 ) + // Exclude codepoints above U+10FFFF: + && ! ( 0xF4 === $byte_1 && $byte_2 > 0x8F ) + ) { + $this->bytes_already_read += 4; + continue; + } + + // Not a valid identifier character. + break; + } } if ( $this->bytes_already_read === $started_at ) { @@ -1370,12 +1401,59 @@ private function read_quoted_text(): ?int { return $is_identifier_quote ? self::IDENT_QUOTED : self::TEXT_STRING; } + /** + * Read dollar-quoted text, which has the form $tag$text$tag$. + * + * Rules: + * 1. The tag can be empty. Otherwise, it consists of unquoted identifier + * characters other than "$", and it is case-sensitive. + * 2. The text can't be empty, and it has no escape sequences. It ends with + * the first closing delimiter. + * + * @param string $delimiter The opening delimiter, at the start of the current token. + */ + private function read_dollar_quoted_text( string $delimiter ): ?int { + // A "." that read_identifier() found after the name is a part of the text. + $this->next_state = self::STATE_START; + + $delimiter_length = strlen( $delimiter ); + $text_start = $this->token_starts_at + $delimiter_length; + $at = $text_start; + while ( $at < $this->sql_length ) { + $at = strpos( $this->sql, '$', $at ); + if ( false === $at ) { + break; + } + + $matched = 1; + while ( + $matched < $delimiter_length + && ( $this->sql[ $at + $matched ] ?? null ) === $delimiter[ $matched ] + ) { + ++$matched; + } + if ( $matched === $delimiter_length ) { + // MySQL rejects empty text, unlike an empty string as a routine body. + if ( $at === $text_start ) { + break; + } + $this->bytes_already_read = $at + $delimiter_length; + return self::DOLLAR_QUOTED_STRING_SYM; + } + + // As in MySQL, the byte that breaks the match is not checked again, + // so "$$a$" doesn't close "$a$". + $at += $matched + 1; + } + return null; // Invalid input. + } + private function read_line_comment(): int { $this->bytes_already_read += strcspn( $this->sql, "\r\n", $this->bytes_already_read ); return self::COMMENT; } - private function read_mysql_comment(): int { + private function read_mysql_comment(): ?int { // @TODO: Consider supporting optimizer hints (/*+ ... */) or document // that they are not supported. @@ -1400,9 +1478,19 @@ private function read_mysql_comment(): int { $version = (int) substr( $this->sql, $this->bytes_already_read, $version_length ); if ( $this->mysql_version < $version ) { - // Version not satisfied. Treat the content as a regular comment. - $this->read_comment_content(); - return self::COMMENT; + // Version not satisfied. Treat the content as a comment. Unlike a regular + // comment, it can contain other comments, which can't be nested any further. + while ( true ) { + $nested_start = strpos( $this->sql, '/*', $this->bytes_already_read ); + $comment_end = strpos( $this->sql, '*/', $this->bytes_already_read ); + if ( false === $nested_start || ( false !== $comment_end && $comment_end < $nested_start ) ) { + return $this->read_comment_content(); + } + $this->bytes_already_read = $nested_start + 2; + if ( null === $this->read_comment_content() ) { + return null; // Invalid input. + } + } } else { // Version satisfied or not specified. Treat the content as SQL code. $this->bytes_already_read += $version_length; // Skip the version number. @@ -1411,13 +1499,13 @@ private function read_mysql_comment(): int { } } - private function read_comment_content(): void { + private function read_comment_content(): ?int { $comment_end = strpos( $this->sql, '*/', $this->bytes_already_read ); if ( false === $comment_end ) { - $this->bytes_already_read = $this->sql_length; - } else { - $this->bytes_already_read = $comment_end + 2; + return null; // Invalid input. } + $this->bytes_already_read = $comment_end + 2; + return self::COMMENT; } private function determine_identifier_or_keyword_type( string $value ): int { diff --git a/packages/mysql-parser/src/class-wp-mysql-token.php b/packages/mysql-parser/src/class-wp-mysql-token.php index 2b8924197..b3d4a23d4 100644 --- a/packages/mysql-parser/src/class-wp-mysql-token.php +++ b/packages/mysql-parser/src/class-wp-mysql-token.php @@ -182,6 +182,11 @@ public function get_value(): string { */ $value = preg_replace( '/\\\\(.)/s', '$1', $value ); } + if ( WP_MySQL_Lexer::DOLLAR_QUOTED_STRING_SYM === $this->id ) { + // Remove the bounding "$tag$" delimiters. The text has no escape sequences. + $delimiter_length = strpos( $value, '$', 1 ) + 1; + return substr( $value, $delimiter_length, -$delimiter_length ); + } return $value; } diff --git a/packages/mysql-parser/tests/WP_MySQL_Lexer_Tests.php b/packages/mysql-parser/tests/WP_MySQL_Lexer_Tests.php index f577372c0..0f377fe9e 100644 --- a/packages/mysql-parser/tests/WP_MySQL_Lexer_Tests.php +++ b/packages/mysql-parser/tests/WP_MySQL_Lexer_Tests.php @@ -149,6 +149,27 @@ public function data_version_comments(): array { 'six digits without space' => array( 'SELECT /*!080100+ */ 1', 80100, array( 'SELECT', '0', '+', '1' ) ), 'six digits at comment end' => array( 'SELECT /*!080100*/ + 1', 80100, array( 'SELECT', '0', '+', '1' ) ), 'seven digits' => array( 'SELECT /*!0801007 + */ 1', 80100, array( 'SELECT', '07', '+', '1' ) ), + + // A version comment that doesn't apply can contain other comments. + 'nested comment' => array( 'SELECT 1 /*!99999 /* */ */', 80410, array( 'SELECT', '1' ) ), + 'text around nested' => array( 'SELECT 1 /*!99999 a /* b */ c */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'two nested comments' => array( 'SELECT 1 /*!99999 /* a */ /* b */ */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'nested version comment' => array( 'SELECT 1 /*!99999 /*!99999 a */ */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'nested comment on 5.7' => array( 'SELECT 1 /*!80000 /* */ */ + 2', 50744, array( 'SELECT', '1', '+', '2' ) ), + + // A nested comment ends at its first closing marker. + 'only one level of nesting' => array( 'SELECT 1 /*!99999 /* /* */ */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'text after the outer end' => array( 'SELECT 1 /*!99999 /* /* */ */ */', 80410, array( 'SELECT', '1', '*', '/' ) ), + + // Markers can't overlap. + '"/*/" opens a comment' => array( 'SELECT 1 /*!99999 /*/ */ */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + '"*/*" closes a comment' => array( 'SELECT 1 /*!99999 */* 2', 80410, array( 'SELECT', '1', '*', '2' ) ), + + // Other comments have their own rules. + 'regular comment' => array( 'SELECT 1 /* /* */ + 2', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'closed at the end' => array( 'SELECT 1 /* a */', 80410, array( 'SELECT', '1' ) ), + 'applied, closed at end' => array( 'SELECT 1 /*!80000 + 2 */', 80410, array( 'SELECT', '1', '+', '2' ) ), + 'applied version comment' => array( 'SELECT 1 /*!80000 /* */ + 2 */', 80410, array( 'SELECT', '1', '+', '2' ) ), ); foreach ( array( @@ -330,6 +351,58 @@ public function test_invalid_input_returns_partial_stream_without_end_markers(): $this->assertSame( array( 'SELECT', 'NUM', 'WITH' ), $names ); } + /** + * @dataProvider data_unterminated_comments + */ + public function test_unterminated_comment_is_invalid_input( string $sql, array $expected_bytes ): void { + $read_bytes = static function ( array $tokens ): array { + return array_map( + static function ( WP_MySQL_Token $token ): string { + return $token->get_bytes(); + }, + $tokens + ); + }; + $this->assertSame( $expected_bytes, $read_bytes( ( new WP_MySQL_Lexer( $sql ) )->remaining_tokens() ) ); + + // The pull iterator follows the same path as remaining_tokens(). + $lexer = new WP_MySQL_Lexer( $sql ); + $tokens = array(); + while ( $lexer->next_token() ) { + $tokens[] = $lexer->get_token(); + } + $this->assertSame( $expected_bytes, $read_bytes( $tokens ) ); + } + + public function data_unterminated_comments(): array { + return array( + // A regular comment. + 'text' => array( 'SELECT 1 /* a', array( 'SELECT', '1' ) ), + 'only an opening marker' => array( 'SELECT 1 /*', array( 'SELECT', '1' ) ), + 'overlapping markers' => array( 'SELECT 1 /*/', array( 'SELECT', '1' ) ), + 'nothing before the comment' => array( '/* a', array() ), + 'an earlier closed comment' => array( 'SELECT /* a */ 1 /* b', array( 'SELECT', '1' ) ), + 'a closing marker before it' => array( 'SELECT 1 */ /* a', array( 'SELECT', '1', '*', '/' ) ), + 'after WITH' => array( 'SELECT 1 WITH /* a', array( 'SELECT', '1', 'WITH' ) ), + + // A version comment that applies. + 'applied' => array( 'SELECT 1 /*!80000 + 2', array( 'SELECT', '1', '+', '2' ) ), + 'applied, without a version' => array( 'SELECT 1 /*! + 2', array( 'SELECT', '1', '+', '2' ) ), + 'applied and empty' => array( 'SELECT 1 /*!80000', array( 'SELECT', '1' ) ), + 'applied, after a nested comment' => array( 'SELECT 1 /*!80000 /* a */ + 2', array( 'SELECT', '1', '+', '2' ) ), + 'applied, in a nested comment' => array( 'SELECT 1 /*!80000 /* a', array( 'SELECT', '1' ) ), + 'applied, a closing marker string' => array( "SELECT 1 /*!80000 + '*/'", array( 'SELECT', '1', '+', "'*/'" ) ), + 'applied, a commented-out marker' => array( 'SELECT 1 /*!80000 + 2 -- */', array( 'SELECT', '1', '+', '2' ) ), + + // A version comment that doesn't apply. + 'skipped' => array( 'SELECT 1 /*!99999 a', array( 'SELECT', '1' ) ), + 'skipped and empty' => array( 'SELECT 1 /*!99999', array( 'SELECT', '1' ) ), + 'skipped, after a nested comment' => array( 'SELECT 1 /*!99999 /* a */ b', array( 'SELECT', '1' ) ), + 'skipped, in a nested comment' => array( 'SELECT 1 /*!99999 /* a', array( 'SELECT', '1' ) ), + 'skipped, overlapping markers' => array( 'SELECT 1 /*!99999 /*/ */', array( 'SELECT', '1' ) ), + ); + } + public function test_system_variable_name_must_not_be_empty(): void { // As in MySQL, the name after "@@" can't be empty, and only backticks // can quote it. Otherwise, the stream ends after the "@@". @@ -593,7 +666,6 @@ public function data_qualified_name_tokens(): array { 'after a float' => array( '1e5.1', array( 'FLOAT_NUM', 'DECIMAL_NUM' ) ), 'after a hex number' => array( '0x1F.1', array( 'HEX_NUM', 'DECIMAL_NUM' ) ), 'after a binary number' => array( '0b1.1', array( 'BIN_NUM', 'DECIMAL_NUM' ) ), - 'after "\N"' => array( '\N.1', array( 'NULL', 'DECIMAL_NUM' ) ), 'after a version comment' => array( '/*!50000.5*/', array( 'DECIMAL_NUM' ) ), // A user variable name includes the dot. @@ -898,6 +970,196 @@ public function data_national_strings(): array { ); } + /** + * @dataProvider data_dollar_quoted_text + */ + public function test_dollar_quoted_text( string $sql, array $expected ): void { + $tokens = ( new WP_MySQL_Lexer( $sql ) )->remaining_tokens(); + $this->assertSame( 'YYEOF', array_pop( $tokens )->get_name(), $sql ); + $this->assertSame( 'END_OF_INPUT', array_pop( $tokens )->get_name(), $sql ); + + $actual = array(); + foreach ( $tokens as $token ) { + $actual[] = array( $token->get_name(), $token->get_bytes() ); + } + $this->assertSame( $expected, $actual, $sql ); + + // The pull iterator follows the same path as remaining_tokens(). + $lexer = new WP_MySQL_Lexer( $sql ); + foreach ( $tokens as $token ) { + $this->assertTrue( $lexer->next_token(), $sql ); + $this->assertSame( $token->id, $lexer->get_token()->id, $sql ); + $this->assertSame( $token->get_bytes(), $lexer->get_token()->get_bytes(), $sql ); + } + } + + public function data_dollar_quoted_text(): array { + $dollar = 'DOLLAR_QUOTED_STRING_SYM'; + return array( + // The tag can be empty, or contain identifier characters other than "$". + 'empty tag' => array( '$$ a $$', array( array( $dollar, '$$ a $$' ) ) ), + 'tag' => array( '$tag$ a $tag$', array( array( $dollar, '$tag$ a $tag$' ) ) ), + 'digits in a tag' => array( '$1$ a $1$', array( array( $dollar, '$1$ a $1$' ) ) ), + 'underscore in a tag' => array( '$_$ a $_$', array( array( $dollar, '$_$ a $_$' ) ) ), + 'a tag with a non-ASCII character' => array( '$∂$ a $∂$', array( array( $dollar, '$∂$ a $∂$' ) ) ), + 'a tag with a 4-byte character' => array( '$😀$ a $😀$', array( array( $dollar, '$😀$ a $😀$' ) ) ), + + // The text can contain anything except for the closing delimiter. + 'a line break in the text' => array( "\$\$ a\nb \$\$", array( array( $dollar, "\$\$ a\nb \$\$" ) ) ), + 'quotes and comments in the text' => array( "\$\$ ' \" ` /* -- # \$\$", array( array( $dollar, "\$\$ ' \" ` /* -- # \$\$" ) ) ), + 'other delimiters in the text' => array( '$a$ $$ $b$ $a$', array( array( $dollar, '$a$ $$ $b$ $a$' ) ) ), + 'a tag is case-sensitive' => array( '$a$ $A$ $a$', array( array( $dollar, '$a$ $A$ $a$' ) ) ), + 'a partial tag in the text' => array( '$ab$ $a $ab$', array( array( $dollar, '$ab$ $a $ab$' ) ) ), + 'a dollar sign in the text' => array( '$$ a$b $$', array( array( $dollar, '$$ a$b $$' ) ) ), + 'multibyte characters in the text' => array( '$😀$ $😔 $😀$', array( array( $dollar, '$😀$ $😔 $😀$' ) ) ), + + // As in MySQL, the byte that breaks a closing delimiter match is skipped. + 'a dollar sign just before a close' => array( '$a$ $$a$ $a$', array( array( $dollar, '$a$ $$a$ $a$' ) ) ), + 'a broken match that ends with "$"' => array( '$ab$ $a$ab$ $ab$', array( array( $dollar, '$ab$ $a$ab$ $ab$' ) ) ), + + // Dollar-quoted text ends with the closing delimiter. + 'a name right after the text' => array( '$$a$$b', array( array( $dollar, '$$a$$' ), array( 'IDENT', 'b' ) ) ), + 'a name after a tagged text' => array( '$a$b$a$c', array( array( $dollar, '$a$b$a$' ), array( 'IDENT', 'c' ) ) ), + 'a number after the text' => array( '$$a$$.5', array( array( $dollar, '$$a$$' ), array( 'DECIMAL_NUM', '.5' ) ) ), + 'two texts' => array( '$$a$$ $$b$$', array( array( $dollar, '$$a$$' ), array( $dollar, '$$b$$' ) ) ), + 'after a space and a comment' => array( ' /* a */ $$b$$', array( array( $dollar, '$$b$$' ) ) ), + 'after WITH' => array( 'WITH $$a$$', array( array( 'WITH', 'WITH' ), array( $dollar, '$$a$$' ) ) ), + + // Without a second "$" in the identifier characters, it's an identifier. + 'a name with a leading dollar sign' => array( '$a', array( array( 'IDENT', '$a' ) ) ), + 'a name with digits' => array( '$1', array( array( 'IDENT', '$1' ) ) ), + 'a lone dollar sign' => array( '$', array( array( 'IDENT', '$' ) ) ), + 'two lone dollar signs' => array( '$ $', array( array( 'IDENT', '$' ), array( 'IDENT', '$' ) ) ), + 'a dollar sign before a dot' => array( '$a.$', array( array( 'IDENT', '$a' ), array( 'DOT', '.' ), array( 'IDENT', '$' ) ) ), + + // Only a token that starts with "$" can open dollar-quoted text. + 'dollar signs inside a name' => array( 'a$$b$$', array( array( 'IDENT', 'a$$b$$' ) ) ), + 'a name after a dot' => array( 't.$$', array( array( 'IDENT', 't' ), array( 'DOT', '.' ), array( 'IDENT', '$$' ) ) ), + 'a tagged name after a dot' => array( 't.$a$', array( array( 'IDENT', 't' ), array( 'DOT', '.' ), array( 'IDENT', '$a$' ) ) ), + 'a user variable' => array( '@$$', array( array( 'AT_SIGN', '@' ), array( 'IDENT', '$$' ) ) ), + 'a system variable' => array( '@@$$', array( array( 'AT_SIGN', '@' ), array( 'AT_SIGN', '@' ), array( 'IDENT', '$$' ) ) ), + 'a quoted name' => array( '`$$`', array( array( 'IDENT_QUOTED', '`$$`' ) ) ), + 'a string' => array( "'\$\$'", array( array( 'TEXT_STRING', "'\$\$'" ) ) ), + ); + } + + /** + * @dataProvider data_invalid_dollar_quoted_text + */ + public function test_invalid_dollar_quoted_text( string $sql ): void { + $tokens = ( new WP_MySQL_Lexer( "SELECT $sql" ) )->remaining_tokens(); + $this->assertCount( 1, $tokens, $sql ); + $this->assertSame( 'SELECT', $tokens[0]->get_name(), $sql ); + + // The pull iterator follows the same path as remaining_tokens(). + $lexer = new WP_MySQL_Lexer( "SELECT $sql" ); + $this->assertTrue( $lexer->next_token(), $sql ); + $this->assertFalse( $lexer->next_token(), $sql ); + } + + public function data_invalid_dollar_quoted_text(): array { + return array( + 'empty text' => array( '$$$$' ), + 'empty text with a tag' => array( '$a$$a$' ), + 'no text' => array( '$$' ), + 'no closing delimiter' => array( '$$ a' ), + 'half a delimiter' => array( '$$ a $' ), + 'no text after a tag' => array( '$a$' ), + 'a partial closing tag' => array( '$ab$ c $a' ), + 'a tag without its "$"' => array( '$a$ b $a' ), + 'another tag' => array( '$a$ b $b$' ), + 'a different tag case' => array( '$a$ b $A$' ), + 'a dollar sign in a tag' => array( '$a$b' ), + 'a skipped close' => array( '$a$ $$a$' ), + 'a broken match at end' => array( '$ab$ $a$ab$' ), + ); + } + + /** + * @dataProvider data_backslash_n + */ + public function test_backslash_n_is_null_before_mysql_8_0_1( string $sql, int $mysql_version, array $expected ): void { + $tokens = ( new WP_MySQL_Lexer( $sql, $mysql_version ) )->remaining_tokens(); + $names = array_map( + static function ( WP_MySQL_Token $token ): string { + return $token->get_name(); + }, + $tokens + ); + $this->assertSame( $expected, $names, "$sql on $mysql_version" ); + } + + public function data_backslash_n(): array { + $null = array( 'SELECT', 'NULL', 'END_OF_INPUT', 'YYEOF' ); + $invalid = array( 'SELECT' ); + return array( + 'MySQL 5.7' => array( 'SELECT \N', 50744, $null ), + 'MySQL 8.0.0' => array( 'SELECT \N', 80000, $null ), + 'before a number' => array( '\N.1', 80000, array( 'NULL', 'DECIMAL_NUM', 'END_OF_INPUT', 'YYEOF' ) ), + 'MySQL 8.0.1' => array( 'SELECT \N', 80001, $invalid ), + 'MySQL 8.4' => array( 'SELECT \N', 80410, $invalid ), + 'lowercase on 5.7' => array( 'SELECT \n', 50744, $invalid ), + 'lowercase on 8.4' => array( 'SELECT \n', 80410, $invalid ), + 'another letter on 5.7' => array( 'SELECT \A', 50744, $invalid ), + 'another letter on 8.4' => array( 'SELECT \A', 80410, $invalid ), + ); + } + + /** + * MySQL treats "?" as a parameter marker only if the next byte can't be part of + * an identifier. + * + * @dataProvider data_parameter_marker_tokens + */ + public function test_parameter_marker_tokens( string $sql, array $expected ): void { + $this->assertSame( $expected, self::token_names( $sql ), $sql ); + } + + /** + * @return array + */ + public function data_parameter_marker_tokens(): array { + $marker = array( 'SELECT', 'PARAM_MARKER', 'END_OF_INPUT', 'YYEOF' ); + $invalid = array( 'SELECT' ); + return array( + 'at the end of the input' => array( 'SELECT ?', $marker ), + 'before a space' => array( 'SELECT ? ', $marker ), + 'before an operator' => array( 'SELECT ?+1', array( 'SELECT', 'PARAM_MARKER', 'PLUS', 'NUM', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a comma' => array( 'SELECT ?,?', array( 'SELECT', 'PARAM_MARKER', 'COMMA', 'PARAM_MARKER', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a marker' => array( 'SELECT ??', array( 'SELECT', 'PARAM_MARKER', 'PARAM_MARKER', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a string' => array( "SELECT ?'a'", array( 'SELECT', 'PARAM_MARKER', 'TEXT_STRING', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a quoted name' => array( 'SELECT ?`a`', array( 'SELECT', 'PARAM_MARKER', 'IDENT_QUOTED', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a comment' => array( 'SELECT ?/* c */', $marker ), + 'before a dot' => array( 'SELECT ?.a', array( 'SELECT', 'PARAM_MARKER', 'DOT', 'IDENT', 'END_OF_INPUT', 'YYEOF' ) ), + 'after a keyword' => array( 'SELECT * FROM t WHERE?=1', array( 'SELECT', 'ASTERISK', 'FROM', 'IDENT', 'WHERE', 'PARAM_MARKER', '=', 'NUM', 'END_OF_INPUT', 'YYEOF' ) ), + 'before a letter' => array( 'SELECT ?a', $invalid ), + 'before a keyword' => array( 'SELECT ?FROM t', $invalid ), + 'before a digit' => array( 'SELECT ?1', $invalid ), + 'before an underscore' => array( 'SELECT ?_', $invalid ), + 'before a dollar sign' => array( 'SELECT ?$', $invalid ), + 'before a UTF-8 name' => array( "SELECT ?\u{00E9}", $invalid ), + 'before an emoji' => array( "SELECT ?\u{1F42C}", $invalid ), + 'before invalid UTF-8' => array( "SELECT ?\xC0", $invalid ), + ); + } + + public function test_dollar_quoted_text_requires_mysql_8_1(): void { + $tokens = ( new WP_MySQL_Lexer( '$$ a $$', 80099 ) )->remaining_tokens(); + $this->assertSame( + array( '$$', 'a', '$$', '', '' ), + array_map( + static function ( WP_MySQL_Token $token ): string { + return $token->get_bytes(); + }, + $tokens + ) + ); + $this->assertSame( 'IDENT', $tokens[0]->get_name() ); + + $tokens = ( new WP_MySQL_Lexer( '$$ a $$', 80100 ) )->remaining_tokens(); + $this->assertSame( 'DOLLAR_QUOTED_STRING_SYM', $tokens[0]->get_name() ); + } + public function test_composite_ansi_mode_expands_to_lexer_component_modes(): void { // ANSI_QUOTES: a double-quoted sequence is a quoted identifier. $lexer = new WP_MySQL_Lexer( '"foo"', 80410, array( 'ANSI' ) ); diff --git a/packages/mysql-parser/tests/WP_MySQL_Parser_Tests.php b/packages/mysql-parser/tests/WP_MySQL_Parser_Tests.php index 3827af341..e287a6e97 100644 --- a/packages/mysql-parser/tests/WP_MySQL_Parser_Tests.php +++ b/packages/mysql-parser/tests/WP_MySQL_Parser_Tests.php @@ -115,14 +115,43 @@ public function test_parses_representative_statements(): void { 'SELECT @@`version`', 'SHOW TABLES', 'EXPLAIN SELECT 1', + 'SELECT 1 /*!99999 /* */ */', + 'SELECT ?', + 'SELECT ?, ? FROM t', + 'SELECT ?+1', + 'SELECT * FROM t WHERE?=1', + 'SELECT ?`a`', + "SELECT ?'a'", ); foreach ( $statements as $sql ) { $this->assertNotNull( self::parse( $sql ), "Failed to parse: $sql" ); } } + public function test_dollar_quoted_routine_body_is_a_routine_string(): void { + $statements = array( + 'CREATE FUNCTION f() RETURNS INT LANGUAGE JAVASCRIPT AS $$ return 1; $$', + 'CREATE PROCEDURE p() LANGUAGE JAVASCRIPT AS $tag$ return 1; $tag$', + ); + foreach ( $statements as $sql ) { + $ast = self::parse( $sql ); + $this->assertNotNull( $ast, "Failed to parse: $sql" ); + $this->assertSame( + ' return 1; ', + $ast->get_first_descendant_node( 'routine_string' ) + ->get_first_descendant_token( WP_MySQL_Lexer::DOLLAR_QUOTED_STRING_SYM ) + ->get_value() + ); + } + } + public function test_rejects_statements_invalid_in_mysql_84(): void { $statements = array( + 'SELECT $$a$$', // Dollar quotes are only for routine bodies. + 'SET @x = $$a$$', // Dollar quotes are only for routine bodies. + 'SELECT $a$b', // Unterminated dollar-quoted text. + 'CREATE FUNCTION f() RETURNS INT LANGUAGE JAVASCRIPT AS $$ a', // Unterminated. + 'CREATE FUNCTION f() RETURNS INT LANGUAGE JAVASCRIPT AS $$$$', // Empty body. 'RESET MASTER', // Removed in MySQL 8.4. 'SHOW SLAVE STATUS', // Removed in MySQL 8.4. 'SELECT 1; SELECT 2', // Multi-statement input. @@ -133,6 +162,15 @@ public function test_rejects_statements_invalid_in_mysql_84(): void { 'SELECT 0.select', // "SELECT" after "0." is a keyword. 'SELECT @@ version', // An empty name after "@@". "SELECT @@'version'", // A single-quoted name after "@@". + 'SELECT \N', // "\N" was removed in MySQL 8.0.1. + 'SELECT ?a', // A marker before an identifier byte. + 'SELECT ?FROM t', // A marker before an identifier byte. + 'UPDATE t SET a = a + ?WHERE 1', // A marker before an identifier byte. + "SELECT ?\u{00E9}", // A marker before an identifier byte. + 'SELECT 1 /* a', // An unterminated comment. + 'SELECT 1 /*!80000 + 2', // An unterminated version comment. + 'SELECT 1 /*!99999 a', // An unterminated skipped comment. + "DELETE FROM t WHERE a = 7 OR 1=1/*' AND b = 'c'", // A comment hides the rest. ); foreach ( $statements as $sql ) { $this->assertNull( self::parse( $sql ), "Should not parse: $sql" ); diff --git a/packages/mysql-parser/tests/WP_MySQL_Query_Corpus_SQL_Modes_Tests.php b/packages/mysql-parser/tests/WP_MySQL_Query_Corpus_SQL_Modes_Tests.php new file mode 100644 index 000000000..53fc12100 --- /dev/null +++ b/packages/mysql-parser/tests/WP_MySQL_Query_Corpus_SQL_Modes_Tests.php @@ -0,0 +1,229 @@ +run_query( $query ); + } + $this->assertSame( $expected, $sql_modes->get_modes() ); + } + + public function data_queries(): array { + return array( + // The value can be a string or a word, and the modes are sorted. + 'no query' => array( array(), '' ), + 'single-quoted string' => array( array( "SET sql_mode = 'ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + 'double-quoted string' => array( array( 'SET sql_mode = "ANSI_QUOTES"' ), 'ANSI_QUOTES' ), + 'word' => array( array( 'set sql_mode=pipes_as_concat' ), 'PIPES_AS_CONCAT' ), + 'several modes' => array( array( "SET sql_mode = 'PIPES_AS_CONCAT,ANSI_QUOTES'" ), 'ANSI_QUOTES,PIPES_AS_CONCAT' ), + 'spaces in a string' => array( array( "SET sql_mode = 'PIPES_AS_CONCAT, ANSI_QUOTES'" ), 'ANSI_QUOTES,PIPES_AS_CONCAT' ), + 'every lexer mode' => array( + array( "SET sql_mode = 'PIPES_AS_CONCAT,NO_BACKSLASH_ESCAPES,IGNORE_SPACE,HIGH_NOT_PRECEDENCE,ANSI_QUOTES'" ), + 'ANSI_QUOTES,HIGH_NOT_PRECEDENCE,IGNORE_SPACE,NO_BACKSLASH_ESCAPES,PIPES_AS_CONCAT', + ), + 'modes that the lexer ignores' => array( array( "SET sql_mode = 'TRADITIONAL,ANSI_QUOTES,NO_ZERO_DATE'" ), 'ANSI_QUOTES' ), + 'the ANSI mode' => array( array( "set sql_mode='ansi'" ), 'ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT' ), + 'a word for the ANSI mode' => array( array( 'set sql_mode=ansi' ), 'ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT' ), + + // The session variable has several spellings. + 'SESSION' => array( array( "SET SESSION sql_mode='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + 'LOCAL' => array( array( "SET LOCAL sql_mode='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + '@@' => array( array( "SET @@sql_mode='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + '@@session.' => array( array( "SET @@session.sql_mode='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + '@@local.' => array( array( "SET @@local.sql_mode='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + 'uppercase name' => array( array( "SET @@SQL_MODE='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + ':=' => array( array( "SET sql_mode:='ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + 'line breaks' => array( array( "SET\nsql_mode\n=\n'ANSI_QUOTES'\n" ), 'ANSI_QUOTES' ), + + // A later assignment replaces the modes. + 'empty string' => array( array( "SET sql_mode = 'ANSI_QUOTES'", "SET sql_mode = ''" ), '' ), + 'zero' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = 0' ), '' ), + 'another mode' => array( array( "SET sql_mode = 'ANSI_QUOTES'", "SET sql_mode = 'IGNORE_SPACE'" ), 'IGNORE_SPACE' ), + 'a mode that the lexer ignores' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = traditional' ), '' ), + 'DEFAULT' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = DEFAULT' ), '' ), + + // An expression can edit the current modes. + 'CONCAT' => array( array( "SET sql_mode = 'IGNORE_SPACE'", "SET sql_mode = CONCAT(@@sql_mode, ',ANSI_QUOTES')" ), 'ANSI_QUOTES,IGNORE_SPACE' ), + 'CONCAT in a subquery' => array( array( "SET sql_mode=(SELECT CONCAT(@@sql_mode, ',PIPES_AS_CONCAT'))" ), 'PIPES_AS_CONCAT' ), + 'sys.LIST_ADD' => array( array( "SET sql_mode = sys.LIST_ADD(@@sql_mode, 'ANSI_QUOTES')" ), 'ANSI_QUOTES' ), + 'sys.LIST_DROP' => array( array( "SET sql_mode = 'ANSI_QUOTES,IGNORE_SPACE'", "SET sql_mode = sys.LIST_DROP(@@sql_mode, 'ANSI_QUOTES')" ), 'IGNORE_SPACE' ), + 'adding a mode twice' => array( array( "SET sql_mode = 'ANSI_QUOTES'", "SET sql_mode = sys.LIST_ADD(@@sql_mode, 'ANSI_QUOTES')" ), 'ANSI_QUOTES' ), + + // A user variable can save and restore the modes. + 'SET saves' => array( + array( "SET sql_mode = 'ANSI_QUOTES'", 'SET @saved = @@sql_mode', "SET sql_mode = ''", 'SET sql_mode = @saved' ), + 'ANSI_QUOTES', + ), + 'SET saves @@session.' => array( + array( "SET sql_mode = 'ANSI_QUOTES'", 'SET @saved = @@session.sql_mode', "SET sql_mode = ''", 'SET sql_mode = @saved' ), + 'ANSI_QUOTES', + ), + 'SELECT INTO saves' => array( + array( "SET sql_mode = 'ANSI_QUOTES'", 'SELECT @@sql_mode INTO @saved', "SET sql_mode = ''", 'SET sql_mode = @saved' ), + 'ANSI_QUOTES', + ), + 'SELECT INTO saves @@session.' => array( + array( "SET sql_mode = 'ANSI_QUOTES'", 'select @@session.sql_mode into @saved', "SET sql_mode = ''", 'SET sql_mode = @saved' ), + 'ANSI_QUOTES', + ), + 'variable names are case-insensitive' => array( + array( "SET sql_mode = 'ANSI_QUOTES'", 'SET @Saved = @@sql_mode', "SET sql_mode = ''", 'SET sql_mode = @SAVED' ), + 'ANSI_QUOTES', + ), + 'one assignment saves, another sets' => array( + array( "SET sql_mode = 'IGNORE_SPACE'", "SET @saved = @@sql_mode, sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = @saved' ), + 'IGNORE_SPACE', + ), + + // Other assignments can be in the same statement. + 'an assignment after' => array( array( "SET sql_mode = 'ANSI_QUOTES', @a = 1" ), 'ANSI_QUOTES' ), + 'an assignment before' => array( array( "SET @a = 1, sql_mode = 'ANSI_QUOTES'" ), 'ANSI_QUOTES' ), + 'a comma in a string' => array( array( "SET @a = 'b,sql_mode=ANSI_QUOTES', sql_mode = 'IGNORE_SPACE'" ), 'IGNORE_SPACE' ), + 'a comma in parentheses' => array( array( "SET @a = CONCAT('b', 'c'), sql_mode = 'IGNORE_SPACE'" ), 'IGNORE_SPACE' ), + + // A query can have several statements. + 'several statements' => array( array( "SET sql_mode = 'ANSI_QUOTES'; SELECT 1; SET sql_mode = CONCAT(@@sql_mode, ',IGNORE_SPACE')" ), 'ANSI_QUOTES,IGNORE_SPACE' ), + 'an assignment before a routine' => array( array( "SET sql_mode = 'ANSI_QUOTES';\nCREATE PROCEDURE p() BEGIN SELECT 1; END" ), 'ANSI_QUOTES' ), + + // A routine doesn't run when it's created. + 'a procedure body' => array( array( "CREATE PROCEDURE p() SET sql_mode = 'ANSI_QUOTES'" ), '' ), + 'a function body' => array( array( "CREATE FUNCTION f() RETURNS INT BEGIN SET sql_mode = 'ANSI_QUOTES'; RETURN 1; END" ), '' ), + 'a trigger body' => array( array( "CREATE TRIGGER t BEFORE INSERT ON a FOR EACH ROW SET sql_mode = 'ANSI_QUOTES'" ), '' ), + 'an event body' => array( array( "CREATE EVENT e ON SCHEDULE EVERY 1 DAY DO SET sql_mode = 'ANSI_QUOTES'" ), '' ), + 'a body with a definer' => array( array( "CREATE DEFINER = root@localhost PROCEDURE p() SET sql_mode = 'ANSI_QUOTES'" ), '' ), + 'a body in a later statement' => array( array( "DROP PROCEDURE p; CREATE PROCEDURE p() BEGIN SELECT 1; SET sql_mode = 'ANSI_QUOTES'; END" ), '' ), + + // Other queries don't change the modes. + 'reading the modes' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SELECT @@sql_mode' ), 'ANSI_QUOTES' ), + 'a column with that name' => array( array( "SET sql_mode = 'ANSI_QUOTES'", "UPDATE t SET sql_mode = ''" ), 'ANSI_QUOTES' ), + 'another variable' => array( array( "SET sql_mode = 'ANSI_QUOTES'", "SET my_sql_mode = ''" ), 'ANSI_QUOTES' ), + 'a modes string in another query' => array( array( "SELECT 'SET sql_mode = ANSI_QUOTES'" ), '' ), + + // A value that can't be evaluated keeps the modes. + 'an unknown variable' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = @unknown' ), 'ANSI_QUOTES' ), + 'a number' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = 2097152' ), 'ANSI_QUOTES' ), + 'an expression' => array( array( "SET sql_mode = 'ANSI_QUOTES'", 'SET sql_mode = 32+(65536*4)' ), 'ANSI_QUOTES' ), + ); + } + + /** + * @dataProvider data_global_modes + */ + public function test_global_modes_apply_to_new_connections( string $assignment, string $current, string $connected ): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_query( "SET GLOBAL sql_mode = 'IGNORE_SPACE'" ); + $sql_modes->run_query( $assignment ); + $this->assertSame( $current, $sql_modes->get_modes(), 'The current session' ); + + $sql_modes->run_command( 'connect (con1,localhost,root,,)' ); + $this->assertSame( $connected, $sql_modes->get_modes(), 'A new session' ); + } + + public function data_global_modes(): array { + return array( + 'GLOBAL' => array( "SET GLOBAL sql_mode = 'ANSI_QUOTES'", '', 'ANSI_QUOTES' ), + '@@global.' => array( "SET @@global.sql_mode = 'ANSI_QUOTES'", '', 'ANSI_QUOTES' ), + 'DEFAULT has no lexer mode' => array( 'SET GLOBAL sql_mode = DEFAULT', '', '' ), + 'a session DEFAULT' => array( 'SET sql_mode = DEFAULT', 'IGNORE_SPACE', 'IGNORE_SPACE' ), + 'reading the global modes' => array( 'SET sql_mode = @@global.sql_mode', 'IGNORE_SPACE', 'IGNORE_SPACE' ), + 'a session assignment' => array( "SET sql_mode = 'ANSI_QUOTES'", 'ANSI_QUOTES', 'IGNORE_SPACE' ), + 'global from session modes' => array( "SET sql_mode = 'ANSI_QUOTES'; SET GLOBAL sql_mode = @@sql_mode", 'ANSI_QUOTES', 'ANSI_QUOTES' ), + ); + } + + public function test_each_connection_has_its_own_modes(): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_query( "SET sql_mode = 'ANSI_QUOTES'" ); + + $sql_modes->run_command( 'connect (con1,localhost,root,,)' ); + $this->assertSame( '', $sql_modes->get_modes() ); + $sql_modes->run_query( "SET sql_mode = 'IGNORE_SPACE'" ); + + $sql_modes->run_command( 'connection default' ); + $this->assertSame( 'ANSI_QUOTES', $sql_modes->get_modes() ); + + $sql_modes->run_command( 'connection con1' ); + $this->assertSame( 'IGNORE_SPACE', $sql_modes->get_modes() ); + } + + /** + * @dataProvider data_commands + */ + public function test_commands_select_connections( string $connect, string $connection ): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_command( $connect ); + $sql_modes->run_query( "SET sql_mode = 'ANSI_QUOTES'" ); + + $sql_modes->run_command( 'connection default' ); + $this->assertSame( '', $sql_modes->get_modes(), $connect ); + + $sql_modes->run_command( $connection ); + $this->assertSame( 'ANSI_QUOTES', $sql_modes->get_modes(), $connection ); + } + + public function data_commands(): array { + return array( + 'mysqltest commands' => array( 'connect (con1,localhost,root,,)', 'connection con1' ), + '-- commands' => array( '--connect (con1,localhost,root,,)', '--connection con1' ), + 'no space' => array( '--connect(con1,localhost,root,,)', 'connection con1' ), + 'spaces and uppercase' => array( 'CONNECT ( con1 , localhost, root,,)', '--CONNECTION con1 ' ), + 'a line break' => array( "connect (con1,\nlocalhost,root,,)", 'connection con1' ), + ); + } + + public function test_a_connection_that_the_file_did_not_open_has_the_global_modes(): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_query( "SET GLOBAL sql_mode = 'ANSI_QUOTES'" ); + $sql_modes->run_command( 'connection opened_in_an_include_file' ); + $this->assertSame( 'ANSI_QUOTES', $sql_modes->get_modes() ); + } + + public function test_opening_a_connection_again_starts_a_new_session(): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_command( 'connect (con1,localhost,root,,)' ); + $sql_modes->run_query( "SET sql_mode = 'ANSI_QUOTES'" ); + $sql_modes->run_command( 'connection default' ); + $sql_modes->run_command( 'connect (con1,localhost,root,,)' ); + $this->assertSame( '', $sql_modes->get_modes() ); + } + + public function test_other_commands_keep_the_connection(): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_query( "SET sql_mode = 'ANSI_QUOTES'" ); + foreach ( array( '--echo connection con1', '--disconnect con1', 'disconnect con1', '--source include/connect.inc' ) as $command ) { + $sql_modes->run_command( $command ); + $this->assertSame( 'ANSI_QUOTES', $sql_modes->get_modes(), $command ); + } + } + + /** + * @dataProvider data_session_resets + */ + public function test_session_resets_read_the_global_modes( string $command ): void { + $sql_modes = new Query_Corpus_SQL_Modes(); + $sql_modes->run_query( "SET GLOBAL sql_mode = 'IGNORE_SPACE'" ); + $sql_modes->run_query( "SET sql_mode = 'ANSI_QUOTES'" ); + $sql_modes->run_command( $command ); + $this->assertSame( 'IGNORE_SPACE', $sql_modes->get_modes(), $command ); + } + + public function data_session_resets(): array { + return array( + 'reset_connection' => array( 'reset_connection' ), + '--reset_connection' => array( '--reset_connection' ), + 'change_user' => array( 'change_user root' ), + '--change_user' => array( '--change_user root,,test' ), + ); + } +} diff --git a/packages/mysql-parser/tests/WP_MySQL_Server_Suite_Parser_Tests.php b/packages/mysql-parser/tests/WP_MySQL_Server_Suite_Parser_Tests.php index ffa5d1d2a..05fece037 100644 --- a/packages/mysql-parser/tests/WP_MySQL_Server_Suite_Parser_Tests.php +++ b/packages/mysql-parser/tests/WP_MySQL_Server_Suite_Parser_Tests.php @@ -13,14 +13,14 @@ class WP_MySQL_Server_Suite_Parser_Tests extends TestCase { const FAILURES_PATH = __DIR__ . '/data/corpus-failures.csv'; /** - * The exact corpus tally: rejected queries are multi-statement input, a few - * unsupported statements (such as LANGUAGE JAVASCRIPT function bodies), and - * session-dependent or lexer edge cases (see the README). The exact failing - * set is pinned in FAILURES_PATH; update it when the accepted language - * legitimately changes. + * The exact corpus tally. The rejected queries are multi-statement input, which + * needs the CLIENT_MULTI_STATEMENTS client flag. MySQL rejects them too without it. + * + * The exact failing set is pinned in FAILURES_PATH; update it when the accepted + * language legitimately changes. */ - const EXPECTED_QUERIES = 69076; - const EXPECTED_FAILURES = 166; + const EXPECTED_QUERIES = 69370; + const EXPECTED_FAILURES = 43; public function test_corpus_acceptance_rate(): void { $parser = WP_MySQL_Parser_Factory::create_parser(); @@ -36,7 +36,8 @@ public function test_corpus_acceptance_rate(): void { ++$total; // Pin the MySQL version. The failure set in FAILURES_PATH depends on it. - $tokens = ( new WP_MySQL_Lexer( $query, 80410 ) )->remaining_tokens(); + $sql_modes = isset( $record[1] ) ? explode( ',', $record[1] ) : array(); + $tokens = ( new WP_MySQL_Lexer( $query, 80410, $sql_modes ) )->remaining_tokens(); if ( null === $parser->parse( $tokens ) ) { $failures[] = $query; } @@ -85,6 +86,61 @@ public function data_query_texts(): array { 'vertical tab in a version comment' => array( "DO 1 /*!80034\v+1*/" ), 'form feed in a version comment' => array( "DO 1 /*!80034\f+1*/" ), 'carriage return in a version comment' => array( "DO 1 /*!80034\r+1*/" ), + 'query after --error and --reap' => array( 'CREATE PROCEDURE mIxEdCaSe() BEGIN END' ), + 'query after --error and --remove_file' => array( 'drop procedure if exists bug13012' ), + ); + } + + /** + * Pin queries that test files expect to fail, using the "error" command instead of + * "--error", because the tally can't see an additional query that parses. + * + * @dataProvider data_omitted_query_texts + */ + public function test_corpus_omits_query_text( string $query ): void { + $this->assertNotContains( $query, $this->read_queries( self::CORPUS_PATH ) ); + } + + /** + * @return array + */ + public function data_omitted_query_texts(): array { + return array( + 'error with a name' => array( "BINLOG '\nRaNlZRMBAAAAMAAAAG0DAAAAAG8AAAAAAAEABHRlc3QAAnQxAAEDAAEBAQAg5VHP\nRaNlZR4BAAAAKAAAAJUDAAAAAG8AAAAAAAEAAgAB/wACAAAAczmjEA==\n'" ), + 'error with a number' => array( "BINLOG '\njKNlZRMBAAAAMAAAAOkFAAAAAG8AAAAAAAEABHRlc3QAAnQxAAEDAAEBAQCwxzWH\njKNlZR4BAAAAKAAAABEGAAAAAG8AAAAAAAEAAgAB/wAFAAAAVI7NfA==\n'" ), + ); + } + + /** + * Pin the SQL modes of queries that test files select them for in different ways, + * because the tally can't see a change in the modes of a query that still parses. + * + * @dataProvider data_query_sql_modes + */ + public function test_corpus_stores_query_sql_modes( string $query, array $expected ): void { + static $sql_modes = null; + if ( null === $sql_modes ) { + $sql_modes = array(); + foreach ( $this->read_records( self::CORPUS_PATH ) as $record ) { + $sql_modes[ $record[0] ][] = $record[1] ?? ''; + } + } + $this->assertSame( $expected, $sql_modes[ $query ] ?? array() ); + } + + /** + * @return array + */ + public function data_query_sql_modes(): array { + return array( + 'no modes' => array( "DO 1 /*!80034\n+1*/", array( '' ) ), + 'SET sql_mode' => array( 'SELECT * from "full"', array( 'ANSI_QUOTES' ) ), + 'the ANSI mode' => array( 'create table t1 ("a*b" int)', array( 'ANSI_QUOTES,IGNORE_SPACE,PIPES_AS_CONCAT' ) ), + 'CONCAT(@@sql_mode)' => array( "SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!' || '%' ESCAPE '!'", array( 'PIPES_AS_CONCAT' ) ), + 'sys.LIST_ADD' => array( 'select "$id2", "$$$" from t where t."$id" = 0', array( 'ANSI_QUOTES' ) ), + 'NO_BACKSLASH_ESCAPES' => array( "INSERT INTO t1 (id, val1) VALUES (1, '\\aa')", array( 'NO_BACKSLASH_ESCAPES', '' ) ), + 'two sets of modes' => array( 'select * from t1 where not a between 2 and 3', array( 'HIGH_NOT_PRECEDENCE', '' ) ), + 'IGNORE_SPACE' => array( 'create table ADDDATE (a int)', array( '', 'IGNORE_SPACE' ) ), ); } @@ -106,16 +162,26 @@ private function read_expected_failures(): array { * @return string[] The queries. */ private function read_queries( string $path ): array { + return array_column( $this->read_records( $path ), 0 ); + } + + /** + * Read the records of the queries in a CSV file. + * + * @param string $path The path to the CSV file. + * @return array The records. + */ + private function read_records( string $path ): array { $handle = fopen( $path, 'r' ); - $queries = array(); + $records = array(); while ( ( $record = fgetcsv( $handle, null, ',', '"', '\\' ) ) !== false ) { $query = $record[0] ?? null; if ( null === $query || '' === $query ) { continue; } - $queries[] = $query; + $records[] = $record; } fclose( $handle ); - return $queries; + return $records; } } diff --git a/packages/mysql-parser/tests/WP_MySQL_Token_Tests.php b/packages/mysql-parser/tests/WP_MySQL_Token_Tests.php index d411f3cf5..ae0356224 100644 --- a/packages/mysql-parser/tests/WP_MySQL_Token_Tests.php +++ b/packages/mysql-parser/tests/WP_MySQL_Token_Tests.php @@ -34,6 +34,23 @@ public function test_get_value_unquotes_national_strings(): void { $this->assertSame( "new\nline", self::first_token( "SELECT n'new\\nline'", 'NCHAR_STRING' )->get_value() ); } + /** + * @dataProvider data_dollar_quoted_values + */ + public function test_get_value_removes_dollar_quotes( string $sql, string $expected ): void { + $this->assertSame( $expected, self::first_token( $sql, 'DOLLAR_QUOTED_STRING_SYM' )->get_value() ); + } + + public function data_dollar_quoted_values(): array { + return array( + 'empty tag' => array( '$$ a $$', ' a ' ), + 'tag' => array( '$tag$ a $tag$', ' a ' ), + 'a tag with a 4-byte character' => array( '$😀$ a $😀$', ' a ' ), + 'other delimiters in the text' => array( '$a$ $$ $b$ $a$', ' $$ $b$ ' ), + 'no escape sequences' => array( "\$\$ a\\nb '' \$\$", " a\\nb '' " ), + ); + } + public function test_get_value_honors_no_backslash_escapes_mode(): void { $token = self::first_token( "SELECT 'a\\nb'", 'TEXT_STRING', array( 'NO_BACKSLASH_ESCAPES' ) ); $this->assertSame( 'a\\nb', $token->get_value() ); diff --git a/packages/mysql-parser/tests/benchmark.php b/packages/mysql-parser/tests/benchmark.php index b5bb9abf6..41fc77246 100644 --- a/packages/mysql-parser/tests/benchmark.php +++ b/packages/mysql-parser/tests/benchmark.php @@ -60,7 +60,7 @@ function ( $severity, $message, $file, $line ) { if ( null === $query || '' === $query ) { continue; } - $queries[] = $query; + $queries[] = array( $query, isset( $record[1] ) ? explode( ',', $record[1] ) : array() ); if ( null !== $limit && count( $queries ) >= $limit ) { break; } @@ -75,9 +75,9 @@ function ( $severity, $message, $file, $line ) { $run_pass = function () use ( $queries, $parser, &$failures, &$exceptions ) { $failures = 0; $exceptions = 0; - foreach ( $queries as $query ) { + foreach ( $queries as list( $query, $sql_modes ) ) { try { - $tokens = ( new WP_MySQL_Lexer( $query ) )->remaining_tokens(); + $tokens = ( new WP_MySQL_Lexer( $query, 80410, $sql_modes ) )->remaining_tokens(); if ( null !== $parser && null === $parser->parse( $tokens ) ) { ++$failures; } diff --git a/packages/mysql-parser/tests/data/corpus-failures.csv b/packages/mysql-parser/tests/data/corpus-failures.csv index bf6184f96..7c7e19371 100644 --- a/packages/mysql-parser/tests/data/corpus-failures.csv +++ b/packages/mysql-parser/tests/data/corpus-failures.csv @@ -1,639 +1,5 @@ "COMMIT; INSERT INTO t2 VALUES (1); BEGIN; " "COMMIT; INSERT INTO t2 VALUES (1); BEGIN; INSERT INTO t1 VALUES (99); " -"CREATE FUNCTION JAVASCRIPT(x INTEGER) RETURNS INTEGER DETERMINISTIC -LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -const $x = 3; -const $y$ = 4; -return $x + $y$ + a; -$$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$0$ -return ""$$"" + a + ""$$""; -$0$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$100$ -return ""$$"" + a + ""$$""; -$100$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$12345678901234$ -return ""$$"" + a + ""$$""; -$12345678901234$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM$ -return ""$$"" + a + ""$$""; -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘«åß∂ƒ©˙∆˚¬…æΩ≈ç√∫µ≤≥÷⁄€‹›fifl‡°·‚—±ÅÍÎÏ˝ÓÔÒÚÆ¸˛Ç◊ı¯˘¿$ -return ""$$"" + a + ""$$""; -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘«åß∂ƒ©˙∆˚¬…æΩ≈ç√∫µ≤≥÷⁄€‹›fifl‡°·‚—±ÅÍÎÏ˝ÓÔÒÚÆ¸˛Ç◊ı¯˘¿$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$CODE$ -return ""$$"" + a + ""$$""; -$CODE$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$NULL$ -return ""$$"" + a + ""$$""; -$NULL$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$TAG$ -return ""$$"" + a + ""$$""; -$TAG$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$_$ -return ""$$"" + a + ""$$""; -$_$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$_a$ -return ""$$"" + a + ""$$""; -$_a$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$abdc_1234$ -return ""$$"" + a + ""$$""; -$abdc_1234$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$coDE$ -return ""$$"" + a + ""$$""; -$coDE$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$code$ -const x$$ = 3; -const $y$$z = 4; -return x$$ + $y$$z + a; - -$code$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$code$ -return ""$$"" + a + ""$$""; -$code$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$tag$ -return ""$$"" + a + ""$$""; -$tag$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$¡$ -return ""$$"" + a + ""$$""; -$¡$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -return ""∂"" + a + ""$∂$""; -$$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$∂ -return ""∂"" + a + ""$∂$""; -$$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ -return ""∂"" + a + ""$∂$$""; -$code$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ -return ""∂"" + a + ""$∂$$∂""; -$code$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $co∂e$ -return ""∂"" + a + ""$∂$$""; -$co∂e$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀$ -return ""$x😀😔"" + a + ""$x😀😔$""; -$x😀$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀y$ -return ""$x😀😔y$"" + a + ""$x😀y😔$""; -$x😀y$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀y😔$ -return ""😀😔$"" + a + ""😀$😔$""; -$x😀y😔$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $∂$ -return ""∂"" + a + ""∂$""; -$∂$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀$ -return ""😀$😔"" + a + ""😀$😔$""; -$😀$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀x$ -return ""$😀x😔$"" + a + ""$😀😔x$""; -$😀x$ -" -"CREATE FUNCTION foo(a INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀😔$ -return ""😀$😔"" + a + ""😀$😔$""; -$😀😔$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -const $x = x, -const $y = 1 -return $x + $y; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ " -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -LANGUAGE JAVASCRIPT DETERMINISTIC -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -LANGUAGE -JAVASCRIPT - -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -LANGUAGE -JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER -LANGUAGE SQL DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE $NOLANG -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE 123j -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE JAVA1 -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE JAVASCRIPT -CONTAINS SQL -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE JAVASCRIPT -MODIFIES SQL DATA -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE PYTHON -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE RUBY -AS $$ -x-1 -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE __ -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE jAvaScRIpt -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC LANGUAGE javascript -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC NO SQL -LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER DETERMINISTIC READS SQL DATA -LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS INTEGER NOT DETERMINISTIC -LANGUAGE JAVASCRIPT -AS $$ -return x-1; -$$ -" -"CREATE FUNCTION foo(x INTEGER) RETURNS VARCHAR(20) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ rtrn ""$$"" + x + ""$foo$""; $code$ " -"CREATE PROCEDURE JAVASCRIPT(a INTEGER) DETERMINISTIC -LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -const $x = 3; -const $y$ = 4; -let b = $x + $y$ + a; -$$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$0$ -let b = ""$$"" + a + ""$$""; -$0$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$100$ -let b = ""$$"" + a + ""$$""; -$100$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$12345678901234$ -let b = ""$$"" + a + ""$$""; -$12345678901234$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM$ -let b = ""$$"" + a + ""$$""; -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘«åß∂ƒ©˙∆˚¬…æΩ≈ç√∫µ≤≥÷⁄€‹›fifl‡°·‚—±ÅÍÎÏ˝ÓÔÒÚÆ¸˛Ç◊ı¯˘¿$ -let b = ""$$"" + a + ""$$""; -$1234567890qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM¡™£¢∞§¶•ªº–≠œ∑´®†¥¨ˆøπ“‘«åß∂ƒ©˙∆˚¬…æΩ≈ç√∫µ≤≥÷⁄€‹›fifl‡°·‚—±ÅÍÎÏ˝ÓÔÒÚÆ¸˛Ç◊ı¯˘¿$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$CODE$ -let b = ""$$"" + a + ""$$""; -$CODE$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$NULL$ -let b = ""$$"" + a + ""$$""; -$NULL$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$TAG$ -let b = ""$$"" + a + ""$$""; -$TAG$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$_$ -let b = ""$$"" + a + ""$$""; -$_$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$_a$ -let b = ""$$"" + a + ""$$""; -$_a$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$abdc_1234$ -let b = ""$$"" + a + ""$$""; -$abdc_1234$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$coDE$ -let b = ""$$"" + a + ""$$""; -$coDE$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$code$ -const x$$ = 3; -const $y$$z = 4; -let b = x$$ + $y$$z + a; - -$code$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$code$ -let b = ""$$"" + a + ""$$""; -$code$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$tag$ -let b = ""$$"" + a + ""$$""; -$tag$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS -$¡$ -let b = ""$$"" + a + ""$$""; -$¡$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -let b = ""∂"" + a + ""$∂$""; -$$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -let b = a; -$$ " -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$∂ -let b = ""∂"" + a + ""$∂$""; -$$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ -let b = ""∂"" + a + ""$∂$$""; -$code$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ -let b = ""∂"" + a + ""$∂$$∂""; -$code$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $co∂e$ -let b = ""∂"" + a + ""$∂$$""; -$co∂e$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀$ -let b = ""$x😀😔"" + a + ""$x😀😔$""; -$x😀$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀y$ -let b = ""$x😀😔y$"" + a + ""$x😀y😔$""; -$x😀y$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $x😀y😔$ -let b = ""😀😔$"" + a + ""😀$😔$""; -$x😀y😔$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $∂$ -let b = ""∂"" + a + ""∂$""; -$∂$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀$ -let b = ""😀$😔"" + a + ""😀$😔$""; -$😀$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀x$ -let b = ""$😀x😔$"" + a + ""$😀😔x$""; -$😀x$ -" -"CREATE PROCEDURE bar(a INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $😀😔$ -let b = ""😀$😔"" + a + ""😀$😔$""; -$😀😔$ -" -"CREATE PROCEDURE bar(a INTEGER) -LANGUAGE JAVASCRIPT DETERMINISTIC -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) -LANGUAGE -JAVASCRIPT - -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) -LANGUAGE -JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) -LANGUAGE SQL DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE $NOLANG -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE 123j -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE JAVA1 -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE JAVASCRIPT -CONTAINS SQL -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE JAVASCRIPT -MODIFIES SQL DATA -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE PYTHON -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE RUBY -AS $$ b = a $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE __ -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE jAvaScRIpt -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC LANGUAGE javascript -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC NO SQL -LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) DETERMINISTIC READS SQL DATA -LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(a INTEGER) NOT DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ let b = a; $$ " -"CREATE PROCEDURE bar(x INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $$ -const $x = x, -const $y = 1 -let b = $x + $y; -$$ -" -"CREATE PROCEDURE bar(x INTEGER) -DETERMINISTIC LANGUAGE JAVASCRIPT -AS $code$ let b := ""$$"" + x + ""$foo$""; $code$ " -"CREATE TABLE "" quoted name тест"" (i INT)" -"CREATE TABLE """"""a"" (i INT)" -"CREATE TABLE ""custo`mers"" ( -""customer'_id"" INT AUTO_INCREMENT PRIMARY KEY, -""fir`st_`na`me"" VARCHAR(50) NOT NULL, -""last_'name"" VARCHAR(50) NOT NULL, -""em`ail"" VARCHAR(100) UNIQUE NOT NULL, -`pho""\ne` VARCHAR(15), -""created'_'at"" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -""updated'_'at"" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -)" -"CREATE TABLE ""orders"" ( -""order_id"" INT AUTO_INCREMENT PRIMARY KEY, -""customer_id"" INT NOT NULL, -""order_date"" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -""status"" ENUM('Pending', 'Completed', 'Cancelled') NOT NULL, -""total\n"" DECIMAL(10, 2) NOT NULL CHECK (""total\n"" >= 0), -FOREIGN KEY (customer_id) REFERENCES ""custo`mers""(""customer'_id"") ON DELETE CASCADE, -INDEX (order_date) -)" -"CREATE TABLE ""prod'ucts"" ( -""product`_`id"" INT AUTO_INCREMENT PRIMARY KEY, -""product'_`name"" VARCHAR(100) NOT NULL, -""descri`p`t`i`o`n"" TEXT, -""pr'i'ce"" DECIMAL(10, 2) NOT NULL CHECK (""pr'i'ce"" >= 0), -`stock""_""qua\ntity` INT DEFAULT 0, -`created'_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -`updated""_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -INDEX (""product'_`name"") -)" -"CREATE TABLE `'order'_'items'` ( -`order'_'item_id` INT AUTO_INCREMENT PRIMARY KEY, -`'order'_'id'` INT NOT NULL, -`product'_'id` INT NOT NULL, -`qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0), -`p'rice` DECIMAL(10,2) NOT NULL CHECK (`p'rice` >= 0), -FOREIGN KEY (`'order'_'id'`) REFERENCES ""orders""(order_id) ON DELETE CASCADE, -FOREIGN KEY (`product'_'id`) REFERENCES ""prod'ucts""(""product`_`id"") ON DELETE CASCADE, -UNIQUE KEY (`'order'_'id'`, `product'_'id`) -)" -"CREATE TABLE t1(col1 INT, col2 DATE) -ENGINE=INNODB -PARTITION BY RANGE(YEAR(""col2"")) -SUBPARTITION BY HASH(TO_DAYS(""col2""))( -PARTITION p0 VALUES LESS THAN (1990)( -SUBPARTITION s0, -SUBPARTITION s1 tablespace=`innodb_file_per_table` -), -PARTITION p1 VALUES LESS THAN MAXVALUE( -SUBPARTITION s2, -SUBPARTITION s3 tablespace=""innodb_file_per_table"" -) -)" -"CREATE TABLE table_25930_a ( ""blah"" INT )" "DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() BEGIN SELECT 1; END; CALL p26030() " "DROP PROCEDURE IF EXISTS p26030; CREATE PROCEDURE p26030() SELECT 1; CALL p26030() @@ -641,15 +7,8 @@ SUBPARTITION s3 tablespace=""innodb_file_per_table"" "DROP PROCEDURE bug6866; DROP VIEW tv" -"DROP TABLE """"""a""" "FLUSH TABLES; UNLOCK TABLES" -"SELECT 'a%' LIKE 'a!%' ESCAPE '!', 'a%' LIKE 'a!' || '%' ESCAPE '!'" -"SELECT 'a%' LIKE 'a!%' ESCAPE '$', 'a%' LIKE 'a!' || '%' ESCAPE '$'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '!', 'a%' NOT LIKE 'a!' || '%' ESCAPE '!'" -"SELECT 'a%' NOT LIKE 'a!%' ESCAPE '$', 'a%' NOT LIKE 'a!' || '%' ESCAPE '$'" -"SELECT * from ""full""" -"SELECT 1 /*!99999 /* */ */" "SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; create procedure test_resignal() begin @@ -835,7 +194,6 @@ RETURNS VARCHAR(64) BINARY UNICODE BEGIN RETURN ''; END" -"SHOW CREATE TABLE """"""a""" "alter table t1 add b integer; call p1" "create function bug12812() returns char(2) @@ -843,18 +201,13 @@ begin return 'ok'; end; create user user_bug12812@localhost IDENTIFIED BY 'ABC'" -"create procedure bug2564_2() -insert into ""t1"" values ('foo', 1)" "create procedure bug5307() begin end; set @x = 3" -"create table t1 (""a*b"" int)" -"create table t1 (""t1 column"" int)" "create table t1 (i int); insert into t1 values (1),(2),(3); select * from t1 where i = 2; drop table t1;" -"create trigger t1_bi before insert on t1 for each row set new.""t1 column"" = 5" "create view v1 as select a from t3; create procedure bug10100pt(level int, lim int) begin @@ -918,7 +271,6 @@ else execute stmt2; end if; end" -"select ""$id2"", ""$$$"" from t where t.""$id"" = 0" "select ""stmt 1""; select ""space, stmt 2""" "select ""stmt 1"";/* comment */select ""comment, stmt 2""" "select ""stmt 1"";select ""stmt 2 non terminated""" diff --git a/packages/mysql-parser/tools/class-query-corpus-sql-modes.php b/packages/mysql-parser/tools/class-query-corpus-sql-modes.php new file mode 100644 index 000000000..7c058bffa --- /dev/null +++ b/packages/mysql-parser/tools/class-query-corpus-sql-modes.php @@ -0,0 +1,202 @@ + + */ + private $session_modes = array( 'default' => array() ); + + /** + * The name of the current connection. + * + * @var string + */ + private $connection = 'default'; + + /** + * The modes that user variables hold, by lowercase variable name. + * + * @var array + */ + private $variables = array(); + + /** + * Get the modes of the current session. + * + * @return string The modes, separated by commas. + */ + public function get_modes(): string { + return implode( ',', $this->session_modes[ $this->connection ] ); + } + + /** + * Follow a mysqltest command that opens, selects, or resets a connection. + * + * @param string $command The command, with or without the "--" prefix. + */ + public function run_command( string $command ): void { + if ( preg_match( '/^(?:--\s*)?connect\s*\(\s*([^,\s)]+)/i', $command, $matches ) ) { + $this->connection = $matches[1]; + + $this->session_modes[ $this->connection ] = $this->global_modes; + } elseif ( preg_match( '/^(?:--\s*)?connection\s+([^\s;]+)/i', $command, $matches ) ) { + $this->connection = $matches[1]; + + // A sourced file may have opened the connection. + $this->session_modes[ $this->connection ] = $this->session_modes[ $this->connection ] ?? $this->global_modes; + } elseif ( preg_match( '/^(?:--\s*)?(?:change_user|reset_connection)\b/i', $command ) ) { + $this->session_modes[ $this->connection ] = $this->global_modes; + } + } + + /** + * Follow the statements of a query that ran without an error. + * + * @param string $query The query, which can have several statements. + */ + public function run_query( string $query ): void { + if ( false === stripos( $query, 'sql_mode' ) ) { + return; + } + + foreach ( explode( ';', $query ) as $statement ) { + $statement = trim( $statement ); + + // A routine doesn't run when it's created, and its body may go on from here. + if ( preg_match( '/^create\s+(?:definer\s*=\s*\S+\s+)?(?:procedure|function|trigger|event)\b/i', $statement ) ) { + return; + } + + if ( preg_match( '/^select\s+(@@[\w.]+)\s+into\s+(@\w+)$/i', $statement, $matches ) ) { + $this->run_assignment( $matches[2], $matches[1] ); + } elseif ( preg_match( '/^set\s+(.*)$/is', $statement, $matches ) ) { + // Find the assignments, whose commas aren't in strings or parentheses. + preg_match_all( + '/(?:[^,\'"()]++|\'[^\']*+\'|"[^"]*+"|(\((?:[^()\'"]++|\'[^\']*+\'|"[^"]*+"|(?1))*+\)))++/', + $matches[1], + $assignments + ); + foreach ( $assignments[0] as $assignment ) { + if ( preg_match( '/^\s*(.+?)\s*:?=\s*(.*?)\s*$/s', $assignment, $parts ) ) { + $this->run_assignment( $parts[1], $parts[2] ); + } + } + } + } + } + + /** + * Follow an assignment to the session variable, global variable, or a user variable. + * + * @param string $target The target of the assignment. + * @param string $value The assigned expression. + */ + private function run_assignment( string $target, string $value ): void { + if ( preg_match( '/^(?:(?:session|local)\s+|@@(?:(?:session|local)\.)?)?sql_mode$/i', $target ) ) { + $modes = $this->evaluate( $value, $this->global_modes ); + + $this->session_modes[ $this->connection ] = $modes ?? $this->session_modes[ $this->connection ]; + } elseif ( preg_match( '/^(?:global\s+|@@global\.)sql_mode$/i', $target ) ) { + // For the global variable, DEFAULT is the built-in value, without any lexer modes. + $this->global_modes = $this->evaluate( $value, array() ) ?? $this->global_modes; + } elseif ( preg_match( '/^@(\w+)$/', $target, $matches ) ) { + $this->variables[ strtolower( $matches[1] ) ] = $this->evaluate( $value, array() ); + } + } + + /** + * Evaluate an expression that test files assign to the SQL mode. + * + * @param string $value The expression. + * @param string[] $default_modes The modes that DEFAULT stands for. + * @return string[]|null The modes; null when the expression can't be evaluated. + */ + private function evaluate( string $value, array $default_modes ): ?array { + $session = $this->session_modes[ $this->connection ]; + + if ( preg_match( '/^\(\s*(?:select\s+)?(.*?)\s*\)$/is', $value, $matches ) ) { + return $this->evaluate( $matches[1], $default_modes ); + } + if ( preg_match( '/^([\'"])(.*)\1$/s', $value, $matches ) ) { + return $this->read_modes( $matches[2] ); + } + if ( 0 === strcasecmp( 'DEFAULT', $value ) ) { + return $default_modes; + } + if ( '0' === $value ) { + return array(); + } + if ( preg_match( '/^[a-z_]+$/i', $value ) ) { + return $this->read_modes( $value ); + } + if ( preg_match( '/^@@(?:(?:session|local)\.)?sql_mode$/i', $value ) ) { + return $session; + } + if ( 0 === strcasecmp( '@@global.sql_mode', $value ) ) { + return $this->global_modes; + } + if ( preg_match( '/^@(\w+)$/', $value, $matches ) ) { + return $this->variables[ strtolower( $matches[1] ) ] ?? null; + } + if ( preg_match( '/^(concat|sys\.list_add|sys\.list_drop)\s*\(\s*@@sql_mode\s*,\s*([\'"])(.*?)\2\s*\)$/is', $value, $matches ) ) { + $modes = $this->read_modes( $matches[3] ); + return 0 === strcasecmp( 'sys.list_drop', $matches[1] ) + ? array_values( array_diff( $session, $modes ) ) + : array_values( array_intersect( self::LEXER_MODES, array_merge( $session, $modes ) ) ); + } + return null; + } + + /** + * Read the lexer modes from a list of SQL modes. + * + * @param string $sql_modes The SQL modes, separated by commas. + * @return string[] The lexer modes. + */ + private function read_modes( string $sql_modes ): array { + $modes = array_map( 'trim', explode( ',', strtoupper( $sql_modes ) ) ); + if ( in_array( 'ANSI', $modes, true ) ) { + $modes = array_merge( $modes, self::ANSI_MODES ); + } + return array_values( array_intersect( self::LEXER_MODES, $modes ) ); + } +} diff --git a/packages/mysql-parser/tools/generate-query-corpus.php b/packages/mysql-parser/tools/generate-query-corpus.php index fb249cd6e..ea27b9ed0 100644 --- a/packages/mysql-parser/tools/generate-query-corpus.php +++ b/packages/mysql-parser/tools/generate-query-corpus.php @@ -22,10 +22,14 @@ * The queries are saved in UTF-8. Each line of a test file is read in the character * set of the client that the test selects, as "query-corpus-decoding.php" explains. * + * A query that runs in SQL modes that affect the lexer has them in a second column, + * separated by commas. A query that runs in several sets of modes has a row for each. + * * The script is written on a best-effort basis and may not cover all edge cases. * In the future, we may consider writing a mysqltest format parser. */ +require_once __DIR__ . '/class-query-corpus-sql-modes.php'; require_once __DIR__ . '/query-corpus-decoding.php'; // Paths: @@ -215,6 +219,9 @@ function ( $command ) { // Track the encoding of the client character set that a statement selects. $client_encoding = $default_encoding; + // Track the SQL modes that the statements select. + $sql_modes = new Query_Corpus_SQL_Modes(); + $query = ''; $contents = file_get_contents( $tests_dir . '/' . $file ); @@ -262,7 +269,8 @@ function ( $command ) { continue; } - // Skip queries that are expected to result in parse errors for now. + // Skip queries that are expected to fail. As in mysqltest, the "--error" command + // applies to the command that follows, and any other command ends it. if ( 0 === strpos( strtolower( $line ), '--error' ) || 0 === strpos( strtolower( $line ), '-- error' ) ) { $skip_next = true; continue; @@ -289,6 +297,13 @@ function ( $command ) { if ( 0 === strpos( strtolower( $line ), '--delimiter' ) ) { $line = substr( $line, 2 ); // remove '--' } else { + // Inside a query, this is an SQL comment rather than a command. + if ( '' === $query ) { + if ( ! $skip_next ) { + $sql_modes->run_command( $line ); + } + $skip_next = false; + } continue; } } @@ -322,12 +337,17 @@ function ( $command ) { $delimiter = trim( substr( $query, strlen( 'delimiter' ) ) ); } elseif ( preg_match( $skip_pattern, $query ) ) { // skip commands + if ( ! $skip_next ) { + $sql_modes->run_command( $query ); + } } else { if ( ! $skip_next ) { - $queries[ $query ] = true; + $queries[ $query ][ $sql_modes->get_modes() ] = true; + $sql_modes->run_query( $query ); } } - $skip_next = false; + // The "error" command works like "--error", but it ends with a delimiter. + $skip_next = 1 === preg_match( '/^error\b/i', $query ); $query = ''; @@ -363,7 +383,9 @@ function ( $command ) { fwrite( STDERR, "error: cannot open $query_file for writing.\n" ); exit( 1 ); } -foreach ( $queries as $query => $_ ) { - fputcsv( $output, array( $query ), ',', '"', '\\' ); +foreach ( $queries as $query => $query_modes ) { + foreach ( array_keys( $query_modes ) as $modes ) { + fputcsv( $output, '' === $modes ? array( $query ) : array( $query, $modes ), ',', '"', '\\' ); + } } fclose( $output ); diff --git a/packages/mysql-parser/tools/generate-tokens.php b/packages/mysql-parser/tools/generate-tokens.php index b072c7819..1a61cdfb3 100644 --- a/packages/mysql-parser/tools/generate-tokens.php +++ b/packages/mysql-parser/tools/generate-tokens.php @@ -117,6 +117,7 @@ 'IDENT_QUOTED', 'TEXT_STRING', 'NCHAR_STRING', + 'DOLLAR_QUOTED_STRING_SYM', 'UNDERSCORE_CHARSET', 'BIN_NUM', 'HEX_NUM',