diff --git a/mysql-test/suite/galera/r/MDEV-30732.result b/mysql-test/suite/galera/r/MDEV-30732.result new file mode 100644 index 0000000000000..83dd981a70d60 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-30732.result @@ -0,0 +1,329 @@ +connection node_2; +connection node_1; +SET GLOBAL sql_mode=0; +SET sql_mode=DEFAULT; +CREATE TABLE t (c INT,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 BLOB NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 +3 +4 +5 +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 +3 +4 +5 +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 +3 +4 +5 +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +Warnings: +Warning 1364 Field 'c2' doesn't have a default value +UPDATE t SET c2=NULL WHERE c = 1; +Warnings: +Warning 1048 Column 'c2' cannot be null +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 +3 +4 +5 +DROP TABLE t; +SET GLOBAL sql_mode=DEFAULT; +CREATE TABLE t (c INT,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +c c2 +2 NULL +3 NULL +4 NULL +5 NULL +DROP TABLE t; diff --git a/mysql-test/suite/galera/t/MDEV-30732.test b/mysql-test/suite/galera/t/MDEV-30732.test new file mode 100644 index 0000000000000..0f19e8c02adc0 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-30732.test @@ -0,0 +1,212 @@ +--source include/galera_cluster.inc + +SET GLOBAL sql_mode=0; +SET sql_mode=DEFAULT; +CREATE TABLE t (c INT,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 BLOB NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80) NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="" WHERE c=1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT NOT NULL,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; + +SET GLOBAL sql_mode=DEFAULT; + +CREATE TABLE t (c INT,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(1),(1),(1),(1); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; + +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 BLOB,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 VARCHAR(270),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 CHAR(80),KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; +CREATE TABLE t (c INT NOT NULL PRIMARY KEY,c2 TEXT,KEY k2 (c2 (6),c)) DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; +INSERT INTO t (c) VALUES (1),(2),(3),(4),(5); +UPDATE t SET c2=NULL WHERE c = 1; +UPDATE t SET c2="TESTtest" WHERE c = 1; +UPDATE t SET c2="BUGbug" WHERE c2 = "TESTtest"; +DELETE FROM t WHERE c2="BUGbug"; +SELECT * FROM t; +DROP TABLE t; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ada50c1b409d7..632d9ce53ca34 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6220,25 +6220,22 @@ ha_innobase::close() /* The following accessor functions should really be inside MySQL code! */ #ifdef WITH_WSREP -ulint -wsrep_innobase_mysql_sort( - /* out: str contains sort string */ +size_t +wsrep_normalize_string( int mysql_type, /* in: MySQL type */ uint charset_number, /* in: number of the charset */ - unsigned char* str, /* in: data field */ - ulint str_length, /* in: data field length, + const unsigned char* str, /* in: input data field */ + unsigned char* out_str, /* out: normalized string */ + size_t str_length, /* in: data field length, not UNIV_SQL_NULL */ - ulint buf_length) /* in: total str buffer length */ + size_t buf_length) /* in: total str buffer length */ { - CHARSET_INFO* charset; - enum_field_types mysql_tp; - ulint ret_length = str_length; + size_t ret_length= str_length; + const enum_field_types mysql_tp= (enum_field_types)mysql_type; DBUG_ASSERT(str_length != UNIV_SQL_NULL); - mysql_tp = (enum_field_types) mysql_type; - switch (mysql_tp) { case MYSQL_TYPE_BIT: @@ -6250,8 +6247,7 @@ wsrep_innobase_mysql_sort( case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_VARCHAR: { - uchar tmp_str[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'}; - ulint tmp_length = REC_VERSION_56_MAX_INDEX_COL_LEN; + CHARSET_INFO* charset; /* Use the charset number to pick the right charset struct for the comparison. Since the MySQL function get_charset may be @@ -6266,36 +6262,26 @@ wsrep_innobase_mysql_sort( charset = get_charset(charset_number, MYF(MY_WME)); if (charset == NULL) { - sql_print_error("InnoDB needs charset %lu for doing " - "a comparison, but MariaDB cannot " - "find that charset.", - (ulong) charset_number); + sql_print_error("InnoDB needs charset %lu for doing " + "a comparison, but MariaDB cannot " + "find that charset.", + (ulong) charset_number); ut_a(0); } } - ut_a(str_length <= tmp_length); - memcpy(tmp_str, str, str_length); - - tmp_length = charset->strnxfrm(str, str_length, - uint(str_length), tmp_str, - tmp_length, 0); - DBUG_ASSERT(tmp_length <= str_length); if (wsrep_protocol_version < 3) { - tmp_length = charset->strnxfrm( - str, str_length, - uint(str_length), tmp_str, tmp_length, 0); - DBUG_ASSERT(tmp_length <= str_length); + ret_length = charset->strnxfrm( + out_str, str_length, + uint(str_length), str, buf_length, 0); } else { /* strnxfrm will expand the destination string, - protocols < 3 truncated the sorted sring - protocols >= 3 gets full sorted sring + protocols < 3 truncated the normalized string + protocols >= 3 gets full normalized string */ - tmp_length = charset->strnxfrm( - str, buf_length, - uint(str_length), tmp_str, str_length, 0); - DBUG_ASSERT(tmp_length <= buf_length); - ret_length = tmp_length; + ret_length = charset->strnxfrm( + out_str, buf_length, + uint(str_length), str, str_length, 0); } break; @@ -6665,8 +6651,6 @@ wsrep_store_key_val_for_row( KEY_PART_INFO* key_part = key_info->key_part; KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; char* buff_start = buff; - enum_field_types mysql_type; - Field* field; ulint buff_space = buff_len; DBUG_ENTER("wsrep_store_key_val_for_row"); @@ -6675,8 +6659,8 @@ wsrep_store_key_val_for_row( *key_is_null = true; for (; key_part != end; key_part++) { - uchar sorted[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'}; - bool part_is_null = false; + uchar normalized[REC_VERSION_56_MAX_INDEX_COL_LEN]; + bool part_is_null= false; if (key_part->null_bit) { if (buff_space > 0) { @@ -6696,23 +6680,15 @@ wsrep_store_key_val_for_row( } if (!part_is_null) *key_is_null = false; - field = key_part->field; - mysql_type = field->type(); + const Field* field= key_part->field; + const enum_field_types mysql_type= field->type(); if (mysql_type == MYSQL_TYPE_VARCHAR) { /* >= 5.0.3 true VARCHAR */ - ulint lenlen; - ulint len; - const byte* data; - ulint key_len; - ulint true_len; - const CHARSET_INFO* cs; - int error=0; - - key_len = key_part->length; + const size_t key_len= key_part->length; if (part_is_null) { - true_len = key_len + 2; + size_t true_len= key_len + 2; if (true_len > buff_space) { fprintf (stderr, "WSREP: key truncated: %s\n", @@ -6723,27 +6699,28 @@ wsrep_store_key_val_for_row( buff_space -= true_len; continue; } - cs = field->charset(); + const CHARSET_INFO* cs = field->charset(); - lenlen = (ulint) + ulint lenlen = (ulint) (((Field_varstring*)field)->length_bytes); - data = row_mysql_read_true_varchar(&len, + size_t len; + const byte* data = row_mysql_read_true_varchar(&len, (byte*) (record + (ulint)get_field_offset(table, field)), lenlen); - true_len = len; + size_t true_len= len; /* For multi byte character sets we need to calculate the true length of the key */ if (len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) my_well_formed_length(cs, + int error; + true_len= my_well_formed_length(cs, (const char *) data, (const char *) data + len, - (uint) (key_len / - cs->mbmaxlen), + (key_len / cs->mbmaxlen), &error); } @@ -6752,16 +6729,21 @@ wsrep_store_key_val_for_row( if (true_len > key_len) { true_len = key_len; } - /* cannot exceed max column lenght either, we may need to truncate + /* cannot exceed max column length either, we may need to truncate the stored value: */ - if (true_len > sizeof(sorted)) { - true_len = sizeof(sorted); + if (true_len > sizeof(normalized)) { + true_len = sizeof(normalized); + } + + /* Normalize string if is not empty string */ + if (true_len) { + ut_ad(data); + true_len= wsrep_normalize_string( + mysql_type, cs->number, data, + normalized, true_len, + REC_VERSION_56_MAX_INDEX_COL_LEN); } - memcpy(sorted, data, true_len); - true_len = wsrep_innobase_mysql_sort( - mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); if (wsrep_protocol_version > 1) { /* Note that we always reserve the maximum possible length of the true VARCHAR in the key value, though @@ -6774,7 +6756,7 @@ wsrep_store_key_val_for_row( wsrep_thd_query(thd)); true_len = buff_space; } - memcpy(buff, sorted, true_len); + memcpy(buff, normalized, true_len); buff += true_len; buff_space -= true_len; } else { @@ -6788,19 +6770,11 @@ wsrep_store_key_val_for_row( as BLOB data in innodb. */ || mysql_type == MYSQL_TYPE_GEOMETRY) { - const CHARSET_INFO* cs; - ulint key_len; - ulint true_len; - int error=0; - ulint blob_len; - const byte* blob_data; - + const size_t key_len= key_part->length; ut_a(key_part->key_part_flag & HA_PART_KEY_SEG); - key_len = key_part->length; - if (part_is_null) { - true_len = key_len + 2; + size_t true_len= key_len + 2; if (true_len > buff_space) { fprintf (stderr, "WSREP: key truncated: %s\n", @@ -6813,14 +6787,15 @@ wsrep_store_key_val_for_row( continue; } - cs = field->charset(); + const CHARSET_INFO* cs= field->charset(); - blob_data = row_mysql_read_blob_ref(&blob_len, + size_t blob_len; + const byte* blob_data = row_mysql_read_blob_ref(&blob_len, (byte*) (record + (ulint)get_field_offset(table, field)), (ulint) field->pack_length()); - true_len = blob_len; + size_t true_len= blob_len; ut_a(get_field_offset(table, field) == key_part->offset); @@ -6829,12 +6804,13 @@ wsrep_store_key_val_for_row( the true length of the key */ if (blob_len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) my_well_formed_length(cs, + int error; + + true_len= my_well_formed_length(cs, (const char *) blob_data, (const char *) blob_data + blob_len, - (uint) (key_len / - cs->mbmaxlen), + (key_len / cs->mbmaxlen), &error); } @@ -6846,11 +6822,16 @@ wsrep_store_key_val_for_row( true_len = key_len; } - memcpy(sorted, blob_data, true_len); - true_len = wsrep_innobase_mysql_sort( - mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); - + /* Normalize string if it is not empty string. + When true_len == 0 blob_data is not always + nullptr it may be empty string i.e. "" */ + if (true_len) { + ut_ad(blob_data); + true_len= wsrep_normalize_string( + mysql_type, cs->number, blob_data, + normalized, true_len, + REC_VERSION_56_MAX_INDEX_COL_LEN); + } /* Note that we always reserve the maximum possible length of the BLOB prefix in the key value. */ @@ -6866,24 +6847,15 @@ wsrep_store_key_val_for_row( } else { buff += key_len; } - memcpy(buff, sorted, true_len); + memcpy(buff, normalized, true_len); } else { /* Here we handle all other data types except the true VARCHAR, BLOB and TEXT. Note that the column value we store may be also in a column prefix index. */ - const CHARSET_INFO* cs = NULL; - ulint true_len; - ulint key_len; - const uchar* src_start; - int error=0; - enum_field_types real_type; - - key_len = key_part->length; - if (part_is_null) { - true_len = key_len; + size_t true_len= key_part->length; if (true_len > buff_space) { fprintf (stderr, "WSREP: key truncated: %s\n", @@ -6896,9 +6868,9 @@ wsrep_store_key_val_for_row( continue; } - src_start = record + key_part->offset; - real_type = field->real_type(); - true_len = key_len; + const uchar* src_start= record + key_part->offset; + const enum_field_types real_type= field->real_type(); + size_t true_len= key_part->length; /* Character set for the field is defined only to fields whose type is string and real field @@ -6910,26 +6882,32 @@ wsrep_store_key_val_for_row( && ( mysql_type == MYSQL_TYPE_VAR_STRING || mysql_type == MYSQL_TYPE_STRING)) { - cs = field->charset(); + const CHARSET_INFO* cs= field->charset(); /* For multi byte character sets we need to calculate the true length of the key */ - if (key_len > 0 && cs->mbmaxlen > 1) { + if (true_len > 0 && cs->mbmaxlen > 1) { + int error; - true_len = (ulint) - my_well_formed_length(cs, + true_len= my_well_formed_length(cs, (const char *)src_start, (const char *)src_start - + key_len, - (uint) (key_len / - cs->mbmaxlen), + + true_len, + (true_len / cs->mbmaxlen), &error); } - memcpy(sorted, src_start, true_len); - true_len = wsrep_innobase_mysql_sort( - mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); + + /* Normalize string if it is not empty string */ + if (true_len) { + ut_ad(src_start); + true_len= wsrep_normalize_string( + mysql_type, cs->number, + src_start, normalized, true_len, + REC_VERSION_56_MAX_INDEX_COL_LEN); + } else { + ut_ad(src_start == nullptr); + } if (true_len > buff_space) { fprintf (stderr, @@ -6937,9 +6915,15 @@ wsrep_store_key_val_for_row( wsrep_thd_query(thd)); true_len = buff_space; } - memcpy(buff, sorted, true_len); + memcpy(buff, normalized, true_len); } else { - memcpy(buff, src_start, true_len); + /* Copy only if there is data */ + if (true_len) { + ut_ad(src_start); + memcpy(buff, src_start, true_len); + } else { + ut_ad(src_start == nullptr); + } } buff += true_len; buff_space -= true_len; diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 35a93f32ea3d2..34d1c9fb7a71b 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -148,9 +148,12 @@ innobase_basename( const char* path_name); #ifdef WITH_WSREP -ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, - unsigned char* str, ulint str_length, - ulint buf_length); +size_t wsrep_normalize_string(int mysql_type, + uint charset_number, + const unsigned char* str, + unsigned char* out_str, + ulint str_length, + ulint buf_length); #endif /* WITH_WSREP */ /** Get high resolution timestamp for the current query start time. diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 47be5e447f546..6480c0358ed35 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -2733,11 +2733,10 @@ wsrep_rec_get_foreign_key( *buf++ = 0; key_len++; } - memcpy(buf, data, len); - *buf_len = wsrep_innobase_mysql_sort( + *buf_len = wsrep_normalize_string( (int)(col_f->prtype & DATA_MYSQL_TYPE_MASK), dtype_get_charset_coll(col_f->prtype), - buf, static_cast(len), + data, buf, static_cast(len), static_cast(*buf_len)); } else { /* new protocol */ if (!(col_r->prtype & DATA_NOT_NULL)) { @@ -2766,13 +2765,10 @@ wsrep_rec_get_foreign_key( case DATA_VARMYSQL: case DATA_CHAR: case DATA_MYSQL: - /* Copy the actual data */ - memcpy(buf, data, len); - len = wsrep_innobase_mysql_sort( - (int) - (col_f->prtype & DATA_MYSQL_TYPE_MASK), + len = wsrep_normalize_string( + (int)(col_f->prtype & DATA_MYSQL_TYPE_MASK), dtype_get_charset_coll(col_f->prtype), - buf, len, *buf_len); + data, buf, len, *buf_len); break; case DATA_BLOB: case DATA_BINARY: