MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify

Also fixes:

 MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys)
 MDEV-28328 Assertion failures in btr0cur.cc upon INSERT or in row0sel.cc afterwards

The code in strings/strcoll.inl when comparing an empty string
to a string like 0x0001050001 did not take into account
that the leftmost weight in the latter can be zero, while
there are some more weights can follow the zero weight.

Rewriting the code to treat the shorter string as smaller than
a longer string.
This commit is contained in:
Alexander Barkov 2024-11-08 13:51:34 +04:00
parent 77ea99a4b5
commit d261fa5c70
25 changed files with 340 additions and 2 deletions

View file

@ -5445,5 +5445,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid big5 character string: '\xA3\xC0'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_big5'' collate big5_chinese_nopad_ci, _big5 0x0001050001) as c1;
c1
-1
select strcmp(_big5'' collate big5_nopad_bin, _big5 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -290,6 +290,13 @@ SET NAMES big5;
SET @seq=_big5 0xA3C0;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_big5'' collate big5_chinese_nopad_ci, _big5 0x0001050001) as c1;
select strcmp(_big5'' collate big5_nopad_bin, _big5 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -653,5 +653,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid cp932 character string: '\x81'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_cp932'' collate cp932_japanese_nopad_ci, _cp932 0x0001050001) as c1;
c1
-1
select strcmp(_cp932'' collate cp932_nopad_bin, _cp932 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -61,6 +61,13 @@ SET NAMES cp932;
SET @seq=_cp932 0x81AD;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_cp932'' collate cp932_japanese_nopad_ci, _cp932 0x0001050001) as c1;
select strcmp(_cp932'' collate cp932_nopad_bin, _cp932 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -34547,5 +34547,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid eucjpms character string: '\x8F\xA1\xA1'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_eucjpms'' collate eucjpms_japanese_nopad_ci, _eucjpms 0x0001050001) as c1;
c1
-1
select strcmp(_eucjpms'' collate eucjpms_nopad_bin, _eucjpms 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -612,6 +612,13 @@ SET NAMES eucjpms;
SET @seq=_eucjpms 0x8FA1A1;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_eucjpms'' collate eucjpms_japanese_nopad_ci, _eucjpms 0x0001050001) as c1;
select strcmp(_eucjpms'' collate eucjpms_nopad_bin, _eucjpms 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -26065,5 +26065,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid euckr character string: '\xA2\xE8'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_euckr'' collate euckr_korean_nopad_ci, _euckr 0x0001050001) as c1;
c1
-1
select strcmp(_euckr'' collate euckr_nopad_bin, _euckr 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -241,6 +241,13 @@ SET NAMES euckr;
SET @seq=_euckr 0xA2E8;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_euckr'' collate euckr_korean_nopad_ci, _euckr 0x0001050001) as c1;
select strcmp(_euckr'' collate euckr_nopad_bin, _euckr 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -5135,5 +5135,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid gb2312 character string: '\xA2\xA1'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_gb2312'' collate gb2312_chinese_nopad_ci, _gb2312 0x0001050001) as c1;
c1
-1
select strcmp(_gb2312'' collate gb2312_nopad_bin, _gb2312 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -199,6 +199,13 @@ SET NAMES gb2312;
SET @seq=_gb2312 0xA2A1;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_gb2312'' collate gb2312_chinese_nopad_ci, _gb2312 0x0001050001) as c1;
select strcmp(_gb2312'' collate gb2312_nopad_bin, _gb2312 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -6603,5 +6603,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid gbk character string: '\xAA\xA1'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001);
strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001)
-1
select strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001);
strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001)
-1
#
# End of 10.5 tests
#

View file

@ -500,6 +500,13 @@ SET NAMES gbk;
SET @seq=_gbk 0xAAA1;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_gbk'' collate gbk_chinese_nopad_ci, _gbk 0x0001050001);
select strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001);
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -19389,5 +19389,14 @@ EXECUTE IMMEDIATE CONCAT('a.', @seq, ':=1');
ERROR HY000: Invalid sjis character string: '<27>_x81'
SET sql_mode=DEFAULT;
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_sjis'' collate sjis_japanese_nopad_ci, _sjis 0x0001050001) as c1;
c1
-1
select strcmp(_sjis'' collate sjis_nopad_bin, _sjis 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -328,6 +328,13 @@ SET NAMES sjis;
SET @seq=_sjis 0x81AD;
--source include/ctype_ident_sys.inc
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_sjis'' collate sjis_japanese_nopad_ci, _sjis 0x0001050001) as c1;
select strcmp(_sjis'' collate sjis_nopad_bin, _sjis 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -0,0 +1,23 @@
# Start of 10.5 tests
#
# MDEV-28328 Assertion failures in btr0cur.cc upon INSERT or in row0sel.cc afterwards
#
SET NAMES utf8mb3;
CREATE TABLE t (
a year(4) DEFAULT NULL,
b varbinary(2545) DEFAULT '',
c mediumtext COLLATE sjis_japanese_nopad_ci NOT NULL,
d decimal(7,7) DEFAULT NULL,
e char(219) COLLATE sjis_japanese_nopad_ci DEFAULT '',
f bigint(25) DEFAULT 0,
g bigint(20) DEFAULT NULL,
h datetime(1) DEFAULT '1900-01-01 00:00:00.0',
PRIMARY KEY (c(25),e)
) ENGINE=InnoDB DEFAULT CHARSET=sjis COLLATE=sjis_japanese_nopad_ci;
INSERT IGNORE INTO t VALUES ... a mixture of non-ASCII and binary content
SELECT * FROM t /*output suppressed, just make sure it does not crash*/;
CHECK TABLE t;
Table Op Msg_type Msg_text
test.t check status OK
DROP TABLE t;
# End of 10.5 tests

File diff suppressed because one or more lines are too long

View file

@ -6555,5 +6555,14 @@ SELECT CAST(CONVERT('-9223372036854775808' USING ucs2) AS SIGNED) AS c1;
c1
-9223372036854775808
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_ucs2'' collate ucs2_general_nopad_ci, _ucs2 0x00000001000500000001) as c1;
c1
-1
select strcmp(_ucs2'' collate ucs2_nopad_bin, _ucs2 0x00000001000500000001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -1232,6 +1232,13 @@ DROP TABLE t1;
SELECT CAST(CONVERT('-9223372036854775808' USING ucs2) AS SIGNED) AS c1;
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_ucs2'' collate ucs2_general_nopad_ci, _ucs2 0x00000001000500000001) as c1;
select strcmp(_ucs2'' collate ucs2_nopad_bin, _ucs2 0x00000001000500000001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -26810,3 +26810,18 @@ SET DEFAULT_STORAGE_ENGINE=Default;
#
# End of 10.2 tests
#
#
# Start of 10.5 tests
#
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_ujis'' collate ujis_japanese_nopad_ci, _ujis 0x0001050001) as c1;
c1
-1
select strcmp(_ujis'' collate ujis_nopad_bin, _ujis 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -1436,3 +1436,18 @@ let $coll_pad='ujis_bin';
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_ujis'' collate ujis_japanese_nopad_ci, _ujis 0x0001050001) as c1;
select strcmp(_ujis'' collate ujis_nopad_bin, _ujis 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests
--echo #

View file

@ -11649,5 +11649,14 @@ CAST(_utf8 'яяя' AS INT)
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'яяя'
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
select strcmp(_utf8mb3'' collate utf8mb3_general_nopad_ci, _utf8mb3 0x0001050001) as c1;
c1
-1
select strcmp(_utf8mb3'' collate utf8mb3_nopad_bin, _utf8mb3 0x0001050001) as c1;
c1
-1
#
# End of 10.5 tests
#

View file

@ -2529,6 +2529,12 @@ SELECT CAST(_utf8 'ëëë' AS INT);
SELECT CAST(_utf8 'œœœ' AS INT);
SELECT CAST(_utf8 'яяя' AS INT);
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
select strcmp(_utf8mb3'' collate utf8mb3_general_nopad_ci, _utf8mb3 0x0001050001) as c1;
select strcmp(_utf8mb3'' collate utf8mb3_nopad_bin, _utf8mb3 0x0001050001) as c1;
--echo #
--echo # End of 10.5 tests

View file

@ -0,0 +1,39 @@
# Start of 10.5 tests
#
# MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
#
CREATE TABLE t (
a INT,
b VARCHAR(16),
c CHAR(8),
PRIMARY KEY (b,c),
KEY(c)
) ENGINE=InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_general_nopad_ci;
INSERT INTO t VALUES (1,UNHEX('0001050001'),''),(2,UNHEX('0000'),'x');
UPDATE t SET a = 0;
INSERT INTO t VALUES (0,'','');
CHECK TABLE t EXTENDED;
Table Op Msg_type Msg_text
test.t check status OK
DROP TABLE t;
#
# MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys)
#
CREATE TABLE t (
id INT,
b TEXT,
KEY(id),
PRIMARY KEY (b(2),id)
) ENGINE=InnoDB COLLATE utf8mb3_general_nopad_ci;
INSERT INTO t VALUES
(1,''),(2,'x'),(3,'x'),(4,UNHEX('0010')),(5,'x'),(6,'x'),(7,'x'),(8,'x'),
(9,UNHEX('00')),(10,'x'),(11,''),(12,UNHEX('73')),(13,'+'),(14,'N');
CHECK TABLE t EXTENDED;
Table Op Msg_type Msg_text
test.t check status OK
SELECT id FROM t WHERE id IN (4,8);
id
4
8
DROP TABLE t;
# End of 10.5 tests

View file

@ -0,0 +1,39 @@
--source include/have_innodb.inc
--echo # Start of 10.5 tests
--echo #
--echo # MDEV-30111 InnoDB: Failing assertion: update->n_fields == 0 in row_ins_sec_index_entry_by_modify
--echo #
CREATE TABLE t (
a INT,
b VARCHAR(16),
c CHAR(8),
PRIMARY KEY (b,c),
KEY(c)
) ENGINE=InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_general_nopad_ci;
INSERT INTO t VALUES (1,UNHEX('0001050001'),''),(2,UNHEX('0000'),'x');
UPDATE t SET a = 0;
INSERT INTO t VALUES (0,'','');
CHECK TABLE t EXTENDED;
DROP TABLE t;
--echo #
--echo # MDEV-32190 Index corruption with unique key and nopad collation (without DESC or HASH keys)
--echo #
CREATE TABLE t (
id INT,
b TEXT,
KEY(id),
PRIMARY KEY (b(2),id)
) ENGINE=InnoDB COLLATE utf8mb3_general_nopad_ci;
INSERT INTO t VALUES
(1,''),(2,'x'),(3,'x'),(4,UNHEX('0010')),(5,'x'),(6,'x'),(7,'x'),(8,'x'),
(9,UNHEX('00')),(10,'x'),(11,''),(12,UNHEX('73')),(13,'+'),(14,'N');
CHECK TABLE t EXTENDED;
SELECT id FROM t WHERE id IN (4,8);
DROP TABLE t;
--echo # End of 10.5 tests

View file

@ -190,12 +190,14 @@ MY_FUNCTION_NAME(strnncoll)(CHARSET_INFO *cs __attribute__((unused)),
0 >0 "a" is a prefix of "b", so "a" is smaller.
>0 0 "b" is a prefix of "a", check b_is_prefix.
>0 >0 Two weights were scanned, check weight difference.
Note: weights can be zero and positive (never negative).
*/
if (!a_wlen)
return b_wlen ? -b_weight : 0;
return b_wlen ? -1 : 0;
if (!b_wlen)
return b_is_prefix ? 0 : a_weight;
return b_is_prefix ? 0 : +1;
if ((res= (a_weight - b_weight)))
return res;