MDEV-30034 UNIQUE USING HASH accepts duplicate entries for tricky collations
- Adding a new argument "flag" to MY_COLLATION_HANDLER::strnncollsp_nchars() and a flag MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES. The flag defines if strnncollsp_nchars() should emulate trailing spaces which were possibly trimmed earlier (e.g. in InnoDB CHAR compression). This is important for NOPAD collations. For example, with this input: - str1= 'a ' (Latin letter a followed by one space) - str2= 'a ' (Latin letter a followed by two spaces) - nchars= 3 if the flag is given, strnncollsp_nchars() will virtually restore one trailing space to str1 up to nchars (3) characters and compare two strings as equal: - str1= 'a ' (one extra trailing space emulated) - str2= 'a ' (as is) If the flag is not given, strnncollsp_nchars() does not add trailing virtual spaces, so in case of a NOPAD collation, str1 will be compared as less than str2 because it is shorter. - Field_string::cmp_prefix() now passes the new flag. Field_varstring::cmp_prefix() and Field_blob::cmp_prefix() do not pass the new flag. - The branch in cmp_whole_field() in storage/innobase/rem/rem0cmp.cc (which handles the CHAR data type) now also passed the new flag. - Fixing UCA collations to respect the new flag. Other collations are possibly also affected, however I had no success in making an SQL script demonstrating the problem. Other collations will be extended to respect this flags in a separate patch later. - Changing the meaning of the last parameter of Field::cmp_prefix() from "number of bytes" (internal length) to "number of characters" (user visible length). The code calling cmp_prefix() from handler.cc was wrong. After this change, the call in handler.cc became correct. The code calling cmp_prefix() from key_rec_cmp() in key.cc was adjusted according to this change. - Old strnncollsp_nchar() related tests in unittest/strings/strings-t.c now pass the new flag. A few new tests also were added, without the flag.
This commit is contained in:
parent
0cc1694e9c
commit
8020b1bd73
@ -248,6 +248,28 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
|
|||||||
#define MY_STRXFRM_REVERSE_LEVEL6 0x00200000 /* if reverse order for level6 */
|
#define MY_STRXFRM_REVERSE_LEVEL6 0x00200000 /* if reverse order for level6 */
|
||||||
#define MY_STRXFRM_REVERSE_SHIFT 16
|
#define MY_STRXFRM_REVERSE_SHIFT 16
|
||||||
|
|
||||||
|
/* Flags to strnncollsp_nchars */
|
||||||
|
/*
|
||||||
|
MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES -
|
||||||
|
defines if inside strnncollsp_nchars()
|
||||||
|
short strings should be virtually extended to "nchars"
|
||||||
|
characters by emulating trimmed trailing spaces.
|
||||||
|
|
||||||
|
This flag is needed when comparing packed strings of the CHAR
|
||||||
|
data type, when trailing spaces are trimmed on storage (like in InnoDB),
|
||||||
|
however the actual values (after unpacking) will have those trailing
|
||||||
|
spaces.
|
||||||
|
|
||||||
|
If this flag is passed, strnncollsp_nchars() performs both
|
||||||
|
truncating longer strings and extending shorter strings
|
||||||
|
to exactly "nchars".
|
||||||
|
|
||||||
|
If this flag is not passed, strnncollsp_nchars() only truncates longer
|
||||||
|
strings to "nchars", but does not extend shorter strings to "nchars".
|
||||||
|
*/
|
||||||
|
#define MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES 1
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Collation IDs for MariaDB that should not conflict with MySQL.
|
Collation IDs for MariaDB that should not conflict with MySQL.
|
||||||
We reserve 256..511, because MySQL will most likely use this range
|
We reserve 256..511, because MySQL will most likely use this range
|
||||||
@ -383,7 +405,8 @@ struct my_collation_handler_st
|
|||||||
int (*strnncollsp_nchars)(CHARSET_INFO *,
|
int (*strnncollsp_nchars)(CHARSET_INFO *,
|
||||||
const uchar *str1, size_t len1,
|
const uchar *str1, size_t len1,
|
||||||
const uchar *str2, size_t len2,
|
const uchar *str2, size_t len2,
|
||||||
size_t nchars);
|
size_t nchars,
|
||||||
|
uint flags);
|
||||||
size_t (*strnxfrm)(CHARSET_INFO *,
|
size_t (*strnxfrm)(CHARSET_INFO *,
|
||||||
uchar *dst, size_t dstlen, uint nweights,
|
uchar *dst, size_t dstlen, uint nweights,
|
||||||
const uchar *src, size_t srclen, uint flags);
|
const uchar *src, size_t srclen, uint flags);
|
||||||
|
85
mysql-test/include/ctype_nopad_prefix_unique.inc
Normal file
85
mysql-test/include/ctype_nopad_prefix_unique.inc
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # MDEV-30034 UNIQUE USING HASH accepts duplicate entries for tricky collations
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# TEXT
|
||||||
|
|
||||||
|
if (`SELECT UPPER(@@storage_engine) != 'MEMORY'`)
|
||||||
|
{
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# VARCHAR
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# CHAR
|
||||||
|
|
||||||
|
# MyISAM is buggy on CHAR+BTREE+UNIQUE+PREFIX (see MDEV-30048), disable for now
|
||||||
|
# Other engines work fine
|
||||||
|
|
||||||
|
if (`SELECT UPPER(@@storage_engine) != 'MYISAM'`)
|
||||||
|
{
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
@ -761,3 +761,151 @@ DROP TABLE case_folding;
|
|||||||
#
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.4 tests
|
||||||
|
#
|
||||||
|
SET STORAGE_ENGINE=MyISAM;
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_unicode_nopad_ci;
|
||||||
|
#
|
||||||
|
# MDEV-30034 UNIQUE USING HASH accepts duplicate entries for tricky collations
|
||||||
|
#
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` text CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` text CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(20) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET STORAGE_ENGINE=HEAP;
|
||||||
|
#
|
||||||
|
# MDEV-30034 UNIQUE USING HASH accepts duplicate entries for tricky collations
|
||||||
|
#
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(20) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(20) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET STORAGE_ENGINE=DEFAULT;
|
||||||
|
#
|
||||||
|
# End of 10.4 tests
|
||||||
|
#
|
||||||
|
@ -50,3 +50,21 @@ SET NAMES utf8mb3 COLLATE utf8mb3_thai_520_w2;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET STORAGE_ENGINE=MyISAM;
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_unicode_nopad_ci;
|
||||||
|
--source include/ctype_nopad_prefix_unique.inc
|
||||||
|
|
||||||
|
SET STORAGE_ENGINE=HEAP;
|
||||||
|
--source include/ctype_nopad_prefix_unique.inc
|
||||||
|
|
||||||
|
SET STORAGE_ENGINE=DEFAULT;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
@ -283,3 +283,101 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Start of 10.4 tests
|
||||||
|
#
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_unicode_nopad_ci;
|
||||||
|
#
|
||||||
|
# MDEV-30034 UNIQUE USING HASH accepts duplicate entries for tricky collations
|
||||||
|
#
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` text CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a TEXT COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` text CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a VARCHAR(2000) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
ERROR 23000: Duplicate entry 'ß ' for key 'a'
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)))',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(20) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3))
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXECUTE IMMEDIATE REPLACE(
|
||||||
|
'CREATE TABLE t1 ( '
|
||||||
|
' a CHAR(20) COLLATE <COLLATION>,'
|
||||||
|
'UNIQUE(a(3)) USING HASH)',
|
||||||
|
'<COLLATION>', @@collation_connection);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(20) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci DEFAULT NULL,
|
||||||
|
UNIQUE KEY `a` (`a`(3)) USING HASH
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||||
|
INSERT INTO t1 VALUES ('ss ');
|
||||||
|
INSERT INTO t1 VALUES (_utf8mb3 0xC39F20)/*SZ+SPACE*/;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# End 10.4 tests
|
||||||
|
#
|
||||||
|
@ -23,3 +23,15 @@ let $coll_pad='utf8_bin';
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.4 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET NAMES utf8mb3 COLLATE utf8mb3_unicode_nopad_ci;
|
||||||
|
--source include/ctype_nopad_prefix_unique.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End 10.4 tests
|
||||||
|
--echo #
|
||||||
|
21
sql/field.cc
21
sql/field.cc
@ -7435,7 +7435,8 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
|
|||||||
return field_charset->coll->strnncollsp_nchars(field_charset,
|
return field_charset->coll->strnncollsp_nchars(field_charset,
|
||||||
a_ptr, field_length,
|
a_ptr, field_length,
|
||||||
b_ptr, field_length,
|
b_ptr, field_length,
|
||||||
Field_string::char_length());
|
Field_string::char_length(),
|
||||||
|
MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7835,10 +7836,11 @@ int Field_varstring::cmp(const uchar *a_ptr, const uchar *b_ptr)
|
|||||||
|
|
||||||
|
|
||||||
int Field_varstring::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
int Field_varstring::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
||||||
size_t prefix_len)
|
size_t prefix_char_len)
|
||||||
{
|
{
|
||||||
/* avoid expensive well_formed_char_length if possible */
|
/* avoid more expensive strnncollsp_nchars() if possible */
|
||||||
if (prefix_len == table->field[field_index]->field_length)
|
if (prefix_char_len * field_charset->mbmaxlen ==
|
||||||
|
table->field[field_index]->field_length)
|
||||||
return Field_varstring::cmp(a_ptr, b_ptr);
|
return Field_varstring::cmp(a_ptr, b_ptr);
|
||||||
|
|
||||||
size_t a_length, b_length;
|
size_t a_length, b_length;
|
||||||
@ -7858,7 +7860,8 @@ int Field_varstring::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
|||||||
a_length,
|
a_length,
|
||||||
b_ptr + length_bytes,
|
b_ptr + length_bytes,
|
||||||
b_length,
|
b_length,
|
||||||
prefix_len / field_charset->mbmaxlen);
|
prefix_char_len,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -8635,7 +8638,7 @@ int Field_blob::cmp(const uchar *a_ptr, const uchar *b_ptr)
|
|||||||
|
|
||||||
|
|
||||||
int Field_blob::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
int Field_blob::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
||||||
size_t prefix_len)
|
size_t prefix_char_len)
|
||||||
{
|
{
|
||||||
uchar *blob1,*blob2;
|
uchar *blob1,*blob2;
|
||||||
memcpy(&blob1, a_ptr+packlength, sizeof(char*));
|
memcpy(&blob1, a_ptr+packlength, sizeof(char*));
|
||||||
@ -8644,7 +8647,8 @@ int Field_blob::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
|||||||
return field_charset->coll->strnncollsp_nchars(field_charset,
|
return field_charset->coll->strnncollsp_nchars(field_charset,
|
||||||
blob1, a_len,
|
blob1, a_len,
|
||||||
blob2, b_len,
|
blob2, b_len,
|
||||||
prefix_len / field_charset->mbmaxlen);
|
prefix_char_len,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10114,7 +10118,8 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value)
|
|||||||
The a and b pointer must be pointers to the field in a record
|
The a and b pointer must be pointers to the field in a record
|
||||||
(not the table->record[0] necessarily)
|
(not the table->record[0] necessarily)
|
||||||
*/
|
*/
|
||||||
int Field_bit::cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len)
|
int Field_bit::cmp_prefix(const uchar *a, const uchar *b,
|
||||||
|
size_t prefix_char_len)
|
||||||
{
|
{
|
||||||
my_ptrdiff_t a_diff= a - ptr;
|
my_ptrdiff_t a_diff= a - ptr;
|
||||||
my_ptrdiff_t b_diff= b - ptr;
|
my_ptrdiff_t b_diff= b - ptr;
|
||||||
|
@ -1109,7 +1109,8 @@ public:
|
|||||||
The following method is used for comparing prefix keys.
|
The following method is used for comparing prefix keys.
|
||||||
Currently it's only used in partitioning.
|
Currently it's only used in partitioning.
|
||||||
*/
|
*/
|
||||||
virtual int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len)
|
virtual int cmp_prefix(const uchar *a, const uchar *b,
|
||||||
|
size_t prefix_char_len)
|
||||||
{ return cmp(a, b); }
|
{ return cmp(a, b); }
|
||||||
virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U)
|
virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U)
|
||||||
{ return memcmp(a,b,pack_length()); }
|
{ return memcmp(a,b,pack_length()); }
|
||||||
@ -3728,7 +3729,7 @@ public:
|
|||||||
String *val_str(String*,String *);
|
String *val_str(String*,String *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
int cmp(const uchar *a,const uchar *b);
|
int cmp(const uchar *a,const uchar *b);
|
||||||
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
|
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_char_len);
|
||||||
void sort_string(uchar *buff,uint length);
|
void sort_string(uchar *buff,uint length);
|
||||||
uint get_key_image(uchar *buff,uint length, imagetype type);
|
uint get_key_image(uchar *buff,uint length, imagetype type);
|
||||||
void set_key_image(const uchar *buff,uint length);
|
void set_key_image(const uchar *buff,uint length);
|
||||||
@ -3964,7 +3965,7 @@ public:
|
|||||||
String *val_str(String*,String *);
|
String *val_str(String*,String *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
int cmp(const uchar *a,const uchar *b);
|
int cmp(const uchar *a,const uchar *b);
|
||||||
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
|
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_char_len);
|
||||||
int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length);
|
int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length);
|
||||||
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U);
|
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U);
|
||||||
int key_cmp(const uchar *,const uchar*);
|
int key_cmp(const uchar *,const uchar*);
|
||||||
@ -4501,7 +4502,7 @@ public:
|
|||||||
}
|
}
|
||||||
int cmp_binary_offset(uint row_offset)
|
int cmp_binary_offset(uint row_offset)
|
||||||
{ return cmp_offset(row_offset); }
|
{ return cmp_offset(row_offset); }
|
||||||
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
|
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_char_len);
|
||||||
int key_cmp(const uchar *a, const uchar *b)
|
int key_cmp(const uchar *a, const uchar *b)
|
||||||
{ return cmp_binary((uchar *) a, (uchar *) b); }
|
{ return cmp_binary((uchar *) a, (uchar *) b); }
|
||||||
int key_cmp(const uchar *str, uint length);
|
int key_cmp(const uchar *str, uint length);
|
||||||
|
@ -612,7 +612,8 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
|
|||||||
that take the max length into account.
|
that take the max length into account.
|
||||||
*/
|
*/
|
||||||
if ((result= field->cmp_prefix(field->ptr+first_diff, field->ptr+sec_diff,
|
if ((result= field->cmp_prefix(field->ptr+first_diff, field->ptr+sec_diff,
|
||||||
key_part->length)))
|
key_part->length /
|
||||||
|
field->charset()->mbmaxlen)))
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
next_loop:
|
next_loop:
|
||||||
key_part++;
|
key_part++;
|
||||||
|
@ -327,7 +327,8 @@ static int cmp_whole_field(ulint mtype, ulint prtype,
|
|||||||
if (CHARSET_INFO *cs= get_charset(dtype_get_charset_coll(prtype),
|
if (CHARSET_INFO *cs= get_charset(dtype_get_charset_coll(prtype),
|
||||||
MYF(MY_WME)))
|
MYF(MY_WME)))
|
||||||
return cs->coll->strnncollsp_nchars(cs, a, a_length, b, b_length,
|
return cs->coll->strnncollsp_nchars(cs, a, a_length, b, b_length,
|
||||||
std::max(a_length, b_length));
|
std::max(a_length, b_length),
|
||||||
|
MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES);
|
||||||
}
|
}
|
||||||
|
|
||||||
ib::fatal() << "Unable to find charset-collation for " << prtype;
|
ib::fatal() << "Unable to find charset-collation for " << prtype;
|
||||||
|
@ -128,7 +128,8 @@ static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)),
|
|||||||
static int my_strnncollsp_nchars_binary(CHARSET_INFO * cs __attribute__((unused)),
|
static int my_strnncollsp_nchars_binary(CHARSET_INFO * cs __attribute__((unused)),
|
||||||
const uchar *s, size_t slen,
|
const uchar *s, size_t slen,
|
||||||
const uchar *t, size_t tlen,
|
const uchar *t, size_t tlen,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
set_if_smaller(slen, nchars);
|
set_if_smaller(slen, nchars);
|
||||||
set_if_smaller(tlen, nchars);
|
set_if_smaller(tlen, nchars);
|
||||||
@ -213,7 +214,8 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
|
|||||||
static int my_strnncollsp_nchars_8bit_bin(CHARSET_INFO * cs,
|
static int my_strnncollsp_nchars_8bit_bin(CHARSET_INFO * cs,
|
||||||
const uchar *a, size_t a_length,
|
const uchar *a, size_t a_length,
|
||||||
const uchar *b, size_t b_length,
|
const uchar *b, size_t b_length,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
set_if_smaller(a_length, nchars);
|
set_if_smaller(a_length, nchars);
|
||||||
set_if_smaller(b_length, nchars);
|
set_if_smaller(b_length, nchars);
|
||||||
|
@ -212,7 +212,8 @@ static int
|
|||||||
my_strnncollsp_nchars_simple(CHARSET_INFO * cs,
|
my_strnncollsp_nchars_simple(CHARSET_INFO * cs,
|
||||||
const uchar *a, size_t a_length,
|
const uchar *a, size_t a_length,
|
||||||
const uchar *b, size_t b_length,
|
const uchar *b, size_t b_length,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
set_if_smaller(a_length, nchars);
|
set_if_smaller(a_length, nchars);
|
||||||
set_if_smaller(b_length, nchars);
|
set_if_smaller(b_length, nchars);
|
||||||
|
@ -589,7 +589,8 @@ static int
|
|||||||
my_strnncollsp_nchars_tis620(CHARSET_INFO * cs,
|
my_strnncollsp_nchars_tis620(CHARSET_INFO * cs,
|
||||||
const uchar *a, size_t a_length,
|
const uchar *a, size_t a_length,
|
||||||
const uchar *b, size_t b_length,
|
const uchar *b, size_t b_length,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
set_if_smaller(a_length, nchars);
|
set_if_smaller(a_length, nchars);
|
||||||
set_if_smaller(b_length, nchars);
|
set_if_smaller(b_length, nchars);
|
||||||
|
@ -317,6 +317,7 @@ MY_FUNCTION_NAME(strnncollsp_nopad_multilevel)(CHARSET_INFO *cs,
|
|||||||
static inline weight_and_nchars_t
|
static inline weight_and_nchars_t
|
||||||
MY_FUNCTION_NAME(scanner_next_pad_trim)(my_uca_scanner *scanner,
|
MY_FUNCTION_NAME(scanner_next_pad_trim)(my_uca_scanner *scanner,
|
||||||
size_t nchars,
|
size_t nchars,
|
||||||
|
uint flags,
|
||||||
uint *generated)
|
uint *generated)
|
||||||
{
|
{
|
||||||
weight_and_nchars_t res;
|
weight_and_nchars_t res;
|
||||||
@ -330,7 +331,10 @@ MY_FUNCTION_NAME(scanner_next_pad_trim)(my_uca_scanner *scanner,
|
|||||||
We reached the end of the string, but the caller wants more weights.
|
We reached the end of the string, but the caller wants more weights.
|
||||||
Perform space padding.
|
Perform space padding.
|
||||||
*/
|
*/
|
||||||
res.weight= my_space_weight(scanner->level);
|
res.weight=
|
||||||
|
flags & MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES ?
|
||||||
|
my_space_weight(scanner->level) : 0;
|
||||||
|
|
||||||
res.nchars= 1;
|
res.nchars= 1;
|
||||||
(*generated)++;
|
(*generated)++;
|
||||||
}
|
}
|
||||||
@ -367,7 +371,8 @@ MY_FUNCTION_NAME(strnncollsp_nchars_onelevel)(CHARSET_INFO *cs,
|
|||||||
const MY_UCA_WEIGHT_LEVEL *level,
|
const MY_UCA_WEIGHT_LEVEL *level,
|
||||||
const uchar *s, size_t slen,
|
const uchar *s, size_t slen,
|
||||||
const uchar *t, size_t tlen,
|
const uchar *t, size_t tlen,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
my_uca_scanner sscanner;
|
my_uca_scanner sscanner;
|
||||||
my_uca_scanner tscanner;
|
my_uca_scanner tscanner;
|
||||||
@ -385,15 +390,17 @@ MY_FUNCTION_NAME(strnncollsp_nchars_onelevel)(CHARSET_INFO *cs,
|
|||||||
int diff;
|
int diff;
|
||||||
|
|
||||||
s_res= MY_FUNCTION_NAME(scanner_next_pad_trim)(&sscanner, s_nchars_left,
|
s_res= MY_FUNCTION_NAME(scanner_next_pad_trim)(&sscanner, s_nchars_left,
|
||||||
&generated);
|
flags, &generated);
|
||||||
t_res= MY_FUNCTION_NAME(scanner_next_pad_trim)(&tscanner, t_nchars_left,
|
t_res= MY_FUNCTION_NAME(scanner_next_pad_trim)(&tscanner, t_nchars_left,
|
||||||
&generated);
|
flags, &generated);
|
||||||
|
|
||||||
if ((diff= (s_res.weight - t_res.weight)))
|
if ((diff= (s_res.weight - t_res.weight)))
|
||||||
return diff;
|
return diff;
|
||||||
|
|
||||||
if (generated == 2)
|
if (generated == 2)
|
||||||
{
|
{
|
||||||
if (cs->state & MY_CS_NOPAD)
|
if ((cs->state & MY_CS_NOPAD) &&
|
||||||
|
(flags & MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Both values are auto-generated. There's no real data any more.
|
Both values are auto-generated. There's no real data any more.
|
||||||
@ -445,11 +452,12 @@ static int
|
|||||||
MY_FUNCTION_NAME(strnncollsp_nchars)(CHARSET_INFO *cs,
|
MY_FUNCTION_NAME(strnncollsp_nchars)(CHARSET_INFO *cs,
|
||||||
const uchar *s, size_t slen,
|
const uchar *s, size_t slen,
|
||||||
const uchar *t, size_t tlen,
|
const uchar *t, size_t tlen,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
return MY_FUNCTION_NAME(strnncollsp_nchars_onelevel)(cs, &cs->uca->level[0],
|
return MY_FUNCTION_NAME(strnncollsp_nchars_onelevel)(cs, &cs->uca->level[0],
|
||||||
s, slen, t, tlen,
|
s, slen, t, tlen,
|
||||||
nchars);
|
nchars, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -460,7 +468,8 @@ static int
|
|||||||
MY_FUNCTION_NAME(strnncollsp_nchars_multilevel)(CHARSET_INFO *cs,
|
MY_FUNCTION_NAME(strnncollsp_nchars_multilevel)(CHARSET_INFO *cs,
|
||||||
const uchar *s, size_t slen,
|
const uchar *s, size_t slen,
|
||||||
const uchar *t, size_t tlen,
|
const uchar *t, size_t tlen,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
uint num_level= cs->levels_for_order;
|
uint num_level= cs->levels_for_order;
|
||||||
uint i;
|
uint i;
|
||||||
@ -470,7 +479,7 @@ MY_FUNCTION_NAME(strnncollsp_nchars_multilevel)(CHARSET_INFO *cs,
|
|||||||
&cs->uca->level[i],
|
&cs->uca->level[i],
|
||||||
s, slen,
|
s, slen,
|
||||||
t, tlen,
|
t, tlen,
|
||||||
nchars);
|
nchars, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1215,7 +1215,8 @@ outp:
|
|||||||
int my_strnncollsp_nchars_generic(CHARSET_INFO *cs,
|
int my_strnncollsp_nchars_generic(CHARSET_INFO *cs,
|
||||||
const uchar *str1, size_t len1,
|
const uchar *str1, size_t len1,
|
||||||
const uchar *str2, size_t len2,
|
const uchar *str2, size_t len2,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
len1= my_well_formed_length(cs, (const char *) str1,
|
len1= my_well_formed_length(cs, (const char *) str1,
|
||||||
@ -1232,7 +1233,8 @@ int my_strnncollsp_nchars_generic(CHARSET_INFO *cs,
|
|||||||
int my_strnncollsp_nchars_generic_8bit(CHARSET_INFO *cs,
|
int my_strnncollsp_nchars_generic_8bit(CHARSET_INFO *cs,
|
||||||
const uchar *str1, size_t len1,
|
const uchar *str1, size_t len1,
|
||||||
const uchar *str2, size_t len2,
|
const uchar *str2, size_t len2,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
set_if_smaller(len1, nchars);
|
set_if_smaller(len1, nchars);
|
||||||
set_if_smaller(len2, nchars);
|
set_if_smaller(len2, nchars);
|
||||||
|
@ -304,7 +304,8 @@ static int
|
|||||||
MY_FUNCTION_NAME(strnncollsp_nchars)(CHARSET_INFO *cs __attribute__((unused)),
|
MY_FUNCTION_NAME(strnncollsp_nchars)(CHARSET_INFO *cs __attribute__((unused)),
|
||||||
const uchar *a, size_t a_length,
|
const uchar *a, size_t a_length,
|
||||||
const uchar *b, size_t b_length,
|
const uchar *b, size_t b_length,
|
||||||
size_t nchars)
|
size_t nchars,
|
||||||
|
uint flags)
|
||||||
{
|
{
|
||||||
const uchar *a_end= a + a_length;
|
const uchar *a_end= a + a_length;
|
||||||
const uchar *b_end= b + b_length;
|
const uchar *b_end= b + b_length;
|
||||||
|
@ -108,12 +108,14 @@ static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
|
|||||||
int my_strnncollsp_nchars_generic(CHARSET_INFO *cs,
|
int my_strnncollsp_nchars_generic(CHARSET_INFO *cs,
|
||||||
const uchar *str1, size_t len1,
|
const uchar *str1, size_t len1,
|
||||||
const uchar *str2, size_t len2,
|
const uchar *str2, size_t len2,
|
||||||
size_t nchars);
|
size_t nchars,
|
||||||
|
uint flags);
|
||||||
|
|
||||||
int my_strnncollsp_nchars_generic_8bit(CHARSET_INFO *cs,
|
int my_strnncollsp_nchars_generic_8bit(CHARSET_INFO *cs,
|
||||||
const uchar *str1, size_t len1,
|
const uchar *str1, size_t len1,
|
||||||
const uchar *str2, size_t len2,
|
const uchar *str2, size_t len2,
|
||||||
size_t nchars);
|
size_t nchars,
|
||||||
|
uint flags);
|
||||||
|
|
||||||
uint my_8bit_charset_flags_from_data(CHARSET_INFO *cs);
|
uint my_8bit_charset_flags_from_data(CHARSET_INFO *cs);
|
||||||
uint my_8bit_collation_flags_from_data(CHARSET_INFO *cs);
|
uint my_8bit_collation_flags_from_data(CHARSET_INFO *cs);
|
||||||
|
@ -787,9 +787,14 @@ typedef struct
|
|||||||
LEX_CSTRING a;
|
LEX_CSTRING a;
|
||||||
LEX_CSTRING b;
|
LEX_CSTRING b;
|
||||||
size_t nchars;
|
size_t nchars;
|
||||||
|
uint flags;
|
||||||
int res;
|
int res;
|
||||||
} STRNNCOLLSP_CHAR_PARAM;
|
} STRNNCOLLSP_CHAR_PARAM;
|
||||||
|
|
||||||
|
#undef TCHAR
|
||||||
|
#define TCHAR MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES
|
||||||
|
|
||||||
|
#define TVCHAR 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some lines in the below test data are marked as follows:
|
Some lines in the below test data are marked as follows:
|
||||||
@ -811,266 +816,273 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen1_xpad_common[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen1_xpad_common[]=
|
||||||
{
|
{
|
||||||
{{CSTR("a")}, {CSTR("a")}, 0, 0},
|
{{CSTR("a")}, {CSTR("a")}, 0, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a")}, 1, 0},
|
{{CSTR("a")}, {CSTR("a")}, 1, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a")}, 2, 0},
|
{{CSTR("a")}, {CSTR("a")}, 2, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a")}, 3, 0},
|
{{CSTR("a")}, {CSTR("a")}, 3, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a")}, 100, 0},
|
{{CSTR("a")}, {CSTR("a")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("a")}, {CSTR("ab")}, 0, 0},
|
{{CSTR("a")}, {CSTR("ab")}, 0, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("ab")}, 1, 0},
|
{{CSTR("a")}, {CSTR("ab")}, 1, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("ab")}, 2, -1},
|
{{CSTR("a")}, {CSTR("ab")}, 2, TCHAR, -1},
|
||||||
{{CSTR("a")}, {CSTR("ab")}, 3, -1},
|
{{CSTR("a")}, {CSTR("ab")}, 3, TCHAR, -1},
|
||||||
{{CSTR("a")}, {CSTR("ab")}, 100, -1},
|
{{CSTR("a")}, {CSTR("ab")}, 100, TCHAR, -1},
|
||||||
|
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 0, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 0, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 1, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 1, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 2, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 2, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 3, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 3, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 100, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 0, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 0, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 1, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 1, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 2, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 2, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 3, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 3, TCHAR, 0},
|
||||||
{{CSTR("a")}, {CSTR("a ")}, 100, 0},
|
{{CSTR("a")}, {CSTR("a ")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ss")}, {CSTR("ss")}, 0, 0},
|
{{CSTR("ss")}, {CSTR("ss")}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("ss")}, 1, 0},
|
{{CSTR("ss")}, {CSTR("ss")}, 1, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("ss")}, 2, 0},
|
{{CSTR("ss")}, {CSTR("ss")}, 2, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("ss")}, 3, 0},
|
{{CSTR("ss")}, {CSTR("ss")}, 3, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("ss")}, 100, 0},
|
{{CSTR("ss")}, {CSTR("ss")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Tests for utf8, for both PAD SPACE and NOPAD collations */
|
/* Tests for utf8, for both PAD SPACE and NOPAD collations */
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_xpad_common[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_xpad_common[]=
|
||||||
{
|
{
|
||||||
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 0, 0},
|
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 1, 0},
|
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 1, TCHAR, 0},
|
||||||
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 2, 0},
|
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 2, TCHAR, 0},
|
||||||
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 3, 0},
|
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 3, TCHAR, 0},
|
||||||
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 100, 0},
|
{{CSTR(UTF8_sz)}, {CSTR(UTF8_sz)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Tests for latin1, for both PAD and NOPAD collations */
|
/* Tests for latin1, for both PAD and NOPAD collations */
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_latin1_xpad_common[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_latin1_xpad_common[]=
|
||||||
{
|
{
|
||||||
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 0, 0},
|
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 1, 0},
|
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 1, TCHAR, 0},
|
||||||
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 2, 0},
|
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 2, TCHAR, 0},
|
||||||
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 3, 0},
|
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 3, TCHAR, 0},
|
||||||
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 100, 0},
|
{{CSTR(LATIN1_sz)}, {CSTR(LATIN1_sz)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Tests for utf8 collations that sort "A WITH DIAERESIS" equal to "A" */
|
/* Tests for utf8 collations that sort "A WITH DIAERESIS" equal to "A" */
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_xpad_a_eq_auml[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_xpad_a_eq_auml[]=
|
||||||
{
|
{
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 0, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 0, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 1, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 1, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 2, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 2, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 3, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 3, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 100, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 0, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 0, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 1, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 1, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 2, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 2, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 3, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 3, TCHAR, 0},
|
||||||
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 100, 0},
|
{{CSTR(UTF8_auml "h")}, {CSTR("ah ")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_ci[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_ci[]=
|
||||||
{
|
{
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 0, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 1, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 1, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}/*IF*/, 2, 1},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}/*IF*/, 2, TCHAR, 1},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 3, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 3, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 4, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 4, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 100, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_nopad_ci[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_unicode_nopad_ci[]=
|
||||||
{
|
{
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 0, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 1, 0},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 1, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}/*IF*/, 2, 1},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}/*IF*/, 2, TCHAR, 1},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 3, 1},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 3, TCHAR, 1},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 4, 1},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 4, TCHAR, 1},
|
||||||
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 100, 1},
|
{{CSTR("ss")}, {CSTR("s" "\x00" "s")}, 100, TCHAR, 1},
|
||||||
|
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TCHAR, -1},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, TVCHAR, 0},
|
||||||
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, TVCHAR, -1},
|
||||||
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, TVCHAR, 0},
|
||||||
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, TVCHAR, 0},
|
||||||
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 4, TVCHAR, 0},
|
||||||
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TVCHAR, 0},
|
||||||
|
|
||||||
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_danish_ci[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mb3_danish_ci[]=
|
||||||
{
|
{
|
||||||
{{CSTR("aa")}, {CSTR("")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("")}, 1, 1},
|
{{CSTR("aa")}/*CF*/, {CSTR("")}, 1, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("")}, 2, 1},
|
{{CSTR("aa")}, {CSTR("")}, 2, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("")}, 3, 1},
|
{{CSTR("aa")}, {CSTR("")}, 3, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("")}, 100, 1},
|
{{CSTR("aa")}, {CSTR("")}, 100, TCHAR, 1},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR("a")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("a")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("a")}, 1, 0},
|
{{CSTR("aa")}/*CF*/, {CSTR("a")}, 1, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("a")}, 2, 1},
|
{{CSTR("aa")}, {CSTR("a")}, 2, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("a")}, 3, 1},
|
{{CSTR("aa")}, {CSTR("a")}, 3, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("a")}, 100, 1},
|
{{CSTR("aa")}, {CSTR("a")}, 100, TCHAR, 1},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR("aa")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("aa")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("aa")}/*CF*/, 1, 0},
|
{{CSTR("aa")}/*CF*/, {CSTR("aa")}/*CF*/, 1, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("aa")}, 2, 0},
|
{{CSTR("aa")}, {CSTR("aa")}, 2, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("aa")}, 3, 0},
|
{{CSTR("aa")}, {CSTR("aa")}, 3, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("aa")}, 100, 0},
|
{{CSTR("aa")}, {CSTR("aa")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "a")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("\x00" "a")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("\x00" "a")}/*IF*/, 1, 1},
|
{{CSTR("aa")}/*CF*/, {CSTR("\x00" "a")}/*IF*/, 1, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "a")}, 2, 1},
|
{{CSTR("aa")}, {CSTR("\x00" "a")}, 2, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "a")}, 3, 1},
|
{{CSTR("aa")}, {CSTR("\x00" "a")}, 3, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "a")}, 100, 1},
|
{{CSTR("aa")}, {CSTR("\x00" "a")}, 100, TCHAR, 1},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("\x00" "aa")}/*IF*/, 1, 1},
|
{{CSTR("aa")}/*CF*/, {CSTR("\x00" "aa")}/*IF*/, 1, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "aa")}/*IF*/, 2, 1},
|
{{CSTR("aa")}, {CSTR("\x00" "aa")}/*IF*/, 2, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 3, 0},
|
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 3, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 100, 0},
|
{{CSTR("aa")}, {CSTR("\x00" "aa")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 0, 0},
|
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR("a" "\x00" "a")}, 1, 0},
|
{{CSTR("aa")}/*CF*/, {CSTR("a" "\x00" "a")}, 1, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}/*IF*/, 2, 1},
|
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}/*IF*/, 2, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 3, 1},
|
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 3, TCHAR, 1},
|
||||||
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 100, 1},
|
{{CSTR("aa")}, {CSTR("a" "\x00" "a")}, 100, TCHAR, 1},
|
||||||
|
|
||||||
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 0, 0},
|
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 0, TCHAR, 0},
|
||||||
{{CSTR("aa")}/*CF*/, {CSTR(UTF8_ARING)}, 1, -1},
|
{{CSTR("aa")}/*CF*/, {CSTR(UTF8_ARING)}, 1, TCHAR, -1},
|
||||||
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 2, 0},
|
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 2, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 3, 0},
|
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 3, TCHAR, 0},
|
||||||
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 100, 0},
|
{{CSTR("aa")}, {CSTR(UTF8_ARING)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_latin1_german2_ci[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_latin1_german2_ci[]=
|
||||||
{
|
{
|
||||||
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 0, 0},
|
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 1, -1},
|
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 2, 0},
|
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 2, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 3, 0},
|
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 3, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 100, 0},
|
{{CSTR("ss")}, {CSTR(LATIN1_sz)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 0, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 1, -1},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 2, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 2, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 3, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 3, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 100, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 0, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 0, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 1, -1},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 1, TCHAR, -1},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 2, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 2, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 3, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 3, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 100, 0},
|
{{CSTR("ae")}, {CSTR(LATIN1_auml " ")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_german2_ci[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_utf8mbx_german2_ci[]=
|
||||||
{
|
{
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, -1},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 2, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 3, TCHAR, 0},
|
||||||
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, 0},
|
{{CSTR("ss")}, {CSTR(UTF8_sz)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 0, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 0, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 1, -1},
|
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 1, TCHAR, -1},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 2, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 2, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 3, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 3, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 100, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 0, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 0, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 1, -1},
|
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 1, TCHAR, -1},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 2, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 2, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 3, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 3, TCHAR, 0},
|
||||||
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 100, 0},
|
{{CSTR("ae")}, {CSTR(UTF8_auml " ")}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen1_xpad_czech[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen1_xpad_czech[]=
|
||||||
{
|
{
|
||||||
{{CSTR("c")}, {CSTR("ch")}, 0, 0},
|
{{CSTR("c")}, {CSTR("ch")}, 0, TCHAR, 0},
|
||||||
{{CSTR("c")}, {CSTR("ch")}, 1, 0},
|
{{CSTR("c")}, {CSTR("ch")}, 1, TCHAR, 0},
|
||||||
{{CSTR("c")}, {CSTR("ch")}, 2, -1},
|
{{CSTR("c")}, {CSTR("ch")}, 2, TCHAR, -1},
|
||||||
|
|
||||||
{{CSTR("h")}, {CSTR("ch")}, 0, 0},
|
{{CSTR("h")}, {CSTR("ch")}, 0, TCHAR, 0},
|
||||||
{{CSTR("h")}, {CSTR("ch")}, 1, 1},
|
{{CSTR("h")}, {CSTR("ch")}, 1, TCHAR, 1},
|
||||||
{{CSTR("h")}, {CSTR("ch")}, 2, -1},
|
{{CSTR("h")}, {CSTR("ch")}, 2, TCHAR, -1},
|
||||||
|
|
||||||
{{CSTR("i")}, {CSTR("ch")}, 0, 0},
|
{{CSTR("i")}, {CSTR("ch")}, 0, TCHAR, 0},
|
||||||
{{CSTR("i")}, {CSTR("ch")}, 1, 1},
|
{{CSTR("i")}, {CSTR("ch")}, 1, TCHAR, 1},
|
||||||
{{CSTR("i")}, {CSTR("ch")}, 2, 1},
|
{{CSTR("i")}, {CSTR("ch")}, 2, TCHAR, 1},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen2_xpad_common[]=
|
static STRNNCOLLSP_CHAR_PARAM strnncollsp_char_mbminlen2_xpad_common[]=
|
||||||
{
|
{
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 0, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 0, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 1, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 1, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 2, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 2, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 3, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 3, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 100, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 0, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 0, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 1, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 1, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 2, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 2, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 3, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 3, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 100, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 0, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 0, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 1, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 1, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 2, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 2, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 3, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 3, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 100, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_sp UCS2_sp)}, 100, TCHAR, 0},
|
||||||
|
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 0, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 0, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 1, 0},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 1, TCHAR, 0},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 2, -1},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 2, TCHAR, -1},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 3, -1},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 3, TCHAR, -1},
|
||||||
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 100, -1},
|
{{CSTR(UCS2_a)}, {CSTR(UCS2_a UCS2_b)}, 100, TCHAR, -1},
|
||||||
|
|
||||||
{{NULL, 0}, {NULL, 0}, 0, 0}
|
{{NULL, 0}, {NULL, 0}, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1082,7 +1094,7 @@ strnncollsp_char_one(CHARSET_INFO *cs, const STRNNCOLLSP_CHAR_PARAM *p)
|
|||||||
int res= cs->coll->strnncollsp_nchars(cs,
|
int res= cs->coll->strnncollsp_nchars(cs,
|
||||||
(uchar *) p->a.str, p->a.length,
|
(uchar *) p->a.str, p->a.length,
|
||||||
(uchar *) p->b.str, p->b.length,
|
(uchar *) p->b.str, p->b.length,
|
||||||
p->nchars);
|
p->nchars, p->flags);
|
||||||
str2hex(ahex, sizeof(ahex), p->a.str, p->a.length);
|
str2hex(ahex, sizeof(ahex), p->a.str, p->a.length);
|
||||||
str2hex(bhex, sizeof(bhex), p->b.str, p->b.length);
|
str2hex(bhex, sizeof(bhex), p->b.str, p->b.length);
|
||||||
diag("%-25s %-12s %-12s %3d %7d %7d%s",
|
diag("%-25s %-12s %-12s %3d %7d %7d%s",
|
||||||
@ -1098,7 +1110,7 @@ strnncollsp_char_one(CHARSET_INFO *cs, const STRNNCOLLSP_CHAR_PARAM *p)
|
|||||||
res= cs->coll->strnncollsp_nchars(cs,
|
res= cs->coll->strnncollsp_nchars(cs,
|
||||||
(uchar *) p->b.str, p->b.length,
|
(uchar *) p->b.str, p->b.length,
|
||||||
(uchar *) p->a.str, p->a.length,
|
(uchar *) p->a.str, p->a.length,
|
||||||
p->nchars);
|
p->nchars, p->flags);
|
||||||
if (!eqres(res, -p->res))
|
if (!eqres(res, -p->res))
|
||||||
{
|
{
|
||||||
diag("Comparison in reverse order failed. Expected %d, got %d",
|
diag("Comparison in reverse order failed. Expected %d, got %d",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user