diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1d5935f981a..7ff4817feac 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -88,6 +88,9 @@ enforces the coding style — flag style violations as well as bugs. ## PR hygiene - Subject line starts with `MDEV-NNNNN`; body wrapped at 72 cols. +- AI attribution must use the `Assisted-by: NAME:MODEL` line in the commit + comment, for example, `Assisted-by: Claude:claude-5.5-opus`. Flag if it's + `Co-Authored-By`, flag if an AI-assisted commit has no attribution. - Bug fix targets the oldest maintained branch that reproduces (≤3y since GA); new feature targets the main branch. - Bug fix commit is minimal; cleanups (unrelated and related - prerequisite diff --git a/COMMUNITY_CONTRIBUTIONS.md b/COMMUNITY_CONTRIBUTIONS.md index 39776384bef..b306b681d51 100644 --- a/COMMUNITY_CONTRIBUTIONS.md +++ b/COMMUNITY_CONTRIBUTIONS.md @@ -1,4 +1,4 @@ -# Community Contributions Process # +# Community Contributions Process MariaDB Server is an Open Source project that thrives thanks to its community. MariaDB Foundation handles all community contributions in a timely manner. @@ -25,7 +25,7 @@ But it's important to always have both prior to review. There are constant efforts (including background processes) to make sure the states of the Jira and the corresponding pull request(s) are kept in sync. -### What should go into the jira ### +### What should go into the jira The [Jira](https://jira.mariadb.org) is used to describe the design of the feature: why is it a good idea, what should work, what might not work etc. @@ -45,9 +45,9 @@ See [here](https://mariadb.org/contribute/#contribute-to-testing) > [!CAUTION] > If the jira already exists and is assigned to somebody please reach out -> to them **before** starting to working on it to avoid effort duplication. +> to them **before** starting to working on it to avoid effort duplication. -### What should go into the pull request ### +### What should go into the pull request The pull request is used to describe the implementation. E.g. how the bug is fixed. Or how the feature is implemented in detail. @@ -64,7 +64,7 @@ And that commit should have a commit message that's compliant with > If there's no Jira or no reference to it in your pull request > there might be delays in processing it -## States of a Community Contribution ## +## States of a Community Contribution ```mermaid stateDiagram-v2 @@ -87,7 +87,7 @@ stateDiagram-v2 Closed --> [*] ``` -### Draft ### +### Draft * Pull request * State: Draft @@ -114,7 +114,7 @@ the GitHub pull request viewer UI. > and "External Contribution" pull request labels and there's > been no activity for 3 months. -### Open ## +### Open * Pull request * State: Open @@ -169,7 +169,7 @@ Questions and Answers > label to pull requests in this state, if absent. > This marks the contribution entering the preliminary review queue. -### Preliminary Review ### +### Preliminary Review * Pull request * State: Open @@ -199,7 +199,7 @@ The preliminary reviewer does the following: Or that an internal developer has taken over the contribution to re-do it and push it directly. -### Final review ### +### Final review * Pull request * State: Open @@ -245,7 +245,7 @@ detailed information: > There's a requirement that certain contributions need to undergo > a separate test step. This is usually done for the new features or > for more complex and risky bug fixes. If that's the desired state, -> a test engineer will be assigned as a final reviewer. See +> a test engineer will be assigned as a final reviewer. See > https://mariadb.com/docs/server/reference/product-development/mariadb-quality-development-rules > for more details. @@ -256,7 +256,7 @@ detailed information: > in the middle of the new feature development cycle or vice versa > it might take up to a couple of months for a developer to do a review. -### Approved ### +### Approved * Pull request * State: Open @@ -280,7 +280,7 @@ The person that does the merge might need some assistance by the contributor. When the pull request is successfully merged the Jira should be moved to "Closed" state and its target version should be specified. -### Merged ### +### Merged * Pull request * State: Merged @@ -295,7 +295,7 @@ This is the "success" final state for a contribution. Ideally all contributions will end up in this state. No further actions are necessary. -### Closed ### +### Closed * Pull request * State: Closed diff --git a/client/mysql.cc b/client/mysql.cc index ed7280a48c0..42f946118e7 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4539,6 +4539,8 @@ print_tab_data(MYSQL_RES *result) } while ((cur = fetch_row(result))) { + if (interrupted_query) + break; lengths=mysql_fetch_lengths(result); field= mysql_fetch_fields(result); if (opt_binhex && is_binary_field(&field[0])) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 1c304c48b90..19549eff440 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -748,17 +748,13 @@ static bool print_partial_row_event(PRINT_EVENT_INFO *print_event_info, Log_even header info here for filtering. */ const uchar *rows_data_begin= prle->ev_buffer_base + prle->start_offset; - Log_event_type event_type= (Log_event_type)(uchar)rows_data_begin[EVENT_TYPE_OFFSET]; - uint8 const post_header_len= glob_description_event->post_header_len[event_type-1]; + uint8 const post_header_len= PARTIAL_ROWS_HEADER_LEN; const uchar *table_id_ptr= rows_data_begin + print_event_info->common_header_len + RW_MAPID_OFFSET; ulonglong table_id; - if (post_header_len == 6) - table_id= uint4korr(table_id_ptr); - else - table_id= (ulonglong) uint6korr(table_id_ptr); + table_id= (ulonglong) uint6korr(table_id_ptr); /* Cache the flags of the Rows_log_event to use it for the last @@ -1421,7 +1417,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, size_t len_to= 0; const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); - if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) + if (len_to && map->rewrite_db(db_to, len_to)) { error("Could not rewrite database name"); goto err; @@ -2514,6 +2510,53 @@ static Exit_status safe_connect() } +/** + Copied from sql-common/pack.c, since it is needed for reading Log_event + objects in sql/log_event.cc, but this function is not available in + libmariadbclient. + + The function is simple and the format of the variable length field is + fixed, so we can probably live with copying the code for now. +*/ +my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len) +{ + uchar *pos= *packet; + if (packet_len < 1) + goto err; + if (*pos < 251) + { + (*packet)++; + return (my_ulonglong) *pos; + } + if (*pos == 251) + { + (*packet)++; + return (my_ulonglong) NULL_LENGTH; + } + if (*pos == 252) + { + if (packet_len < 3) + goto err; + (*packet)+=3; + return (my_ulonglong) uint2korr(pos+1); + } + if (*pos == 253) + { + if (packet_len < 4) + goto err; + (*packet)+=4; + return (my_ulonglong) uint3korr(pos+1); + } + if (packet_len < 9 || *pos != 254) + goto err; + (*packet)+=9; + return (my_ulonglong) uint8korr(pos+1); +err: + *packet = NULL; + return 0; +} + + /** High-level function for dumping a named binlog. diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 095c9693dd6..4e0b5ed28a0 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -809,6 +809,16 @@ struct Expression_value void set_int(long long value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= false; + int_val= (unsigned long long) value; + } + + + /* Preserve the bit pattern after a defined unsigned operation. */ + void set_int_from_uint(unsigned long long value) { type= EXPR_INT; is_numeric= true; @@ -1001,6 +1011,17 @@ struct Expression_value }; +static void check_mixed_unsigned_arithmetic(const Expression_value &left, + const Expression_value &right, + const char *op) +{ + if ((left.is_unsigned || right.is_unsigned) && + ((!left.is_unsigned && left.to_int() < 0) || + (!right.is_unsigned && right.to_int() < 0))) + die("Evaluation error: Signed integer overflow in operator '%s'", op); +} + + /* Core expression parsing functions */ static void expr(Expression_value *result, const char **s); static void logical_or(Expression_value *result, const char **s); @@ -5436,7 +5457,7 @@ void do_sync_with_master(struct st_command *command) long offset= 0; char *p= command->first_argument; const char *offset_start= p; - char *start, *buff= 0; + char *start, *buff= 0, *str; start= const_cast(""); if (*offset_start) @@ -5454,15 +5475,15 @@ void do_sync_with_master(struct st_command *command) p++; while (*p && my_isspace(charset_info, *p)) p++; - start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1, - MYF(MY_WME|MY_FAE)); - get_string(&buff, &p, command); + str= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1, + MYF(MY_WME|MY_FAE)); + start= get_string(&str, &p, command); } command->last_argument= p; } do_sync_with_master2(command, offset, start); if (buff) - my_free(start); + my_free(buff); return; } @@ -5753,7 +5774,15 @@ static void unary(Expression_value *result, const char **s) unary(result, s); if (!result->is_numeric) die("Type error: unary minus requires an integer operand"); - result->set_int(-result->to_int()); + if (result->is_unsigned) + result->set_int_from_uint(0ULL - result->to_uint()); + else + { + long long value= result->to_int(); + if (value == LLONG_MIN) + die("Evaluation error: Signed integer overflow in unary '-'"); + result->set_int(-value); + } return; } if (match(s, "~")) @@ -5802,10 +5831,26 @@ static void factor(Expression_value *result, const char **s) bitwise_xor(&rhs, s); if (!result->is_numeric || !rhs.is_numeric) die("Type error: operator '*' requires integer operands"); + check_mixed_unsigned_arithmetic(*result, rhs, "*"); if (result->is_unsigned || rhs.is_unsigned) - result->set_uint(result->to_uint() * rhs.to_uint()); + { + unsigned long long left= result->to_uint(); + unsigned long long right= rhs.to_uint(); + if (right != 0 && left > ULLONG_MAX / right) + die("Evaluation error: Unsigned integer overflow in operator '*'"); + result->set_uint(left * right); + } else - result->set_int(result->to_int() * rhs.to_int()); + { + long long left= result->to_int(); + long long right= rhs.to_int(); + if ((left > 0 && right > 0 && left > LLONG_MAX / right) || + (left > 0 && right < 0 && right < LLONG_MIN / left) || + (left < 0 && right > 0 && left < LLONG_MIN / right) || + (left < 0 && right < 0 && left < LLONG_MAX / right)) + die("Evaluation error: Signed integer overflow in operator '*'"); + result->set_int(left * right); + } } else if (match(s, "/")) { @@ -5815,17 +5860,17 @@ static void factor(Expression_value *result, const char **s) die("Type error: operator '/' requires integer operands"); if (rhs.to_int() == 0) die("Evaluation error: Division by zero"); + check_mixed_unsigned_arithmetic(*result, rhs, "/"); if (result->is_unsigned || rhs.is_unsigned) result->set_uint(result->to_uint() / rhs.to_uint()); else { long long nominator= result->to_int(); long long denominator= rhs.to_int(); - // Prevent fatal integer overflow from LLONG_MIN / -1, which causes a crash + // Prevent signed overflow from LLONG_MIN / -1. if (nominator == LLONG_MIN && denominator == -1) - result->set_int(nominator); - else - result->set_int(nominator / denominator); + die("Evaluation error: Signed integer overflow in operator '/'"); + result->set_int(nominator / denominator); } } else if (match(s, "%")) @@ -5836,13 +5881,14 @@ static void factor(Expression_value *result, const char **s) die("Type error: operator '%%' requires integer operands"); if (rhs.to_int() == 0) die("Evaluation error: Modulo by zero"); + check_mixed_unsigned_arithmetic(*result, rhs, "%"); if (result->is_unsigned || rhs.is_unsigned) result->set_uint(result->to_uint() % rhs.to_uint()); else { long long nominator= result->to_int(); long long denominator= rhs.to_int(); - // Prevent fatal integer overflow from LLONG_MIN % -1, which causes a crash + // LLONG_MIN % -1 is zero, but the CPU division can still trap. if (nominator == LLONG_MIN && denominator == -1) result->set_int(0); else @@ -5868,10 +5914,24 @@ static void term(Expression_value *result, const char **s) factor(&rhs, s); if (!result->is_numeric || !rhs.is_numeric) die("Type error: operator '+' requires integer operands"); + check_mixed_unsigned_arithmetic(*result, rhs, "+"); if (result->is_unsigned || rhs.is_unsigned) - result->set_uint(result->to_uint() + rhs.to_uint()); + { + unsigned long long left= result->to_uint(); + unsigned long long right= rhs.to_uint(); + if (left > ULLONG_MAX - right) + die("Evaluation error: Unsigned integer overflow in operator '+'"); + result->set_uint(left + right); + } else - result->set_int(result->to_int() + rhs.to_int()); + { + long long left= result->to_int(); + long long right= rhs.to_int(); + if ((right > 0 && left > LLONG_MAX - right) || + (right < 0 && left < LLONG_MIN - right)) + die("Evaluation error: Signed integer overflow in operator '+'"); + result->set_int(left + right); + } } else if (match(s, "-")) { @@ -5879,10 +5939,27 @@ static void term(Expression_value *result, const char **s) factor(&rhs, s); if (!result->is_numeric || !rhs.is_numeric) die("Type error: operator '-' requires integer operands"); + check_mixed_unsigned_arithmetic(*result, rhs, "-"); if (result->is_unsigned || rhs.is_unsigned) - result->set_uint(result->to_uint() - rhs.to_uint()); + { + unsigned long long left= result->to_uint(); + unsigned long long right= rhs.to_uint(); + if (left >= right) + result->set_uint(left - right); + else if (right - left <= (unsigned long long) LLONG_MAX + 1) + result->set_int_from_uint(left - right); /* negative result */ + else + die("Evaluation error: Integer overflow in operator '-'"); + } else - result->set_int(result->to_int() - rhs.to_int()); + { + long long left= result->to_int(); + long long right= rhs.to_int(); + if ((right > 0 && left < LLONG_MIN + right) || + (right < 0 && left > LLONG_MAX + right)) + die("Evaluation error: Signed integer overflow in operator '-'"); + result->set_int(left - right); + } } else break; @@ -6348,7 +6425,19 @@ void func_abs(Expression_value args[], int count, Expression_value *result) if (!args[0].is_numeric) die("abs() requires numeric argument"); - result->set_int(llabs(args[0].to_int())); + if (args[0].is_unsigned) + { + if (args[0].to_uint() > (unsigned long long) LLONG_MAX) + die("Evaluation error: Signed integer overflow in abs()"); + result->set_int((long long) args[0].to_uint()); + } + else + { + long long value= args[0].to_int(); + if (value == LLONG_MIN) + die("Evaluation error: Signed integer overflow in abs()"); + result->set_int(value < 0 ? -value : value); + } } @@ -8506,7 +8595,7 @@ void do_get_errcodes(struct st_command *command) /* - Get a string; Return ptr to end of string + Get a string; Return ptr to start of string Strings may be surrounded by " or ' If string is a '$variable', return the value of the variable. @@ -12809,7 +12898,7 @@ void init_re(void) */ const char *ps2_re_str = "^(" - "[[:space:]]*SELECT[[:space:]])"; + "[[:space:]]*(\\([[:space:]]*)*SELECT[[:space:]])"; /* Filter for queries that can be run as views diff --git a/cmake/build_depends.cmake b/cmake/build_depends.cmake index c628585090d..e4a43d8b6d1 100644 --- a/cmake/build_depends.cmake +++ b/cmake/build_depends.cmake @@ -28,6 +28,10 @@ IF(RPM) STRING(REGEX REPLACE "^Have library " "" L ${H}) SET(V ${L}_LIBRARY) FIND_LIBRARY(${V} ${L}) + ELSEIF(H MATCHES "^Have includes? [^/]" AND ${V}) + STRING(REGEX REPLACE "^Have includes? (.*;)?" "" I ${H}) + SET(V ${I}_INCLUDE) + FIND_FILE(${V} ${I}) ENDIF() GET_PROPERTY(T CACHE ${V} PROPERTY TYPE) IF ((T STREQUAL FILEPATH OR V MATCHES "^CMAKE_COMMAND$") AND ${V} MATCHES "^/") diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index 0ba7fc7d6dd..cd209f067e0 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -59,6 +59,11 @@ MACRO(CHECK_DTRACE) SET(DTRACE_FLAGS -64 CACHE INTERNAL "DTrace architecture flags") ENDIF() ENDIF() + include(CheckIncludeFile) + CHECK_INCLUDE_FILE("sys/sdt.h" HAVE_SYS_SDT_H) + IF(NOT HAVE_SYS_SDT_H) + SET(ENABLE_DTRACE OFF CACHE BOOL "Disable dtrace") + ENDIF() ENDMACRO() CHECK_DTRACE() diff --git a/debian/mariadb-server.lintian-overrides b/debian/mariadb-server.lintian-overrides index c790a6ed22f..31363e5f414 100644 --- a/debian/mariadb-server.lintian-overrides +++ b/debian/mariadb-server.lintian-overrides @@ -1,5 +1,5 @@ # Used to check if running in Bash -bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/wsrep_notify:86] +bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/wsrep_notify:94] bash-term-in-posix-shell '[ "$url" ==' [usr/bin/mariadbd-safe:216] # In comment so false-positive bash-term-in-posix-shell 'let' [usr/bin/mariadbd-safe:41] diff --git a/debian/mariadb-test-data.lintian-overrides b/debian/mariadb-test-data.lintian-overrides index 7cc4a793038..7e653da7c71 100644 --- a/debian/mariadb-test-data.lintian-overrides +++ b/debian/mariadb-test-data.lintian-overrides @@ -5,9 +5,6 @@ incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mar incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_1/lib/DataGen_modify.pl] incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/funcs_2/lib/gen_charset_utf8.pl] incorrect-path-for-interpreter /usr/bin/env perl != /usr/bin/perl [usr/share/mariadb/mariadb-test/suite/rpl/extension/checksum.pl] -# This is used to check if we are running under Bash -bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/mariadb-test/std_data/wsrep_notify.sh:87] -bash-term-in-posix-shell '${BASH_VERSION' [usr/share/mysql/mariadb-test/std_data/wsrep_notify_ssl.sh:87] # These files are result files and they are supposed to be # National encoded (ISO/IEC 8859-1) not UTF-8 national-encoding [usr/share/mysql/mariadb-test/include/ctype_E05C.inc] diff --git a/debian/mariadb-test.install b/debian/mariadb-test.install index bc49ac7f63e..774ba9bdb9e 100644 --- a/debian/mariadb-test.install +++ b/debian/mariadb-test.install @@ -23,6 +23,8 @@ usr/lib/mysql/plugin/ha_example.so usr/lib/mysql/plugin/ha_test_sql_discovery.so usr/lib/mysql/plugin/libdaemon_example.so usr/lib/mysql/plugin/mypluglib.so +usr/lib/mysql/plugin/plugin_name_ascii.so +usr/lib/mysql/plugin/plugin_name_non_ascii.so usr/lib/mysql/plugin/qa_auth_interface.so usr/lib/mysql/plugin/qa_auth_server.so usr/lib/mysql/plugin/test_sql_service.so diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 118158ba732..8e4974801ec 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -5675,13 +5675,14 @@ static bool xtrabackup_backup_func() msg("cd to %s", mysql_real_data_home); encryption_plugin_backup_init(mysql_connection); if (innodb_log_checkpoint_now) { - msg("Initiating checkpoint"); - if (mysql_send_query(mysql_connection, - C_STRING_WITH_LEN("SET GLOBAL " - "innodb_log_checkpoint_now=ON;"))) { - msg("initiating checkpoint failed"); - return(false); - } + /* This had better finish before recv_sys.find_checkpoint() + starts executing below. The command may not be recognised + by an old server; we can ignore a failure to execute this + performance tweak. */ + xb_mysql_query( + mysql_connection, + "SET GLOBAL innodb_log_checkpoint_now=ON;", + false, false); } msg("open files limit requested %lu, set to %lu", @@ -5793,13 +5794,6 @@ fail: goto fail; } - /* try to wait for a log checkpoint, but do not fail if the - server does not support this */ - if (innodb_log_checkpoint_now != false) { - mysql_read_query_result(mysql_connection); - msg("Finished waiting for checkpoint"); - } - if (!select_history()) { goto fail; } diff --git a/include/m_ctype.h b/include/m_ctype.h index 226d9417588..237a60def4e 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -99,6 +99,12 @@ struct casefold_info_st my_wc_t maxchar; const MY_CASEFOLD_CHARACTER * const *page; const uint16 * const *simple_weight; /* For general_ci-alike collations */ + /* + TRUE if an ASCII character can be converted to a non-ASCII character + by LOWER() or UPPER(), e.g. in Turkish: LOWER('I') -> U+0131, + UPPER('i') -> U+0130. + */ + my_bool can_convert_to_non_ascii_on_casefolding; }; @@ -299,18 +305,116 @@ extern MY_UNI_CTYPE my_uni_ctype[256]; to weights, e.g. contractions, expansions, ignorable characters */ #define MY_CS_UPPER_EQUAL_AS_EQUAL 0x80000 /* (UPPER(x)=UPPER(y)) <=> (x=y)*/ +/* + MY_CS_ASCII_CASEUP_CI means that the collation maps lower case ASCII + letters a-z to their upper case counter parts A-Z, and sorts the ASCII + range according to the code point otherwise. Therefore the underscore + (0x5F) sorts after the letters. A collation which converts upper case + letters to lower case would sort the underscore before the letters. + Sorting on the non-ASCII range can be any, not necessarily + according to the code point. +*/ +#define MY_CS_ASCII_CASEUP_CI 0x100000 /* ASCII CASEUP CI sorting */ +/* + MY_CS_IDENT_CASEUP_CI means that the collation maps lower case ASCII + letters a-z to their upper case counter parts A-Z, and sorts "identifier" + ranges (0-9,A-Z,_) according to the code point. As a-z are folded + to A-Z, the order is: digits < letters (case insensitive) < underscore, + i.e. the underscore (0x5F) sorts after all letters. + Sorting on the other ASCII characters is not important, sorting on + non-ASCII characters is not important. +*/ +#define MY_CS_IDENT_CASEUP_CI 0x200000 /* CASEUP CI sorting, IDENT range */ +/* + MY_CS_ASCII_STD_UCA means that the collation sorts all characters in the + range U+0000..U+007F like the default (not-tailored) UCA collations do: + utf8mb3_unicode_ci, utf8mb3_uca1400_ai_ci. +*/ +#define MY_CS_ASCII_STD_UCA 0x400000 /* Standard UCA sorting on ASCII */ +/* + MY_CS_DIGITS_STD means that the collation sorts the ASCII digits 0..9 + in the code point order, and does not tailor them (no contractions, + expansions or ignorable digits). For a PAD collation it also means that + the space sorts before the digits, as a shorter string is padded with + spaces for comparison. Therefore strings consisting of ASCII digits + are compared in the same way in all collations having this flag + (with the same MY_CS_NOPAD), regardless of case sensitivity + and the order of letters. +*/ +#define MY_CS_DIGITS_STD 0x800000 /* Standard sorting of 0..9 */ +/* + MY_CS_ASCII_MINUS_DOT_DIGITS means MY_CS_DIGITS_STD, and additionally, + the ASCII minus (-) sorts before the ASCII dot (.), which sorts before + the digits, and, for PAD collations, the space sorts before the minus. + Therefore strings consisting of minuses, dots and digits + (e.g. decimal numbers like '-10.5') are compared in the same way + in all collations having this flag (with the same MY_CS_NOPAD). +*/ +#define MY_CS_ASCII_MINUS_DOT_DIGITS 0x1000000 /* Standard order of -.0..9 */ #define MY_CHARSET_UNDEFINED 0 /* Character repertoire flags */ typedef enum enum_repertoire_t { - MY_REPERTOIRE_NONE= 0, - MY_REPERTOIRE_ASCII= 1, /* Pure ASCII U+0000..U+007F */ - MY_REPERTOIRE_EXTENDED= 2, /* Extended characters: U+0080..U+FFFF */ - MY_REPERTOIRE_UNICODE30= 3 /* ASCII | EXTENDED: U+0000..U+FFFF */ + MY_REPERTOIRE_NONE= 0, + /* ASCII digits 0..9 */ + MY_REPERTOIRE_ASCII_DIGITS= 1, + /* ASCII letters A..Z */ + MY_REPERTOIRE_ASCII_LETTERS_UPPER= 2, + /* ASCII letters a..z */ + MY_REPERTOIRE_ASCII_LETTERS_LOWER= 4, + /* ASCII letters A..Z, a..z */ + MY_REPERTOIRE_ASCII_LETTERS= MY_REPERTOIRE_ASCII_LETTERS_UPPER | + MY_REPERTOIRE_ASCII_LETTERS_LOWER, + /* ASCII letters and digits */ + MY_REPERTOIRE_ASCII_ALNUM= MY_REPERTOIRE_ASCII_DIGITS | + MY_REPERTOIRE_ASCII_LETTERS, + /* ASCII underscore character */ + MY_REPERTOIRE_ASCII_UNDERSCORE= 8, + /* A combination of alnum and underscore */ + MY_REPERTOIRE_ASCII_IDENT= MY_REPERTOIRE_ASCII_ALNUM | + MY_REPERTOIRE_ASCII_UNDERSCORE, + /* + Other ASCII characters, not covered by MY_REPERTOIRE_ASCII_IDENT, + MY_REPERTOIRE_ASCII_DOT and MY_REPERTOIRE_ASCII_MINUS: + */ + MY_REPERTOIRE_ASCII_NOT_IDENT= 16, + /* Extended characters: U+0080..U+10FFFF */ + MY_REPERTOIRE_EXTENDED= 32, + /* ASCII dot (full stop) character: . */ + MY_REPERTOIRE_ASCII_DOT= 64, + /* ASCII minus (hyphen-minus) character: - */ + MY_REPERTOIRE_ASCII_MINUS= 128, + /* Decimal numbers, e.g. '-10.5': digits, dot and minus */ + MY_REPERTOIRE_ASCII_MINUS_DOT_DIGITS= MY_REPERTOIRE_ASCII_DIGITS | + MY_REPERTOIRE_ASCII_DOT | + MY_REPERTOIRE_ASCII_MINUS, + /* Entire pure ASCII: U+0000..U+007F */ + MY_REPERTOIRE_ASCII= MY_REPERTOIRE_ASCII_IDENT | + MY_REPERTOIRE_ASCII_NOT_IDENT | + MY_REPERTOIRE_ASCII_DOT | + MY_REPERTOIRE_ASCII_MINUS, + /* All characters: U+0000..U+10FFFF */ + MY_REPERTOIRE_UNICODE30= MY_REPERTOIRE_ASCII | + MY_REPERTOIRE_EXTENDED } my_repertoire_t; +/* + Check if all characters of "repertoire" belong to "of", + e.g. my_repertoire_is_subset_of(rep, MY_REPERTOIRE_ASCII) means + "rep contains only ASCII". + Note, do not use "repertoire == MY_REPERTOIRE_ASCII" for this purpose, + as repertoire values are sets of bits. +*/ +static inline +my_bool my_repertoire_is_subset_of(my_repertoire_t repertoire, + my_repertoire_t of) +{ + return (repertoire & ~of) == 0; +} + + /* ID compatibility */ typedef enum enum_collation_id_type { @@ -665,6 +769,54 @@ struct my_collation_handler_st @return 1 Identical */ my_bool (*eq_collation)(CHARSET_INFO *self, CHARSET_INFO *other); + + /* + Get collation rules on the given repertoire. + This virtual function is used for tailoring-based optimization. + If two different collations have equal rules (tailoring) on the + given repertoire, then they can be mutually substituted in a comparison + operator instead of raising an "Illegal mix of collations" error, + if the additional conditions listed below are met. + For example: + SET NAMES latin1 COLLATE latin1_swedish_ci; + CREATE VIEW v1 AS SELECT IF(cond,'Y','N') AS c1 FROM t1; + SET NAMES big5 COLLATE big5_chinese_ci; + SELECT * FROM v1 WHERE c1='Y'; + Although latin1_swedish_ci and big5_chinese_ci are different collations, + their rules on the given range (i.e. MY_REPERTOIRE_ASCII_ALNUM) are + exactly the same, so it does not matter which collation to use for + comparison purposes - the result will be the same. There is no need + to raise the "Illegal mix of collations". + If "tailoring()" returns a null LEX_CSTRING {0,0}, it means this + collation can not use tailoring-based optimization in the passed + repertoire. + + The tailoring() results must not be compared directly by the callers. + Use my_collations_equal_on_repertoire(), which knows how tailorings + are compared and which additional properties of the collations + (PAD/NOPAD, UCA version) must be checked. + + Currently two tailorings are considered equal when the str pointers + of the returned LEX_CSTRING values are equal (not when their texts + are equal). So an implementation must return shared constant strings, + and never its own literals, even if the text of such a literal is the + same. The shared constants (my_tailoring_str_*) are defined in + strings/ctype.c and declared in strings/strings_def.h, which is not + a public header. So only the implementations inside strings/ can + return them. An implementation defined elsewhere should return {0,0} + on all repertoires, which disables the optimization for its collations. + + Equal tailorings are necessary, but not sufficient for the collations + to be interchangeable. The returned string does not describe the PAD/ + NOPAD attribute and the UCA version of the collation, which are + additionally checked by my_collations_equal_on_repertoire(). + + For MY_REPERTOIRE_NONE (the empty repertoire) the implementations + inside strings/ return the shared constant my_tailoring_str_empty: + any two collations are trivially compatible on the empty repertoire + (the additional checks above still apply). + */ + LEX_CSTRING (*tailoring)(CHARSET_INFO *self, my_repertoire_t repertoire); }; @@ -1282,6 +1434,21 @@ struct charset_info_st return this == rhs || (coll->eq_collation)(this, rhs); } + /* + Check if the character set can store all ASCII characters + U+0000..U+007F. An expression with the ASCII repertoire can be safely + converted to such a character set. + - All supported multibyte character sets can store U+0000..U+007F + - All supported 7bit character sets can store U+0000..U+007F + except those marked with MY_CS_NONASCII (e.g. swe7). + Note, this is not the same as the byte level ASCII compatibility, + see my_charset_is_ascii_based(). + */ + bool is_ascii_superset() const + { + return mbmaxlen > 1 || !(state & MY_CS_NONASCII); + } + #endif /* __cplusplus */ }; @@ -1854,6 +2021,8 @@ void my_string_metadata_get(MY_STRING_METADATA *metadata, my_repertoire_t my_string_repertoire(CHARSET_INFO *cs, const char *str, size_t len); my_bool my_charset_is_ascii_based(CHARSET_INFO *cs); +my_bool my_collations_equal_on_repertoire(CHARSET_INFO *cs1, CHARSET_INFO *cs2, + my_repertoire_t repertoire); my_repertoire_t my_charset_repertoire(CHARSET_INFO *cs); uint my_strxfrm_flag_normalize(CHARSET_INFO *cs, uint flags); diff --git a/include/my_base.h b/include/my_base.h index 1768be00940..e2272664f9a 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -573,7 +573,8 @@ enum ha_base_keytype { #define HA_NAMELEN 64 /* Max length of saved filename */ #define NO_SUCH_KEY (~(uint)0) /* used as a key no. */ -typedef ulong key_part_map; +typedef uint32 key_part_map; +#define MAX_REF_PARTS sizeof(key_part_map)*8 /* Max parts used as ref */ #define HA_WHOLE_KEY (~(key_part_map)0) /* Intern constants in databases */ diff --git a/include/my_sys.h b/include/my_sys.h index a8c6546a77f..35314539e12 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -96,8 +96,9 @@ C_MODE_START #define MY_ROOT_USE_VMEM 0x20000U /* init_alloc_root: use my_virtual_mem_commit */ /* Tree that should delete things automatically */ #define MY_TREE_WITH_DELETE 0x40000U -#define MY_TRACK 0x80000U /* Track tmp usage */ -#define MY_TRACK_WITH_LIMIT 0x100000U /* Give error if over tmp_file_usage */ +#define MY_TRY_LARGE_PAGES 0x80000U /* try to allocate large pages */ +#define MY_TRACK 0x100000U /* Track tmp usage */ +#define MY_TRACK_WITH_LIMIT 0x200000U /* Give error if over tmp_file_usage */ #define MY_CHECK_ERROR 1U /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2U /* Give time info about process*/ @@ -180,14 +181,19 @@ extern void my_free(void *ptr); extern void *my_memdup(PSI_memory_key key, const void *from,size_t length,myf MyFlags); extern char *my_strdup(PSI_memory_key key, const char *from,myf MyFlags); extern char *my_strndup(PSI_memory_key key, const char *from, size_t length, myf MyFlags); -extern my_bool my_use_large_pages; +/** + 0, or MY_TRY_LARGE_PAGES to request large pages from my_large_malloc(), + my_large_virtual_alloc(), or the my_virtual_mem_*() functions. Set once + by my_init_large_pages(), does not change thereafter. +*/ +extern myf my_large_pages_flag; int my_init_large_pages(void); uchar *my_large_malloc(size_t *size, myf my_flags); #ifdef _WIN32 /* On Windows, use my_virtual_mem_reserve() and my_virtual_mem_commit(). */ #else -char *my_large_virtual_alloc(size_t *size); +char *my_large_virtual_alloc(size_t *size, myf my_flags); #endif void my_large_free(void *ptr, size_t size); void my_large_page_truncate(size_t *size); @@ -945,6 +951,7 @@ extern void init_alloc_root(PSI_memory_key key, MEM_ROOT *mem_root, extern void *alloc_root(MEM_ROOT *mem_root, size_t Size); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void free_root(MEM_ROOT *root, myf MyFLAGS); +/* There is also dbug_get_mem_root_alloc_size() in sql/sql_test.cc */ extern void move_root(MEM_ROOT *to, MEM_ROOT *from); extern void set_prealloc_root(MEM_ROOT *root, char *ptr); extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, diff --git a/include/my_virtual_mem.h b/include/my_virtual_mem.h index 689c75d5258..2700cf8012c 100644 --- a/include/my_virtual_mem.h +++ b/include/my_virtual_mem.h @@ -19,6 +19,7 @@ (reserve, commit, decommit, release) */ #include /*size_t*/ +#include /*myf*/ #ifdef __cplusplus extern "C" { @@ -26,9 +27,9 @@ extern "C" { enum my_vmem_prot { MY_VMEM_READONLY= 0, MY_VMEM_READWRITE }; -char *my_virtual_mem_reserve(size_t *size); -char *my_virtual_mem_commit(char *ptr, size_t size); -void my_virtual_mem_decommit(char *ptr, size_t size); +char *my_virtual_mem_reserve(size_t *size, myf my_flags); +char *my_virtual_mem_commit(char *ptr, size_t size, myf my_flags); +void my_virtual_mem_decommit(char *ptr, size_t size, myf my_flags); void my_virtual_mem_release(char *ptr, size_t size); void my_virtual_mem_protect(void *ptr, size_t size, enum my_vmem_prot prot); diff --git a/include/mysql_com.h b/include/mysql_com.h index 8793a919efd..89a6931cf78 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -471,10 +471,19 @@ typedef struct st_net { my_bool thread_specific_malloc; unsigned char compress; my_bool pkt_nr_can_be_reset; - /* Bits: NET_PROXY_PROTOCOL, NET_PROXY_PROTOCOL_CONNECT_ERRORS */ - my_bool using_proxy_protocol; + /* Bits: NET_PROXY_PROTOCOL, NET_PROXY_PROTOCOL_CONNECT_ERRORS, + NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED, NET_PROXY_PROTOCOL_HOST_BLOCKED */ + unsigned char using_proxy_protocol; #define NET_PROXY_PROTOCOL 1 #define NET_PROXY_PROTOCOL_CONNECT_ERRORS 2 +/* + A PROXY-header-derived peer address failed the "host privileged"/"host + blocked" check; rejection is deferred until the client's handshake + response is parsed, after SSL if requested, instead of being sent in + clear text right away. +*/ +#define NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED 4 +#define NET_PROXY_PROTOCOL_HOST_BLOCKED 8 /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet diff --git a/mysql-test/include/ctype_tailoring_00.inc b/mysql-test/include/ctype_tailoring_00.inc new file mode 100644 index 00000000000..93804b9c413 --- /dev/null +++ b/mysql-test/include/ctype_tailoring_00.inc @@ -0,0 +1,341 @@ +CREATE TABLE cmp_result ( + cl1 VARCHAR(64), cl2 VARCHAR(64), is_error INT, is_error_expected INT, expected_reason TEXT +) ENGINE=MyISAM; + +CREATE TABLE cmp_result_all AS SELECT *, SPACE(32) AS repertoire FROM cmp_result LIMIT 0; + + +# Unicode collations that reorder ASCII letters +DELIMITER $$; +CREATE FUNCTION unicode_reorders_ascii_letters(cl VARCHAR(64)) RETURNS BOOL +BEGIN + + /* Old collations */ + CASE + WHEN cl RLIKE '^(utf8mb3|ucs2|utf8mb4|utf16|utf32)' + '_(czech|croatian|croatian_mysql561|danish|estonian|latvian|lithuanian|roman|slovak|spanish2|turkish)' + '_ci$' + THEN RETURN 1; + + /* MySQL 0900 compatibility collations */ + WHEN cl RLIKE '^utf8mb4' + '_(es_trad|cs|et|la|lt|lv|sk|tr)' + '_0900_ai_(ci|cs)$' + THEN RETURN 1; + + /* uca1400 collations*/ + WHEN cl RLIKE '^(utf8mb3|ucs2|utf8mb4|utf16|utf32)' + '_uca1400' + '_(czech|croatian|danish|estonian|latvian|lithuanian|roman|slovak|spanish2|turkish)' + '_(|nopad_)' + '(ai_cs|ai_ci|as_cs|as_ci)$' + THEN RETURN 1; + ELSE + RETURN 0; + END CASE; + + RETURN 0; +END; +$$ +DELIMITER ;$$ + + +DELIMITER $$; +CREATE PROCEDURE update_expected_reasons(repertoire VARCHAR(32)) +BEGIN + UPDATE cmp_result SET is_error_expected=0, expected_reason='000 cl1 = cl2' WHERE is_error_expected IS NULL AND cl1=cl2; + + UPDATE cmp_result SET is_error_expected=0, expected_reason='001 LEFT binary' WHERE is_error_expected IS NULL AND cl1='binary' AND cl2<>'binary'; + UPDATE cmp_result SET is_error_expected=0, expected_reason='001 RIGHT binary' WHERE is_error_expected IS NULL AND cl1<>'binary' AND cl2='binary'; + + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 RIGHT sameCS_bin' WHERE is_error_expected IS NULL AND cl1 NOT LIKE '%_bin' AND concat(substring_index(cl1,'_',1),'_bin')=cl2; + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 RIGHT sameCS_bin' WHERE is_error_expected IS NULL AND cl1 NOT LIKE '%_bin' AND concat(substring_index(cl1,'_',1),'_nopad_bin')=cl2; + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 RIGHT sameCS_bin' WHERE is_error_expected IS NULL AND cl1 NOT LIKE '%_bin' AND concat(substring_index(cl1,'_',1),'_0900_bin')=cl2; + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 LEFT sameCS_bin' WHERE is_error_expected IS NULL AND cl2 NOT LIKE '%_bin' AND cl1=concat(substring_index(cl2,'_',1),'_bin'); + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 LEFT sameCS_bin' WHERE is_error_expected IS NULL AND cl2 NOT LIKE '%_bin' AND cl1=concat(substring_index(cl2,'_',1),'_nopad_bin'); + UPDATE cmp_result SET is_error_expected=0, expected_reason='002 LEFT sameCS_bin' WHERE is_error_expected IS NULL AND cl2 NOT LIKE '%_bin' AND cl1=concat(substring_index(cl2,'_',1),'_0900_bin'); + + UPDATE cmp_result SET is_error_expected=0, expected_reason='003 LEFT superset' WHERE is_error_expected IS NULL AND cl1 RLIKE '^(utf8mb4).*' AND cl2 NOT RLIKE '^(ucs2|utf8mb4|utf32|utf16).*'; + UPDATE cmp_result SET is_error_expected=0, expected_reason='003 RIGHT superset' WHERE is_error_expected IS NULL AND cl1 NOT RLIKE '^(ucs2|utf8mb4|utf32|utf16).*' AND cl2 RLIKE '^(utf8mb4).*'; + UPDATE cmp_result SET is_error_expected=0, expected_reason='003 LEFT superset' WHERE is_error_expected IS NULL AND cl1 RLIKE '^(utf16|utf32).*' AND cl2 NOT RLIKE '^(ucs2|utf8mb3|utf8mb4|utf32|utf16).*'; + UPDATE cmp_result SET is_error_expected=0, expected_reason='003 RIGHT superset' WHERE is_error_expected IS NULL AND cl1 NOT RLIKE '^(ucs2|utf8mb3|utf8mb4|utf32|utf16).*' AND cl2 RLIKE '^(utf16|utf32).*'; + + UPDATE cmp_result SET is_error_expected=0, expected_reason='004 LEFT superset' WHERE is_error_expected IS NULL AND cl1 RLIKE '^(ucs2|utf8mb3).*' AND cl2 NOT RLIKE '^(utf8mb4|utf32|utf16|ucs2|utf8mb3).*'; + UPDATE cmp_result SET is_error_expected=0, expected_reason='004 RIGHT superset' WHERE is_error_expected IS NULL AND cl1 NOT RLIKE '^(utf8mb4|utf32|utf16|utf8mb3|ucs2).*' AND cl2 RLIKE '^(ucs2|utf8mb3).*'; + + + IF repertoire ='ascii' THEN + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 sjis_bin reorders ASCII punctuation' WHERE is_error_expected IS NULL AND (cl1='sjis_bin' OR cl2='sjis_bin'); + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 sjis_nopad_bin reorders ASCII punctuation' WHERE is_error_expected IS NULL AND (cl1='sjis_nopad_bin' OR cl2='sjis_nopad_bin'); + END IF; + + IF repertoire ='ascii' THEN + /* These collations have no tailoring on the entire ASCII repertoire */ + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 no tailoring on the entire ASCII repertoire' + WHERE is_error_expected IS NULL + AND (cl1 RLIKE '^(big5_chinese|gb2312_chinese|gbk_chinese|sjis_japanese)' OR + cl2 RLIKE '^(big5_chinese|gb2312_chinese|gbk_chinese|sjis_japanese)'); + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 hp8_english_ci has anomalies on ASCII punctuation' + WHERE is_error_expected IS NULL AND (cl1='hp8_english_ci' OR cl2='hp8_english_ci'); + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 swe7_swedish_nopad_ci reorders ASCII punctuation' + WHERE is_error_expected IS NULL AND (cl1='swe7_swedish_nopad_ci' OR cl2='swe7_swedish_nopad_ci'); + END IF; + + /* + The ASCII digits are sorted in the code point order in all collations, + regardless of the order of the letters and the case sensitivity. + So on the digits repertoire only PAD vs NOPAD collations are incompatible. + */ + IF repertoire NOT IN ('digits', 'minus_dot_digits') THEN + UPDATE cmp_result SET is_error_expected=1, expected_reason='010 cp1257_lithuanian_ci reorders ASCII letters: Iis_error_expected" would skip them. + */ + UPDATE cmp_result SET is_error_expected=0, expected_reason='100 equal tailoring' WHERE is_error_expected IS NULL; + +END; +$$ +DELIMITER ;$$ + + + +DELIMITER $$; +CREATE PROCEDURE check_compatibility(repertoire VARCHAR(32), param VARCHAR(32)) +BEGIN + DECLARE mask VARCHAR(32) DEFAULT COALESCE(@mask,''); + DECLARE errmsg TEXT; + DECLARE c1 CURSOR FOR SELECT full_collation_name + FROM collations + ORDER BY full_collation_name; + DECLARE c2 CURSOR FOR SELECT full_collation_name + FROM collations + ORDER BY full_collation_name; + + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + BEGIN + GET DIAGNOSTICS CONDITION 1 errmsg = MESSAGE_TEXT; + END; + + TRUNCATE TABLE cmp_result; + FOR rec1 IN c1 DO + SET @@collation_connection=rec1.full_collation_name; + EXECUTE IMMEDIATE REPLACE('CREATE VIEW v1 AS ' + 'SELECT ''PARAM'' AS alnum', 'PARAM', param); + SET NAMES DEFAULT; + FOR rec2 IN c2 DO + SET errmsg= NULL; + SET @@collation_connection=rec2.full_collation_name; + /* This query raises an error on incompatible collations */ + IF (rec1.full_collation_name RLIKE mask OR + rec2.full_collation_name RLIKE mask) + THEN + SET @a= NULL; + EXECUTE IMMEDIATE + REPLACE('SET @a=(SELECT COUNT(*) FROM v1 WHERE v1.alnum=''PARAM'')', + 'PARAM', param); + /* + is_error is set to 1 if the query raised an error, and to 2 if it + did not raise an error but did not return the expected single row. + So a wrong result is reported by "is_error<>is_error_expected", + as is_error_expected can be only 0 or 1. + */ + INSERT INTO cmp_result (cl1, cl2, is_error) + VALUES (rec1.full_collation_name, + rec2.full_collation_name, + IF(errmsg IS NOT NULL, 1, IF(@a=1, 0, 2))); + END IF; + END FOR; + DROP VIEW v1; + END FOR; + SET NAMES DEFAULT; + CALL update_expected_reasons(repertoire); +END; +$$ +DELIMITER ;$$ + + +CREATE TABLE collations (full_collation_name VARCHAR(64) NOT NULL PRIMARY KEY); +INSERT INTO collations VALUES +('latin1_general_cs'), ('latin5_turkish_ci'), +('latin1_swedish_nopad_ci'), ('swe7_swedish_nopad_ci'), +('utf8mb3_uca1400_nopad_ai_cs'),('utf8mb4_0900_as_cs'), +('latin1_nopad_bin'), ('swe7_nopad_bin'), +('latin1_german1_ci'),('latin1_swedish_ci'), +('utf8mb3_uca1400_ai_cs'),('utf32_uca1400_as_cs'), +('latin1_bin'),('latin5_bin'), +('hp8_english_ci'); + +INSERT INTO collations VALUES +('utf8mb3_general_ci'),('utf8mb3_general_nopad_ci'), +('utf8mb3_unicode_ci'),('utf8mb3_unicode_nopad_ci'), +('utf8mb3_bin'),('utf8mb3_nopad_bin'), +('utf8mb4_general_ci'),('utf8mb4_general_nopad_ci'), +('utf8mb4_uca1400_ai_ci'),('utf8mb4_uca1400_nopad_ai_ci'), +('utf8mb4_unicode_ci'),('utf8mb4_unicode_nopad_ci'), +('utf8mb4_bin'),('utf8mb4_nopad_bin'); + + +DELIMITER $$; +BEGIN NOT ATOMIC + IF @extra_collations_query IS NOT NULL + THEN + EXECUTE IMMEDIATE @extra_collations_query; + END IF; +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # ASCII digits repertoire +--echo # + +CALL check_compatibility('digits', '12'); +SELECT * FROM cmp_result WHERE is_error<>is_error_expected; +SELECT + RPAD(cl1, 32) AS cl1, RPAD(cl2, 32) AS cl2, + is_error, is_error_expected, expected_reason +FROM cmp_result ORDER BY expected_reason,cl1, cl2; +INSERT INTO cmp_result_all SELECT *, '0_digits' FROM cmp_result; + + +--echo # +--echo # ASCII minus, dot and digits repertoire +--echo # + +CALL check_compatibility('minus_dot_digits', '-1.5'); +SELECT * FROM cmp_result WHERE is_error<>is_error_expected; +SELECT + RPAD(cl1, 32) AS cl1, RPAD(cl2, 32) AS cl2, + is_error, is_error_expected, expected_reason +FROM cmp_result ORDER BY expected_reason,cl1, cl2; +INSERT INTO cmp_result_all SELECT *, '1_minus_dot_digits' FROM cmp_result; + + +--echo # +--echo # ALNUM repertoire +--echo # + +CALL check_compatibility('alnum', 'a1'); +SELECT * FROM cmp_result WHERE is_error<>is_error_expected; +SELECT + RPAD(cl1, 32) AS cl1, RPAD(cl2, 32) AS cl2, + is_error, is_error_expected, expected_reason +FROM cmp_result ORDER BY expected_reason,cl1, cl2; +INSERT INTO cmp_result_all SELECT *, 'A_alnum' FROM cmp_result; + + +--echo # +--echo # IDENT repertoire +--echo # + +CALL check_compatibility('ident', 'a_'); +SELECT * FROM cmp_result WHERE is_error<>is_error_expected; +SELECT + RPAD(cl1, 32) AS cl1, RPAD(cl2, 32) AS cl2, + is_error, is_error_expected, expected_reason +FROM cmp_result ORDER BY expected_reason,cl1, cl2; +INSERT INTO cmp_result_all SELECT *, 'B_ident' FROM cmp_result; + + +--echo # +--echo # Entire ASCII-7 repertoire +--echo # + +CALL check_compatibility('ascii', 'a#'); +SELECT * FROM cmp_result WHERE is_error<>is_error_expected; +SELECT + RPAD(cl1, 32) AS cl1, RPAD(cl2, 32) AS cl2, + is_error, is_error_expected, expected_reason +FROM cmp_result ORDER BY expected_reason,cl1, cl2; +INSERT INTO cmp_result_all SELECT *, 'C_ascii' FROM cmp_result; + + +--echo # +--echo # Collation pairs having different results on different repertoires +--echo # + +SELECT + RPAD(cl1,32) AS cl1, RPAD(cl2,32) AS cl2, + GROUP_CONCAT(repertoire, is_error ORDER BY repertoire) AS is_error_all +FROM cmp_result_all +GROUP BY cmp_result_all.cl1, cmp_result_all.cl2 +HAVING is_error_all NOT IN + ('0_digits0,1_minus_dot_digits0,A_alnum0,B_ident0,C_ascii0', + '0_digits1,1_minus_dot_digits1,A_alnum1,B_ident1,C_ascii1') +ORDER BY is_error_all; + + +DROP TABLE cmp_result_all; +DROP TABLE cmp_result; +DROP TABLE collations; +DROP PROCEDURE check_compatibility; +DROP PROCEDURE update_expected_reasons; +DROP FUNCTION unicode_reorders_ascii_letters; +SET @extra_collations_query=NULL; +SET @mask=NULL; diff --git a/mysql-test/include/ctype_tailoring_01_probe.inc b/mysql-test/include/ctype_tailoring_01_probe.inc new file mode 100644 index 00000000000..569d6a66db3 --- /dev/null +++ b/mysql-test/include/ctype_tailoring_01_probe.inc @@ -0,0 +1,28 @@ +# The ASCII digits repertoire. It is compatible even with collations having +# anomalies on letters, but not with a collation with a different PAD/NOPAD. +# The result is printed instead of raising the error, to show both outcomes. +--echo # ASCII digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS d; + SELECT d FROM v_tailoring WHERE d='1'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +--echo # ASCII minus, dot and digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS e; + SELECT e FROM v_tailoring WHERE e='-1.5'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +SELECT c FROM v_tailoring WHERE c='Y'; +SELECT c FROM v_tailoring WHERE c<>'Y_'; +SELECT c FROM v_tailoring WHERE c<>'Y+'; diff --git a/mysql-test/include/ctype_tailoring_02_probe_error.inc b/mysql-test/include/ctype_tailoring_02_probe_error.inc new file mode 100644 index 00000000000..38c5fb1f608 --- /dev/null +++ b/mysql-test/include/ctype_tailoring_02_probe_error.inc @@ -0,0 +1,31 @@ +# The ASCII digits repertoire. It is compatible even with collations having +# anomalies on letters, but not with a collation with a different PAD/NOPAD. +# The result is printed instead of raising the error, to show both outcomes. +--echo # ASCII digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS d; + SELECT d FROM v_tailoring WHERE d='1'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +--echo # ASCII minus, dot and digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS e; + SELECT e FROM v_tailoring WHERE e='-1.5'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c<>'Y_'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c<>'Y+'; diff --git a/mysql-test/include/ctype_tailoring_03_mysql_user_Insert_priv_last_error.inc b/mysql-test/include/ctype_tailoring_03_mysql_user_Insert_priv_last_error.inc new file mode 100644 index 00000000000..4eab7de0dfa --- /dev/null +++ b/mysql-test/include/ctype_tailoring_03_mysql_user_Insert_priv_last_error.inc @@ -0,0 +1,4 @@ +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y' LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y_' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y+' LIMIT 0; diff --git a/mysql-test/include/ctype_tailoring_03_probe_last_error.inc b/mysql-test/include/ctype_tailoring_03_probe_last_error.inc new file mode 100644 index 00000000000..6963166abfe --- /dev/null +++ b/mysql-test/include/ctype_tailoring_03_probe_last_error.inc @@ -0,0 +1,29 @@ +# The ASCII digits repertoire. It is compatible even with collations having +# anomalies on letters, but not with a collation with a different PAD/NOPAD. +# The result is printed instead of raising the error, to show both outcomes. +--echo # ASCII digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS d; + SELECT d FROM v_tailoring WHERE d='1'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +--echo # ASCII minus, dot and digits +--disable_query_log +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE CONTINUE HANDLER FOR 1267 /*Illegal mix of collations*/ + SELECT 'ER_CANT_AGGREGATE_2COLLATIONS' AS e; + SELECT e FROM v_tailoring WHERE e='-1.5'; +END; +$$ +DELIMITER ;$$ +--enable_query_log +SELECT c FROM v_tailoring WHERE c='Y'; +SELECT c FROM v_tailoring WHERE c<>'Y_'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c<>'Y+'; diff --git a/mysql-test/include/ctype_tailoring_view_create.inc b/mysql-test/include/ctype_tailoring_view_create.inc new file mode 100644 index 00000000000..00a5cc8925d --- /dev/null +++ b/mysql-test/include/ctype_tailoring_view_create.inc @@ -0,0 +1,24 @@ +# Create a test view similar to mysql.user, which caused MDEV-41246: +# a latin1_swedish_ci column with the narrow repertoire ASCII_ALNUM, +# calculated by IF() from two literals. It always has exactly one row. +# The column c has the value 'Y', the column d (ASCII digits repertoire) +# has the value '1', and the column e (ASCII minus, dot and digits repertoire) +# has the value '-1.5'. +# The current client/connection character sets are preserved. +# The view is dropped by ctype_tailoring_view_drop.inc. + +--disable_query_log +SET @ctype_tailoring_save_client= @@character_set_client; +SET @ctype_tailoring_save_results= @@character_set_results; +SET @ctype_tailoring_save_collation= @@collation_connection; +SET NAMES latin1 COLLATE latin1_swedish_ci; +CREATE TABLE t_tailoring (a INT); +INSERT INTO t_tailoring VALUES (1); +CREATE VIEW v_tailoring AS + SELECT IF(a=1,'Y','N') AS c, IF(a=1,'1','2') AS d, + IF(a=1,'-1.5','2.5') AS e + FROM t_tailoring; +SET @@character_set_client= @ctype_tailoring_save_client; +SET @@character_set_results= @ctype_tailoring_save_results; +SET @@collation_connection= @ctype_tailoring_save_collation; +--enable_query_log diff --git a/mysql-test/include/ctype_tailoring_view_drop.inc b/mysql-test/include/ctype_tailoring_view_drop.inc new file mode 100644 index 00000000000..76360ce5bf1 --- /dev/null +++ b/mysql-test/include/ctype_tailoring_view_drop.inc @@ -0,0 +1,7 @@ +--disable_query_log +DROP VIEW v_tailoring; +DROP TABLE t_tailoring; +SET @ctype_tailoring_save_client= NULL; +SET @ctype_tailoring_save_results= NULL; +SET @ctype_tailoring_save_collation= NULL; +--enable_query_log diff --git a/mysql-test/include/galera_wait_ready.inc b/mysql-test/include/galera_wait_ready.inc index a726116f000..83e8717bb11 100644 --- a/mysql-test/include/galera_wait_ready.inc +++ b/mysql-test/include/galera_wait_ready.inc @@ -2,11 +2,26 @@ # # Waits for galera node to transition to READY state. # +# Parameters +# ---------- +# $galera_wait_ready_timeout (optional) +# Seconds to wait before giving up, 60 by default. Raise it around a +# restart which has to wait for a full SST, as that takes considerably +# longer than a plain restart and on a loaded machine can exceed the +# default. The value is reset here, so it only applies to the next +# sourcing of this file. +# --enable_reconnect --disable_query_log --disable_result_log + let $wait_counter = 600; +if ($galera_wait_ready_timeout) +{ + let $wait_counter = $($galera_wait_ready_timeout * 10); +} + while ($wait_counter) { --disable_abort_on_error @@ -25,7 +40,7 @@ while ($wait_counter) if (!$success) { - die "Server did not transition to READY state"; + die "Server did not transition to READY state in $_galera_wait_ready_timeout seconds"; } --disable_reconnect --enable_query_log diff --git a/mysql-test/include/kill_galera.inc b/mysql-test/include/kill_galera.inc index 887e21f5f79..47381d1dce4 100644 --- a/mysql-test/include/kill_galera.inc +++ b/mysql-test/include/kill_galera.inc @@ -1,5 +1,34 @@ +# Kill the server the current connection is on, and wait until its process +# is really gone. +# +# USAGE +# +# [--let $kill_signal = TERM] # defaults to KILL +# --source include/kill_galera.inc +# +# $kill_signal applies to this call only and is reset afterwards. Give the +# signal by name and never by number: signal numbers are not portable, and +# "kill -9" fails as an unknown signal on FreeBSD. +# +# On return the process no longer exists, so its pid file, ports and data +# directory are free: the node can be restarted, or its grastate.dat read, +# straight away. Waiting only for the connection to drop is not enough for +# that. The connection dies as soon as the server stops serving it, which for +# a signal that lets mysqld shut down gracefully is long before the process +# actually exits, and tests used to paper over the difference with a --sleep. +# +# What this does NOT wait for is the rest of the cluster noticing. A test that +# needs the surviving nodes to have processed the loss of this one has to wait +# for that itself, on a surviving node, e.g. for wsrep_cluster_size to drop or +# for wsrep_cluster_status to become non-Primary. + --echo Killing server ... +if (!$kill_signal) +{ +--let $kill_signal = KILL +} + # Write file to make mysql-test-run.pl expect the crash, but don't start it --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect @@ -7,14 +36,31 @@ # Kill the connected server --disable_reconnect +--let KILL_SIGNAL_VALUE = $kill_signal --let KILL_NODE_PIDFILE = `SELECT @@pid_file` --perl + my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'}; my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -9 $mysqld_pid"); + die "No pid found in $pid_filename\n" + unless $mysqld_pid =~ /^\d+$/; + system("kill -s $kill_sig $mysqld_pid"); + + # Wait for the process to be gone, and not merely for it to stop + # serving connections. my_safe_process is its parent and is sitting + # in waitpid() on it, so it is reaped as soon as it exits and kill(0) + # stops finding it. + my $waited = 0; + while (kill(0, $mysqld_pid)) { + die "Server pid $mysqld_pid did not exit\n" if $waited >= 60; + select(undef, undef, undef, 0.1); + $waited += 0.1; + } exit(0); EOF +--let $kill_signal = + --source include/wait_until_disconnected.inc diff --git a/mysql-test/include/mysqlbinlog_have_debug.inc b/mysql-test/include/mysqlbinlog_have_debug.inc deleted file mode 100644 index 14da1379ecd..00000000000 --- a/mysql-test/include/mysqlbinlog_have_debug.inc +++ /dev/null @@ -1,34 +0,0 @@ -############################################# -# checks if mysqlbinlog is debug compiled -# this "cannot" be done simply by using -# have_debug.inc -############################################# - ---disable_query_log ---let $temp_out_help_file=$MYSQL_TMP_DIR/mysqlbinlog_help.tmp ---exec $MYSQL_BINLOG --help>$temp_out_help_file -let log_tmp=$temp_out_help_file; ---let $temp_inc=$MYSQL_TMP_DIR/temp.inc -let inc_tmp=$temp_inc; - ---perl -use strict; -my $tmp_file= $ENV{'log_tmp'} or die "log_tmp not set"; -open(FILE, "$tmp_file") or die("Unable to open $tmp_file: $!\n"); -my $count = () = grep(/Output debug log/g,); -close FILE; - -my $temp_inc= $ENV{'inc_tmp'} or die "temp_inc not set"; -open(FILE_INC,">", "$temp_inc") or die("can't open file \"$temp_inc\": $!"); -print FILE_INC '--let $is_debug= '.$count; -close FILE_INC; -EOF ---source $temp_inc - -if (!$is_debug) -{ - --skip mysqlbinlog needs to be debug compiled -} ---remove_file $temp_out_help_file ---remove_file $temp_inc ---enable_query_log diff --git a/mysql-test/include/truncate_ddl_log.inc b/mysql-test/include/truncate_ddl_log.inc new file mode 100644 index 00000000000..171551cf72b --- /dev/null +++ b/mysql-test/include/truncate_ddl_log.inc @@ -0,0 +1,6 @@ +# Truncate the ddl log by cycling BACKUP STAGE END/START on con1, so a +# subsequent print_ddl_log.inc only shows entries logged after this point. +connection con1; +BACKUP STAGE END; +BACKUP STAGE START; +connection default; diff --git a/mysql-test/lib/generate-ssl-certs.sh b/mysql-test/lib/generate-ssl-certs.sh index d1788fd8f19..7f5dae194d7 100644 --- a/mysql-test/lib/generate-ssl-certs.sh +++ b/mysql-test/lib/generate-ssl-certs.sh @@ -52,6 +52,13 @@ openssl req -newkey rsa:4096 -keyout client-key.pem -out demoCA/client-req.pem - openssl rsa -in client-key.pem -out client-key.pem openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out client-cert.pem -in demoCA/client-req.pem +# client cert with a single RDN whose value is the literal string "a/b+c" +# ('/' and '+' are separator characters some SSL libraries escape and +# some don't -- see https://github.com/wolfSSL/wolfssl/issues/11392) +openssl req -newkey rsa:4096 -keyout client-slash-cn-key.pem -out demoCA/client-slash-cn-req.pem -days 7300 -nodes -subj '/CN=a\/b\+c' +openssl rsa -in client-slash-cn-key.pem -out client-slash-cn-key.pem +openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out client-slash-cn-cert.pem -in demoCA/client-slash-cn-req.pem + # generate combined client cert and key file cat client-cert.pem client-key.pem > client-certkey.pem @@ -78,10 +85,12 @@ openssl genrsa -out gcadir/root.key 4096 openssl req -new -x509 '-sha256' -key gcadir/root.key -out galera-chain-ca.pem -days 7300 -subj "/O=MariaDB/OU=MariaDB/CN=Galera Chain Root CA" -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign" openssl genrsa -out gcadir/int.key 4096 openssl req -new '-sha256' -key gcadir/int.key -out gcadir/int.csr -subj "/O=MariaDB/OU=MariaDB/CN=Galera Chain Intermediate CA" -openssl x509 -req -in gcadir/int.csr -CA galera-chain-ca.pem -CAkey gcadir/root.key -CAcreateserial -days 7200 -sha256 -extfile <(printf "basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign") -out gcadir/int.crt +printf "basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign\n" > gcadir/int.ext +openssl x509 -req -in gcadir/int.csr -CA galera-chain-ca.pem -CAkey gcadir/root.key -CAcreateserial -days 7200 -sha256 -extfile gcadir/int.ext -out gcadir/int.crt openssl genrsa -out galera-chain-key.pem 4096 openssl req -new '-sha256' -key galera-chain-key.pem -out gcadir/leaf.csr -subj "/CN=localhost" -openssl x509 -req -in gcadir/leaf.csr -CA gcadir/int.crt -CAkey gcadir/int.key -CAcreateserial -days 7100 -sha256 -extfile <(printf "basicConstraints=CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth,clientAuth\nsubjectAltName=DNS:localhost,IP:127.0.0.1") -out gcadir/leaf.crt +printf "basicConstraints=CA:FALSE\nkeyUsage=critical,digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth,clientAuth\nsubjectAltName=DNS:localhost,IP:127.0.0.1\n" > gcadir/leaf.ext +openssl x509 -req -in gcadir/leaf.csr -CA gcadir/int.crt -CAkey gcadir/int.key -CAcreateserial -days 7100 -sha256 -extfile gcadir/leaf.ext -out gcadir/leaf.crt cat gcadir/leaf.crt gcadir/int.crt > galera-chain-cert.pem rm -rf gcadir diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl index 5a3891fa480..ebf659205ac 100755 --- a/mysql-test/lib/v1/mysql-test-run.pl +++ b/mysql-test/lib/v1/mysql-test-run.pl @@ -23,7 +23,7 @@ # Tool used for executing a suite of .test file # # See the "MySQL Test framework manual" for more information -# https://mariadb.com/kb/en/library/mysqltest/ +# https://mariadb.com/docs/server/clients-and-utilities/testing-tools/mariadb-test # # Please keep the test framework tools identical in all versions! # diff --git a/mysql-test/main/backup_log.result b/mysql-test/main/backup_log.result index df6592a9b34..d1da8fb1a0a 100644 --- a/mysql-test/main/backup_log.result +++ b/mysql-test/main/backup_log.result @@ -233,9 +233,27 @@ ALTER,DATABASE,0,mysqltest,,,,0,,, DROP,MyISAM,0,mysqltest,t90,id: 27,,0,,, DROP,InnoDB,0,mysqltest,t91,id: 28,,0,,, DROP,DATABASE,0,mysqltest,,,,0,,, +connection con1; +BACKUP STAGE END; +BACKUP STAGE START; +connection default; +# +# MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer +# +CREATE TABLE t1 (id INT) ENGINE=MyISAM; +RENAME TABLE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`#mysql50#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%` TO `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.t2; +DROP DATABASE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; +# +# Reading backup ddl log file +# +CREATE,MyISAM,0,test,t1,id: 1,,0,,, +RENAME,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,#sql1,id: 1,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,t2,id: 1 +DROP,MyISAM,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,t2,id: 1,,0,,, +DROP,DATABASE,0,@0023mysql50@0023@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,, # # Cleanup # DROP TABLE t_exists; DROP TABLE t_exists_template; disconnect con1; +# End of 10.11 tests diff --git a/mysql-test/main/backup_log.test b/mysql-test/main/backup_log.test index ee34484e92b..daa004cf004 100644 --- a/mysql-test/main/backup_log.test +++ b/mysql-test/main/backup_log.test @@ -31,9 +31,31 @@ CREATE TABLE IF NOT EXISTS t_exists LIKE t_exists_template; --source include/print_ddl_log.inc +--source include/truncate_ddl_log.inc + +--echo # +--echo # MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer +--echo # +# A #mysql50# name is stored on disk as is, but is filename-encoded +# (up to 5 bytes per character) in the ddl log, so the record gets long +# without hitting MAX_PATH on Windows. Such names can't be created with +# SQL, so create the 5.0-style files directly. +let $MYSQLD_DATADIR= `select @@datadir`; +--mkdir $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +CREATE TABLE t1 (id INT) ENGINE=MyISAM; +--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.frm +--move_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.MYI +--move_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.MYD +RENAME TABLE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`#mysql50#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%` TO `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.t2; +DROP DATABASE `#mysql50#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; + +--source include/print_ddl_log.inc + --echo # --echo # Cleanup --echo # DROP TABLE t_exists; DROP TABLE t_exists_template; disconnect con1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/backup_log_no_windows.result b/mysql-test/main/backup_log_no_windows.result new file mode 100644 index 00000000000..2ac24978e2c --- /dev/null +++ b/mysql-test/main/backup_log_no_windows.result @@ -0,0 +1,24 @@ +connect con1,localhost,root,,; +BACKUP STAGE START; +connection default; +# +# MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer +# +CREATE DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; +CREATE TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` (id INT) ENGINE=MyISAM; +RENAME TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` TO `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`; +DROP TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`; +DROP DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; +# +# Reading backup ddl log file +# +CREATE,DATABASE,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,, +CREATE,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040,id: 1,,0,,, +RENAME,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040@0040,id: 1,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025,id: 1 +DROP,MyISAM,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025@0025,id: 1,,0,,, +DROP,DATABASE,0,@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021@0021,,,,0,,, +connection con1; +BACKUP STAGE END; +disconnect con1; +connection default; +# End of 10.11 tests diff --git a/mysql-test/main/backup_log_no_windows.test b/mysql-test/main/backup_log_no_windows.test new file mode 100644 index 00000000000..6dcd3da3839 --- /dev/null +++ b/mysql-test/main/backup_log_no_windows.test @@ -0,0 +1,27 @@ +# Logging of ddl's with long special-character identifiers under backup +# stages. Not on Windows: the file paths of these identifiers exceed MAX_PATH. + +--source include/not_embedded.inc +--source include/not_windows.inc + +connect (con1,localhost,root,,); +BACKUP STAGE START; +connection default; + +--echo # +--echo # MDEV-41175 ASAN stack-buffer-overflow in add_str_to_buffer/add_name_to_buffer +--echo # +CREATE DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; +CREATE TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` (id INT) ENGINE=MyISAM; +RENAME TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`@@@@@@@@@@@@@@@@@@@@` TO `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`; +DROP TABLE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`.`%%%%%%%%%%%%%%%%%%%%`; +DROP DATABASE `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`; + +--source include/print_ddl_log.inc + +connection con1; +BACKUP STAGE END; +disconnect con1; +connection default; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/bad_user_table.result b/mysql-test/main/bad_user_table.result index d94998d7058..c68cb45f5d9 100644 --- a/mysql-test/main/bad_user_table.result +++ b/mysql-test/main/bad_user_table.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Host 'localhost' is not allowed to connect to this MariaDB server"); # # MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty # diff --git a/mysql-test/main/bad_user_table.test b/mysql-test/main/bad_user_table.test index 0d6e0b2d6fd..46ee75f9d60 100644 --- a/mysql-test/main/bad_user_table.test +++ b/mysql-test/main/bad_user_table.test @@ -1,5 +1,7 @@ source include/not_embedded.inc; +call mtr.add_suppression("Host 'localhost' is not allowed to connect to this MariaDB server"); + --echo # --echo # MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty --echo # diff --git a/mysql-test/main/brackets.result b/mysql-test/main/brackets.result index 1f1922416a1..c86426eb97a 100644 --- a/mysql-test/main/brackets.result +++ b/mysql-test/main/brackets.result @@ -4569,3 +4569,293 @@ a drop view v1; drop table t1,t2; # End of 10.4 tests +# +# MDEV-41225: window functions and subqueries in the ORDER BY of a +# parenthesized query expression that must be wrapped into a derived table +# +CREATE TABLE t1 (c1 INT); +(SELECT 1 FROM t1 LIMIT 1) +ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER(); +1 +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2),(3); +# window functions must be computed over the rows left after LIMIT 2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY LEAD(c1) OVER (ORDER BY c1) IS NULL DESC, c1 LIMIT 1; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1; +c1 +2 +1 +((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) UNION (SELECT 3) ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1; +c1 +2 +SELECT * FROM ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) dt; +c1 +2 +SELECT ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) AS c; +c +2 +# inner ORDER BY without LIMIT also forces the wrapping +(SELECT c1 FROM t1 ORDER BY c1) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +c1 +3 +# no wrapping: the tail belongs to the parenthesized select itself +(SELECT c1 FROM t1) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +c1 +3 +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1; +c1 +3 +# subqueries must be attached to the wrapping select +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1) +ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1; +c1 +2 +EXPLAIN EXTENDED (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using filesort +3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort +Warnings: +Note 1276 Field or reference '__2.c1' of SELECT #3 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `__2`.`c1` AS `c1` from ((/* select#2 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` order by `test`.`t1`.`c1` limit 2)) `__2` order by <`__2`.`c1`>((/* select#3 */ select count(0) from `test`.`t2` where `test`.`t2`.`a` > `__2`.`c1`)) limit 1 +# t1.c1 is not visible outside of the derived table +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > t1.c1) LIMIT 1; +ERROR 42S22: Unknown column 't1.c1' in 'WHERE' +CREATE VIEW v1 AS (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a > c1), c1 +LIMIT 1; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `__3`.`c1` AS `c1` from (select `t1`.`c1` AS `c1` from `t1` order by `t1`.`c1` limit 2) `__3` order by `__3`.`c1` = count(0) over () desc,(select max(`t2`.`a`) from `t2` where `t2`.`a` > `__3`.`c1`),`__3`.`c1` limit 1 latin1 latin1_swedish_ci +SELECT * FROM v1; +c1 +2 +DROP VIEW v1; +PREPARE stmt FROM "(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, + (SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1"; +EXECUTE stmt; +c1 +2 +EXECUTE stmt; +c1 +2 +DEALLOCATE PREPARE stmt; +# original query on a non-empty table +(SELECT 1 FROM t1 LIMIT 1) +ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER(); +1 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY c1) OVER () = c1 DESC, c1 +LIMIT 1; +c1 +2 +# locking clauses after a tail with ORDER BY +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 FOR UPDATE WAIT 1; +c1 +2 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 FOR UPDATE NOWAIT; +c1 +2 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE SKIP LOCKED; +c1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, c1 LOCK IN SHARE MODE WAIT 1; +c1 +2 +1 +(SELECT c1 FROM t1) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +c1 +3 +(SELECT c1 FROM t1) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE; +c1 +3 +# locking clauses after a tail without ORDER BY +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 FOR UPDATE; +c1 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 LOCK IN SHARE MODE; +c1 +1 +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 FOR UPDATE NOWAIT; +c1 +3 +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 LOCK IN SHARE MODE; +c1 +3 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE; +c1 +1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE; +c1 +1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE SKIP LOCKED; +c1 +1 +2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE NOWAIT; +c1 +1 +2 +# tail referring to a table of the enclosing query +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY ABS(c1 - t2.a), c1 LIMIT 1) AS nearest +FROM t2 ORDER BY a; +a nearest +1 1 +2 2 +3 2 +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY (SELECT COUNT(*) FROM t2 AS x WHERE x.a >= t2.a) = c1 DESC, +c1 LIMIT 1) AS c +FROM t2 ORDER BY a; +a c +1 1 +2 2 +3 1 +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () + t2.a - 1 DESC, c1 LIMIT 1) AS c +FROM t2 ORDER BY a; +a c +1 2 +2 1 +3 1 +SELECT a FROM t2 +WHERE a = ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = t2.a DESC, c1 DESC LIMIT 1) +ORDER BY a; +a +1 +2 +# aggregate function in the tail belongs to the wrapping select +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY MAX(c1); +c1 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY COUNT(*), c1; +c1 +1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY (SELECT MAX(a) FROM t2 WHERE a >= MAX(c1)); +c1 +1 +(SELECT c1 FROM t1) ORDER BY MAX(c1); +c1 +1 +# named window of the wrapped select is not visible in the tail +(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1) ORDER BY c1 LIMIT 2) +ORDER BY ROW_NUMBER() OVER w; +ERROR HY000: Window specification with name 'w' is not defined +(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1)) +ORDER BY ROW_NUMBER() OVER w DESC LIMIT 1; +c1 +3 +# MATCH in the tail +CREATE TABLE t3 (b VARCHAR(20), FULLTEXT (b)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('apple'),('banana'),('cherry'),('apple pie'); +(SELECT b FROM t3 ORDER BY b LIMIT 3) ORDER BY MATCH(b) AGAINST ('apple'); +ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes +(SELECT b FROM t3 ORDER BY b LIMIT 3) +ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b; +ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes +SELECT b FROM (SELECT b FROM t3 ORDER BY b LIMIT 3) dt +ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b; +ERROR HY000: The storage engine MEMORY doesn't support FULLTEXT indexes +(SELECT b FROM t3) ORDER BY MATCH(b) AGAINST ('cherry') DESC, b LIMIT 1; +b +cherry +DROP TABLE t3; +# wrapped query inside a wrapped query +((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) +ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1 +LIMIT 1; +c1 +1 +EXPLAIN EXTENDED ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) +ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1 +LIMIT 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where +3 DERIVED ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort +Warnings: +Note 1276 Field or reference '__3.c1' of SELECT #4 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `__3`.`c1` AS `c1` from ((/* select#3 */ select `__2`.`c1` AS `c1` from ((/* select#2 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` order by `test`.`t1`.`c1` limit 3)) `__2` order by ntile(2) over ( order by `__2`.`c1`) desc,`__2`.`c1` limit 2)) `__3` order by `__3`.`c1` = count(0) over () desc,<`__3`.`c1`>((/* select#4 */ select max(`test`.`t2`.`a`) from `test`.`t2` where `test`.`t2`.`a` < `__3`.`c1`)),`__3`.`c1` limit 1 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY ((SELECT a FROM t2 ORDER BY a LIMIT 2) +ORDER BY a = COUNT(*) OVER () DESC, a LIMIT 1) = c1 DESC, c1 +LIMIT 1; +c1 +2 +# stored procedure +CREATE PROCEDURE p1() +BEGIN +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) +ORDER BY c1 = COUNT(*) OVER () DESC, +(SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1; +((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) +ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) +ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +END| +CALL p1(); +c1 +2 +c1 +3 +CALL p1(); +c1 +2 +c1 +3 +DROP PROCEDURE p1; +DROP TABLE t1, t2; +# End of 10.11 tests diff --git a/mysql-test/main/brackets.test b/mysql-test/main/brackets.test index 4300e8a0592..b62e33ee68f 100644 --- a/mysql-test/main/brackets.test +++ b/mysql-test/main/brackets.test @@ -2504,3 +2504,178 @@ drop table t1,t2; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-41225: window functions and subqueries in the ORDER BY of a +--echo # parenthesized query expression that must be wrapped into a derived table +--echo # + +CREATE TABLE t1 (c1 INT); +(SELECT 1 FROM t1 LIMIT 1) + ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER(); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1),(2),(3); + +--echo # window functions must be computed over the rows left after LIMIT 2 +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY LEAD(c1) OVER (ORDER BY c1) IS NULL DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1; +((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) UNION (SELECT 3) ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1; +SELECT * FROM ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) dt; +SELECT ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1) AS c; +--echo # inner ORDER BY without LIMIT also forces the wrapping +(SELECT c1 FROM t1 ORDER BY c1) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +--echo # no wrapping: the tail belongs to the parenthesized select itself +(SELECT c1 FROM t1) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1; + +--echo # subqueries must be attached to the wrapping select +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1) + ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1; +EXPLAIN EXTENDED (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > c1) LIMIT 1; +--echo # t1.c1 is not visible outside of the derived table +--error ER_BAD_FIELD_ERROR +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY (SELECT COUNT(*) FROM t2 WHERE a > t1.c1) LIMIT 1; + +CREATE VIEW v1 AS (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a > c1), c1 + LIMIT 1; +SHOW CREATE VIEW v1; +SELECT * FROM v1; +DROP VIEW v1; + +PREPARE stmt FROM "(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, + (SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +--echo # original query on a non-empty table +(SELECT 1 FROM t1 LIMIT 1) + ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY TIME'0') OVER(); +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY PERCENTILE_DISC(1) WITHIN GROUP(ORDER BY c1) OVER () = c1 DESC, c1 + LIMIT 1; + +--echo # locking clauses after a tail with ORDER BY +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = (SELECT MAX(a) - 1 FROM t2) DESC, c1 FOR UPDATE WAIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 FOR UPDATE NOWAIT; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LIMIT 1 FOR UPDATE SKIP LOCKED; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, c1 LOCK IN SHARE MODE WAIT 1; +(SELECT c1 FROM t1) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +(SELECT c1 FROM t1) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 LOCK IN SHARE MODE; +--echo # locking clauses after a tail without ORDER BY +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 FOR UPDATE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LIMIT 1 LOCK IN SHARE MODE; +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 FOR UPDATE NOWAIT; +(SELECT c1 FROM t1 ORDER BY c1 DESC) LIMIT 1 LOCK IN SHARE MODE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) FOR UPDATE SKIP LOCKED; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) LOCK IN SHARE MODE NOWAIT; + +--echo # tail referring to a table of the enclosing query +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY ABS(c1 - t2.a), c1 LIMIT 1) AS nearest +FROM t2 ORDER BY a; +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY (SELECT COUNT(*) FROM t2 AS x WHERE x.a >= t2.a) = c1 DESC, + c1 LIMIT 1) AS c +FROM t2 ORDER BY a; +SELECT a, ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () + t2.a - 1 DESC, c1 LIMIT 1) AS c +FROM t2 ORDER BY a; +SELECT a FROM t2 +WHERE a = ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = t2.a DESC, c1 DESC LIMIT 1) +ORDER BY a; + +--echo # aggregate function in the tail belongs to the wrapping select +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY MAX(c1); +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) ORDER BY COUNT(*), c1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY (SELECT MAX(a) FROM t2 WHERE a >= MAX(c1)); +(SELECT c1 FROM t1) ORDER BY MAX(c1); + +--echo # named window of the wrapped select is not visible in the tail +--error ER_WRONG_WINDOW_SPEC_NAME +(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1) ORDER BY c1 LIMIT 2) + ORDER BY ROW_NUMBER() OVER w; +(SELECT c1 FROM t1 WINDOW w AS (ORDER BY c1)) + ORDER BY ROW_NUMBER() OVER w DESC LIMIT 1; + +--echo # MATCH in the tail +CREATE TABLE t3 (b VARCHAR(20), FULLTEXT (b)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('apple'),('banana'),('cherry'),('apple pie'); +--error ER_TABLE_CANT_HANDLE_FT +(SELECT b FROM t3 ORDER BY b LIMIT 3) ORDER BY MATCH(b) AGAINST ('apple'); +--error ER_TABLE_CANT_HANDLE_FT +(SELECT b FROM t3 ORDER BY b LIMIT 3) + ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b; +--error ER_TABLE_CANT_HANDLE_FT +SELECT b FROM (SELECT b FROM t3 ORDER BY b LIMIT 3) dt + ORDER BY MATCH(b) AGAINST ('cherry' IN BOOLEAN MODE) DESC, b; +(SELECT b FROM t3) ORDER BY MATCH(b) AGAINST ('cherry') DESC, b LIMIT 1; +DROP TABLE t3; + +--echo # wrapped query inside a wrapped query +((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) + ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1 + LIMIT 1; +EXPLAIN EXTENDED ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) + ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, (SELECT MAX(a) FROM t2 WHERE a < c1), c1 + LIMIT 1; +(SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY ((SELECT a FROM t2 ORDER BY a LIMIT 2) + ORDER BY a = COUNT(*) OVER () DESC, a LIMIT 1) = c1 DESC, c1 + LIMIT 1; + +--echo # stored procedure +DELIMITER |; +CREATE PROCEDURE p1() +BEGIN + (SELECT c1 FROM t1 ORDER BY c1 LIMIT 2) + ORDER BY c1 = COUNT(*) OVER () DESC, + (SELECT COUNT(*) FROM t2 WHERE a > c1), c1 LIMIT 1; + ((SELECT c1 FROM t1 ORDER BY c1 LIMIT 3) + ORDER BY NTILE(2) OVER (ORDER BY c1) DESC, c1 LIMIT 2) + ORDER BY c1 = MAX(c1) OVER () DESC, c1 LIMIT 1 FOR UPDATE; +END| +DELIMITER ;| +CALL p1(); +CALL p1(); +DROP PROCEDURE p1; + +DROP TABLE t1, t2; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/column_compression.result b/mysql-test/main/column_compression.result index b0818a911d9..1c541a8acb0 100644 --- a/mysql-test/main/column_compression.result +++ b/mysql-test/main/column_compression.result @@ -1538,7 +1538,7 @@ LENGTH(a) SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` blob /*M!100301 COMPRESSED*/ NOT NULL DEFAULT '' + `a` blob /*M!100301 COMPRESSED*/ NOT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" DROP TABLE t1; @@ -3091,3 +3091,55 @@ REPLACE INTO t VALUES ('abcdefghijklm'); UPDATE t SET c=MID(c,2,4); DROP TABLE t; # End of 10.6 tests +# +# MDEV-40417 A column with compression enabled automatically adds DEFAULT '' +# +CREATE TABLE t ( +c1 LONGTEXT COMPRESSED NOT NULL, +nc1 LONGTEXT NOT NULL, +c2 LONGTEXT COMPRESSED NOT NULL DEFAULT '', +nc2 LONGTEXT NOT NULL DEFAULT '', +c3 VARCHAR(100) COMPRESSED NOT NULL, +nc3 VARCHAR(100) NOT NULL +) ENGINE=InnoDB; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `c1` longtext /*M!100301 COMPRESSED*/ NOT NULL, + `nc1` longtext NOT NULL, + `c2` longtext /*M!100301 COMPRESSED*/ NOT NULL DEFAULT '', + `nc2` longtext NOT NULL DEFAULT '', + `c3` varchar(100) /*M!100301 COMPRESSED*/ NOT NULL, + `nc3` varchar(100) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t' ORDER BY ORDINAL_POSITION; +COLUMN_NAME COLUMN_DEFAULT +c1 NULL +nc1 NULL +c2 '' +nc2 '' +c3 NULL +nc3 NULL +# A compressed column must be as mandatory as an uncompressed one +INSERT INTO t (nc1) VALUES ('x'); +ERROR HY000: Field 'c1' doesn't have a default value +INSERT INTO t (c1, nc1, nc3) VALUES ('x', 'x', 'x'); +ERROR HY000: Field 'c3' doesn't have a default value +INSERT INTO t (c1, nc1, c3, nc3) VALUES ('x', 'x', 'x', 'x'); +SELECT * FROM t; +c1 nc1 c2 nc2 c3 nc3 +x x x x +DROP TABLE t; +# ALTER TABLE must not add an implicit default either +CREATE TABLE t (c LONGTEXT COMPRESSED NOT NULL DEFAULT 'x') ENGINE=InnoDB; +ALTER TABLE t MODIFY c LONGTEXT COMPRESSED NOT NULL; +ALTER TABLE t ADD c2 VARCHAR(100) COMPRESSED NOT NULL; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `c` longtext /*M!100301 COMPRESSED*/ NOT NULL, + `c2` varchar(100) /*M!100301 COMPRESSED*/ NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +DROP TABLE t; +# End of 10.11 tests diff --git a/mysql-test/main/column_compression.test b/mysql-test/main/column_compression.test index 067c659ca10..6d0e42f7a4c 100644 --- a/mysql-test/main/column_compression.test +++ b/mysql-test/main/column_compression.test @@ -599,3 +599,37 @@ UPDATE t SET c=MID(c,2,4); DROP TABLE t; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-40417 A column with compression enabled automatically adds DEFAULT '' +--echo # + +CREATE TABLE t ( + c1 LONGTEXT COMPRESSED NOT NULL, + nc1 LONGTEXT NOT NULL, + c2 LONGTEXT COMPRESSED NOT NULL DEFAULT '', + nc2 LONGTEXT NOT NULL DEFAULT '', + c3 VARCHAR(100) COMPRESSED NOT NULL, + nc3 VARCHAR(100) NOT NULL +) ENGINE=InnoDB; +SHOW CREATE TABLE t; +SELECT COLUMN_NAME, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t' ORDER BY ORDINAL_POSITION; + +--echo # A compressed column must be as mandatory as an uncompressed one +--error ER_NO_DEFAULT_FOR_FIELD +INSERT INTO t (nc1) VALUES ('x'); +--error ER_NO_DEFAULT_FOR_FIELD +INSERT INTO t (c1, nc1, nc3) VALUES ('x', 'x', 'x'); +INSERT INTO t (c1, nc1, c3, nc3) VALUES ('x', 'x', 'x', 'x'); +SELECT * FROM t; +DROP TABLE t; + +--echo # ALTER TABLE must not add an implicit default either +CREATE TABLE t (c LONGTEXT COMPRESSED NOT NULL DEFAULT 'x') ENGINE=InnoDB; +ALTER TABLE t MODIFY c LONGTEXT COMPRESSED NOT NULL; +ALTER TABLE t ADD c2 VARCHAR(100) COMPRESSED NOT NULL; +SHOW CREATE TABLE t; +DROP TABLE t; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/comment_database.result b/mysql-test/main/comment_database.result index 2b18385b50c..7d7a0067a46 100644 --- a/mysql-test/main/comment_database.result +++ b/mysql-test/main/comment_database.result @@ -89,3 +89,65 @@ db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4 Warnings: Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed DROP DATABASE db1; +# +# MDEV-41157 CREATE DATABASE COMMENT overflows db.opt comment buffer +# +set session sql_mode=''; +create database db comment '$long_comment'; +Warnings: +Warning 4160 Comment for database 'db' is too long (max = 1024) +# Bug 1: put_dbopt() must not overflow when storing a truncated comment +show create database db; +Database Create Database +db CREATE DATABASE `db` COMMENT '' +flush tables; +# Bug 2: write_db_opt() must persist a properly terminated truncated comment +show create database db; +Database Create Database +db CREATE DATABASE `db` COMMENT '' +# Bug 3: load_db_opt() must clamp an overlong comment loaded from a legacy db.opt file +flush tables; +show create database db; +Database Create Database +db CREATE DATABASE `db` COMMENT '' +Warnings: +Warning 4160 Comment in database options file './db/db.opt' is too long (max = 1024), truncated +# Bug 3: ALTER DATABASE without COMMENT must clamp a legacy overlong comment too +flush tables; +alter database db character set 'latin1'; +Warnings: +Warning 4160 Comment in database options file './db/db.opt' is too long (max = 1024), truncated +show create database db; +Database Create Database +db CREATE DATABASE `db` COMMENT '' +drop database db; +# Bug 4: multi-byte comment must be truncated at a character boundary +set names utf8mb3; +create database dbmb comment '$mb_comment'; +Warnings: +Warning 4160 Comment for database 'dbmb' is too long (max = 1024) +select char_length(schema_comment), octet_length(schema_comment) +from information_schema.schemata where schema_name='dbmb'; +char_length(schema_comment) octet_length(schema_comment) +341 1023 +flush tables; +select char_length(schema_comment), octet_length(schema_comment) +from information_schema.schemata where schema_name='dbmb'; +char_length(schema_comment) octet_length(schema_comment) +341 1023 +drop database dbmb; +# Bug 4: strict sql_mode must reject an overlong multi-byte comment +set session sql_mode='TRADITIONAL'; +create database dbmb comment '$mb_comment'; +ERROR HY000: Comment for database 'dbmb' is too long (max = 1024) +set session sql_mode=''; +# a 1024-character multi-byte table comment must not be byte-clamped +create table test.t1 (a int) comment '$mb_table_comment'; +select char_length(table_comment), octet_length(table_comment) +from information_schema.tables where table_name='t1'; +char_length(table_comment) octet_length(table_comment) +1024 3072 +drop table test.t1; +set names default; +set session sql_mode=default; +# End of 10.11 tests diff --git a/mysql-test/main/comment_database.test b/mysql-test/main/comment_database.test index a6f43a91e5d..0ab58871694 100644 --- a/mysql-test/main/comment_database.test +++ b/mysql-test/main/comment_database.test @@ -71,3 +71,70 @@ CREATE DATABASE db1; SHOW CREATE DATABASE db1; SHOW CREATE DATABASE db1; DROP DATABASE db1; + +--echo # +--echo # MDEV-41157 CREATE DATABASE COMMENT overflows db.opt comment buffer +--echo # +set session sql_mode=''; +--let $long_comment= `select repeat('A', 4000)` +evalp create database db comment '$long_comment'; + +--echo # Bug 1: put_dbopt() must not overflow when storing a truncated comment +--replace_regex /A{1024}// # /\*!40100[^*]*\*/## +show create database db; +flush tables; +--echo # Bug 2: write_db_opt() must persist a properly terminated truncated comment +--replace_regex /A{1024}// # /\*!40100[^*]*\*/## +show create database db; + +--echo # Bug 3: load_db_opt() must clamp an overlong comment loaded from a legacy db.opt file +--let $def_charset= `select @@character_set_server` +--let $def_collation= `select @@collation_server` +--remove_file $MARIADB_DATADIR/db/db.opt +--write_file $MARIADB_DATADIR/db/db.opt EOF eval +default-character-set=$def_charset +default-collation=$def_collation +comment=$long_comment +EOF +flush tables; +--replace_regex /A{1024}// /[\\]/\// # /\*!40100[^*]*\*/## +show create database db; + +--echo # Bug 3: ALTER DATABASE without COMMENT must clamp a legacy overlong comment too +flush tables; +--replace_regex /[\\]/\// +alter database db character set 'latin1'; +--replace_regex /A{1024}// # /\*!40100[^*]*\*/## +show create database db; + +drop database db; + +--echo # Bug 4: multi-byte comment must be truncated at a character boundary +set names utf8mb3; +--let $mb_comment= `select repeat(convert(0xE4B8AD using utf8mb3), 4000)` +evalp create database dbmb comment '$mb_comment'; +select char_length(schema_comment), octet_length(schema_comment) +from information_schema.schemata where schema_name='dbmb'; +flush tables; +select char_length(schema_comment), octet_length(schema_comment) +from information_schema.schemata where schema_name='dbmb'; +drop database dbmb; + +--echo # Bug 4: strict sql_mode must reject an overlong multi-byte comment +set session sql_mode='TRADITIONAL'; +--error ER_TOO_LONG_DATABASE_COMMENT +evalp create database dbmb comment '$mb_comment'; +set session sql_mode=''; + +--echo # a 1024-character multi-byte table comment must not be byte-clamped +--let $mb_table_comment= `select repeat(convert(0xE4B8AD using utf8mb3), 1024)` +evalp create table test.t1 (a int) comment '$mb_table_comment'; +select char_length(table_comment), octet_length(table_comment) +from information_schema.tables where table_name='t1'; +drop table test.t1; + +set names default; + +set session sql_mode=default; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/create_windows.result b/mysql-test/main/create_windows.result index c064eb7c86f..3678cf0c27e 100644 --- a/mysql-test/main/create_windows.result +++ b/mysql-test/main/create_windows.result @@ -1,2 +1,8 @@ create table `...................................................`(i int); ERROR HY000: Can't create table `test`.`...................................................` (errno: 38 "Filename too long") +# +# MDEV-28746 continued: a *relative* path can overflow MAX_PATH too +# +CREATE TABLE `NAME` (id INT); +ERROR HY000: Can't create table `test`.`NAME` (errno: 38 "Filename too long") +# End of 10.11 tests diff --git a/mysql-test/main/create_windows.test b/mysql-test/main/create_windows.test index 6fe99f6aeb6..608a816a98c 100644 --- a/mysql-test/main/create_windows.test +++ b/mysql-test/main/create_windows.test @@ -8,3 +8,17 @@ let $t = `SELECT(REPEAT('.',51))`; --error ER_CANT_CREATE_TABLE eval create table `$t`(i int); + +--echo # +--echo # MDEV-28746 continued: a *relative* path can overflow MAX_PATH too +--echo # +# mariadbd opens table files via relative (to datadir) paths, so a short +# identifier can still overflow MAX_PATH (260) once resolved against a long +# enough datadir. '!' encodes to 5 bytes; pick the fewest of them that push +# datadir + "test\.frm" (9 fixed bytes) to 260. +--let $t2= `SELECT REPEAT('!', GREATEST(1, CEIL((260 - LENGTH(@@datadir) - 9) / 5)))` +--replace_regex /!+/NAME/ +--error ER_CANT_CREATE_TABLE +eval CREATE TABLE `$t2` (id INT); + +--echo # End of 10.11 tests diff --git a/mysql-test/main/ctype_armscii8.result b/mysql-test/main/ctype_armscii8.result new file mode 100644 index 00000000000..b66bd53c00b --- /dev/null +++ b/mysql-test/main/ctype_armscii8.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES armscii8 COLLATE armscii8_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES armscii8 COLLATE armscii8_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (armscii8_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_armscii8.test b/mysql-test/main/ctype_armscii8.test new file mode 100644 index 00000000000..1ff6c4707c7 --- /dev/null +++ b/mysql-test/main/ctype_armscii8.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES armscii8 COLLATE armscii8_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES armscii8 COLLATE armscii8_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_ascii.result b/mysql-test/main/ctype_ascii.result index 06362486073..9356e351e34 100644 --- a/mysql-test/main/ctype_ascii.result +++ b/mysql-test/main/ctype_ascii.result @@ -175,3 +175,27 @@ z z ~ ~ drop table t1; End of 5.0 tests. +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES ascii COLLATE ascii_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES ascii COLLATE ascii_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (ascii_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_ascii.test b/mysql-test/main/ctype_ascii.test index 2a5118c7d34..c66222f4f60 100644 --- a/mysql-test/main/ctype_ascii.test +++ b/mysql-test/main/ctype_ascii.test @@ -11,3 +11,21 @@ drop table t1; # --echo End of 5.0 tests. + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES ascii COLLATE ascii_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES ascii COLLATE ascii_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_big5.result b/mysql-test/main/ctype_big5.result index 5c932905f27..ca5e35a966d 100644 --- a/mysql-test/main/ctype_big5.result +++ b/mysql-test/main/ctype_big5.result @@ -5644,3 +5644,406 @@ c1 # # End of 10.5 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# Two different explicit COLLATE clauses are still not accepted, +# whether the character sets are different or the same +SELECT _latin1'a' COLLATE latin1_swedish_ci = _big5'a' COLLATE big5_chinese_ci; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,EXPLICIT) and (big5_chinese_ci,EXPLICIT) for operation '=' +SELECT _latin1'a' COLLATE latin1_german1_ci = _latin1'a' COLLATE latin1_swedish_ci; +ERROR HY000: Illegal mix of collations (latin1_german1_ci,EXPLICIT) and (latin1_swedish_ci,EXPLICIT) for operation '=' +SET NAMES big5 COLLATE big5_chinese_ci; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y_' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y+' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +# Same as above, but using BETWEEN (3-operand aggregation) +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z_' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A_' AND 'Z' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z+' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'between' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A+' AND 'Z' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'between' +# Same as above, but using IN() (N-operand aggregation) +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N') LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y_','N') LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N+') LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'in' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y+','N') LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'in' +# Same as above, but using STRCMP() +SELECT STRCMP(Insert_priv,'Y') FROM mysql.user LIMIT 0; +STRCMP(Insert_priv,'Y') +SELECT STRCMP(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +STRCMP(Insert_priv,'Y_') +SELECT STRCMP(Insert_priv,'Y+') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'strcmp' +# Same as above, but using LOCATE()/POSITION()/INSTR() +SELECT LOCATE('Y',Insert_priv) FROM mysql.user LIMIT 0; +LOCATE('Y',Insert_priv) +SELECT LOCATE('Y_',Insert_priv) FROM mysql.user LIMIT 0; +LOCATE('Y_',Insert_priv) +SELECT LOCATE('Y+',Insert_priv) FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +SELECT POSITION('Y' IN Insert_priv) FROM mysql.user LIMIT 0; +POSITION('Y' IN Insert_priv) +SELECT POSITION('Y+' IN Insert_priv) FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +SELECT INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +INSTR(Insert_priv,'Y') +SELECT INSTR(Insert_priv,'Y+') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +# Same as above, but using FIELD() +SELECT FIELD(Insert_priv,'Y','N') FROM mysql.user LIMIT 0; +FIELD(Insert_priv,'Y','N') +SELECT FIELD(Insert_priv,'Y_','N') FROM mysql.user LIMIT 0; +FIELD(Insert_priv,'Y_','N') +SELECT FIELD(Insert_priv,'Y','N+') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'field' +SELECT FIELD(Insert_priv,'Y+','N') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'field' +# Same as above, but using FIND_IN_SET() +# (a single-value haystack, so the ',' separator does not +# itself force a wider repertoire) +SELECT FIND_IN_SET(Insert_priv,'Y') FROM mysql.user LIMIT 0; +FIND_IN_SET(Insert_priv,'Y') +SELECT FIND_IN_SET(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +FIND_IN_SET(Insert_priv,'Y_') +SELECT FIND_IN_SET(Insert_priv,'Y+') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'find_in_set' +# Same as above, but using LIKE +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y_' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y+' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'like' +# Same as above, but using RLIKE +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y_' LIMIT 0; +Insert_priv +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y+' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'regexp' +# Same as above, but using REGEXP_INSTR() +SELECT REGEXP_INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +REGEXP_INSTR(Insert_priv,'Y') +SELECT REGEXP_INSTR(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +REGEXP_INSTR(Insert_priv,'Y_') +SELECT REGEXP_INSTR(Insert_priv,'Y+') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'regexp_instr' +# Same as above, but using MATCH ... AGAINST(). +# Unlike the other comparison functions above, MATCH ... AGAINST() +# does not aggregate the AGAINST phrase's collation for the illegal-mix +# check: Item_func_match::fix_fields() calls +# agg_arg_charsets_for_comparison() on args+1 (the indexed column(s) +# only), skipping args[0], which is the AGAINST phrase (key_item()). +# The phrase is instead silently converted to the column's collation +# (search_value), so none of the queries below raise an error, even +# with a _bin column. +CREATE TABLE t1 (a VARCHAR(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci, +FULLTEXT(a)); +INSERT INTO t1 VALUES ('Y'),('N'); +SET NAMES big5 COLLATE big5_chinese_ci; +SELECT MATCH(a) AGAINST('Y') FROM t1; +MATCH(a) AGAINST('Y') +0 +0 +SELECT MATCH(a) AGAINST('Y_') FROM t1; +MATCH(a) AGAINST('Y_') +0 +0 +SELECT MATCH(a) AGAINST('Y+') FROM t1; +MATCH(a) AGAINST('Y+') +0 +0 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(200) CHARACTER SET latin1 COLLATE latin1_bin, +FULLTEXT(a)); +INSERT INTO t1 VALUES ('Y'),('N'); +SELECT MATCH(a) AGAINST('Y') FROM t1; +MATCH(a) AGAINST('Y') +0 +0 +DROP TABLE t1; +# Same as above, but using the simple CASE operator +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END +SELECT CASE Insert_priv WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +CASE Insert_priv WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N+' THEN 0 END FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'case' +SELECT CASE Insert_priv WHEN 'Y+' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'case' +SET NAMES big5 COLLATE big5_bin; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation '=' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'like' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'regexp' +SELECT REGEXP_INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'regexp_instr' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z' LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'between' +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N') LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'in' +SELECT STRCMP(Insert_priv,'Y') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'strcmp' +SELECT LOCATE('Y',Insert_priv) FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'locate' +SELECT FIELD(Insert_priv,'Y','N') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'field' +SELECT FIND_IN_SET(Insert_priv,'Y') FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'find_in_set' +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'case' +# +# The same checks using an own view instead of mysql.user. +# The view has exactly one row, so every query below returns +# a row, or raises an error. +# +SET NAMES big5 COLLATE big5_chinese_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '<>' +# Same as above, but using BETWEEN (3-operand aggregation) +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z'; +c +Y +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z_'; +c +Y +SELECT c FROM v_tailoring WHERE c BETWEEN 'A_' AND 'Z'; +c +Y +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'between' +SELECT c FROM v_tailoring WHERE c BETWEEN 'A+' AND 'Z'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'between' +# Same as above, but using IN() (N-operand aggregation) +SELECT c FROM v_tailoring WHERE c IN ('Y','N'); +c +Y +SELECT c FROM v_tailoring WHERE c NOT IN ('Y_','N'); +c +Y +SELECT c FROM v_tailoring WHERE c IN ('Y','N+'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'in' +SELECT c FROM v_tailoring WHERE c NOT IN ('Y+','N'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'in' +# Same as above, but using STRCMP() +SELECT STRCMP(c,'Y') FROM v_tailoring; +STRCMP(c,'Y') +0 +SELECT STRCMP(c,'Y_') FROM v_tailoring; +STRCMP(c,'Y_') +-1 +SELECT STRCMP(c,'Y+') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'strcmp' +# Same as above, but using LOCATE()/POSITION()/INSTR() +SELECT LOCATE('Y',c) FROM v_tailoring; +LOCATE('Y',c) +1 +SELECT LOCATE('Y_',c) FROM v_tailoring; +LOCATE('Y_',c) +0 +SELECT LOCATE('Y+',c) FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +SELECT POSITION('Y' IN c) FROM v_tailoring; +POSITION('Y' IN c) +1 +SELECT POSITION('Y+' IN c) FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +SELECT INSTR(c,'Y') FROM v_tailoring; +INSTR(c,'Y') +1 +SELECT INSTR(c,'Y+') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'locate' +# Same as above, but using FIELD() +SELECT FIELD(c,'Y','N') FROM v_tailoring; +FIELD(c,'Y','N') +1 +SELECT FIELD(c,'Y_','N') FROM v_tailoring; +FIELD(c,'Y_','N') +0 +SELECT FIELD(c,'Y','N+') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'field' +SELECT FIELD(c,'Y+','N') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'field' +# Same as above, but using FIND_IN_SET() +# (a single-value haystack, so the ',' separator does not +# itself force a wider repertoire) +SELECT FIND_IN_SET(c,'Y') FROM v_tailoring; +FIND_IN_SET(c,'Y') +1 +SELECT FIND_IN_SET(c,'Y_') FROM v_tailoring; +FIND_IN_SET(c,'Y_') +0 +SELECT FIND_IN_SET(c,'Y+') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'find_in_set' +# Same as above, but using LIKE +SELECT c FROM v_tailoring WHERE c LIKE 'Y'; +c +Y +SELECT c FROM v_tailoring WHERE c NOT LIKE 'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c NOT LIKE 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'like' +# Same as above, but using RLIKE +SELECT c FROM v_tailoring WHERE c RLIKE 'Y'; +c +Y +SELECT c FROM v_tailoring WHERE c NOT RLIKE 'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c RLIKE 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'regexp' +# Same as above, but using REGEXP_INSTR() +SELECT REGEXP_INSTR(c,'Y') FROM v_tailoring; +REGEXP_INSTR(c,'Y') +1 +SELECT REGEXP_INSTR(c,'Y_') FROM v_tailoring; +REGEXP_INSTR(c,'Y_') +0 +SELECT REGEXP_INSTR(c,'Y+') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation 'regexp_instr' +# Same as above, but using the simple CASE operator +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +CASE c WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END +1 +SELECT CASE c WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +CASE c WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END +NULL +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N+' THEN 0 END FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'case' +SELECT CASE c WHEN 'Y+' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'case' +SET NAMES big5 COLLATE big5_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c LIKE 'Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'like' +SELECT c FROM v_tailoring WHERE c RLIKE 'Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'regexp' +SELECT REGEXP_INSTR(c,'Y') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'regexp_instr' +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'between' +SELECT c FROM v_tailoring WHERE c IN ('Y','N'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'in' +SELECT STRCMP(c,'Y') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'strcmp' +SELECT LOCATE('Y',c) FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'locate' +SELECT FIELD(c,'Y','N') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'field' +SELECT FIND_IN_SET(c,'Y') FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_bin,COERCIBLE) for operation 'find_in_set' +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_bin,COERCIBLE), (big5_bin,COERCIBLE) for operation 'case' +# The originally reported scenario: a view is created under latin1 +# and queried under big5. The comparison must return the right rows. +SET NAMES latin1 COLLATE latin1_swedish_ci; +CREATE VIEW v1 AS SELECT 'Y' AS c1 UNION SELECT 'N'; +SET NAMES big5 COLLATE big5_chinese_ci; +SELECT * FROM v1 WHERE c1='y'; +c1 +Y +SELECT * FROM v1 WHERE c1='Y'; +c1 +Y +SELECT * FROM v1 WHERE 'n'=c1; +c1 +N +SELECT * FROM v1 WHERE c1='N'; +c1 +N +SELECT * FROM v1 WHERE c1='x'; +c1 +SELECT * FROM v1 WHERE c1 IN ('y','n') ORDER BY c1; +c1 +N +Y +SELECT * FROM v1 WHERE c1 BETWEEN 'm' AND 'z' ORDER BY c1; +c1 +N +Y +# The same view with prepared statement parameters. +# A parameter with a non-ALNUM value makes the collations incompatible. +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1=? ORDER BY c1'; +SET @y='y', @n='N', @y_plus='Y+'; +EXECUTE stmt USING @y; +c1 +Y +EXECUTE stmt USING @n; +c1 +N +EXECUTE stmt USING @y_plus; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +EXECUTE stmt USING 'y'; +c1 +Y +EXECUTE stmt USING 'x'; +c1 +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1 IN (?,?) ORDER BY c1'; +EXECUTE stmt USING 'y', 'n'; +c1 +N +Y +EXECUTE stmt USING 'y', 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE), (big5_chinese_ci,COERCIBLE) for operation 'in' +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'y'; +c1 +Y +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +DROP VIEW v1; +# Prepared statement parameters compared to a literal of another charset. +# A parameter with a non-ALNUM value makes the collations incompatible. +PREPARE stmt FROM 'SELECT _latin1''Y'' = ? AS r'; +EXECUTE stmt USING @y; +r +1 +EXECUTE stmt USING @n; +r +0 +EXECUTE stmt USING @y_plus; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT _latin1''Y+'' = ? AS r'; +EXECUTE stmt USING 'y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +EXECUTE stmt USING 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'y'; +r +1 +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (big5_chinese_ci,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_big5.test b/mysql-test/main/ctype_big5.test index c35f2f8262c..b5be31a5b47 100644 --- a/mysql-test/main/ctype_big5.test +++ b/mysql-test/main/ctype_big5.test @@ -297,3 +297,311 @@ select strcmp(_big5'' collate big5_nopad_bin, _big5 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +--echo # Two different explicit COLLATE clauses are still not accepted, +--echo # whether the character sets are different or the same +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT _latin1'a' COLLATE latin1_swedish_ci = _big5'a' COLLATE big5_chinese_ci; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT _latin1'a' COLLATE latin1_german1_ci = _latin1'a' COLLATE latin1_swedish_ci; + + +SET NAMES big5 COLLATE big5_chinese_ci; +--disable_service_connection +--source include/ctype_tailoring_03_mysql_user_Insert_priv_last_error.inc + +--echo # Same as above, but using BETWEEN (3-operand aggregation) +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z' LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z_' LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A_' AND 'Z' LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z+' LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A+' AND 'Z' LIMIT 0; + +--echo # Same as above, but using IN() (N-operand aggregation) +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N') LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y_','N') LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N+') LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y+','N') LIMIT 0; + +--echo # Same as above, but using STRCMP() +SELECT STRCMP(Insert_priv,'Y') FROM mysql.user LIMIT 0; +SELECT STRCMP(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT STRCMP(Insert_priv,'Y+') FROM mysql.user LIMIT 0; + +--echo # Same as above, but using LOCATE()/POSITION()/INSTR() +SELECT LOCATE('Y',Insert_priv) FROM mysql.user LIMIT 0; +SELECT LOCATE('Y_',Insert_priv) FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT LOCATE('Y+',Insert_priv) FROM mysql.user LIMIT 0; +SELECT POSITION('Y' IN Insert_priv) FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT POSITION('Y+' IN Insert_priv) FROM mysql.user LIMIT 0; +SELECT INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT INSTR(Insert_priv,'Y+') FROM mysql.user LIMIT 0; + +--echo # Same as above, but using FIELD() +SELECT FIELD(Insert_priv,'Y','N') FROM mysql.user LIMIT 0; +SELECT FIELD(Insert_priv,'Y_','N') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(Insert_priv,'Y','N+') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(Insert_priv,'Y+','N') FROM mysql.user LIMIT 0; + +--echo # Same as above, but using FIND_IN_SET() +--echo # (a single-value haystack, so the ',' separator does not +--echo # itself force a wider repertoire) +SELECT FIND_IN_SET(Insert_priv,'Y') FROM mysql.user LIMIT 0; +SELECT FIND_IN_SET(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT FIND_IN_SET(Insert_priv,'Y+') FROM mysql.user LIMIT 0; + +--echo # Same as above, but using LIKE +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y' LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y_' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y+' LIMIT 0; + +--echo # Same as above, but using RLIKE +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y' LIMIT 0; +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y_' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y+' LIMIT 0; + +--echo # Same as above, but using REGEXP_INSTR() +SELECT REGEXP_INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +SELECT REGEXP_INSTR(Insert_priv,'Y_') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT REGEXP_INSTR(Insert_priv,'Y+') FROM mysql.user LIMIT 0; + +--echo # Same as above, but using MATCH ... AGAINST(). +--echo # Unlike the other comparison functions above, MATCH ... AGAINST() +--echo # does not aggregate the AGAINST phrase's collation for the illegal-mix +--echo # check: Item_func_match::fix_fields() calls +--echo # agg_arg_charsets_for_comparison() on args+1 (the indexed column(s) +--echo # only), skipping args[0], which is the AGAINST phrase (key_item()). +--echo # The phrase is instead silently converted to the column's collation +--echo # (search_value), so none of the queries below raise an error, even +--echo # with a _bin column. +CREATE TABLE t1 (a VARCHAR(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci, + FULLTEXT(a)); +INSERT INTO t1 VALUES ('Y'),('N'); +SET NAMES big5 COLLATE big5_chinese_ci; +SELECT MATCH(a) AGAINST('Y') FROM t1; +SELECT MATCH(a) AGAINST('Y_') FROM t1; +SELECT MATCH(a) AGAINST('Y+') FROM t1; +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(200) CHARACTER SET latin1 COLLATE latin1_bin, + FULLTEXT(a)); +INSERT INTO t1 VALUES ('Y'),('N'); +SELECT MATCH(a) AGAINST('Y') FROM t1; +DROP TABLE t1; + +--echo # Same as above, but using the simple CASE operator +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +SELECT CASE Insert_priv WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N+' THEN 0 END FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE Insert_priv WHEN 'Y+' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; + +SET NAMES big5 COLLATE big5_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv='Y' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv LIKE 'Y' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv RLIKE 'Y' LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT REGEXP_INSTR(Insert_priv,'Y') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv BETWEEN 'A' AND 'Z' LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT Insert_priv FROM mysql.user WHERE Insert_priv IN ('Y','N') LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT STRCMP(Insert_priv,'Y') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT LOCATE('Y',Insert_priv) FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(Insert_priv,'Y','N') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT FIND_IN_SET(Insert_priv,'Y') FROM mysql.user LIMIT 0; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE Insert_priv WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM mysql.user LIMIT 0; +--echo # +--echo # The same checks using an own view instead of mysql.user. +--echo # The view has exactly one row, so every query below returns +--echo # a row, or raises an error. +--echo # + +--source include/ctype_tailoring_view_create.inc +SET NAMES big5 COLLATE big5_chinese_ci; +--source include/ctype_tailoring_03_probe_last_error.inc + +--echo # Same as above, but using BETWEEN (3-operand aggregation) +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z'; +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z_'; +SELECT c FROM v_tailoring WHERE c BETWEEN 'A_' AND 'Z'; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z+'; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c BETWEEN 'A+' AND 'Z'; + +--echo # Same as above, but using IN() (N-operand aggregation) +SELECT c FROM v_tailoring WHERE c IN ('Y','N'); +SELECT c FROM v_tailoring WHERE c NOT IN ('Y_','N'); +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c IN ('Y','N+'); +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c NOT IN ('Y+','N'); + +--echo # Same as above, but using STRCMP() +SELECT STRCMP(c,'Y') FROM v_tailoring; +SELECT STRCMP(c,'Y_') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT STRCMP(c,'Y+') FROM v_tailoring; + +--echo # Same as above, but using LOCATE()/POSITION()/INSTR() +SELECT LOCATE('Y',c) FROM v_tailoring; +SELECT LOCATE('Y_',c) FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT LOCATE('Y+',c) FROM v_tailoring; +SELECT POSITION('Y' IN c) FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT POSITION('Y+' IN c) FROM v_tailoring; +SELECT INSTR(c,'Y') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT INSTR(c,'Y+') FROM v_tailoring; + +--echo # Same as above, but using FIELD() +SELECT FIELD(c,'Y','N') FROM v_tailoring; +SELECT FIELD(c,'Y_','N') FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(c,'Y','N+') FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(c,'Y+','N') FROM v_tailoring; + +--echo # Same as above, but using FIND_IN_SET() +--echo # (a single-value haystack, so the ',' separator does not +--echo # itself force a wider repertoire) +SELECT FIND_IN_SET(c,'Y') FROM v_tailoring; +SELECT FIND_IN_SET(c,'Y_') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT FIND_IN_SET(c,'Y+') FROM v_tailoring; + +--echo # Same as above, but using LIKE +SELECT c FROM v_tailoring WHERE c LIKE 'Y'; +SELECT c FROM v_tailoring WHERE c NOT LIKE 'Y_'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c NOT LIKE 'Y+'; + +--echo # Same as above, but using RLIKE +SELECT c FROM v_tailoring WHERE c RLIKE 'Y'; +SELECT c FROM v_tailoring WHERE c NOT RLIKE 'Y_'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c RLIKE 'Y+'; + +--echo # Same as above, but using REGEXP_INSTR() +SELECT REGEXP_INSTR(c,'Y') FROM v_tailoring; +SELECT REGEXP_INSTR(c,'Y_') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT REGEXP_INSTR(c,'Y+') FROM v_tailoring; + +--echo # Same as above, but using the simple CASE operator +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +SELECT CASE c WHEN 'Y_' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N+' THEN 0 END FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE c WHEN 'Y+' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; + +SET NAMES big5 COLLATE big5_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c LIKE 'Y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c RLIKE 'Y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT REGEXP_INSTR(c,'Y') FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c BETWEEN 'A' AND 'Z'; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT c FROM v_tailoring WHERE c IN ('Y','N'); +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT STRCMP(c,'Y') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT LOCATE('Y',c) FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT FIELD(c,'Y','N') FROM v_tailoring; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT FIND_IN_SET(c,'Y') FROM v_tailoring; +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT CASE c WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END FROM v_tailoring; +--source include/ctype_tailoring_view_drop.inc + +--echo # The originally reported scenario: a view is created under latin1 +--echo # and queried under big5. The comparison must return the right rows. +SET NAMES latin1 COLLATE latin1_swedish_ci; +CREATE VIEW v1 AS SELECT 'Y' AS c1 UNION SELECT 'N'; +SET NAMES big5 COLLATE big5_chinese_ci; +SELECT * FROM v1 WHERE c1='y'; +SELECT * FROM v1 WHERE c1='Y'; +SELECT * FROM v1 WHERE 'n'=c1; +SELECT * FROM v1 WHERE c1='N'; +SELECT * FROM v1 WHERE c1='x'; +SELECT * FROM v1 WHERE c1 IN ('y','n') ORDER BY c1; +SELECT * FROM v1 WHERE c1 BETWEEN 'm' AND 'z' ORDER BY c1; +--enable_service_connection + +--echo # The same view with prepared statement parameters. +--echo # A parameter with a non-ALNUM value makes the collations incompatible. +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1=? ORDER BY c1'; +SET @y='y', @n='N', @y_plus='Y+'; +EXECUTE stmt USING @y; +EXECUTE stmt USING @n; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE stmt USING @y_plus; +EXECUTE stmt USING 'y'; +EXECUTE stmt USING 'x'; +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1 IN (?,?) ORDER BY c1'; +EXECUTE stmt USING 'y', 'n'; +--error ER_CANT_AGGREGATE_3COLLATIONS +EXECUTE stmt USING 'y', 'Y+'; +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'Y+'; +DROP VIEW v1; + +--echo # Prepared statement parameters compared to a literal of another charset. +--echo # A parameter with a non-ALNUM value makes the collations incompatible. +PREPARE stmt FROM 'SELECT _latin1''Y'' = ? AS r'; +EXECUTE stmt USING @y; +EXECUTE stmt USING @n; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE stmt USING @y_plus; +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT _latin1''Y+'' = ? AS r'; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE stmt USING 'y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE stmt USING 'Y+'; +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'Y+'; +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_big5_tailoring.result b/mysql-test/main/ctype_big5_tailoring.result new file mode 100644 index 00000000000..b4fdc800cf1 --- /dev/null +++ b/mysql-test/main/ctype_big5_tailoring.result @@ -0,0 +1,1554 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +big5_bin big5_bin 0 0 000 cl1 = cl2 +big5_chinese_ci big5_chinese_ci 0 0 000 cl1 = cl2 +big5_chinese_nopad_ci big5_chinese_nopad_ci 0 0 000 cl1 = cl2 +big5_nopad_bin big5_nopad_bin 0 0 000 cl1 = cl2 +big5_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_chinese_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs big5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin big5_bin 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +big5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin big5_bin 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +big5_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +big5_nopad_bin big5_bin 1 1 030 nopad vs pad +big5_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +big5_nopad_bin latin1_bin 1 1 030 nopad vs pad +big5_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +big5_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +big5_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +big5_nopad_bin latin5_bin 1 1 030 nopad vs pad +big5_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin big5_bin 1 1 030 nopad vs pad +latin1_nopad_bin big5_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci big5_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin big5_bin 1 1 030 nopad vs pad +swe7_nopad_bin big5_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci big5_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +big5_bin big5_nopad_bin 1 1 030 pad vs nopad +big5_bin latin1_nopad_bin 1 1 030 pad vs nopad +big5_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +big5_bin swe7_nopad_bin 1 1 030 pad vs nopad +big5_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +big5_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +big5_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci big5_nopad_bin 1 1 030 pad vs nopad +latin1_bin big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin big5_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs big5_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci big5_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci big5_nopad_bin 1 1 030 pad vs nopad +latin5_bin big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin big5_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci big5_nopad_bin 1 1 030 pad vs nopad +big5_bin hp8_english_ci 0 0 100 equal tailoring +big5_bin latin1_bin 0 0 100 equal tailoring +big5_bin latin1_general_cs 0 0 100 equal tailoring +big5_bin latin1_german1_ci 0 0 100 equal tailoring +big5_bin latin1_swedish_ci 0 0 100 equal tailoring +big5_bin latin5_bin 0 0 100 equal tailoring +big5_bin latin5_turkish_ci 0 0 100 equal tailoring +big5_chinese_ci hp8_english_ci 0 0 100 equal tailoring +big5_chinese_ci latin1_bin 0 0 100 equal tailoring +big5_chinese_ci latin1_general_cs 0 0 100 equal tailoring +big5_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +big5_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +big5_chinese_ci latin5_bin 0 0 100 equal tailoring +big5_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +big5_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +big5_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +big5_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +big5_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +big5_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +big5_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +big5_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +big5_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci big5_bin 0 0 100 equal tailoring +hp8_english_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_bin big5_bin 0 0 100 equal tailoring +latin1_bin big5_chinese_ci 0 0 100 equal tailoring +latin1_general_cs big5_bin 0 0 100 equal tailoring +latin1_general_cs big5_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci big5_bin 0 0 100 equal tailoring +latin1_german1_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin big5_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin big5_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci big5_bin 0 0 100 equal tailoring +latin1_swedish_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci big5_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci big5_nopad_bin 0 0 100 equal tailoring +latin5_bin big5_bin 0 0 100 equal tailoring +latin5_bin big5_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci big5_bin 0 0 100 equal tailoring +latin5_turkish_ci big5_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin big5_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin big5_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci big5_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci big5_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +big5_bin big5_bin 0 0 000 cl1 = cl2 +big5_chinese_ci big5_chinese_ci 0 0 000 cl1 = cl2 +big5_chinese_nopad_ci big5_chinese_nopad_ci 0 0 000 cl1 = cl2 +big5_nopad_bin big5_nopad_bin 0 0 000 cl1 = cl2 +big5_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_chinese_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs big5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin big5_bin 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +big5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin big5_bin 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +big5_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +big5_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +big5_nopad_bin big5_bin 1 1 030 nopad vs pad +big5_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +big5_nopad_bin latin1_bin 1 1 030 nopad vs pad +big5_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +big5_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +big5_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +big5_nopad_bin latin5_bin 1 1 030 nopad vs pad +big5_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin big5_bin 1 1 030 nopad vs pad +latin1_nopad_bin big5_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci big5_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin big5_bin 1 1 030 nopad vs pad +swe7_nopad_bin big5_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci big5_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci big5_chinese_ci 1 1 030 nopad vs pad +big5_bin big5_nopad_bin 1 1 030 pad vs nopad +big5_bin latin1_nopad_bin 1 1 030 pad vs nopad +big5_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +big5_bin swe7_nopad_bin 1 1 030 pad vs nopad +big5_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +big5_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +big5_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +big5_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci big5_nopad_bin 1 1 030 pad vs nopad +latin1_bin big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin big5_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs big5_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci big5_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci big5_nopad_bin 1 1 030 pad vs nopad +latin5_bin big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin big5_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci big5_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci big5_nopad_bin 1 1 030 pad vs nopad +big5_bin hp8_english_ci 0 0 100 equal tailoring +big5_bin latin1_bin 0 0 100 equal tailoring +big5_bin latin1_general_cs 0 0 100 equal tailoring +big5_bin latin1_german1_ci 0 0 100 equal tailoring +big5_bin latin1_swedish_ci 0 0 100 equal tailoring +big5_bin latin5_bin 0 0 100 equal tailoring +big5_bin latin5_turkish_ci 0 0 100 equal tailoring +big5_chinese_ci hp8_english_ci 0 0 100 equal tailoring +big5_chinese_ci latin1_bin 0 0 100 equal tailoring +big5_chinese_ci latin1_general_cs 0 0 100 equal tailoring +big5_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +big5_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +big5_chinese_ci latin5_bin 0 0 100 equal tailoring +big5_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +big5_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +big5_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +big5_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +big5_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +big5_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +big5_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +big5_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +big5_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci big5_bin 0 0 100 equal tailoring +hp8_english_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_bin big5_bin 0 0 100 equal tailoring +latin1_bin big5_chinese_ci 0 0 100 equal tailoring +latin1_general_cs big5_bin 0 0 100 equal tailoring +latin1_general_cs big5_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci big5_bin 0 0 100 equal tailoring +latin1_german1_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin big5_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin big5_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci big5_bin 0 0 100 equal tailoring +latin1_swedish_ci big5_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci big5_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci big5_nopad_bin 0 0 100 equal tailoring +latin5_bin big5_bin 0 0 100 equal tailoring +latin5_bin big5_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci big5_bin 0 0 100 equal tailoring +latin5_turkish_ci big5_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin big5_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin big5_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci big5_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci big5_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +big5_bin big5_bin 0 0 000 cl1 = cl2 +big5_chinese_ci big5_chinese_ci 0 0 000 cl1 = cl2 +big5_chinese_nopad_ci big5_chinese_nopad_ci 0 0 000 cl1 = cl2 +big5_nopad_bin big5_nopad_bin 0 0 000 cl1 = cl2 +big5_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_ci 0 0 002 LEFT sameCS_bin +big5_nopad_bin big5_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +big5_chinese_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_bin 0 0 002 RIGHT sameCS_bin +big5_chinese_nopad_ci big5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs big5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin big5_bin 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci big5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci big5_nopad_bin 0 0 003 LEFT superset +big5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +big5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin big5_bin 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci big5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci big5_nopad_bin 0 0 004 LEFT superset +big5_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +big5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +big5_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1250 COLLATE cp1250_croatian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1250 COLLATE cp1250_polish_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1250 COLLATE cp1250_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1250_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1250.test b/mysql-test/main/ctype_cp1250.test new file mode 100644 index 00000000000..713476d5ec8 --- /dev/null +++ b/mysql-test/main/ctype_cp1250.test @@ -0,0 +1,23 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp1250 COLLATE cp1250_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1250 COLLATE cp1250_croatian_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1250 COLLATE cp1250_polish_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1250 COLLATE cp1250_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1250_ch.result b/mysql-test/main/ctype_cp1250_ch.result index c65b3d260af..1ffcd37ef70 100644 --- a/mysql-test/main/ctype_cp1250_ch.result +++ b/mysql-test/main/ctype_cp1250_ch.result @@ -912,3 +912,24 @@ A401 # # End of 5.6 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp1250 COLLATE cp1250_czech_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1250_czech_cs,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1250_czech_cs,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1250_czech_cs,COERCIBLE) for operation '<>' +SET NAMES cp1250 COLLATE cp1250_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1250_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1250_ch.test b/mysql-test/main/ctype_cp1250_ch.test index 0bbe4cafca6..c653130367c 100644 --- a/mysql-test/main/ctype_cp1250_ch.test +++ b/mysql-test/main/ctype_cp1250_ch.test @@ -114,3 +114,18 @@ set names cp1250 collate cp1250_czech_cs; --echo # End of 5.6 tests --echo # + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp1250 COLLATE cp1250_czech_cs; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc +SET NAMES cp1250 COLLATE cp1250_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1251.result b/mysql-test/main/ctype_cp1251.result index 9a77f986349..3c77d3004b4 100644 --- a/mysql-test/main/ctype_cp1251.result +++ b/mysql-test/main/ctype_cp1251.result @@ -3425,3 +3425,71 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp1251 COLLATE cp1251_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1251 COLLATE cp1251_bulgarian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1251 COLLATE cp1251_ukrainian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1251_ukrainian_ci,COERCIBLE) for operation '<>' +SET NAMES cp1251 COLLATE cp1251_general_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1251_general_cs,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1251_general_cs,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1251_general_cs,COERCIBLE) for operation '<>' +SET NAMES cp1251 COLLATE cp1251_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1251_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1251.test b/mysql-test/main/ctype_cp1251.test index 97978463407..71370c0c31e 100644 --- a/mysql-test/main/ctype_cp1251.test +++ b/mysql-test/main/ctype_cp1251.test @@ -143,3 +143,33 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp1251 COLLATE cp1251_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1251 COLLATE cp1251_bulgarian_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1251 COLLATE cp1251_ukrainian_ci; +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES cp1251 COLLATE cp1251_general_cs; +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES cp1251 COLLATE cp1251_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection + +SET NAMES DEFAULT; + + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1256.result b/mysql-test/main/ctype_cp1256.result new file mode 100644 index 00000000000..70aabde1491 --- /dev/null +++ b/mysql-test/main/ctype_cp1256.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp1256 COLLATE cp1256_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1256 COLLATE cp1256_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1256_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1256.test b/mysql-test/main/ctype_cp1256.test new file mode 100644 index 00000000000..1a42034f9e9 --- /dev/null +++ b/mysql-test/main/ctype_cp1256.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp1256 COLLATE cp1256_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1256 COLLATE cp1256_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1257.result b/mysql-test/main/ctype_cp1257.result new file mode 100644 index 00000000000..c10880e27c2 --- /dev/null +++ b/mysql-test/main/ctype_cp1257.result @@ -0,0 +1,37 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp1257 COLLATE cp1257_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp1257 COLLATE cp1257_lithuanian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1257_lithuanian_ci,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1257_lithuanian_ci,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1257_lithuanian_ci,COERCIBLE) for operation '<>' +SET NAMES cp1257 COLLATE cp1257_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp1257_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp1257.test b/mysql-test/main/ctype_cp1257.test new file mode 100644 index 00000000000..d09be27b28b --- /dev/null +++ b/mysql-test/main/ctype_cp1257.test @@ -0,0 +1,20 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp1257 COLLATE cp1257_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp1257 COLLATE cp1257_lithuanian_ci; +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES cp1257 COLLATE cp1257_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp850.result b/mysql-test/main/ctype_cp850.result index c6aba9d3f4e..8ec91a663fa 100644 --- a/mysql-test/main/ctype_cp850.result +++ b/mysql-test/main/ctype_cp850.result @@ -1062,3 +1062,27 @@ _cp850'' LIKE _cp850'' ESCAPE _cp850 0xFF # # End of 10.2 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp850 COLLATE cp850_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp850 COLLATE cp850_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp850_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp850.test b/mysql-test/main/ctype_cp850.test index d2fac6f3646..fbe00f73520 100644 --- a/mysql-test/main/ctype_cp850.test +++ b/mysql-test/main/ctype_cp850.test @@ -46,3 +46,22 @@ DELIMITER ;$$ --echo # --echo # End of 10.2 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp850 COLLATE cp850_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp850 COLLATE cp850_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp852.result b/mysql-test/main/ctype_cp852.result new file mode 100644 index 00000000000..e3b23c1f530 --- /dev/null +++ b/mysql-test/main/ctype_cp852.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp852 COLLATE cp852_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp852 COLLATE cp852_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp852_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp852.test b/mysql-test/main/ctype_cp852.test new file mode 100644 index 00000000000..76711ef420b --- /dev/null +++ b/mysql-test/main/ctype_cp852.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp852 COLLATE cp852_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp852 COLLATE cp852_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp866.result b/mysql-test/main/ctype_cp866.result index 008f94f3c79..a86e0639690 100644 --- a/mysql-test/main/ctype_cp866.result +++ b/mysql-test/main/ctype_cp866.result @@ -10,3 +10,24 @@ _cp866'' LIKE _cp866'' ESCAPE _cp866 0xFF # # End of 10.2 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp866 COLLATE cp866_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp866_general_ci,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp866_general_ci,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp866_general_ci,COERCIBLE) for operation '<>' +SET NAMES cp866 COLLATE cp866_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp866_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp866.test b/mysql-test/main/ctype_cp866.test index cdc694d2fc7..29406bbaa3b 100644 --- a/mysql-test/main/ctype_cp866.test +++ b/mysql-test/main/ctype_cp866.test @@ -12,3 +12,21 @@ SELECT _cp866'' LIKE _cp866'' ESCAPE _cp866 0xFF; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp866 COLLATE cp866_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES cp866 COLLATE cp866_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp932.result b/mysql-test/main/ctype_cp932.result index f80989b5529..8d3bc647af7 100644 --- a/mysql-test/main/ctype_cp932.result +++ b/mysql-test/main/ctype_cp932.result @@ -939,3 +939,49 @@ c1 # # End of 10.5 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES cp932 COLLATE cp932_japanese_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES cp932 COLLATE cp932_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp932_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# +# MDEV-41246 ExtractValue() and UpdateXML() return a string, so they +# must not use the tailoring-based collation aggregation, which is only +# intended for comparison operators. +# +SET NAMES latin1; +SELECT COLLATION(ExtractValue(_cp932'x', _latin1'a')); +ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'extractvalue' +SELECT COLLATION(ExtractValue(_latin1'x', _cp932'a')); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (cp932_japanese_ci,COERCIBLE) for operation 'extractvalue' +SELECT COLLATION(UpdateXML(_latin1'x', _cp932'/a', _cp932'y')); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (cp932_japanese_ci,COERCIBLE), (cp932_japanese_ci,COERCIBLE) for operation 'updatexml' +SELECT COLLATION(UpdateXML(_cp932'x', _latin1'/a', _latin1'y')); +ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'updatexml' +# Same character set arguments still work +SELECT ExtractValue(_cp932'x', _cp932'/a'); +ExtractValue(_cp932'x', _cp932'/a') +x +SELECT UpdateXML(_latin1'x', _latin1'/a', _latin1'y'); +UpdateXML(_latin1'x', _latin1'/a', _latin1'y') +y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_cp932.test b/mysql-test/main/ctype_cp932.test index b340461b74f..d72fddf29c4 100644 --- a/mysql-test/main/ctype_cp932.test +++ b/mysql-test/main/ctype_cp932.test @@ -80,3 +80,43 @@ select strcmp(_cp932'' collate cp932_nopad_bin, _cp932 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES cp932 COLLATE cp932_japanese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES cp932 COLLATE cp932_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # +--echo # MDEV-41246 ExtractValue() and UpdateXML() return a string, so they +--echo # must not use the tailoring-based collation aggregation, which is only +--echo # intended for comparison operators. +--echo # + +SET NAMES latin1; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT COLLATION(ExtractValue(_cp932'x', _latin1'a')); +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT COLLATION(ExtractValue(_latin1'x', _cp932'a')); +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT COLLATION(UpdateXML(_latin1'x', _cp932'/a', _cp932'y')); +--error ER_CANT_AGGREGATE_3COLLATIONS +SELECT COLLATION(UpdateXML(_cp932'x', _latin1'/a', _latin1'y')); + +--echo # Same character set arguments still work +SELECT ExtractValue(_cp932'x', _cp932'/a'); +SELECT UpdateXML(_latin1'x', _latin1'/a', _latin1'y'); +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_cp932_tailoring.result b/mysql-test/main/ctype_cp932_tailoring.result new file mode 100644 index 00000000000..7bdcb6159e0 --- /dev/null +++ b/mysql-test/main/ctype_cp932_tailoring.result @@ -0,0 +1,1373 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +cp932_bin cp932_bin 0 0 000 cl1 = cl2 +cp932_japanese_ci cp932_japanese_ci 0 0 000 cl1 = cl2 +cp932_japanese_nopad_ci cp932_japanese_nopad_ci 0 0 000 cl1 = cl2 +cp932_nopad_bin cp932_nopad_bin 0 0 000 cl1 = cl2 +cp932_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_japanese_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs cp932_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +cp932_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +cp932_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +cp932_nopad_bin cp932_bin 1 1 030 nopad vs pad +cp932_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin1_bin 1 1 030 nopad vs pad +cp932_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +cp932_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin5_bin 1 1 030 nopad vs pad +cp932_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin cp932_bin 1 1 030 nopad vs pad +latin1_nopad_bin cp932_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci cp932_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin cp932_bin 1 1 030 nopad vs pad +swe7_nopad_bin cp932_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci cp932_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +cp932_bin cp932_nopad_bin 1 1 030 pad vs nopad +cp932_bin latin1_nopad_bin 1 1 030 pad vs nopad +cp932_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_bin swe7_nopad_bin 1 1 030 pad vs nopad +cp932_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +cp932_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +cp932_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin1_bin cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin cp932_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs cp932_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin5_bin cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin cp932_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci cp932_nopad_bin 1 1 030 pad vs nopad +cp932_bin hp8_english_ci 0 0 100 equal tailoring +cp932_bin latin1_bin 0 0 100 equal tailoring +cp932_bin latin1_general_cs 0 0 100 equal tailoring +cp932_bin latin1_german1_ci 0 0 100 equal tailoring +cp932_bin latin1_swedish_ci 0 0 100 equal tailoring +cp932_bin latin5_bin 0 0 100 equal tailoring +cp932_bin latin5_turkish_ci 0 0 100 equal tailoring +cp932_japanese_ci hp8_english_ci 0 0 100 equal tailoring +cp932_japanese_ci latin1_bin 0 0 100 equal tailoring +cp932_japanese_ci latin1_general_cs 0 0 100 equal tailoring +cp932_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +cp932_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +cp932_japanese_ci latin5_bin 0 0 100 equal tailoring +cp932_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +cp932_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +cp932_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +cp932_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +cp932_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +cp932_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +cp932_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +cp932_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +cp932_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci cp932_bin 0 0 100 equal tailoring +hp8_english_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_bin cp932_bin 0 0 100 equal tailoring +latin1_bin cp932_japanese_ci 0 0 100 equal tailoring +latin1_general_cs cp932_bin 0 0 100 equal tailoring +latin1_general_cs cp932_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci cp932_bin 0 0 100 equal tailoring +latin1_german1_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin cp932_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin cp932_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci cp932_bin 0 0 100 equal tailoring +latin1_swedish_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci cp932_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci cp932_nopad_bin 0 0 100 equal tailoring +latin5_bin cp932_bin 0 0 100 equal tailoring +latin5_bin cp932_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci cp932_bin 0 0 100 equal tailoring +latin5_turkish_ci cp932_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin cp932_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin cp932_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci cp932_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci cp932_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +cp932_bin cp932_bin 0 0 000 cl1 = cl2 +cp932_japanese_ci cp932_japanese_ci 0 0 000 cl1 = cl2 +cp932_japanese_nopad_ci cp932_japanese_nopad_ci 0 0 000 cl1 = cl2 +cp932_nopad_bin cp932_nopad_bin 0 0 000 cl1 = cl2 +cp932_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_japanese_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs cp932_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +cp932_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +cp932_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +cp932_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +cp932_nopad_bin cp932_bin 1 1 030 nopad vs pad +cp932_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin1_bin 1 1 030 nopad vs pad +cp932_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +cp932_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +cp932_nopad_bin latin5_bin 1 1 030 nopad vs pad +cp932_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin cp932_bin 1 1 030 nopad vs pad +latin1_nopad_bin cp932_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci cp932_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin cp932_bin 1 1 030 nopad vs pad +swe7_nopad_bin cp932_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci cp932_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci cp932_japanese_ci 1 1 030 nopad vs pad +cp932_bin cp932_nopad_bin 1 1 030 pad vs nopad +cp932_bin latin1_nopad_bin 1 1 030 pad vs nopad +cp932_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_bin swe7_nopad_bin 1 1 030 pad vs nopad +cp932_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +cp932_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +cp932_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +cp932_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin1_bin cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin cp932_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs cp932_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci cp932_nopad_bin 1 1 030 pad vs nopad +latin5_bin cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin cp932_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci cp932_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci cp932_nopad_bin 1 1 030 pad vs nopad +cp932_bin hp8_english_ci 0 0 100 equal tailoring +cp932_bin latin1_bin 0 0 100 equal tailoring +cp932_bin latin1_general_cs 0 0 100 equal tailoring +cp932_bin latin1_german1_ci 0 0 100 equal tailoring +cp932_bin latin1_swedish_ci 0 0 100 equal tailoring +cp932_bin latin5_bin 0 0 100 equal tailoring +cp932_bin latin5_turkish_ci 0 0 100 equal tailoring +cp932_japanese_ci hp8_english_ci 0 0 100 equal tailoring +cp932_japanese_ci latin1_bin 0 0 100 equal tailoring +cp932_japanese_ci latin1_general_cs 0 0 100 equal tailoring +cp932_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +cp932_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +cp932_japanese_ci latin5_bin 0 0 100 equal tailoring +cp932_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +cp932_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +cp932_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +cp932_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +cp932_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +cp932_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +cp932_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +cp932_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +cp932_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci cp932_bin 0 0 100 equal tailoring +hp8_english_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_bin cp932_bin 0 0 100 equal tailoring +latin1_bin cp932_japanese_ci 0 0 100 equal tailoring +latin1_general_cs cp932_bin 0 0 100 equal tailoring +latin1_general_cs cp932_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci cp932_bin 0 0 100 equal tailoring +latin1_german1_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin cp932_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin cp932_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci cp932_bin 0 0 100 equal tailoring +latin1_swedish_ci cp932_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci cp932_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci cp932_nopad_bin 0 0 100 equal tailoring +latin5_bin cp932_bin 0 0 100 equal tailoring +latin5_bin cp932_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci cp932_bin 0 0 100 equal tailoring +latin5_turkish_ci cp932_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin cp932_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin cp932_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci cp932_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci cp932_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +cp932_bin cp932_bin 0 0 000 cl1 = cl2 +cp932_japanese_ci cp932_japanese_ci 0 0 000 cl1 = cl2 +cp932_japanese_nopad_ci cp932_japanese_nopad_ci 0 0 000 cl1 = cl2 +cp932_nopad_bin cp932_nopad_bin 0 0 000 cl1 = cl2 +cp932_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_ci 0 0 002 LEFT sameCS_bin +cp932_nopad_bin cp932_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +cp932_japanese_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_bin 0 0 002 RIGHT sameCS_bin +cp932_japanese_nopad_ci cp932_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs cp932_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci cp932_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci cp932_nopad_bin 0 0 003 LEFT superset +cp932_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +cp932_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci cp932_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci cp932_nopad_bin 0 0 004 LEFT superset +cp932_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +cp932_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +cp932_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES dec8 COLLATE dec8_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (dec8_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_dec8.test b/mysql-test/main/ctype_dec8.test index 869d6242225..b0db0a90e3c 100644 --- a/mysql-test/main/ctype_dec8.test +++ b/mysql-test/main/ctype_dec8.test @@ -13,3 +13,22 @@ SET @seq=_dec8 0xD0; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES dec8 COLLATE dec8_swedish_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES dec8 COLLATE dec8_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_eucjpms.result b/mysql-test/main/ctype_eucjpms.result index d65c942f1c4..64752a1baaa 100644 --- a/mysql-test/main/ctype_eucjpms.result +++ b/mysql-test/main/ctype_eucjpms.result @@ -34833,3 +34833,27 @@ c1 # # End of 10.5 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES eucjpms COLLATE eucjpms_japanese_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES eucjpms COLLATE eucjpms_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (eucjpms_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_eucjpms.test b/mysql-test/main/ctype_eucjpms.test index 370b4a77328..808e295ea66 100644 --- a/mysql-test/main/ctype_eucjpms.test +++ b/mysql-test/main/ctype_eucjpms.test @@ -630,3 +630,22 @@ select strcmp(_eucjpms'' collate eucjpms_nopad_bin, _eucjpms 0x0001050001) as c1 --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES eucjpms COLLATE eucjpms_japanese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES eucjpms COLLATE eucjpms_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_eucjpms_tailoring.result b/mysql-test/main/ctype_eucjpms_tailoring.result new file mode 100644 index 00000000000..a882b305633 --- /dev/null +++ b/mysql-test/main/ctype_eucjpms_tailoring.result @@ -0,0 +1,1303 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +eucjpms_bin eucjpms_bin 0 0 000 cl1 = cl2 +eucjpms_japanese_ci eucjpms_japanese_ci 0 0 000 cl1 = cl2 +eucjpms_japanese_nopad_ci eucjpms_japanese_nopad_ci 0 0 000 cl1 = cl2 +eucjpms_nopad_bin eucjpms_nopad_bin 0 0 000 cl1 = cl2 +eucjpms_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_japanese_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs eucjpms_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +eucjpms_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +eucjpms_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin5_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +latin1_nopad_bin eucjpms_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci eucjpms_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +swe7_nopad_bin eucjpms_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci eucjpms_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +eucjpms_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin latin1_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_bin swe7_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +eucjpms_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +eucjpms_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_bin eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin5_bin eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin hp8_english_ci 0 0 100 equal tailoring +eucjpms_bin latin1_bin 0 0 100 equal tailoring +eucjpms_bin latin1_general_cs 0 0 100 equal tailoring +eucjpms_bin latin1_german1_ci 0 0 100 equal tailoring +eucjpms_bin latin1_swedish_ci 0 0 100 equal tailoring +eucjpms_bin latin5_bin 0 0 100 equal tailoring +eucjpms_bin latin5_turkish_ci 0 0 100 equal tailoring +eucjpms_japanese_ci hp8_english_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_bin 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_general_cs 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin5_bin 0 0 100 equal tailoring +eucjpms_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +eucjpms_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +eucjpms_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci eucjpms_bin 0 0 100 equal tailoring +hp8_english_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_bin eucjpms_bin 0 0 100 equal tailoring +latin1_bin eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_general_cs eucjpms_bin 0 0 100 equal tailoring +latin1_general_cs eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci eucjpms_bin 0 0 100 equal tailoring +latin1_german1_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin eucjpms_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci eucjpms_bin 0 0 100 equal tailoring +latin1_swedish_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci eucjpms_nopad_bin 0 0 100 equal tailoring +latin5_bin eucjpms_bin 0 0 100 equal tailoring +latin5_bin eucjpms_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci eucjpms_bin 0 0 100 equal tailoring +latin5_turkish_ci eucjpms_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin eucjpms_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci eucjpms_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +eucjpms_bin eucjpms_bin 0 0 000 cl1 = cl2 +eucjpms_japanese_ci eucjpms_japanese_ci 0 0 000 cl1 = cl2 +eucjpms_japanese_nopad_ci eucjpms_japanese_nopad_ci 0 0 000 cl1 = cl2 +eucjpms_nopad_bin eucjpms_nopad_bin 0 0 000 cl1 = cl2 +eucjpms_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_japanese_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs eucjpms_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +eucjpms_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +eucjpms_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +eucjpms_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +eucjpms_nopad_bin latin5_bin 1 1 030 nopad vs pad +eucjpms_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +latin1_nopad_bin eucjpms_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci eucjpms_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin eucjpms_bin 1 1 030 nopad vs pad +swe7_nopad_bin eucjpms_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci eucjpms_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci eucjpms_japanese_ci 1 1 030 nopad vs pad +eucjpms_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin latin1_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_bin swe7_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +eucjpms_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +eucjpms_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +eucjpms_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_bin eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +latin5_bin eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin eucjpms_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci eucjpms_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci eucjpms_nopad_bin 1 1 030 pad vs nopad +eucjpms_bin hp8_english_ci 0 0 100 equal tailoring +eucjpms_bin latin1_bin 0 0 100 equal tailoring +eucjpms_bin latin1_general_cs 0 0 100 equal tailoring +eucjpms_bin latin1_german1_ci 0 0 100 equal tailoring +eucjpms_bin latin1_swedish_ci 0 0 100 equal tailoring +eucjpms_bin latin5_bin 0 0 100 equal tailoring +eucjpms_bin latin5_turkish_ci 0 0 100 equal tailoring +eucjpms_japanese_ci hp8_english_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_bin 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_general_cs 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +eucjpms_japanese_ci latin5_bin 0 0 100 equal tailoring +eucjpms_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +eucjpms_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +eucjpms_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +eucjpms_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +eucjpms_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci eucjpms_bin 0 0 100 equal tailoring +hp8_english_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_bin eucjpms_bin 0 0 100 equal tailoring +latin1_bin eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_general_cs eucjpms_bin 0 0 100 equal tailoring +latin1_general_cs eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci eucjpms_bin 0 0 100 equal tailoring +latin1_german1_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin eucjpms_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci eucjpms_bin 0 0 100 equal tailoring +latin1_swedish_ci eucjpms_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci eucjpms_nopad_bin 0 0 100 equal tailoring +latin5_bin eucjpms_bin 0 0 100 equal tailoring +latin5_bin eucjpms_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci eucjpms_bin 0 0 100 equal tailoring +latin5_turkish_ci eucjpms_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin eucjpms_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci eucjpms_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci eucjpms_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +eucjpms_bin eucjpms_bin 0 0 000 cl1 = cl2 +eucjpms_japanese_ci eucjpms_japanese_ci 0 0 000 cl1 = cl2 +eucjpms_japanese_nopad_ci eucjpms_japanese_nopad_ci 0 0 000 cl1 = cl2 +eucjpms_nopad_bin eucjpms_nopad_bin 0 0 000 cl1 = cl2 +eucjpms_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_ci 0 0 002 LEFT sameCS_bin +eucjpms_nopad_bin eucjpms_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +eucjpms_japanese_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_bin 0 0 002 RIGHT sameCS_bin +eucjpms_japanese_nopad_ci eucjpms_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs eucjpms_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci eucjpms_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci eucjpms_nopad_bin 0 0 003 LEFT superset +eucjpms_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +eucjpms_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci eucjpms_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci eucjpms_nopad_bin 0 0 004 LEFT superset +eucjpms_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +eucjpms_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +eucjpms_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES euckr COLLATE euckr_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (euckr_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_euckr.test b/mysql-test/main/ctype_euckr.test index 596a079932a..d768cad5ef6 100644 --- a/mysql-test/main/ctype_euckr.test +++ b/mysql-test/main/ctype_euckr.test @@ -260,3 +260,22 @@ select strcmp(_euckr'' collate euckr_nopad_bin, _euckr 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES euckr COLLATE euckr_korean_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES euckr COLLATE euckr_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_euckr_tailoring.result b/mysql-test/main/ctype_euckr_tailoring.result new file mode 100644 index 00000000000..a9e3fb8f195 --- /dev/null +++ b/mysql-test/main/ctype_euckr_tailoring.result @@ -0,0 +1,1303 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +euckr_bin euckr_bin 0 0 000 cl1 = cl2 +euckr_korean_ci euckr_korean_ci 0 0 000 cl1 = cl2 +euckr_korean_nopad_ci euckr_korean_nopad_ci 0 0 000 cl1 = cl2 +euckr_nopad_bin euckr_nopad_bin 0 0 000 cl1 = cl2 +euckr_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_korean_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs euckr_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +euckr_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +euckr_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_bin 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin5_bin 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +euckr_nopad_bin euckr_bin 1 1 030 nopad vs pad +euckr_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin1_bin 1 1 030 nopad vs pad +euckr_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +euckr_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin5_bin 1 1 030 nopad vs pad +euckr_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin euckr_bin 1 1 030 nopad vs pad +latin1_nopad_bin euckr_korean_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci euckr_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +swe7_nopad_bin euckr_bin 1 1 030 nopad vs pad +swe7_nopad_bin euckr_korean_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci euckr_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +euckr_bin euckr_nopad_bin 1 1 030 pad vs nopad +euckr_bin latin1_nopad_bin 1 1 030 pad vs nopad +euckr_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_bin swe7_nopad_bin 1 1 030 pad vs nopad +euckr_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci latin1_nopad_bin 1 1 030 pad vs nopad +euckr_korean_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci swe7_nopad_bin 1 1 030 pad vs nopad +euckr_korean_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin1_bin euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_bin euckr_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs euckr_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin5_bin euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin5_bin euckr_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci euckr_nopad_bin 1 1 030 pad vs nopad +euckr_bin hp8_english_ci 0 0 100 equal tailoring +euckr_bin latin1_bin 0 0 100 equal tailoring +euckr_bin latin1_general_cs 0 0 100 equal tailoring +euckr_bin latin1_german1_ci 0 0 100 equal tailoring +euckr_bin latin1_swedish_ci 0 0 100 equal tailoring +euckr_bin latin5_bin 0 0 100 equal tailoring +euckr_bin latin5_turkish_ci 0 0 100 equal tailoring +euckr_korean_ci hp8_english_ci 0 0 100 equal tailoring +euckr_korean_ci latin1_bin 0 0 100 equal tailoring +euckr_korean_ci latin1_general_cs 0 0 100 equal tailoring +euckr_korean_ci latin1_german1_ci 0 0 100 equal tailoring +euckr_korean_ci latin1_swedish_ci 0 0 100 equal tailoring +euckr_korean_ci latin5_bin 0 0 100 equal tailoring +euckr_korean_ci latin5_turkish_ci 0 0 100 equal tailoring +euckr_korean_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +euckr_korean_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +euckr_korean_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +euckr_korean_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +euckr_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +euckr_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +euckr_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +euckr_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci euckr_bin 0 0 100 equal tailoring +hp8_english_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_bin euckr_bin 0 0 100 equal tailoring +latin1_bin euckr_korean_ci 0 0 100 equal tailoring +latin1_general_cs euckr_bin 0 0 100 equal tailoring +latin1_general_cs euckr_korean_ci 0 0 100 equal tailoring +latin1_german1_ci euckr_bin 0 0 100 equal tailoring +latin1_german1_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_nopad_bin euckr_korean_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin euckr_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci euckr_bin 0 0 100 equal tailoring +latin1_swedish_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci euckr_korean_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci euckr_nopad_bin 0 0 100 equal tailoring +latin5_bin euckr_bin 0 0 100 equal tailoring +latin5_bin euckr_korean_ci 0 0 100 equal tailoring +latin5_turkish_ci euckr_bin 0 0 100 equal tailoring +latin5_turkish_ci euckr_korean_ci 0 0 100 equal tailoring +swe7_nopad_bin euckr_korean_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin euckr_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci euckr_korean_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci euckr_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +euckr_bin euckr_bin 0 0 000 cl1 = cl2 +euckr_korean_ci euckr_korean_ci 0 0 000 cl1 = cl2 +euckr_korean_nopad_ci euckr_korean_nopad_ci 0 0 000 cl1 = cl2 +euckr_nopad_bin euckr_nopad_bin 0 0 000 cl1 = cl2 +euckr_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_korean_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs euckr_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +euckr_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +euckr_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_bin 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin5_bin 1 1 030 nopad vs pad +euckr_korean_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +euckr_nopad_bin euckr_bin 1 1 030 nopad vs pad +euckr_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin1_bin 1 1 030 nopad vs pad +euckr_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +euckr_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +euckr_nopad_bin latin5_bin 1 1 030 nopad vs pad +euckr_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin euckr_bin 1 1 030 nopad vs pad +latin1_nopad_bin euckr_korean_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci euckr_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +swe7_nopad_bin euckr_bin 1 1 030 nopad vs pad +swe7_nopad_bin euckr_korean_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci euckr_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci euckr_korean_ci 1 1 030 nopad vs pad +euckr_bin euckr_nopad_bin 1 1 030 pad vs nopad +euckr_bin latin1_nopad_bin 1 1 030 pad vs nopad +euckr_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_bin swe7_nopad_bin 1 1 030 pad vs nopad +euckr_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci latin1_nopad_bin 1 1 030 pad vs nopad +euckr_korean_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +euckr_korean_ci swe7_nopad_bin 1 1 030 pad vs nopad +euckr_korean_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin1_bin euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_bin euckr_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs euckr_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci euckr_nopad_bin 1 1 030 pad vs nopad +latin5_bin euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin5_bin euckr_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci euckr_korean_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci euckr_nopad_bin 1 1 030 pad vs nopad +euckr_bin hp8_english_ci 0 0 100 equal tailoring +euckr_bin latin1_bin 0 0 100 equal tailoring +euckr_bin latin1_general_cs 0 0 100 equal tailoring +euckr_bin latin1_german1_ci 0 0 100 equal tailoring +euckr_bin latin1_swedish_ci 0 0 100 equal tailoring +euckr_bin latin5_bin 0 0 100 equal tailoring +euckr_bin latin5_turkish_ci 0 0 100 equal tailoring +euckr_korean_ci hp8_english_ci 0 0 100 equal tailoring +euckr_korean_ci latin1_bin 0 0 100 equal tailoring +euckr_korean_ci latin1_general_cs 0 0 100 equal tailoring +euckr_korean_ci latin1_german1_ci 0 0 100 equal tailoring +euckr_korean_ci latin1_swedish_ci 0 0 100 equal tailoring +euckr_korean_ci latin5_bin 0 0 100 equal tailoring +euckr_korean_ci latin5_turkish_ci 0 0 100 equal tailoring +euckr_korean_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +euckr_korean_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +euckr_korean_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +euckr_korean_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +euckr_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +euckr_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +euckr_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +euckr_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci euckr_bin 0 0 100 equal tailoring +hp8_english_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_bin euckr_bin 0 0 100 equal tailoring +latin1_bin euckr_korean_ci 0 0 100 equal tailoring +latin1_general_cs euckr_bin 0 0 100 equal tailoring +latin1_general_cs euckr_korean_ci 0 0 100 equal tailoring +latin1_german1_ci euckr_bin 0 0 100 equal tailoring +latin1_german1_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_nopad_bin euckr_korean_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin euckr_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci euckr_bin 0 0 100 equal tailoring +latin1_swedish_ci euckr_korean_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci euckr_korean_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci euckr_nopad_bin 0 0 100 equal tailoring +latin5_bin euckr_bin 0 0 100 equal tailoring +latin5_bin euckr_korean_ci 0 0 100 equal tailoring +latin5_turkish_ci euckr_bin 0 0 100 equal tailoring +latin5_turkish_ci euckr_korean_ci 0 0 100 equal tailoring +swe7_nopad_bin euckr_korean_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin euckr_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci euckr_korean_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci euckr_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +euckr_bin euckr_bin 0 0 000 cl1 = cl2 +euckr_korean_ci euckr_korean_ci 0 0 000 cl1 = cl2 +euckr_korean_nopad_ci euckr_korean_nopad_ci 0 0 000 cl1 = cl2 +euckr_nopad_bin euckr_nopad_bin 0 0 000 cl1 = cl2 +euckr_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_ci 0 0 002 LEFT sameCS_bin +euckr_nopad_bin euckr_korean_nopad_ci 0 0 002 LEFT sameCS_bin +euckr_korean_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_bin 0 0 002 RIGHT sameCS_bin +euckr_korean_nopad_ci euckr_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs euckr_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci euckr_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_korean_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci euckr_nopad_bin 0 0 003 LEFT superset +euckr_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_korean_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +euckr_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci euckr_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_korean_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci euckr_nopad_bin 0 0 004 LEFT superset +euckr_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_korean_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +euckr_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +euckr_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gb2312_chinese_ci,COERCIBLE) for operation '<>' +SET NAMES gb2312 COLLATE gb2312_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gb2312_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_gb2312.test b/mysql-test/main/ctype_gb2312.test index 50b530a1d78..4ee8ce732d2 100644 --- a/mysql-test/main/ctype_gb2312.test +++ b/mysql-test/main/ctype_gb2312.test @@ -210,3 +210,22 @@ select strcmp(_gb2312'' collate gb2312_nopad_bin, _gb2312 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES gb2312 COLLATE gb2312_chinese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES gb2312 COLLATE gb2312_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_gb2312_tailoring.result b/mysql-test/main/ctype_gb2312_tailoring.result new file mode 100644 index 00000000000..b4bfad19bdc --- /dev/null +++ b/mysql-test/main/ctype_gb2312_tailoring.result @@ -0,0 +1,1309 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gb2312_bin gb2312_bin 0 0 000 cl1 = cl2 +gb2312_chinese_ci gb2312_chinese_ci 0 0 000 cl1 = cl2 +gb2312_chinese_nopad_ci gb2312_chinese_nopad_ci 0 0 000 cl1 = cl2 +gb2312_nopad_bin gb2312_nopad_bin 0 0 000 cl1 = cl2 +gb2312_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_chinese_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gb2312_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +gb2312_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +gb2312_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +gb2312_nopad_bin gb2312_bin 1 1 030 nopad vs pad +gb2312_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_bin 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin5_bin 1 1 030 nopad vs pad +gb2312_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin gb2312_bin 1 1 030 nopad vs pad +latin1_nopad_bin gb2312_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gb2312_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin gb2312_bin 1 1 030 nopad vs pad +swe7_nopad_bin gb2312_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gb2312_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +gb2312_bin gb2312_nopad_bin 1 1 030 pad vs nopad +gb2312_bin latin1_nopad_bin 1 1 030 pad vs nopad +gb2312_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_bin swe7_nopad_bin 1 1 030 pad vs nopad +gb2312_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +gb2312_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +gb2312_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_bin gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin5_bin gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin gb2312_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci gb2312_nopad_bin 1 1 030 pad vs nopad +gb2312_bin hp8_english_ci 0 0 100 equal tailoring +gb2312_bin latin1_bin 0 0 100 equal tailoring +gb2312_bin latin1_general_cs 0 0 100 equal tailoring +gb2312_bin latin1_german1_ci 0 0 100 equal tailoring +gb2312_bin latin1_swedish_ci 0 0 100 equal tailoring +gb2312_bin latin5_bin 0 0 100 equal tailoring +gb2312_bin latin5_turkish_ci 0 0 100 equal tailoring +gb2312_chinese_ci hp8_english_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin1_bin 0 0 100 equal tailoring +gb2312_chinese_ci latin1_general_cs 0 0 100 equal tailoring +gb2312_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin5_bin 0 0 100 equal tailoring +gb2312_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +gb2312_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +gb2312_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +gb2312_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +gb2312_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +gb2312_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci gb2312_bin 0 0 100 equal tailoring +hp8_english_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_bin gb2312_bin 0 0 100 equal tailoring +latin1_bin gb2312_chinese_ci 0 0 100 equal tailoring +latin1_general_cs gb2312_bin 0 0 100 equal tailoring +latin1_general_cs gb2312_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci gb2312_bin 0 0 100 equal tailoring +latin1_german1_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin gb2312_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin gb2312_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci gb2312_bin 0 0 100 equal tailoring +latin1_swedish_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gb2312_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gb2312_nopad_bin 0 0 100 equal tailoring +latin5_bin gb2312_bin 0 0 100 equal tailoring +latin5_bin gb2312_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci gb2312_bin 0 0 100 equal tailoring +latin5_turkish_ci gb2312_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin gb2312_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin gb2312_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci gb2312_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci gb2312_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gb2312_bin gb2312_bin 0 0 000 cl1 = cl2 +gb2312_chinese_ci gb2312_chinese_ci 0 0 000 cl1 = cl2 +gb2312_chinese_nopad_ci gb2312_chinese_nopad_ci 0 0 000 cl1 = cl2 +gb2312_nopad_bin gb2312_nopad_bin 0 0 000 cl1 = cl2 +gb2312_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_chinese_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gb2312_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +gb2312_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +gb2312_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +gb2312_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +gb2312_nopad_bin gb2312_bin 1 1 030 nopad vs pad +gb2312_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_bin 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +gb2312_nopad_bin latin5_bin 1 1 030 nopad vs pad +gb2312_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin gb2312_bin 1 1 030 nopad vs pad +latin1_nopad_bin gb2312_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gb2312_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin gb2312_bin 1 1 030 nopad vs pad +swe7_nopad_bin gb2312_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gb2312_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gb2312_chinese_ci 1 1 030 nopad vs pad +gb2312_bin gb2312_nopad_bin 1 1 030 pad vs nopad +gb2312_bin latin1_nopad_bin 1 1 030 pad vs nopad +gb2312_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_bin swe7_nopad_bin 1 1 030 pad vs nopad +gb2312_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +gb2312_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gb2312_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +gb2312_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_bin gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci gb2312_nopad_bin 1 1 030 pad vs nopad +latin5_bin gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin gb2312_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci gb2312_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci gb2312_nopad_bin 1 1 030 pad vs nopad +gb2312_bin hp8_english_ci 0 0 100 equal tailoring +gb2312_bin latin1_bin 0 0 100 equal tailoring +gb2312_bin latin1_general_cs 0 0 100 equal tailoring +gb2312_bin latin1_german1_ci 0 0 100 equal tailoring +gb2312_bin latin1_swedish_ci 0 0 100 equal tailoring +gb2312_bin latin5_bin 0 0 100 equal tailoring +gb2312_bin latin5_turkish_ci 0 0 100 equal tailoring +gb2312_chinese_ci hp8_english_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin1_bin 0 0 100 equal tailoring +gb2312_chinese_ci latin1_general_cs 0 0 100 equal tailoring +gb2312_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +gb2312_chinese_ci latin5_bin 0 0 100 equal tailoring +gb2312_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +gb2312_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +gb2312_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +gb2312_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +gb2312_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +gb2312_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +gb2312_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci gb2312_bin 0 0 100 equal tailoring +hp8_english_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_bin gb2312_bin 0 0 100 equal tailoring +latin1_bin gb2312_chinese_ci 0 0 100 equal tailoring +latin1_general_cs gb2312_bin 0 0 100 equal tailoring +latin1_general_cs gb2312_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci gb2312_bin 0 0 100 equal tailoring +latin1_german1_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin gb2312_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin gb2312_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci gb2312_bin 0 0 100 equal tailoring +latin1_swedish_ci gb2312_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gb2312_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gb2312_nopad_bin 0 0 100 equal tailoring +latin5_bin gb2312_bin 0 0 100 equal tailoring +latin5_bin gb2312_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci gb2312_bin 0 0 100 equal tailoring +latin5_turkish_ci gb2312_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin gb2312_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin gb2312_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci gb2312_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci gb2312_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gb2312_bin gb2312_bin 0 0 000 cl1 = cl2 +gb2312_chinese_ci gb2312_chinese_ci 0 0 000 cl1 = cl2 +gb2312_chinese_nopad_ci gb2312_chinese_nopad_ci 0 0 000 cl1 = cl2 +gb2312_nopad_bin gb2312_nopad_bin 0 0 000 cl1 = cl2 +gb2312_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_ci 0 0 002 LEFT sameCS_bin +gb2312_nopad_bin gb2312_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gb2312_chinese_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_bin 0 0 002 RIGHT sameCS_bin +gb2312_chinese_nopad_ci gb2312_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gb2312_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gb2312_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gb2312_nopad_bin 0 0 003 LEFT superset +gb2312_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gb2312_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gb2312_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gb2312_nopad_bin 0 0 004 LEFT superset +gb2312_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gb2312_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gb2312_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation '<>' +SET NAMES gbk COLLATE gbk_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_gbk.test b/mysql-test/main/ctype_gbk.test index c5033555376..02289626643 100644 --- a/mysql-test/main/ctype_gbk.test +++ b/mysql-test/main/ctype_gbk.test @@ -513,3 +513,22 @@ select strcmp(_gbk'' collate gbk_nopad_bin, _gbk 0x0001050001); --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES gbk COLLATE gbk_chinese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES gbk COLLATE gbk_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_gbk_tailoring.result b/mysql-test/main/ctype_gbk_tailoring.result new file mode 100644 index 00000000000..5abe4f1aa36 --- /dev/null +++ b/mysql-test/main/ctype_gbk_tailoring.result @@ -0,0 +1,1309 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gbk_bin gbk_bin 0 0 000 cl1 = cl2 +gbk_chinese_ci gbk_chinese_ci 0 0 000 cl1 = cl2 +gbk_chinese_nopad_ci gbk_chinese_nopad_ci 0 0 000 cl1 = cl2 +gbk_nopad_bin gbk_nopad_bin 0 0 000 cl1 = cl2 +gbk_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_chinese_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gbk_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +gbk_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +gbk_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +gbk_nopad_bin gbk_bin 1 1 030 nopad vs pad +gbk_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin1_bin 1 1 030 nopad vs pad +gbk_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +gbk_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin5_bin 1 1 030 nopad vs pad +gbk_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin gbk_bin 1 1 030 nopad vs pad +latin1_nopad_bin gbk_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gbk_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin gbk_bin 1 1 030 nopad vs pad +swe7_nopad_bin gbk_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gbk_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +gbk_bin gbk_nopad_bin 1 1 030 pad vs nopad +gbk_bin latin1_nopad_bin 1 1 030 pad vs nopad +gbk_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_bin swe7_nopad_bin 1 1 030 pad vs nopad +gbk_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +gbk_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +gbk_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin1_bin gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin gbk_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs gbk_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin5_bin gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin gbk_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci gbk_nopad_bin 1 1 030 pad vs nopad +gbk_bin hp8_english_ci 0 0 100 equal tailoring +gbk_bin latin1_bin 0 0 100 equal tailoring +gbk_bin latin1_general_cs 0 0 100 equal tailoring +gbk_bin latin1_german1_ci 0 0 100 equal tailoring +gbk_bin latin1_swedish_ci 0 0 100 equal tailoring +gbk_bin latin5_bin 0 0 100 equal tailoring +gbk_bin latin5_turkish_ci 0 0 100 equal tailoring +gbk_chinese_ci hp8_english_ci 0 0 100 equal tailoring +gbk_chinese_ci latin1_bin 0 0 100 equal tailoring +gbk_chinese_ci latin1_general_cs 0 0 100 equal tailoring +gbk_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +gbk_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +gbk_chinese_ci latin5_bin 0 0 100 equal tailoring +gbk_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +gbk_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +gbk_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +gbk_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +gbk_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +gbk_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +gbk_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +gbk_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +gbk_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci gbk_bin 0 0 100 equal tailoring +hp8_english_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_bin gbk_bin 0 0 100 equal tailoring +latin1_bin gbk_chinese_ci 0 0 100 equal tailoring +latin1_general_cs gbk_bin 0 0 100 equal tailoring +latin1_general_cs gbk_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci gbk_bin 0 0 100 equal tailoring +latin1_german1_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin gbk_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin gbk_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci gbk_bin 0 0 100 equal tailoring +latin1_swedish_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gbk_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gbk_nopad_bin 0 0 100 equal tailoring +latin5_bin gbk_bin 0 0 100 equal tailoring +latin5_bin gbk_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci gbk_bin 0 0 100 equal tailoring +latin5_turkish_ci gbk_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin gbk_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin gbk_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci gbk_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci gbk_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gbk_bin gbk_bin 0 0 000 cl1 = cl2 +gbk_chinese_ci gbk_chinese_ci 0 0 000 cl1 = cl2 +gbk_chinese_nopad_ci gbk_chinese_nopad_ci 0 0 000 cl1 = cl2 +gbk_nopad_bin gbk_nopad_bin 0 0 000 cl1 = cl2 +gbk_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_chinese_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gbk_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +gbk_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +gbk_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_bin 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin5_bin 1 1 030 nopad vs pad +gbk_chinese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +gbk_nopad_bin gbk_bin 1 1 030 nopad vs pad +gbk_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin1_bin 1 1 030 nopad vs pad +gbk_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +gbk_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +gbk_nopad_bin latin5_bin 1 1 030 nopad vs pad +gbk_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_nopad_bin gbk_bin 1 1 030 nopad vs pad +latin1_nopad_bin gbk_chinese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gbk_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +swe7_nopad_bin gbk_bin 1 1 030 nopad vs pad +swe7_nopad_bin gbk_chinese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gbk_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci gbk_chinese_ci 1 1 030 nopad vs pad +gbk_bin gbk_nopad_bin 1 1 030 pad vs nopad +gbk_bin latin1_nopad_bin 1 1 030 pad vs nopad +gbk_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_bin swe7_nopad_bin 1 1 030 pad vs nopad +gbk_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci latin1_nopad_bin 1 1 030 pad vs nopad +gbk_chinese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +gbk_chinese_ci swe7_nopad_bin 1 1 030 pad vs nopad +gbk_chinese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin1_bin gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_bin gbk_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs gbk_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci gbk_nopad_bin 1 1 030 pad vs nopad +latin5_bin gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_bin gbk_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci gbk_chinese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci gbk_nopad_bin 1 1 030 pad vs nopad +gbk_bin hp8_english_ci 0 0 100 equal tailoring +gbk_bin latin1_bin 0 0 100 equal tailoring +gbk_bin latin1_general_cs 0 0 100 equal tailoring +gbk_bin latin1_german1_ci 0 0 100 equal tailoring +gbk_bin latin1_swedish_ci 0 0 100 equal tailoring +gbk_bin latin5_bin 0 0 100 equal tailoring +gbk_bin latin5_turkish_ci 0 0 100 equal tailoring +gbk_chinese_ci hp8_english_ci 0 0 100 equal tailoring +gbk_chinese_ci latin1_bin 0 0 100 equal tailoring +gbk_chinese_ci latin1_general_cs 0 0 100 equal tailoring +gbk_chinese_ci latin1_german1_ci 0 0 100 equal tailoring +gbk_chinese_ci latin1_swedish_ci 0 0 100 equal tailoring +gbk_chinese_ci latin5_bin 0 0 100 equal tailoring +gbk_chinese_ci latin5_turkish_ci 0 0 100 equal tailoring +gbk_chinese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +gbk_chinese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +gbk_chinese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +gbk_chinese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +gbk_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +gbk_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +gbk_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +gbk_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +hp8_english_ci gbk_bin 0 0 100 equal tailoring +hp8_english_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_bin gbk_bin 0 0 100 equal tailoring +latin1_bin gbk_chinese_ci 0 0 100 equal tailoring +latin1_general_cs gbk_bin 0 0 100 equal tailoring +latin1_general_cs gbk_chinese_ci 0 0 100 equal tailoring +latin1_german1_ci gbk_bin 0 0 100 equal tailoring +latin1_german1_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_nopad_bin gbk_chinese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin gbk_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci gbk_bin 0 0 100 equal tailoring +latin1_swedish_ci gbk_chinese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gbk_chinese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci gbk_nopad_bin 0 0 100 equal tailoring +latin5_bin gbk_bin 0 0 100 equal tailoring +latin5_bin gbk_chinese_ci 0 0 100 equal tailoring +latin5_turkish_ci gbk_bin 0 0 100 equal tailoring +latin5_turkish_ci gbk_chinese_ci 0 0 100 equal tailoring +swe7_nopad_bin gbk_chinese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin gbk_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci gbk_chinese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci gbk_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +gbk_bin gbk_bin 0 0 000 cl1 = cl2 +gbk_chinese_ci gbk_chinese_ci 0 0 000 cl1 = cl2 +gbk_chinese_nopad_ci gbk_chinese_nopad_ci 0 0 000 cl1 = cl2 +gbk_nopad_bin gbk_nopad_bin 0 0 000 cl1 = cl2 +gbk_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_ci 0 0 002 LEFT sameCS_bin +gbk_nopad_bin gbk_chinese_nopad_ci 0 0 002 LEFT sameCS_bin +gbk_chinese_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_bin 0 0 002 RIGHT sameCS_bin +gbk_chinese_nopad_ci gbk_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs gbk_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci gbk_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci gbk_nopad_bin 0 0 003 LEFT superset +gbk_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_chinese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +gbk_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci gbk_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_chinese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci gbk_nopad_bin 0 0 004 LEFT superset +gbk_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_chinese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +gbk_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +gbk_bin latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (geostd8_general_ci,COERCIBLE) for operation '<>' +SET NAMES geostd8 COLLATE geostd8_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (geostd8_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_geostd8.test b/mysql-test/main/ctype_geostd8.test new file mode 100644 index 00000000000..fd95a9d3899 --- /dev/null +++ b/mysql-test/main/ctype_geostd8.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES geostd8 COLLATE geostd8_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES geostd8 COLLATE geostd8_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_greek.result b/mysql-test/main/ctype_greek.result new file mode 100644 index 00000000000..afa1d603096 --- /dev/null +++ b/mysql-test/main/ctype_greek.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES greek COLLATE greek_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES greek COLLATE greek_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (greek_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_greek.test b/mysql-test/main/ctype_greek.test new file mode 100644 index 00000000000..b6a21dce5c9 --- /dev/null +++ b/mysql-test/main/ctype_greek.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES greek COLLATE greek_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES greek COLLATE greek_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_hebrew.result b/mysql-test/main/ctype_hebrew.result index d938b2e47f3..7221fa8231d 100644 --- a/mysql-test/main/ctype_hebrew.result +++ b/mysql-test/main/ctype_hebrew.result @@ -9,3 +9,27 @@ E2808E E2808F DROP TABLE t1; End of 4.1 tests +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES hebrew COLLATE hebrew_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES hebrew COLLATE hebrew_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (hebrew_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_hebrew.test b/mysql-test/main/ctype_hebrew.test index f786d05141d..bebd9ab0833 100644 --- a/mysql-test/main/ctype_hebrew.test +++ b/mysql-test/main/ctype_hebrew.test @@ -14,3 +14,21 @@ SELECT HEX(a) FROM t1; DROP TABLE t1; --echo End of 4.1 tests + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES hebrew COLLATE hebrew_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES hebrew COLLATE hebrew_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_hp8.result b/mysql-test/main/ctype_hp8.result new file mode 100644 index 00000000000..1725dea5c03 --- /dev/null +++ b/mysql-test/main/ctype_hp8.result @@ -0,0 +1,23 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES hp8 COLLATE hp8_english_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (hp8_english_ci,COERCIBLE) for operation '<>' +SET NAMES hp8 COLLATE hp8_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (hp8_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_hp8.test b/mysql-test/main/ctype_hp8.test new file mode 100644 index 00000000000..fd2de7ab4a7 --- /dev/null +++ b/mysql-test/main/ctype_hp8.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES hp8 COLLATE hp8_english_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES hp8 COLLATE hp8_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_keybcs2.result b/mysql-test/main/ctype_keybcs2.result new file mode 100644 index 00000000000..e125d3cc4fd --- /dev/null +++ b/mysql-test/main/ctype_keybcs2.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES keybcs2 COLLATE keybcs2_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES keybcs2 COLLATE keybcs2_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (keybcs2_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_keybcs2.test b/mysql-test/main/ctype_keybcs2.test new file mode 100644 index 00000000000..d4dcb457ba3 --- /dev/null +++ b/mysql-test/main/ctype_keybcs2.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES keybcs2 COLLATE keybcs2_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES keybcs2 COLLATE keybcs2_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_koi8r.result b/mysql-test/main/ctype_koi8r.result new file mode 100644 index 00000000000..0f2d3e9fa71 --- /dev/null +++ b/mysql-test/main/ctype_koi8r.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES koi8r COLLATE koi8r_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES koi8r COLLATE koi8r_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (koi8r_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_koi8r.test b/mysql-test/main/ctype_koi8r.test new file mode 100644 index 00000000000..1fb58004e02 --- /dev/null +++ b/mysql-test/main/ctype_koi8r.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES koi8r COLLATE koi8r_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES koi8r COLLATE koi8r_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_koi8u.result b/mysql-test/main/ctype_koi8u.result new file mode 100644 index 00000000000..cfdbc76a571 --- /dev/null +++ b/mysql-test/main/ctype_koi8u.result @@ -0,0 +1,23 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES koi8u COLLATE koi8u_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (koi8u_general_ci,COERCIBLE) for operation '<>' +SET NAMES koi8u COLLATE koi8u_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (koi8u_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_koi8u.test b/mysql-test/main/ctype_koi8u.test new file mode 100644 index 00000000000..46aab7e560f --- /dev/null +++ b/mysql-test/main/ctype_koi8u.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES koi8u COLLATE koi8u_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES koi8u COLLATE koi8u_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index a496b9270ad..20eaf005459 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -9063,3 +9063,104 @@ Warning 1292 Truncated incorrect INTEGER value: '-9223372036854775809' DROP TABLE t1, t2; SET @@sql_mode= @old_mode; # End of 10.11 tests +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES latin1 COLLATE latin1_swedish_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin1 COLLATE latin1_danish_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin1 COLLATE latin1_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin1 COLLATE latin1_german1_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin1 COLLATE latin1_spanish_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin1 COLLATE latin1_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin1.test b/mysql-test/main/ctype_latin1.test index 56e2d41e6ca..d1123d72f3e 100644 --- a/mysql-test/main/ctype_latin1.test +++ b/mysql-test/main/ctype_latin1.test @@ -579,3 +579,32 @@ DROP TABLE t1, t2; SET @@sql_mode= @old_mode; --echo # End of 10.11 tests + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin1 COLLATE latin1_swedish_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin1 COLLATE latin1_danish_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin1 COLLATE latin1_general_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin1 COLLATE latin1_german1_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin1 COLLATE latin1_spanish_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin1 COLLATE latin1_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin1_de.result b/mysql-test/main/ctype_latin1_de.result index a76e854a13f..2aab0676962 100644 --- a/mysql-test/main/ctype_latin1_de.result +++ b/mysql-test/main/ctype_latin1_de.result @@ -839,3 +839,24 @@ hex(weight_string('x # drop database latin1_german2_ci; use test; +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES latin1 COLLATE latin1_german2_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin1_de.test b/mysql-test/main/ctype_latin1_de.test index 09cbcf0ad87..664992cffee 100644 --- a/mysql-test/main/ctype_latin1_de.test +++ b/mysql-test/main/ctype_latin1_de.test @@ -189,3 +189,16 @@ select hex(weight_string('x drop database latin1_german2_ci; use test; + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin1 COLLATE latin1_german2_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin2.result b/mysql-test/main/ctype_latin2.result index 47169eb025c..664e31576e4 100644 --- a/mysql-test/main/ctype_latin2.result +++ b/mysql-test/main/ctype_latin2.result @@ -844,3 +844,58 @@ DFDF9C9D9E # # End of 5.6 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES latin2 COLLATE latin2_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin2 COLLATE latin2_croatian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES latin2 COLLATE latin2_hungarian_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_hungarian_ci,COERCIBLE) for operation '<>' +SET NAMES latin2 COLLATE latin2_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin2.test b/mysql-test/main/ctype_latin2.test index e71a60a2324..cccbe603dd7 100644 --- a/mysql-test/main/ctype_latin2.test +++ b/mysql-test/main/ctype_latin2.test @@ -74,3 +74,28 @@ set collation_connection=latin2_bin; --echo # --echo # End of 5.6 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin2 COLLATE latin2_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin2 COLLATE latin2_croatian_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES latin2 COLLATE latin2_hungarian_ci; +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES latin2 COLLATE latin2_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin2_ch.result b/mysql-test/main/ctype_latin2_ch.result index 68e763f7eb6..6aea54b8d27 100644 --- a/mysql-test/main/ctype_latin2_ch.result +++ b/mysql-test/main/ctype_latin2_ch.result @@ -1006,3 +1006,20 @@ hex(weight_string('a' LEVEL 1,8)) # # End of 5.6 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES latin2 COLLATE latin2_czech_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_czech_cs,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_czech_cs,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_czech_cs,COERCIBLE) for operation '<>' +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin2_ch.test b/mysql-test/main/ctype_latin2_ch.test index 6d3453ed1fb..f23c1aa5127 100644 --- a/mysql-test/main/ctype_latin2_ch.test +++ b/mysql-test/main/ctype_latin2_ch.test @@ -248,3 +248,17 @@ set names latin2 collate latin2_czech_cs; --echo # End of 5.6 tests --echo # + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin2 COLLATE latin2_czech_cs; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection + + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin5.result b/mysql-test/main/ctype_latin5.result new file mode 100644 index 00000000000..8ece02f01db --- /dev/null +++ b/mysql-test/main/ctype_latin5.result @@ -0,0 +1,38 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES latin5 COLLATE latin5_turkish_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin5_turkish_ci,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin5_turkish_ci,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin5_turkish_ci,COERCIBLE) for operation '<>' +SET NAMES latin5 COLLATE latin5_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin5_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# +# MDEV-41246 LOWER() and UPPER() can convert ASCII letters to +# non-ASCII ones in Turkish collations (I -> dotless i, i -> dotted I), +# so their results are not ASCII-only and are converted to latin5 +# when mixed with a latin1 string, rather than the other way round. +# +SET NAMES latin5 COLLATE latin5_turkish_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +HEX(LOWER('I')) LOWER('I') = _latin1'i' +FD 0 +SELECT HEX(UPPER('i')), UPPER('i') = _latin1'I'; +HEX(UPPER('i')) UPPER('i') = _latin1'I' +DD 0 +SELECT _latin1'i' = LOWER('I'); +_latin1'i' = LOWER('I') +0 +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin5.test b/mysql-test/main/ctype_latin5.test new file mode 100644 index 00000000000..838d9643c09 --- /dev/null +++ b/mysql-test/main/ctype_latin5.test @@ -0,0 +1,29 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin5 COLLATE latin5_turkish_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES latin5 COLLATE latin5_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # +--echo # MDEV-41246 LOWER() and UPPER() can convert ASCII letters to +--echo # non-ASCII ones in Turkish collations (I -> dotless i, i -> dotted I), +--echo # so their results are not ASCII-only and are converted to latin5 +--echo # when mixed with a latin1 string, rather than the other way round. +--echo # +SET NAMES latin5 COLLATE latin5_turkish_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +SELECT HEX(UPPER('i')), UPPER('i') = _latin1'I'; +SELECT _latin1'i' = LOWER('I'); +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_latin5_tailoring.result b/mysql-test/main/ctype_latin5_tailoring.result new file mode 100644 index 00000000000..7b5d32c9ec5 --- /dev/null +++ b/mysql-test/main/ctype_latin5_tailoring.result @@ -0,0 +1,1255 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +latin5_bin latin5_bin 0 0 000 cl1 = cl2 +latin5_nopad_bin latin5_nopad_bin 0 0 000 cl1 = cl2 +latin5_turkish_ci latin5_turkish_ci 0 0 000 cl1 = cl2 +latin5_turkish_nopad_ci latin5_turkish_nopad_ci 0 0 000 cl1 = cl2 +latin5_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_turkish_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs latin5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +latin5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +latin5_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin latin5_bin 1 1 030 nopad vs pad +latin1_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci latin5_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +latin5_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin1_bin 1 1 030 nopad vs pad +latin5_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +latin5_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin5_bin 1 1 030 nopad vs pad +latin5_turkish_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_bin 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +swe7_nopad_bin latin5_bin 1 1 030 nopad vs pad +swe7_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci latin5_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +hp8_english_ci latin5_nopad_bin 1 1 030 pad vs nopad +hp8_english_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_bin latin5_nopad_bin 1 1 030 pad vs nopad +latin1_bin latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs latin5_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci latin5_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci latin5_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin5_bin latin1_nopad_bin 1 1 030 pad vs nopad +latin5_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_bin latin5_nopad_bin 1 1 030 pad vs nopad +latin5_bin swe7_nopad_bin 1 1 030 pad vs nopad +latin5_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci latin1_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci swe7_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci latin5_bin 0 0 100 equal tailoring +hp8_english_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_bin latin5_bin 0 0 100 equal tailoring +latin1_bin latin5_turkish_ci 0 0 100 equal tailoring +latin1_general_cs latin5_bin 0 0 100 equal tailoring +latin1_general_cs latin5_turkish_ci 0 0 100 equal tailoring +latin1_german1_ci latin5_bin 0 0 100 equal tailoring +latin1_german1_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_nopad_bin latin5_nopad_bin 0 0 100 equal tailoring +latin1_nopad_bin latin5_turkish_nopad_ci 0 0 100 equal tailoring +latin1_swedish_ci latin5_bin 0 0 100 equal tailoring +latin1_swedish_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci latin5_nopad_bin 0 0 100 equal tailoring +latin1_swedish_nopad_ci latin5_turkish_nopad_ci 0 0 100 equal tailoring +latin5_bin hp8_english_ci 0 0 100 equal tailoring +latin5_bin latin1_bin 0 0 100 equal tailoring +latin5_bin latin1_general_cs 0 0 100 equal tailoring +latin5_bin latin1_german1_ci 0 0 100 equal tailoring +latin5_bin latin1_swedish_ci 0 0 100 equal tailoring +latin5_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +latin5_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +latin5_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +latin5_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +latin5_turkish_ci hp8_english_ci 0 0 100 equal tailoring +latin5_turkish_ci latin1_bin 0 0 100 equal tailoring +latin5_turkish_ci latin1_general_cs 0 0 100 equal tailoring +latin5_turkish_ci latin1_german1_ci 0 0 100 equal tailoring +latin5_turkish_ci latin1_swedish_ci 0 0 100 equal tailoring +latin5_turkish_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +latin5_turkish_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +latin5_turkish_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +latin5_turkish_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin latin5_nopad_bin 0 0 100 equal tailoring +swe7_nopad_bin latin5_turkish_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci latin5_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci latin5_turkish_nopad_ci 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +latin5_bin latin5_bin 0 0 000 cl1 = cl2 +latin5_nopad_bin latin5_nopad_bin 0 0 000 cl1 = cl2 +latin5_turkish_ci latin5_turkish_ci 0 0 000 cl1 = cl2 +latin5_turkish_nopad_ci latin5_turkish_nopad_ci 0 0 000 cl1 = cl2 +latin5_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_turkish_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs latin5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +latin5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +latin5_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin latin5_bin 1 1 030 nopad vs pad +latin1_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci latin5_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +latin5_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin1_bin 1 1 030 nopad vs pad +latin5_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +latin5_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +latin5_nopad_bin latin5_bin 1 1 030 nopad vs pad +latin5_turkish_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_bin 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +latin5_turkish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +swe7_nopad_bin latin5_bin 1 1 030 nopad vs pad +swe7_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci latin5_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +hp8_english_ci latin5_nopad_bin 1 1 030 pad vs nopad +hp8_english_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_bin latin5_nopad_bin 1 1 030 pad vs nopad +latin1_bin latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs latin5_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci latin5_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci latin5_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin5_bin latin1_nopad_bin 1 1 030 pad vs nopad +latin5_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_bin latin5_nopad_bin 1 1 030 pad vs nopad +latin5_bin swe7_nopad_bin 1 1 030 pad vs nopad +latin5_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci latin1_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci latin5_turkish_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci swe7_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci latin5_bin 0 0 100 equal tailoring +hp8_english_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_bin latin5_bin 0 0 100 equal tailoring +latin1_bin latin5_turkish_ci 0 0 100 equal tailoring +latin1_general_cs latin5_bin 0 0 100 equal tailoring +latin1_general_cs latin5_turkish_ci 0 0 100 equal tailoring +latin1_german1_ci latin5_bin 0 0 100 equal tailoring +latin1_german1_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_nopad_bin latin5_nopad_bin 0 0 100 equal tailoring +latin1_nopad_bin latin5_turkish_nopad_ci 0 0 100 equal tailoring +latin1_swedish_ci latin5_bin 0 0 100 equal tailoring +latin1_swedish_ci latin5_turkish_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci latin5_nopad_bin 0 0 100 equal tailoring +latin1_swedish_nopad_ci latin5_turkish_nopad_ci 0 0 100 equal tailoring +latin5_bin hp8_english_ci 0 0 100 equal tailoring +latin5_bin latin1_bin 0 0 100 equal tailoring +latin5_bin latin1_general_cs 0 0 100 equal tailoring +latin5_bin latin1_german1_ci 0 0 100 equal tailoring +latin5_bin latin1_swedish_ci 0 0 100 equal tailoring +latin5_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +latin5_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +latin5_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +latin5_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +latin5_turkish_ci hp8_english_ci 0 0 100 equal tailoring +latin5_turkish_ci latin1_bin 0 0 100 equal tailoring +latin5_turkish_ci latin1_general_cs 0 0 100 equal tailoring +latin5_turkish_ci latin1_german1_ci 0 0 100 equal tailoring +latin5_turkish_ci latin1_swedish_ci 0 0 100 equal tailoring +latin5_turkish_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +latin5_turkish_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +latin5_turkish_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +latin5_turkish_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin latin5_nopad_bin 0 0 100 equal tailoring +swe7_nopad_bin latin5_turkish_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci latin5_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci latin5_turkish_nopad_ci 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +latin5_bin latin5_bin 0 0 000 cl1 = cl2 +latin5_nopad_bin latin5_nopad_bin 0 0 000 cl1 = cl2 +latin5_turkish_ci latin5_turkish_ci 0 0 000 cl1 = cl2 +latin5_turkish_nopad_ci latin5_turkish_nopad_ci 0 0 000 cl1 = cl2 +latin5_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_ci 0 0 002 LEFT sameCS_bin +latin5_nopad_bin latin5_turkish_nopad_ci 0 0 002 LEFT sameCS_bin +latin5_turkish_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_bin 0 0 002 RIGHT sameCS_bin +latin5_turkish_nopad_ci latin5_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs latin5_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 003 LEFT superset +latin5_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +latin5_turkish_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci latin5_turkish_nopad_ci 0 0 004 LEFT superset +latin5_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +latin5_turkish_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +hp8_english_ci latin5_turkish_ci 1 1 010 latin5_turkish_ci reorders ASCII letters: I' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_general_ci,COERCIBLE) for operation '<>' +SET NAMES latin7 COLLATE latin7_estonian_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_estonian_cs,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_estonian_cs,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_estonian_cs,COERCIBLE) for operation '<>' +SET NAMES latin7 COLLATE latin7_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_latin7.test b/mysql-test/main/ctype_latin7.test new file mode 100644 index 00000000000..d52a97e2bba --- /dev/null +++ b/mysql-test/main/ctype_latin7.test @@ -0,0 +1,20 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES latin7 COLLATE latin7_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES latin7 COLLATE latin7_estonian_cs; +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES latin7 COLLATE latin7_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_ldml.result b/mysql-test/main/ctype_ldml.result index c6bc0a3ab74..60ec07acc9f 100644 --- a/mysql-test/main/ctype_ldml.result +++ b/mysql-test/main/ctype_ldml.result @@ -474,6 +474,7 @@ latin1_test latin1 331 1 PAD SPACE cp1252 West European latin1_test2 latin1 332 1 PAD SPACE cp1252 West European latin1_test2_cs latin1 333 1 PAD SPACE cp1252 West European latin1_swedish_nopad2_ci latin1 334 1 NO PAD cp1252 West European +latin1_space_after_letters_ci latin1 335 1 PAD SPACE cp1252 West European utf8mb3_bengali_standard_ci utf8mb3 336 8 PAD SPACE utf8mb3_bengali_traditional_ci utf8mb3 337 8 PAD SPACE utf8mb3_implicit_weights_ci utf8mb3 338 8 PAD SPACE diff --git a/mysql-test/main/ctype_macce.result b/mysql-test/main/ctype_macce.result new file mode 100644 index 00000000000..537f8ac64e4 --- /dev/null +++ b/mysql-test/main/ctype_macce.result @@ -0,0 +1,21 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES macce COLLATE macce_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (macce_general_ci,COERCIBLE) for operation '=' +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (macce_general_ci,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (macce_general_ci,COERCIBLE) for operation '<>' +SET NAMES macce COLLATE macce_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (macce_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_macce.test b/mysql-test/main/ctype_macce.test new file mode 100644 index 00000000000..be5d9417d04 --- /dev/null +++ b/mysql-test/main/ctype_macce.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES macce COLLATE macce_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_02_probe_error.inc + +SET NAMES macce COLLATE macce_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_macroman.result b/mysql-test/main/ctype_macroman.result new file mode 100644 index 00000000000..5fe496657a0 --- /dev/null +++ b/mysql-test/main/ctype_macroman.result @@ -0,0 +1,24 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES macroman COLLATE macroman_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES macroman COLLATE macroman_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (macroman_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_macroman.test b/mysql-test/main/ctype_macroman.test new file mode 100644 index 00000000000..db07ce47aaa --- /dev/null +++ b/mysql-test/main/ctype_macroman.test @@ -0,0 +1,17 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES macroman COLLATE macroman_general_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES macroman COLLATE macroman_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_sjis.result b/mysql-test/main/ctype_sjis.result index 7648511245d..a1fddb6d0ee 100644 --- a/mysql-test/main/ctype_sjis.result +++ b/mysql-test/main/ctype_sjis.result @@ -19670,3 +19670,26 @@ c1 # # End of 10.5 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES sjis COLLATE sjis_japanese_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (sjis_japanese_ci,COERCIBLE) for operation '<>' +SET NAMES sjis COLLATE sjis_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (sjis_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_sjis.test b/mysql-test/main/ctype_sjis.test index 2e089cd85ba..3c2c02fb771 100644 --- a/mysql-test/main/ctype_sjis.test +++ b/mysql-test/main/ctype_sjis.test @@ -338,3 +338,22 @@ select strcmp(_sjis'' collate sjis_nopad_bin, _sjis 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES sjis COLLATE sjis_japanese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES sjis COLLATE sjis_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_sjis_tailoring.result b/mysql-test/main/ctype_sjis_tailoring.result new file mode 100644 index 00000000000..05e3dbb507c --- /dev/null +++ b/mysql-test/main/ctype_sjis_tailoring.result @@ -0,0 +1,1317 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +sjis_bin sjis_bin 0 0 000 cl1 = cl2 +sjis_japanese_ci sjis_japanese_ci 0 0 000 cl1 = cl2 +sjis_japanese_nopad_ci sjis_japanese_nopad_ci 0 0 000 cl1 = cl2 +sjis_nopad_bin sjis_nopad_bin 0 0 000 cl1 = cl2 +sjis_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_japanese_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs sjis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +sjis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +sjis_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin sjis_bin 1 1 030 nopad vs pad +latin1_nopad_bin sjis_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci sjis_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +sjis_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin1_bin 1 1 030 nopad vs pad +sjis_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +sjis_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin5_bin 1 1 030 nopad vs pad +sjis_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +sjis_nopad_bin sjis_bin 1 1 030 nopad vs pad +swe7_nopad_bin sjis_bin 1 1 030 nopad vs pad +swe7_nopad_bin sjis_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci sjis_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +hp8_english_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin1_bin sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin sjis_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs sjis_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin5_bin sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin sjis_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci sjis_nopad_bin 1 1 030 pad vs nopad +sjis_bin latin1_nopad_bin 1 1 030 pad vs nopad +sjis_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_bin sjis_nopad_bin 1 1 030 pad vs nopad +sjis_bin swe7_nopad_bin 1 1 030 pad vs nopad +sjis_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +sjis_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +sjis_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci sjis_bin 0 0 100 equal tailoring +hp8_english_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_bin sjis_bin 0 0 100 equal tailoring +latin1_bin sjis_japanese_ci 0 0 100 equal tailoring +latin1_general_cs sjis_bin 0 0 100 equal tailoring +latin1_general_cs sjis_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci sjis_bin 0 0 100 equal tailoring +latin1_german1_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin sjis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin sjis_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci sjis_bin 0 0 100 equal tailoring +latin1_swedish_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci sjis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci sjis_nopad_bin 0 0 100 equal tailoring +latin5_bin sjis_bin 0 0 100 equal tailoring +latin5_bin sjis_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci sjis_bin 0 0 100 equal tailoring +latin5_turkish_ci sjis_japanese_ci 0 0 100 equal tailoring +sjis_bin hp8_english_ci 0 0 100 equal tailoring +sjis_bin latin1_bin 0 0 100 equal tailoring +sjis_bin latin1_general_cs 0 0 100 equal tailoring +sjis_bin latin1_german1_ci 0 0 100 equal tailoring +sjis_bin latin1_swedish_ci 0 0 100 equal tailoring +sjis_bin latin5_bin 0 0 100 equal tailoring +sjis_bin latin5_turkish_ci 0 0 100 equal tailoring +sjis_japanese_ci hp8_english_ci 0 0 100 equal tailoring +sjis_japanese_ci latin1_bin 0 0 100 equal tailoring +sjis_japanese_ci latin1_general_cs 0 0 100 equal tailoring +sjis_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +sjis_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +sjis_japanese_ci latin5_bin 0 0 100 equal tailoring +sjis_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +sjis_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +sjis_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +sjis_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +sjis_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +sjis_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +sjis_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +sjis_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +sjis_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin sjis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin sjis_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci sjis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci sjis_nopad_bin 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +sjis_bin sjis_bin 0 0 000 cl1 = cl2 +sjis_japanese_ci sjis_japanese_ci 0 0 000 cl1 = cl2 +sjis_japanese_nopad_ci sjis_japanese_nopad_ci 0 0 000 cl1 = cl2 +sjis_nopad_bin sjis_nopad_bin 0 0 000 cl1 = cl2 +sjis_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_japanese_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs sjis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +sjis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +sjis_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin sjis_bin 1 1 030 nopad vs pad +latin1_nopad_bin sjis_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci sjis_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +sjis_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +sjis_japanese_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +sjis_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin1_bin 1 1 030 nopad vs pad +sjis_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +sjis_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +sjis_nopad_bin latin5_bin 1 1 030 nopad vs pad +sjis_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +sjis_nopad_bin sjis_bin 1 1 030 nopad vs pad +swe7_nopad_bin sjis_bin 1 1 030 nopad vs pad +swe7_nopad_bin sjis_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci sjis_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci sjis_japanese_ci 1 1 030 nopad vs pad +hp8_english_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin1_bin sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin sjis_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs sjis_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci sjis_nopad_bin 1 1 030 pad vs nopad +latin5_bin sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin sjis_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci sjis_nopad_bin 1 1 030 pad vs nopad +sjis_bin latin1_nopad_bin 1 1 030 pad vs nopad +sjis_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_bin sjis_nopad_bin 1 1 030 pad vs nopad +sjis_bin swe7_nopad_bin 1 1 030 pad vs nopad +sjis_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +sjis_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci sjis_japanese_nopad_ci 1 1 030 pad vs nopad +sjis_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +sjis_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci sjis_bin 0 0 100 equal tailoring +hp8_english_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_bin sjis_bin 0 0 100 equal tailoring +latin1_bin sjis_japanese_ci 0 0 100 equal tailoring +latin1_general_cs sjis_bin 0 0 100 equal tailoring +latin1_general_cs sjis_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci sjis_bin 0 0 100 equal tailoring +latin1_german1_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin sjis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin sjis_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci sjis_bin 0 0 100 equal tailoring +latin1_swedish_ci sjis_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci sjis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci sjis_nopad_bin 0 0 100 equal tailoring +latin5_bin sjis_bin 0 0 100 equal tailoring +latin5_bin sjis_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci sjis_bin 0 0 100 equal tailoring +latin5_turkish_ci sjis_japanese_ci 0 0 100 equal tailoring +sjis_bin hp8_english_ci 0 0 100 equal tailoring +sjis_bin latin1_bin 0 0 100 equal tailoring +sjis_bin latin1_general_cs 0 0 100 equal tailoring +sjis_bin latin1_german1_ci 0 0 100 equal tailoring +sjis_bin latin1_swedish_ci 0 0 100 equal tailoring +sjis_bin latin5_bin 0 0 100 equal tailoring +sjis_bin latin5_turkish_ci 0 0 100 equal tailoring +sjis_japanese_ci hp8_english_ci 0 0 100 equal tailoring +sjis_japanese_ci latin1_bin 0 0 100 equal tailoring +sjis_japanese_ci latin1_general_cs 0 0 100 equal tailoring +sjis_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +sjis_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +sjis_japanese_ci latin5_bin 0 0 100 equal tailoring +sjis_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +sjis_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +sjis_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +sjis_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +sjis_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +sjis_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +sjis_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +sjis_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +sjis_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin sjis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin sjis_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci sjis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci sjis_nopad_bin 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +sjis_bin sjis_bin 0 0 000 cl1 = cl2 +sjis_japanese_ci sjis_japanese_ci 0 0 000 cl1 = cl2 +sjis_japanese_nopad_ci sjis_japanese_nopad_ci 0 0 000 cl1 = cl2 +sjis_nopad_bin sjis_nopad_bin 0 0 000 cl1 = cl2 +sjis_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_ci 0 0 002 LEFT sameCS_bin +sjis_nopad_bin sjis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +sjis_japanese_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_bin 0 0 002 RIGHT sameCS_bin +sjis_japanese_nopad_ci sjis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs sjis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci sjis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci sjis_nopad_bin 0 0 003 LEFT superset +sjis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +sjis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci sjis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci sjis_nopad_bin 0 0 004 LEFT superset +sjis_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +sjis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci sjis_bin 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (swe7_swedish_ci,COERCIBLE) for operation '<>' +SET NAMES swe7 COLLATE swe7_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (swe7_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_swe7.test b/mysql-test/main/ctype_swe7.test index d2f59084342..58f897bc398 100644 --- a/mysql-test/main/ctype_swe7.test +++ b/mysql-test/main/ctype_swe7.test @@ -71,3 +71,21 @@ EXECUTE IMMEDIATE _swe7 0x01; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES swe7 COLLATE swe7_swedish_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_03_probe_last_error.inc + +SET NAMES swe7 COLLATE swe7_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_tis620.result b/mysql-test/main/ctype_tis620.result index 6d817be2b22..7ce7d101c94 100644 --- a/mysql-test/main/ctype_tis620.result +++ b/mysql-test/main/ctype_tis620.result @@ -4497,3 +4497,21 @@ DROP TABLE t1; # # End of 10.4 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES tis620 COLLATE tis620_thai_ci; +# tis620_thai_ci sorts the underscore before the letters, so it is +# compatible only on the ALNUM repertoire. +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (tis620_thai_ci,COERCIBLE) for operation '<>' +SELECT c FROM v_tailoring WHERE c<>'Y+'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (tis620_thai_ci,COERCIBLE) for operation '<>' +SET NAMES tis620 COLLATE tis620_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (tis620_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_tis620.test b/mysql-test/main/ctype_tis620.test index 39908b995b2..dd179ca4664 100644 --- a/mysql-test/main/ctype_tis620.test +++ b/mysql-test/main/ctype_tis620.test @@ -254,3 +254,28 @@ DROP TABLE t1; --echo # --echo # End of 10.4 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES tis620 COLLATE tis620_thai_ci; +--echo # tis620_thai_ci sorts the underscore before the letters, so it is +--echo # compatible only on the ALNUM repertoire. +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +SELECT c FROM v_tailoring WHERE c='Y'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c<>'Y_'; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c<>'Y+'; + +SET NAMES tis620 COLLATE tis620_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_tis620_tailoring.result b/mysql-test/main/ctype_tis620_tailoring.result new file mode 100644 index 00000000000..c3f121c72ff --- /dev/null +++ b/mysql-test/main/ctype_tis620_tailoring.result @@ -0,0 +1,1329 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +tis620_bin tis620_bin 0 0 000 cl1 = cl2 +tis620_nopad_bin tis620_nopad_bin 0 0 000 cl1 = cl2 +tis620_thai_ci tis620_thai_ci 0 0 000 cl1 = cl2 +tis620_thai_nopad_ci tis620_thai_nopad_ci 0 0 000 cl1 = cl2 +tis620_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_thai_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs tis620_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +tis620_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +tis620_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin tis620_bin 1 1 030 nopad vs pad +latin1_nopad_bin tis620_thai_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci tis620_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +swe7_nopad_bin tis620_bin 1 1 030 nopad vs pad +swe7_nopad_bin tis620_thai_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci tis620_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +tis620_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin1_bin 1 1 030 nopad vs pad +tis620_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +tis620_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin5_bin 1 1 030 nopad vs pad +tis620_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +tis620_nopad_bin tis620_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin5_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +hp8_english_ci tis620_nopad_bin 1 1 030 pad vs nopad +hp8_english_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_bin tis620_nopad_bin 1 1 030 pad vs nopad +latin1_bin tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs tis620_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin5_bin tis620_nopad_bin 1 1 030 pad vs nopad +latin5_bin tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +tis620_bin latin1_nopad_bin 1 1 030 pad vs nopad +tis620_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_bin swe7_nopad_bin 1 1 030 pad vs nopad +tis620_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_bin tis620_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci latin1_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_thai_ci swe7_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_thai_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci tis620_bin 0 0 100 equal tailoring +hp8_english_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_bin tis620_bin 0 0 100 equal tailoring +latin1_bin tis620_thai_ci 0 0 100 equal tailoring +latin1_general_cs tis620_bin 0 0 100 equal tailoring +latin1_general_cs tis620_thai_ci 0 0 100 equal tailoring +latin1_german1_ci tis620_bin 0 0 100 equal tailoring +latin1_german1_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_nopad_bin tis620_nopad_bin 0 0 100 equal tailoring +latin1_nopad_bin tis620_thai_nopad_ci 0 0 100 equal tailoring +latin1_swedish_ci tis620_bin 0 0 100 equal tailoring +latin1_swedish_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci tis620_nopad_bin 0 0 100 equal tailoring +latin1_swedish_nopad_ci tis620_thai_nopad_ci 0 0 100 equal tailoring +latin5_bin tis620_bin 0 0 100 equal tailoring +latin5_bin tis620_thai_ci 0 0 100 equal tailoring +latin5_turkish_ci tis620_bin 0 0 100 equal tailoring +latin5_turkish_ci tis620_thai_ci 0 0 100 equal tailoring +swe7_nopad_bin tis620_nopad_bin 0 0 100 equal tailoring +swe7_nopad_bin tis620_thai_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci tis620_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci tis620_thai_nopad_ci 0 0 100 equal tailoring +tis620_bin hp8_english_ci 0 0 100 equal tailoring +tis620_bin latin1_bin 0 0 100 equal tailoring +tis620_bin latin1_general_cs 0 0 100 equal tailoring +tis620_bin latin1_german1_ci 0 0 100 equal tailoring +tis620_bin latin1_swedish_ci 0 0 100 equal tailoring +tis620_bin latin5_bin 0 0 100 equal tailoring +tis620_bin latin5_turkish_ci 0 0 100 equal tailoring +tis620_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +tis620_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +tis620_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +tis620_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +tis620_thai_ci hp8_english_ci 0 0 100 equal tailoring +tis620_thai_ci latin1_bin 0 0 100 equal tailoring +tis620_thai_ci latin1_general_cs 0 0 100 equal tailoring +tis620_thai_ci latin1_german1_ci 0 0 100 equal tailoring +tis620_thai_ci latin1_swedish_ci 0 0 100 equal tailoring +tis620_thai_ci latin5_bin 0 0 100 equal tailoring +tis620_thai_ci latin5_turkish_ci 0 0 100 equal tailoring +tis620_thai_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +tis620_thai_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +tis620_thai_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +tis620_thai_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +tis620_bin tis620_bin 0 0 000 cl1 = cl2 +tis620_nopad_bin tis620_nopad_bin 0 0 000 cl1 = cl2 +tis620_thai_ci tis620_thai_ci 0 0 000 cl1 = cl2 +tis620_thai_nopad_ci tis620_thai_nopad_ci 0 0 000 cl1 = cl2 +tis620_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_thai_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs tis620_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +tis620_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +tis620_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin tis620_bin 1 1 030 nopad vs pad +latin1_nopad_bin tis620_thai_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci tis620_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +swe7_nopad_bin tis620_bin 1 1 030 nopad vs pad +swe7_nopad_bin tis620_thai_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci tis620_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +tis620_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin1_bin 1 1 030 nopad vs pad +tis620_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +tis620_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +tis620_nopad_bin latin5_bin 1 1 030 nopad vs pad +tis620_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +tis620_nopad_bin tis620_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin5_bin 1 1 030 nopad vs pad +tis620_thai_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +tis620_thai_nopad_ci tis620_thai_ci 1 1 030 nopad vs pad +hp8_english_ci tis620_nopad_bin 1 1 030 pad vs nopad +hp8_english_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_bin tis620_nopad_bin 1 1 030 pad vs nopad +latin1_bin tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs tis620_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin5_bin tis620_nopad_bin 1 1 030 pad vs nopad +latin5_bin tis620_thai_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci tis620_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +tis620_bin latin1_nopad_bin 1 1 030 pad vs nopad +tis620_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_bin swe7_nopad_bin 1 1 030 pad vs nopad +tis620_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_bin tis620_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci latin1_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_thai_ci swe7_nopad_bin 1 1 030 pad vs nopad +tis620_thai_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +tis620_thai_ci tis620_thai_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci tis620_bin 0 0 100 equal tailoring +hp8_english_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_bin tis620_bin 0 0 100 equal tailoring +latin1_bin tis620_thai_ci 0 0 100 equal tailoring +latin1_general_cs tis620_bin 0 0 100 equal tailoring +latin1_general_cs tis620_thai_ci 0 0 100 equal tailoring +latin1_german1_ci tis620_bin 0 0 100 equal tailoring +latin1_german1_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_nopad_bin tis620_nopad_bin 0 0 100 equal tailoring +latin1_nopad_bin tis620_thai_nopad_ci 0 0 100 equal tailoring +latin1_swedish_ci tis620_bin 0 0 100 equal tailoring +latin1_swedish_ci tis620_thai_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci tis620_nopad_bin 0 0 100 equal tailoring +latin1_swedish_nopad_ci tis620_thai_nopad_ci 0 0 100 equal tailoring +latin5_bin tis620_bin 0 0 100 equal tailoring +latin5_bin tis620_thai_ci 0 0 100 equal tailoring +latin5_turkish_ci tis620_bin 0 0 100 equal tailoring +latin5_turkish_ci tis620_thai_ci 0 0 100 equal tailoring +swe7_nopad_bin tis620_nopad_bin 0 0 100 equal tailoring +swe7_nopad_bin tis620_thai_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci tis620_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci tis620_thai_nopad_ci 0 0 100 equal tailoring +tis620_bin hp8_english_ci 0 0 100 equal tailoring +tis620_bin latin1_bin 0 0 100 equal tailoring +tis620_bin latin1_general_cs 0 0 100 equal tailoring +tis620_bin latin1_german1_ci 0 0 100 equal tailoring +tis620_bin latin1_swedish_ci 0 0 100 equal tailoring +tis620_bin latin5_bin 0 0 100 equal tailoring +tis620_bin latin5_turkish_ci 0 0 100 equal tailoring +tis620_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +tis620_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +tis620_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +tis620_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +tis620_thai_ci hp8_english_ci 0 0 100 equal tailoring +tis620_thai_ci latin1_bin 0 0 100 equal tailoring +tis620_thai_ci latin1_general_cs 0 0 100 equal tailoring +tis620_thai_ci latin1_german1_ci 0 0 100 equal tailoring +tis620_thai_ci latin1_swedish_ci 0 0 100 equal tailoring +tis620_thai_ci latin5_bin 0 0 100 equal tailoring +tis620_thai_ci latin5_turkish_ci 0 0 100 equal tailoring +tis620_thai_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +tis620_thai_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +tis620_thai_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +tis620_thai_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +tis620_bin tis620_bin 0 0 000 cl1 = cl2 +tis620_nopad_bin tis620_nopad_bin 0 0 000 cl1 = cl2 +tis620_thai_ci tis620_thai_ci 0 0 000 cl1 = cl2 +tis620_thai_nopad_ci tis620_thai_nopad_ci 0 0 000 cl1 = cl2 +tis620_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_ci 0 0 002 LEFT sameCS_bin +tis620_nopad_bin tis620_thai_nopad_ci 0 0 002 LEFT sameCS_bin +tis620_thai_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_bin 0 0 002 RIGHT sameCS_bin +tis620_thai_nopad_ci tis620_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs tis620_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci tis620_thai_nopad_ci 0 0 003 LEFT superset +tis620_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +tis620_thai_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci tis620_thai_nopad_ci 0 0 004 LEFT superset +tis620_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +tis620_thai_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci tis620_bin 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +End of 11.8 tests diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index 4e9b5276cde..da0836713a3 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -1276,3 +1276,22 @@ DROP TABLE t1; SET @@sql_mode= @old_mode; --echo # End of 10.11 tests + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb3; +SET collation_connection=ucs2_general_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo End of 11.8 tests diff --git a/mysql-test/main/ctype_ucs2_uca.result b/mysql-test/main/ctype_ucs2_uca.result index a49cdb8c4e0..3ec4b4b4bfb 100644 --- a/mysql-test/main/ctype_ucs2_uca.result +++ b/mysql-test/main/ctype_ucs2_uca.result @@ -1166,3 +1166,110 @@ SET NAMES utf8; # # End of 10.9 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb3; +SET collation_connection=ucs2_unicode_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_czech_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_ai_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_ai_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_as_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_as_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_ucs2_uca.test b/mysql-test/main/ctype_ucs2_uca.test index 5d0699401da..355d34e2dcd 100644 --- a/mysql-test/main/ctype_ucs2_uca.test +++ b/mysql-test/main/ctype_ucs2_uca.test @@ -41,3 +41,38 @@ SET @charset='ucs2'; --echo # --echo # End of 10.9 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb3; +SET collation_connection=ucs2_unicode_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_czech_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_ai_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_ai_cs; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_as_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3; +SET collation_connection=ucs2_uca1400_as_cs; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_ujis.result b/mysql-test/main/ctype_ujis.result index e1a93e13d35..573d5077061 100644 --- a/mysql-test/main/ctype_ujis.result +++ b/mysql-test/main/ctype_ujis.result @@ -27101,3 +27101,27 @@ c1 # # End of 10.5 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES ujis COLLATE ujis_japanese_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES ujis COLLATE ujis_bin; +SELECT c FROM v_tailoring WHERE c='Y'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (ujis_bin,COERCIBLE) for operation '=' +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_ujis.test b/mysql-test/main/ctype_ujis.test index 0cd280f65fc..5a9042ceb56 100644 --- a/mysql-test/main/ctype_ujis.test +++ b/mysql-test/main/ctype_ujis.test @@ -1461,3 +1461,22 @@ select strcmp(_ujis'' collate ujis_nopad_bin, _ujis 0x0001050001) as c1; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES ujis COLLATE ujis_japanese_ci; +--disable_service_connection +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES ujis COLLATE ujis_bin; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM v_tailoring WHERE c='Y'; +--source include/ctype_tailoring_view_drop.inc +--enable_service_connection +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_ujis_tailoring.result b/mysql-test/main/ctype_ujis_tailoring.result new file mode 100644 index 00000000000..3c401ebf542 --- /dev/null +++ b/mysql-test/main/ctype_ujis_tailoring.result @@ -0,0 +1,1303 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# ASCII digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +ujis_bin ujis_bin 0 0 000 cl1 = cl2 +ujis_japanese_ci ujis_japanese_ci 0 0 000 cl1 = cl2 +ujis_japanese_nopad_ci ujis_japanese_nopad_ci 0 0 000 cl1 = cl2 +ujis_nopad_bin ujis_nopad_bin 0 0 000 cl1 = cl2 +ujis_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_japanese_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs ujis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +ujis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +ujis_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin ujis_bin 1 1 030 nopad vs pad +latin1_nopad_bin ujis_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci ujis_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin ujis_bin 1 1 030 nopad vs pad +swe7_nopad_bin ujis_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci ujis_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +ujis_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin1_bin 1 1 030 nopad vs pad +ujis_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +ujis_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin5_bin 1 1 030 nopad vs pad +ujis_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +ujis_nopad_bin ujis_bin 1 1 030 nopad vs pad +hp8_english_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin1_bin ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin ujis_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs ujis_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin5_bin ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin ujis_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci ujis_nopad_bin 1 1 030 pad vs nopad +ujis_bin latin1_nopad_bin 1 1 030 pad vs nopad +ujis_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_bin swe7_nopad_bin 1 1 030 pad vs nopad +ujis_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_bin ujis_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_japanese_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci ujis_bin 0 0 100 equal tailoring +hp8_english_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_bin ujis_bin 0 0 100 equal tailoring +latin1_bin ujis_japanese_ci 0 0 100 equal tailoring +latin1_general_cs ujis_bin 0 0 100 equal tailoring +latin1_general_cs ujis_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci ujis_bin 0 0 100 equal tailoring +latin1_german1_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin ujis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin ujis_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci ujis_bin 0 0 100 equal tailoring +latin1_swedish_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci ujis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci ujis_nopad_bin 0 0 100 equal tailoring +latin5_bin ujis_bin 0 0 100 equal tailoring +latin5_bin ujis_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci ujis_bin 0 0 100 equal tailoring +latin5_turkish_ci ujis_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin ujis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin ujis_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci ujis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci ujis_nopad_bin 0 0 100 equal tailoring +ujis_bin hp8_english_ci 0 0 100 equal tailoring +ujis_bin latin1_bin 0 0 100 equal tailoring +ujis_bin latin1_general_cs 0 0 100 equal tailoring +ujis_bin latin1_german1_ci 0 0 100 equal tailoring +ujis_bin latin1_swedish_ci 0 0 100 equal tailoring +ujis_bin latin5_bin 0 0 100 equal tailoring +ujis_bin latin5_turkish_ci 0 0 100 equal tailoring +ujis_japanese_ci hp8_english_ci 0 0 100 equal tailoring +ujis_japanese_ci latin1_bin 0 0 100 equal tailoring +ujis_japanese_ci latin1_general_cs 0 0 100 equal tailoring +ujis_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +ujis_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +ujis_japanese_ci latin5_bin 0 0 100 equal tailoring +ujis_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +ujis_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +ujis_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +ujis_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +ujis_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +ujis_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +ujis_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +ujis_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +ujis_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +# +# ASCII minus, dot and digits repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +ujis_bin ujis_bin 0 0 000 cl1 = cl2 +ujis_japanese_ci ujis_japanese_ci 0 0 000 cl1 = cl2 +ujis_japanese_nopad_ci ujis_japanese_nopad_ci 0 0 000 cl1 = cl2 +ujis_nopad_bin ujis_nopad_bin 0 0 000 cl1 = cl2 +ujis_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_japanese_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs ujis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +ujis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +ujis_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin1_nopad_bin ujis_bin 1 1 030 nopad vs pad +latin1_nopad_bin ujis_japanese_ci 1 1 030 nopad vs pad +latin1_swedish_nopad_ci ujis_bin 1 1 030 nopad vs pad +latin1_swedish_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +swe7_nopad_bin ujis_bin 1 1 030 nopad vs pad +swe7_nopad_bin ujis_japanese_ci 1 1 030 nopad vs pad +swe7_swedish_nopad_ci ujis_bin 1 1 030 nopad vs pad +swe7_swedish_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci hp8_english_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_bin 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_general_cs 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_german1_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin1_swedish_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin5_bin 1 1 030 nopad vs pad +ujis_japanese_nopad_ci latin5_turkish_ci 1 1 030 nopad vs pad +ujis_japanese_nopad_ci ujis_japanese_ci 1 1 030 nopad vs pad +ujis_nopad_bin hp8_english_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin1_bin 1 1 030 nopad vs pad +ujis_nopad_bin latin1_general_cs 1 1 030 nopad vs pad +ujis_nopad_bin latin1_german1_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin1_swedish_ci 1 1 030 nopad vs pad +ujis_nopad_bin latin5_bin 1 1 030 nopad vs pad +ujis_nopad_bin latin5_turkish_ci 1 1 030 nopad vs pad +ujis_nopad_bin ujis_bin 1 1 030 nopad vs pad +hp8_english_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin1_bin ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_bin ujis_nopad_bin 1 1 030 pad vs nopad +latin1_general_cs ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_general_cs ujis_nopad_bin 1 1 030 pad vs nopad +latin1_german1_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_german1_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin1_swedish_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin1_swedish_ci ujis_nopad_bin 1 1 030 pad vs nopad +latin5_bin ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_bin ujis_nopad_bin 1 1 030 pad vs nopad +latin5_turkish_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +latin5_turkish_ci ujis_nopad_bin 1 1 030 pad vs nopad +ujis_bin latin1_nopad_bin 1 1 030 pad vs nopad +ujis_bin latin1_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_bin swe7_nopad_bin 1 1 030 pad vs nopad +ujis_bin swe7_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_bin ujis_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci latin1_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci latin1_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_japanese_ci swe7_nopad_bin 1 1 030 pad vs nopad +ujis_japanese_ci swe7_swedish_nopad_ci 1 1 030 pad vs nopad +ujis_japanese_ci ujis_japanese_nopad_ci 1 1 030 pad vs nopad +hp8_english_ci ujis_bin 0 0 100 equal tailoring +hp8_english_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_bin ujis_bin 0 0 100 equal tailoring +latin1_bin ujis_japanese_ci 0 0 100 equal tailoring +latin1_general_cs ujis_bin 0 0 100 equal tailoring +latin1_general_cs ujis_japanese_ci 0 0 100 equal tailoring +latin1_german1_ci ujis_bin 0 0 100 equal tailoring +latin1_german1_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_nopad_bin ujis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_nopad_bin ujis_nopad_bin 0 0 100 equal tailoring +latin1_swedish_ci ujis_bin 0 0 100 equal tailoring +latin1_swedish_ci ujis_japanese_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci ujis_japanese_nopad_ci 0 0 100 equal tailoring +latin1_swedish_nopad_ci ujis_nopad_bin 0 0 100 equal tailoring +latin5_bin ujis_bin 0 0 100 equal tailoring +latin5_bin ujis_japanese_ci 0 0 100 equal tailoring +latin5_turkish_ci ujis_bin 0 0 100 equal tailoring +latin5_turkish_ci ujis_japanese_ci 0 0 100 equal tailoring +swe7_nopad_bin ujis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_nopad_bin ujis_nopad_bin 0 0 100 equal tailoring +swe7_swedish_nopad_ci ujis_japanese_nopad_ci 0 0 100 equal tailoring +swe7_swedish_nopad_ci ujis_nopad_bin 0 0 100 equal tailoring +ujis_bin hp8_english_ci 0 0 100 equal tailoring +ujis_bin latin1_bin 0 0 100 equal tailoring +ujis_bin latin1_general_cs 0 0 100 equal tailoring +ujis_bin latin1_german1_ci 0 0 100 equal tailoring +ujis_bin latin1_swedish_ci 0 0 100 equal tailoring +ujis_bin latin5_bin 0 0 100 equal tailoring +ujis_bin latin5_turkish_ci 0 0 100 equal tailoring +ujis_japanese_ci hp8_english_ci 0 0 100 equal tailoring +ujis_japanese_ci latin1_bin 0 0 100 equal tailoring +ujis_japanese_ci latin1_general_cs 0 0 100 equal tailoring +ujis_japanese_ci latin1_german1_ci 0 0 100 equal tailoring +ujis_japanese_ci latin1_swedish_ci 0 0 100 equal tailoring +ujis_japanese_ci latin5_bin 0 0 100 equal tailoring +ujis_japanese_ci latin5_turkish_ci 0 0 100 equal tailoring +ujis_japanese_nopad_ci latin1_nopad_bin 0 0 100 equal tailoring +ujis_japanese_nopad_ci latin1_swedish_nopad_ci 0 0 100 equal tailoring +ujis_japanese_nopad_ci swe7_nopad_bin 0 0 100 equal tailoring +ujis_japanese_nopad_ci swe7_swedish_nopad_ci 0 0 100 equal tailoring +ujis_nopad_bin latin1_nopad_bin 0 0 100 equal tailoring +ujis_nopad_bin latin1_swedish_nopad_ci 0 0 100 equal tailoring +ujis_nopad_bin swe7_nopad_bin 0 0 100 equal tailoring +ujis_nopad_bin swe7_swedish_nopad_ci 0 0 100 equal tailoring +# +# ALNUM repertoire +# +cl1 cl2 is_error is_error_expected expected_reason +cl1 cl2 is_error is_error_expected expected_reason +ujis_bin ujis_bin 0 0 000 cl1 = cl2 +ujis_japanese_ci ujis_japanese_ci 0 0 000 cl1 = cl2 +ujis_japanese_nopad_ci ujis_japanese_nopad_ci 0 0 000 cl1 = cl2 +ujis_nopad_bin ujis_nopad_bin 0 0 000 cl1 = cl2 +ujis_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_ci 0 0 002 LEFT sameCS_bin +ujis_nopad_bin ujis_japanese_nopad_ci 0 0 002 LEFT sameCS_bin +ujis_japanese_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_bin 0 0 002 RIGHT sameCS_bin +ujis_japanese_nopad_ci ujis_nopad_bin 0 0 002 RIGHT sameCS_bin +utf32_uca1400_as_cs ujis_bin 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf32_uca1400_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_bin 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_0900_as_cs ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_general_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_bin 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_nopad_bin ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_uca1400_nopad_ai_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_ci ujis_nopad_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_bin 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 003 LEFT superset +utf8mb4_unicode_nopad_ci ujis_nopad_bin 0 0 003 LEFT superset +ujis_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_japanese_nopad_ci utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf32_uca1400_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_0900_as_cs 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_general_nopad_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_nopad_bin 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_uca1400_nopad_ai_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_ci 0 0 003 RIGHT superset +ujis_nopad_bin utf8mb4_unicode_nopad_ci 0 0 003 RIGHT superset +utf8mb3_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_general_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_bin 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_nopad_bin ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_bin 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_uca1400_nopad_ai_cs ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_ci ujis_nopad_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_bin 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_japanese_nopad_ci 0 0 004 LEFT superset +utf8mb3_unicode_nopad_ci ujis_nopad_bin 0 0 004 LEFT superset +ujis_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_japanese_nopad_ci utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_general_nopad_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_nopad_bin 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_uca1400_nopad_ai_cs 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_ci 0 0 004 RIGHT superset +ujis_nopad_bin utf8mb3_unicode_nopad_ci 0 0 004 RIGHT superset +latin5_turkish_ci ujis_bin 1 1 010 latin5_turkish_ci reorders ASCII letters: I'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf16.test b/mysql-test/main/ctype_utf16.test index 2a9757f145e..02731a2e864 100644 --- a/mysql-test/main/ctype_utf16.test +++ b/mysql-test/main/ctype_utf16.test @@ -1042,3 +1042,22 @@ SET NAMES utf8mb3; --echo # --echo # End of 10.5 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4; +SET collation_connection=utf16_general_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf16_uca.result b/mysql-test/main/ctype_utf16_uca.result index 59e0a977842..02355f3ca54 100644 --- a/mysql-test/main/ctype_utf16_uca.result +++ b/mysql-test/main/ctype_utf16_uca.result @@ -8524,3 +8524,110 @@ SET NAMES utf8; # # End of 10.9 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb4; +SET collation_connection=utf16_unicode_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_czech_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_ai_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_ai_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_as_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_as_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf16_uca.test b/mysql-test/main/ctype_utf16_uca.test index 0a03c4fa57b..4b883477618 100644 --- a/mysql-test/main/ctype_utf16_uca.test +++ b/mysql-test/main/ctype_utf16_uca.test @@ -288,6 +288,42 @@ SET NAMES utf8; SET @charset='utf16'; --source include/ctype_uca1400_ids_using_convert.inc + --echo # --echo # End of 10.9 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4; +SET collation_connection=utf16_unicode_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_czech_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_ai_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_ai_cs; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_as_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf16_uca1400_as_cs; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result index ae80b27abe8..103b222d892 100644 --- a/mysql-test/main/ctype_utf32.result +++ b/mysql-test/main/ctype_utf32.result @@ -3424,3 +3424,42 @@ SELECT CONV('-AzL8n0Y58m8', -62, -10); CONV('-AzL8n0Y58m8', -62, -10) -9223372036854775808 # End of 11.4 tests +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb4; +SET collation_connection=utf32_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test index dfab164365d..57b5bf8c4a0 100644 --- a/mysql-test/main/ctype_utf32.test +++ b/mysql-test/main/ctype_utf32.test @@ -1136,11 +1136,8 @@ SELECT HEX(DATE_FORMAT(TIME'-01:01:01','%h')); --echo # utf8 format, utf32 result SELECT DATE_FORMAT('2004-02-02',_utf8'%W'); SELECT HEX(DATE_FORMAT('2004-02-02',_utf8'%W')); -#enable after fix MDEV-34215 ---disable_cursor_protocol SELECT DATE_FORMAT(TIME'-01:01:01',_utf8'%h'); SELECT HEX(DATE_FORMAT(TIME'-01:01:01',_utf8'%h')); ---enable_cursor_protocol --echo # utf32 format, utf8 result SET NAMES utf8; @@ -1264,3 +1261,21 @@ SET NAMES utf8mb3, character_set_connection=utf32; SELECT CONV('-AzL8n0Y58m8', -62, -10); --echo # End of 11.4 tests + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4; +SET collation_connection=utf32_general_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf32_uca.result b/mysql-test/main/ctype_utf32_uca.result index 9b0cac00686..e4d012243e0 100644 --- a/mysql-test/main/ctype_utf32_uca.result +++ b/mysql-test/main/ctype_utf32_uca.result @@ -8558,3 +8558,110 @@ SET NAMES utf8; # # End of 10.9 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb4; +SET collation_connection=utf32_unicode_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_czech_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_ai_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_ai_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_as_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_as_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf32_uca.test b/mysql-test/main/ctype_utf32_uca.test index dd60feaf8e2..09a90fb0d1e 100644 --- a/mysql-test/main/ctype_utf32_uca.test +++ b/mysql-test/main/ctype_utf32_uca.test @@ -345,3 +345,38 @@ SET @charset='utf32'; --echo # --echo # End of 10.9 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4; +SET collation_connection=utf32_unicode_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_czech_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_ai_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_ai_cs; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_as_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4; +SET collation_connection=utf32_uca1400_as_cs; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 55b95de9135..8d20da621a4 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -10834,3 +10834,56 @@ DROP TABLE t1; # # End of 11.6 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb3 COLLATE utf8mb3_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_general_mysql500_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8.test b/mysql-test/main/ctype_utf8.test index e6b43cd45bc..b68090ba6dc 100644 --- a/mysql-test/main/ctype_utf8.test +++ b/mysql-test/main/ctype_utf8.test @@ -2565,3 +2565,22 @@ DROP TABLE t1; --echo # --echo # End of 11.6 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb3 COLLATE utf8mb3_general_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_general_mysql500_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8_uca.result b/mysql-test/main/ctype_utf8_uca.result index 616e4feba94..923d34d3857 100644 --- a/mysql-test/main/ctype_utf8_uca.result +++ b/mysql-test/main/ctype_utf8_uca.result @@ -2026,3 +2026,103 @@ DROP TABLE case_folding; # # End of 10.10 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb3 COLLATE utf8mb3_unicode_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_czech_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_as_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_as_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8_uca.test b/mysql-test/main/ctype_utf8_uca.test index df9e70590e3..b3d2c262ee4 100644 --- a/mysql-test/main/ctype_utf8_uca.test +++ b/mysql-test/main/ctype_utf8_uca.test @@ -124,3 +124,30 @@ SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_ci; --echo # --echo # End of 10.10 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb3 COLLATE utf8mb3_unicode_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_czech_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_ai_cs; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_as_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb3 COLLATE utf8mb3_uca1400_as_cs; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8mb4.result b/mysql-test/main/ctype_utf8mb4.result index 5a4394e5816..3d99b3d549c 100644 --- a/mysql-test/main/ctype_utf8mb4.result +++ b/mysql-test/main/ctype_utf8mb4.result @@ -3779,3 +3779,57 @@ DROP TABLE t1; # # End of 10.11 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_bin; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES DEFAULT; +# +# MDEV-41246 LOWER() and UPPER() can convert ASCII letters to +# non-ASCII ones in Turkish collations (I -> dotless i, i -> dotted I), +# which is not the case in non-Turkish collations +# +SET NAMES utf8mb4 COLLATE utf8mb4_turkish_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +HEX(LOWER('I')) LOWER('I') = _latin1'i' +C4B1 0 +SELECT HEX(UPPER('i')), UPPER('i') = _latin1'I'; +HEX(UPPER('i')) UPPER('i') = _latin1'I' +C4B0 0 +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +HEX(LOWER('I')) LOWER('I') = _latin1'i' +69 1 +SET NAMES DEFAULT; +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8mb4.test b/mysql-test/main/ctype_utf8mb4.test index 997450b2bd1..16989e5e005 100644 --- a/mysql-test/main/ctype_utf8mb4.test +++ b/mysql-test/main/ctype_utf8mb4.test @@ -2205,3 +2205,31 @@ DROP TABLE t1; --echo # --echo # End of 10.11 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_bin; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc +SET NAMES DEFAULT; + +--echo # +--echo # MDEV-41246 LOWER() and UPPER() can convert ASCII letters to +--echo # non-ASCII ones in Turkish collations (I -> dotless i, i -> dotted I), +--echo # which is not the case in non-Turkish collations +--echo # +SET NAMES utf8mb4 COLLATE utf8mb4_turkish_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +SELECT HEX(UPPER('i')), UPPER('i') = _latin1'I'; +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +SELECT HEX(LOWER('I')), LOWER('I') = _latin1'i'; +SET NAMES DEFAULT; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8mb4_uca.result b/mysql-test/main/ctype_utf8mb4_uca.result index f6a89557359..4e7555a0c01 100644 --- a/mysql-test/main/ctype_utf8mb4_uca.result +++ b/mysql-test/main/ctype_utf8mb4_uca.result @@ -11687,3 +11687,103 @@ DROP TABLE case_folding; # # End of 10.10 tests # +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_czech_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_ai_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_as_ci; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_as_cs; +# ASCII digits +d +1 +# ASCII minus, dot and digits +e +-1.5 +SELECT c FROM v_tailoring WHERE c='Y'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y_'; +c +Y +SELECT c FROM v_tailoring WHERE c<>'Y+'; +c +Y +# End of 11.8 tests diff --git a/mysql-test/main/ctype_utf8mb4_uca.test b/mysql-test/main/ctype_utf8mb4_uca.test index a11db5628b9..095f1a6d0f4 100644 --- a/mysql-test/main/ctype_utf8mb4_uca.test +++ b/mysql-test/main/ctype_utf8mb4_uca.test @@ -448,3 +448,30 @@ SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_turkish_ai_ci; --echo # --echo # End of 10.10 tests --echo # + + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; +--source include/ctype_tailoring_view_create.inc +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_czech_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_ai_cs; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_as_ci; +--source include/ctype_tailoring_01_probe.inc + +SET NAMES utf8mb4 COLLATE utf8mb4_uca1400_as_cs; +--source include/ctype_tailoring_01_probe.inc +--source include/ctype_tailoring_view_drop.inc + +--echo # End of 11.8 tests diff --git a/mysql-test/main/custom_aggregate_functions.result b/mysql-test/main/custom_aggregate_functions.result index da0a411d8ce..1a038c5ad2a 100644 --- a/mysql-test/main/custom_aggregate_functions.result +++ b/mysql-test/main/custom_aggregate_functions.result @@ -1222,3 +1222,71 @@ ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK DO FETCH GROUP NEXT ROW; ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context # End of 10.4 tests +# +# MDEV-38004 Double free on repeated execution of prepared aggregate +# function against empty table in Query_arena::free_items() +# +create aggregate function agg_cnt() returns int +begin +declare z int default 0; +declare continue handler for not found return z; +loop +fetch group next row; +set z= z+1; +end loop; +end| +create table t1 (id int); +prepare stmt from "select agg_cnt() from t1"; +execute stmt; +agg_cnt() +NULL +execute stmt; +agg_cnt() +NULL +insert into t1 values (1),(2),(2); +execute stmt; +agg_cnt() +3 +execute stmt; +agg_cnt() +3 +deallocate prepare stmt; +# +# Compare with +select agg_cnt() from t1; +agg_cnt() +3 +prepare stmt from "select id, agg_cnt() from t1 group by id with rollup"; +execute stmt; +id agg_cnt() +1 1 +2 2 +NULL 3 +execute stmt; +id agg_cnt() +1 1 +2 2 +NULL 3 +deallocate prepare stmt; +# +# The same item is reused between two CALLs of a stored procedure +# +delete from t1; +create procedure p() select agg_cnt() from t1; +call p(); +agg_cnt() +NULL +call p(); +agg_cnt() +NULL +insert into t1 values (1),(2),(2); +call p(); +agg_cnt() +3 +call p(); +agg_cnt() +3 +drop procedure p; +drop function agg_cnt; +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/custom_aggregate_functions.test b/mysql-test/main/custom_aggregate_functions.test index cf103264569..f632c64cd27 100644 --- a/mysql-test/main/custom_aggregate_functions.test +++ b/mysql-test/main/custom_aggregate_functions.test @@ -1062,3 +1062,55 @@ CREATE EVENT ev1 DO FETCH GROUP NEXT ROW; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-38004 Double free on repeated execution of prepared aggregate +--echo # function against empty table in Query_arena::free_items() +--echo # + +--delimiter | +create aggregate function agg_cnt() returns int +begin +declare z int default 0; +declare continue handler for not found return z; +loop +fetch group next row; +set z= z+1; +end loop; +end| +--delimiter ; + +create table t1 (id int); +prepare stmt from "select agg_cnt() from t1"; +execute stmt; +execute stmt; +insert into t1 values (1),(2),(2); +execute stmt; +execute stmt; +deallocate prepare stmt; +--echo # +--echo # Compare with +select agg_cnt() from t1; + +prepare stmt from "select id, agg_cnt() from t1 group by id with rollup"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +--echo # +--echo # The same item is reused between two CALLs of a stored procedure +--echo # +delete from t1; +create procedure p() select agg_cnt() from t1; +call p(); +call p(); +insert into t1 values (1),(2),(2); +call p(); +call p(); + +# Cleanup +drop procedure p; +drop function agg_cnt; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index e1a462f7e50..389920d639a 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1987,3 +1987,23 @@ ERROR HY000: Encountered illegal format of dynamic column string SELECT COLUMN_JSON(CONCAT(0x040200020001000000000000004241, REPEAT('D', 512))); ERROR HY000: Encountered illegal format of dynamic column string # End of 10.6 tests +# +# MDEV-41144 Assertion `scale <= precision' failed in decimal_bin_size +# +SELECT COLUMN_JSON(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex; +ERROR HY000: Encountered illegal format of dynamic column string +SELECT COLUMN_CHECK(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex; +ex +0 +# +# Round trip check: a decimal scale beyond the SQL-layer +# DECIMAL_MAX_SCALE (38) must still be readable, since the dyncol +# format itself allows up to DECIMAL_MAX_POSSIBLE_PRECISION (81). +# +SELECT COLUMN_JSON(COLUMN_CREATE(1, '0.123456789012345678901234567890123456789' AS decimal)) AS ex; +ex +{"1":0.1234567890123456789012345678901234567} +SELECT COLUMN_CHECK(COLUMN_CREATE(1, 0.1234567890123456789012345678901234567890123456789 AS decimal)) AS ex; +ex +1 +# End of 10.11 tests diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index 8c8cd647240..4dc82d29bfd 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -1044,3 +1044,20 @@ SELECT COLUMN_LIST(0x040100FFFF00000300666F6F21626172); SELECT COLUMN_JSON(CONCAT(0x040200020001000000000000004241, REPEAT('D', 512))); --echo # End of 10.6 tests + +--echo # +--echo # MDEV-41144 Assertion `scale <= precision' failed in decimal_bin_size +--echo # +--error ER_DYN_COL_WRONG_FORMAT +SELECT COLUMN_JSON(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex; +SELECT COLUMN_CHECK(0x010300070004000D007D000F000D00DFE9CE2BA3BCF60303FF290D71CD4C14D50F0000E03D0F001309890E67F466037DC899337129E8) AS ex; + +--echo # +--echo # Round trip check: a decimal scale beyond the SQL-layer +--echo # DECIMAL_MAX_SCALE (38) must still be readable, since the dyncol +--echo # format itself allows up to DECIMAL_MAX_POSSIBLE_PRECISION (81). +--echo # +SELECT COLUMN_JSON(COLUMN_CREATE(1, '0.123456789012345678901234567890123456789' AS decimal)) AS ex; +SELECT COLUMN_CHECK(COLUMN_CREATE(1, 0.1234567890123456789012345678901234567890123456789 AS decimal)) AS ex; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/fulltext.result b/mysql-test/main/fulltext.result index b7caf4f7663..b16ea49453d 100644 --- a/mysql-test/main/fulltext.result +++ b/mysql-test/main/fulltext.result @@ -791,3 +791,34 @@ CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria; ALTER TABLE tmp ADD FULLTEXT (a); INSERT INTO tmp VALUES ('foo'); DROP TABLE tmp; +# +# MDEV-32383 Server crashes in Item_func_match::init_search on 2nd execution of PS +# +CREATE TABLE t (a VARCHAR(255), FULLTEXT(a)); +INSERT INTO t VALUES ('MariaDB'),('MariaDB server'), +('foo'),('bar'),('baz'),('qux'),('quux'),('corge'); +CREATE VIEW v AS +SELECT MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) AS f +FROM t +WHERE MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) > 0 +ORDER BY f; +# all three must return the same rows in the same order +SELECT ROUND(f,6) FROM v ORDER BY f; +ROUND(f,6) +1.073912 +1.086122 +PREPARE stmt FROM "SELECT ROUND(f,6) FROM v ORDER BY f"; +EXECUTE stmt; +ROUND(f,6) +1.073912 +1.086122 +EXECUTE stmt; +ROUND(f,6) +1.073912 +1.086122 +DEALLOCATE PREPARE stmt; +DROP VIEW v; +DROP TABLE t; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/fulltext.test b/mysql-test/main/fulltext.test index acc016b082e..a80d580c0ea 100644 --- a/mysql-test/main/fulltext.test +++ b/mysql-test/main/fulltext.test @@ -738,3 +738,31 @@ CREATE TEMPORARY TABLE tmp (a TEXT) ENGINE=Aria; ALTER TABLE tmp ADD FULLTEXT (a); INSERT INTO tmp VALUES ('foo'); DROP TABLE tmp; + +--echo # +--echo # MDEV-32383 Server crashes in Item_func_match::init_search on 2nd execution of PS +--echo # + +CREATE TABLE t (a VARCHAR(255), FULLTEXT(a)); +INSERT INTO t VALUES ('MariaDB'),('MariaDB server'), + ('foo'),('bar'),('baz'),('qux'),('quux'),('corge'); + +CREATE VIEW v AS + SELECT MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) AS f + FROM t + WHERE MATCH (a) AGAINST ('MariaDB' IN NATURAL LANGUAGE MODE) > 0 + ORDER BY f; + +--echo # all three must return the same rows in the same order +SELECT ROUND(f,6) FROM v ORDER BY f; +PREPARE stmt FROM "SELECT ROUND(f,6) FROM v ORDER BY f"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP VIEW v; +DROP TABLE t; + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/mysql-test/main/func_concat.result b/mysql-test/main/func_concat.result index 4b91fb97c6c..cbb25364552 100644 --- a/mysql-test/main/func_concat.result +++ b/mysql-test/main/func_concat.result @@ -304,3 +304,12 @@ f NULL DROP TABLE t1; # End of 10.5 tests +# Start of 10.11 tests +# +# MDEV-40673: Preserve the results of JSON_TYPE and GET_FORMAT in CONCAT +# +SELECT CONCAT(JSON_TYPE('{"a":1}'),'X') AS json_type, +CONCAT(GET_FORMAT(DATE, 'USA'), 'X') AS get_format; +json_type get_format +OBJECTX %m.%d.%YX +# End of 10.11 tests diff --git a/mysql-test/main/func_concat.test b/mysql-test/main/func_concat.test index f93b150f88f..7fdd7ca2977 100644 --- a/mysql-test/main/func_concat.test +++ b/mysql-test/main/func_concat.test @@ -281,3 +281,11 @@ SELECT CONCAT_WS(' ', a, b, PASSWORD(c)) AS f FROM t1 GROUP BY f WITH ROLLUP; DROP TABLE t1; --echo # End of 10.5 tests + +--echo # Start of 10.11 tests +--echo # +--echo # MDEV-40673: Preserve the results of JSON_TYPE and GET_FORMAT in CONCAT +--echo # +SELECT CONCAT(JSON_TYPE('{"a":1}'),'X') AS json_type, + CONCAT(GET_FORMAT(DATE, 'USA'), 'X') AS get_format; +--echo # End of 10.11 tests diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index d094c43dccc..c9392511866 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -2724,6 +2724,47 @@ SELECT JSON_OVERLAPS(@json1, @json2); JSON_OVERLAPS(@json1, @json2) 0 # +# MDEV-41067: Empty and nonempty nested JSON arrays +# +SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS forward, +JSON_OVERLAPS('[[]]', '[[1]]') AS reverse; +forward reverse +0 0 +SELECT JSON_OVERLAPS('[[1],[2]]', '[[],[2]]') AS forward, +JSON_OVERLAPS('[[],[2]]', '[[1],[2]]') AS reverse; +forward reverse +1 1 +SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS forward, +JSON_OVERLAPS('[[1,2]]', '[[1]]') AS reverse; +forward reverse +0 0 +SELECT JSON_OVERLAPS('[[]]', '[[]]') AS r; +r +1 +SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],2]]') AS r; +r +1 +SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],3]]') AS forward, +JSON_OVERLAPS('[[[1],3]]', '[[[1],2]]') AS reverse; +forward reverse +0 0 +SELECT JSON_OVERLAPS('[[[],1],[4]]', '[[{},1],[4]]') AS forward, +JSON_OVERLAPS('[[{},1],[4]]', '[[[],1],[4]]') AS reverse; +forward reverse +1 1 +SELECT JSON_OVERLAPS('[[true]]', '[[1]]') AS forward, +JSON_OVERLAPS('[[1]]', '[[true]]') AS reverse; +forward reverse +0 0 +SELECT JSON_OVERLAPS('[[1,2]]', '[[2,1]]') AS forward, +JSON_OVERLAPS('[[2,1]]', '[[1,2]]') AS reverse; +forward reverse +0 0 +SELECT JSON_OVERLAPS('{"a":[1],"b":2}', '{"a":[],"b":2}') AS forward, +JSON_OVERLAPS('{"a":[],"b":2}', '{"a":[1],"b":2}') AS reverse; +forward reverse +1 1 +# # MDEV-30304: Json Range only affects first row of the result set # CREATE TABLE t1 ( j JSON ); @@ -3107,6 +3148,20 @@ NULL ["a", "b"] NULL {"r": 1} NULL NULL [{"a": 3}, {"d": [1, 2, 3]}] [{"d": [1E0, 2E0, 3E0]}, {"a":3E0}] 1 DROP TABLE t; +# +# MDEV-39049: Memory corruption & crash in check_key_in_list upon +# using JSON_KEYS after modifying character set name/collation +# +SET SESSION character_set_database=utf32; +SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}'); +JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}') +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 25 +SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }'); +JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }') +["", "k2"] +SET SESSION character_set_database= default; # End of 10.11 Test # # MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 1ed745ba9da..c340bd76408 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1917,6 +1917,28 @@ SET @json2 = '{"kk":{"k1":"v1","k2":"v2","k3":"v3"}}'; SELECT JSON_OVERLAPS(@json2, @json1); SELECT JSON_OVERLAPS(@json1, @json2); +--echo # +--echo # MDEV-41067: Empty and nonempty nested JSON arrays +--echo # +SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS forward, + JSON_OVERLAPS('[[]]', '[[1]]') AS reverse; +SELECT JSON_OVERLAPS('[[1],[2]]', '[[],[2]]') AS forward, + JSON_OVERLAPS('[[],[2]]', '[[1],[2]]') AS reverse; +SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS forward, + JSON_OVERLAPS('[[1,2]]', '[[1]]') AS reverse; +SELECT JSON_OVERLAPS('[[]]', '[[]]') AS r; +SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],2]]') AS r; +SELECT JSON_OVERLAPS('[[[1],2]]', '[[[1],3]]') AS forward, + JSON_OVERLAPS('[[[1],3]]', '[[[1],2]]') AS reverse; +SELECT JSON_OVERLAPS('[[[],1],[4]]', '[[{},1],[4]]') AS forward, + JSON_OVERLAPS('[[{},1],[4]]', '[[[],1],[4]]') AS reverse; +SELECT JSON_OVERLAPS('[[true]]', '[[1]]') AS forward, + JSON_OVERLAPS('[[1]]', '[[true]]') AS reverse; +SELECT JSON_OVERLAPS('[[1,2]]', '[[2,1]]') AS forward, + JSON_OVERLAPS('[[2,1]]', '[[1,2]]') AS reverse; +SELECT JSON_OVERLAPS('{"a":[1],"b":2}', '{"a":[],"b":2}') AS forward, + JSON_OVERLAPS('{"a":[],"b":2}', '{"a":[1],"b":2}') AS reverse; + --echo # --echo # MDEV-30304: Json Range only affects first row of the result set --echo # @@ -2169,6 +2191,14 @@ SELECT c1, JSON_OVERLAPS(c1, '{"r": 1E0}') AS jo_c1_const FROM t; SELECT c1, c2, JSON_OVERLAPS(c1, c2) AS jo_c1_c2 FROM t; DROP TABLE t; +--echo # +--echo # MDEV-39049: Memory corruption & crash in check_key_in_list upon +--echo # using JSON_KEYS after modifying character set name/collation +--echo # +SET SESSION character_set_database=utf32; +SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}'); +SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }'); +SET SESSION character_set_database= default; --echo # End of 10.11 Test --echo # diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index e1e3f4db15e..aac251fa448 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -496,7 +496,16 @@ select 1=_latin2'1'; 1=_latin2'1' 1 select _latin1'1'=_latin2'1'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' +_latin1'1'=_latin2'1' +1 +select _latin1'a'=_latin7'a'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_general_ci,COERCIBLE) for operation '=' +select _latin1'1'=_latin7'1'; +_latin1'1'=_latin7'1' +1 +select _latin1'' = _latin7''; +_latin1'' = _latin7'' +1 select row('a','b','c') = row('a','b','c'); row('a','b','c') = row('a','b','c') 1 @@ -532,9 +541,15 @@ select FIELD('b','A' COLLATE latin1_bin,'B'); FIELD('b','A' COLLATE latin1_bin,'B') 0 select FIELD(_latin2'b','A','B'); -ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +FIELD(_latin2'b','A','B') +2 select FIELD('b',_latin2'A','B'); -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +FIELD('b',_latin2'A','B') +2 +select FIELD(_latin7'b','A','B'); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +select FIELD('b',_latin7'A','B'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' select FIELD('1',_latin2'3','2',1); FIELD('1',_latin2'3','2',1) 3 @@ -550,14 +565,20 @@ POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd') select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_general_ci,EXPLICIT) for operation 'locate' select POSITION(_latin1'B' IN _latin2'abcd'); -ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'locate' +POSITION(_latin1'B' IN _latin2'abcd') +2 select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); FIND_IN_SET(_latin1'B',_latin1'a,b,c,d') 2 +select POSITION(_latin1'B' IN _latin7'abcd'); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'locate' select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'find_in_set' select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'find_in_set' +FIND_IN_SET(_latin1'B',_latin2'a,b,c,d') +2 +select FIND_IN_SET(_latin1'B',_latin7'a,b,c,d'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_general_ci,COERCIBLE) for operation 'find_in_set' select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2) abcdabc @@ -578,11 +599,20 @@ select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin 0 select _latin2'B' between _latin1'a' and _latin1'b'; -ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +_latin2'B' between _latin1'a' and _latin1'b' +1 select _latin1'B' between _latin2'a' and _latin1'b'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +_latin1'B' between _latin2'a' and _latin1'b' +1 select _latin1'B' between _latin1'a' and _latin2'b'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation 'between' +_latin1'B' between _latin1'a' and _latin2'b' +1 +select _latin1'B' between _latin7'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' between _latin1'a' and _latin7'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin7_general_ci,COERCIBLE) for operation 'between' +select _latin7'B' between _latin1'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation 'between' select _latin1'B' in (_latin1'a',_latin1'b'); @@ -598,11 +628,20 @@ select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin) 0 select _latin2'B' in (_latin1'a',_latin1'b'); -ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'in' +_latin2'B' in (_latin1'a',_latin1'b') +1 select _latin1'B' in (_latin2'a',_latin1'b'); -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'in' +_latin1'B' in (_latin2'a',_latin1'b') +1 select _latin1'B' in (_latin1'a',_latin2'b'); -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation 'in' +_latin1'B' in (_latin1'a',_latin2'b') +1 +select _latin1'B' in (_latin1'a',_latin7'b'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin7_general_ci,COERCIBLE) for operation 'in' +select _latin7'B' in (_latin1'a',_latin1'b'); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'in' +select _latin1'B' in (_latin7'a',_latin1'b'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin7_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'in' select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation 'in' select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE latin1_bin); diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 279e6265352..e34bc891da8 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -285,8 +285,21 @@ select 1=_latin1'1'; select _latin1'1'=1; select _latin2'1'=1; select 1=_latin2'1'; ---error 1267 select _latin1'1'=_latin2'1'; + +# The tests using latin7_general_ci below expect an error: this collation +# has anomalies on the ASCII letters, so it is not compatible with other +# collations even on ASCII-only strings with letters. +--error ER_CANT_AGGREGATE_2COLLATIONS +select _latin1'a'=_latin7'a'; + +# But the ASCII digits are sorted in the same way in all collations +select _latin1'1'=_latin7'1'; + +# The empty string has repertoire NONE on both sides, so it is always +# compatible, regardless of collation anomalies. +select _latin1'' = _latin7''; + select row('a','b','c') = row('a','b','c'); select row('A','b','c') = row('a','b','c'); select row('A' COLLATE latin1_bin,'b','c') = row('a','b','c'); @@ -298,8 +311,10 @@ select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,' select concat(_latin1'a',_latin2'a'); --error 1270 select concat(_latin1'a',_latin2'a',_latin5'a'); ---error 1271 + +--error ER_CANT_AGGREGATE_NCOLLATIONS select concat(_latin1'a',_latin2'a',_latin5'a',_latin7'a'); + --error 1267 select concat_ws(_latin1'a',_latin2'a'); @@ -312,10 +327,14 @@ select FIELD('b' COLLATE latin1_bin,'A','B'); select FIELD('b','A' COLLATE latin1_bin,'B'); #enable after fix MDEV-29601 --disable_service_connection ---error 1270 select FIELD(_latin2'b','A','B'); ---error 1270 select FIELD('b',_latin2'A','B'); + +--error ER_CANT_AGGREGATE_3COLLATIONS +select FIELD(_latin7'b','A','B'); +--error ER_CANT_AGGREGATE_3COLLATIONS +select FIELD('b',_latin7'A','B'); + --enable_service_connection select FIELD('1',_latin2'3','2',1); @@ -324,11 +343,13 @@ select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); --error 1267 select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); ---error 1267 select POSITION(_latin1'B' IN _latin2'abcd'); select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); +--error ER_CANT_AGGREGATE_2COLLATIONS +select POSITION(_latin1'B' IN _latin7'abcd'); + # fix this: --disable_parsing select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d' COLLATE latin1_bin); @@ -337,9 +358,11 @@ select FIND_IN_SET(_latin1'B' COLLATE latin1_bin,_latin1'a,b,c,d'); --error 1267 select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); ---error 1267 select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); +--error ER_CANT_AGGREGATE_2COLLATIONS +select FIND_IN_SET(_latin1'B',_latin7'a,b,c,d'); + select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); # fix this: @@ -357,12 +380,17 @@ select _latin1'B' between _latin1'a' and _latin1'c'; select _latin1'B' collate latin1_bin between _latin1'a' and _latin1'c'; select _latin1'B' between _latin1'a' collate latin1_bin and _latin1'c'; select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; ---error 1270 select _latin2'B' between _latin1'a' and _latin1'b'; ---error 1270 select _latin1'B' between _latin2'a' and _latin1'b'; ---error 1270 select _latin1'B' between _latin1'a' and _latin2'b'; + +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin1'B' between _latin7'a' and _latin1'b'; +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin1'B' between _latin1'a' and _latin7'b'; +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin7'B' between _latin1'a' and _latin1'b'; + --error 1270 select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; @@ -370,12 +398,17 @@ select _latin1'B' in (_latin1'a',_latin1'b'); select _latin1'B' collate latin1_bin in (_latin1'a',_latin1'b'); select _latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b'); select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); ---error 1270 select _latin2'B' in (_latin1'a',_latin1'b'); ---error 1270 select _latin1'B' in (_latin2'a',_latin1'b'); ---error 1270 select _latin1'B' in (_latin1'a',_latin2'b'); + +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin1'B' in (_latin1'a',_latin7'b'); +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin7'B' in (_latin1'a',_latin1'b'); +--error ER_CANT_AGGREGATE_3COLLATIONS +select _latin1'B' in (_latin7'a',_latin1'b'); + --error 1270 select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); --error 1270 diff --git a/mysql-test/main/func_test.result b/mysql-test/main/func_test.result index b5d11ab5291..81b41670303 100644 --- a/mysql-test/main/func_test.result +++ b/mysql-test/main/func_test.result @@ -110,8 +110,8 @@ _koi8r'a' COLLATE koi8r_bin = _koi8r'A' 0 select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; ERROR HY000: Illegal mix of collations (koi8r_bin,EXPLICIT) and (koi8r_general_ci,EXPLICIT) for operation '=' -select _koi8r'a' = _latin1'A'; -ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +select concat(_koi8r'a', _latin1'A'); +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'concat' select strcmp(_koi8r'a', _koi8r'A'); strcmp(_koi8r'a', _koi8r'A') 0 @@ -130,7 +130,10 @@ strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A') select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'strcmp' select strcmp(_koi8r'a', _latin1'A'); -ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'strcmp' +strcmp(_koi8r'a', _latin1'A') +0 +select strcmp(_latin7'a', _latin1'A'); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'strcmp' select _koi8r'a' LIKE _koi8r'A'; _koi8r'a' LIKE _koi8r'A' 1 @@ -149,7 +152,10 @@ _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A' select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'like' select _koi8r'a' LIKE _latin1'A'; -ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like' +_koi8r'a' LIKE _latin1'A' +1 +select _latin7'a' LIKE _latin1'A'; +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like' CREATE TABLE t1 ( faq_group_id int(11) NOT NULL default '0', faq_id int(11) NOT NULL default '0', title varchar(240) default NULL, keywords text, description longblob, solution longblob, status tinyint(4) NOT NULL default '0', access_id smallint(6) default NULL, lang_id smallint(6) NOT NULL default '0', created datetime NOT NULL default '0000-00-00 00:00:00', updated datetime default NULL, last_access datetime default NULL, last_notify datetime default NULL, solved_count int(11) NOT NULL default '0', static_solved int(11) default NULL, solved_1 int(11) default NULL, solved_2 int(11) default NULL, solved_3 int(11) default NULL, solved_4 int(11) default NULL, solved_5 int(11) default NULL, expires datetime default NULL, notes text, assigned_to smallint(6) default NULL, assigned_group smallint(6) default NULL, last_edited_by smallint(6) default NULL, orig_ref_no varchar(15) binary default NULL, c$fundstate smallint(6) default NULL, c$contributor smallint(6) default NULL, UNIQUE KEY t1$faq_id (faq_id), KEY t1$group_id$faq_id (faq_group_id,faq_id), KEY t1$c$fundstate (c$fundstate) ) ENGINE=MyISAM; INSERT INTO t1 VALUES (82,82,'How to use the DynaVox Usage Counts Feature','usages count, number, corner, white, box, button','\r\n\r\n \r\n \r\n \r\n \r\n
 \r\n

How \r\n To: \r\n Display or Hide the Usage Counts to find out how many times each button is being selected.

\r\n
','\r\n \r\n \r\n \r\n \r\n\r\n \r\n
  \r\n \r\n

1. Select \r\n the On/Setup button to access the DynaVox Setup Menu.
\r\n 2. Select Button Features.
\r\n 3. Below the OK button is the Usage Counts button.
\r\n a. If it says \"Hidden\" then the Usage Counts will not be displayed.
\r\n b. If it says \"Displayed\" then the Usage Counts will be shown.
\r\n c. Select the Usage Counts Option Ring once and it will toggle \r\n to the alternative option.
\r\n 4. Once the correct setting has been chosen, select OK to leave the Button \r\n Features menu.
\r\n 5. Select OK out of the Setup menu and return to the communication \r\n page.

\r\n

For \r\n further information on Usage Counts, see the Button Features \r\n Menu Entry in the DynaVox/DynaMyte Reference Manual.

\r\n
',4,1,1,'2001-11-16 16:43:34','2002-11-25 12:09:43','2003-07-24 01:04:48',NULL,11,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,11,NULL,NULL,NULL); CREATE TABLE t2 ( access_id smallint(6) NOT NULL default '0', name varchar(20) binary default NULL, rank smallint(6) NOT NULL default '0', KEY t2$access_id (access_id) ) ENGINE=MyISAM; diff --git a/mysql-test/main/func_test.test b/mysql-test/main/func_test.test index fe0b5e326f0..30c7c90398f 100644 --- a/mysql-test/main/func_test.test +++ b/mysql-test/main/func_test.test @@ -53,7 +53,7 @@ select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; --error 1267 select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; --error 1267 -select _koi8r'a' = _latin1'A'; +select concat(_koi8r'a', _latin1'A'); select strcmp(_koi8r'a', _koi8r'A'); select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); @@ -62,8 +62,10 @@ select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); --error 1267 select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); ---error 1267 select strcmp(_koi8r'a', _latin1'A'); +# latin7_general_ci has anomalies on the ASCII range +--error ER_CANT_AGGREGATE_2COLLATIONS +select strcmp(_latin7'a', _latin1'A'); select _koi8r'a' LIKE _koi8r'A'; select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; @@ -72,8 +74,10 @@ select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; --error 1267 select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; ---error 1267 select _koi8r'a' LIKE _latin1'A'; +# latin7_general_ci has anomalies on the ASCII range +--error ER_CANT_AGGREGATE_2COLLATIONS +select _latin7'a' LIKE _latin1'A'; # # Test for LEAST() BUG in LEFT JOIN diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index ca743d6540e..b5d91f3c188 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -1266,8 +1266,11 @@ select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) # set names swe7; -select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; +select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),'[ull')) from t1; ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (swe7_swedish_ci,COERCIBLE) for operation 'concat' +select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; +concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) +# set names latin1; set lc_time_names=fr_FR; select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index c0e5bad2fc4..f8ab21f4bbb 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -768,9 +768,14 @@ insert into t1 values ('070514-000000'); # is safe with the default locale en_US --replace_column 1 # select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; -# Error for swe7: it is not ASCII compatible +# Error for swe7: it is not ASCII compatible, +# e.g. 0x5B is LATIN CAPITAL LETTER A WITH DIAERESIS in swe7 set names swe7; --error 1267 +select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),'[ull')) from t1; +# But swe7 strings consisting only of ASCII letters, digits and spaces +# are the same in swe7 and ASCII, so the conversion is safe +--replace_column 1 # select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; set names latin1; # Conversion of date_format() result to ASCII diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index 4be6f3b9134..db1da7b02e5 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -969,4 +969,188 @@ disconnect con1; connection default; drop procedure mysql.p1; drop user u@localhost; +# +# MDEV-41099 HANDLER READ missing column privilege check +# +create database db; +create table db.t (id int primary key, a varchar(64), b int); +insert into db.t values (1,'tok1',100), (2,'tok2',200); +create user u@localhost; +grant select (id) on db.t to u@localhost; +connect con1, localhost, u, , db; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +handler t read first; +ERROR 42S02: Unknown table 't' in HANDLER +connection default; +grant select (a, b) on db.t to u@localhost; +connection con1; +handler t open; +handler t read first; +id a b +1 tok1 100 +connect con2, localhost, root; +flush tables db.t; +connection default; +connection con1; +select 1 from information_schema.character_sets limit 1; +1 +1 +connection con2; +disconnect con2; +connection con1; +handler t read next; +id a b +1 tok1 100 +# reopen after a column without privilege was added +connect con2, localhost, root; +alter table db.t add column c int default 42; +connection default; +connection con1; +select 1 from information_schema.character_sets limit 1; +1 +1 +connection con2; +disconnect con2; +connection con1; +handler t read first; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +handler t close; +# reopen after privileges changed +connection default; +grant select (c) on db.t to u@localhost; +connection con1; +handler t open; +handler t read first; +id a b c +1 tok1 100 42 +connection default; +revoke select (id, a, b, c) on db.t from u@localhost; +grant select on db.t to u@localhost; +connection con1; +connect con2, localhost, root; +flush tables db.t; +connection default; +connection con1; +select 1 from information_schema.character_sets limit 1; +1 +1 +connection con2; +disconnect con2; +connection con1; +handler t read next; +id a b c +1 tok1 100 42 +connection default; +revoke select on db.t from u@localhost; +connection con1; +connect con2, localhost, root; +flush tables db.t; +connection default; +connection con1; +select 1 from information_schema.character_sets limit 1; +1 +1 +connection con2; +disconnect con2; +connection con1; +handler t read next; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +connection default; +grant select (id, a, b, c) on db.t to u@localhost; +connection con1; +handler t read next; +id a b c +1 tok1 100 42 +handler t close; +connection default; +revoke select (id, a, b, c) on db.t from u@localhost; +connection con1; +# column grants through a role +connection default; +create role r; +grant select (id) on db.t to r; +grant r to u@localhost; +connection con1; +set role r; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +connection default; +grant select (a, b, c) on db.t to r; +connection con1; +handler t open; +handler t read first; +id a b c +1 tok1 100 42 +handler t close; +set role none; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +# column grants to PUBLIC +connection default; +grant select (id) on db.t to public; +connection con1; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +connection default; +grant select (a, b, c) on db.t to public; +connection con1; +handler t open; +handler t read first; +id a b c +1 tok1 100 42 +handler t close; +# column grants split between PUBLIC and a role +connection default; +revoke select (a, b, c) on db.t from public; +revoke select (id) on db.t from r; +connection con1; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +set role r; +handler t open; +handler t read first; +id a b c +1 tok1 100 42 +handler t close; +disconnect con1; +connection default; +revoke select (id) on db.t from public; +delete from mysql.global_priv where user="PUBLIC"; +flush privileges; +drop role r; +drop user u@localhost; +drop database db; +# Invisible columns: INVISIBLE_USER (a) needs a grant, +# INVISIBLE_SYSTEM (row_start, row_end) and INVISIBLE_FULL +# (DB_ROW_HASH_1) need none, as for SELECT +create database db; +create table db.t (id int primary key, a int invisible, b blob, unique(b)) +with system versioning; +set time_zone= '+00:00'; +set timestamp= unix_timestamp('2001-01-01 00:00:00'); +insert into db.t (id, a, b) values (1, 10, 'x'); +set timestamp= default; +set time_zone= default; +create user u@localhost; +grant select (id, b) on db.t to u@localhost; +connect con1, localhost, u, , db; +handler t open; +ERROR 42000: SELECT command denied to user 'u'@'localhost' for table `db`.`t` +connection default; +grant select (a) on db.t to u@localhost; +connection con1; +set time_zone= '+00:00'; +select row_start, row_end from t; +row_start row_end +2001-01-01 00:00:00.000000 2106-02-07 06:28:15.999999 +handler t open; +handler t read first; +id a b row_start row_end DB_ROW_HASH_1 +1 10 x 2001-01-01 00:00:00.000000 2106-02-07 06:28:15.999999 # +handler t close; +disconnect con1; +connection default; +drop user u@localhost; +drop database db; # End of 10.11 tests diff --git a/mysql-test/main/grant2.test b/mysql-test/main/grant2.test index 9b6b2d1c5ec..916fbc73413 100644 --- a/mysql-test/main/grant2.test +++ b/mysql-test/main/grant2.test @@ -1046,4 +1046,144 @@ connection default; drop procedure mysql.p1; drop user u@localhost; +--echo # +--echo # MDEV-41099 HANDLER READ missing column privilege check +--echo # +create database db; +create table db.t (id int primary key, a varchar(64), b int); +insert into db.t values (1,'tok1',100), (2,'tok2',200); +create user u@localhost; +grant select (id) on db.t to u@localhost; +connect con1, localhost, u, , db; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; +--error ER_UNKNOWN_TABLE +handler t read first; +connection default; +grant select (a, b) on db.t to u@localhost; +connection con1; +handler t open; +handler t read first; +let $ddl= flush tables db.t; +--source grant2_handler_reopen.inc +handler t read next; + +--echo # reopen after a column without privilege was added +let $ddl= alter table db.t add column c int default 42; +--source grant2_handler_reopen.inc +--error ER_TABLEACCESS_DENIED_ERROR +handler t read first; +handler t close; + +--echo # reopen after privileges changed +connection default; +grant select (c) on db.t to u@localhost; +connection con1; +handler t open; +handler t read first; +connection default; +revoke select (id, a, b, c) on db.t from u@localhost; +grant select on db.t to u@localhost; +connection con1; +let $ddl= flush tables db.t; +--source grant2_handler_reopen.inc +handler t read next; +connection default; +revoke select on db.t from u@localhost; +connection con1; +let $ddl= flush tables db.t; +--source grant2_handler_reopen.inc +--error ER_TABLEACCESS_DENIED_ERROR +handler t read next; +connection default; +grant select (id, a, b, c) on db.t to u@localhost; +connection con1; +handler t read next; +handler t close; +connection default; +revoke select (id, a, b, c) on db.t from u@localhost; +connection con1; + +--echo # column grants through a role +connection default; +create role r; +grant select (id) on db.t to r; +grant r to u@localhost; +connection con1; +set role r; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; +connection default; +grant select (a, b, c) on db.t to r; +connection con1; +handler t open; +handler t read first; +handler t close; +set role none; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; + +--echo # column grants to PUBLIC +connection default; +grant select (id) on db.t to public; +connection con1; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; +connection default; +grant select (a, b, c) on db.t to public; +connection con1; +handler t open; +handler t read first; +handler t close; + +--echo # column grants split between PUBLIC and a role +connection default; +revoke select (a, b, c) on db.t from public; +revoke select (id) on db.t from r; +connection con1; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; +set role r; +handler t open; +handler t read first; +handler t close; +disconnect con1; +connection default; +revoke select (id) on db.t from public; +delete from mysql.global_priv where user="PUBLIC"; +flush privileges; +drop role r; +drop user u@localhost; +drop database db; + +--echo # Invisible columns: INVISIBLE_USER (a) needs a grant, +--echo # INVISIBLE_SYSTEM (row_start, row_end) and INVISIBLE_FULL +--echo # (DB_ROW_HASH_1) need none, as for SELECT +create database db; +create table db.t (id int primary key, a int invisible, b blob, unique(b)) + with system versioning; +set time_zone= '+00:00'; +set timestamp= unix_timestamp('2001-01-01 00:00:00'); +insert into db.t (id, a, b) values (1, 10, 'x'); +set timestamp= default; +set time_zone= default; +create user u@localhost; +grant select (id, b) on db.t to u@localhost; +connect con1, localhost, u, , db; +--error ER_TABLEACCESS_DENIED_ERROR +handler t open; +connection default; +grant select (a) on db.t to u@localhost; +connection con1; +set time_zone= '+00:00'; +select row_start, row_end from t; +handler t open; +--replace_column 6 # +handler t read first; +handler t close; +disconnect con1; +connection default; +drop user u@localhost; +drop database db; + --echo # End of 10.11 tests diff --git a/mysql-test/main/grant2_handler_reopen.inc b/mysql-test/main/grant2_handler_reopen.inc new file mode 100644 index 00000000000..c9c3b197ece --- /dev/null +++ b/mysql-test/main/grant2_handler_reopen.inc @@ -0,0 +1,17 @@ +# Forces HANDLER tables of connection con1 to be reopened on next read: +# $ddl (exclusive MDL) waits for con1 to close the handler table, which +# happens when con1 opens any other table. +# Expects connection con1 to exist and con2 not to exist. + +connect con2, localhost, root; +send_eval $ddl; +connection default; +let $wait_condition= select count(*) = 1 from information_schema.processlist + where state = 'Waiting for table metadata lock' and info = '$ddl'; +--source include/wait_condition.inc +connection con1; +select 1 from information_schema.character_sets limit 1; +connection con2; +reap; +disconnect con2; +connection con1; diff --git a/mysql-test/main/group_by.result b/mysql-test/main/group_by.result index c9a937c14c8..b1bd1f900cb 100644 --- a/mysql-test/main/group_by.result +++ b/mysql-test/main/group_by.result @@ -3043,7 +3043,7 @@ EXPLAIN { "query_block": { "select_id": 1, - "pseudo_bits_condition": "if(uuid_short(),NULL,1)", + "outer_ref_condition": "if(uuid_short(),NULL,1)", "nested_loop": [ { "table": { @@ -3069,7 +3069,7 @@ EXPLAIN { "query_block": { "select_id": 1, - "pseudo_bits_condition": "10 = rand()", + "outer_ref_condition": "10 = rand()", "nested_loop": [ { "table": { diff --git a/mysql-test/main/having_cond_pushdown.result b/mysql-test/main/having_cond_pushdown.result index eaf0421a0e4..1a3efd81e48 100644 --- a/mysql-test/main/having_cond_pushdown.result +++ b/mysql-test/main/having_cond_pushdown.result @@ -6609,3 +6609,71 @@ a 0 DROP TABLE t1; # End of 10.11 tests +# +# MDEV-32412 Pushdown from HAVING: Item_func is immutable while arguments are not +# +CREATE TABLE t1 (a int); +INSERT INTO t1 values (1),(2),(3); +SELECT a FROM ( SELECT a, 1 AS b FROM t1 ) AS dt +GROUP BY a, b +HAVING a = b + 1; +a +2 +EXPLAIN FORMAT=JSON SELECT a FROM ( SELECT a, 1 AS b FROM t1 ) AS dt +GROUP BY a, b +HAVING a = b + 1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.012403489, + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100, + "attached_condition": "t1.a = (1 + 1)" + } + } + ] + } + } + } +} +# Item_param as an immutable argument of the pushed equality +PREPARE stmt FROM +"SELECT a FROM ( SELECT a, 1 AS b FROM t1 ) AS dt + GROUP BY a, b + HAVING a = b + ?"; +SET @p= 1; +EXECUTE stmt USING @p; +a +2 +SET @p= 2; +EXECUTE stmt USING @p; +a +3 +DEALLOCATE PREPARE stmt; +# Item_param as the basic constant behind the view reference +PREPARE stmt FROM +"SELECT a FROM ( SELECT a, ? AS b FROM t1 ) AS dt + GROUP BY a, b + HAVING a = b + 1"; +SET @p= 1; +EXECUTE stmt USING @p; +a +2 +SET @p= 2; +EXECUTE stmt USING @p; +a +3 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# End of 11.4 tests diff --git a/mysql-test/main/having_cond_pushdown.test b/mysql-test/main/having_cond_pushdown.test index b7250545311..3fb97d31b8b 100644 --- a/mysql-test/main/having_cond_pushdown.test +++ b/mysql-test/main/having_cond_pushdown.test @@ -1822,3 +1822,45 @@ HAVING (NOT a) AND TRUE; DROP TABLE t1; --echo # End of 10.11 tests + +--echo # +--echo # MDEV-32412 Pushdown from HAVING: Item_func is immutable while arguments are not +--echo # +CREATE TABLE t1 (a int); +INSERT INTO t1 values (1),(2),(3); + +let $q= SELECT a FROM ( SELECT a, 1 AS b FROM t1 ) AS dt +GROUP BY a, b +HAVING a = b + 1; + +eval $q; + +eval EXPLAIN FORMAT=JSON $q; + +--echo # Item_param as an immutable argument of the pushed equality + +PREPARE stmt FROM +"SELECT a FROM ( SELECT a, 1 AS b FROM t1 ) AS dt + GROUP BY a, b + HAVING a = b + ?"; +SET @p= 1; +EXECUTE stmt USING @p; +SET @p= 2; +EXECUTE stmt USING @p; +DEALLOCATE PREPARE stmt; + +--echo # Item_param as the basic constant behind the view reference + +PREPARE stmt FROM +"SELECT a FROM ( SELECT a, ? AS b FROM t1 ) AS dt + GROUP BY a, b + HAVING a = b + 1"; +SET @p= 1; +EXECUTE stmt USING @p; +SET @p= 2; +EXECUTE stmt USING @p; +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + +--echo # End of 11.4 tests diff --git a/mysql-test/main/json_normalize.result b/mysql-test/main/json_normalize.result index 89c010f44b2..2cce33db76b 100644 --- a/mysql-test/main/json_normalize.result +++ b/mysql-test/main/json_normalize.result @@ -45,6 +45,21 @@ json_normalize('{ "invalid": "no_close"') NULL Warnings: Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize' +select json_normalize(''); +json_normalize('') +NULL +Warnings: +Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize' +select json_normalize(' '); +json_normalize(' ') +NULL +Warnings: +Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize' +select json_normalize('123 garbage'); +json_normalize('123 garbage') +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_normalize' at position 5 drop table t1; drop view v1; create table t1 (text varchar(200) character set 'latin1'); diff --git a/mysql-test/main/json_normalize.test b/mysql-test/main/json_normalize.test index a1c0b12026d..d4f27efd2c8 100644 --- a/mysql-test/main/json_normalize.test +++ b/mysql-test/main/json_normalize.test @@ -25,6 +25,9 @@ order by json; select json_normalize(NULL); select json_normalize('{ "invalid": "no_close"'); +select json_normalize(''); +select json_normalize(' '); +select json_normalize('123 garbage'); drop table t1; drop view v1; diff --git a/mysql-test/main/large_pages.result b/mysql-test/main/large_pages.result index c5e73f044a9..9e70be21b94 100644 --- a/mysql-test/main/large_pages.result +++ b/mysql-test/main/large_pages.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("\\[Warning\\] (mysqld|mariadbd): Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEMLOCK) page size [0-9]+\\).*"); +call mtr.add_suppression("\\[Warning\\] mariadbd: Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEM_LARGE_PAGES|MEMLOCK) page size [0-9]+\\).*"); call mtr.add_suppression("\\[ERROR\\]*Lock Pages in memory access rights required.*"); create table t1 ( a int not null auto_increment, diff --git a/mysql-test/main/large_pages.test b/mysql-test/main/large_pages.test index 7c0f497c6d3..c0a2e9e94da 100644 --- a/mysql-test/main/large_pages.test +++ b/mysql-test/main/large_pages.test @@ -2,7 +2,7 @@ --source include/have_innodb.inc -call mtr.add_suppression("\\[Warning\\] (mysqld|mariadbd): Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEMLOCK) page size [0-9]+\\).*"); +call mtr.add_suppression("\\[Warning\\] mariadbd: Couldn't allocate [0-9]+ bytes \\((Large/HugeTLB memory|MEM_LARGE_PAGES|MEMLOCK) page size [0-9]+\\).*"); call mtr.add_suppression("\\[ERROR\\]*Lock Pages in memory access rights required.*"); create table t1 ( a int not null auto_increment, diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 405343c8662..eaa467339fb 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -850,6 +850,20 @@ create table t(c int primary key, c2 blob unique) engine=innodb; insert into t values (0, ''); replace into t values (0, '123'); drop table t; +# +# MDEV-30441 ASAN heap-use-after-free in Field_blob::pack/pack_row +# +create table t1 (a blob, va mediumtext as (a) stored, b varchar(3845), +unique key (b, va(64))) +engine=innodb default charset=utf8mb3; +insert into t1 (a, b) values ('111', '222'); +delete from t1 order by b limit 1; +drop table t1; +create table t (a blob, b text as (a) stored, unique (b)) +engine=innodb character set utf8mb3 +as select 'x' as a; +delete from t; +drop table t; # End of 10.11 tests # # MDEV-39559: Assertion `b` failed in `my_strnncoll_xxxx_nopad_ci` diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index b6411ff8b11..258bd50be96 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -776,6 +776,22 @@ insert into t values (0, ''); replace into t values (0, '123'); drop table t; +--echo # +--echo # MDEV-30441 ASAN heap-use-after-free in Field_blob::pack/pack_row +--echo # +create table t1 (a blob, va mediumtext as (a) stored, b varchar(3845), + unique key (b, va(64))) +engine=innodb default charset=utf8mb3; +insert into t1 (a, b) values ('111', '222'); +delete from t1 order by b limit 1; +drop table t1; + +create table t (a blob, b text as (a) stored, unique (b)) +engine=innodb character set utf8mb3 +as select 'x' as a; +delete from t; +drop table t; + --echo # End of 10.11 tests --echo # diff --git a/mysql-test/main/mdev_40698.result b/mysql-test/main/mdev_40698.result new file mode 100644 index 00000000000..3c51bf2d37d --- /dev/null +++ b/mysql-test/main/mdev_40698.result @@ -0,0 +1,54 @@ +# +# MDEV-40698: ROLLUP query returns incorrect result with empty result set +# +CREATE TABLE t0(a INT, b INT, c INT); +SELECT *, COUNT(0) FROM t0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0) FROM t0 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) ROW_NUMBER() OVER () +NULL NULL NULL 0 1 +SELECT 1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP); +1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP) +NULL +INSERT INTO t0 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t0 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT EXISTS (SELECT t0.a FROM t0 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e +FROM t0; +e +1 +1 +SELECT DISTINCT a FROM t0 GROUP BY a, b WITH ROLLUP; +a +0 +NULL +CREATE TABLE t1 (a INT, b INT, c INT) ENGINE=InnoDB; +SELECT *, COUNT(0) FROM t1 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0) FROM t1 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t1 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) ROW_NUMBER() OVER () +NULL NULL NULL 0 1 +INSERT INTO t1 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t1 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT EXISTS (SELECT t1.a FROM t1 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e +FROM t1; +e +1 +1 +SELECT DISTINCT a FROM t1 GROUP BY a, b WITH ROLLUP; +a +0 +NULL +DROP TABLE t0, t1; +# End of 10.11 tests diff --git a/mysql-test/main/mdev_40698.test b/mysql-test/main/mdev_40698.test new file mode 100644 index 00000000000..dfe7a0fe68b --- /dev/null +++ b/mysql-test/main/mdev_40698.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-40698: ROLLUP query returns incorrect result with empty result set +--echo # + +CREATE TABLE t0(a INT, b INT, c INT); +SELECT *, COUNT(0) FROM t0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0) FROM t0 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t0 GROUP BY a, b, c WITH ROLLUP; +SELECT 1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP); +INSERT INTO t0 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t0 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +SELECT EXISTS (SELECT t0.a FROM t0 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e + FROM t0; +SELECT DISTINCT a FROM t0 GROUP BY a, b WITH ROLLUP; + +CREATE TABLE t1 (a INT, b INT, c INT) ENGINE=InnoDB; +SELECT *, COUNT(0) FROM t1 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0) FROM t1 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t1 GROUP BY a, b, c WITH ROLLUP; +INSERT INTO t1 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t1 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +SELECT EXISTS (SELECT t1.a FROM t1 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e + FROM t1; +SELECT DISTINCT a FROM t1 GROUP BY a, b WITH ROLLUP; + +DROP TABLE t0, t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index b86e58c05db..c3256c187a6 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -10,6 +10,13 @@ call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm call mtr.add_suppression(" IP address .* could not be resolved"); call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'"); call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example.com'"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); +FOUND 1 /Host '192\.0\.2\.222' is not allowed to connect to this MariaDB server/ in mysqld.1.err ok # cat MYSQL_TMP_DIR/test_wl4435.out.log diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test index a227e95c984..c3aeb9f2537 100644 --- a/mysql-test/main/mysql_client_test.test +++ b/mysql-test/main/mysql_client_test.test @@ -17,6 +17,12 @@ call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm call mtr.add_suppression(" IP address .* could not be resolved"); call mtr.add_suppression("Aborted connection .* host: '192.0.2.50'"); call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example.com'"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); # We run with different binaries for normal and --embedded-server # @@ -28,6 +34,12 @@ call mtr.add_suppression("Aborted connection .* host: 'santa.claus.ipv6.example. --write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test.out.log --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1 +# MDEV-40967: test_proxy_header_host_denied() must have caused this to be +# logged (log_warnings defaults to 2). +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN= Host '192\.0\.2\.222' is not allowed to connect to this MariaDB server +--source include/search_pattern_in_file.inc + # End of 4.1 tests echo ok; diff --git a/mysql-test/main/mysql_client_test_comp.result b/mysql-test/main/mysql_client_test_comp.result index 096331db4f1..c4385db809e 100644 --- a/mysql-test/main/mysql_client_test_comp.result +++ b/mysql-test/main/mysql_client_test_comp.result @@ -1,5 +1,11 @@ SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); ok SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/main/mysql_client_test_comp.test b/mysql-test/main/mysql_client_test_comp.test index f37d82a20e5..e16b64d7a91 100644 --- a/mysql-test/main/mysql_client_test_comp.test +++ b/mysql-test/main/mysql_client_test_comp.test @@ -12,6 +12,12 @@ SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); --write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log 2>&1 diff --git a/mysql-test/main/mysql_client_test_nonblock.result b/mysql-test/main/mysql_client_test_nonblock.result index 391794f082f..d53c0d5fcc6 100644 --- a/mysql-test/main/mysql_client_test_nonblock.result +++ b/mysql-test/main/mysql_client_test_nonblock.result @@ -2,6 +2,12 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); ok SET @@global.general_log= @old_general_log; SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/main/mysql_client_test_nonblock.test b/mysql-test/main/mysql_client_test_nonblock.test index c4bc4304307..8987e3d7464 100644 --- a/mysql-test/main/mysql_client_test_nonblock.test +++ b/mysql-test/main/mysql_client_test_nonblock.test @@ -11,6 +11,12 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); +call mtr.add_suppression("Failed to parse proxy header"); +call mtr.add_suppression("Proxy header is not accepted from "); +call mtr.add_suppression("Host '192.0.2.50' is blocked because of many connection errors"); +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); +call mtr.add_suppression("Host '192.0.2.22[234]' is not allowed to connect to this MariaDB server"); +call mtr.add_suppression("Host '1.2.3.4' is not allowed to connect to this MariaDB server"); # We run with different binaries for normal and --embedded-server # diff --git a/mysql-test/main/mysqlbinlog.result b/mysql-test/main/mysqlbinlog.result index 994e62766de..6ef331c0b2a 100644 --- a/mysql-test/main/mysqlbinlog.result +++ b/mysql-test/main/mysqlbinlog.result @@ -960,255 +960,6 @@ SET GLOBAL SERVER_ID = 1; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 -#130807 20:29:20 server id 1 end_log_pos 106 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 4 |20 ae 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 01 -# -# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-| -# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......| -# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -# 47 00 00 00 00 20 ae 02 52 17 38 0d 00 08 00 12 00 |.... ..R.8......| -# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........| -# 67 08 08 02 |...| -# -# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 20:29:20 at startup -ROLLBACK/*!*/; -BINLOG ' -IK4CUg8BAAAAZgAAAGoAAAAAAQQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAgrgJSFzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC -'/*!*/; -# at 106 -#130807 20:29:24 server id 1 end_log_pos 207 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 6a |24 ae 02 52 |02 |01 00 00 00 |65 00 00 00 |cf 00 00 00 |00 00 -# -# 81 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 91 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# a1 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t| -# b1 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id| -# c1 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375907364/*!*/; -SET @@session.pseudo_thread_id=1/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.system_versioning_insert_history=0/*!*/; -SET @@session.sql_mode=0/*!*/; -SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; -/*!\C latin1 *//*!*/; -SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -SET @@session.lc_time_names=0/*!*/; -SET @@session.collation_database=DEFAULT/*!*/; -create table test.t1 (id int not null) -/*!*/; -# at 207 -#130807 20:29:26 server id 1 end_log_pos 305 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# cf |26 ae 02 52 |02 |01 00 00 00 |62 00 00 00 |31 01 00 00 |00 00 -# -# e6 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# f6 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 106 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i| -# 116 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)| -# 126 20 76 61 6c 75 65 73 20 28 31 29 | values (1)| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375907366/*!*/; -insert into test.t1 (id) values (1) -/*!*/; -# at 305 -#130807 20:29:28 server id 1 end_log_pos 386 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 131 |28 ae 02 52 |02 |01 00 00 00 |51 00 00 00 |82 01 00 00 |00 00 -# -# 148 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 158 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 168 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab| -# 178 6c 65 20 74 65 73 74 2e 74 31 |le test.t1| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375907368/*!*/; -drop table test.t1 -/*!*/; -DELIMITER ; -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; -/*!40019 SET @@session.max_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -DELIMITER /*!*/; -# at 4 -#130807 20:25:35 server id 1 end_log_pos 106 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 4 |3f ad 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 00 -# -# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-| -# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......| -# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -# 47 00 00 00 00 3f ad 02 52 1b 38 0d 00 08 00 12 00 |....?..R.8......| -# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........| -# 67 08 08 02 |...| -# -# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 20:25:35 at startup -ROLLBACK/*!*/; -BINLOG ' -P60CUg8BAAAAZgAAAGoAAAAAAAQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAA/rQJSGzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC -'/*!*/; -# at 106 -#130807 20:25:41 server id 1 end_log_pos 211 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 6a |45 ad 02 52 |02 |01 00 00 00 |69 00 00 00 |d3 00 00 00 |00 00 -# -# 85 01 00 00 00 01 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 95 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# a5 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t| -# b5 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id| -# c5 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)| -# -# Event: Query thread_id=1 exec_time=1 error_code=0 xid=0 -SET TIMESTAMP=1375907141/*!*/; -SET @@session.pseudo_thread_id=1/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.system_versioning_insert_history=0/*!*/; -SET @@session.sql_mode=0/*!*/; -SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; -/*!\C latin1 *//*!*/; -SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -SET @@session.lc_time_names=0/*!*/; -SET @@session.collation_database=DEFAULT/*!*/; -create table test.t1 (id int not null) -/*!*/; -# at 211 -#130807 20:25:44 server id 1 end_log_pos 313 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# d3 |48 ad 02 52 |02 |01 00 00 00 |66 00 00 00 |39 01 00 00 |00 00 -# -# ee 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# fe 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 10e 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i| -# 11e 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)| -# 12e 20 76 61 6c 75 65 73 20 28 31 29 | values (1)| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375907144/*!*/; -insert into test.t1 (id) values (1) -/*!*/; -# at 313 -#130807 20:25:48 server id 1 end_log_pos 398 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 139 |4c ad 02 52 |02 |01 00 00 00 |55 00 00 00 |8e 01 00 00 |00 00 -# -# 154 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 164 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 174 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab| -# 184 6c 65 20 74 65 73 74 2e 74 31 |le test.t1| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375907148/*!*/; -drop table test.t1 -/*!*/; -DELIMITER ; -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; -/*!40019 SET @@session.max_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -DELIMITER /*!*/; -# at 4 -#130807 20:20:55 server id 1 end_log_pos 106 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 4 |27 ac 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 01 -# -# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-| -# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......| -# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -# 47 00 00 00 00 27 ac 02 52 1f 38 0d 00 08 00 12 00 |....'..R.8......| -# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........| -# 67 08 08 02 |...| -# -# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 20:20:55 at startup -ROLLBACK/*!*/; -BINLOG ' -J6wCUg8BAAAAZgAAAGoAAAAAAQQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAnrAJSHzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC -'/*!*/; -# at 106 -#130807 20:21:19 server id 1 end_log_pos 215 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 6a |3f ac 02 52 |02 |01 00 00 00 |6d 00 00 00 |d7 00 00 00 |00 00 -# -# 89 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 99 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# a9 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t| -# b9 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id| -# c9 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375906879/*!*/; -SET @@session.pseudo_thread_id=1/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.system_versioning_insert_history=0/*!*/; -SET @@session.sql_mode=0/*!*/; -SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; -/*!\C latin1 *//*!*/; -SET @@session.character_set_client=latin1,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -SET @@session.lc_time_names=0/*!*/; -SET @@session.collation_database=DEFAULT/*!*/; -create table test.t1 (id int not null) -/*!*/; -# at 215 -#130807 20:21:31 server id 1 end_log_pos 321 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# d7 |4b ac 02 52 |02 |01 00 00 00 |6a 00 00 00 |41 01 00 00 |00 00 -# -# f6 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 106 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 116 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i| -# 126 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)| -# 136 20 76 61 6c 75 65 73 20 28 31 29 | values (1)| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375906891/*!*/; -insert into test.t1 (id) values (1) -/*!*/; -# at 321 -#130807 20:21:41 server id 1 end_log_pos 410 -# Position -# |Timestamp |Type |Master ID |Size |Master Pos |Flags -# 141 |55 ac 02 52 |02 |01 00 00 00 |59 00 00 00 |9a 01 00 00 |00 00 -# -# 160 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@| -# 170 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std| -# 180 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab| -# 190 6c 65 20 74 65 73 74 2e 74 31 |le test.t1| -# -# Event: Query thread_id=1 exec_time=0 error_code=0 xid=0 -SET TIMESTAMP=1375906901/*!*/; -drop table test.t1 -/*!*/; -DELIMITER ; -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; -/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; -/*!40019 SET @@session.max_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -DELIMITER /*!*/; -# at 4 #130807 20:38:51 server id 1 end_log_pos 106 # Position # |Timestamp |Type |Master ID |Size |Master Pos |Flags diff --git a/mysql-test/main/mysqlbinlog.test b/mysql-test/main/mysqlbinlog.test index 0cd599b4c3e..65438abd9b9 100644 --- a/mysql-test/main/mysqlbinlog.test +++ b/mysql-test/main/mysqlbinlog.test @@ -606,9 +606,10 @@ eval SET GLOBAL SERVER_ID = $old_server_id; --echo # FDE corrupted in relay log --echo # --let TZ=GMT ---exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_checksum.binlog ---exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id.binlog ---exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id_checksum.binlog +# Here used to be testing with special binlog files where the Format Description +# event had common_header_len increased. We no longer support different +# common_header_len, as such are never generated by MariaDB nor MySQL, would +# require custom fork of the server code. --exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_none.binlog # diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 213dba858d8..75d65d48605 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -869,8 +869,8 @@ The following specify which files/extra groups are read (specified before remain MySQL versions. Any combination of: NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO, ZERO_DATE_TIME_CAST, UTF8_IS_UTF8MB3, IGNORE_INDEX_ONLY_FOR_JOIN, COMPAT_5_1_CHECKSUM, NO_NULL_COLLATION_IDS, LOCK_ALTER_TABLE_COPY, - OLD_FLUSH_STATUS, SESSION_USER_IS_USER, or ALL to set all - combinations + OLD_FLUSH_STATUS, SESSION_USER_IS_USER, X509_LENIENT_COMPARE, + or ALL to set all combinations --old-passwords Use old password encryption method (needed for 4.0 and older clients) --old-style-user-limits diff --git a/mysql-test/main/mysqldump-nl.result b/mysql-test/main/mysqldump-nl.result index ae753646668..99f5b846e0f 100644 --- a/mysql-test/main/mysqldump-nl.result +++ b/mysql-test/main/mysqldump-nl.result @@ -216,7 +216,7 @@ CHANGE MASTER '' TO MASTER_HOST='master''host', MASTER_PORT=3306, MASTER_LOG_FIL -- SET GLOBAL gtid_slave_pos=''; call mtr.add_suppression('Slave I/O: Fatal error: .* Connection attempt terminated'); -reset slave; +reset slave all; Warnings: Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' change master to master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; diff --git a/mysql-test/main/mysqldump-nl.test b/mysql-test/main/mysqldump-nl.test index 9a75a9f96d8..8c8771bafa9 100644 --- a/mysql-test/main/mysqldump-nl.test +++ b/mysql-test/main/mysqldump-nl.test @@ -79,7 +79,7 @@ exec $MYSQL_DUMP --compact --dump-slave --include-master-host-port test; # cleanup after mariadb-dump executed START SLAVE call mtr.add_suppression('Slave I/O: Fatal error: .* Connection attempt terminated'); -reset slave; +reset slave all; change master to master_host='127.0.0.1', master_user='root', master_ssl_verify_server_cert=0; --echo # End of 10.6 tests diff --git a/mysql-test/main/mysqltest_expression_evaluation.result b/mysql-test/main/mysqltest_expression_evaluation.result index b74fc767d47..3cdabdc5d5f 100644 --- a/mysql-test/main/mysqltest_expression_evaluation.result +++ b/mysql-test/main/mysqltest_expression_evaluation.result @@ -55,13 +55,18 @@ Multiple variables: 10 * 20 / 10 = 20 # ---------------------------------------------------------------------------- # Overflow edge cases # ---------------------------------------------------------------------------- --9223372036854775808 / -1 -> -9223372036854775808 +-9223372036854775808 / -1 -> error +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/' -9223372036854775808 % -1 -> 0 --(-9223372036854775808) -> -9223372036854775808 +-(-9223372036854775808) -> error +mysqltest: At line 1: Evaluation error: Signed integer overflow in unary '-' -4611686018427387904 * 2 -> -9223372036854775808 --4611686018427387904 * 2 / -1 -> -9223372036854775808 --4611686018427387904 * -2 / -1 -> -9223372036854775808 -18446744073709551615 / 2 / -1 -> 0 +-4611686018427387904 * 2 / -1 -> error +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/' +-4611686018427387904 * -2 / -1 -> error +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '*' +18446744073709551615 / 2 / -1 -> error +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '/' # ---------------------------------------------------------------------------- # Comparison operators # ---------------------------------------------------------------------------- @@ -505,6 +510,15 @@ mysqltest: At line 1: Evaluation error: Modulo by zero # Test case: Overflow mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type +# Signed arithmetic overflow +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '+' +mysqltest: At line 1: Evaluation error: Signed integer overflow in operator '-' +mysqltest: At line 1: Evaluation error: Signed integer overflow in abs() +# Unsigned overflow +mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '+' +mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '*' +mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '*' +mysqltest: At line 1: Evaluation error: Unsigned integer overflow in operator '+' # # MDEV-37865: IF() function is returning incorrect error # diff --git a/mysql-test/main/mysqltest_expression_evaluation.test b/mysql-test/main/mysqltest_expression_evaluation.test index b76648284fc..3cdcae5aea5 100644 --- a/mysql-test/main/mysqltest_expression_evaluation.test +++ b/mysql-test/main/mysqltest_expression_evaluation.test @@ -112,13 +112,23 @@ let $multi_var = $($var_a * $var_b / $var_a); --echo # Overflow edge cases --echo # ---------------------------------------------------------------------------- ---echo -9223372036854775808 / -1 -> $(-9223372036854775808 / -1) +--echo -9223372036854775808 / -1 -> error +--error 1 +--exec echo "let \$a = \$(-9223372036854775808 / -1);" | $MYSQL_TEST 2>&1 --echo -9223372036854775808 % -1 -> $(-9223372036854775808 % -1) ---echo -(-9223372036854775808) -> $(-(-9223372036854775808)) +--echo -(-9223372036854775808) -> error +--error 1 +--exec echo "let \$a = \$(-(-9223372036854775808));" | $MYSQL_TEST 2>&1 --echo -4611686018427387904 * 2 -> $(-4611686018427387904 * 2) ---echo -4611686018427387904 * 2 / -1 -> $(-4611686018427387904 * 2 / -1) ---echo -4611686018427387904 * -2 / -1 -> $(-4611686018427387904 * -2 / -1) ---echo 18446744073709551615 / 2 / -1 -> $(18446744073709551615 / 2 / -1) +--echo -4611686018427387904 * 2 / -1 -> error +--error 1 +--exec echo "let \$a = \$(-4611686018427387904 * 2 / -1);" | $MYSQL_TEST 2>&1 +--echo -4611686018427387904 * -2 / -1 -> error +--error 1 +--exec echo "let \$a = \$(-4611686018427387904 * -2 / -1);" | $MYSQL_TEST 2>&1 +--echo 18446744073709551615 / 2 / -1 -> error +--error 1 +--exec echo "let \$a = \$(18446744073709551615 / 2 / -1);" | $MYSQL_TEST 2>&1 --echo # ---------------------------------------------------------------------------- --echo # Comparison operators @@ -894,6 +904,29 @@ let $large_xor = $(0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE); --error 1 --exec echo "let \$a = \$(-18446744073709551616);" | $MYSQL_TEST 2>&1 +--echo # Signed arithmetic overflow +--error 1 +--exec echo "let \$a = \$(9223372036854775807 + 1);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(-9223372036854775807 - 2);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(abs(-9223372036854775808));" | $MYSQL_TEST 2>&1 + +--echo # Unsigned overflow +--error 1 +--exec echo "let \$a = \$(18446744073709551615 + 1);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(0x8000000000000000 * 2);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(18446744073709551615 * 2);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$((0xFFFFFFFFFFFFFFFF & 0xFFFFFFFFFFFFFFFF) + 1);" | $MYSQL_TEST 2>&1 + --echo # --echo # MDEV-37865: IF() function is returning incorrect error --echo # diff --git a/mysql-test/main/mysqltest_ps.result b/mysql-test/main/mysqltest_ps.result index d6266964e3d..4168ce5220a 100644 --- a/mysql-test/main/mysqltest_ps.result +++ b/mysql-test/main/mysqltest_ps.result @@ -32,3 +32,16 @@ a a Warnings: Warning 1052 Column 'a' in GROUP BY is ambiguous drop table t; +# +# MDEV-41408 MTR prepared statement protocol skipping statements starting with '(' +# +SELECT 1; +1 +1 +( ( SELECT 1)); +1 +1 +SELECT $e2 - $e1 = $e1 - $e0 AS parens_same; +parens_same +1 +# End of 10.11 tests diff --git a/mysql-test/main/mysqltest_ps.test b/mysql-test/main/mysqltest_ps.test index c5a332f691f..14ff0ef2940 100644 --- a/mysql-test/main/mysqltest_ps.test +++ b/mysql-test/main/mysqltest_ps.test @@ -32,3 +32,16 @@ select 1 + "2 a"; create table t (a int primary key, b blob default ''); select a, (2*a) AS a from t group by a; drop table t; + +--echo # +--echo # MDEV-41408 MTR prepared statement protocol skipping statements starting with '(' +--echo # + +let $e0= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1); +SELECT 1; +let $e1= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1); +( ( SELECT 1)); +let $e2= query_get_value(SHOW SESSION STATUS LIKE 'Com_stmt_execute', Value, 1); +evalp SELECT $e2 - $e1 = $e1 - $e0 AS parens_same; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result index b8aea1c7c2b..15baaa672b5 100644 --- a/mysql-test/main/olap.result +++ b/mysql-test/main/olap.result @@ -920,4 +920,20 @@ MAX(c) 1001 DROP TABLE t1; # End of 10.11 tests +# +# MDEV-41146: WHERE is not checked when every table is const and +# the query needs a temporary table +# +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +# rand() < 0 is never true, so only the ROLLUP total row is returned. +select distinct a from t1 where a=1 and rand() < 0 group by a with rollup; +a +NULL +select distinct a from t1 where a=1 and rand() >= 0 group by a with rollup; +a +1 +NULL +drop table t1; +# End of 11.4 tests ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test index d6b3c41747f..2a23a398443 100644 --- a/mysql-test/main/olap.test +++ b/mysql-test/main/olap.test @@ -546,4 +546,20 @@ SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP limit 5; DROP TABLE t1; --echo # End of 10.11 tests +--echo # +--echo # MDEV-41146: WHERE is not checked when every table is const and +--echo # the query needs a temporary table +--echo # + +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); + +--echo # rand() < 0 is never true, so only the ROLLUP total row is returned. +select distinct a from t1 where a=1 and rand() < 0 group by a with rollup; +select distinct a from t1 where a=1 and rand() >= 0 group by a with rollup; + +drop table t1; + +--echo # End of 11.4 tests + --source include/test_db_charset_restore.inc diff --git a/mysql-test/main/opt_tvc.result b/mysql-test/main/opt_tvc.result index beafad5e5ec..55f9a62b5f3 100644 --- a/mysql-test/main/opt_tvc.result +++ b/mysql-test/main/opt_tvc.result @@ -791,4 +791,24 @@ select * from t1 where a in (1, 2) and b = 2 order by a, b; a b c 1 2 NULL drop table t1; +# +# MDEV-31225: Signal 11 after select ..WHERE ROW(a,(a,a)) IN +# ((1,(1,1)),(2,(2,null))) with in_predicate_conversion_threshold=1 +# +create table t1 (a int); +insert into t1 values (1), (2), (3); +set in_predicate_conversion_threshold=1; +explain extended select a from t1 where row(a,(a,a)) in ((1,(1,1)),(2,(2,null))); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a`,(`test`.`t1`.`a`,`test`.`t1`.`a`)) in (((1,(1,1))),((2,(2,NULL)))) +select a from t1 where row(a,(a,a)) in ((1,(1,1)),(2,(2,null))); +a +1 +select a from t1 where row(a,(a,a)) not in ((1,(1,1)),(2,(2,2))); +a +3 +drop table t1; +set in_predicate_conversion_threshold=default; # End of 11.4 tests diff --git a/mysql-test/main/opt_tvc.test b/mysql-test/main/opt_tvc.test index 1288e0d51a6..52ec9eadfad 100644 --- a/mysql-test/main/opt_tvc.test +++ b/mysql-test/main/opt_tvc.test @@ -488,4 +488,25 @@ select * from t1 where a in (1, 2) and b = 2 order by a, b; drop table t1; +--echo # +--echo # MDEV-31225: Signal 11 after select ..WHERE ROW(a,(a,a)) IN +--echo # ((1,(1,1)),(2,(2,null))) with in_predicate_conversion_threshold=1 +--echo # + +create table t1 (a int); +insert into t1 values (1), (2), (3); + +set in_predicate_conversion_threshold=1; + +let $query= +select a from t1 where row(a,(a,a)) in ((1,(1,1)),(2,(2,null))); +eval explain extended $query; +eval $query; + +select a from t1 where row(a,(a,a)) not in ((1,(1,1)),(2,(2,2))); + +drop table t1; + +set in_predicate_conversion_threshold=default; + --echo # End of 11.4 tests diff --git a/mysql-test/main/order_by_limit_join.result b/mysql-test/main/order_by_limit_join.result index 1c8a2cb9004..795bc523a01 100644 --- a/mysql-test/main/order_by_limit_join.result +++ b/mysql-test/main/order_by_limit_join.result @@ -684,4 +684,39 @@ SELECT * FROM t1 ORDER BY c1 LIMIT 1; c1 1 DROP TABLE t1; +# +# MDEV-41252: Assertion partial_join_cost >= -2.2204460492503131e-16 +# when optimizer_scan_setup_cost=100000000, and +# optimizer_join_limit_pref_ratio=1 +# +CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB; +INSERT INTO t VALUES (0),(1),(2),(3),(4),(5); +ANALYZE TABLE t; +Table Op Msg_type Msg_text +test.t analyze status Engine-independent statistics collected +test.t analyze status OK +SET optimizer_scan_setup_cost=100000000; +SET optimizer_join_limit_pref_ratio=1; +EXPLAIN SELECT c FROM t ORDER BY c LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t index NULL c 4 NULL 1 +SET optimizer_join_limit_pref_ratio= DEFAULT; +SET optimizer_scan_setup_cost= DEFAULT; +DROP TABLE t; +# another variant, with only optimizer_join_limit_pref_ratio=1 +CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB; +INSERT INTO t SELECT seq FROM seq_1_to_30000; +ANALYZE TABLE t; +Table Op Msg_type Msg_text +test.t analyze status Engine-independent statistics collected +test.t analyze status OK +SET optimizer_join_limit_pref_ratio=1; +EXPLAIN SELECT c FROM t ORDER BY c LIMIT 28000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t index NULL c 4 NULL 28000 +SET optimizer_join_limit_pref_ratio= DEFAULT; +DROP TABLE t; +# +# End of 11.4 tests +# set optimizer_join_limit_pref_ratio=default; diff --git a/mysql-test/main/order_by_limit_join.test b/mysql-test/main/order_by_limit_join.test index c0a84d82fd4..5e526eec3d7 100644 --- a/mysql-test/main/order_by_limit_join.test +++ b/mysql-test/main/order_by_limit_join.test @@ -344,4 +344,41 @@ INSERT INTO t1 VALUES (1),(2); SELECT * FROM t1 ORDER BY c1 LIMIT 1; DROP TABLE t1; +--echo # +--echo # MDEV-41252: Assertion partial_join_cost >= -2.2204460492503131e-16 +--echo # when optimizer_scan_setup_cost=100000000, and +--echo # optimizer_join_limit_pref_ratio=1 +--echo # +CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB; +INSERT INTO t VALUES (0),(1),(2),(3),(4),(5); +ANALYZE TABLE t; + +SET optimizer_scan_setup_cost=100000000; +SET optimizer_join_limit_pref_ratio=1; + +EXPLAIN SELECT c FROM t ORDER BY c LIMIT 1; + +SET optimizer_join_limit_pref_ratio= DEFAULT; +SET optimizer_scan_setup_cost= DEFAULT; + +DROP TABLE t; + +--echo # another variant, with only optimizer_join_limit_pref_ratio=1 + +CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB; +INSERT INTO t SELECT seq FROM seq_1_to_30000; +ANALYZE TABLE t; + +SET optimizer_join_limit_pref_ratio=1; + +EXPLAIN SELECT c FROM t ORDER BY c LIMIT 28000; + +SET optimizer_join_limit_pref_ratio= DEFAULT; + +DROP TABLE t; + +--echo # +--echo # End of 11.4 tests +--echo # + set optimizer_join_limit_pref_ratio=default; diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 2029cc9a1ed..938e21e708d 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -2272,6 +2272,53 @@ select 1b from test.1a; select select.1c from test.select; 1c drop table 1a, `select`; +# +# MDEV-37167 Nested BEGINs (4600+) cause a segmentation fault +# +# +# Unclosed BEGINs +# +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +# +# Well-formed deep routine +# +DROP PROCEDURE p2; +# +# Same, with variables, so the contexts are not empty +# +DROP PROCEDURE p3; +# +# A deep FUNCTION tears down the same way +# +DROP FUNCTION f1; +# +# Invoking a deep routine must not crash. It is rejected with +# ER_STACK_OVERRUN_NEED_MORE when the frame does not fit the thread +# stack, which depends on the build, so both outcomes are accepted. +# +CALL p4(); +DROP PROCEDURE p4; +# +# Nested scopes must still resolve correctly +# +CREATE PROCEDURE p5() +BEGIN +DECLARE a INT DEFAULT 1; +BEGIN +DECLARE b INT DEFAULT 2; +BEGIN +DECLARE c INT DEFAULT 3; +SELECT a + b + c AS total; +END; +END; +END$$ +CALL p5(); +total +6 +DROP PROCEDURE p5; +SELECT 'Server is alive' AS state; +state +Server is alive # End of 10.11 tests # # Start of 11.7 tests diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index c46cae1392e..fc4f9dae1e9 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -2078,6 +2078,80 @@ select select.1c from test.select; drop table 1a, `select`; +--echo # +--echo # MDEV-37167 Nested BEGINs (4600+) cause a segmentation fault +--echo # + +# Each nested BEGIN adds one sp_pcontext. Freeing them used to recurse once +# per nesting level and overran the thread stack. Building the run-time frame +# still recurses, but checks the stack now, and the depth where it gives up +# follows thread_stack, so the invoking statements accept either outcome. + +--echo # +--echo # Unclosed BEGINs +--echo # +--disable_query_log +--error ER_PARSE_ERROR +--eval CREATE PROCEDURE p1() $(repeat("BEGIN ", 6000)) +--enable_query_log + +--echo # +--echo # Well-formed deep routine +--echo # +--disable_query_log +--eval CREATE PROCEDURE p2() $(repeat("BEGIN ", 6000)) $(repeat("END; ", 5999)) END +--enable_query_log +DROP PROCEDURE p2; + +--echo # +--echo # Same, with variables, so the contexts are not empty +--echo # +--disable_query_log +--eval CREATE PROCEDURE p3() $(repeat("BEGIN DECLARE v INT DEFAULT 1; ", 2000)) $(repeat("END; ", 1999)) END +--enable_query_log +DROP PROCEDURE p3; + +--echo # +--echo # A deep FUNCTION tears down the same way +--echo # +--disable_query_log +--eval CREATE FUNCTION f1() RETURNS INT $(repeat("BEGIN ", 6000)) RETURN 1; $(repeat("END; ", 5999)) END +--enable_query_log +DROP FUNCTION f1; + +--echo # +--echo # Invoking a deep routine must not crash. It is rejected with +--echo # ER_STACK_OVERRUN_NEED_MORE when the frame does not fit the thread +--echo # stack, which depends on the build, so both outcomes are accepted. +--echo # +--disable_query_log +--eval CREATE PROCEDURE p4() $(repeat("BEGIN ", 6000)) $(repeat("END; ", 5999)) END +--enable_query_log +--error 0,ER_STACK_OVERRUN_NEED_MORE +CALL p4(); +DROP PROCEDURE p4; + +--echo # +--echo # Nested scopes must still resolve correctly +--echo # +DELIMITER $$; +CREATE PROCEDURE p5() +BEGIN + DECLARE a INT DEFAULT 1; + BEGIN + DECLARE b INT DEFAULT 2; + BEGIN + DECLARE c INT DEFAULT 3; + SELECT a + b + c AS total; + END; + END; +END$$ +DELIMITER ;$$ +CALL p5(); +DROP PROCEDURE p5; + +SELECT 'Server is alive' AS state; + --echo # End of 10.11 tests --echo # diff --git a/mysql-test/main/partition_explicit_prune.result b/mysql-test/main/partition_explicit_prune.result index 5cad54d0472..2efa0e44fca 100644 --- a/mysql-test/main/partition_explicit_prune.result +++ b/mysql-test/main/partition_explicit_prune.result @@ -2007,6 +2007,29 @@ drop table t1; # End of 10.4 tests # # +# MDEV-17613 Read sole now-partition for non-historical versioned query +# +# INSERT ... SELECT from explicit PARTITION() without WHERE must not +# read partitions outside of it (read_partitions widened by auto-increment) +# +create table t1 (id int auto_increment primary key, x int) +partition by range (id) ( +partition p0 values less than (10), +partition p1 values less than maxvalue); +insert into t1 values (1, 1), (2, 2), (11, 11), (12, 12); +create table t2 (id int, x int); +# Fresh share: auto-increment is not initialized yet +flush tables; +insert into t2 select * from t1 partition (p0); +select * from t2; +id x +1 1 +2 2 +drop tables t1, t2; +# +# End of 10.11 tests +# +# # MDEV-33988 DELETE (single table) to support table aliases # CREATE TABLE `t1` ( diff --git a/mysql-test/main/partition_explicit_prune.test b/mysql-test/main/partition_explicit_prune.test index bd42af70aa2..1a4b20d4b8b 100644 --- a/mysql-test/main/partition_explicit_prune.test +++ b/mysql-test/main/partition_explicit_prune.test @@ -942,6 +942,29 @@ drop table t1; --echo # End of 10.4 tests --echo # +--echo # +--echo # MDEV-17613 Read sole now-partition for non-historical versioned query +--echo # +--echo # INSERT ... SELECT from explicit PARTITION() without WHERE must not +--echo # read partitions outside of it (read_partitions widened by auto-increment) +--echo # +create table t1 (id int auto_increment primary key, x int) +partition by range (id) ( + partition p0 values less than (10), + partition p1 values less than maxvalue); +insert into t1 values (1, 1), (2, 2), (11, 11), (12, 12); +create table t2 (id int, x int); +--echo # Fresh share: auto-increment is not initialized yet +flush tables; +insert into t2 select * from t1 partition (p0); +--sorted_result +select * from t2; +drop tables t1, t2; + +--echo # +--echo # End of 10.11 tests +--echo # + --echo # --echo # MDEV-33988 DELETE (single table) to support table aliases --echo # diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index 5b36be3426a..bf14fcae266 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -4514,6 +4514,11 @@ EXECUTE stmt USING 'xxx', CONCAT('yyy','zzz'); CONCAT(?,?) xxxyyyzzz DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT ?'; +EXECUTE stmt USING _latin1'a'=_latin2'a'; +? +1 +DEALLOCATE PREPARE stmt; # # Testing disallowed expressions in USING # @@ -4531,8 +4536,10 @@ DROP FUNCTION f1; # Testing erroneous expressions in USING # PREPARE stmt FROM 'SELECT ?'; -EXECUTE stmt USING _latin1'a'=_latin2'a'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' +EXECUTE stmt USING CONCAT(_latin1'a',_latin2'a'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat' +EXECUTE stmt USING _latin1'a'=_latin7'a'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_general_ci,COERCIBLE) for operation '=' DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'SELECT ?'; EXECUTE stmt USING ROW(1,2); @@ -4693,6 +4700,9 @@ a EXECUTE IMMEDIATE 'SELECT ? AS a' USING 20; a 20 +EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin2'a'; +? +1 # # Erroneous queries # @@ -4710,8 +4720,10 @@ EXECUTE IMMEDIATE 'EXECUTE stmt'; ERROR HY000: This command is not supported in the prepared statement protocol yet EXECUTE IMMEDIATE 'DEALLOCATE PREPARE stmt'; ERROR HY000: This command is not supported in the prepared statement protocol yet -EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin2'a'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' +EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(_latin1'a',_latin2'a'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat' +EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin7'a'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin7_general_ci,COERCIBLE) for operation '=' EXECUTE IMMEDIATE 'SELECT ?' USING ROW(1,2); ERROR 21000: Operand should contain 1 column(s) # @@ -6146,4 +6158,78 @@ delete from t1 where a=1 or b=2; ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column drop table t1, t2; # End of 11.7 tests +# Start of 11.8 tests +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# Parameters of prepared statements +# +SET NAMES latin2 COLLATE latin2_general_ci; +PREPARE stmt FROM 'SELECT _latin1''Y'' = ? AS r'; +SET @y='y', @n='N', @y_plus='Y+'; +EXECUTE stmt USING @y; +r +1 +EXECUTE stmt USING @n; +r +0 +EXECUTE stmt USING @y_plus; +r +0 +EXECUTE stmt USING 'y'; +r +1 +EXECUTE stmt USING 'Y+'; +r +0 +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT _latin1''Y+'' = ? AS r'; +EXECUTE stmt USING 'y'; +r +0 +EXECUTE stmt USING 'Y+'; +r +1 +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'y'; +r +1 +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'Y+'; +r +0 +# Parameters compared to a view column created under another charset +SET NAMES latin1 COLLATE latin1_swedish_ci; +CREATE VIEW v1 AS SELECT 'Y' AS c1 UNION SELECT 'N'; +SET NAMES latin2 COLLATE latin2_general_ci; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1=? ORDER BY c1'; +EXECUTE stmt USING @y; +c1 +Y +EXECUTE stmt USING @n; +c1 +N +EXECUTE stmt USING @y_plus; +c1 +EXECUTE stmt USING 'y'; +c1 +Y +EXECUTE stmt USING 'x'; +c1 +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1 IN (?,?) ORDER BY c1'; +EXECUTE stmt USING 'y', 'n'; +c1 +N +Y +EXECUTE stmt USING 'y', 'Y+'; +c1 +Y +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'y'; +c1 +Y +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'Y+'; +c1 +DROP VIEW v1; +SET NAMES DEFAULT; +# End of 11.8 tests ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index 4041e0e7d65..35f621a8cc4 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -4058,6 +4058,10 @@ PREPARE stmt FROM 'SELECT CONCAT(?,?) FROM DUAL'; EXECUTE stmt USING 'xxx', CONCAT('yyy','zzz'); DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT ?'; +EXECUTE stmt USING _latin1'a'=_latin2'a'; +DEALLOCATE PREPARE stmt; + --echo # --echo # Testing disallowed expressions in USING --echo # @@ -4080,7 +4084,11 @@ DROP FUNCTION f1; PREPARE stmt FROM 'SELECT ?'; --error ER_CANT_AGGREGATE_2COLLATIONS -EXECUTE stmt USING _latin1'a'=_latin2'a'; +EXECUTE stmt USING CONCAT(_latin1'a',_latin2'a'); +# latin7_general_ci has anomalies on the ASCII range +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE stmt USING _latin1'a'=_latin7'a'; + DEALLOCATE PREPARE stmt; PREPARE stmt FROM 'SELECT ?'; @@ -4206,6 +4214,8 @@ SET @a=10; EXECUTE IMMEDIATE 'SELECT ? AS a' USING @a; EXECUTE IMMEDIATE 'SELECT ? AS a' USING 20; +EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin2'a'; + --echo # --echo # Erroneous queries @@ -4233,7 +4243,11 @@ EXECUTE IMMEDIATE 'EXECUTE stmt'; EXECUTE IMMEDIATE 'DEALLOCATE PREPARE stmt'; --error ER_CANT_AGGREGATE_2COLLATIONS -EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin2'a'; +EXECUTE IMMEDIATE 'SELECT ?' USING CONCAT(_latin1'a',_latin2'a'); + +# latin7_general_ci has anomalies on the ASCII range +--error ER_CANT_AGGREGATE_2COLLATIONS +EXECUTE IMMEDIATE 'SELECT ?' USING _latin1'a'=_latin7'a'; --error ER_OPERAND_COLUMNS EXECUTE IMMEDIATE 'SELECT ?' USING ROW(1,2); @@ -5635,4 +5649,51 @@ drop table t1, t2; --echo # End of 11.7 tests +--echo # Start of 11.8 tests + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # Parameters of prepared statements +--echo # + +SET NAMES latin2 COLLATE latin2_general_ci; +PREPARE stmt FROM 'SELECT _latin1''Y'' = ? AS r'; +SET @y='y', @n='N', @y_plus='Y+'; +EXECUTE stmt USING @y; +EXECUTE stmt USING @n; +EXECUTE stmt USING @y_plus; +EXECUTE stmt USING 'y'; +EXECUTE stmt USING 'Y+'; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'SELECT _latin1''Y+'' = ? AS r'; +EXECUTE stmt USING 'y'; +EXECUTE stmt USING 'Y+'; +DEALLOCATE PREPARE stmt; + +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'y'; +EXECUTE IMMEDIATE 'SELECT _latin1''Y'' = ? AS r' USING 'Y+'; + +--echo # Parameters compared to a view column created under another charset +SET NAMES latin1 COLLATE latin1_swedish_ci; +CREATE VIEW v1 AS SELECT 'Y' AS c1 UNION SELECT 'N'; +SET NAMES latin2 COLLATE latin2_general_ci; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1=? ORDER BY c1'; +EXECUTE stmt USING @y; +EXECUTE stmt USING @n; +EXECUTE stmt USING @y_plus; +EXECUTE stmt USING 'y'; +EXECUTE stmt USING 'x'; +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT c1 FROM v1 WHERE c1 IN (?,?) ORDER BY c1'; +EXECUTE stmt USING 'y', 'n'; +EXECUTE stmt USING 'y', 'Y+'; +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'y'; +EXECUTE IMMEDIATE 'SELECT c1 FROM v1 WHERE c1=?' USING 'Y+'; +DROP VIEW v1; +SET NAMES DEFAULT; + +--echo # End of 11.8 tests + --source include/test_db_charset_restore.inc diff --git a/mysql-test/main/ps_error.result b/mysql-test/main/ps_error.result index ad178f86915..f3fa78a1bbe 100644 --- a/mysql-test/main/ps_error.result +++ b/mysql-test/main/ps_error.result @@ -10,6 +10,7 @@ EXECUTE stmt; ERROR 22007: Truncated incorrect DOUBLE value: 'foo' SELECT a FROM t1 GROUP BY NULL WITH ROLLUP; a +NULL DROP TABLE t1; SET sql_mode=DEFAULT; SET SQL_MODE= 'STRICT_ALL_TABLES'; diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 56560180c80..216261a7578 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -3813,6 +3813,60 @@ id key1 3 2 drop table t1; # +# MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV +# +CREATE TABLE t1 ( +c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT, +c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT, +c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT, +c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT, +c32 INT, +KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17, +c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31) +); +INSERT INTO t1 (c0) VALUES (1), (2); +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 +AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 +AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 +AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 +AND c29=30 AND c30=31 AND c31=32; +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 +AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 +AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 +AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 +AND c29=30 AND c30=31 AND c31=32 AND c32=33; +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 +truncate t1; +# test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF +INSERT INTO t1 ( +c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, +c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31 +) +SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000; +CREATE TABLE t2 (x INT); +INSERT INTO t2 VALUES (1),(2); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32) +WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND +t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND +t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND +t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND +t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND +t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t1 ref_or_null k32 k32 160 const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,test.t2.x 798 Using where; Using index +DROP TABLE t1, t2; +# # End of 10.11 tests # set global innodb_stats_persistent= @innodb_stats_persistent_save; @@ -3870,6 +3924,4 @@ l_orderkey 292 291 DROP TABLE lineitem; -# # End of 11.0 tests -# diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index ae3bc84aed0..4d80170f705 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -1,4 +1,5 @@ --source include/no_valgrind_without_big.inc +--source include/have_sequence.inc # # Problem with range optimizer # @@ -2581,6 +2582,60 @@ evalp $query; drop table t1; +--echo # +--echo # MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV +--echo # + +CREATE TABLE t1 ( + c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT, + c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT, + c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT, + c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT, + c32 INT, + KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17, + c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31) +); + +INSERT INTO t1 (c0) VALUES (1), (2); + +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 + AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 + AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 + AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 + AND c29=30 AND c30=31 AND c31=32; + +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 + AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 + AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 + AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 + AND c29=30 AND c30=31 AND c31=32 AND c32=33; + +truncate t1; + +--echo # test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF +INSERT INTO t1 ( + c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, + c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31 +) +SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000; + +CREATE TABLE t2 (x INT); +INSERT INTO t2 VALUES (1),(2); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; + +EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32) +WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND +t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND +t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND +t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND +t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND +t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1; + +DROP TABLE t1, t2; + --echo # --echo # End of 10.11 tests --echo # @@ -2638,6 +2693,4 @@ EXPLAIN SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_re SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; DROP TABLE lineitem; ---echo # --echo # End of 11.0 tests ---echo # diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index 3e7048e1e46..5537c543f0d 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -3811,6 +3811,60 @@ id key1 3 2 drop table t1; # +# MDEV-41179 MAX_KEY_PARTS ranges in select causing SEGV +# +CREATE TABLE t1 ( +c0 INT, c1 INT, c2 INT, c3 INT, c4 INT, c5 INT, c6 INT, c7 INT, +c8 INT, c9 INT, c10 INT, c11 INT, c12 INT, c13 INT, c14 INT, c15 INT, +c16 INT, c17 INT, c18 INT, c19 INT, c20 INT, c21 INT, c22 INT, c23 INT, +c24 INT, c25 INT, c26 INT, c27 INT, c28 INT, c29 INT, c30 INT, c31 INT, +c32 INT, +KEY k32(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17, +c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31) +); +INSERT INTO t1 (c0) VALUES (1), (2); +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 +AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 +AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 +AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 +AND c29=30 AND c30=31 AND c31=32; +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 +SELECT * FROM t1 +WHERE c0=1 AND c1=2 AND c2=3 AND c3=4 AND c4=5 AND c5=6 AND c6=7 AND c7=8 +AND c8=9 AND c9=10 AND c10=11 AND c11=12 AND c12=13 AND c13=14 AND c14=15 +AND c15=16 AND c16=17 AND c17=18 AND c18=19 AND c19=20 AND c20=21 AND c21=22 +AND c22=23 AND c23=24 AND c24=25 AND c25=26 AND c26=27 AND c27=28 AND c28=29 +AND c29=30 AND c30=31 AND c31=32 AND c32=33; +c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 +truncate t1; +# test best_access_path, non default OPTIMIZER_ADJ_FIX_REUSE_RANGE_FOR_REF +INSERT INTO t1 ( +c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, +c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31 +) +SELECT 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +IF(seq<=3, NULL, seq%5) FROM seq_1_to_2000; +CREATE TABLE t2 (x INT); +INSERT INTO t2 VALUES (1),(2); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +EXPLAIN SELECT COUNT(*) FROM t2 STRAIGHT_JOIN t1 FORCE INDEX(k32) +WHERE t1.c0=1 AND t1.c1=1 AND t1.c2=1 AND t1.c3=1 AND t1.c4=1 AND t1.c5=1 AND +t1.c6=1 AND t1.c7=1 AND t1.c8=1 AND t1.c9=1 AND t1.c10=1 AND t1.c11=1 AND +t1.c12=1 AND t1.c13=1 AND t1.c14=1 AND t1.c15=1 AND t1.c16=1 AND t1.c17=1 AND +t1.c18=1 AND t1.c19=1 AND t1.c20=1 AND t1.c21=1 AND t1.c22=1 AND t1.c23=1 AND +t1.c24=1 AND t1.c25=1 AND t1.c26=1 AND t1.c27=1 AND t1.c28=1 AND t1.c29=1 AND +t1.c30=1 AND (t1.c31=t2.x OR t1.c31 IS NULL) AND t1.c31 < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t1 ref_or_null k32 k32 160 const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,const,test.t2.x 798 Using where; Using index +DROP TABLE t1, t2; +# # End of 10.11 tests # set global innodb_stats_persistent= @innodb_stats_persistent_save; @@ -3868,7 +3922,5 @@ l_orderkey 292 291 DROP TABLE lineitem; -# # End of 11.0 tests -# set optimizer_switch=@mrr_icp_extra_tmp; diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index bf8937a86cc..f0dca4f1b86 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -2340,10 +2340,40 @@ TEXT36 TEXT,TEXT37 TEXT,TEXT38 TEXT,TEXT39 TEXT,TEXT40 TEXT, TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT, TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT ) ENGINE=InnoDB; +insert into t1 ( +TEXT1, TEXT2, TEXT3, TEXT4, TEXT5, +TEXT6, TEXT7, TEXT8, TEXT9, TEXT10, +TEXT11, TEXT12,TEXT13,TEXT14,TEXT15, +TEXT16,TEXT17,TEXT18,TEXT19,TEXT20, +TEXT21,TEXT22,TEXT23,TEXT24,TEXT25, +TEXT26,TEXT27,TEXT28,TEXT29,TEXT30, +TEXT31,TEXT32,TEXT33,TEXT34,TEXT35, +TEXT36,TEXT37,TEXT38,TEXT39,TEXT40, +TEXT41,TEXT42,TEXT43,TEXT44,TEXT45, +TEXT46,TEXT47,TEXT48,TEXT49,TEXT50 +) values ( +"TEXT1", "TEXT2", "TEXT3", "TEXT4", "TEXT5", +"TEXT6", "TEXT7", "TEXT8", "TEXT9", "TEXT10", +"TEXT11", "TEXT12","TEXT13","TEXT14","TEXT15", +"TEXT16","TEXT17","TEXT18","TEXT19","TEXT20", +"TEXT21","TEXT22","TEXT23","TEXT24","TEXT25", +"TEXT26","TEXT27","TEXT28","TEXT29","TEXT30", +"TEXT31","TEXT32","TEXT33","TEXT34","TEXT35", +"TEXT36","TEXT37","TEXT38","TEXT39","TEXT40", +"TEXT41","TEXT42","TEXT43","TEXT44","TEXT45", +"TEXT46","TEXT47","TEXT48","TEXT49","TEXT50" +); +# A second row, differing only in a column outside the hash key +INSERT INTO t1 SELECT * FROM t1; +UPDATE t1 SET TEXT50= 'X' LIMIT 1; +SELECT 1 FROM t1 NATURAL JOIN t1 AS t2; +1 +1 +1 EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using where -1 SIMPLE t2 hash_ALL NULL #hash#$hj 150 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32,test.t1.TEXT33,test.t1.TEXT34,test.t1.TEXT35,test.t1.TEXT36,test.t1.TEXT37,test.t1.TEXT38,test.t1.TEXT39,test.t1.TEXT40,test.t1.TEXT41,test.t1.TEXT42,test.t1.TEXT43,test.t1.TEXT44,test.t1.TEXT45,test.t1.TEXT46,test.t1.TEXT47,test.t1.TEXT48,test.t1.TEXT49,test.t1.TEXT50 1 Using where; Using join buffer (flat, BNLH join) +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 hash_ALL NULL #hash#$hj 96 test.t1.TEXT1,test.t1.TEXT2,test.t1.TEXT3,test.t1.TEXT4,test.t1.TEXT5,test.t1.TEXT6,test.t1.TEXT7,test.t1.TEXT8,test.t1.TEXT9,test.t1.TEXT10,test.t1.TEXT11,test.t1.TEXT12,test.t1.TEXT13,test.t1.TEXT14,test.t1.TEXT15,test.t1.TEXT16,test.t1.TEXT17,test.t1.TEXT18,test.t1.TEXT19,test.t1.TEXT20,test.t1.TEXT21,test.t1.TEXT22,test.t1.TEXT23,test.t1.TEXT24,test.t1.TEXT25,test.t1.TEXT26,test.t1.TEXT27,test.t1.TEXT28,test.t1.TEXT29,test.t1.TEXT30,test.t1.TEXT31,test.t1.TEXT32 2 Using where; Using join buffer (flat, BNLH join) set join_cache_level=@tmp_jcl; drop table t1; # diff --git a/mysql-test/main/selectivity_innodb.test b/mysql-test/main/selectivity_innodb.test index 253e4b86431..95ce845ff8f 100644 --- a/mysql-test/main/selectivity_innodb.test +++ b/mysql-test/main/selectivity_innodb.test @@ -211,6 +211,7 @@ drop table t1; --echo # SET join_cache_level=3; + CREATE TABLE t1 ( TEXT1 TEXT, TEXT2 TEXT, TEXT3 TEXT, TEXT4 TEXT, TEXT5 TEXT, TEXT6 TEXT, TEXT7 TEXT, TEXT8 TEXT, TEXT9 TEXT, TEXT10 TEXT, @@ -223,6 +224,36 @@ CREATE TABLE t1 ( TEXT41 TEXT,TEXT42 TEXT,TEXT43 TEXT,TEXT44 TEXT,TEXT45 TEXT, TEXT46 TEXT,TEXT47 TEXT,TEXT48 TEXT,TEXT49 TEXT,TEXT50 TEXT ) ENGINE=InnoDB; + +insert into t1 ( + TEXT1, TEXT2, TEXT3, TEXT4, TEXT5, + TEXT6, TEXT7, TEXT8, TEXT9, TEXT10, + TEXT11, TEXT12,TEXT13,TEXT14,TEXT15, + TEXT16,TEXT17,TEXT18,TEXT19,TEXT20, + TEXT21,TEXT22,TEXT23,TEXT24,TEXT25, + TEXT26,TEXT27,TEXT28,TEXT29,TEXT30, + TEXT31,TEXT32,TEXT33,TEXT34,TEXT35, + TEXT36,TEXT37,TEXT38,TEXT39,TEXT40, + TEXT41,TEXT42,TEXT43,TEXT44,TEXT45, + TEXT46,TEXT47,TEXT48,TEXT49,TEXT50 +) values ( + "TEXT1", "TEXT2", "TEXT3", "TEXT4", "TEXT5", + "TEXT6", "TEXT7", "TEXT8", "TEXT9", "TEXT10", + "TEXT11", "TEXT12","TEXT13","TEXT14","TEXT15", + "TEXT16","TEXT17","TEXT18","TEXT19","TEXT20", + "TEXT21","TEXT22","TEXT23","TEXT24","TEXT25", + "TEXT26","TEXT27","TEXT28","TEXT29","TEXT30", + "TEXT31","TEXT32","TEXT33","TEXT34","TEXT35", + "TEXT36","TEXT37","TEXT38","TEXT39","TEXT40", + "TEXT41","TEXT42","TEXT43","TEXT44","TEXT45", + "TEXT46","TEXT47","TEXT48","TEXT49","TEXT50" +); + +--echo # A second row, differing only in a column outside the hash key +INSERT INTO t1 SELECT * FROM t1; +UPDATE t1 SET TEXT50= 'X' LIMIT 1; + +SELECT 1 FROM t1 NATURAL JOIN t1 AS t2; EXPLAIN SELECT 1 FROM t1 NATURAL JOIN t1 AS t2; set join_cache_level=@tmp_jcl; diff --git a/mysql-test/main/selectivity_no_engine.result b/mysql-test/main/selectivity_no_engine.result index f957e139e63..ad24dbbd4ed 100644 --- a/mysql-test/main/selectivity_no_engine.result +++ b/mysql-test/main/selectivity_no_engine.result @@ -313,7 +313,7 @@ EXPLAIN SELECT * FROM t1 AS a NATURAL JOIN t1 AS b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE a ALL NULL NULL NULL NULL 5 Using where -1 SIMPLE b hash_ALL NULL #hash#$hj 1341 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv,test.a.Delete_history_priv,test.a.ssl_type,test.a.ssl_cipher,test.a.x509_issuer,test.a.x509_subject,test.a.max_questions,test.a.max_updates,test.a.max_connections,test.a.max_user_connections,test.a.plugin,test.a.authentication_string,test.a.password_expired,test.a.is_role,test.a.default_role,test.a.max_statement_time 5 Using where; Using join buffer (flat, BNLH join) +1 SIMPLE b hash_ALL NULL #hash#$hj 1268 test.a.Host,test.a.User,test.a.Password,test.a.Select_priv,test.a.Insert_priv,test.a.Update_priv,test.a.Delete_priv,test.a.Create_priv,test.a.Drop_priv,test.a.Reload_priv,test.a.Shutdown_priv,test.a.Process_priv,test.a.File_priv,test.a.Grant_priv,test.a.References_priv,test.a.Index_priv,test.a.Alter_priv,test.a.Show_db_priv,test.a.Super_priv,test.a.Create_tmp_table_priv,test.a.Lock_tables_priv,test.a.Execute_priv,test.a.Repl_slave_priv,test.a.Repl_client_priv,test.a.Create_view_priv,test.a.Show_view_priv,test.a.Create_routine_priv,test.a.Alter_routine_priv,test.a.Create_user_priv,test.a.Event_priv,test.a.Trigger_priv,test.a.Create_tablespace_priv 5 Using where; Using join buffer (flat, BNLH join) DROP TABLE t1,t2,t3; # # MDEV-30529: Assertion `rnd_records <= s->found_records' failed in best_access_path diff --git a/mysql-test/main/shutdown_debug.result b/mysql-test/main/shutdown_debug.result index 524cdf20fa2..944c5ddd4b9 100644 --- a/mysql-test/main/shutdown_debug.result +++ b/mysql-test/main/shutdown_debug.result @@ -6,3 +6,26 @@ set @old_dbug=@@global.debug_dbug; set global debug_dbug='+d,CONNECT_wait'; select variable_value into @cons from information_schema.global_status where variable_name='connections'; # restart +# +# MDEV-25176 Shutdown hangs if event scheduler is started during shutdown +# +set global event_scheduler= 1; +connect con1, localhost, root; +set global debug_dbug= '+d,only_kill_system_threads'; +shutdown; +disconnect con1; +connection default; +set global event_scheduler= 1; +# Must be 0: the scheduler is not started after Events::stop() +select count(*) as scheduler_started from information_schema.processlist +where user = 'event_scheduler'; +scheduler_started +0 +# ON: the skipped start reports no error +select @@global.event_scheduler; +@@global.event_scheduler +ON +set global event_scheduler= 0; +disconnect default; +connect default, localhost, root; +# End of 10.11 tests diff --git a/mysql-test/main/shutdown_debug.test b/mysql-test/main/shutdown_debug.test index 664b4aea25e..c1bc364ad0d 100644 --- a/mysql-test/main/shutdown_debug.test +++ b/mysql-test/main/shutdown_debug.test @@ -1,5 +1,7 @@ source include/not_embedded.inc; source include/have_debug.inc; +# IO::Socket::UNIX in MDEV-25176 +source include/not_windows.inc; -- source include/no_view_protocol.inc --echo # @@ -15,3 +17,65 @@ exec $MYSQL -e "select sleep(3600)" >/dev/null 2>&1 &; let $wait_condition= select variable_value>@cons from information_schema.global_status where variable_name='connections'; source include/wait_condition.inc; source include/restart_mysqld.inc; + +--echo # +--echo # MDEV-25176 Shutdown hangs if event scheduler is started during shutdown +--echo # + +# How it works: the test starts the scheduler, then con1 sets +# only_kill_system_threads and does SHUTDOWN, so kill phase 1 of +# close_connections() leaves default connection alive. When the +# scheduler is gone from processlist, Events::stop() is done and default +# connection tries to start it again by setting event_scheduler= 1. +# +# With the bug Events::stop() works normally, so wait_condition does not +# halt, but the scheduler starts again (count 1) and shutdown would wait +# for it forever, so default connection stops it by setting +# event_scheduler= 0 before disconnecting. Then the test waits for the +# server to restart. + +set global event_scheduler= 1; +let $wait_condition= select count(*) = 1 from information_schema.processlist + where user = 'event_scheduler'; +source include/wait_condition.inc; + +let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')`; +let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect; +write_line wait $_expect_file_name; + +# Kill phase 1 of close_connections() skips client threads. +connect con1, localhost, root; +set global debug_dbug= '+d,only_kill_system_threads'; +# shutdown_mysqld.inc cannot be used from con1 as it deadlocks: it waits +# for the server to exit, while the server waits for default connection +# to disconnect. The deadlock ends with the server killed by timeout and +# the bug is never checked. +shutdown; +disconnect con1; + +# close_connections() did Events::stop() +connection default; +let $wait_condition= select count(*) = 0 from information_schema.processlist + where user = 'event_scheduler'; +source include/wait_condition.inc; +set global event_scheduler= 1; +--echo # Must be 0: the scheduler is not started after Events::stop() +select count(*) as scheduler_started from information_schema.processlist + where user = 'event_scheduler'; +--echo # ON: the skipped start reports no error +select @@global.event_scheduler; +set global event_scheduler= 0; +write_line restart $_expect_file_name; +disconnect default; + +# Restart failure or hang is caught by --start-timeout or --testcase-timeout +perl; + use IO::Socket::UNIX; + until (IO::Socket::UNIX->new(Peer => $ENV{MASTER_MYSOCK})) + { + select(undef, undef, undef, 0.1); + } +EOF +connect default, localhost, root; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/subselect_cache.result b/mysql-test/main/subselect_cache.result index 68e1216c207..b1f2cef0d21 100644 --- a/mysql-test/main/subselect_cache.result +++ b/mysql-test/main/subselect_cache.result @@ -3930,9 +3930,80 @@ pk b 29 3 drop view v1; drop table t1,t2,t3,t4; +# +# MDEV-32401 expression cache lead to crash if table of wrong type +# created and the cache switched off +# +CREATE TABLE t0 (c TEXT); +INSERT INTO t0 VALUES (71), (-79); +SELECT t1.d FROM (SELECT c AS d FROM t0) AS t1 JOIN t0 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +d +71 +-79 +71 +-79 +EXPLAIN EXTENDED SELECT t1.d FROM (SELECT c AS d FROM t0) AS t1 JOIN t0 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t0 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t0 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +3 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1276 Field or reference 'd' of SELECT #4 was resolved in SELECT #1 +Note 1981 Aggregate function 'bit_or()' of SELECT #4 belongs to SELECT #3 +Note 1276 Field or reference 'd' of SELECT #3 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t0`.`c` AS `d` from `test`.`t0` join `test`.`t0` where <`test`.`t0`.`c`>((/* select#3 */ select ord(<`test`.`t0`.`c`,bit_or(`test`.`t0`.`c`),bit_or(`test`.`t0`.`c`)>((/* select#4 */ select bit_or(`test`.`t0`.`c`)))) from `test`.`t0` group by `test`.`t0`.`c`)) +SELECT t1.d FROM (SELECT CAST(c as int) AS d FROM t0) AS t1 JOIN t0 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +d +71 +-79 +71 +-79 +EXPLAIN EXTENDED SELECT t1.d FROM (SELECT CAST(c as int) AS d FROM t0) AS t1 JOIN t0 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t0 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t0 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +3 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1276 Field or reference 'd' of SELECT #4 was resolved in SELECT #1 +Note 1981 Aggregate function 'bit_or()' of SELECT #4 belongs to SELECT #3 +Note 1276 Field or reference 'd' of SELECT #3 was resolved in SELECT #1 +Note 1003 /* select#1 */ select cast(`test`.`t0`.`c` as signed) AS `d` from `test`.`t0` join `test`.`t0` where ((/* select#3 */ select ord(((/* select#4 */ select bit_or(cast(`test`.`t0`.`c` as signed))))) from `test`.`t0` group by cast(`test`.`t0`.`c` as signed))) +CREATE TABLE t1 (c INT); +INSERT INTO t1 VALUES (71), (-79); +SELECT t2.d FROM (SELECT c AS d FROM t1) AS t2 JOIN t1 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t1 GROUP BY d +); +d +71 +-79 +71 +-79 +EXPLAIN EXTENDED SELECT t2.d FROM (SELECT c AS d FROM t1) AS t2 JOIN t1 ON ( +SELECT ORD((SELECT BIT_OR(d))) FROM t1 GROUP BY d +); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1276 Field or reference 'd' of SELECT #4 was resolved in SELECT #1 +Note 1981 Aggregate function 'bit_or()' of SELECT #4 belongs to SELECT #3 +Note 1276 Field or reference 'd' of SELECT #3 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `d` from `test`.`t1` join `test`.`t1` where <`test`.`t1`.`c`>((/* select#3 */ select ord(<`test`.`t1`.`c`,bit_or(`test`.`t1`.`c`),bit_or(`test`.`t1`.`c`)>((/* select#4 */ select bit_or(`test`.`t1`.`c`)))) from `test`.`t1` group by `test`.`t1`.`c`)) +DROP TABLE t0, t1; +# End of 11.4 tests SET optimizer_switch=@save_optimizer_switch; -# restore default -set @@optimizer_switch= default; # # MDEV-38801 implement Item_cache_year shallow_copy() # @@ -3957,4 +4028,4 @@ NATURAL JOIN 2000 1 2001 1 DROP TABLE t1; -# end of 10.11 tests +# End of 11.8 tests diff --git a/mysql-test/main/subselect_cache.test b/mysql-test/main/subselect_cache.test index 34b3fbbe6ff..fdbe700025a 100644 --- a/mysql-test/main/subselect_cache.test +++ b/mysql-test/main/subselect_cache.test @@ -1739,12 +1739,40 @@ SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 ); drop view v1; drop table t1,t2,t3,t4; +--echo # +--echo # MDEV-32401 expression cache lead to crash if table of wrong type +--echo # created and the cache switched off +--echo # + +CREATE TABLE t0 (c TEXT); +INSERT INTO t0 VALUES (71), (-79); +SELECT t1.d FROM (SELECT c AS d FROM t0) AS t1 JOIN t0 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +EXPLAIN EXTENDED SELECT t1.d FROM (SELECT c AS d FROM t0) AS t1 JOIN t0 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +SELECT t1.d FROM (SELECT CAST(c as int) AS d FROM t0) AS t1 JOIN t0 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +EXPLAIN EXTENDED SELECT t1.d FROM (SELECT CAST(c as int) AS d FROM t0) AS t1 JOIN t0 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t0 GROUP BY d +); +CREATE TABLE t1 (c INT); +INSERT INTO t1 VALUES (71), (-79); +SELECT t2.d FROM (SELECT c AS d FROM t1) AS t2 JOIN t1 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t1 GROUP BY d +); +EXPLAIN EXTENDED SELECT t2.d FROM (SELECT c AS d FROM t1) AS t2 JOIN t1 ON ( + SELECT ORD((SELECT BIT_OR(d))) FROM t1 GROUP BY d +); + +DROP TABLE t0, t1; + +--echo # End of 11.4 tests + SET optimizer_switch=@save_optimizer_switch; ---echo # restore default -set @@optimizer_switch= default; - - --echo # --echo # MDEV-38801 implement Item_cache_year shallow_copy() --echo # @@ -1762,4 +1790,4 @@ SELECT ) FROM t1; DROP TABLE t1; ---echo # end of 10.11 tests +--echo # End of 11.8 tests diff --git a/mysql-test/main/subselect_extra_no_semijoin.result b/mysql-test/main/subselect_extra_no_semijoin.result index 0cfb2b7cc48..f3e67a19ce8 100644 --- a/mysql-test/main/subselect_extra_no_semijoin.result +++ b/mysql-test/main/subselect_extra_no_semijoin.result @@ -537,10 +537,16 @@ CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM CHARSET=latin1; SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo'); a SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' ); +a +# Non-ASCII tis620 values cannot be converted to latin1, +# so the error path (the original MDEV-6439 scenario) is still used +SELECT * FROM t1 WHERE a >= ANY ( SELECT _tis620 0xA1 UNION SELECT _tis620 0xA2 ); ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' create table t2 (b int); insert into t2 values (1),(2),(3); SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2); +a +SELECT * FROM t1 WHERE a >= ANY ( SELECT _tis620 0xA1 FROM t2); ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' drop table t1,t2; SET GLOBAL slow_query_log=@tmp; diff --git a/mysql-test/main/subselect_extra_no_semijoin.test b/mysql-test/main/subselect_extra_no_semijoin.test index 97ceab6764e..7b8eae73523 100644 --- a/mysql-test/main/subselect_extra_no_semijoin.test +++ b/mysql-test/main/subselect_extra_no_semijoin.test @@ -25,14 +25,18 @@ SET log_slow_verbosity = 'explain'; CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM CHARSET=latin1; SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo'); ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' ); +--echo # Non-ASCII tis620 values cannot be converted to latin1, +--echo # so the error path (the original MDEV-6439 scenario) is still used +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT * FROM t1 WHERE a >= ANY ( SELECT _tis620 0xA1 UNION SELECT _tis620 0xA2 ); create table t2 (b int); insert into t2 values (1),(2),(3); ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2); +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT * FROM t1 WHERE a >= ANY ( SELECT _tis620 0xA1 FROM t2); drop table t1,t2; SET GLOBAL slow_query_log=@tmp; diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index 68de5be7c71..4b36960582a 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -2755,6 +2755,30 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1); c 0 DROP TABLE t1; +# +# MDEV-24907: Empty the source list after merging an Item_equal +# +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,0); +CREATE TABLE t2 (c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (2),(0); +CREATE TABLE t3 (d INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1),(3); +SELECT * FROM t1 LEFT JOIN ( +t2 JOIN t3 ON (t3.d = t2.c) +) ON ( +t1.b NOT IN (SELECT d FROM t3) +) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b; +a b c d +SELECT * FROM t1 LEFT JOIN ( +t2 JOIN t3 ON (t3.d = t2.c) +) ON ( +t1.b > 3 +) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND +t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND +t1.a = t1.b; +a b c d +DROP TABLE t1, t2, t3; # end of 10.11 tests # # MDEV-41303 rand() in a semi-join subquery is checked on outer rows diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result index c798e754400..d08bac2530f 100644 --- a/mysql-test/main/subselect_no_semijoin.result +++ b/mysql-test/main/subselect_no_semijoin.result @@ -7681,7 +7681,7 @@ EXPLAIN { "query_block": { "select_id": 2, - "pseudo_bits_condition": "1 = t1.a or (1,(subquery#3))", + "outer_ref_condition": "1 = t1.a or (1,(subquery#3))", "nested_loop": [ { "table": { diff --git a/mysql-test/main/subselect_sj.result b/mysql-test/main/subselect_sj.result index 3115b54469e..98583e69afd 100644 --- a/mysql-test/main/subselect_sj.result +++ b/mysql-test/main/subselect_sj.result @@ -3069,8 +3069,18 @@ DROP TABLE t1,t2,t3,t4; create table t1(a int); insert into t1 values(1),(2),(3),(null); explain +select 1 from t1 where _latin7 "a" in (select 'a' from t1); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +explain +select 1 from t1 where _latin7 "1" in (select '1' from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 FirstMatch +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +explain select 1 from t1 where _cp932 "1" in (select '1' from t1); -ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 FirstMatch +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) drop table t1; # # MDEV-7823: Server crashes in next_depth_first_tab on nested IN clauses with SQ inside diff --git a/mysql-test/main/subselect_sj.test b/mysql-test/main/subselect_sj.test index 1a3816b46ab..e962ebe62be 100644 --- a/mysql-test/main/subselect_sj.test +++ b/mysql-test/main/subselect_sj.test @@ -2765,8 +2765,14 @@ DROP TABLE t1,t2,t3,t4; create table t1(a int); insert into t1 values(1),(2),(3),(null); +# latin7_general_ci has anomalies on the ASCII letters --error ER_CANT_AGGREGATE_2COLLATIONS explain +select 1 from t1 where _latin7 "a" in (select 'a' from t1); +# But the ASCII digits are sorted in the same way in all collations +explain +select 1 from t1 where _latin7 "1" in (select '1' from t1); +explain select 1 from t1 where _cp932 "1" in (select '1' from t1); drop table t1; diff --git a/mysql-test/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result index 93b5e2592f2..2e031a5414d 100644 --- a/mysql-test/main/subselect_sj_jcl6.result +++ b/mysql-test/main/subselect_sj_jcl6.result @@ -3075,8 +3075,18 @@ DROP TABLE t1,t2,t3,t4; create table t1(a int); insert into t1 values(1),(2),(3),(null); explain +select 1 from t1 where _latin7 "a" in (select 'a' from t1); +ERROR HY000: Illegal mix of collations (latin7_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +explain +select 1 from t1 where _latin7 "1" in (select '1' from t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 FirstMatch +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) +explain select 1 from t1 where _cp932 "1" in (select '1' from t1); -ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 FirstMatch +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) drop table t1; # # MDEV-7823: Server crashes in next_depth_first_tab on nested IN clauses with SQ inside diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index aaccecaa0ef..0c229042b68 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -2781,6 +2781,30 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1); c 0 DROP TABLE t1; +# +# MDEV-24907: Empty the source list after merging an Item_equal +# +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,0); +CREATE TABLE t2 (c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (2),(0); +CREATE TABLE t3 (d INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1),(3); +SELECT * FROM t1 LEFT JOIN ( +t2 JOIN t3 ON (t3.d = t2.c) +) ON ( +t1.b NOT IN (SELECT d FROM t3) +) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b; +a b c d +SELECT * FROM t1 LEFT JOIN ( +t2 JOIN t3 ON (t3.d = t2.c) +) ON ( +t1.b > 3 +) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND +t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND +t1.a = t1.b; +a b c d +DROP TABLE t1, t2, t3; # end of 10.11 tests # # MDEV-41303 rand() in a semi-join subquery is checked on outer rows diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index 1cb6285d7e8..79b93241a36 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -2479,6 +2479,33 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1); DROP TABLE t1; +--echo # +--echo # MDEV-24907: Empty the source list after merging an Item_equal +--echo # +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (0,0); +CREATE TABLE t2 (c INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (2),(0); +CREATE TABLE t3 (d INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1),(3); + +# Result should be empty. +SELECT * FROM t1 LEFT JOIN ( + t2 JOIN t3 ON (t3.d = t2.c) +) ON ( + t1.b NOT IN (SELECT d FROM t3) +) WHERE (t1.a, t3.d) IN (SELECT c, MAX(c) FROM t2) AND t1.a = t1.b; + +SELECT * FROM t1 LEFT JOIN ( + t2 JOIN t3 ON (t3.d = t2.c) +) ON ( + t1.b > 3 +) WHERE t1.a IN (SELECT MAX(c) FROM t2 GROUP BY c) AND + t3.d IN (SELECT COUNT(c) FROM t2 GROUP BY c) AND + t1.a = t1.b; + +DROP TABLE t1, t2, t3; + --echo # end of 10.11 tests --echo # diff --git a/mysql-test/main/subselect_sj_mat_rand.opt b/mysql-test/main/subselect_sj_mat_rand.opt new file mode 100644 index 00000000000..1af9e30741b --- /dev/null +++ b/mysql-test/main/subselect_sj_mat_rand.opt @@ -0,0 +1 @@ +--memory.optimizer_row_copy_cost=0 diff --git a/mysql-test/main/subselect_sj_mat_rand.result b/mysql-test/main/subselect_sj_mat_rand.result new file mode 100644 index 00000000000..692d522e4c9 --- /dev/null +++ b/mysql-test/main/subselect_sj_mat_rand.result @@ -0,0 +1,421 @@ +# +# MDEV-41146: rand() in WHERE is not checked when every base table +# is const and a materialized semi-join terminates the join order +# +# A WHERE conjunct that calls rand() and names no field is checked on +# the last top level base table that is not const. When every base +# table is const, the conjunct is checked once in outer_ref_condition. +# +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +create table t2 (b int primary key); +insert into t2 values (1),(2),(3),(4); +create table t3 (c int, d int); +insert into t3 values (1,1),(2,2),(3,3),(4,4),(5,5), +(6,6),(7,7),(8,8),(9,9),(10,10); +insert into t3 select c+10, d+10 from t3; +insert into t3 select c+20, d+20 from t3; +insert into t3 select c+40, d+40 from t3; +create table t4 (e int, f int); +insert into t4 select c, d from t3; +create table t5 (g int); +insert into t5 select c+1000 from t3; +set @save_optimizer_switch= @@optimizer_switch; +set @save_optimizer_where_cost= @@optimizer_where_cost; +set optimizer_switch='firstmatch=off,loosescan=off'; +set optimizer_where_cost=0; +# One const table. rand() < 0 is never true, so the result is empty. +explain +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() < 0; +a +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() >= 0; +a +1 +# The IN-equality is still checked. t5 holds no value below 1001. +select t1.a from t1 where t1.a=1 and t1.a in (select g from t5) and rand() >= 0; +a +select t1.a from t1 where t1.a=1 and t1.a in (select g from t5) and rand() < 0; +a +# Two rand() conjuncts. outer_ref_condition shows both. +explain format=json +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() < 0 and rand() < 2; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "outer_ref_condition": "rand() < 0 and rand() < 2", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "const", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["a"], + "ref": ["const"], + "rows": 1, + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", + "key_length": "4", + "used_key_parts": ["c"], + "ref": ["func"], + "rows": 1, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 2, + "nested_loop": [ + { + "table": { + "table_name": "t3", + "access_type": "ALL", + "loops": 1, + "rows": 80, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t3.c = 1" + } + } + ] + } + } + } + } + ] + } +} +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() < 0 and rand() < 2; +a +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() >= 0 and rand() < 2; +a +1 +# Two const tables joined, as in the original report. +explain +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() < 0; +x y +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() >= 0; +x y +1 1 +# Two materialized nests terminate the join order. +explain +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) +and rand() < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +3 MATERIALIZED t4 ALL NULL NULL NULL NULL 80 Using where +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) +and rand() < 0; +a +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) +and rand() >= 0; +a +1 +# The const table column is bigint and the subquery column is int. +create table t6 (a bigint primary key); +insert into t6 values (1),(2),(3); +explain +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t6 const PRIMARY PRIMARY 8 const 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() < 0; +a +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() >= 0; +a +1 +# An outer table that is not const precedes the nest. The conjunct +# is checked on that table. +create table t7 (a int); +insert into t7 values (1),(2),(3),(100); +explain +select t7.a from t7 where t7.a in (select c from t3) and rand() < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t7 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 +select t7.a from t7 where t7.a in (select c from t3) and rand() < 0; +a +select t7.a from t7 where t7.a in (select c from t3) and rand() >= 0; +a +1 +2 +3 +# The conjunct also reads a column of the enclosing query. It is true +# when t7.a is 4 or more, which holds only for the row where t7.a is +# 100. +explain +select t7.a, +(select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < t7.a - 3) x +from t7; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t7 ALL NULL NULL NULL NULL 4 +2 DEPENDENT SUBQUERY t1 const PRIMARY PRIMARY 4 const 1 Using index +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +select t7.a, +(select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < t7.a - 3) x +from t7; +a x +1 NULL +100 1 +2 NULL +3 NULL +# rand(7) continues one sequence across the executions of the +# subquery. The conjunct takes one value for each row of t8, +# including the rows where t8.a is 100 and the lookup finds no match. +# A plan where t1 is not const checks the conjunct on t1 before the +# lookup and returns the same rows. +create table t8 (id int, a int); +insert into t8 values (1,1),(2,100),(3,2),(4,100),(5,3),(6,100),(7,4), +(8,100),(9,5),(10,100),(11,6),(12,7),(13,8),(14,9); +explain +select t8.id, +(select t1.a from t1 +where t1.a=1 and t8.a in (select c from t3) and rand(7) < 0.5) x +from t8; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t8 ALL NULL NULL NULL NULL 14 +2 DEPENDENT SUBQUERY t1 const PRIMARY PRIMARY 4 const 1 Using index +2 DEPENDENT SUBQUERY eq_ref distinct_key distinct_key 4 func 1 +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 +select t8.id, +(select t1.a from t1 +where t1.a=1 and t8.a in (select c from t3) and rand(7) < 0.5) x +from t8 order by t8.id; +id x +1 NULL +2 NULL +3 1 +4 NULL +5 NULL +6 NULL +7 1 +8 NULL +9 1 +10 NULL +11 NULL +12 1 +13 1 +14 NULL +# rand() in the WHERE of the subquery instead of the outer query. +# Every row of t9 has c=1. The first four values of rand(1) are not +# below 0.09 and the fifth is, so checking the condition on each row +# of t9 matches t1.a=1. A subquery that calls rand() is not converted +# to a semi-join, so the condition is not moved to the outer query and +# checked once there. Adding 0*t9.d makes the condition read a column +# of t9, which gives the same result in any plan. +create table t9 (c int, d int); +insert into t9 select 1, 1 from seq_1_to_80; +explain +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY const distinct_key distinct_key 4 const 1 +2 MATERIALIZED t9 ALL NULL NULL NULL NULL 80 Using where +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09); +count(*) +1 +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09 + 0*t9.d); +count(*) +1 +# The conjunct is checked once, in outer_ref_condition, only when +# the join returns at most one row. f1() counts its calls. With +# the const t1 and a lookup nest, f1() is called once. Adding t10, +# which holds two rows, makes the join return two rows, and f1() is +# called once for each. +create table t10 (b int); +insert into t10 values (1),(2); +create function f1() returns int not deterministic +begin +set @calls= @calls + 1; +return 1; +end| +explain +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +set @calls= 0; +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +a +1 +select @calls; +@calls +1 +explain +select t1.a, t10.b from t1, t10 +where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index +1 PRIMARY t10 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 80 Using where +set @calls= 0; +select t1.a, t10.b from t1, t10 +where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +a b +1 1 +1 2 +select @calls; +@calls +2 +drop function f1; +# A materialized nest read by a scan precedes t11, which is not +# const, so the conjunct is checked on t11. The optimizer chooses +# the scan only with the statistics from ANALYZE, which give 200 +# rows of t11 for each value of a. +create table t11 (a int, key(a)); +insert into t11 select seq mod 10 from seq_1_to_2000; +create table t12 (b int); +insert into t12 select seq mod 10 from seq_1_to_20; +analyze table t11, t12 persistent for all; +Table Op Msg_type Msg_text +test.t11 analyze status Engine-independent statistics collected +test.t11 analyze status Table is already up to date +test.t12 analyze status Engine-independent statistics collected +test.t12 analyze status OK +explain format=json +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() < 0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "const", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["a"], + "ref": ["const"], + "rows": 1, + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "", + "access_type": "ALL", + "possible_keys": ["distinct_key"], + "rows": 20, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 2, + "nested_loop": [ + { + "table": { + "table_name": "t12", + "access_type": "ALL", + "loops": 1, + "rows": 20, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t12.b is not null" + } + } + ] + } + } + } + }, + { + "table": { + "table_name": "t11", + "access_type": "ref", + "possible_keys": ["a"], + "key": "a", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t12.b"], + "loops": 20, + "rows": 200, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "rand() < 0", + "using_index": true + } + } + ] + } +} +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() < 0; +count(*) +0 +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() >= 0; +count(*) +2000 +# A prepared statement executed twice, with the bound for rand() +# passed as a parameter. The first execution returns no row and +# the second returns t1.a=1. +prepare stmt from "select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < ?"; +execute stmt using 0; +a +execute stmt using 2; +a +1 +deallocate prepare stmt; +# The same query in a stored procedure called twice. +create procedure p1(x int) +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < x; +call p1(0); +a +call p1(2); +a +1 +drop procedure p1; +set optimizer_switch= @save_optimizer_switch; +set optimizer_where_cost= @save_optimizer_where_cost; +drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12; +# End of 11.4 tests diff --git a/mysql-test/main/subselect_sj_mat_rand.test b/mysql-test/main/subselect_sj_mat_rand.test new file mode 100644 index 00000000000..be6c85739b2 --- /dev/null +++ b/mysql-test/main/subselect_sj_mat_rand.test @@ -0,0 +1,214 @@ +--source include/have_sequence.inc + +--echo # +--echo # MDEV-41146: rand() in WHERE is not checked when every base table +--echo # is const and a materialized semi-join terminates the join order +--echo # +--echo # A WHERE conjunct that calls rand() and names no field is checked on +--echo # the last top level base table that is not const. When every base +--echo # table is const, the conjunct is checked once in outer_ref_condition. +--echo # + +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +create table t2 (b int primary key); +insert into t2 values (1),(2),(3),(4); +create table t3 (c int, d int); +insert into t3 values (1,1),(2,2),(3,3),(4,4),(5,5), +(6,6),(7,7),(8,8),(9,9),(10,10); +insert into t3 select c+10, d+10 from t3; +insert into t3 select c+20, d+20 from t3; +insert into t3 select c+40, d+40 from t3; +create table t4 (e int, f int); +insert into t4 select c, d from t3; +create table t5 (g int); +insert into t5 select c+1000 from t3; + +set @save_optimizer_switch= @@optimizer_switch; +set @save_optimizer_where_cost= @@optimizer_where_cost; +set optimizer_switch='firstmatch=off,loosescan=off'; +set optimizer_where_cost=0; + +--echo # One const table. rand() < 0 is never true, so the result is empty. +explain +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() < 0; +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() < 0; +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and rand() >= 0; + +--echo # The IN-equality is still checked. t5 holds no value below 1001. +select t1.a from t1 where t1.a=1 and t1.a in (select g from t5) and rand() >= 0; +select t1.a from t1 where t1.a=1 and t1.a in (select g from t5) and rand() < 0; + +--echo # Two rand() conjuncts. outer_ref_condition shows both. +--source include/explain-no-costs.inc +explain format=json +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() < 0 and rand() < 2; +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() < 0 and rand() < 2; +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) +and rand() >= 0 and rand() < 2; + +--echo # Two const tables joined, as in the original report. +explain +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() < 0; +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() < 0; +select t1.a x, t2.b y from t1 left join t2 on t1.a=t2.b +where t1.a=1 and t2.b=1 and t1.a in (select c from t3) and rand() >= 0; + +--echo # Two materialized nests terminate the join order. +explain +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) + and rand() < 0; +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) + and rand() < 0; +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and t1.a in (select e from t4) + and rand() >= 0; + +--echo # The const table column is bigint and the subquery column is int. +create table t6 (a bigint primary key); +insert into t6 values (1),(2),(3); +explain +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() < 0; +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() < 0; +select t6.a from t6 where t6.a=1 and t6.a in (select c from t3) and rand() >= 0; + +--echo # An outer table that is not const precedes the nest. The conjunct +--echo # is checked on that table. +create table t7 (a int); +insert into t7 values (1),(2),(3),(100); +explain +select t7.a from t7 where t7.a in (select c from t3) and rand() < 0; +select t7.a from t7 where t7.a in (select c from t3) and rand() < 0; +--sorted_result +select t7.a from t7 where t7.a in (select c from t3) and rand() >= 0; + +--echo # The conjunct also reads a column of the enclosing query. It is true +--echo # when t7.a is 4 or more, which holds only for the row where t7.a is +--echo # 100. +explain +select t7.a, + (select t1.a from t1 + where t1.a=1 and t1.a in (select c from t3) and rand() < t7.a - 3) x +from t7; +--sorted_result +select t7.a, + (select t1.a from t1 + where t1.a=1 and t1.a in (select c from t3) and rand() < t7.a - 3) x +from t7; + +--echo # rand(7) continues one sequence across the executions of the +--echo # subquery. The conjunct takes one value for each row of t8, +--echo # including the rows where t8.a is 100 and the lookup finds no match. +--echo # A plan where t1 is not const checks the conjunct on t1 before the +--echo # lookup and returns the same rows. +create table t8 (id int, a int); +insert into t8 values (1,1),(2,100),(3,2),(4,100),(5,3),(6,100),(7,4), +(8,100),(9,5),(10,100),(11,6),(12,7),(13,8),(14,9); +explain +select t8.id, + (select t1.a from t1 + where t1.a=1 and t8.a in (select c from t3) and rand(7) < 0.5) x +from t8; +select t8.id, + (select t1.a from t1 + where t1.a=1 and t8.a in (select c from t3) and rand(7) < 0.5) x +from t8 order by t8.id; + +--echo # rand() in the WHERE of the subquery instead of the outer query. +--echo # Every row of t9 has c=1. The first four values of rand(1) are not +--echo # below 0.09 and the fifth is, so checking the condition on each row +--echo # of t9 matches t1.a=1. A subquery that calls rand() is not converted +--echo # to a semi-join, so the condition is not moved to the outer query and +--echo # checked once there. Adding 0*t9.d makes the condition read a column +--echo # of t9, which gives the same result in any plan. +create table t9 (c int, d int); +insert into t9 select 1, 1 from seq_1_to_80; +explain +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09); +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09); +select count(*) from t1 +where t1.a=1 and t1.a in (select c from t9 where rand(1) < 0.09 + 0*t9.d); + +--echo # The conjunct is checked once, in outer_ref_condition, only when +--echo # the join returns at most one row. f1() counts its calls. With +--echo # the const t1 and a lookup nest, f1() is called once. Adding t10, +--echo # which holds two rows, makes the join return two rows, and f1() is +--echo # called once for each. +create table t10 (b int); +insert into t10 values (1),(2); +delimiter |; +create function f1() returns int not deterministic +begin + set @calls= @calls + 1; + return 1; +end| +delimiter ;| +explain +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +set @calls= 0; +# A second execution under --ps-protocol would double @calls. +--disable_ps2_protocol +select t1.a from t1 where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +--enable_ps2_protocol +select @calls; +explain +select t1.a, t10.b from t1, t10 +where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +set @calls= 0; +# A second execution under --ps-protocol would double @calls. +--disable_ps2_protocol +--sorted_result +select t1.a, t10.b from t1, t10 +where t1.a=1 and t1.a in (select c from t3) and f1() > 0; +--enable_ps2_protocol +select @calls; +drop function f1; + +--echo # A materialized nest read by a scan precedes t11, which is not +--echo # const, so the conjunct is checked on t11. The optimizer chooses +--echo # the scan only with the statistics from ANALYZE, which give 200 +--echo # rows of t11 for each value of a. +create table t11 (a int, key(a)); +insert into t11 select seq mod 10 from seq_1_to_2000; +create table t12 (b int); +insert into t12 select seq mod 10 from seq_1_to_20; +analyze table t11, t12 persistent for all; +--source include/explain-no-costs.inc +explain format=json +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() < 0; +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() < 0; +select count(*) from t1, t11 +where t1.a=1 and t11.a in (select b from t12) and rand() >= 0; + +--echo # A prepared statement executed twice, with the bound for rand() +--echo # passed as a parameter. The first execution returns no row and +--echo # the second returns t1.a=1. +prepare stmt from "select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < ?"; +execute stmt using 0; +execute stmt using 2; +deallocate prepare stmt; + +--echo # The same query in a stored procedure called twice. +create procedure p1(x int) +select t1.a from t1 +where t1.a=1 and t1.a in (select c from t3) and rand() < x; +call p1(0); +call p1(2); +drop procedure p1; + +set optimizer_switch= @save_optimizer_switch; +set optimizer_where_cost= @save_optimizer_where_cost; +drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12; + +--echo # End of 11.4 tests diff --git a/mysql-test/main/sum_distinct.result b/mysql-test/main/sum_distinct.result index 2746f5a09f4..a8c83712362 100644 --- a/mysql-test/main/sum_distinct.result +++ b/mysql-test/main/sum_distinct.result @@ -107,3 +107,38 @@ SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; SUM(DISTINCT a) NULL DROP TABLE t1; +# +# MDEV-39194: SUM DISTINCT of a bit literal +# +SELECT SUM(DISTINCT b'1100') AS r; +r +12 +SELECT SUM(DISTINCT b'00000000') AS zero_value, +SUM(DISTINCT b'11111111') AS byte_value, +SUM(DISTINCT b'100000000') AS two_byte_value; +zero_value byte_value two_byte_value +0 255 256 +SELECT SUM(DISTINCT 0xff) AS hex_value, +AVG(DISTINCT b'1100') = 12 AS bit_average_is_12; +hex_value bit_average_is_12 +255 1 +SELECT SUM(DISTINCT 0xffffffffffffffff) = SUM(0xffffffffffffffff) +AS unsigned_sum_matches, +AVG(DISTINCT 0xffffffffffffffff) = AVG(0xffffffffffffffff) +AS unsigned_average_matches; +unsigned_sum_matches unsigned_average_matches +1 1 +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (2,1), (3,1); +SELECT SUM(DISTINCT b'1100') AS bit_sum, +AVG(DISTINCT b'1100') = 12 AS bit_average_is_12, +COUNT(DISTINCT b'1100') AS bit_count FROM t1; +bit_sum bit_average_is_12 bit_count +12 1 1 +SELECT AVG(DISTINCT b / a) AS decimal_average FROM t1; +decimal_average +0.61110000 +DROP TABLE t1; +# +# End of 11.4 tests +# diff --git a/mysql-test/main/sum_distinct.test b/mysql-test/main/sum_distinct.test index 633a72fddc8..81c4f4bf372 100644 --- a/mysql-test/main/sum_distinct.test +++ b/mysql-test/main/sum_distinct.test @@ -105,3 +105,30 @@ SELECT SUM(DISTINCT a) FROM t1; SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; DROP TABLE t1; + +--echo # +--echo # MDEV-39194: SUM DISTINCT of a bit literal +--echo # +SELECT SUM(DISTINCT b'1100') AS r; +SELECT SUM(DISTINCT b'00000000') AS zero_value, + SUM(DISTINCT b'11111111') AS byte_value, + SUM(DISTINCT b'100000000') AS two_byte_value; +SELECT SUM(DISTINCT 0xff) AS hex_value, + AVG(DISTINCT b'1100') = 12 AS bit_average_is_12; +SELECT SUM(DISTINCT 0xffffffffffffffff) = SUM(0xffffffffffffffff) + AS unsigned_sum_matches, + AVG(DISTINCT 0xffffffffffffffff) = AVG(0xffffffffffffffff) + AS unsigned_average_matches; + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (2,1), (3,1); +SELECT SUM(DISTINCT b'1100') AS bit_sum, + AVG(DISTINCT b'1100') = 12 AS bit_average_is_12, + COUNT(DISTINCT b'1100') AS bit_count FROM t1; +# DISTINCT inputs keep the argument's decimal scale, not AVG's result scale. +SELECT AVG(DISTINCT b / a) AS decimal_average FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 11.4 tests +--echo # diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 24111441ee5..868104fffec 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -3856,7 +3856,8 @@ SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'text1' AS `c1`,'text2' AS `c2` latin1 latin1_general_ci SELECT * FROM v1 WHERE c1 = 'text1'; -ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin1_general_ci,COERCIBLE) for operation '=' +c1 c2 +text1 text2 SELECT * FROM v1 WHERE c2 = 'text2'; c1 c2 text1 text2 @@ -3869,7 +3870,31 @@ SELECT * FROM v1 WHERE c1 = 'text1'; c1 c2 text1 text2 SELECT * FROM v1 WHERE c2 = 'text2'; -ERROR HY000: Illegal mix of collations (latin1_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +c1 c2 +text1 text2 +DROP VIEW v1; +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# A view created under latin1_general_ci, queried under latin1. +# The probes match a row on each of the ALNUM, IDENT and ASCII +# repertoires. +# +SET collation_connection = latin1_general_ci; +CREATE VIEW v1 AS +SELECT 'text1' AS c1 UNION SELECT 'text_1' UNION SELECT 'te+xt'; +SET NAMES latin1; +# ALNUM repertoire +SELECT * FROM v1 WHERE c1 = 'TEXT1'; +c1 +text1 +# IDENT repertoire +SELECT * FROM v1 WHERE c1 = 'TEXT_1'; +c1 +text_1 +# ASCII repertoire +SELECT * FROM v1 WHERE c1 = 'TE+XT'; +c1 +te+xt DROP VIEW v1; create procedure p() begin diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 50dbf1a862c..bad2aecc75d 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -3593,7 +3593,6 @@ SELECT COLLATION(c1), COLLATION(c2) FROM v1; SHOW CREATE VIEW v1; ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM v1 WHERE c1 = 'text1'; SELECT * FROM v1 WHERE c2 = 'text2'; @@ -3605,11 +3604,29 @@ SELECT COLLATION(c1), COLLATION(c2) FROM v1; SELECT * FROM v1 WHERE c1 = 'text1'; ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM v1 WHERE c2 = 'text2'; DROP VIEW v1; +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # A view created under latin1_general_ci, queried under latin1. +--echo # The probes match a row on each of the ALNUM, IDENT and ASCII +--echo # repertoires. +--echo # + +SET collation_connection = latin1_general_ci; +CREATE VIEW v1 AS + SELECT 'text1' AS c1 UNION SELECT 'text_1' UNION SELECT 'te+xt'; +SET NAMES latin1; +--echo # ALNUM repertoire +SELECT * FROM v1 WHERE c1 = 'TEXT1'; +--echo # IDENT repertoire +SELECT * FROM v1 WHERE c1 = 'TEXT_1'; +--echo # ASCII repertoire +SELECT * FROM v1 WHERE c1 = 'TE+XT'; +DROP VIEW v1; + # # Bug#34587 Creating a view inside a stored procedure leads to a server crash # diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 14caa158064..fddfab55959 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3539,6 +3539,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; 1 row_number() over (order by 1) +1 1 drop table t1; explain SELECT DISTINCT BIT_OR(100) OVER () FROM dual @@ -4874,3 +4875,27 @@ DROP TABLE t1; # # End of 10.11 tests # +# +# MDEV-41146: WHERE is not checked when every table is const and +# the query needs a temporary table +# +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (1),(10); +# rand() < 0 is never true, so the result is empty. +select a, row_number() over () from t1 where a=1 and rand() < 0; +a row_number() over () +select a, row_number() over () from t1 where a=1 and rand() >= 0; +a row_number() over () +1 1 +# t2.b > 5 is true only for the row where t2.b is 10. +select b, (select row_number() over () from t1 where t1.a=1 and t2.b > 5) x +from t2; +b x +1 NULL +10 1 +drop table t1, t2; +# +# End of 11.4 tests +# diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 3c11037d68d..48927597716 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -3150,3 +3150,28 @@ DROP TABLE t1; --echo # --echo # End of 10.11 tests --echo # + +--echo # +--echo # MDEV-41146: WHERE is not checked when every table is const and +--echo # the query needs a temporary table +--echo # + +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (1),(10); + +--echo # rand() < 0 is never true, so the result is empty. +select a, row_number() over () from t1 where a=1 and rand() < 0; +select a, row_number() over () from t1 where a=1 and rand() >= 0; + +--echo # t2.b > 5 is true only for the row where t2.b is 10. +--sorted_result +select b, (select row_number() over () from t1 where t1.a=1 and t2.b > 5) x +from t2; + +drop table t1, t2; + +--echo # +--echo # End of 11.4 tests +--echo # diff --git a/mysql-test/main/x509_oneline_separators,openssl_1.rdiff b/mysql-test/main/x509_oneline_separators,openssl_1.rdiff new file mode 100644 index 00000000000..e68eb4d1fbf --- /dev/null +++ b/mysql-test/main/x509_oneline_separators,openssl_1.rdiff @@ -0,0 +1,16 @@ +--- main/x509_oneline_separators.result ++++ main/x509_oneline_separators.reject +@@ -6,10 +6,10 @@ + # Default old_mode: only one grant matches, library-dependent + # + # connect as escaped_user +-connect_test +-escaped_user@localhost connected ++ERROR 1045 (28000): Access denied for user 'escaped_user'@'localhost' (using password: NO) + # connect as raw_user +-ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO) ++connect_test ++raw_user@localhost connected + # + # old_mode=X509_LENIENT_COMPARE: both grants now match + # diff --git a/mysql-test/main/x509_oneline_separators,wolfssl.rdiff b/mysql-test/main/x509_oneline_separators,wolfssl.rdiff new file mode 100644 index 00000000000..e68eb4d1fbf --- /dev/null +++ b/mysql-test/main/x509_oneline_separators,wolfssl.rdiff @@ -0,0 +1,16 @@ +--- main/x509_oneline_separators.result ++++ main/x509_oneline_separators.reject +@@ -6,10 +6,10 @@ + # Default old_mode: only one grant matches, library-dependent + # + # connect as escaped_user +-connect_test +-escaped_user@localhost connected ++ERROR 1045 (28000): Access denied for user 'escaped_user'@'localhost' (using password: NO) + # connect as raw_user +-ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO) ++connect_test ++raw_user@localhost connected + # + # old_mode=X509_LENIENT_COMPARE: both grants now match + # diff --git a/mysql-test/main/x509_oneline_separators.combinations b/mysql-test/main/x509_oneline_separators.combinations new file mode 100644 index 00000000000..5aa3ec01523 --- /dev/null +++ b/mysql-test/main/x509_oneline_separators.combinations @@ -0,0 +1,5 @@ +[wolfssl] + +[openssl_1] + +[openssl_3_or_later] diff --git a/mysql-test/main/x509_oneline_separators.result b/mysql-test/main/x509_oneline_separators.result new file mode 100644 index 00000000000..3835deb2f3e --- /dev/null +++ b/mysql-test/main/x509_oneline_separators.result @@ -0,0 +1,27 @@ +create user escaped_user@localhost +require subject '/CN=a\\/b\\+c'; +create user raw_user@localhost +require subject '/CN=a/b+c'; +# +# Default old_mode: only one grant matches, library-dependent +# +# connect as escaped_user +connect_test +escaped_user@localhost connected +# connect as raw_user +ERROR 1045 (28000): Access denied for user 'raw_user'@'localhost' (using password: NO) +# +# old_mode=X509_LENIENT_COMPARE: both grants now match +# +set @old_mode_save= @@global.old_mode; +set global old_mode= concat(@@global.old_mode, ',X509_LENIENT_COMPARE'); +Warnings: +Warning 1287 'X509_LENIENT_COMPARE' is deprecated and will be removed in a future release +# connect as escaped_user +connect_test +escaped_user@localhost connected +# connect as raw_user +connect_test +raw_user@localhost connected +set global old_mode= @old_mode_save; +drop user escaped_user@localhost, raw_user@localhost; diff --git a/mysql-test/main/x509_oneline_separators.test b/mysql-test/main/x509_oneline_separators.test new file mode 100644 index 00000000000..e551ae0af31 --- /dev/null +++ b/mysql-test/main/x509_oneline_separators.test @@ -0,0 +1,54 @@ +# +# MDEV-41008 Parsing of forward slash '/' and plus '+' behaving +# differently between OpenSSL 3 vs OpenSSL 1 vs WolfSSL +# +# Real certificate whose subject has a single RDN, value "a/b+c" (literal +# '/' and '+' inside the value, not separators). A library that escapes +# (OpenSSL >= 3.0) renders this as /CN=a\/b\+c. One that doesn't (WolfSSL, +# OpenSSL < 3.0) renders it raw: /CN=a/b+c. +# + +--source include/have_ssl_communication.inc +--source include/not_embedded.inc + +let $lib_combination= `SELECT IF(@@version_ssl_library LIKE 'WolfSSL%', 'wolfssl', + IF(NATURAL_SORT_KEY(@@version_ssl_library) < NATURAL_SORT_KEY('OpenSSL 3.0.0'), + 'openssl_1', 'openssl_3_or_later'))`; + +if ($MTR_COMBINATIONS != $lib_combination) +{ + skip Needs SSL library '$lib_combination'; +} + +let $MYSQL_CLIENT= $MYSQL --ssl-key=$MYSQL_TEST_DIR/std_data/client-slash-cn-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-slash-cn-cert.pem --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem; + +create user escaped_user@localhost + require subject '/CN=a\\/b\\+c'; + +create user raw_user@localhost + require subject '/CN=a/b+c'; + +--echo # +--echo # Default old_mode: only one grant matches, library-dependent +--echo # +--disable_abort_on_error +--echo # connect as escaped_user +--exec $MYSQL_CLIENT --user=escaped_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1 +--echo # connect as raw_user +--exec $MYSQL_CLIENT --user=raw_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1 +--enable_abort_on_error + +--echo # +--echo # old_mode=X509_LENIENT_COMPARE: both grants now match +--echo # +set @old_mode_save= @@global.old_mode; +set global old_mode= concat(@@global.old_mode, ',X509_LENIENT_COMPARE'); +--disable_abort_on_error +--echo # connect as escaped_user +--exec $MYSQL_CLIENT --user=escaped_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1 +--echo # connect as raw_user +--exec $MYSQL_CLIENT --user=raw_user -e "select concat(current_user(), ' connected') as connect_test" 2>&1 +--enable_abort_on_error +set global old_mode= @old_mode_save; + +drop user escaped_user@localhost, raw_user@localhost; diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 3db3a6f9c13..99612925e93 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -2322,6 +2322,19 @@ sub environment_setup { $ENV{'MYSQLHOTCOPY'}= $mysqlhotcopy; } + # ---------------------------------------------------- + # wsrep_notify (shipped example wsrep_notify_cmd script; tests point + # wsrep_notify_cmd at this instead of keeping a private std_data copy) + # ---------------------------------------------------- + my $wsrep_notify= + mtr_pl_maybe_exists("$bindir/support-files/wsrep_notify") || + mtr_pl_maybe_exists("$bindir/share/mariadb/wsrep_notify") || + mtr_pl_maybe_exists("$bindir/share/mysql/wsrep_notify"); + if ($wsrep_notify) + { + $ENV{'WSREP_NOTIFY_CMD'}= $wsrep_notify; + } + # ---------------------------------------------------- # perror # ---------------------------------------------------- diff --git a/mysql-test/std_data/client-slash-cn-cert.pem b/mysql-test/std_data/client-slash-cn-cert.pem new file mode 100644 index 00000000000..e2541cd4a00 --- /dev/null +++ b/mysql-test/std_data/client-slash-cn-cert.pem @@ -0,0 +1,118 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB + Validity + Not Before: Sep 28 18:02:52 2026 GMT + Not After : Sep 23 18:02:52 2046 GMT + Subject: CN=a\/b\+c + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:86:2d:e1:df:5e:f0:6f:7f:11:95:72:3f:61:4c: + a1:f7:3f:c8:16:cd:37:1a:5b:00:fc:99:fd:2b:68: + f7:d5:87:f9:41:05:8e:97:73:0a:11:c8:6d:bb:f7: + 68:dd:8d:b3:15:8f:db:aa:45:94:d0:b0:ad:55:91: + dd:36:34:a1:f7:e8:e8:69:a1:6e:78:0f:a1:45:06: + 28:cc:5a:1d:bb:06:6f:c5:9b:dd:b5:a2:7a:31:25: + 23:05:bf:91:a0:e3:25:b4:3b:58:df:b5:9d:7d:16: + 11:aa:09:41:38:3d:3b:89:0d:59:b5:1d:4b:4d:25: + 0d:e8:f0:a0:8e:8b:b4:48:bb:8b:25:79:93:6d:31: + 55:7a:be:2d:df:8a:6d:76:ba:56:ce:c2:7a:9f:30: + 30:f8:a5:4b:f5:79:ac:39:8c:50:0e:4f:b0:3d:52: + e3:c9:ff:3e:e1:ee:27:76:1e:a6:74:35:a4:87:05: + ec:44:5b:d9:a7:b0:82:82:14:b9:e1:e9:93:1f:10: + a0:93:67:76:a5:f8:02:79:b5:32:57:3a:7c:bc:1c: + 69:44:ad:a4:6a:d2:0d:fd:40:f9:a2:9d:37:09:eb: + 1d:f0:56:22:16:82:e3:87:6b:fc:68:08:00:88:cb: + 9d:29:7e:9e:c1:15:3d:22:19:0a:7b:fb:8a:67:a6: + 6c:99:a0:95:f6:b8:fc:e3:7a:36:35:ef:63:2a:5c: + 8f:5b:a4:d9:57:ec:9a:ae:a1:8a:2c:0f:16:70:75: + 54:35:99:13:a0:87:e0:af:90:52:67:f2:ee:85:c9: + f0:02:c5:b5:e2:58:93:a8:c8:13:63:a8:f6:8b:9b: + 1a:a5:91:63:bf:b8:ec:65:24:46:bd:93:61:8b:55: + 20:76:5c:e4:22:28:55:3c:0e:f5:f6:c0:29:4c:ba: + 49:46:88:52:bf:78:51:7b:5a:1f:f4:9d:34:cf:c4: + 8d:84:c6:ce:2a:15:0c:97:ad:c4:b9:51:6f:fd:81: + cf:db:c2:c5:5a:8f:21:52:8e:d7:d0:2f:09:41:26: + 2d:53:26:e5:1d:82:f1:e6:0d:7e:51:f8:0f:6a:5c: + 60:91:0d:c0:29:95:5a:dd:b2:dc:f4:ee:34:94:ae: + 6c:07:9f:93:99:5d:9d:6f:34:25:be:05:d5:6c:fd: + 56:c1:3b:2b:d3:41:e2:14:94:28:00:bb:d1:9d:5b: + 70:3a:4e:83:2d:1e:b4:cb:6e:af:64:dc:02:f9:b4: + 4a:4c:e2:f3:f8:be:22:9d:18:9b:ac:fe:fc:d8:0f: + 58:34:ae:0d:0e:ac:f5:6c:c2:fd:b8:3a:a4:3d:5a: + 14:0d:26:8d:55:8f:30:8a:63:3f:e5:6b:58:36:27: + 4e:9e:b1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 93:EC:3D:13:75:A3:A1:3F:E0:01:F0:4C:DF:EE:D5:AA:D7:76:6A:28 + X509v3 Authority Key Identifier: + 4D:FC:7A:19:F3:2B:0C:7D:F6:C0:7C:4D:F8:72:34:4C:8C:35:52:74 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 10:9e:44:ec:2f:81:62:86:42:69:e1:8e:11:3d:bc:ae:79:bf: + d4:04:1c:45:9e:19:71:d0:ed:78:3c:53:ee:0a:8f:b3:af:96: + 24:f5:cc:ac:49:13:73:05:f9:f3:37:bd:bd:06:97:01:2b:6c: + 8e:27:80:b4:c8:fb:47:7c:f2:55:4b:c7:b0:d4:25:fb:35:c0: + 17:ce:ac:4f:71:a7:5c:4f:a8:7f:91:21:2b:cc:d5:cf:99:63: + 3c:b1:bf:c0:98:14:66:12:22:bc:f9:f9:3d:7d:ec:17:65:b5: + f9:04:1d:cb:76:a9:22:15:dd:29:4e:23:e0:94:7f:14:e2:5d: + 5a:97:96:e6:c4:5b:3d:ab:d1:8f:dd:bc:be:96:11:65:6e:1b: + 02:c2:a9:a3:f0:44:bb:37:5d:08:80:99:41:8a:76:60:18:fe: + 46:2d:cc:5d:8d:84:ba:7e:c9:d3:82:21:e8:f9:07:10:ec:0b: + 2d:99:2f:5c:b9:51:e9:2a:bf:ea:db:05:06:6d:e4:2d:41:e7: + 72:bc:1b:16:dd:71:38:50:ed:a4:97:d6:76:b5:23:84:4c:67: + 72:c9:7a:a4:d9:8a:00:ce:1e:3f:db:09:84:80:ba:94:f8:6c: + 16:02:dc:95:8c:bd:ab:bb:00:d0:d8:cb:84:e7:15:aa:81:a3: + 09:70:97:37:52:4c:2d:08:6b:38:aa:ba:e6:eb:67:ea:01:ec: + 77:ca:81:78:b5:95:f6:87:3c:0f:a7:b8:20:ba:fd:df:aa:5e: + c6:0d:39:67:47:93:12:e6:2a:b9:4e:4d:19:b0:bb:dc:5e:5e: + 70:ea:1e:d4:e3:29:ca:2c:3f:e4:c8:ea:a2:3d:e8:a2:82:6b: + 56:dd:d4:e4:19:e2:d4:01:8b:08:13:13:75:4e:af:d1:cf:cf: + 24:b9:9d:a3:b4:8e:86:27:93:07:07:63:fb:4a:c9:c1:9a:10: + 26:51:83:b1:1f:1d:0c:0e:ca:0e:a0:1a:f7:77:73:05:93:eb: + cc:06:8d:66:2b:43:e2:81:6f:03:20:bc:39:5e:ec:09:1e:9d: + ce:8b:e1:26:47:30:63:22:03:80:7e:f2:05:2c:47:c2:fc:da: + c4:c4:fa:81:d8:b8:2c:67:11:4d:1b:7b:0e:65:97:7c:4e:1c: + 64:c9:87:6b:22:65:79:f9:9d:fc:9c:9a:63:a2:08:a8:a2:f9: + 79:bb:94:3c:b1:57:d1:ed:54:a5:82:62:c7:ce:b9:b7:db:d8: + 40:cd:5e:6c:ca:95:ac:5f:af:de:31:bb:6f:08:f4:e1:35:72: + 1b:cf:f5:9a:27:8e:dd:31:37:70:b1:6a:ca:9c:93:26:ab:36: + 85:9a:89:de:1b:53:8e:95 +-----BEGIN CERTIFICATE----- +MIIFLjCCAxagAwIBAgIBATANBgkqhkiG9w0BAQsFADBWMQ8wDQYDVQQDDAZjYWNl +cnQxCzAJBgNVBAYTAkZJMREwDwYDVQQIDAhIZWxzaW5raTERMA8GA1UEBwwISGVs +c2lua2kxEDAOBgNVBAoMB01hcmlhREIwHhcNMjYwOTI4MTgwMjUyWhcNNDYwOTIz +MTgwMjUyWjAQMQ4wDAYDVQQDDAVhL2IrYzCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAIYt4d9e8G9/EZVyP2FMofc/yBbNNxpbAPyZ/Sto99WH+UEFjpdz +ChHIbbv3aN2NsxWP26pFlNCwrVWR3TY0offo6GmhbngPoUUGKMxaHbsGb8Wb3bWi +ejElIwW/kaDjJbQ7WN+1nX0WEaoJQTg9O4kNWbUdS00lDejwoI6LtEi7iyV5k20x +VXq+Ld+KbXa6Vs7Cep8wMPilS/V5rDmMUA5PsD1S48n/PuHuJ3YepnQ1pIcF7ERb +2aewgoIUueHpkx8QoJNndqX4Anm1Mlc6fLwcaUStpGrSDf1A+aKdNwnrHfBWIhaC +44dr/GgIAIjLnSl+nsEVPSIZCnv7imembJmglfa4/ON6NjXvYypcj1uk2Vfsmq6h +iiwPFnB1VDWZE6CH4K+QUmfy7oXJ8ALFteJYk6jIE2Oo9oubGqWRY7+47GUkRr2T +YYtVIHZc5CIoVTwO9fbAKUy6SUaIUr94UXtaH/SdNM/EjYTGzioVDJetxLlRb/2B +z9vCxVqPIVKO19AvCUEmLVMm5R2C8eYNflH4D2pcYJENwCmVWt2y3PTuNJSubAef +k5ldnW80Jb4F1Wz9VsE7K9NB4hSUKAC70Z1bcDpOgy0etMtur2TcAvm0Skzi8/i+ +Ip0Ym6z+/NgPWDSuDQ6s9WzC/bg6pD1aFA0mjVWPMIpjP+VrWDYnTp6xAgMBAAGj +TTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFJPsPRN1o6E/4AHwTN/u1arXdmooMB8G +A1UdIwQYMBaAFE38ehnzKwx99sB8TfhyNEyMNVJ0MA0GCSqGSIb3DQEBCwUAA4IC +AQAQnkTsL4FihkJp4Y4RPbyueb/UBBxFnhlx0O14PFPuCo+zr5Yk9cysSRNzBfnz +N729BpcBK2yOJ4C0yPtHfPJVS8ew1CX7NcAXzqxPcadcT6h/kSErzNXPmWM8sb/A +mBRmEiK8+fk9fewXZbX5BB3LdqkiFd0pTiPglH8U4l1al5bmxFs9q9GP3by+lhFl +bhsCwqmj8ES7N10IgJlBinZgGP5GLcxdjYS6fsnTgiHo+QcQ7AstmS9cuVHpKr/q +2wUGbeQtQedyvBsW3XE4UO2kl9Z2tSOETGdyyXqk2YoAzh4/2wmEgLqU+GwWAtyV +jL2ruwDQ2MuE5xWqgaMJcJc3UkwtCGs4qrrm62fqAex3yoF4tZX2hzwPp7gguv3f +ql7GDTlnR5MS5iq5Tk0ZsLvcXl5w6h7U4ynKLD/kyOqiPeiigmtW3dTkGeLUAYsI +ExN1Tq/Rz88kuZ2jtI6GJ5MHB2P7SsnBmhAmUYOxHx0MDsoOoBr3d3MFk+vMBo1m +K0PigW8DILw5XuwJHp3Oi+EmRzBjIgOAfvIFLEfC/NrExPqB2LgsZxFNG3sOZZd8 +ThxkyYdrImV5+Z38nJpjogioovl5u5Q8sVfR7VSlgmLHzrm329hAzV5sypWsX6/e +MbtvCPThNXIbz/WaJ47dMTdwsWrKnJMmqzaFmoneG1OOlQ== +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-slash-cn-key.pem b/mysql-test/std_data/client-slash-cn-key.pem new file mode 100644 index 00000000000..9399395e784 --- /dev/null +++ b/mysql-test/std_data/client-slash-cn-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCGLeHfXvBvfxGV +cj9hTKH3P8gWzTcaWwD8mf0raPfVh/lBBY6XcwoRyG2792jdjbMVj9uqRZTQsK1V +kd02NKH36OhpoW54D6FFBijMWh27Bm/Fm921onoxJSMFv5Gg4yW0O1jftZ19FhGq +CUE4PTuJDVm1HUtNJQ3o8KCOi7RIu4sleZNtMVV6vi3fim12ulbOwnqfMDD4pUv1 +eaw5jFAOT7A9UuPJ/z7h7id2HqZ0NaSHBexEW9mnsIKCFLnh6ZMfEKCTZ3al+AJ5 +tTJXOny8HGlEraRq0g39QPminTcJ6x3wViIWguOHa/xoCACIy50pfp7BFT0iGQp7 ++4pnpmyZoJX2uPzjejY172MqXI9bpNlX7JquoYosDxZwdVQ1mROgh+CvkFJn8u6F +yfACxbXiWJOoyBNjqPaLmxqlkWO/uOxlJEa9k2GLVSB2XOQiKFU8DvX2wClMuklG +iFK/eFF7Wh/0nTTPxI2Exs4qFQyXrcS5UW/9gc/bwsVajyFSjtfQLwlBJi1TJuUd +gvHmDX5R+A9qXGCRDcAplVrdstz07jSUrmwHn5OZXZ1vNCW+BdVs/VbBOyvTQeIU +lCgAu9GdW3A6ToMtHrTLbq9k3AL5tEpM4vP4viKdGJus/vzYD1g0rg0OrPVswv24 +OqQ9WhQNJo1VjzCKYz/la1g2J06esQIDAQABAoICABap2kxtz0Ot3Uz2SqFHHdZS +xhuf1u5TL7P62InEBZRiDqY+Z4rKKgm95lcI34QIgpaiQVKdxRiItwZMiGY29qKW +iucIls2dqjor46k8kWf9GtTwUj7zLhtt79/xLwpTQ5ORMJ48oVi26Q3k2UjEAvHP +uPa/92+U0igluKDLFQzx7HtMcSvQ2OTOCZaH3ZxftfjfXXHU5HijBtT0E7R2sDDy +ocyB2yrLu5XSsYSggbIAO4V46SLUtss9o5WQJaN0Xd6x4sVzBNXcsaJYCiQ0o0vs +qpUolSxbxXQgzOl8D4dT2K83BTPzMLY3dZ8mttxkM+wF0I/BZB2FyEEPyB1gvVfo +7U6dlcBX66YEcbFheyQ/6Hb86i52sWWWV0URkD3eEJI0frpJZYtV9CgyWJDhwadh +zPgGmXeRmtorh9wmSFVcy3BPcGDOJpRQuPSekM5vRIp3QpjecMXr6zdU0SWA8hhx +c7W9SHNlQZmjMpv5NP+UMC0Se3eFwxNVYCjr3oIif6avU2QATWbp75tuSN6wo9ta +KocaKOyCQX+MqoIJpeij0A6oynN4W1ZWF1IMAje7CeNnZI2sEamF5ZRAJADmUf4l +dkroT1v/OrkphCClBinPZBDs5CXP2yezrTDGOzRgxx7ZOtz+VhclxsqTn/pqYLQ2 +BC3Fz+jU6YXivJn5IDZpAoIBAQC5arwI6iZlI7WPmXtKzmI1Zv4fruKa8/wIGUsv +5/MdohF3z8LqSHlpC2urx5ohnJLziqVJp0u0JimVQ40bkfvhSSOEV4M5eWtg5AfW +z1066PxiETiPAXXFPt7zuxPVcdJkr55jIlgc11hInPmsB2sw2WjH3by50AiZ3Gga +MuIfg9fY5Ej4LqQwPTH+IRW6TirSIV88FZjfahGX4k3PN4rp+BDyE3uy/4F4hopa +o22rQnG7R4apcHV/IW4GgMe6AcogN/B9QQl+ZQW2EPfZ34tuHA7l18+maAWkRFuf +KY+N/uVRM51OIe7/SPVqioJndEnnUYGYe1i09jKhCpimHddVAoIBAQC5Qe1R+V7Q +dK/Z2F+RTt+3p5FIs8x30Vm+ASv1aMHy8LDuHihqm3lGczk8DfJXSHNVn/EhNepl +LSwMSrZ+HFVaHG/2NDV+cw8Hqu8wKuDW69U0frSSCpCIP/i73KlJZ/WQhbaDv8Yq +SNhf4/0P1UWfTXU5Xgh2cOlooq58qzuxyYqf2OAWvkhL8kZumHpZ/2/Ym9takkDa +KrZzKTLKGqLhN9f6WIR1bE+kqqiBNJ1QMAMyDo5+LqOCXZ56IOQOOMNMUsthwkDk +EUZzLKyCsS11576zalXXtCBbN21qya7jHdwyFVjf7bGv0ZGOHnhkiAtW0FcjVoKp +qnnzWmwrmzHtAoIBAHGBJGC0rhJl/MROaYpOsxIL3W8ZyQCgcV2n1j4aWNqAFv9o +QOLYwPIMGrqKsxD2X4MVEb/32MEMR5JnSt9gy3eLJWHjjKJHcPNcRGw8fs8MR0vl +TOFGPIklxqgfkrGsPuaCF4yKPrRRI2s4JSMpW3YI8TrAw8Jf1pQRt+ypz4EJXb4Z +aY38R2h8Xbk7Gaj2JwKBiWInunCx5tk6oPVEBBbcU8tNIAFgpipY+iMoPn+DakoC +LC5XeKX9mfQDK8DzTX/Rnreec6hbQVbGJmPKk/kw1fHf3e75aNK5Qfk6IPYE3u6J +kTd+UGcYi5vP9KpOJtujKplkkNYejLnG2dF/HQ0CggEAbL+Vl0RCcy28OK36U6sw +SnfUIhBhm4hKHO5FJrdK+thtlCoh4YrIoyFqXKV3N+NwyLet7affo2rj64dEHz10 +oQQGeUlmiYbzMLYX2HejKqafrkQerYgEFecvlN/QhCXBkgfb/vTpV9MRKSEFYXD5 +gK0Qfg+D+jsH2QN+V/KQhSng9TpzOQaUG/jpfWyGjiQTPN0o477s0OS321w400jV +ik2ku/GQN/nPusLvTYFcQ0Eb7xt6a/nmw9U+/UQne224vynu98D3JKo7Z8q2rbVi +EU9rs5hdMdUsFT+xPDmOLwZNRx0e4bx/TM1Bm2Kpm6H8vgZo0HatFvnawo625tYg +dQKCAQEAsFeRsBuArUBf8b9h9v3BFgCTGezZfOvgx/QtlVxDnNxYt2cut1cPgBLx +elp2C6SH6cJZiRWPgpYBlZuHbQh+RUwcXg5doTU6DX3x8remjPhA6pc7c3Jqb1lV +x4q5uDvLvHNzAtTGr99+Ci4se40/oKDcEcvJ8ShEptudmT2KWWbfpham3ECotMrs +NSavmBul473FxZrPOM7FLNWyjT/XOcGpsn8n0OgNC+qUSN9CzuC+CLiBuo6AHhrn +kPEo1ng06/7Ropzz0+nLfZ2nDwzeWSVVBKbsgfUABwOorMIj90nGYKhwAAz8p8uk +rNrrA26be3EZ5z7Pb/9PVMLQLJbKew== +-----END PRIVATE KEY----- diff --git a/mysql-test/std_data/ldml/Index.xml b/mysql-test/std_data/ldml/Index.xml index 6e833610ab2..634659008c3 100644 --- a/mysql-test/std_data/ldml/Index.xml +++ b/mysql-test/std_data/ldml/Index.xml @@ -386,6 +386,7 @@ + diff --git a/mysql-test/std_data/ldml/latin1.xml b/mysql-test/std_data/ldml/latin1.xml index 47733a570ad..594c66ec363 100644 --- a/mysql-test/std_data/ldml/latin1.xml +++ b/mysql-test/std_data/ldml/latin1.xml @@ -175,6 +175,57 @@ + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 5B 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + + diff --git a/mysql-test/std_data/mdev-4645-binlog_checksum.binlog b/mysql-test/std_data/mdev-4645-binlog_checksum.binlog deleted file mode 100644 index 861e9b4fd67..00000000000 Binary files a/mysql-test/std_data/mdev-4645-binlog_checksum.binlog and /dev/null differ diff --git a/mysql-test/std_data/mdev-4645-binlog_group_id.binlog b/mysql-test/std_data/mdev-4645-binlog_group_id.binlog deleted file mode 100644 index a9a6722bea2..00000000000 Binary files a/mysql-test/std_data/mdev-4645-binlog_group_id.binlog and /dev/null differ diff --git a/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog b/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog deleted file mode 100644 index a936ffb139a..00000000000 Binary files a/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog and /dev/null differ diff --git a/mysql-test/std_data/wsrep_notify.sh b/mysql-test/std_data/wsrep_notify.sh deleted file mode 100755 index 19da0dfc378..00000000000 --- a/mysql-test/std_data/wsrep_notify.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/bin/sh -eu - -# This is a simple example of wsrep notification script (wsrep_notify_cmd). -# It will create 'wsrep' schema and two tables in it: 'membership' and 'status' -# and fill them on every membership or node status change. -# -# Edit parameters below to specify the address and login to server: -# -USER='root' -PSWD='' -# -# If these parameters are not set, then the values -# passed by the server are taken: -# -HOST="127.0.0.1" -PORT=$NODE_MYPORT_1 -# -# Edit parameters below to specify SSL parameters: -# -ssl_cert="" -ssl_key="" -ssl_ca="" -ssl_capath="" -ssl_cipher="" -ssl_crl="" -ssl_crlpath="" -ssl_verify_server_cert=0 -# -# Client executable path: -# -CLIENT="$EXE_MYSQL" -# -# Name of schema and tables: -# -SCHEMA="mtr_wsrep_notify" -MEMB_TABLE="$SCHEMA.membership" -STATUS_TABLE="$SCHEMA.status" - -WSREP_ON='SET wsrep_on=ON' -WSREP_OFF='SET wsrep_on=OFF' - -BEGIN="$WSREP_OFF; -CREATE SCHEMA IF NOT EXISTS $SCHEMA; -CREATE TABLE IF NOT EXISTS $MEMB_TABLE ( - idx INT, - uuid CHAR(40), /* node UUID */ - name VARCHAR(32), /* node name */ - addr VARCHAR(256) /* node address */ -) ENGINE=MEMORY; -CREATE TABLE IF NOT EXISTS $STATUS_TABLE ( - size INT, /* component size */ - idx INT, /* this node index */ - status CHAR(16), /* this node status */ - uuid CHAR(40), /* cluster UUID */ - prim BOOLEAN /* if component is primary */ -) ENGINE=MEMORY; -BEGIN" -END="COMMIT; $WSREP_ON" - -configuration_change() -{ - echo "$BEGIN;" - - local idx=0 - - for NODE in $(echo "$MEMBERS" | sed s/,/\ /g) - do - echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " - # Don't forget to properly quote string values - echo "'$NODE'" | sed s/\\//\',\'/g - echo ");" - idx=$(( $idx+1 )) - done - - echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" - - echo "$END;" -} - -status_update() -{ - echo "$BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;" -} - -trim_string() -{ - if [ -n "${BASH_VERSION:-}" ]; then - local pattern="[![:space:]${2:-}]" - local x="${1#*$pattern}" - local z=${#1} - x=${#x} - if [ $x -ne $z ]; then - local y="${1%$pattern*}" - y=${#y} - x=$(( z-x-1 )) - y=$(( y-x+1 )) - printf '%s' "${1:$x:$y}" - else - printf '' - fi - else - local pattern="[[:space:]${2:-}]" - echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g" - fi -} - -COM='status_update' # not a configuration change by default - -STATUS="" -CLUSTER_UUID="" -PRIMARY=0 -INDEX="" -MEMBERS="" - -while [ $# -gt 0 ]; do - case $1 in - '--status') - STATUS=$(trim_string "$2") - shift - ;; - '--uuid') - CLUSTER_UUID=$(trim_string "$2") - shift - ;; - '--primary') - arg=$(trim_string "$2") - [ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0 - COM='configuration_change' - shift - ;; - '--index') - INDEX=$(trim_string "$2") - shift - ;; - '--members') - MEMBERS=$(trim_string "$2") - shift - ;; - esac - shift -done - -USER=$(trim_string "$USER") -PSWD=$(trim_string "$PSWD") - -HOST=$(trim_string "$HOST") -PORT=$(trim_string "$PORT") - -case "$HOST" in -\[*) - HOST="${HOST##\[}" - HOST=$(trim_string "${HOST%%\]}") - ;; -esac - -if [ -z "$HOST" ]; then - HOST="${NOTIFY_HOST:-}" -fi -if [ -z "$PORT" ]; then - PORT="${NOTIFY_PORT:-}" -fi - -ssl_key=$(trim_string "$ssl_key"); -ssl_cert=$(trim_string "$ssl_cert"); -ssl_ca=$(trim_string "$ssl_ca"); -ssl_capath=$(trim_string "$ssl_capath"); -ssl_cipher=$(trim_string "$ssl_cipher"); -ssl_crl=$(trim_string "$ssl_crl"); -ssl_crlpath=$(trim_string "$ssl_crlpath"); -ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); - -SSL_PARAM="" - -if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] -then - SSL_PARAM=' --ssl' - [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" - [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'" - [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'" - [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'" - [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'" - [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" - [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" - if [ -n "$ssl_verify_server_cert" ]; then - if [ "$ssl_verify_server_cert" != "0" -o \ - "$ssl_verify_server_cert" = "on" ] - then - SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" - fi - fi -fi - -case "$STATUS" in - 'joined' | 'donor' | 'synced') - "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\ - "-h'$HOST'" "-P$PORT"$SSL_PARAM - ;; - *) - # The node might be shutting down or not initialized - ;; -esac - -exit 0 diff --git a/mysql-test/std_data/wsrep_notify_argv_recorder.sh b/mysql-test/std_data/wsrep_notify_argv_recorder.sh new file mode 100755 index 00000000000..df7507d5609 --- /dev/null +++ b/mysql-test/std_data/wsrep_notify_argv_recorder.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# Fake mysql client for the galera_wsrep_notify_pwd_injection test. +# Records argv and MYSQL_PWD instead of connecting anywhere, and drops +# the SQL the wsrep_notify script pipes into stdin. + +: > "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.argv" +for arg in "$@"; do + printf '%s\n' "$arg" >> "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.argv" +done +printf 'MYSQL_PWD=%s\n' "${MYSQL_PWD-}" > "$MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.env" +cat >/dev/null +exit 0 diff --git a/mysql-test/std_data/wsrep_notify_ssl.sh b/mysql-test/std_data/wsrep_notify_ssl.sh deleted file mode 100755 index 5a1b2f68473..00000000000 --- a/mysql-test/std_data/wsrep_notify_ssl.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/sh -eu - -# This is a simple example of wsrep notification script (wsrep_notify_cmd). -# It will create 'wsrep' schema and two tables in it: 'membership' and 'status' -# and fill them on every membership or node status change. -# -# Edit parameters below to specify the address and login to server: -# -USER='root' -PSWD='' -# -# If these parameters are not set, then the values -# passed by the server are taken: -# -HOST="::1" -PORT=$NODE_MYPORT_1 -# -# Edit parameters below to specify SSL parameters: -# -ssl_cert="$MYSQL_TEST_DIR/std_data/client-cert.pem" -ssl_key="$MYSQL_TEST_DIR/std_data/client-key.pem" -ssl_ca="$MYSQL_TEST_DIR/std_data/cacert.pem" -ssl_capath="" -ssl_cipher="" -ssl_crl="" -ssl_crlpath="" -ssl_verify_server_cert=0 -# -# Client executable path: -# -CLIENT="$EXE_MYSQL" -# -# Name of schema and tables: -# -SCHEMA="mtr_wsrep_notify" -MEMB_TABLE="$SCHEMA.membership" -STATUS_TABLE="$SCHEMA.status" - -WSREP_ON='SET wsrep_on=ON' -WSREP_OFF='SET wsrep_on=OFF' - -BEGIN="$WSREP_OFF; -CREATE SCHEMA IF NOT EXISTS $SCHEMA; -CREATE TABLE IF NOT EXISTS $MEMB_TABLE ( - idx INT, - uuid CHAR(40), /* node UUID */ - name VARCHAR(32), /* node name */ - addr VARCHAR(256) /* node address */ -) ENGINE=MEMORY; -CREATE TABLE IF NOT EXISTS $STATUS_TABLE ( - size INT, /* component size */ - idx INT, /* this node index */ - status CHAR(16), /* this node status */ - uuid CHAR(40), /* cluster UUID */ - prim BOOLEAN /* if component is primary */ -) ENGINE=MEMORY; -BEGIN" -END="COMMIT; $WSREP_ON" - -configuration_change() -{ - echo "$BEGIN;" - - local idx=0 - - for NODE in $(echo "$MEMBERS" | sed s/,/\ /g) - do - echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " - # Don't forget to properly quote string values - echo "'$NODE'" | sed s/\\//\',\'/g - echo ");" - idx=$(( $idx+1 )) - done - - echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" - - echo "$END;" -} - -status_update() -{ - echo "$BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;" -} - -trim_string() -{ - if [ -n "${BASH_VERSION:-}" ]; then - local pattern="[![:space:]${2:-}]" - local x="${1#*$pattern}" - local z=${#1} - x=${#x} - if [ $x -ne $z ]; then - local y="${1%$pattern*}" - y=${#y} - x=$(( z-x-1 )) - y=$(( y-x+1 )) - printf '%s' "${1:$x:$y}" - else - printf '' - fi - else - local pattern="[[:space:]${2:-}]" - echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g" - fi -} - -COM='status_update' # not a configuration change by default - -STATUS="" -CLUSTER_UUID="" -PRIMARY=0 -INDEX="" -MEMBERS="" - -while [ $# -gt 0 ]; do - case $1 in - '--status') - STATUS=$(trim_string "$2") - shift - ;; - '--uuid') - CLUSTER_UUID=$(trim_string "$2") - shift - ;; - '--primary') - arg=$(trim_string "$2") - [ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0 - COM='configuration_change' - shift - ;; - '--index') - INDEX=$(trim_string "$2") - shift - ;; - '--members') - MEMBERS=$(trim_string "$2") - shift - ;; - esac - shift -done - -USER=$(trim_string "$USER") -PSWD=$(trim_string "$PSWD") - -HOST=$(trim_string "$HOST") -PORT=$(trim_string "$PORT") - -case "$HOST" in -\[*) - HOST="${HOST##\[}" - HOST=$(trim_string "${HOST%%\]}") - ;; -esac - -if [ -z "$HOST" ]; then - HOST="${NOTIFY_HOST:-}" -fi -if [ -z "$PORT" ]; then - PORT="${NOTIFY_PORT:-}" -fi - -ssl_key=$(trim_string "$ssl_key"); -ssl_cert=$(trim_string "$ssl_cert"); -ssl_ca=$(trim_string "$ssl_ca"); -ssl_capath=$(trim_string "$ssl_capath"); -ssl_cipher=$(trim_string "$ssl_cipher"); -ssl_crl=$(trim_string "$ssl_crl"); -ssl_crlpath=$(trim_string "$ssl_crlpath"); -ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); - -SSL_PARAM="" - -if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] -then - SSL_PARAM=' --ssl' - [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" - [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'" - [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'" - [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'" - [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'" - [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" - [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" - if [ -n "$ssl_verify_server_cert" ]; then - if [ "$ssl_verify_server_cert" != "0" -o \ - "$ssl_verify_server_cert" = "on" ] - then - SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" - else - SSL_PARAM="$SSL_PARAM --disable-ssl-verify-server-cert" - fi - fi -fi - -case "$STATUS" in - 'joined' | 'donor' | 'synced') - "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\ - "-h'$HOST'" "-P$PORT"$SSL_PARAM - ;; - *) - # The node might be shutting down or not initialized - ;; -esac - -exit 0 diff --git a/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result index 71eecd881ca..8adeb4827ce 100644 --- a/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result +++ b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result @@ -3,4 +3,11 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb; # Set gtid_slave_pos should not hang SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos; COMMIT; +### MDEV-22848: SET GLOBAL gtid_slave_pos leaves dangling partial transaction +CREATE TABLE t1 (c INT) ENGINE=MyISAM; +SET GLOBAL gtid_slave_pos="0-1-100"; +INSERT INTO t1 VALUES (0); +DROP TABLE not_there; +ERROR 42S02: Unknown table 'test.not_there' +DROP TABLE t1; RESET MASTER; diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result index 0d90fde0094..e5577e87faf 100644 --- a/mysql-test/suite/binlog/r/binlog_base64_flag.result +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("BINLOG_BASE64_EVENT: According to the master's version"); +call mtr.add_suppression("BINLOG_BASE64_EVENT: Master's version is earlier than"); call mtr.add_suppression("BINLOG_BASE64_EVENT: Column 1 of table 'test.char128_utf8' cannot be converted"); CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1), (1); @@ -39,21 +39,6 @@ a SELECT @binlog_fragment_0, @binlog_fragment_1 as 'NULL','NULL'; @binlog_fragment_0 NULL NULL NULL NULL NULL -==== Test non-matching FD event and Row event ==== -BINLOG ' -4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAADgJ1hHEzgNAAgAEgAEBAQEEgAATwAEGggICAg= -'; -BINLOG ' -Dl1YRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= -Dl1YRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+BQAAAA== -'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use -select * from t1; -a -1 -1 -3 CREATE TABLE char128_utf8 ( i1 INT NOT NULL, c CHAR(128) CHARACTER SET utf8 NOT NULL, diff --git a/mysql-test/suite/binlog/r/binlog_purge_stale_refusal_cache.result b/mysql-test/suite/binlog/r/binlog_purge_stale_refusal_cache.result new file mode 100644 index 00000000000..9b864e634bb --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_purge_stale_refusal_cache.result @@ -0,0 +1,72 @@ +SET @@global.binlog_expire_logs_seconds= 0; +SET @@global.max_binlog_total_size= 0; +SET @@global.slave_connections_needed_for_purge= 1; +SELECT @@global.slave_connections_needed_for_purge; +@@global.slave_connections_needed_for_purge +1 +SELECT @@global.binlog_expire_logs_seconds, @@global.max_binlog_total_size; +@@global.binlog_expire_logs_seconds @@global.max_binlog_total_size +0 0 +# No replica has ever connected: +SELECT COUNT(*) AS dump_threads FROM information_schema.PROCESSLIST +WHERE COMMAND = 'Binlog Dump'; +dump_threads +0 +RESET MASTER; +# +# Part 1 (control). Nothing has attempted a purge yet, so no refusal is +# cached, and the interactive purge correctly ignores the slave's guard. +# +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # +master-bin.000004 # +PURGE BINARY LOGS TO 'master-bin.000003'; +SHOW WARNINGS; +Level Code Message +show binary logs; +Log_name File_size +master-bin.000003 # +master-bin.000004 # +# +# Part 2. Let one automatic purge be refused, then try PURGE that must +# be effective on the fixed server. +# +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +show binary logs; +Log_name File_size +master-bin.000003 # +master-bin.000004 # +master-bin.000005 # +master-bin.000006 # +master-bin.000007 # +# Let the files age past binlog_expire_logs_seconds: purge_logs_before_date +# skips can_purge_log() for any file whose mtime is not older than that. +SET @@global.binlog_expire_logs_seconds= 1; +# Rotating attempts an automatic purge, which the guard refuses. That +# refusal is what populates the cache. +FLUSH BINARY LOGS; +# The automatic refusal states the correct reason in the error log: +FOUND 1 /Binary log .master-bin.000003. is not purged because less than .slave_connections_needed_for_purge. slaves have processed it/ in mysqld.1.err +# Now the interactive purge. It should behave exactly as in part 1. +PURGE BINARY LOGS TO 'master-bin.000006'; +# On affected versions this reports master-bin.000003 as the current active +# binlog, while master-bin.000008 is active: +SHOW WARNINGS; +Level Code Message +show binary logs; +Log_name File_size +master-bin.000006 # +master-bin.000007 # +master-bin.000008 # +SET @@global.binlog_expire_logs_seconds = $save_binlog_expire_logs_seconds; +SET @@global.max_binlog_total_size= $save_max_binlog_total_size; +SET @@global.slave_connections_needed_for_purge= $save_slave_connections_needed_for_purge; +RESET MASTER; diff --git a/mysql-test/suite/binlog/std_data/invalid_row_v2_tag.001 b/mysql-test/suite/binlog/std_data/invalid_row_v2_tag.001 deleted file mode 100644 index 4b558372ea5..00000000000 Binary files a/mysql-test/suite/binlog/std_data/invalid_row_v2_tag.001 and /dev/null differ diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test index 0038a6e2bf7..2c1945f84f5 100644 --- a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test +++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test @@ -37,6 +37,15 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb; SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos; COMMIT; +--echo ### MDEV-22848: SET GLOBAL gtid_slave_pos leaves dangling partial transaction +CREATE TABLE t1 (c INT) ENGINE=MyISAM; +SET GLOBAL gtid_slave_pos="0-1-100"; +INSERT INTO t1 VALUES (0); +--error ER_BAD_TABLE_ERROR +DROP TABLE not_there; +DROP TABLE t1; + + # Revert table type --disable_query_log --eval ALTER TABLE mysql.gtid_slave_pos ENGINE=$old_slave_pos_engine diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test index 46d6c4950e7..c3b22cb529b 100644 --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -6,7 +6,7 @@ # BINLOG statement does not work in embedded mode. source include/not_embedded.inc; -call mtr.add_suppression("BINLOG_BASE64_EVENT: According to the master's version"); +call mtr.add_suppression("BINLOG_BASE64_EVENT: Master's version is earlier than"); call mtr.add_suppression("BINLOG_BASE64_EVENT: Column 1 of table 'test.char128_utf8' cannot be converted"); CREATE TABLE t1 (a int); @@ -62,31 +62,6 @@ select * from t1; # show "one-shot" feature of binlog_fragment variables SELECT @binlog_fragment_0, @binlog_fragment_1 as 'NULL','NULL'; -# Test that the following fails cleanly: "First, read a -# Format_description event which has N event types. Then, read an -# event of type M>N" ---echo ==== Test non-matching FD event and Row event ==== - -# This is the Format_description_log_event from -# bug32407.001, encoded in base64. It contains only the old -# row events (number of event types is 22) -BINLOG ' -4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAADgJ1hHEzgNAAgAEgAEBAQEEgAATwAEGggICAg= -'; - -# The following is a Write_rows_log_event with event type 23, i.e., -# not supported by the Format_description_log_event above. It -# corresponds to the following query: -# INSERT INTO t1 VALUES (5) -error 1149; -BINLOG ' -Dl1YRxMBAAAAKQAAADQBAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE= -Dl1YRxcBAAAAIgAAAFYBAAAQABAAAAAAAAEAAf/+BQAAAA== -'; -# the above line should fail and 5 should not be in the binlog. -select * from t1; - # Test that BUG#37426 is triggered. CREATE TABLE char128_utf8 ( diff --git a/mysql-test/suite/binlog/t/binlog_purge_stale_refusal_cache.test b/mysql-test/suite/binlog/t/binlog_purge_stale_refusal_cache.test new file mode 100644 index 00000000000..755ee265853 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_purge_stale_refusal_cache.test @@ -0,0 +1,90 @@ +# MDEV-41214 PURGE BINARY LOGS does not delete non-active binlog files +# +# PURGE BINARY LOGS could end with a warning instead of deleting files, as +# this test shows when run on the base of the fix. The warning names a wrong +# reason. It follows an automatic purge that was refused by the slave guard, +# slave_connections_needed_for_purge: the automatic purge does not delete a +# binlog while it might still be needed by a slave, not necessarily a +# connected one, that is while fewer than the variable's number of slaves +# are connected. +# +# Part 1 is a control: the same statement shape, with nothing cached, succeeds. +# +# The test sets slave_connections_needed_for_purge=1, +# binlog_expire_logs_seconds=0 and max_binlog_total_size=0, and restores the +# old values at the end. With slave_connections_needed_for_purge=0 the guard +# is off and the bug does not show. +# +--source include/have_binlog_format_mixed.inc + +--let $save_slave_connections_needed_for_purge= `SELECT @@global.slave_connections_needed_for_purge` +--let $save_binlog_expire_logs_seconds= `SELECT @@global.binlog_expire_logs_seconds` +--let $save_max_binlog_total_size= `SELECT @@global.max_binlog_total_size` +SET @@global.binlog_expire_logs_seconds= 0; +SET @@global.max_binlog_total_size= 0; +SET @@global.slave_connections_needed_for_purge= 1; +SELECT @@global.slave_connections_needed_for_purge; +SELECT @@global.binlog_expire_logs_seconds, @@global.max_binlog_total_size; +--echo # No replica has ever connected: +SELECT COUNT(*) AS dump_threads FROM information_schema.PROCESSLIST + WHERE COMMAND = 'Binlog Dump'; + +RESET MASTER; +--echo # +--echo # Part 1 (control). Nothing has attempted a purge yet, so no refusal is +--echo # cached, and the interactive purge correctly ignores the slave's guard. +--echo # +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +--source include/show_binary_logs.inc +PURGE BINARY LOGS TO 'master-bin.000003'; +SHOW WARNINGS; +--source include/show_binary_logs.inc + +--let $first= query_get_value(SHOW BINARY LOGS, Log_name, 1) +if ($first != master-bin.000003) +{ + --echo # Control failed: expected master-bin.000003 first, got $first + --die Interactive purge did not work even with no cached refusal +} + +--echo # +--echo # Part 2. Let one automatic purge be refused, then try PURGE that must +--echo # be effective on the fixed server. +--echo # +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +FLUSH BINARY LOGS; +--source include/show_binary_logs.inc + +--echo # Let the files age past binlog_expire_logs_seconds: purge_logs_before_date +--echo # skips can_purge_log() for any file whose mtime is not older than that. +--real_sleep 2 +SET @@global.binlog_expire_logs_seconds= 1; +--echo # Rotating attempts an automatic purge, which the guard refuses. That +--echo # refusal is what populates the cache. +FLUSH BINARY LOGS; + +--let $first= query_get_value(SHOW BINARY LOGS, Log_name, 1) +if ($first != master-bin.000003) +{ + --echo # Setup failed: expected the automatic purge to delete nothing. + --die The automatic purge was not refused, so nothing was cached +} +--echo # The automatic refusal states the correct reason in the error log: +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN= Binary log .master-bin.000003. is not purged because less than .slave_connections_needed_for_purge. slaves have processed it +--source include/search_pattern_in_file.inc + +--echo # Now the interactive purge. It should behave exactly as in part 1. +PURGE BINARY LOGS TO 'master-bin.000006'; +--echo # On affected versions this reports master-bin.000003 as the current active +--echo # binlog, while master-bin.000008 is active: +SHOW WARNINGS; +--source include/show_binary_logs.inc + +--evalp SET @@global.binlog_expire_logs_seconds = $save_binlog_expire_logs_seconds +--evalp SET @@global.max_binlog_total_size= $save_max_binlog_total_size +--evalp SET @@global.slave_connections_needed_for_purge= $save_slave_connections_needed_for_purge +RESET MASTER; diff --git a/mysql-test/suite/binlog_encryption/rpl_packet.result b/mysql-test/suite/binlog_encryption/rpl_packet.result index 3f62e585ad5..f7dc64a86ab 100644 --- a/mysql-test/suite/binlog_encryption/rpl_packet.result +++ b/mysql-test/suite/binlog_encryption/rpl_packet.result @@ -45,7 +45,7 @@ connection master; CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; connection slave; connection master; -INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2560'); connection slave; include/wait_for_slave_io_error.inc [errno=1153] Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index bd125108fee..9d5ef30ec61 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -3545,6 +3545,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; 1 row_number() over (order by 1) +1 1 drop table t1; explain SELECT DISTINCT BIT_OR(100) OVER () FROM dual @@ -4881,6 +4882,30 @@ DROP TABLE t1; # End of 10.11 tests # # +# MDEV-41146: WHERE is not checked when every table is const and +# the query needs a temporary table +# +create table t1 (a int primary key); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (1),(10); +# rand() < 0 is never true, so the result is empty. +select a, row_number() over () from t1 where a=1 and rand() < 0; +a row_number() over () +select a, row_number() over () from t1 where a=1 and rand() >= 0; +a row_number() over () +1 1 +# t2.b > 5 is true only for the row where t2.b is 10. +select b, (select row_number() over () from t1 where t1.a=1 and t2.b > 5) x +from t2; +b x +1 NULL +10 1 +drop table t1, t2; +# +# End of 11.4 tests +# +# # MDEV-23867: select crash in compute_window_func # set @save_sort_buffer_size=@@sort_buffer_size; diff --git a/mysql-test/suite/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test index e440e3d3344..d4a3d78a944 100644 --- a/mysql-test/suite/encryption/t/innochecksum.test +++ b/mysql-test/suite/encryption/t/innochecksum.test @@ -300,6 +300,16 @@ if (0 && $have_debug) { # these messages sometimes fail to appear --source include/start_mysqld.inc +# The check of pages_old needs old pages in the buffer pool LRU list. +# They exist only when the list holds at least BUF_LRU_OLD_MIN_LEN pages. +# Without the asynchronous load of the buffer pool dump, the list can be +# shorter than that. +let $wait_condition = + SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) load completed at ' + FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_load_status'; +--source include/wait_condition.inc + --echo # Trigger AHI and test pages_hashed, pages_old as non zero from sys view SELECT STRAIGHT_JOIN COUNT(t6a.a) diff --git a/mysql-test/suite/galera/include/kill_galera.inc b/mysql-test/suite/galera/include/kill_galera.inc deleted file mode 100644 index 3c218a19bee..00000000000 --- a/mysql-test/suite/galera/include/kill_galera.inc +++ /dev/null @@ -1,27 +0,0 @@ ---echo Killing server ... - -if (!$kill_signal) -{ ---let $kill_signal = KILL -} - -# Write file to make mysql-test-run.pl expect the crash, but don't start it ---let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` ---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---write_line wait $_expect_file_name - -# Kill the connected server ---disable_reconnect ---let KILL_SIGNAL_VALUE = $kill_signal ---let KILL_NODE_PIDFILE = `SELECT @@pid_file` - ---perl - my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'}; - my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; - my $mysqld_pid = `cat $pid_filename`; - chomp($mysqld_pid); - system("kill -s $kill_sig $mysqld_pid"); - exit(0); -EOF - ---source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/galera/include/wait_condition_with_debug_and_kill.inc b/mysql-test/suite/galera/include/wait_condition_with_debug_and_kill.inc index 184f75eb57c..5c1fdbfd660 100644 --- a/mysql-test/suite/galera/include/wait_condition_with_debug_and_kill.inc +++ b/mysql-test/suite/galera/include/wait_condition_with_debug_and_kill.inc @@ -4,7 +4,13 @@ # # Waits until the passed statement returns true, or the operation # times out. If the operation times out, the additional error -# statement will be executed and server is killed. +# statement will be executed, the server is killed to leave a core +# for post-mortem analysis, and the test is aborted. +# +# The abort is essential: the node is gone once we return, so any +# statement the caller would execute next runs against a dead server +# and fails in an unrelated and non-deterministic way, hiding the +# timeout that actually caused the failure. # # USAGE # @@ -32,4 +38,5 @@ if (!$success) { --source include/kill_galera.inc + --die Timeout in wait_condition_with_debug_and_kill.inc for $wait_condition } diff --git a/mysql-test/suite/galera/r/MDEV-38920-evs-config-warn.result b/mysql-test/suite/galera/r/MDEV-38920-evs-config-warn.result new file mode 100644 index 00000000000..df5c1be9dfa --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-38920-evs-config-warn.result @@ -0,0 +1,4 @@ +connection node_2; +connection node_1; +include/assert_grep.inc [provider must warn that evs.install_timeout is below evs.suspect_timeout] +include/assert_grep.inc [provider must warn that evs.inactive_check_period exceeds evs.keepalive_period] diff --git a/mysql-test/suite/galera/r/MDEV-38920-install-timer-expired.result b/mysql-test/suite/galera/r/MDEV-38920-install-timer-expired.result new file mode 100644 index 00000000000..427d2f87f7c --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-38920-install-timer-expired.result @@ -0,0 +1,22 @@ +connection node_4; +connection node_3; +connection node_2; +connection node_1; +connection node_4; +connection node_3; +connection node_2; +connection node_1; +connection node_4; +SET SESSION wsrep_sync_wait = 0; +connection node_3; +SET SESSION wsrep_sync_wait = 0; +connection node_2; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET SESSION wsrep_sync_wait = 0; +include/assert_grep.inc [node_4 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)] +include/assert_grep.inc [node_3 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)] +include/assert_grep.inc [node_2 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)] +include/assert_grep.inc [node_1 did not time out the EVS view-install protocol (no NON_PRIM on single-node failure)] diff --git a/mysql-test/suite/galera/r/MDEV-41012-collision.result b/mysql-test/suite/galera/r/MDEV-41012-collision.result new file mode 100644 index 00000000000..dc3af178d72 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-41012-collision.result @@ -0,0 +1,115 @@ +connection node_2; +connection node_1; +# +# Each pair below is two distinct values whose bytes fold to the same +# latin1_swedish_ci weight string (0xC0->0x41, 0x6A->0x4A, 0x6B->0x4B, +# 0xD2->0x4F, 0x7A->0x5A). A UUID is stored as a byte permutation of the +# value shown, which does not affect a byte-wise folding. +# +SELECT WEIGHT_STRING(_latin1 0xC0A8016B9E4D4F7AB3D26A1E8F9C0D1B) = +WEIGHT_STRING(_latin1 0x41A8014B9E4D4F5AB34F4A1E8F9C0D1B) AS uuid_pair_collides, +WEIGHT_STRING(_latin1 0x20010DB80000000000000000C0A8016B) = +WEIGHT_STRING(_latin1 0x20010DB8000000000000000041A8014B) AS inet6_pair_collides, +WEIGHT_STRING(_latin1 0xC0A8016B) = +WEIGHT_STRING(_latin1 0x41A8014B) AS inet4_pair_collides; +uuid_pair_collides inet6_pair_collides inet4_pair_collides +1 1 1 +# +# UUID +# +connection node_1; +CREATE TABLE t (id UUID PRIMARY KEY, v INT) ENGINE=InnoDB; +INSERT INTO t VALUES ('c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b', 0), ('41a8014b-9e4d-4f5a-b34f-4a1e8f9c0d1b', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +UPDATE t SET v = 1 WHERE id = 'c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b'; +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE t SET v = 2 WHERE id = '41a8014b-9e4d-4f5a-b34f-4a1e8f9c0d1b'; +connection node_2; +no_false_dependency +1 +SELECT COUNT(*) = 1 AS second_row_applied_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +second_row_applied_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT id, v FROM t ORDER BY v; +id v +c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b 1 +41a8014b-9e4d-4f5a-b34f-4a1e8f9c0d1b 2 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE t; +# +# INET6 +# +connection node_1; +CREATE TABLE t (id INET6 PRIMARY KEY, v INT) ENGINE=InnoDB; +INSERT INTO t VALUES ('2001:db8::c0a8:16b', 0), ('2001:db8::41a8:14b', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +UPDATE t SET v = 1 WHERE id = '2001:db8::c0a8:16b'; +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE t SET v = 2 WHERE id = '2001:db8::41a8:14b'; +connection node_2; +no_false_dependency +1 +SELECT COUNT(*) = 1 AS second_row_applied_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +second_row_applied_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT id, v FROM t ORDER BY v; +id v +2001:db8::c0a8:16b 1 +2001:db8::41a8:14b 2 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE t; +# +# INET4 +# +connection node_1; +CREATE TABLE t (id INET4 PRIMARY KEY, v INT) ENGINE=InnoDB; +INSERT INTO t VALUES ('192.168.1.107', 0), ('65.168.1.75', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +UPDATE t SET v = 1 WHERE id = '192.168.1.107'; +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE t SET v = 2 WHERE id = '65.168.1.75'; +connection node_2; +no_false_dependency +1 +SELECT COUNT(*) = 1 AS second_row_applied_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +second_row_applied_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT id, v FROM t ORDER BY v; +id v +192.168.1.107 1 +65.168.1.75 2 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE t; diff --git a/mysql-test/suite/galera/r/MDEV-41012.result b/mysql-test/suite/galera/r/MDEV-41012.result new file mode 100644 index 00000000000..8f1b258f64a --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-41012.result @@ -0,0 +1,104 @@ +connection node_2; +connection node_1; +# +# UUID +# +connection node_1; +CREATE TABLE p (id UUID PRIMARY KEY, v INT) ENGINE=InnoDB; +CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, p_id UUID NOT NULL, KEY k (p_id), FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB; +INSERT INTO p VALUES ('c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +INSERT INTO c (p_id) VALUES ('c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b'); +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p SET v = v + 1 WHERE id = 'c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b'; +connection node_2; +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +no_row_modified_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT v FROM p; +v +1 +SELECT COUNT(*) FROM c; +COUNT(*) +1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE c, p; +# +# INET6 +# +connection node_1; +CREATE TABLE p (id INET6 PRIMARY KEY, v INT) ENGINE=InnoDB; +CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, p_id INET6 NOT NULL, KEY k (p_id), FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB; +INSERT INTO p VALUES ('2001:db8::c0a8:16b', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +INSERT INTO c (p_id) VALUES ('2001:db8::c0a8:16b'); +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p SET v = v + 1 WHERE id = '2001:db8::c0a8:16b'; +connection node_2; +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +no_row_modified_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT v FROM p; +v +1 +SELECT COUNT(*) FROM c; +COUNT(*) +1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE c, p; +# +# INET4 +# +connection node_1; +CREATE TABLE p (id INET4 PRIMARY KEY, v INT) ENGINE=InnoDB; +CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, p_id INET4 NOT NULL, KEY k (p_id), FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB; +INSERT INTO p VALUES ('192.168.1.107', 0); +connection node_2; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +INSERT INTO c (p_id) VALUES ('192.168.1.107'); +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p SET v = v + 1 WHERE id = '192.168.1.107'; +connection node_2; +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +no_row_modified_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT v FROM p; +v +1 +SELECT COUNT(*) FROM c; +COUNT(*) +1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE c, p; diff --git a/mysql-test/suite/galera/r/MW-292.result b/mysql-test/suite/galera/r/MW-292.result index 81e5a316b63..54374b87128 100644 --- a/mysql-test/suite/galera/r/MW-292.result +++ b/mysql-test/suite/galera/r/MW-292.result @@ -24,13 +24,9 @@ SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync'; connection node_1; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'dbug=d,abort_trx_end'; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'signal=abort_trx_end'; SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync'; diff --git a/mysql-test/suite/galera/r/galera_change_user.result b/mysql-test/suite/galera/r/galera_change_user.result index 55f3bb76910..cd0e27bb2d7 100644 --- a/mysql-test/suite/galera/r/galera_change_user.result +++ b/mysql-test/suite/galera/r/galera_change_user.result @@ -12,5 +12,27 @@ INSERT INTO t1 VALUES (1); change_user user1,,; disconnect node_1a; connection node_1; +GRANT SELECT ON test.t1 TO user1; +connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1; +# Fresh connection +SET SESSION wsrep_sync_wait = 1; +SELECT COUNT(*) FROM test.t1; +COUNT(*) +0 +include/assert.inc [SELECT did a causal read on a fresh connection] +# After COM_CHANGE_USER +SET SESSION wsrep_sync_wait = 1; +SELECT COUNT(*) FROM test.t1; +COUNT(*) +0 +include/assert.inc [SELECT did a causal read after COM_CHANGE_USER] +# After COM_RESET_CONNECTION +SET SESSION wsrep_sync_wait = 1; +SELECT COUNT(*) FROM test.t1; +COUNT(*) +0 +include/assert.inc [SELECT did a causal read after COM_RESET_CONNECTION] +disconnect node_1a; +connection node_1; DROP TABLE t1; DROP USER user1; diff --git a/mysql-test/suite/galera/r/galera_fk_char_key.result b/mysql-test/suite/galera/r/galera_fk_char_key.result new file mode 100644 index 00000000000..34f4ac7f9f7 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_fk_char_key.result @@ -0,0 +1,37 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE p (id CHAR(5) CHARACTER SET utf8mb4 PRIMARY KEY, v INT) ENGINE=InnoDB; +CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, +p_id CHAR(5) CHARACTER SET utf8mb4 NOT NULL, +KEY k (p_id), +FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB; +INSERT INTO p VALUES (_utf8mb4 0xC3A9, 0); +connection node_2; +SET SESSION wsrep_sync_wait = 1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_slave_threads = 2; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +connection node_1; +INSERT INTO c (p_id) VALUES (_utf8mb4 0xC3A9); +connection node_2; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +UPDATE p SET v = v + 1 WHERE id = _utf8mb4 0xC3A9; +connection node_2; +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; +no_row_modified_in_parallel +1 +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SELECT v FROM p; +v +1 +SELECT COUNT(*) FROM c; +COUNT(*) +1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; +connection node_1; +DROP TABLE c, p; diff --git a/mysql-test/suite/galera/r/galera_fk_char_key_big.result b/mysql-test/suite/galera/r/galera_fk_char_key_big.result new file mode 100644 index 00000000000..d4be5aca312 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_fk_char_key_big.result @@ -0,0 +1,19 @@ +connection node_2; +connection node_1; +connection node_2; +SET GLOBAL wsrep_slave_threads = 2; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +SET SESSION wsrep_sync_wait = 0; +# Shape 1: CHAR(36) utf8mb4 +# Shape 2: CHAR(36) utf8mb3 +# Shape 3: CHAR(36) utf8mb4, four byte characters +# Shape 4: CHAR(36) utf8mb4_bin +# Shape 5: CHAR(36) utf8mb4, ROW_FORMAT=REDUNDANT +# Shape 6: CHAR(36) utf16 +# Shape 7: CHAR(36) ucs2 +# Shape 8: CHAR(36) latin1 +# Shape 9: CHAR(36) utf8mb4, ASCII value +# Shape 10: VARCHAR(36) utf8mb4 +connection node_2; +SET GLOBAL wsrep_slave_threads = DEFAULT; +disconnect node_2a; diff --git a/mysql-test/suite/galera/r/galera_fulltext.result b/mysql-test/suite/galera/r/galera_fulltext.result index 94780f235ad..5722dbc9100 100644 --- a/mysql-test/suite/galera/r/galera_fulltext.result +++ b/mysql-test/suite/galera/r/galera_fulltext.result @@ -1,5 +1,10 @@ connection node_2; connection node_1; +connection node_1; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_2; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_1; CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); connection node_1; @@ -42,6 +47,7 @@ CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb; INSERT IGNORE INTO t VALUES(@value); Warnings: Warning 1265 Data truncated for column 'a' at row 1 +Warning 1071 WSREP: Write set key for table 'test.t' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. SELECT COUNT(*) FROM t; COUNT(*) 1 @@ -70,6 +76,7 @@ CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8 INSERT IGNORE INTO t VALUES(@value); Warnings: Warning 1265 Data truncated for column 'a' at row 1 +Warning 1071 WSREP: Write set key for table 'test.t' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. SELECT COUNT(*) FROM t; COUNT(*) 1 diff --git a/mysql-test/suite/galera/r/galera_partitioned_tables.result b/mysql-test/suite/galera/r/galera_partitioned_tables.result index ccfc9dacc2a..91d0943f400 100644 --- a/mysql-test/suite/galera/r/galera_partitioned_tables.result +++ b/mysql-test/suite/galera/r/galera_partitioned_tables.result @@ -227,3 +227,21 @@ customer_id customer_name store_id bill_number bill_date amount 8 Oscar S012 125 2019-07-24 300.00 9 Darryl S456 119 2019-08-02 492.20 DROP TABLE sales; +connection node_1; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0),(2,0),(3,0); +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +3 +connection node_2; +connection node_1; +DROP TABLE t1, t2; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +connection node_2; +connection node_1; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/r/galera_toi_alter_auto_increment.result b/mysql-test/suite/galera/r/galera_toi_alter_auto_increment.result index a9923ba4211..ee9f73ebb9f 100644 --- a/mysql-test/suite/galera/r/galera_toi_alter_auto_increment.result +++ b/mysql-test/suite/galera/r/galera_toi_alter_auto_increment.result @@ -20,6 +20,8 @@ MIN(f1) >= 1000 COUNT(*) = 20 COUNT(DISTINCT f1) = 20 1 1 1 connection node_1; ALTER TABLE t1 AUTO_INCREMENT = 5; +Warnings: +Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '5' to '1039' INSERT INTO t1 (f2) SELECT 1 FROM ten; connection node_2; INSERT INTO t1 (f2) SELECT 1 FROM ten; diff --git a/mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result b/mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result index 41e5e960872..ac1e8bdbdd5 100644 --- a/mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result +++ b/mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result @@ -13,7 +13,7 @@ SET SESSION wsrep_sync_wait=0; SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; connection node_2; # DDL 1 -ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000);; +ALTER TABLE t1 ADD COLUMN f3 INTEGER; connection node_1a; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; @@ -21,14 +21,22 @@ SET GLOBAL wsrep_provider_options = 'dbug='; # This will block on acquiring total order isolation connection node_1; # DDL 2 -CREATE UNIQUE INDEX i1 ON t1(f2);; +CREATE UNIQUE INDEX i1 ON t1(f2); +connection node_2a; +# Neither DDL has been applied on node_1 yet connection node_1a; +SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +EXPECT_2 +2 +SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; +EXPECT_1 +1 # Signal DDL 1 -SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; connection node_2; connection node_1; connection node_2; +INSERT INTO t1 VALUES (NULL, 10000, 10000); SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; EXPECT_3 3 diff --git a/mysql-test/suite/galera/r/galera_var_notify_cmd.result b/mysql-test/suite/galera/r/galera_var_notify_cmd.result index 432d6c0adbd..60c0bc700fa 100644 --- a/mysql-test/suite/galera/r/galera_var_notify_cmd.result +++ b/mysql-test/suite/galera/r/galera_var_notify_cmd.result @@ -7,7 +7,7 @@ EXPECT_2 SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status; EXPECT_2 2 -SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status; -EXPECT_2 -2 +SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE; +EXPECT_1 +1 DROP SCHEMA mtr_wsrep_notify; diff --git a/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result b/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result index 432d6c0adbd..60c0bc700fa 100644 --- a/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result +++ b/mysql-test/suite/galera/r/galera_var_notify_ssl_ipv6.result @@ -7,7 +7,7 @@ EXPECT_2 SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status; EXPECT_2 2 -SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status; -EXPECT_2 -2 +SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE; +EXPECT_1 +1 DROP SCHEMA mtr_wsrep_notify; diff --git a/mysql-test/suite/galera/r/galera_ws_datatypes.result b/mysql-test/suite/galera/r/galera_ws_datatypes.result new file mode 100644 index 00000000000..dc00dc2a823 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ws_datatypes.result @@ -0,0 +1,698 @@ +connection node_2; +connection node_1; +connection node_1; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_2; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_1; +CREATE TABLE p (a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +d INT, +PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, +a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +KEY k (a,b,c), +FOREIGN KEY (a,b,c) REFERENCES p (a,b,c)) ENGINE=InnoDB; +SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci; +SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254), +_utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci; +# +# Under strict mode a cut key fails the statement +# +INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v, 1); +ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# INSERT IGNORE turns the error back into a warning and the row goes in +# +INSERT IGNORE INTO p (a,b,c,d) VALUES (@v, @v, @v, 1); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# The child row goes down the foreign key path and behaves the same. +# Before the fix this statement took the server down with +# "[FATAL] InnoDB: Unknown error Generic error". +# +INSERT INTO ch (a,b,c) VALUES (@v, @v, @v); +ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT IGNORE INTO ch (a,b,c) VALUES (@v, @v, @v); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# Without strict mode the client also only gets the warning +# +SET SESSION sql_mode = ''; +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +# +# A second parent row that differs only past the cut +# +connection node_1; +INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v2, 2); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SELECT COUNT(*) AS EXPECT_2 FROM p; +EXPECT_2 +2 +connection node_2; +SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci; +SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254), +_utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci; +# +# An UPDATE under strict mode fails with the same error +# +connection node_1; +SET SESSION sql_mode = DEFAULT; +UPDATE p SET d = 9 WHERE a = @v AND b = @v AND c = @v; +ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# UPDATE IGNORE turns it back into a warning as well +# +UPDATE IGNORE p SET d = 9 WHERE a = @v AND b = @v AND c = @v; +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# Without strict mode the same statement gets the warning and runs. +# False positive. The two rows are different rows, but their keys are +# equal up to the cut, so the transaction on node_1 loses +# certification against the one on node_2. +# +connection node_1; +SET SESSION sql_mode = ''; +connection node_2; +SET SESSION sql_mode = ''; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1a; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_slave_enter_sync'; +connection node_1; +BEGIN; +UPDATE p SET d = 10 WHERE a = @v AND b = @v AND c = @v; +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +connection node_2; +UPDATE p SET d = 20 WHERE a = @v AND b = @v AND c = @v2; +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_slave_enter_sync'; +connection node_1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +# Only the update from node_2 is there +connection node_1; +SELECT d FROM p ORDER BY d; +d +9 +20 +# +# Short values leave the key inside the buffer. The same pattern on +# two different rows then commits. +# +connection node_1; +CREATE TABLE p2 (a CHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +d INT, +PRIMARY KEY (a)) ENGINE=InnoDB; +INSERT INTO p2 (a,d) VALUES ('aaaaaaaa', 1), ('aaaaaaab', 2); +connection node_2; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_slave_enter_sync'; +connection node_1; +BEGIN; +UPDATE p2 SET d = 10 WHERE a = 'aaaaaaaa'; +connection node_2; +UPDATE p2 SET d = 20 WHERE a = 'aaaaaaab'; +connection node_1a; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +connection node_1; +COMMIT; +connection node_1a; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_slave_enter_sync'; +connection node_1; +SELECT d FROM p2 ORDER BY d; +d +10 +20 +# +# Foreign keys on the other string types. InnoDB needs the whole +# column in a foreign key, so TEXT and BLOB cannot take part: they +# can only be indexed by a prefix. That leaves VARCHAR, VARBINARY and +# BINARY beside the CHAR columns above. +# +connection node_1; +SET SESSION sql_mode = DEFAULT; +CREATE TABLE fp_v (a VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +b VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +c VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +d INT, +PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_v (id INT AUTO_INCREMENT PRIMARY KEY, +a VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +b VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +c VARCHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +KEY k (a,b,c), +FOREIGN KEY (a,b,c) REFERENCES fp_v (a,b,c)) ENGINE=InnoDB; +# VARCHAR parent, row key path +INSERT INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1); +ERROR 42000: WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT IGNORE INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# VARCHAR child, foreign key path +INSERT INTO fc_v (a,b,c) VALUES (@v, @v, @v); +ERROR 42000: WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT IGNORE INTO fc_v (a,b,c) VALUES (@v, @v, @v); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.fp_v' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# BINARY and VARBINARY are not collated, so the key stays inside the +# buffer and both statements run +CREATE TABLE fp_b (a BINARY(255), +b VARBINARY(1000), +c VARBINARY(1000), +d INT, +PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_b (id INT AUTO_INCREMENT PRIMARY KEY, +a BINARY(255), +b VARBINARY(1000), +c VARBINARY(1000), +KEY k (a,b,c), +FOREIGN KEY (a,b,c) REFERENCES fp_b (a,b,c)) ENGINE=InnoDB; +SET @b255 = REPEAT('a', 255); +SET @b1000 = REPEAT('a', 1000); +INSERT INTO fp_b (a,b,c,d) VALUES (@b255, @b1000, @b1000, 1); +INSERT INTO fc_b (a,b,c) VALUES (@b255, @b1000, @b1000); +# TEXT and BLOB can only be indexed by a prefix, and InnoDB refuses a +# foreign key on such a column +CREATE TABLE fc_t (id INT AUTO_INCREMENT PRIMARY KEY, +a TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +KEY k (a(255)), +FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`fc_t` (errno: 150 "Foreign key constraint is incorrectly formed") +# BLOB behaves the same way +CREATE TABLE fc_bl (id INT AUTO_INCREMENT PRIMARY KEY, +a BLOB, +KEY k (a(255)), +FOREIGN KEY (a) REFERENCES fp_b (a)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`fc_bl` (errno: 150 "Foreign key constraint is incorrectly formed") +# JSON is stored as LONGTEXT and behaves the same way +CREATE TABLE fc_j (id INT AUTO_INCREMENT PRIMARY KEY, +a JSON, +KEY k (a(255)), +FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`fc_j` (errno: 150 "Foreign key constraint is incorrectly formed") +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM fp_v; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM fc_v; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM fp_b; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM fc_b; +EXPECT_1 +1 +# +# Foreign keys on FLOAT, DOUBLE, TIMESTAMP, DATE and DATETIME. These +# are fixed width and not collated, so wsrep_store_key_val_for_row() +# and wsrep_rec_get_foreign_key() never cut the key for them; the +# point is to show the same key-building code path used above still +# produces a working, replicated foreign key for these types. +# +connection node_1; +CREATE TABLE fp_num (a FLOAT, +b DOUBLE, +c TIMESTAMP, +dt DATE, +e DATETIME, +f INT, +PRIMARY KEY (a,b,c,dt,e)) ENGINE=InnoDB; +CREATE TABLE fc_num (id INT AUTO_INCREMENT PRIMARY KEY, +a FLOAT, +b DOUBLE, +c TIMESTAMP, +dt DATE, +e DATETIME, +KEY k (a,b,c,dt,e), +FOREIGN KEY (a,b,c,dt,e) +REFERENCES fp_num (a,b,c,dt,e)) ENGINE=InnoDB; +INSERT INTO fp_num (a,b,c,dt,e,f) VALUES +(1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00', 1); +INSERT INTO fc_num (a,b,c,dt,e) VALUES +(1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00'); +# No matching parent row for this combination, the insert is rejected +INSERT INTO fc_num (a,b,c,dt,e) VALUES +(9.5, 9.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`fc_num`, CONSTRAINT `fc_num_ibfk_1` FOREIGN KEY (`a`, `b`, `c`, `dt`, `e`) REFERENCES `fp_num` (`a`, `b`, `c`, `dt`, `e`)) +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM fp_num; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM fc_num; +EXPECT_1 +1 +# +# Foreign key where part of the key is NULL. InnoDB foreign keys use +# MATCH SIMPLE: when any column of a multi-column foreign key is +# NULL, the row is not checked against the parent at all, whether or +# not a matching parent row exists. +# +connection node_1; +CREATE TABLE fp_n (a INT, b INT, c INT, d INT, +PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_n (id INT AUTO_INCREMENT PRIMARY KEY, +a INT, b INT, c INT, +KEY k (a,b,c), +FOREIGN KEY (a,b,c) REFERENCES fp_n (a,b,c)) ENGINE=InnoDB; +# No parent row for (1,2,3) at all, but c is NULL so the row is +# accepted anyway +INSERT INTO fc_n (a,b,c) VALUES (1,2,NULL); +# A parent row exists for (10,20,30), but the child is still not +# checked against it because c is NULL +INSERT INTO fp_n (a,b,c,d) VALUES (10,20,30,1); +INSERT INTO fc_n (a,b,c) VALUES (10,20,NULL); +# A row with every foreign key column NULL is accepted the same way +INSERT INTO fc_n (a,b,c) VALUES (NULL,NULL,NULL); +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM fp_n; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_3 FROM fc_n; +EXPECT_3 +3 +# +# The same MATCH SIMPLE rule with only the last column of the +# foreign key nullable, the other columns NOT NULL. Position does +# not matter: any NULL column, first, middle or last, is enough to +# skip the check. +# +connection node_1; +CREATE TABLE mfp (a INT, b INT, c INT, PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE mfc (id INT AUTO_INCREMENT PRIMARY KEY, +a INT NOT NULL, b INT NOT NULL, c INT, +KEY k (a,b,c), +FOREIGN KEY (a,b,c) REFERENCES mfp (a,b,c)) ENGINE=InnoDB; +INSERT INTO mfp VALUES (1,2,3); +# Last column (c) is NULL: no matching parent row required +INSERT INTO mfc (a,b,c) VALUES (9,9,NULL); +# Last column (c) is non-NULL and matches: the constraint is +# checked and passes +INSERT INTO mfc (a,b,c) VALUES (1,2,3); +# Last column (c) is non-NULL and does not match: the constraint is +# checked and fails +INSERT INTO mfc (a,b,c) VALUES (1,2,99); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`mfc`, CONSTRAINT `mfc_ibfk_1` FOREIGN KEY (`a`, `b`, `c`) REFERENCES `mfp` (`a`, `b`, `c`)) +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM mfp; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_2 FROM mfc; +EXPECT_2 +2 +# +# Every remaining fixed width data type built into the server, in a +# primary key, in a unique key, in a plain key on a table with no +# primary key, and in a foreign key that references a primary key +# and one that references a unique key. wsrep_store_key_val_for_row() +# copies these types with a plain memcpy (TINYINT .. VARBINARY below) +# or through the ENUM/SET branch that skips collation; FLOAT, DOUBLE, +# TIMESTAMP, DATE and DATETIME were already covered above. UUID and +# INET6 are in galera_ws_datatypes_plugin.test. +# +connection node_1; +CREATE TABLE g1_pk (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, +bi BIGINT, de DECIMAL(10,2), bt BIT(8), +bn BINARY(4), vb VARBINARY(8), f INT, +PRIMARY KEY (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; +CREATE TABLE g1_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, +ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, +bi BIGINT, de DECIMAL(10,2), bt BIT(8), +bn BINARY(4), vb VARBINARY(8), +KEY k (ti,si,mi,ii,bi,de,bt,bn,vb), +FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb) +REFERENCES g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb)) +ENGINE=InnoDB; +CREATE TABLE g1_uk (id INT AUTO_INCREMENT PRIMARY KEY, +ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, +bi BIGINT, de DECIMAL(10,2), bt BIT(8), +bn BINARY(4), vb VARBINARY(8), +UNIQUE KEY u (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; +CREATE TABLE g1_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, +ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, +bi BIGINT, de DECIMAL(10,2), bt BIT(8), +bn BINARY(4), vb VARBINARY(8), +KEY k (ti,si,mi,ii,bi,de,bt,bn,vb), +FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb) +REFERENCES g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb)) +ENGINE=InnoDB; +CREATE TABLE g1_key (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, +bi BIGINT, de DECIMAL(10,2), bt BIT(8), +bn BINARY(4), vb VARBINARY(8), +KEY k (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; +# TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, DECIMAL, BIT, BINARY, +# VARBINARY together, in a primary key and a foreign key that +# references it +INSERT INTO g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb,f) +VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh',1); +INSERT INTO g1_pk_child (ti,si,mi,ii,bi,de,bt,bn,vb) +VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); +# The same types in a unique key and a foreign key that references it +INSERT INTO g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb) +VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); +INSERT INTO g1_uk_child (ti,si,mi,ii,bi,de,bt,bn,vb) +VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); +# The same types in a plain, non-unique key on a table with no +# primary key +INSERT INTO g1_key (ti,si,mi,ii,bi,de,bt,bn,vb) +VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM g1_pk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g1_pk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g1_uk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g1_uk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g1_key; +EXPECT_1 +1 +# +# TIME, YEAR, ENUM and SET, the same way. UUID and INET6 are provided +# by the mandatory type_uuid and type_inet plugins rather than being +# built into the server proper; they are covered by +# galera_ws_datatypes_plugin.test instead. +# +connection node_1; +CREATE TABLE g2_pk (tm TIME, yr YEAR, en ENUM('a','b','c'), +st SET('a','b','c'), f INT, +PRIMARY KEY (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, +tm TIME, yr YEAR, en ENUM('a','b','c'), +st SET('a','b','c'), +KEY k (tm,yr,en,st), +FOREIGN KEY (tm,yr,en,st) +REFERENCES g2_pk (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_uk (id INT AUTO_INCREMENT PRIMARY KEY, +tm TIME, yr YEAR, en ENUM('a','b','c'), +st SET('a','b','c'), +UNIQUE KEY u (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, +tm TIME, yr YEAR, en ENUM('a','b','c'), +st SET('a','b','c'), +KEY k (tm,yr,en,st), +FOREIGN KEY (tm,yr,en,st) +REFERENCES g2_uk (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_key (tm TIME, yr YEAR, en ENUM('a','b','c'), +st SET('a','b','c'), +KEY k (tm,yr,en,st)) ENGINE=InnoDB; +INSERT INTO g2_pk (tm,yr,en,st,f) +VALUES ('10:00:00',2026,'b','a,c',1); +INSERT INTO g2_pk_child (tm,yr,en,st) +VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_uk (tm,yr,en,st) +VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_uk_child (tm,yr,en,st) +VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_key (tm,yr,en,st) +VALUES ('10:00:00',2026,'b','a,c'); +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM g2_pk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g2_pk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g2_uk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g2_uk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g2_key; +EXPECT_1 +1 +# +# SERIAL, an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, +# as a primary key +# +connection node_1; +CREATE TABLE g_serial (id SERIAL PRIMARY KEY, f INT) ENGINE=InnoDB; +INSERT INTO g_serial (f) VALUES (1); +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM g_serial; +EXPECT_1 +1 +# +# Other string types and prefix indexes outside a foreign key. The +# indexes are +# unique because wsrep_append_keys() only builds a key for a unique +# index, one referenced by a foreign key, or any index of a table +# without a primary key. The key is cut when the collation weights of +# the indexed bytes pass the buffer; the binary types are not +# collated, so they never are. +# +connection node_1; +SET SESSION sql_mode = DEFAULT; +SET @c200 = REPEAT(_utf8mb4 0xEFAC84, 200) COLLATE utf8mb4_unicode_ci; +SET @c768 = REPEAT(_utf8mb4 0xEFAC84, 768) COLLATE utf8mb4_unicode_ci; +SET @bin255 = REPEAT('a', 255); +SET @bin3000 = REPEAT('a', 3000); +CREATE TABLE k1 (id INT AUTO_INCREMENT PRIMARY KEY, +v VARCHAR(768) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (v)) ENGINE=InnoDB; +CREATE TABLE k2 (id INT AUTO_INCREMENT PRIMARY KEY, +t TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k3 (id INT AUTO_INCREMENT PRIMARY KEY, +c CHAR(255) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (c(200))) ENGINE=InnoDB; +CREATE TABLE k4 (id INT AUTO_INCREMENT PRIMARY KEY, +v VARCHAR(768) CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (v(700))) ENGINE=InnoDB; +CREATE TABLE k5 (id INT AUTO_INCREMENT PRIMARY KEY, +b BLOB, +UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k6 (id INT AUTO_INCREMENT PRIMARY KEY, +bn BINARY(255), +vb VARBINARY(3000), +UNIQUE KEY (bn), +UNIQUE KEY (vb(3000))) ENGINE=InnoDB; +CREATE TABLE k7 (id INT AUTO_INCREMENT PRIMARY KEY, +t TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (t(50))) ENGINE=InnoDB; +CREATE TABLE k8 (id INT AUTO_INCREMENT PRIMARY KEY, +t MEDIUMTEXT CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k9 (id INT AUTO_INCREMENT PRIMARY KEY, +t LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k10 (id INT AUTO_INCREMENT PRIMARY KEY, +b TINYBLOB, +UNIQUE KEY (b(50))) ENGINE=InnoDB; +CREATE TABLE k11 (id INT AUTO_INCREMENT PRIMARY KEY, +b MEDIUMBLOB, +UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k12 (id INT AUTO_INCREMENT PRIMARY KEY, +b LONGBLOB, +UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k13 (id INT AUTO_INCREMENT PRIMARY KEY, +j JSON, +UNIQUE KEY (j(768))) ENGINE=InnoDB; +# VARCHAR, whole column +INSERT INTO k1 (v) VALUES (@c768); +ERROR 42000: WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# TEXT, prefix +INSERT INTO k2 (t) VALUES (@c768); +ERROR 42000: WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# CHAR, prefix short enough to stay inside the buffer +INSERT INTO k3 (c) VALUES (@c200); +# VARCHAR, prefix +INSERT INTO k4 (v) VALUES (@c768); +ERROR 42000: WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# BLOB, prefix. Bytes are not collated, so nothing is cut +INSERT INTO k5 (b) VALUES (@bin3000); +# BINARY and VARBINARY, whole column and prefix +INSERT INTO k6 (bn, vb) VALUES (@bin255, @bin3000); +SET @tiny = REPEAT('a', 50); +# TINYTEXT, prefix short enough to stay inside the buffer +INSERT INTO k7 (t) VALUES (@tiny); +# MEDIUMTEXT, prefix short enough to stay inside the buffer +INSERT INTO k8 (t) VALUES (@c200); +# LONGTEXT, prefix short enough to stay inside the buffer +INSERT INTO k9 (t) VALUES (@c200); +# TINYBLOB, prefix. Bytes are not collated, so nothing is cut +INSERT INTO k10 (b) VALUES (@tiny); +# MEDIUMBLOB, prefix +INSERT INTO k11 (b) VALUES (@bin3000); +# LONGBLOB, prefix +INSERT INTO k12 (b) VALUES (@bin3000); +# JSON, stored as LONGTEXT with a validity check, prefix +INSERT INTO k13 (j) VALUES ('{"a":1}'); +# Without strict mode the cut ones go in with a warning +SET SESSION sql_mode = ''; +INSERT INTO k1 (v) VALUES (@c768); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.k1' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT INTO k2 (t) VALUES (@c768); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.k2' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT INTO k4 (v) VALUES (@c768); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.k4' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SET SESSION sql_mode = DEFAULT; +# The rows the server accepted reach node_2 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM k1; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k2; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k3; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k4; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k5; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k6; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k7; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k8; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k9; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k10; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k11; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k12; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM k13; +EXPECT_1 +1 +# +# GEOMETRY is stored as BLOB and behaves the same way: a key needs an +# explicit prefix length, and a foreign key is rejected regardless of +# length. POINT is fixed length (an SRID plus one X/Y pair), so it can +# be a whole-column primary or unique key without a prefix, but a +# foreign key on it is still rejected. +# +connection node_1; +CREATE TABLE g_pk (g GEOMETRY NOT NULL, PRIMARY KEY (g)) ENGINE=InnoDB; +ERROR 42000: BLOB/TEXT column 'g' used in key specification without a key length +CREATE TABLE g_uk (id INT AUTO_INCREMENT PRIMARY KEY, +g GEOMETRY NOT NULL, UNIQUE KEY (g(25))) ENGINE=InnoDB; +INSERT INTO g_uk (g) VALUES (ST_PointFromText('POINT(1 1)')); +CREATE TABLE g_fk (id INT AUTO_INCREMENT PRIMARY KEY, +g GEOMETRY, +KEY k (g(25)), +FOREIGN KEY (g) REFERENCES g_uk (g)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`g_fk` (errno: 150 "Foreign key constraint is incorrectly formed") +CREATE TABLE g_pk2 (p POINT NOT NULL, PRIMARY KEY (p)) ENGINE=InnoDB; +INSERT INTO g_pk2 (p) VALUES (ST_PointFromText('POINT(1 1)')); +CREATE TABLE g_uk2 (id INT AUTO_INCREMENT PRIMARY KEY, +p POINT NOT NULL, UNIQUE KEY (p)) ENGINE=InnoDB; +INSERT INTO g_uk2 (p) VALUES (ST_PointFromText('POINT(1 1)')); +CREATE TABLE g_fk2 (id INT AUTO_INCREMENT PRIMARY KEY, +p POINT, +KEY k (p), +FOREIGN KEY (p) REFERENCES g_pk2 (p)) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`g_fk2` (errno: 150 "Foreign key constraint is incorrectly formed") +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM g_uk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g_pk2; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM g_uk2; +EXPECT_1 +1 +connection node_1; +DROP TABLE ch, p; +DROP TABLE p2; +DROP TABLE fc_v, fp_v; +DROP TABLE fc_b, fp_b; +DROP TABLE fc_num, fp_num; +DROP TABLE fc_n, fp_n; +DROP TABLE mfc, mfp; +DROP TABLE g1_pk_child, g1_pk, g1_uk_child, g1_uk, g1_key; +DROP TABLE g2_pk_child, g2_pk, g2_uk_child, g2_uk, g2_key; +DROP TABLE g_serial; +DROP TABLE g_uk, g_pk2, g_uk2; +DROP TABLE k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13; +disconnect node_1a; +disconnect node_2; +disconnect node_1; +# End of test diff --git a/mysql-test/suite/galera/r/galera_ws_datatypes_fixed_length.result b/mysql-test/suite/galera/r/galera_ws_datatypes_fixed_length.result new file mode 100644 index 00000000000..bb2fffa2112 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ws_datatypes_fixed_length.result @@ -0,0 +1,60 @@ +connection node_2; +connection node_1; +connection node_1; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_2; +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +connection node_1; +CREATE TABLE p (a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +m VARBINARY(8) NOT NULL, +c FLOAT NOT NULL, +PRIMARY KEY (a,m,c)) ENGINE=InnoDB; +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, +a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +m VARBINARY(8) NOT NULL, +c FLOAT NOT NULL, +KEY k (a,m,c), +FOREIGN KEY (a,m,c) REFERENCES p (a,m,c)) ENGINE=InnoDB; +SET @v = REPEAT(_utf8mb4 0xEFAC84, 582) COLLATE utf8mb4_unicode_ci; +# +# Under strict mode a cut key fails the statement +# +INSERT INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5); +ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# INSERT IGNORE turns the error back into a warning and the row goes in +# +INSERT IGNORE INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +# +# The child row goes down the foreign key path and behaves the same. +# Before the fix this statement took the server down with +# "Assertion `len == sizeof(float)' failed." +# +INSERT INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5); +ERROR 42000: WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +INSERT IGNORE INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5); +Warnings: +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SHOW WARNINGS; +Level Code Message +Warning 1071 WSREP: Write set key for table 'test.p' was cut to 3500 bytes. Rows whose key values are equal up to that length produce the same key and conflict in certification. +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +connection node_1; +DROP TABLE ch, p; diff --git a/mysql-test/suite/galera/r/galera_ws_datatypes_plugin.result b/mysql-test/suite/galera/r/galera_ws_datatypes_plugin.result new file mode 100644 index 00000000000..d9d096ac26e --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ws_datatypes_plugin.result @@ -0,0 +1,53 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE gp_pk (uu UUID, i6 INET6, f INT, +PRIMARY KEY (uu,i6)) ENGINE=InnoDB; +CREATE TABLE gp_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, +uu UUID, i6 INET6, +KEY k (uu,i6), +FOREIGN KEY (uu,i6) REFERENCES gp_pk (uu,i6)) +ENGINE=InnoDB; +CREATE TABLE gp_uk (id INT AUTO_INCREMENT PRIMARY KEY, +uu UUID, i6 INET6, +UNIQUE KEY u (uu,i6)) ENGINE=InnoDB; +CREATE TABLE gp_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, +uu UUID, i6 INET6, +KEY k (uu,i6), +FOREIGN KEY (uu,i6) REFERENCES gp_uk (uu,i6)) +ENGINE=InnoDB; +CREATE TABLE gp_key (uu UUID, i6 INET6, +KEY k (uu,i6)) ENGINE=InnoDB; +SET @uu = '11111111-1111-1111-1111-111111111111'; +SET @i6 = '2001:db8::1'; +# UUID and INET6 together, in a primary key and a foreign key that +# references it +INSERT INTO gp_pk (uu,i6,f) VALUES (@uu,@i6,1); +INSERT INTO gp_pk_child (uu,i6) VALUES (@uu,@i6); +# The same types in a unique key and a foreign key that references it +INSERT INTO gp_uk (uu,i6) VALUES (@uu,@i6); +INSERT INTO gp_uk_child (uu,i6) VALUES (@uu,@i6); +# The same types in a plain, non-unique key on a table with no +# primary key +INSERT INTO gp_key (uu,i6) VALUES (@uu,@i6); +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM gp_pk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM gp_pk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM gp_uk; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM gp_uk_child; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM gp_key; +EXPECT_1 +1 +connection node_1; +DROP TABLE gp_pk_child, gp_pk, gp_uk_child, gp_uk, gp_key; +disconnect node_2; +disconnect node_1; +# End of test diff --git a/mysql-test/suite/galera/r/galera_ws_datatypes_varchar_cap.result b/mysql-test/suite/galera/r/galera_ws_datatypes_varchar_cap.result new file mode 100644 index 00000000000..38a3808047a --- /dev/null +++ b/mysql-test/suite/galera/r/galera_ws_datatypes_varchar_cap.result @@ -0,0 +1,27 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE p (a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, +a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, +KEY k (a), +FOREIGN KEY (a) REFERENCES p (a)) ENGINE=InnoDB; +SET @v = REPEAT(_utf8mb4 0xEFAC84, 550) COLLATE utf8mb4_unicode_ci; +INSERT INTO p (a) VALUES (@v); +INSERT INTO ch (a) VALUES (@v); +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +connection node_2; +SELECT COUNT(*) AS EXPECT_1 FROM p; +EXPECT_1 +1 +SELECT COUNT(*) AS EXPECT_1 FROM ch; +EXPECT_1 +1 +UPDATE p SET a = a WHERE a = @v; +connection node_1; +DROP TABLE ch, p; diff --git a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result index 143dee3e6e4..2a85fe3268a 100644 --- a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result +++ b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result @@ -1,5 +1,6 @@ connection node_2; connection node_1; +# Correct Galera library found connection node_1; connection node_2; connection node_2; diff --git a/mysql-test/suite/galera/r/galera_wsrep_notify_pwd_injection.result b/mysql-test/suite/galera/r/galera_wsrep_notify_pwd_injection.result new file mode 100644 index 00000000000..c571d6010fd --- /dev/null +++ b/mysql-test/suite/galera/r/galera_wsrep_notify_pwd_injection.result @@ -0,0 +1,11 @@ +connection node_2; +connection node_1; +connection node_1; +SELECT 1; +1 +1 +-B +-uroot +-h127.0.0.1 +-P3306 +MYSQL_PWD=x' y='z diff --git a/mysql-test/suite/galera/r/mdev-41075.result b/mysql-test/suite/galera/r/mdev-41075.result new file mode 100644 index 00000000000..ed0e495fbe5 --- /dev/null +++ b/mysql-test/suite/galera/r/mdev-41075.result @@ -0,0 +1,36 @@ +connection node_2; +connection node_1; +connect primary, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +connection node_2; +connection node_1; +START SLAVE; +# Many foreign-domain DDLs, each applied as TOI on node_2 +connection primary; +connection node_2; +SELECT COUNT(*) AS EXPECT_150 FROM base; +EXPECT_150 +150 +connection node_1; +connection primary; +DROP TABLE base; +connection node_1; +STOP SLAVE; +RESET SLAVE ALL; +SET GLOBAL wsrep_on = OFF; +RESET MASTER; +SET GLOBAL wsrep_on = ON; +SET GLOBAL gtid_slave_pos = ""; +connection node_2; +SET GLOBAL wsrep_on = OFF; +RESET MASTER; +SET GLOBAL wsrep_on = ON; +SET GLOBAL gtid_slave_pos = ""; +connection primary; +RESET MASTER; +connection node_1; +disconnect primary; +disconnect node_2; +disconnect node_1; +# End of test diff --git a/mysql-test/suite/galera/r/mysql-wsrep#198.result b/mysql-test/suite/galera/r/mysql-wsrep#198.result index 2be2d6c0186..ba7e83d9ce3 100644 --- a/mysql-test/suite/galera/r/mysql-wsrep#198.result +++ b/mysql-test/suite/galera/r/mysql-wsrep#198.result @@ -9,16 +9,20 @@ SELECT 1 FROM DUAL; LOCK TABLE t2 WRITE; connect node_2_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2_ctrl; -SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_sync_wait = 0; connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2a; +SET DEBUG_SYNC = 'mdl_acquire_lock_wait SIGNAL optimize_blocked'; OPTIMIZE TABLE t1,t2;; connection node_2_ctrl; -SET SESSION wsrep_sync_wait = 0; +SET DEBUG_SYNC = 'now WAIT_FOR optimize_blocked'; connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_2b; +SET DEBUG_SYNC = 'wsrep_before_toi_begin SIGNAL repair_at_toi'; REPAIR TABLE t1,t2;; connection node_2_ctrl; +SET DEBUG_SYNC = 'now WAIT_FOR repair_at_toi'; +SET DEBUG_SYNC = 'RESET'; connection node_1; INSERT INTO t2 VALUES (1); connection node_2; @@ -29,10 +33,12 @@ test.t1 optimize note Table does not support optimize, doing recreate + analyze test.t1 optimize status OK test.t2 optimize note Table does not support optimize, doing recreate + analyze instead test.t2 optimize status OK +SET DEBUG_SYNC = 'RESET'; connection node_2b; Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK +SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; DROP TABLE t2; connection node_1; diff --git a/mysql-test/suite/galera/t/GAL-419.test b/mysql-test/suite/galera/t/GAL-419.test index 699a8e54361..2d39bf69ed3 100644 --- a/mysql-test/suite/galera/t/GAL-419.test +++ b/mysql-test/suite/galera/t/GAL-419.test @@ -20,8 +20,6 @@ SET SESSION wsrep_sync_wait = 0; SET SESSION wsrep_sync_wait = 0; --source include/kill_galera.inc ---sleep 2 - # Node #1 has wsrep_cluster_address=gcomm:// in my.cnf, so should fail to bootstrap --error 1 diff --git a/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.cnf b/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.cnf new file mode 100644 index 00000000000..bfdb4bf8b4b --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.cnf @@ -0,0 +1,17 @@ +!include ../galera_2nodes.cnf + +# MDEV-38920: two deliberate EVS misconfigurations that a correct provider must +# NOT silently accept - it has to warn and clamp each: +# evs.install_timeout (PT5S) < evs.suspect_timeout (PT16S) +# evs.inactive_check_period (PT5S) > evs.keepalive_period (PT1S) +# +# inactive_check_period is kept <= suspect_timeout/2+1 (= 9s) so the provider's +# own range check does not clamp it first - that leaves the keepalive-period +# check to fire. install_timeout stays within [keepalive, inactive+1] for the +# same reason. + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT5S;evs.keepalive_period=PT1S;evs.inactive_check_period=PT5S;gcache.size=10M' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT5S;evs.keepalive_period=PT1S;evs.inactive_check_period=PT5S;gcache.size=10M' diff --git a/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.test b/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.test new file mode 100644 index 00000000000..b4e753259b2 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-38920-evs-config-warn.test @@ -0,0 +1,46 @@ +# +# MDEV-38920: the EVS layer must not silently accept a misconfigured set of +# timeouts. Both nodes are started (see .cnf) with: +# evs.install_timeout (PT5S) < evs.suspect_timeout (PT16S) +# evs.inactive_check_period (PT5S) > evs.keepalive_period (PT1S) +# +# A correct provider clamps each offending value and logs a warning, so the +# cluster still comes up. This test FAILS if the cluster comes up with either +# bad value silently accepted (i.e. with no warning) - which is what an +# un-sanitized provider does. +# +--let $galera_version=26.4.29 +source ../wsrep/include/check_galera_version.inc; + +--source include/have_innodb.inc +--let $galera_cluster_size = 2 +--source include/galera_cluster.inc + +# Reaching this point means the cluster formed - galera_cluster.inc waits for +# both nodes to be a Primary Component of size 2 - so "the cluster starts up" +# holds. The two warnings below are expected; suppress them so that MTR itself +# does not fail the test for finding warnings in the error log. +--disable_query_log +--connection node_1 +CALL mtr.add_suppression("WSREP: Ignoring configured evs.install_timeout"); +CALL mtr.add_suppression("WSREP: Ignoring configured evs.inactive_check_period"); +--connection node_2 +CALL mtr.add_suppression("WSREP: Ignoring configured evs.install_timeout"); +CALL mtr.add_suppression("WSREP: Ignoring configured evs.inactive_check_period"); +--enable_query_log + +# Verdict: the provider must have warned about each misconfiguration. If a +# warning is absent, $assert_select selects no lines, the concatenated string is +# empty and $assert_match cannot match, so assert_grep.inc fails the test - which +# is exactly the "started up but accepted the bad value silently" case. +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err + +--let $assert_text = provider must warn that evs.install_timeout is below evs.suspect_timeout +--let $assert_select = Ignoring configured evs.install_timeout +--let $assert_match = Ignoring configured evs.install_timeout=.*it must be between evs.suspect_timeout +--source include/assert_grep.inc + +--let $assert_text = provider must warn that evs.inactive_check_period exceeds evs.keepalive_period +--let $assert_select = Ignoring configured evs.inactive_check_period +--let $assert_match = Ignoring configured evs.inactive_check_period=.*it must not exceed evs.keepalive_period +--source include/assert_grep.inc diff --git a/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.cnf b/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.cnf new file mode 100644 index 00000000000..5137ca7c8c5 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.cnf @@ -0,0 +1,19 @@ +!include ../galera_4nodes.cnf + +# 4 nodes, 2 segments (seg1: node_1,2 ; seg2: node_3,4). +# Misconfiguration under test: install_timeout(12s) < suspect_timeout(16s): the EVS +# view-install protocol gives up ("install timer expired") before a silent peer +# can be suspected/evicted. These are about the smallest timeouts that still +# reliably reproduce; smaller (e.g. suspect=6) makes post-collapse recovery too slow. + +[mysqld.1] +wsrep_provider_options='gmcast.segment=1;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT12S;evs.max_install_timeouts=2;pc.wait_prim_timeout=PT23S;gcache.size=10M' + +[mysqld.2] +wsrep_provider_options='gmcast.segment=1;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT12S;evs.max_install_timeouts=2;pc.wait_prim_timeout=PT23S;gcache.size=10M' + +[mysqld.3] +wsrep_provider_options='gmcast.segment=2;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT12S;evs.max_install_timeouts=2;pc.wait_prim_timeout=PT23S;gcache.size=10M' + +[mysqld.4] +wsrep_provider_options='gmcast.segment=2;base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT16S;evs.inactive_timeout=PT32S;evs.install_timeout=PT12S;evs.max_install_timeouts=2;pc.wait_prim_timeout=PT23S;gcache.size=10M' diff --git a/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.test b/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.test new file mode 100644 index 00000000000..ce5442b05aa --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-38920-install-timer-expired.test @@ -0,0 +1,211 @@ +# +# Reproduce: in a multi-segment Galera cluster a single ungraceful (silent / +# black-holed) node failure drives the surviving quorum into NON_PRIM even +# though a majority is still up, and the cluster cannot self-heal. +# +# Topology (see .cnf): 4 nodes in 2 segments +# segment 1: node_1, node_2 +# segment 2: node_3, node_4 +# +# The failure is injected with SIGSTOP (freeze): the process keeps its TCP +# connections but stops all EVS traffic, so peers fall back on the +# suspect/inactive timers while the view-install protocol runs. +# +# Verdict: the presence of "install timer expired" in any node's error log is +# the signature of the reported failure. assert_grep at the end fails the test +# whenever that signature is found. +# + +--let $galera_version=26.4.29 +source ../wsrep/include/check_galera_version.inc; + +--source include/have_innodb.inc + +--let $galera_cluster_size = 4 +--source include/galera_cluster.inc + +# All four nodes must see a Primary Component of size 4. +--let $i = $galera_cluster_size +while ($i) +{ + --connection node_$i + --let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + --source include/wait_condition.inc + --dec $i +} + +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--let $node_4=node_4 +--disable_query_log +--source ../include/auto_increment_offset_save.inc +--enable_query_log + + +# Do not let status reads block on wsrep sync-wait during a view change, and +# suppress the gcomm/EVS noise a silent-node failure legitimately produces. +--let $i = $galera_cluster_size +while ($i) +{ + --connection node_$i + SET SESSION wsrep_sync_wait = 0; + --disable_query_log + CALL mtr.add_suppression("WSREP: Ignoring configured evs\\.install_timeout="); + CALL mtr.add_suppression("WSREP: .*install timer expired"); + CALL mtr.add_suppression("WSREP: no install message received"); + CALL mtr.add_suppression("WSREP: .* timed out"); + CALL mtr.add_suppression("WSREP: evs::proto.*"); + CALL mtr.add_suppression("WSREP: New COMPONENT: primary = no"); + CALL mtr.add_suppression("WSREP: Suspecting node"); + CALL mtr.add_suppression("WSREP: .*declaring .* inactive"); + CALL mtr.add_suppression("WSREP: .*(non-Primary|NON_PRIM).*"); + CALL mtr.add_suppression("WSREP: .*Failed to report last committed"); + CALL mtr.add_suppression("WSREP: gcs.*"); + CALL mtr.add_suppression("WSREP: .*overriding.*"); + CALL mtr.add_suppression("WSREP: user message in state LEAVING"); + CALL mtr.add_suppression("WSREP: .*max install timeouts reached.*"); + CALL mtr.add_suppression("WSREP: .*going to give up.*"); + CALL mtr.add_suppression("WSREP: Failed to send SYNC signal.*"); + --enable_query_log + --dec $i +} + +# +# Retry loop over nodes 2 and 3, alternating. node_1 is +# the observer. Freeze the victim, poll the survivors for loss of the Primary +# Component (under the 60s inactive window so a healthy cluster would not yet +# evict the frozen peer), resume, reconverge. Stop as soon as a survivor is seen +# non-Primary *and* the "install timer expired" signature has been logged - i.e. +# the actual reported failure, not a transient view-change blip. +# +--connection node_1 +SET SESSION wsrep_sync_wait = 0; + +--let $reproduced = 0 +# Paths for the per-round error-log check below, handed to the perl block via +# UPPER-CASE --let names (those are exported into the perl %ENV, the same +# mechanism as KILL_NODE_PIDFILE below). +--let MTR_ITE_LOGS = $MYSQLTEST_VARDIR/log/mysqld.*.err +--let MTR_ITE_INC = $MYSQLTEST_VARDIR/tmp/ite_found.inc +--let $round = 4 +while ($round) +{ + if (!$reproduced) + { + --disable_query_log + --let $victim = `SELECT IF(MOD($round,2) = 0, 2, 3)` + + --connection node_$victim + --let KILL_NODE_PIDFILE = `SELECT @@pid_file` + + --perl + my $pid = `cat $ENV{'KILL_NODE_PIDFILE'}`; + chomp($pid); + system("kill -STOP $pid"); + exit(0); + EOF + + --let $saw_np = 0 + --let $poll = 20 # make sure 16s suspect timeout is triggered + while ($poll) + { + --let $j = $galera_cluster_size + while ($j) + { + if ($j != $victim) + { + --connection node_$j + --let $np = `SELECT VARIABLE_VALUE = 'non-Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'` + if ($np) + { + # A survivor lost the Primary Component. Just record it and stop + # polling; whether this is the real failure or a transient + # view-change blip is decided after reconverge by grepping the error + # log for the "install timer expired" signature (see below). The log + # check is deliberately done there, not here: mysqltest does not run + # a --perl block nested this deep inside the poll loops. + --let $saw_np = 1 + --let $poll = 1 + --let $j = 1 + } + } + --dec $j + } + if (!$reproduced) + { + --real_sleep 1 + } + --dec $poll + } + + --perl + my $pid = `cat $ENV{'KILL_NODE_PIDFILE'}`; + chomp($pid); + system("kill -CONT $pid"); + exit(0); + EOF + + --connection node_1 + --let $wait_timeout = 120 + --let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + --source include/wait_condition.inc + --let $wait_timeout = 120 + --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; + --source include/wait_condition.inc + + # Grep every node's error log for the "install timer expired" signature (the + # same one the final assert checks) and read the count back into $ite_found. + # The --perl block is kept at this nesting depth on purpose: mysqltest does + # not execute a --perl block nested inside a second, inner if-block. + --let $ite_found = 0 + --perl + my @logs = glob($ENV{MTR_ITE_LOGS}); + my $found = 0; + foreach my $f (@logs) { + open(my $fh, '<', $f) or next; + while (my $line = <$fh>) { + if (index($line, 'install timer expired') >= 0) { $found = 1; last; } + } + close($fh); + last if $found; + } + open(my $out, '>', $ENV{MTR_ITE_INC}) or die $!; + print $out "--let \$ite_found = $found\n"; + close($out); + EOF + --source $MYSQLTEST_VARDIR/tmp/ite_found.inc + + # A genuine reproduction = a survivor lost the Primary Component this round + # *and* the signature was logged. A survivor can briefly go non-Primary in a + # normal view change (no signature) - that is not what we are after. Plain + # if/--let nest to any depth, so the decision is safe to make here. + if ($saw_np) + { + if ($ite_found) + { + --let $reproduced = 1 + } + } + } + --dec $round +} +--enable_query_log + +# +# Verdict: no node may have run the EVS view-install protocol to exhaustion. +# +--let $n = $galera_cluster_size +while ($n) +{ + --let $assert_text = node_$n did not time out the EVS view-install protocol (no NON_PRIM on single-node failure) + --let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.$n.err + --let $assert_select = install timer expired + --let $assert_count = 0 + --source include/assert_grep.inc + --dec $n +} + +--disable_query_log +--source ../include/auto_increment_offset_restore.inc +--enable_query_log diff --git a/mysql-test/suite/galera/t/MDEV-41012-collision.inc b/mysql-test/suite/galera/t/MDEV-41012-collision.inc new file mode 100644 index 00000000000..4922009de67 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-41012-collision.inc @@ -0,0 +1,67 @@ +# +# Body of galera.MDEV-41012-collision, parameterized by the data type. +# +# $fbt_type - data type of the primary key column +# $fbt_value1 - a literal of that type +# $fbt_value2 - a *different* literal whose binary representation folds to +# the same latin1_swedish_ci weight string as $fbt_value1 +# + +--connection node_1 +--eval CREATE TABLE t (id $fbt_type PRIMARY KEY, v INT) ENGINE=InnoDB +--eval INSERT INTO t VALUES ($fbt_value1, 0), ($fbt_value2, 0) + +--connection node_2 +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT COUNT(*) = 2 FROM t +--source include/wait_condition.inc + +SET GLOBAL wsrep_slave_threads = 2; + +# Park the applier of the first UPDATE on entry to the apply monitor. +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +--eval UPDATE t SET v = 1 WHERE id = $fbt_value1 + +--connection node_2 +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_wait_sync_point.inc + +# Disarm, so the second applier runs into the real dependency check. +--source include/galera_clear_sync_point.inc + +--let $apply_waits = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits'` + +--connection node_1 +--eval UPDATE t SET v = 2 WHERE id = $fbt_value2 + +--connection node_2 +# The two statements modify two *different* rows, so their +# certification keys must differ, there must be no dependency between the two +# writesets, and the second applier must be free to apply its row while the +# first one is still parked. +--let $wait_condition = SELECT (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits') > $apply_waits OR EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0) +--source include/wait_condition.inc + +# While the key was collated with latin1_swedish_ci the two keys were equal, +# the second writeset was made to depend on the first, and both of these +# reported 0. +--disable_query_log +--eval SELECT VARIABLE_VALUE = $apply_waits AS no_false_dependency FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits' +--enable_query_log +SELECT COUNT(*) = 1 AS second_row_applied_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; + +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--let $wait_condition = SELECT SUM(v) = 3 FROM t +--source include/wait_condition.inc +SELECT id, v FROM t ORDER BY v; + +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1 +DROP TABLE t; diff --git a/mysql-test/suite/galera/t/MDEV-41012-collision.test b/mysql-test/suite/galera/t/MDEV-41012-collision.test new file mode 100644 index 00000000000..f9bfba89e45 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-41012-collision.test @@ -0,0 +1,64 @@ +# +# MDEV-41012: certification key collision between distinct values of a fixed +# binary data type (UUID, INET6, INET4). +# +# Testing key collisions with data types on Field_fbt: UUID, INET6 and INET4, +# where different keys could potentially generate same certification keys. +# i.e. a scenario where two transactions modifying two *different* +# rows certified as a conflict and the later one was aborted with a spurious +# ER_LOCK_DEADLOCK. +# +# A shared key also gives the two writesets a false dependency on each other, +# which serializes applying that should have run in parallel. The test detects +# the collision that way, because it can be driven deterministically. Whether +# the spurious ER_LOCK_DEADLOCK is observed instead depends on whether the +# first writeset has already been applied by the time the second transaction +# replicates, which is a race. +# +# This needs no foreign key: it is the row key path, +# wsrep_store_key_val_for_row(), alone. +# +# This is the second half of MDEV-41012. The other half, a key *mismatch* for +# one and the same row, is covered by galera.MDEV-41012. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/galera_have_debug_sync.inc + +--echo # +--echo # Each pair below is two distinct values whose bytes fold to the same +--echo # latin1_swedish_ci weight string (0xC0->0x41, 0x6A->0x4A, 0x6B->0x4B, +--echo # 0xD2->0x4F, 0x7A->0x5A). A UUID is stored as a byte permutation of the +--echo # value shown, which does not affect a byte-wise folding. +--echo # +SELECT WEIGHT_STRING(_latin1 0xC0A8016B9E4D4F7AB3D26A1E8F9C0D1B) = + WEIGHT_STRING(_latin1 0x41A8014B9E4D4F5AB34F4A1E8F9C0D1B) AS uuid_pair_collides, + WEIGHT_STRING(_latin1 0x20010DB80000000000000000C0A8016B) = + WEIGHT_STRING(_latin1 0x20010DB8000000000000000041A8014B) AS inet6_pair_collides, + WEIGHT_STRING(_latin1 0xC0A8016B) = + WEIGHT_STRING(_latin1 0x41A8014B) AS inet4_pair_collides; + +--echo # +--echo # UUID +--echo # +--let $fbt_type = UUID +--let $fbt_value1 = 'c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b' +--let $fbt_value2 = '41a8014b-9e4d-4f5a-b34f-4a1e8f9c0d1b' +--source MDEV-41012-collision.inc + +--echo # +--echo # INET6 +--echo # +--let $fbt_type = INET6 +--let $fbt_value1 = '2001:db8::c0a8:16b' +--let $fbt_value2 = '2001:db8::41a8:14b' +--source MDEV-41012-collision.inc + +--echo # +--echo # INET4 +--echo # +--let $fbt_type = INET4 +--let $fbt_value1 = '192.168.1.107' +--let $fbt_value2 = '65.168.1.75' +--source MDEV-41012-collision.inc diff --git a/mysql-test/suite/galera/t/MDEV-41012.inc b/mysql-test/suite/galera/t/MDEV-41012.inc new file mode 100644 index 00000000000..edb1430d74c --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-41012.inc @@ -0,0 +1,67 @@ +# +# Body of galera.MDEV-41012, parameterized by the data type of the foreign key. +# +# $fbt_type - data type of the parent PK / child FK column +# $fbt_value - a literal of that type whose binary representation contains +# bytes that latin1_swedish_ci folds (0xC0, 0x6A, 0x6B, 0xD2 ...) +# + +--connection node_1 +--eval CREATE TABLE p (id $fbt_type PRIMARY KEY, v INT) ENGINE=InnoDB +--eval CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, p_id $fbt_type NOT NULL, KEY k (p_id), FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB +--eval INSERT INTO p VALUES ($fbt_value, 0) + +--connection node_2 +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT COUNT(*) = 1 FROM p +--source include/wait_condition.inc + +# Two appliers, so that the two writesets below *can* be applied in parallel +# if certification does not make them depend on each other. +SET GLOBAL wsrep_slave_threads = 2; + +# Park the first applier on entry to the apply monitor, i.e. before the child +# INSERT is applied and before its FK check locks the parent row. +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +--eval INSERT INTO c (p_id) VALUES ($fbt_value) + +--connection node_2 +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_wait_sync_point.inc + +# clear the sync point. The second applier must run into the real dependency +--source include/galera_clear_sync_point.inc + +--let $apply_waits = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits'` + +--connection node_1 +--eval UPDATE p SET v = v + 1 WHERE id = $fbt_value + +--connection node_2 +# Wait until the second applier has blocked in the apply monitor because +--let $wait_condition = SELECT (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits') > $apply_waits +--source include/wait_condition.inc + +# the second applier waited instead of applying it in parallel. +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; + +# Release the child INSERT +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--let $wait_condition = SELECT COUNT(*) = 1 FROM c +--source include/wait_condition.inc +--let $wait_condition = SELECT v = 1 FROM p +--source include/wait_condition.inc + +SELECT v FROM p; +SELECT COUNT(*) FROM c; + +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1 +DROP TABLE c, p; diff --git a/mysql-test/suite/galera/t/MDEV-41012.test b/mysql-test/suite/galera/t/MDEV-41012.test new file mode 100644 index 00000000000..06a8c604dd6 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-41012.test @@ -0,0 +1,40 @@ +# +# MDEV-41012: BF-BF conflict when applying a child INSERT and a parent UPDATE +# in parallel, for a foreign key on a fixed binary data type. +# +# The test sends two write sets having access with the same primary key of fixed +# binary data type, the transactions are: +# * INSERT into the child table havinga reference key for the parent row +# * UPDATE of the parent row having the parent's primary key, +# +# The test orders appliers so that the child INSERT is parked before it +# is applied, the parent UPDATE is replicated after it, and we verify that the +# UPDATE has to wait for the INSERT instead of being applied in parallel. +# +# All three Field_fbt types (UUID, INET4 and INET6) are covered. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/galera_have_debug_sync.inc + +--echo # +--echo # UUID +--echo # +--let $fbt_type = UUID +--let $fbt_value = 'c0a8016b-9e4d-4f7a-b3d2-6a1e8f9c0d1b' +--source MDEV-41012.inc + +--echo # +--echo # INET6 +--echo # +--let $fbt_type = INET6 +--let $fbt_value = '2001:db8::c0a8:16b' +--source MDEV-41012.inc + +--echo # +--echo # INET4 +--echo # +--let $fbt_type = INET4 +--let $fbt_value = '192.168.1.107' +--source MDEV-41012.inc diff --git a/mysql-test/suite/galera/t/MW-292.test b/mysql-test/suite/galera/t/MW-292.test index 9580d53d85c..2daedf47e8d 100644 --- a/mysql-test/suite/galera/t/MW-292.test +++ b/mysql-test/suite/galera/t/MW-292.test @@ -48,8 +48,13 @@ UPDATE t1 SET f2 = 'c' WHERE f1 = 2; --connection node_1a ---let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync ---source include/galera_wait_sync_point.inc +# +# wsrep_debug_sync_waiters holds every waiter of the provider, so waiting for +# the whole list to equal one string fails as soon as anything else waits. +# Look for each sync point on its own instead. +# +--let $wait_condition = SELECT VARIABLE_VALUE LIKE '%apply_monitor_slave_enter_sync%' AND VARIABLE_VALUE LIKE '%commit_monitor_master_enter_sync%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters'; +--source include/wait_condition.inc --source include/galera_clear_sync_point.inc # Let the conflicting UPDATE proceed and wait until it hits abort_trx_end. @@ -59,8 +64,8 @@ UPDATE t1 SET f2 = 'c' WHERE f1 = 2; --source include/galera_set_sync_point.inc --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc ---let $galera_sync_point = abort_trx_end commit_monitor_master_enter_sync ---source include/galera_wait_sync_point.inc +--let $wait_condition = SELECT VARIABLE_VALUE LIKE '%abort_trx_end%' AND VARIABLE_VALUE LIKE '%commit_monitor_master_enter_sync%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters'; +--source include/wait_condition.inc # Let the transactions proceed --source include/galera_clear_sync_point.inc diff --git a/mysql-test/suite/galera/t/MW-86-wait8.test b/mysql-test/suite/galera/t/MW-86-wait8.test index 33036ca7313..1b3f355eb25 100644 --- a/mysql-test/suite/galera/t/MW-86-wait8.test +++ b/mysql-test/suite/galera/t/MW-86-wait8.test @@ -67,7 +67,7 @@ SHOW DATABASES; --error 0 SHOW ENGINE InnoDB STATUS; ---error ER_SP_DOES_NOT_EXIST +--error ER_LOCK_WAIT_TIMEOUT SHOW FUNCTION CODE f1; --error ER_LOCK_WAIT_TIMEOUT @@ -82,7 +82,7 @@ SHOW INDEX FROM t1; --error ER_LOCK_WAIT_TIMEOUT SHOW OPEN TABLES; ---error ER_SP_DOES_NOT_EXIST +--error ER_LOCK_WAIT_TIMEOUT SHOW PROCEDURE CODE p1; --error ER_LOCK_WAIT_TIMEOUT diff --git a/mysql-test/suite/galera/t/galera-features#117.test b/mysql-test/suite/galera/t/galera-features#117.test index 9a3eaf8686e..0c1ffe54332 100644 --- a/mysql-test/suite/galera/t/galera-features#117.test +++ b/mysql-test/suite/galera/t/galera-features#117.test @@ -35,7 +35,6 @@ CREATE TABLE test.t2 (f1 INTEGER); SHOW TABLES IN test; --source include/kill_galera.inc ---source include/wait_until_disconnected.inc --source include/start_mysqld.inc CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); diff --git a/mysql-test/suite/galera/t/galera_change_user.test b/mysql-test/suite/galera/t/galera_change_user.test index 5051b18eec6..7c8525c0074 100644 --- a/mysql-test/suite/galera/t/galera_change_user.test +++ b/mysql-test/suite/galera/t/galera_change_user.test @@ -23,6 +23,50 @@ change_user 'user1'; reset_connection; --disconnect node_1a +# +# MDEV-41385: connection must remain a wsrep client connection after +# COM_CHANGE_USER and COM_RESET_CONNECTION. THD::cleanup() used to clear +# THD::wsrep_client_thread, which silently disabled wsrep_sync_wait and +# other client-only wsrep checks for the rest of the session. +# +# Session variables are reset by both commands, so wsrep_sync_wait is +# set again each time. A causal read is detected by the provider's +# wsrep_causal_reads status counter. +# +--connection node_1 +GRANT SELECT ON test.t1 TO user1; + +--connect node_1a, 127.0.0.1, root, , test, $MYPORT_NODE_1 +--echo # Fresh connection +SET SESSION wsrep_sync_wait = 1; +--let $causal_reads_before = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +SELECT COUNT(*) FROM test.t1; +--let $causal_reads_after = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +--let $assert_text = SELECT did a causal read on a fresh connection +--let $assert_cond = $causal_reads_after > $causal_reads_before +--source include/assert.inc + +--echo # After COM_CHANGE_USER +change_user 'user1'; +SET SESSION wsrep_sync_wait = 1; +--let $causal_reads_before = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +SELECT COUNT(*) FROM test.t1; +--let $causal_reads_after = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +--let $assert_text = SELECT did a causal read after COM_CHANGE_USER +--let $assert_cond = $causal_reads_after > $causal_reads_before +--source include/assert.inc + +--echo # After COM_RESET_CONNECTION +reset_connection; +SET SESSION wsrep_sync_wait = 1; +--let $causal_reads_before = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +SELECT COUNT(*) FROM test.t1; +--let $causal_reads_after = query_get_value(SHOW STATUS LIKE 'wsrep_causal_reads', Value, 1) +--let $assert_text = SELECT did a causal read after COM_RESET_CONNECTION +--let $assert_cond = $causal_reads_after > $causal_reads_before +--source include/assert.inc +--disconnect node_1a + --connection node_1 DROP TABLE t1; DROP USER user1; diff --git a/mysql-test/suite/galera/t/galera_fk_char_key.test b/mysql-test/suite/galera/t/galera_fk_char_key.test new file mode 100644 index 00000000000..84a95a9ce2b --- /dev/null +++ b/mysql-test/suite/galera/t/galera_fk_char_key.test @@ -0,0 +1,94 @@ +# +# A foreign key on a CHAR column of a variable length character set. +# +# The key of the child row is built from the MySQL record by +# wsrep_store_key_val_for_row() and the key of the parent row from the InnoDB +# record by wsrep_rec_get_foreign_key(). A CHAR is not space padded the same +# way in the two formats: the MySQL record pads it to n_chars * mbmaxlen +# bytes, while InnoDB strips that padding down to, but not below, n_chars +# bytes. As that compares a byte count with a character count, a value that +# holds a multi byte character and is shorter than the column ended up with a +# different number of characters on the two paths, the two keys differed, the +# child INSERT got no dependency on the parent row and the appliers were free +# to run it in parallel with a change of that very row. +# +# The value used below is one two byte character in a five character column, +# so it is padded, which is what used to make the two encodings diverge. It +# is written as a hex literal so that the test does not depend on the +# character set of the client connection. +# +# The test parks the applier of the child INSERT and replicates an UPDATE of +# the parent row after it, then verifies that the UPDATE had to wait. +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/galera_have_debug_sync.inc + +--connection node_1 +CREATE TABLE p (id CHAR(5) CHARACTER SET utf8mb4 PRIMARY KEY, v INT) ENGINE=InnoDB; +CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, + p_id CHAR(5) CHARACTER SET utf8mb4 NOT NULL, + KEY k (p_id), + FOREIGN KEY (p_id) REFERENCES p (id)) ENGINE=InnoDB; +INSERT INTO p VALUES (_utf8mb4 0xC3A9, 0); + +--connection node_2 +# Catch up with node_1 with a causal read before causal reads are turned off. +SET SESSION wsrep_sync_wait = 1; +--disable_query_log +--disable_result_log +SELECT COUNT(*) FROM p; +--enable_result_log +--enable_query_log +SET SESSION wsrep_sync_wait = 0; + +# Two appliers, so that the two writesets below *can* be applied in parallel +# if certification does not make them depend on each other. +SET GLOBAL wsrep_slave_threads = 2; + +# Park the first applier on entry to the apply monitor, i.e. before the child +# INSERT is applied and before its FK check locks the parent row. +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +INSERT INTO c (p_id) VALUES (_utf8mb4 0xC3A9); + +--connection node_2 +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_wait_sync_point.inc + +# Clear the sync point, the second applier must run into the real dependency. +--source include/galera_clear_sync_point.inc + +--let $apply_waits = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits'` + +--connection node_1 +UPDATE p SET v = v + 1 WHERE id = _utf8mb4 0xC3A9; + +--connection node_2 +# Wait until the second applier has blocked in the apply monitor because +--let $wait_condition = SELECT (SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_apply_waits') > $apply_waits +--source include/wait_condition.inc + +# the second applier waited instead of applying it in parallel. +SELECT COUNT(*) = 0 AS no_row_modified_in_parallel FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_rows_modified > 0; + +# Release the child INSERT +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--let $wait_condition = SELECT COUNT(*) = 1 FROM c; +--source include/wait_condition.inc +--let $wait_condition = SELECT v = 1 FROM p; +--source include/wait_condition.inc + +SELECT v FROM p; +SELECT COUNT(*) FROM c; + +SET GLOBAL wsrep_slave_threads = DEFAULT; +SET SESSION wsrep_sync_wait = DEFAULT; + +--connection node_1 +DROP TABLE c, p; diff --git a/mysql-test/suite/galera/t/galera_fk_char_key_big.test b/mysql-test/suite/galera/t/galera_fk_char_key_big.test new file mode 100644 index 00000000000..c7da3830eaa --- /dev/null +++ b/mysql-test/suite/galera/t/galera_fk_char_key_big.test @@ -0,0 +1,130 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_sequence.inc + +--connection node_2 +SET GLOBAL wsrep_slave_threads = 2; + +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +SET SESSION wsrep_sync_wait = 0; + +--let $shape = 0 +while ($shape < 10) +{ + --inc $shape + --let $opt = ENGINE=InnoDB + + if ($shape == 1) + { + --let $name = CHAR(36) utf8mb4 + --let $col = CHAR(36) CHARACTER SET utf8mb4 + --let $val = _utf8mb4 0xC3A9C3A9C3A9C3A9C3A9 + } + if ($shape == 2) + { + --let $name = CHAR(36) utf8mb3 + --let $col = CHAR(36) CHARACTER SET utf8mb3 + --let $val = _utf8mb3 0xC3A9C3A9C3A9C3A9C3A9 + } + if ($shape == 3) + { + --let $name = CHAR(36) utf8mb4, four byte characters + --let $col = CHAR(36) CHARACTER SET utf8mb4 + --let $val = _utf8mb4 0xF09F9880F09F9880F09F9880F09F9880F09F9880 + } + if ($shape == 4) + { + --let $name = CHAR(36) utf8mb4_bin + --let $col = CHAR(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin + --let $val = _utf8mb4 0xC3A9C3A9C3A9C3A9C3A9 + } + if ($shape == 5) + { + --let $name = CHAR(36) utf8mb4, ROW_FORMAT=REDUNDANT + --let $col = CHAR(36) CHARACTER SET utf8mb4 + --let $val = _utf8mb4 0xC3A9C3A9C3A9C3A9C3A9 + --let $opt = ENGINE=InnoDB ROW_FORMAT=REDUNDANT + } + if ($shape == 6) + { + --let $name = CHAR(36) utf16 + --let $col = CHAR(36) CHARACTER SET utf16 + --let $val = _utf16 0x00E900E900E900E900E9 + } + if ($shape == 7) + { + --let $name = CHAR(36) ucs2 + --let $col = CHAR(36) CHARACTER SET ucs2 + --let $val = _ucs2 0x00E900E900E900E900E9 + } + if ($shape == 8) + { + --let $name = CHAR(36) latin1 + --let $col = CHAR(36) CHARACTER SET latin1 + --let $val = _latin1 0xE9E9E9E9E9 + } + if ($shape == 9) + { + --let $name = CHAR(36) utf8mb4, ASCII value + --let $col = CHAR(36) CHARACTER SET utf8mb4 + --let $val = _utf8mb4 0x6162636465 + } + if ($shape == 10) + { + --let $name = VARCHAR(36) utf8mb4 + --let $col = VARCHAR(36) CHARACTER SET utf8mb4 + --let $val = _utf8mb4 0xC3A9C3A9C3A9C3A9C3A9 + } + + --echo # Shape $shape: $name + --disable_connect_log + --connection node_1 + --disable_query_log + --eval CREATE TABLE p (id $col PRIMARY KEY, v INT) $opt + --eval CREATE TABLE c (id INT AUTO_INCREMENT PRIMARY KEY, p_id $col NOT NULL, KEY k (p_id), FOREIGN KEY (p_id) REFERENCES p (id)) $opt + --eval CREATE TABLE f (id INT AUTO_INCREMENT PRIMARY KEY, pad CHAR(255)) $opt + --eval INSERT INTO p VALUES ($val, 0) + --enable_query_log + --enable_connect_log + + --let $i = 0 + --let $round = 10 + while ($round) + { + --inc $i + --disable_connect_log + --connection node_1 + --disable_query_log + BEGIN; + INSERT INTO f (pad) SELECT REPEAT('x',255) FROM seq_1_to_2000; + --eval INSERT INTO c (p_id) VALUES ($val) + COMMIT; + --eval UPDATE p SET v = v + 1 WHERE id = $val + --enable_query_log + + --connection node_2a + --let $wait_timeout = 30 + --let $wait_condition = SELECT COUNT(*) = $i FROM c + --source include/wait_condition.inc + --enable_connect_log + + if (!$success) + { + SELECT ID, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user'; + SELECT trx_id, trx_state, trx_mysql_thread_id, trx_query FROM INFORMATION_SCHEMA.INNODB_TRX; + --die Node 2 stopped applying. The two appliers are deadlocked on the foreign key parent row. + } + --dec $round + } + + --disable_connect_log + --connection node_1 + --disable_query_log + DROP TABLE c, p, f; + --enable_query_log + --enable_connect_log +} + +--connection node_2 +SET GLOBAL wsrep_slave_threads = DEFAULT; +--disconnect node_2a diff --git a/mysql-test/suite/galera/t/galera_fulltext.test b/mysql-test/suite/galera/t/galera_fulltext.test index beb6a1b8f6f..aee377710d2 100644 --- a/mysql-test/suite/galera/t/galera_fulltext.test +++ b/mysql-test/suite/galera/t/galera_fulltext.test @@ -4,6 +4,14 @@ # InnoDB FULLTEXT indexes # +# The oversized values below leave the write set key cut, on whichever +# node builds it. +--connection node_1 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +--connection node_2 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +--connection node_1 + CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB; INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); diff --git a/mysql-test/suite/galera/t/galera_gcache_recover.test b/mysql-test/suite/galera/t/galera_gcache_recover.test index 53e6f54f9cb..0122c755ceb 100644 --- a/mysql-test/suite/galera/t/galera_gcache_recover.test +++ b/mysql-test/suite/galera/t/galera_gcache_recover.test @@ -33,8 +33,6 @@ INSERT INTO t1 VALUES (2); --source include/kill_galera.inc ---sleep 1 - --connection node_1 --let $galera_wsrep_recover_server_id=1 --source suite/galera/include/galera_wsrep_recover.inc diff --git a/mysql-test/suite/galera/t/galera_gra_log.test b/mysql-test/suite/galera/t/galera_gra_log.test index ad19bb44118..ee0d9a08d41 100644 --- a/mysql-test/suite/galera/t/galera_gra_log.test +++ b/mysql-test/suite/galera/t/galera_gra_log.test @@ -37,7 +37,6 @@ CREATE TABLE t1 (f1 INTEGER); # restart and reconnect node_2 --source include/kill_galera.inc ---source include/wait_until_disconnected.inc --source include/start_mysqld.inc --eval SET GLOBAL wsrep_ignore_apply_errors = $restore_wsrep_ignore_apply_errors diff --git a/mysql-test/suite/galera/t/galera_partitioned_tables.test b/mysql-test/suite/galera/t/galera_partitioned_tables.test index 41d2689f171..0cd73e1bf7c 100644 --- a/mysql-test/suite/galera/t/galera_partitioned_tables.test +++ b/mysql-test/suite/galera/t/galera_partitioned_tables.test @@ -167,4 +167,40 @@ SELECT * FROM sales; SET GLOBAL wsrep_mode=DEFAULT; --connection node_2 SELECT * FROM sales; -DROP TABLE sales; \ No newline at end of file +DROP TABLE sales; + +# +# MDEV-40929 : CREATE TABLE ... AS SELECT is not replicated in Galera when the table is partitioned +# + +--connection node_1 +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0),(2,0),(3,0); +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_2 +--let $c= query_get_value(SELECT COUNT(*) AS c FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2', c, 1) +if ($c != 1) { + --die The new partitioned table exists on node 1 but not on node 2. It was not replicated to the cluster. +} +--let $c= query_get_value(SELECT COUNT(*) AS c FROM t2, c, 1) +if ($c != 3) { + --die The new partitioned table on node 2 is missing rows. The rows selected on node 1 were not replicated to the cluster. +} + +--connection node_1 +DROP TABLE t1, t2; + +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) ENGINE=InnoDB PARTITION BY LIST (a MOD 2) (PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1)) AS SELECT * FROM t1; +SELECT COUNT(*) FROM t2; + +--connection node_2 +--let $c= query_get_value(SELECT COUNT(*) AS c FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2', c, 1) +if ($c != 1) { + --die The new partitioned table exists on node 1 but not on node 2, with an empty source table. It was not replicated to the cluster. +} + +--connection node_1 +DROP TABLE t1, t2; diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf index 354376baec8..b2dee2c2482 100644 --- a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf @@ -4,6 +4,12 @@ wsrep_sst_method=rsync [sst] +# This is a backward-compatibility test: SSL SST must be enabled purely by the +# presence of tkey/tcert (no ssl-mode). galera_2nodes.cnf sets ssl-mode=DISABLED +# for SST by default; clear it here (empty value overrides the inherited one) so +# the ssl-mode is derived from tkey/tcert (-> REQUIRED) rather than forced by the +# explicit ssl-mode setting. +ssl-mode= tkey=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem tcert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test index ca911b2d323..3884bddc0c3 100644 --- a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test +++ b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test @@ -28,25 +28,49 @@ SET SESSION wsrep_sync_wait=0; --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_set_sync_point.inc +# +# DDL 1 is a TOI operation, it completes on node_2 as soon as it has been +# replicated, it does not wait for node_1. On node_1 its writeset is parked +# in the apply monitor by the sync point above, so node_1 cannot advance +# past it. +# --connection node_2 --echo # DDL 1 ---send ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000); +--send ALTER TABLE t1 ADD COLUMN f3 INTEGER --connection node_1a --source include/galera_wait_sync_point.inc --source include/galera_clear_sync_point.inc +# +# DDL 2 is issued on node_1 while DDL 1 is still parked there. It is therefore +# assigned a later seqno and has to wait for DDL 1 to be applied before it can +# acquire total order isolation. +# --echo # This will block on acquiring total order isolation --connection node_1 --echo # DDL 2 ---send CREATE UNIQUE INDEX i1 ON t1(f2); +--send CREATE UNIQUE INDEX i1 ON t1(f2) ---connection node_1a ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'acquiring total order isolation%' OR STATE LIKE 'Waiting to execute in isolation%'; +# +# Wait until DDL 2 has been replicated and applied on node_2. That proves that +# DDL 2 has reached total order after DDL 1 and is now waiting on node_1. +# +# Polling INFORMATION_SCHEMA.PROCESSLIST on node_1 for the state of the DDL 2 +# thread is not a reliable substitute: wsrep_TOI_begin() sets the +# "Waiting to execute in isolation" stage before it replicates the writeset, +# so that state can be observed before DDL 2 has been ordered at all. +# +--connection node_2a +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc +--echo # Neither DDL has been applied on node_1 yet +--connection node_1a +SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; + --echo # Signal DDL 1 ---source include/galera_clear_sync_point.inc --let $galera_sync_point = apply_monitor_slave_enter_sync --source include/galera_signal_sync_point.inc @@ -56,7 +80,16 @@ SET SESSION wsrep_sync_wait=0; --connection node_1 --reap +# +# The DML is executed only after both DDLs are done on both nodes. When it was +# sent together with DDL 1 in the same --send, its writeset raced with DDL 2: +# the DDL 2 TOI could reach node_2 while the INSERT was still executing there +# and BF-abort it, and the automatic autocommit retry then failed certification +# against the DDL 2 writeset, so the client got ER_LOCK_DEADLOCK. +# --connection node_2 +INSERT INTO t1 VALUES (NULL, 10000, 10000); + --let $wait_condition = SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; diff --git a/mysql-test/suite/galera/t/galera_var_notify_cmd-master.opt b/mysql-test/suite/galera/t/galera_var_notify_cmd-master.opt index 70dfc98736b..4d11610bff5 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_cmd-master.opt +++ b/mysql-test/suite/galera/t/galera_var_notify_cmd-master.opt @@ -1 +1 @@ ---wsrep_notify_cmd=$MYSQL_TEST_DIR/std_data/wsrep_notify.sh --wsrep-sync-wait=0 +--wsrep-sync-wait=0 diff --git a/mysql-test/suite/galera/t/galera_var_notify_cmd.cnf b/mysql-test/suite/galera/t/galera_var_notify_cmd.cnf new file mode 100644 index 00000000000..ee15122f4af --- /dev/null +++ b/mysql-test/suite/galera/t/galera_var_notify_cmd.cnf @@ -0,0 +1,11 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep_notify_cmd=@ENV.WSREP_NOTIFY_CMD + +[ENV] +WSREP_NOTIFY_CLIENT= @ENV.EXE_MYSQL +WSREP_NOTIFY_SCHEMA= mtr_wsrep_notify +WSREP_NOTIFY_PSWD= +WSREP_NOTIFY_HOST= 127.0.0.1 +WSREP_NOTIFY_PORT= @mysqld.1.port diff --git a/mysql-test/suite/galera/t/galera_var_notify_cmd.test b/mysql-test/suite/galera/t/galera_var_notify_cmd.test index fda61bf2914..acdc5255a77 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_cmd.test +++ b/mysql-test/suite/galera/t/galera_var_notify_cmd.test @@ -1,8 +1,13 @@ # -# Test wsrep_notify_cmd. We use a version of the support-files/wsrep_notify.sh script that writes -# notifications into a table. +# Test wsrep_notify_cmd. We use the support-files/wsrep_notify.sh script, which writes +# the current view into a table. # +if (!$WSREP_NOTIFY_CMD) +{ + --skip Needs the shipped wsrep_notify script +} + --source include/galera_cluster.inc --source include/force_restart.inc @@ -12,7 +17,7 @@ SELECT COUNT(DISTINCT uuid) AS EXPECT_2 FROM mtr_wsrep_notify.membership; SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status; -SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status; +SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE; # CLEANUP DROP SCHEMA mtr_wsrep_notify; diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt index 99c5889916b..4d11610bff5 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt +++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6-master.opt @@ -1 +1 @@ ---wsrep_notify_cmd=$MYSQL_TEST_DIR/std_data/wsrep_notify_ssl.sh --wsrep-sync-wait=0 +--wsrep-sync-wait=0 diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf index a8c2826ad0d..901d22045ec 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf +++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf @@ -11,6 +11,7 @@ wsrep_node_incoming_address='[::1]:@mysqld.1.port' wsrep_node_address=[::1]:@mysqld.1.#galera_port wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port' bind-address=:: +wsrep_notify_cmd=@ENV.WSREP_NOTIFY_CMD [mysqld.2] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' @@ -19,3 +20,13 @@ wsrep_node_incoming_address='[::1]:@mysqld.2.port' wsrep_node_address=[::1]:@mysqld.2.#galera_port wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port' bind-address=:: + +[ENV] +WSREP_NOTIFY_CLIENT= @ENV.EXE_MYSQL +WSREP_NOTIFY_SCHEMA= mtr_wsrep_notify +WSREP_NOTIFY_PSWD= +WSREP_NOTIFY_HOST= ::1 +WSREP_NOTIFY_PORT= @mysqld.1.port +WSREP_NOTIFY_SSL_CERT= @ENV.MYSQL_TEST_DIR/std_data/client-cert.pem +WSREP_NOTIFY_SSL_KEY= @ENV.MYSQL_TEST_DIR/std_data/client-key.pem +WSREP_NOTIFY_SSL_CA= @ENV.MYSQL_TEST_DIR/std_data/cacert.pem diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test index eaef34cce32..4abe916f8e4 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test +++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.test @@ -1,8 +1,13 @@ # -# Test wsrep_notify_cmd. We use a version of the support-files/wsrep_notify.sh script that writes -# notifications into a table. +# Test wsrep_notify_cmd. We use the support-files/wsrep_notify.sh script, which writes +# the current view into a table. # +if (!$WSREP_NOTIFY_CMD) +{ + --skip Needs the shipped wsrep_notify script +} + --let galera_connection_address=::1 --source include/galera_cluster.inc --source include/have_ssl_communication.inc @@ -15,7 +20,7 @@ SELECT COUNT(DISTINCT uuid) AS EXPECT_2 FROM mtr_wsrep_notify.membership; SELECT MAX(size) AS EXPECT_2 FROM mtr_wsrep_notify.status; -SELECT COUNT(DISTINCT idx) AS EXPECT_2 FROM mtr_wsrep_notify.status; +SELECT COUNT(*) AS EXPECT_1 FROM mtr_wsrep_notify.status, INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_INDEX' AND idx = VARIABLE_VALUE; # CLEANUP DROP SCHEMA mtr_wsrep_notify; diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test index c868e5e8e5b..a896abe4ade 100644 --- a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test @@ -60,7 +60,6 @@ SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't --connection node_4 SET SESSION wsrep_on=OFF; --source include/kill_galera.inc ---sleep 1 --echo Starting mysqld --source include/start_mysqld.inc diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test index 11c84d0c5d6..089cb5bfc42 100644 --- a/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test @@ -67,7 +67,6 @@ SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; --connection node_4 SET SESSION wsrep_on=OFF; --source include/kill_galera.inc ---sleep 1 --echo Starting mysqld --source include/start_mysqld.inc diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes.cnf b/mysql-test/suite/galera/t/galera_ws_datatypes.cnf new file mode 100644 index 00000000000..479c369b993 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes.cnf @@ -0,0 +1,9 @@ +!include ../galera_2nodes.cnf + +# +# Own configuration so that this test gets its own pair of servers. It parks +# a write set in front of the local monitor, and the next test in the worker +# would otherwise inherit the servers it used. +# +[mysqld] +wsrep-debug=1 diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes.test b/mysql-test/suite/galera/t/galera_ws_datatypes.test new file mode 100644 index 00000000000..feed1469c10 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes.test @@ -0,0 +1,751 @@ +# +# Galera write set keys across every data type MariaDB supports. +# +# MDEV-41073: a write set key whose collation weight form does not fit the +# 3500 byte key buffer. +# +# Three CHAR(255) utf8mb4_unicode_ci columns in a foreign key. U+FB04 is a +# ligature, one character of it expands to several collation weights, so the +# normalized form of the three columns is longer than the buffer. +# +# wsrep_store_key_val_for_row() cuts a row key that does not fit, but +# wsrep_rec_get_foreign_key() returned DB_ERROR for the same condition. The +# caller turned that into a fatal error and the server went down. +# +# Both paths now cut the key, and both tell the client that the key was cut. +# The condition is raised as a warning, which a statement running under +# strict mode turns into an error, so a statement whose key is cut reports +# ER_TOO_LONG_KEY. IGNORE and a non strict sql_mode leave it a warning and +# the row goes in. +# +# A cut key is not free: two rows whose key values are equal up to the cut +# get the same key and conflict in certification although they are different +# rows. The middle part of the test shows that. +# +# The rest of the test walks every data type built into the server through +# the same key-building code: as a primary key, as a unique key, as a plain +# key on a table with no primary key (the only case where wsrep certifies a +# non-unique key), as a foreign key referencing a primary key, and as a +# foreign key referencing a unique key. It also covers a foreign key with +# a NULL column, and the types that are excluded from some or all of that +# (TEXT/BLOB/JSON: prefix keys only, no foreign key; GEOMETRY: prefix keys +# only and no foreign key, except its fixed length POINT subtype, which +# takes a whole-column key but still no foreign key). +# +# UUID and INET6 come from the mandatory type_uuid and type_inet plugins +# rather than the server proper; galera_ws_datatypes_plugin.test covers +# them the same way. +# +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/galera_have_debug_sync.inc + +# The key is cut on whichever node builds it, so both error logs get the +# warning and both need the suppression. +--connection node_1 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +--connection node_2 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); + +--connection node_1 +CREATE TABLE p (a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + d INT, + PRIMARY KEY (a,b,c)) ENGINE=InnoDB; + +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, + a CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + b CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + c CHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + KEY k (a,b,c), + FOREIGN KEY (a,b,c) REFERENCES p (a,b,c)) ENGINE=InnoDB; + +# 255 ligature characters. Each one expands to several collation weights. +SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci; +# The same value with the last character replaced. Columns a and b already +# fill the buffer, so the difference is past the cut. +SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254), + _utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci; + +--echo # +--echo # Under strict mode a cut key fails the statement +--echo # +--error ER_TOO_LONG_KEY +INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v, 1); + +--echo # +--echo # INSERT IGNORE turns the error back into a warning and the row goes in +--echo # +INSERT IGNORE INTO p (a,b,c,d) VALUES (@v, @v, @v, 1); +SHOW WARNINGS; + +--echo # +--echo # The child row goes down the foreign key path and behaves the same. +--echo # Before the fix this statement took the server down with +--echo # "[FATAL] InnoDB: Unknown error Generic error". +--echo # +--error ER_TOO_LONG_KEY +INSERT INTO ch (a,b,c) VALUES (@v, @v, @v); + +INSERT IGNORE INTO ch (a,b,c) VALUES (@v, @v, @v); +SHOW WARNINGS; + +--echo # +--echo # Without strict mode the client also only gets the warning +--echo # +SET SESSION sql_mode = ''; + +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM ch; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +--echo # +--echo # A second parent row that differs only past the cut +--echo # +--connection node_1 +INSERT INTO p (a,b,c,d) VALUES (@v, @v, @v2, 2); +SELECT COUNT(*) AS EXPECT_2 FROM p; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM p; +--source include/wait_condition.inc +# User variables belong to one connection, set them here as well. +SET @v = REPEAT(_utf8mb4 0xEFAC84, 255) COLLATE utf8mb4_unicode_ci; +SET @v2 = CONCAT(REPEAT(_utf8mb4 0xEFAC84, 254), + _utf8mb4 0xEFAC80) COLLATE utf8mb4_unicode_ci; + +--echo # +--echo # An UPDATE under strict mode fails with the same error +--echo # +--connection node_1 +SET SESSION sql_mode = DEFAULT; +--error ER_TOO_LONG_KEY +UPDATE p SET d = 9 WHERE a = @v AND b = @v AND c = @v; + +--echo # +--echo # UPDATE IGNORE turns it back into a warning as well +--echo # +UPDATE IGNORE p SET d = 9 WHERE a = @v AND b = @v AND c = @v; +SHOW WARNINGS; + +--echo # +--echo # Without strict mode the same statement gets the warning and runs. +--echo # False positive. The two rows are different rows, but their keys are +--echo # equal up to the cut, so the transaction on node_1 loses +--echo # certification against the one on node_2. +--echo # +--connection node_1 +SET SESSION sql_mode = ''; +--connection node_2 +SET SESSION sql_mode = ''; + +# +# The write set of node_1 has to be replicated while the one from node_2 is +# still inside the certification interval of node_1, otherwise node_1 has +# already seen it and there is nothing left to certify against. Hold the +# write set from node_2 in front of the local monitor on node_1 until the +# commit on node_1 has been sent. +# +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = local_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +BEGIN; +UPDATE p SET d = 10 WHERE a = @v AND b = @v AND c = @v; + +--connection node_2 +UPDATE p SET d = 20 WHERE a = @v AND b = @v AND c = @v2; + +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = local_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--echo # Only the update from node_2 is there +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM p WHERE d = 20; +--source include/wait_condition.inc +SELECT d FROM p ORDER BY d; + +--echo # +--echo # Short values leave the key inside the buffer. The same pattern on +--echo # two different rows then commits. +--echo # +--connection node_1 +CREATE TABLE p2 (a CHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + d INT, + PRIMARY KEY (a)) ENGINE=InnoDB; +INSERT INTO p2 (a,d) VALUES ('aaaaaaaa', 1), ('aaaaaaab', 2); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM p2; +--source include/wait_condition.inc + +--connection node_1a +--let $galera_sync_point = local_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +--connection node_1 +BEGIN; +UPDATE p2 SET d = 10 WHERE a = 'aaaaaaaa'; + +--connection node_2 +UPDATE p2 SET d = 20 WHERE a = 'aaaaaaab'; + +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = local_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc + +--connection node_1 +--reap +--let $wait_condition = SELECT COUNT(*) = 1 FROM p2 WHERE d = 20; +--source include/wait_condition.inc +SELECT d FROM p2 ORDER BY d; + +--echo # +--echo # Foreign keys on the other string types. InnoDB needs the whole +--echo # column in a foreign key, so TEXT and BLOB cannot take part: they +--echo # can only be indexed by a prefix. That leaves VARCHAR, VARBINARY and +--echo # BINARY beside the CHAR columns above. +--echo # +--connection node_1 +SET SESSION sql_mode = DEFAULT; + +CREATE TABLE fp_v (a VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + b VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + c VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + d INT, + PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_v (id INT AUTO_INCREMENT PRIMARY KEY, + a VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + b VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + c VARCHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + KEY k (a,b,c), + FOREIGN KEY (a,b,c) REFERENCES fp_v (a,b,c)) ENGINE=InnoDB; + +--echo # VARCHAR parent, row key path +--error ER_TOO_LONG_KEY +INSERT INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1); +INSERT IGNORE INTO fp_v (a,b,c,d) VALUES (@v, @v, @v, 1); +SHOW WARNINGS; + +--echo # VARCHAR child, foreign key path +--error ER_TOO_LONG_KEY +INSERT INTO fc_v (a,b,c) VALUES (@v, @v, @v); +INSERT IGNORE INTO fc_v (a,b,c) VALUES (@v, @v, @v); +SHOW WARNINGS; + +--echo # BINARY and VARBINARY are not collated, so the key stays inside the +--echo # buffer and both statements run +CREATE TABLE fp_b (a BINARY(255), + b VARBINARY(1000), + c VARBINARY(1000), + d INT, + PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_b (id INT AUTO_INCREMENT PRIMARY KEY, + a BINARY(255), + b VARBINARY(1000), + c VARBINARY(1000), + KEY k (a,b,c), + FOREIGN KEY (a,b,c) REFERENCES fp_b (a,b,c)) ENGINE=InnoDB; + +SET @b255 = REPEAT('a', 255); +SET @b1000 = REPEAT('a', 1000); +INSERT INTO fp_b (a,b,c,d) VALUES (@b255, @b1000, @b1000, 1); +INSERT INTO fc_b (a,b,c) VALUES (@b255, @b1000, @b1000); + +--echo # TEXT and BLOB can only be indexed by a prefix, and InnoDB refuses a +--echo # foreign key on such a column +--error ER_CANT_CREATE_TABLE +CREATE TABLE fc_t (id INT AUTO_INCREMENT PRIMARY KEY, + a TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + KEY k (a(255)), + FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB; + +--echo # BLOB behaves the same way +--error ER_CANT_CREATE_TABLE +CREATE TABLE fc_bl (id INT AUTO_INCREMENT PRIMARY KEY, + a BLOB, + KEY k (a(255)), + FOREIGN KEY (a) REFERENCES fp_b (a)) ENGINE=InnoDB; + +--echo # JSON is stored as LONGTEXT and behaves the same way +--error ER_CANT_CREATE_TABLE +CREATE TABLE fc_j (id INT AUTO_INCREMENT PRIMARY KEY, + a JSON, + KEY k (a(255)), + FOREIGN KEY (a) REFERENCES fp_v (a)) ENGINE=InnoDB; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM fc_b; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM fp_v; +SELECT COUNT(*) AS EXPECT_1 FROM fc_v; +SELECT COUNT(*) AS EXPECT_1 FROM fp_b; +SELECT COUNT(*) AS EXPECT_1 FROM fc_b; + +--echo # +--echo # Foreign keys on FLOAT, DOUBLE, TIMESTAMP, DATE and DATETIME. These +--echo # are fixed width and not collated, so wsrep_store_key_val_for_row() +--echo # and wsrep_rec_get_foreign_key() never cut the key for them; the +--echo # point is to show the same key-building code path used above still +--echo # produces a working, replicated foreign key for these types. +--echo # +--connection node_1 +CREATE TABLE fp_num (a FLOAT, + b DOUBLE, + c TIMESTAMP, + dt DATE, + e DATETIME, + f INT, + PRIMARY KEY (a,b,c,dt,e)) ENGINE=InnoDB; +CREATE TABLE fc_num (id INT AUTO_INCREMENT PRIMARY KEY, + a FLOAT, + b DOUBLE, + c TIMESTAMP, + dt DATE, + e DATETIME, + KEY k (a,b,c,dt,e), + FOREIGN KEY (a,b,c,dt,e) + REFERENCES fp_num (a,b,c,dt,e)) ENGINE=InnoDB; + +INSERT INTO fp_num (a,b,c,dt,e,f) VALUES + (1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00', 1); +INSERT INTO fc_num (a,b,c,dt,e) VALUES + (1.5, 2.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00'); + +--echo # No matching parent row for this combination, the insert is rejected +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO fc_num (a,b,c,dt,e) VALUES + (9.5, 9.25, '2026-01-01 10:00:00', '2026-01-01', '2026-01-01 10:00:00'); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM fc_num; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM fp_num; +SELECT COUNT(*) AS EXPECT_1 FROM fc_num; + +--echo # +--echo # Foreign key where part of the key is NULL. InnoDB foreign keys use +--echo # MATCH SIMPLE: when any column of a multi-column foreign key is +--echo # NULL, the row is not checked against the parent at all, whether or +--echo # not a matching parent row exists. +--echo # +--connection node_1 +CREATE TABLE fp_n (a INT, b INT, c INT, d INT, + PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE fc_n (id INT AUTO_INCREMENT PRIMARY KEY, + a INT, b INT, c INT, + KEY k (a,b,c), + FOREIGN KEY (a,b,c) REFERENCES fp_n (a,b,c)) ENGINE=InnoDB; + +--echo # No parent row for (1,2,3) at all, but c is NULL so the row is +--echo # accepted anyway +INSERT INTO fc_n (a,b,c) VALUES (1,2,NULL); + +--echo # A parent row exists for (10,20,30), but the child is still not +--echo # checked against it because c is NULL +INSERT INTO fp_n (a,b,c,d) VALUES (10,20,30,1); +INSERT INTO fc_n (a,b,c) VALUES (10,20,NULL); + +--echo # A row with every foreign key column NULL is accepted the same way +INSERT INTO fc_n (a,b,c) VALUES (NULL,NULL,NULL); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 3 FROM fc_n; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM fp_n; +SELECT COUNT(*) AS EXPECT_3 FROM fc_n; + +--echo # +--echo # The same MATCH SIMPLE rule with only the last column of the +--echo # foreign key nullable, the other columns NOT NULL. Position does +--echo # not matter: any NULL column, first, middle or last, is enough to +--echo # skip the check. +--echo # +--connection node_1 +CREATE TABLE mfp (a INT, b INT, c INT, PRIMARY KEY (a,b,c)) ENGINE=InnoDB; +CREATE TABLE mfc (id INT AUTO_INCREMENT PRIMARY KEY, + a INT NOT NULL, b INT NOT NULL, c INT, + KEY k (a,b,c), + FOREIGN KEY (a,b,c) REFERENCES mfp (a,b,c)) ENGINE=InnoDB; + +INSERT INTO mfp VALUES (1,2,3); + +--echo # Last column (c) is NULL: no matching parent row required +INSERT INTO mfc (a,b,c) VALUES (9,9,NULL); + +--echo # Last column (c) is non-NULL and matches: the constraint is +--echo # checked and passes +INSERT INTO mfc (a,b,c) VALUES (1,2,3); + +--echo # Last column (c) is non-NULL and does not match: the constraint is +--echo # checked and fails +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO mfc (a,b,c) VALUES (1,2,99); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM mfc; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM mfp; +SELECT COUNT(*) AS EXPECT_2 FROM mfc; + +--echo # +--echo # Every remaining fixed width data type built into the server, in a +--echo # primary key, in a unique key, in a plain key on a table with no +--echo # primary key, and in a foreign key that references a primary key +--echo # and one that references a unique key. wsrep_store_key_val_for_row() +--echo # copies these types with a plain memcpy (TINYINT .. VARBINARY below) +--echo # or through the ENUM/SET branch that skips collation; FLOAT, DOUBLE, +--echo # TIMESTAMP, DATE and DATETIME were already covered above. UUID and +--echo # INET6 are in galera_ws_datatypes_plugin.test. +--echo # +--connection node_1 +CREATE TABLE g1_pk (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, + bi BIGINT, de DECIMAL(10,2), bt BIT(8), + bn BINARY(4), vb VARBINARY(8), f INT, + PRIMARY KEY (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; +CREATE TABLE g1_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, + ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, + bi BIGINT, de DECIMAL(10,2), bt BIT(8), + bn BINARY(4), vb VARBINARY(8), + KEY k (ti,si,mi,ii,bi,de,bt,bn,vb), + FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb) + REFERENCES g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb)) + ENGINE=InnoDB; +CREATE TABLE g1_uk (id INT AUTO_INCREMENT PRIMARY KEY, + ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, + bi BIGINT, de DECIMAL(10,2), bt BIT(8), + bn BINARY(4), vb VARBINARY(8), + UNIQUE KEY u (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; +CREATE TABLE g1_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, + ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, + bi BIGINT, de DECIMAL(10,2), bt BIT(8), + bn BINARY(4), vb VARBINARY(8), + KEY k (ti,si,mi,ii,bi,de,bt,bn,vb), + FOREIGN KEY (ti,si,mi,ii,bi,de,bt,bn,vb) + REFERENCES g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb)) + ENGINE=InnoDB; +CREATE TABLE g1_key (ti TINYINT, si SMALLINT, mi MEDIUMINT, ii INT, + bi BIGINT, de DECIMAL(10,2), bt BIT(8), + bn BINARY(4), vb VARBINARY(8), + KEY k (ti,si,mi,ii,bi,de,bt,bn,vb)) ENGINE=InnoDB; + +--echo # TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, DECIMAL, BIT, BINARY, +--echo # VARBINARY together, in a primary key and a foreign key that +--echo # references it +INSERT INTO g1_pk (ti,si,mi,ii,bi,de,bt,bn,vb,f) + VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh',1); +INSERT INTO g1_pk_child (ti,si,mi,ii,bi,de,bt,bn,vb) + VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); + +--echo # The same types in a unique key and a foreign key that references it +INSERT INTO g1_uk (ti,si,mi,ii,bi,de,bt,bn,vb) + VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); +INSERT INTO g1_uk_child (ti,si,mi,ii,bi,de,bt,bn,vb) + VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); + +--echo # The same types in a plain, non-unique key on a table with no +--echo # primary key +INSERT INTO g1_key (ti,si,mi,ii,bi,de,bt,bn,vb) + VALUES (1,2,3,4,5,6.50,5,'ab','abcdefgh'); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM g1_key; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM g1_pk; +SELECT COUNT(*) AS EXPECT_1 FROM g1_pk_child; +SELECT COUNT(*) AS EXPECT_1 FROM g1_uk; +SELECT COUNT(*) AS EXPECT_1 FROM g1_uk_child; +SELECT COUNT(*) AS EXPECT_1 FROM g1_key; + +--echo # +--echo # TIME, YEAR, ENUM and SET, the same way. UUID and INET6 are provided +--echo # by the mandatory type_uuid and type_inet plugins rather than being +--echo # built into the server proper; they are covered by +--echo # galera_ws_datatypes_plugin.test instead. +--echo # +--connection node_1 +CREATE TABLE g2_pk (tm TIME, yr YEAR, en ENUM('a','b','c'), + st SET('a','b','c'), f INT, + PRIMARY KEY (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, + tm TIME, yr YEAR, en ENUM('a','b','c'), + st SET('a','b','c'), + KEY k (tm,yr,en,st), + FOREIGN KEY (tm,yr,en,st) + REFERENCES g2_pk (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_uk (id INT AUTO_INCREMENT PRIMARY KEY, + tm TIME, yr YEAR, en ENUM('a','b','c'), + st SET('a','b','c'), + UNIQUE KEY u (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, + tm TIME, yr YEAR, en ENUM('a','b','c'), + st SET('a','b','c'), + KEY k (tm,yr,en,st), + FOREIGN KEY (tm,yr,en,st) + REFERENCES g2_uk (tm,yr,en,st)) ENGINE=InnoDB; +CREATE TABLE g2_key (tm TIME, yr YEAR, en ENUM('a','b','c'), + st SET('a','b','c'), + KEY k (tm,yr,en,st)) ENGINE=InnoDB; + +INSERT INTO g2_pk (tm,yr,en,st,f) + VALUES ('10:00:00',2026,'b','a,c',1); +INSERT INTO g2_pk_child (tm,yr,en,st) + VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_uk (tm,yr,en,st) + VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_uk_child (tm,yr,en,st) + VALUES ('10:00:00',2026,'b','a,c'); +INSERT INTO g2_key (tm,yr,en,st) + VALUES ('10:00:00',2026,'b','a,c'); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM g2_key; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM g2_pk; +SELECT COUNT(*) AS EXPECT_1 FROM g2_pk_child; +SELECT COUNT(*) AS EXPECT_1 FROM g2_uk; +SELECT COUNT(*) AS EXPECT_1 FROM g2_uk_child; +SELECT COUNT(*) AS EXPECT_1 FROM g2_key; + +--echo # +--echo # SERIAL, an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, +--echo # as a primary key +--echo # +--connection node_1 +CREATE TABLE g_serial (id SERIAL PRIMARY KEY, f INT) ENGINE=InnoDB; +INSERT INTO g_serial (f) VALUES (1); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM g_serial; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM g_serial; + +--echo # +--echo # Other string types and prefix indexes outside a foreign key. The +--echo # indexes are +--echo # unique because wsrep_append_keys() only builds a key for a unique +--echo # index, one referenced by a foreign key, or any index of a table +--echo # without a primary key. The key is cut when the collation weights of +--echo # the indexed bytes pass the buffer; the binary types are not +--echo # collated, so they never are. +--echo # +--connection node_1 +SET SESSION sql_mode = DEFAULT; + +SET @c200 = REPEAT(_utf8mb4 0xEFAC84, 200) COLLATE utf8mb4_unicode_ci; +SET @c768 = REPEAT(_utf8mb4 0xEFAC84, 768) COLLATE utf8mb4_unicode_ci; +SET @bin255 = REPEAT('a', 255); +SET @bin3000 = REPEAT('a', 3000); + +CREATE TABLE k1 (id INT AUTO_INCREMENT PRIMARY KEY, + v VARCHAR(768) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (v)) ENGINE=InnoDB; +CREATE TABLE k2 (id INT AUTO_INCREMENT PRIMARY KEY, + t TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k3 (id INT AUTO_INCREMENT PRIMARY KEY, + c CHAR(255) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (c(200))) ENGINE=InnoDB; +CREATE TABLE k4 (id INT AUTO_INCREMENT PRIMARY KEY, + v VARCHAR(768) CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (v(700))) ENGINE=InnoDB; +CREATE TABLE k5 (id INT AUTO_INCREMENT PRIMARY KEY, + b BLOB, + UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k6 (id INT AUTO_INCREMENT PRIMARY KEY, + bn BINARY(255), + vb VARBINARY(3000), + UNIQUE KEY (bn), + UNIQUE KEY (vb(3000))) ENGINE=InnoDB; +CREATE TABLE k7 (id INT AUTO_INCREMENT PRIMARY KEY, + t TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (t(50))) ENGINE=InnoDB; +CREATE TABLE k8 (id INT AUTO_INCREMENT PRIMARY KEY, + t MEDIUMTEXT CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k9 (id INT AUTO_INCREMENT PRIMARY KEY, + t LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + UNIQUE KEY (t(768))) ENGINE=InnoDB; +CREATE TABLE k10 (id INT AUTO_INCREMENT PRIMARY KEY, + b TINYBLOB, + UNIQUE KEY (b(50))) ENGINE=InnoDB; +CREATE TABLE k11 (id INT AUTO_INCREMENT PRIMARY KEY, + b MEDIUMBLOB, + UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k12 (id INT AUTO_INCREMENT PRIMARY KEY, + b LONGBLOB, + UNIQUE KEY (b(3000))) ENGINE=InnoDB; +CREATE TABLE k13 (id INT AUTO_INCREMENT PRIMARY KEY, + j JSON, + UNIQUE KEY (j(768))) ENGINE=InnoDB; + +--echo # VARCHAR, whole column +--error ER_TOO_LONG_KEY +INSERT INTO k1 (v) VALUES (@c768); + +--echo # TEXT, prefix +--error ER_TOO_LONG_KEY +INSERT INTO k2 (t) VALUES (@c768); + +--echo # CHAR, prefix short enough to stay inside the buffer +INSERT INTO k3 (c) VALUES (@c200); + +--echo # VARCHAR, prefix +--error ER_TOO_LONG_KEY +INSERT INTO k4 (v) VALUES (@c768); + +--echo # BLOB, prefix. Bytes are not collated, so nothing is cut +INSERT INTO k5 (b) VALUES (@bin3000); + +--echo # BINARY and VARBINARY, whole column and prefix +INSERT INTO k6 (bn, vb) VALUES (@bin255, @bin3000); + +SET @tiny = REPEAT('a', 50); + +--echo # TINYTEXT, prefix short enough to stay inside the buffer +INSERT INTO k7 (t) VALUES (@tiny); + +--echo # MEDIUMTEXT, prefix short enough to stay inside the buffer +INSERT INTO k8 (t) VALUES (@c200); + +--echo # LONGTEXT, prefix short enough to stay inside the buffer +INSERT INTO k9 (t) VALUES (@c200); + +--echo # TINYBLOB, prefix. Bytes are not collated, so nothing is cut +INSERT INTO k10 (b) VALUES (@tiny); + +--echo # MEDIUMBLOB, prefix +INSERT INTO k11 (b) VALUES (@bin3000); + +--echo # LONGBLOB, prefix +INSERT INTO k12 (b) VALUES (@bin3000); + +--echo # JSON, stored as LONGTEXT with a validity check, prefix +INSERT INTO k13 (j) VALUES ('{"a":1}'); + +--echo # Without strict mode the cut ones go in with a warning +SET SESSION sql_mode = ''; +INSERT INTO k1 (v) VALUES (@c768); +SHOW WARNINGS; +INSERT INTO k2 (t) VALUES (@c768); +SHOW WARNINGS; +INSERT INTO k4 (v) VALUES (@c768); +SHOW WARNINGS; +SET SESSION sql_mode = DEFAULT; + +--echo # The rows the server accepted reach node_2 +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM k6; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM k1; +SELECT COUNT(*) AS EXPECT_1 FROM k2; +SELECT COUNT(*) AS EXPECT_1 FROM k3; +SELECT COUNT(*) AS EXPECT_1 FROM k4; +SELECT COUNT(*) AS EXPECT_1 FROM k5; +SELECT COUNT(*) AS EXPECT_1 FROM k6; +SELECT COUNT(*) AS EXPECT_1 FROM k7; +SELECT COUNT(*) AS EXPECT_1 FROM k8; +SELECT COUNT(*) AS EXPECT_1 FROM k9; +SELECT COUNT(*) AS EXPECT_1 FROM k10; +SELECT COUNT(*) AS EXPECT_1 FROM k11; +SELECT COUNT(*) AS EXPECT_1 FROM k12; +SELECT COUNT(*) AS EXPECT_1 FROM k13; + +--echo # +--echo # GEOMETRY is stored as BLOB and behaves the same way: a key needs an +--echo # explicit prefix length, and a foreign key is rejected regardless of +--echo # length. POINT is fixed length (an SRID plus one X/Y pair), so it can +--echo # be a whole-column primary or unique key without a prefix, but a +--echo # foreign key on it is still rejected. +--echo # +--connection node_1 +--error ER_BLOB_KEY_WITHOUT_LENGTH +CREATE TABLE g_pk (g GEOMETRY NOT NULL, PRIMARY KEY (g)) ENGINE=InnoDB; + +CREATE TABLE g_uk (id INT AUTO_INCREMENT PRIMARY KEY, + g GEOMETRY NOT NULL, UNIQUE KEY (g(25))) ENGINE=InnoDB; +INSERT INTO g_uk (g) VALUES (ST_PointFromText('POINT(1 1)')); + +--error ER_CANT_CREATE_TABLE +CREATE TABLE g_fk (id INT AUTO_INCREMENT PRIMARY KEY, + g GEOMETRY, + KEY k (g(25)), + FOREIGN KEY (g) REFERENCES g_uk (g)) ENGINE=InnoDB; + +CREATE TABLE g_pk2 (p POINT NOT NULL, PRIMARY KEY (p)) ENGINE=InnoDB; +INSERT INTO g_pk2 (p) VALUES (ST_PointFromText('POINT(1 1)')); + +CREATE TABLE g_uk2 (id INT AUTO_INCREMENT PRIMARY KEY, + p POINT NOT NULL, UNIQUE KEY (p)) ENGINE=InnoDB; +INSERT INTO g_uk2 (p) VALUES (ST_PointFromText('POINT(1 1)')); + +--error ER_CANT_CREATE_TABLE +CREATE TABLE g_fk2 (id INT AUTO_INCREMENT PRIMARY KEY, + p POINT, + KEY k (p), + FOREIGN KEY (p) REFERENCES g_pk2 (p)) ENGINE=InnoDB; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM g_uk2; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM g_uk; +SELECT COUNT(*) AS EXPECT_1 FROM g_pk2; +SELECT COUNT(*) AS EXPECT_1 FROM g_uk2; + +--connection node_1 +DROP TABLE ch, p; +DROP TABLE p2; +DROP TABLE fc_v, fp_v; +DROP TABLE fc_b, fp_b; +DROP TABLE fc_num, fp_num; +DROP TABLE fc_n, fp_n; +DROP TABLE mfc, mfp; +DROP TABLE g1_pk_child, g1_pk, g1_uk_child, g1_uk, g1_key; +DROP TABLE g2_pk_child, g2_pk, g2_uk_child, g2_uk, g2_key; +DROP TABLE g_serial; +DROP TABLE g_uk, g_pk2, g_uk2; +DROP TABLE k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13; +--disconnect node_1a + +--source include/galera_end.inc +--echo # End of test diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes_fixed_length.test b/mysql-test/suite/galera/t/galera_ws_datatypes_fixed_length.test new file mode 100644 index 00000000000..271db67b4a5 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes_fixed_length.test @@ -0,0 +1,76 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# MDEV-41073 follow-up: a write set key that cuts a fixed-length column. +# +# wsrep_rec_get_foreign_key() cuts a column that does not fully fit the +# write set key buffer, the same way the row key builder cuts a string. +# A whole number, a float or a double is read out of the record and +# copied as one unit, so cutting it does not produce a shorter version +# of the value, it produces a different one, or, for a float or double, +# not even a valid one: mach_float_read()/mach_double_read() read a +# fixed 4 or 8 bytes regardless of how much of that was actually meant +# to be copied. +# +# Column a below normalizes to exactly 3492 of the 3500 byte buffer +# (582 copies of a ligature character that each normalize to 6 collation +# weight bytes under utf8mb4_unicode_ci), column m takes another 5, which +# leaves exactly 3 bytes for column c, a 4 byte FLOAT: not enough to hold +# it, but enough that the old code cut it to 3 bytes anyway. +# + +--connection node_1 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); +--connection node_2 +call mtr.add_suppression("WSREP: Write set key for table .* was cut to"); + +--connection node_1 +CREATE TABLE p (a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + m VARBINARY(8) NOT NULL, + c FLOAT NOT NULL, + PRIMARY KEY (a,m,c)) ENGINE=InnoDB; + +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, + a VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + m VARBINARY(8) NOT NULL, + c FLOAT NOT NULL, + KEY k (a,m,c), + FOREIGN KEY (a,m,c) REFERENCES p (a,m,c)) ENGINE=InnoDB; + +SET @v = REPEAT(_utf8mb4 0xEFAC84, 582) COLLATE utf8mb4_unicode_ci; + +--echo # +--echo # Under strict mode a cut key fails the statement +--echo # +--error ER_TOO_LONG_KEY +INSERT INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5); + +--echo # +--echo # INSERT IGNORE turns the error back into a warning and the row goes in +--echo # +INSERT IGNORE INTO p (a,m,c) VALUES (@v, 0x0102030405, 1.5); +SHOW WARNINGS; + +--echo # +--echo # The child row goes down the foreign key path and behaves the same. +--echo # Before the fix this statement took the server down with +--echo # "Assertion `len == sizeof(float)' failed." +--echo # +--error ER_TOO_LONG_KEY +INSERT INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5); + +INSERT IGNORE INTO ch (a,m,c) VALUES (@v, 0x0102030405, 1.5); +SHOW WARNINGS; + +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM ch; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +--connection node_1 +DROP TABLE ch, p; diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.cnf b/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.cnf new file mode 100644 index 00000000000..fa33b09d739 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.cnf @@ -0,0 +1 @@ +!include ../galera_2nodes.cnf diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.test b/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.test new file mode 100644 index 00000000000..1e381d183f4 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes_plugin.test @@ -0,0 +1,66 @@ +# +# Galera write set keys for the data types that come from a plugin rather +# than the server proper: UUID and INET6, from the mandatory type_uuid and +# type_inet plugins. See galera_ws_datatypes.test for every type built into +# the server. +# +# wsrep_store_key_val_for_row() and wsrep_rec_get_foreign_key() skip +# collation for these types (MDEV-41012): Field_fbt based types report +# type() == MYSQL_TYPE_STRING and a numeric (non-collated) charset, but +# store plain binary bytes, which InnoDB maps to DATA_FIXBINARY. This walks +# both types through a primary key, a unique key, a plain key on a table +# with no primary key, a foreign key referencing a primary key, and a +# foreign key referencing a unique key. +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connection node_1 +CREATE TABLE gp_pk (uu UUID, i6 INET6, f INT, + PRIMARY KEY (uu,i6)) ENGINE=InnoDB; +CREATE TABLE gp_pk_child (id INT AUTO_INCREMENT PRIMARY KEY, + uu UUID, i6 INET6, + KEY k (uu,i6), + FOREIGN KEY (uu,i6) REFERENCES gp_pk (uu,i6)) + ENGINE=InnoDB; +CREATE TABLE gp_uk (id INT AUTO_INCREMENT PRIMARY KEY, + uu UUID, i6 INET6, + UNIQUE KEY u (uu,i6)) ENGINE=InnoDB; +CREATE TABLE gp_uk_child (id INT AUTO_INCREMENT PRIMARY KEY, + uu UUID, i6 INET6, + KEY k (uu,i6), + FOREIGN KEY (uu,i6) REFERENCES gp_uk (uu,i6)) + ENGINE=InnoDB; +CREATE TABLE gp_key (uu UUID, i6 INET6, + KEY k (uu,i6)) ENGINE=InnoDB; + +SET @uu = '11111111-1111-1111-1111-111111111111'; +SET @i6 = '2001:db8::1'; + +--echo # UUID and INET6 together, in a primary key and a foreign key that +--echo # references it +INSERT INTO gp_pk (uu,i6,f) VALUES (@uu,@i6,1); +INSERT INTO gp_pk_child (uu,i6) VALUES (@uu,@i6); + +--echo # The same types in a unique key and a foreign key that references it +INSERT INTO gp_uk (uu,i6) VALUES (@uu,@i6); +INSERT INTO gp_uk_child (uu,i6) VALUES (@uu,@i6); + +--echo # The same types in a plain, non-unique key on a table with no +--echo # primary key +INSERT INTO gp_key (uu,i6) VALUES (@uu,@i6); + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM gp_key; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM gp_pk; +SELECT COUNT(*) AS EXPECT_1 FROM gp_pk_child; +SELECT COUNT(*) AS EXPECT_1 FROM gp_uk; +SELECT COUNT(*) AS EXPECT_1 FROM gp_uk_child; +SELECT COUNT(*) AS EXPECT_1 FROM gp_key; + +--connection node_1 +DROP TABLE gp_pk_child, gp_pk, gp_uk_child, gp_uk, gp_key; + +--source include/galera_end.inc +--echo # End of test diff --git a/mysql-test/suite/galera/t/galera_ws_datatypes_varchar_cap.test b/mysql-test/suite/galera/t/galera_ws_datatypes_varchar_cap.test new file mode 100644 index 00000000000..6b3b8f71d84 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_ws_datatypes_varchar_cap.test @@ -0,0 +1,53 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# MDEV-41073 follow-up: a VARCHAR write set key cut at the wrong limit. +# +# wsrep_store_key_val_for_row() normalized a VARCHAR column's collation +# weights up to REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes, while +# wsrep_rec_get_foreign_key() normalized the same column up to +# WSREP_MAX_SUPPORTED_KEY_LENGTH (3500) bytes, through +# wsrep_store_string_key_val(). For a value whose normalized form falls +# between 3072 and 3500 bytes, the two functions produced a different +# key for the very same column value: one cut it, the other did not. +# +# CHAR does not have this problem: both functions normalize a CHAR +# column through wsrep_store_string_key_val(), so both already agreed +# at the 3500 byte limit. +# +# Column a below normalizes to exactly 550*6 = 3300 bytes (550 copies +# of a ligature character that each normalize to 6 collation weight +# bytes under utf8mb4_unicode_ci): past the old 3072 byte limit, but +# under the 3500 byte one both functions now share. +# + +--connection node_1 +CREATE TABLE p (a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci PRIMARY KEY) ENGINE=InnoDB; + +CREATE TABLE ch (id INT AUTO_INCREMENT PRIMARY KEY, + a VARCHAR(550) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + KEY k (a), + FOREIGN KEY (a) REFERENCES p (a)) ENGINE=InnoDB; + +SET @v = REPEAT(_utf8mb4 0xEFAC84, 550) COLLATE utf8mb4_unicode_ci; + +INSERT INTO p (a) VALUES (@v); +INSERT INTO ch (a) VALUES (@v); + +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM ch; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_1 FROM p; +SELECT COUNT(*) AS EXPECT_1 FROM ch; + +UPDATE p SET a = a WHERE a = @v; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM p; +--source include/wait_condition.inc + +DROP TABLE ch, p; diff --git a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test index 000f91c8bbc..2de79fccd22 100644 --- a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test +++ b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test @@ -8,6 +8,10 @@ # This is needed because we use wsrep-new-cluster --source include/have_perfschema.inc +# Make sure that the test is operating on the right version of galera library. +--let $galera_version=26.4.28 +source ../wsrep/include/check_galera_version.inc; + # Save original auto_increment_offset values. --let $node_1=node_1 --let $node_2=node_2 @@ -86,6 +90,11 @@ SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME --echo Starting server ... --let $start_mysqld_params= +# Rejoining with an emptied datadir requires a full SST. That is much slower +# than a plain restart and on a loaded machine it does not finish within the +# default 60 seconds, which used to abort the test here while the SST was +# still running. +--let $galera_wait_ready_timeout=300 --source include/start_mysqld.inc --source include/wait_until_ready.inc diff --git a/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.cnf b/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.cnf new file mode 100644 index 00000000000..ca6a0f2b4fd --- /dev/null +++ b/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.cnf @@ -0,0 +1,8 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +wsrep_notify_cmd=@ENV.WSREP_NOTIFY_CMD + +[ENV] +WSREP_NOTIFY_CLIENT= @ENV.MYSQL_TEST_DIR/std_data/wsrep_notify_argv_recorder.sh +WSREP_NOTIFY_PSWD=x' y='z diff --git a/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.test b/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.test new file mode 100644 index 00000000000..59a9ff409d8 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_wsrep_notify_pwd_injection.test @@ -0,0 +1,38 @@ +# +# A configured wsrep_notify_cmd password containing an apostrophe and a +# space must reach the client intact, as a single value, not split into +# two arguments or otherwise reinterpreted. +# +# STEPS: +# - node 1's wsrep_notify_cmd is configured with such a password, and a +# fake argv-recording client instead of a real mysql client +# - wait for the 2-node cluster to fully form (node 1 reaches Synced) +# - check that the notify script passes the password intact via +# MYSQL_PWD, and that it never appears in argv at all +# + +if (!$WSREP_NOTIFY_CMD) +{ + --skip Needs the shipped wsrep_notify script +} + +--source include/galera_cluster.inc +--source include/force_restart.inc + +--connection node_1 +SELECT 1; + +--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'WSREP_LOCAL_STATE_COMMENT' +--source include/wait_condition.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--sleep 2 + +--let $argv_file = $MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.argv +--let $env_file = $MYSQLTEST_VARDIR/tmp/wsrep_notify_pwd_injection.env +cat_file $argv_file; +cat_file $env_file; +--remove_file $argv_file +--remove_file $env_file diff --git a/mysql-test/suite/galera/t/mdev-41075.cnf b/mysql-test/suite/galera/t/mdev-41075.cnf new file mode 100644 index 00000000000..9abeeb1b4d3 --- /dev/null +++ b/mysql-test/suite/galera/t/mdev-41075.cnf @@ -0,0 +1,26 @@ +!include ../galera_2nodes_as_slave.cnf + +[mysqld] +log-bin=mysqld-bin +log-slave-updates +gtid_strict_mode=1 +wsrep-debug=1 + +[mysqld.1] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +wsrep-slave-threads=4 +slave-parallel-threads=4 +slave-parallel-mode=aggressive + +[mysqld.2] +wsrep_gtid_mode=1 +wsrep_gtid_domain_id=16 +gtid_domain_id=11 +wsrep-slave-threads=4 +slave-parallel-threads=4 +slave-parallel-mode=aggressive + +[mysqld.3] +gtid_domain_id=3 diff --git a/mysql-test/suite/galera/t/mdev-41075.test b/mysql-test/suite/galera/t/mdev-41075.test new file mode 100644 index 00000000000..0bab0bf0b86 --- /dev/null +++ b/mysql-test/suite/galera/t/mdev-41075.test @@ -0,0 +1,72 @@ +# +# Stress the store_gtid_event() in_ddl path: DDL carrying a foreign domain +# GTID, applied as TOI on a Galera node whose mysql.gtid_slave_pos is InnoDB, +# so record_gtid() runs against a transactional table. +# +--source include/have_innodb.inc +--source include/have_log_bin.inc +--source include/galera_cluster.inc + +--connect primary, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +--connection node_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='gtid_slave_pos' AND ENGINE='InnoDB'; +--source include/wait_condition.inc +--connection node_2 +--source include/wait_condition.inc + +--connection node_1 +--disable_query_log +--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos; +--enable_query_log +START SLAVE; + +--echo # Many foreign-domain DDLs, each applied as TOI on node_2 +--connection primary +--disable_query_log +CREATE TABLE base (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB; +--let $i= 0 +while ($i < 150) +{ + --eval CREATE TABLE d$i (f1 INT PRIMARY KEY) ENGINE=InnoDB + --eval INSERT INTO base VALUES ($i, $i) + --eval ALTER TABLE d$i ADD COLUMN f2 INT + --eval DROP TABLE d$i + --inc $i +} +--enable_query_log + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 150 FROM base; +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_150 FROM base; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 150 FROM base; +--source include/wait_condition.inc + +--connection primary +DROP TABLE base; +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='base'; +--source include/wait_condition.inc +STOP SLAVE; +RESET SLAVE ALL; +SET GLOBAL wsrep_on = OFF; +RESET MASTER; +SET GLOBAL wsrep_on = ON; +SET GLOBAL gtid_slave_pos = ""; +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='base'; +--source include/wait_condition.inc +SET GLOBAL wsrep_on = OFF; +RESET MASTER; +SET GLOBAL wsrep_on = ON; +SET GLOBAL gtid_slave_pos = ""; +--connection primary +RESET MASTER; +--connection node_1 +--disconnect primary +--source include/galera_end.inc +--echo # End of test diff --git a/mysql-test/suite/galera/t/mysql-wsrep#198.test b/mysql-test/suite/galera/t/mysql-wsrep#198.test index 57b2b3ac958..30c4063e49c 100644 --- a/mysql-test/suite/galera/t/mysql-wsrep#198.test +++ b/mysql-test/suite/galera/t/mysql-wsrep#198.test @@ -1,5 +1,6 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--source include/have_debug_sync.inc CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB; @@ -12,26 +13,51 @@ LOCK TABLE t2 WRITE; --connect node_2_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2_ctrl -SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_sync_wait = 0; + +# +# Both DDLs below have to be parked before we release the table lock, and +# OPTIMIZE has to enter total order isolation before REPAIR asks for it, so +# that the two queue up in a known order. +# +# Neither state can be observed through INFORMATION_SCHEMA.PROCESSLIST: +# +# - "acquiring total order isolation" is set with thd_proc_info() in +# wsrep_TOI_begin() and overwritten by THD_STAGE_INFO() two lines later, +# so it never reaches the process list at all. +# +# - while a statement waits for a metadata lock, MDL_context::acquire_lock() +# waits in one second slices, and the thread state alternates between +# "Waiting for table metadata lock" (inside the wait) and the stage that +# is restored when the wait is left, which for a statement that already +# holds total order isolation is "Waiting for TOI DDL". +# +# Use the debug sync points instead. +# --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2a +# OPTIMIZE enters total order isolation and then blocks on the metadata +# lock for t2 held by the LOCK TABLE above. mdl_acquire_lock_wait is +# reached only after the waiting ticket has been queued, so it tells us +# the statement is parked for good. +SET DEBUG_SYNC = 'mdl_acquire_lock_wait SIGNAL optimize_blocked'; --send OPTIMIZE TABLE t1,t2; --connection node_2_ctrl -SET SESSION wsrep_sync_wait = 0; ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'acquiring total order isolation%' OR STATE LIKE 'Waiting to execute in isolation%'; ---let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST ---source include/wait_condition_with_debug_and_kill.inc +SET DEBUG_SYNC = 'now WAIT_FOR optimize_blocked'; --connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2b +# REPAIR cannot be granted total order isolation while OPTIMIZE holds it, +# so it parks inside wsrep_TOI_begin(). wsrep_before_toi_begin is the last +# point reached before that. +SET DEBUG_SYNC = 'wsrep_before_toi_begin SIGNAL repair_at_toi'; --send REPAIR TABLE t1,t2; --connection node_2_ctrl ---let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for table metadata lock%' OR STATE LIKE 'acquiring total order isolation%' OR STATE LIKE 'Waiting to execute in isolation%'; ---let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST ---source include/wait_condition_with_debug_and_kill.inc +SET DEBUG_SYNC = 'now WAIT_FOR repair_at_toi'; +SET DEBUG_SYNC = 'RESET'; --connection node_1 # We have LOCK TABLE in node_2 so this could fail on lock wait @@ -44,9 +70,11 @@ UNLOCK TABLES; --connection node_2a --reap +SET DEBUG_SYNC = 'RESET'; --connection node_2b --reap +SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.test b/mysql-test/suite/galera_3nodes/t/GCF-354.test index db4f32fccf9..e5602d48d32 100644 --- a/mysql-test/suite/galera_3nodes/t/GCF-354.test +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.test @@ -56,7 +56,6 @@ SHOW STATUS LIKE 'wsrep_cluster_status'; --source include/kill_galera.inc --connection node_2 ---source include/wait_until_disconnected.inc --echo Starting node_2 --source include/start_mysqld.inc @@ -73,7 +72,6 @@ SHOW STATUS LIKE 'wsrep_cluster_status'; --source include/kill_galera.inc --connection node_3 ---source include/wait_until_disconnected.inc --echo Starting node_3 --source include/start_mysqld.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera-features#119.test b/mysql-test/suite/galera_3nodes/t/galera-features#119.test index bf5c31e4faf..6f5fbd9dcdb 100644 --- a/mysql-test/suite/galera_3nodes/t/galera-features#119.test +++ b/mysql-test/suite/galera_3nodes/t/galera-features#119.test @@ -56,7 +56,6 @@ DROP TABLE test.t1; # reconnect node 2, since it is now inconsistent --connection node_2 --source include/kill_galera.inc ---source include/wait_until_disconnected.inc --source include/start_mysqld.inc --connection node_2 diff --git a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test index 8c2f659aa26..d3777613665 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test +++ b/mysql-test/suite/galera_3nodes/t/galera_safe_to_bootstrap.test @@ -125,7 +125,7 @@ SET SESSION wsrep_on = OFF; --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc ---source ../galera/include/kill_galera.inc +--source include/kill_galera.inc # # Only node #1 should have safe_to_bootstrap: 1 diff --git a/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test index bd53c510cd4..eb80fc7a421 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test +++ b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test @@ -57,7 +57,6 @@ SET SESSION wsrep_sync_wait=0; # reconnect node 3, since it failed --source include/kill_galera.inc ---source include/wait_until_disconnected.inc --source include/start_mysqld.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_after_apply_rollback2.test b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_after_apply_rollback2.test index b32eafe5e9c..5875500a822 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_after_apply_rollback2.test +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_after_apply_rollback2.test @@ -35,7 +35,6 @@ SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; --source include/wait_condition.inc --source include/kill_galera.inc ---sleep 1 --connection node_1 INSERT INTO t1 VALUES (6); diff --git a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_nobootstrap.test b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_nobootstrap.test index 8fba27f9a73..5e3ccf251c5 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_nobootstrap.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_nobootstrap.test @@ -25,8 +25,6 @@ INSERT INTO t1 VALUES (5); --connection node_1 --source include/kill_galera.inc ---sleep 1 - # Bootstrap the cluster from scratch --connection node_1 diff --git a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_pcrecovery.test b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_pcrecovery.test index 0ba7cedbd8f..838cb62bc98 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_pcrecovery.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_pcrecovery.test @@ -25,8 +25,6 @@ INSERT INTO t1 VALUES (5); --connection node_1 --source include/kill_galera.inc ---sleep 1 - # Bootstrap the cluster from scratch --connection node_1 diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug.result b/mysql-test/suite/gcol/r/innodb_virtual_debug.result index 7dfc48b9630..3bf189434c4 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug.result @@ -147,4 +147,53 @@ DROP TABLE t1; disconnect con1; connection default; SET DEBUG_SYNC=RESET; +# +# MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value +# +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (),(); +connect con1,localhost,root,,test; +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +SET GLOBAL innodb_max_purge_lag_wait= 0; +FLUSH TABLES t1; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +DELETE FROM t1; +connection default; +SET debug_sync= "now WAIT_FOR delete_open"; +SELECT a FROM t1; +a +NULL +NULL +SET debug_sync= "now SIGNAL another_open"; +connection con1; +disconnect con1; +connection default; +SET debug_sync= "RESET"; +DROP TABLE t1; +# +# MDEV-26057 Assertion `!vcol->v_indexes.empty() in trx_undo_log_v_idx +# +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +f3 INT AS (f2) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, 1); +SET DEBUG_SYNC="alter_rollback_complete SIGNAL dml_start WAIT_FOR default_resume"; +set STATEMENT DEBUG_DBUG="d,innodb_OOM_inplace_alter" FOR alter table t1 add index(f3), algorithm=inplace; +connect con1,localhost,root,,,; +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +INSERT INTO t1(f1, f2) VALUES(2, 2); +SET DEBUG_SYNC="now SIGNAL default_resume"; +connection default; +ERROR HY000: Out of memory. +connection default; +disconnect con1; +SET DEBUG_SYNC="RESET"; +SELECT * FROM t1; +f1 f2 f3 +1 1 1 +2 2 2 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +# End of 11.4 tests SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug.test b/mysql-test/suite/gcol/t/innodb_virtual_debug.test index 6d28383ae9e..4d43649a97e 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug.test @@ -341,4 +341,60 @@ DROP TABLE t1; connection default; SET DEBUG_SYNC=RESET; +--echo # +--echo # MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value +--echo # +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; + +INSERT INTO t1 () VALUES (),(); +--connect (con1,localhost,root,,test) +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +# Purge may open t1 and leave TABLE in cache, then DELETE skips ha_innobase::open. +# Setting innodb_max_purge_lag_wait to 0 blocks until purge has processed +# all history, so purge no longer touches t1 after FLUSH. +SET GLOBAL innodb_max_purge_lag_wait= 0; +FLUSH TABLES t1; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +--send +DELETE FROM t1; +--connection default +SET debug_sync= "now WAIT_FOR delete_open"; +SELECT a FROM t1; +SET debug_sync= "now SIGNAL another_open"; +--connection con1 +--reap + +# Cleanup +--disconnect con1 +--connection default +SET debug_sync= "RESET"; +DROP TABLE t1; + +--echo # +--echo # MDEV-26057 Assertion `!vcol->v_indexes.empty() in trx_undo_log_v_idx +--echo # +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + f3 INT AS (f2) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, 1); + +SET DEBUG_SYNC="alter_rollback_complete SIGNAL dml_start WAIT_FOR default_resume"; +send set STATEMENT DEBUG_DBUG="d,innodb_OOM_inplace_alter" FOR alter table t1 add index(f3), algorithm=inplace; + +connect(con1,localhost,root,,,); +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +INSERT INTO t1(f1, f2) VALUES(2, 2); +SET DEBUG_SYNC="now SIGNAL default_resume"; + +connection default; +--error ER_OUT_OF_RESOURCES +--reap +connection default; +disconnect con1; +SET DEBUG_SYNC="RESET"; +SELECT * FROM t1; +CHECK TABLE t1; +DROP TABLE t1; + +--echo # End of 11.4 tests + SET GLOBAL innodb_stats_persistent = @save_stats_persistent; diff --git a/mysql-test/suite/innodb/include/assert_blob_not_purged.inc b/mysql-test/suite/innodb/include/assert_blob_not_purged.inc new file mode 100644 index 00000000000..378b6d5031a --- /dev/null +++ b/mysql-test/suite/innodb/include/assert_blob_not_purged.inc @@ -0,0 +1,28 @@ +# Assert that purge has not freed the BLOB while a version-chain walk is parked +# at the dereference of its reference. Purging an update record is what would +# free it; the caller must have enabled and reset that monitor, the counter +# being cumulative over the lifetime of the server. +# +# The wait gives purge every chance to get there first, which is what makes the +# assertion fail rather than pass by accident; without the freeze it needs about +# a second. It cannot be a wait_condition, because a frozen purge_sys.view is +# precisely what stops every purge counter from moving. + +--disable_query_log +let $purge_wait_rounds= 20; +while ($purge_wait_rounds) +{ + let $freed= `SELECT count FROM information_schema.innodb_metrics WHERE name = 'purge_upd_exist_or_extern_records'`; + if ($freed) + { + let $purge_wait_rounds= 0; + } + if (!$freed) + { + real_sleep 0.1; + dec $purge_wait_rounds; + } +} +--enable_query_log +SELECT count AS upd_records_purged_while_parked FROM information_schema.innodb_metrics +WHERE name = 'purge_upd_exist_or_extern_records'; diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result b/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result deleted file mode 100644 index 21f4ee39093..00000000000 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result +++ /dev/null @@ -1,43 +0,0 @@ -CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; -INSERT INTO t1 () VALUES (),(); -connect con1,localhost,root,,test; -ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; -SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; -DELETE FROM t1; -connection default; -SET debug_sync= "now WAIT_FOR delete_open"; -SELECT a FROM t1; -a -NULL -NULL -SET debug_sync= "now SIGNAL another_open"; -connection con1; -disconnect con1; -connection default; -SET debug_sync= "RESET"; -DROP TABLE t1; -# -# MDEV-26057 Assertion `!vcol->v_indexes.empty() in trx_undo_log_v_idx -# -CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, -f3 INT AS (f2) VIRTUAL) ENGINE=InnoDB; -INSERT INTO t1(f1, f2) VALUES(1, 1); -SET DEBUG_SYNC="alter_rollback_complete SIGNAL dml_start WAIT_FOR default_resume"; -set STATEMENT DEBUG_DBUG="d,innodb_OOM_inplace_alter" FOR alter table t1 add index(f3), algorithm=inplace; -connect con1,localhost,root,,,; -SET DEBUG_SYNC="now WAIT_FOR dml_start"; -INSERT INTO t1(f1, f2) VALUES(2, 2); -SET DEBUG_SYNC="now SIGNAL default_resume"; -connection default; -ERROR HY000: Out of memory. -connection default; -disconnect con1; -SET DEBUG_SYNC="RESET"; -SELECT * FROM t1; -f1 f2 f3 -1 1 1 -2 2 2 -CHECK TABLE t1; -Table Op Msg_type Msg_text -test.t1 check status OK -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_pressure.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_pressure.result new file mode 100644 index 00000000000..a9cbab21df2 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize_pressure.result @@ -0,0 +1,9 @@ +SET @save_min=@@GLOBAL.innodb_buffer_pool_size_auto_min; +SET @save_size=@@GLOBAL.innodb_buffer_pool_size; +SET GLOBAL innodb_buffer_pool_size_auto_min=8388608; +SET GLOBAL innodb_buffer_pool_size=25165824; +SET STATEMENT debug_dbug='+d,trigger_garbage_collection,buf_shrink_fail' FOR +SET GLOBAL innodb_buffer_pool_size=25165824; +FOUND 1 /\[Note\] InnoDB: Memory pressure event failed to shrink innodb_buffer_pool_size=(16|24)m/ in mysqld.1.err +SET GLOBAL innodb_buffer_pool_size_auto_min=@save_min; +SET GLOBAL innodb_buffer_pool_size=@save_size; diff --git a/mysql-test/suite/innodb/r/innodb_ctype_ldml.result b/mysql-test/suite/innodb/r/innodb_ctype_ldml.result index 609c98f52d6..c16352cbb63 100644 --- a/mysql-test/suite/innodb/r/innodb_ctype_ldml.result +++ b/mysql-test/suite/innodb/r/innodb_ctype_ldml.result @@ -407,6 +407,7 @@ latin1_test latin1 331 1 latin1_test2 latin1 332 1 latin1_test2_cs latin1 333 1 latin1_swedish_nopad2_ci latin1 334 1 +latin1_space_after_letters_ci latin1 335 1 utf8mb3_bengali_standard_ci utf8mb3 336 8 utf8mb3_bengali_traditional_ci utf8mb3 337 8 utf8mb3_implicit_weights_ci utf8mb3 338 8 diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result b/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result index c2db4bed2f9..59f0dd0be28 100644 --- a/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result +++ b/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result @@ -16,3 +16,7 @@ connection default; SELECT * FROM t0 LIMIT 0 LOCK IN SHARE MODE; a DROP TABLE t0,t1; +# +# MDEV-38942 i_s_dict_fill_sys_tables() aborts when reading +# INNODB_SYS_TABLES after innodb_force_recovery +# diff --git a/mysql-test/suite/innodb/r/instant_alter_rollback.result b/mysql-test/suite/innodb/r/instant_alter_rollback.result index 6e84580c672..c2adfd52852 100644 --- a/mysql-test/suite/innodb/r/instant_alter_rollback.result +++ b/mysql-test/suite/innodb/r/instant_alter_rollback.result @@ -62,3 +62,18 @@ SELECT * FROM thrice; d3 id d1 10 1 20 DROP TABLE empty, once, twice, thrice; +# +# MDEV-40319 Instant ALTER TABLE rollback corrupts virtual column +# +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1 (a INT, b1 TEXT, b2 TEXT, b3 TEXT, b4 TEXT, +b5 TEXT, b6 TEXT, b7 TEXT, b8 TEXT, b9 TEXT, +b10 TEXT, b11 TEXT, v INT AS (a) VIRTUAL) +ENGINE=InnoDB ROW_FORMAT=COMPACT; +Warnings: +Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline. +SET SESSION innodb_strict_mode=ON; +ALTER TABLE t1 ADD COLUMN c INT, ALGORITHM=INSTANT; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/old_blob.result b/mysql-test/suite/innodb/r/old_blob.result new file mode 100644 index 00000000000..3c52fb127f1 --- /dev/null +++ b/mysql-test/suite/innodb/r/old_blob.result @@ -0,0 +1,46 @@ +# +# MDEV-38056 An implicit-lock check must keep purge_sys.view frozen across +# the dereference of an externally stored column of a version it rebuilt. +# The transaction it references commits meanwhile, deregistering itself +# from trx_sys before it waits for the reader's reference, which makes its +# history purgeable under the reader. +# +InnoDB 0 transactions not purged +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; +INSERT INTO t VALUES (1, CONCAT('x', REPEAT('x', @@innodb_page_size))); +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; +BEGIN; +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; +UPDATE t SET b = CONCAT('z', REPEAT('z', @@innodb_page_size)) WHERE a = 1; +connect reader,localhost,root,,; +SET DEBUG_SYNC='row_vers_impl_x_locked_row_build SIGNAL parked WAIT_FOR resume'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE; +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +COMMIT; +connect con3,localhost,root,,; +SELECT count AS upd_records_purged_while_parked FROM information_schema.innodb_metrics +WHERE name = 'purge_upd_exist_or_extern_records'; +upd_records_purged_while_parked +0 +SET DEBUG_SYNC='now SIGNAL resume'; +connection reader; +a +1 +connection default; +disconnect reader; +connection con3; +connection default; +disconnect con3; +SET DEBUG_SYNC='RESET'; +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; diff --git a/mysql-test/suite/innodb/r/old_blob_check.result b/mysql-test/suite/innodb/r/old_blob_check.result new file mode 100644 index 00000000000..ee50220dd6f --- /dev/null +++ b/mysql-test/suite/innodb/r/old_blob_check.result @@ -0,0 +1,57 @@ +# +# MDEV-38056 CHECK TABLE ... EXTENDED must keep purge_sys.view frozen +# across the dereference of an externally stored column of a version it +# rebuilt. It reaches versions that purge_sys.view already permits to be +# freed, deciding reachability from the lagging purge_sys.end_view. +# +InnoDB 0 transactions not purged +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; +INSERT INTO t VALUES (1, CONCAT('z', REPEAT('z', @@innodb_page_size))); +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; +connect purge_control,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; +connect victim,localhost,root,,; +BEGIN; +UPDATE t SET b = CONCAT('x', REPEAT('x', @@innodb_page_size)) WHERE a = 1; +connect checker,localhost,root,,; +SET DEBUG_SYNC='row_check_index_extended_match SIGNAL parked WAIT_FOR resume EXECUTE 2'; +CHECK TABLE t EXTENDED; +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +disconnect purge_control; +connection default; +SELECT count AS upd_records_purged_while_parked FROM information_schema.innodb_metrics +WHERE name = 'purge_upd_exist_or_extern_records'; +upd_records_purged_while_parked +0 +SET DEBUG_SYNC='now SIGNAL resume'; +connection checker; +Table Op Msg_type Msg_text +test.t check status OK +disconnect checker; +connection victim; +COMMIT; +connection default; +disconnect victim; +SET DEBUG_SYNC='RESET'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'xx%'; +a +1 +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; diff --git a/mysql-test/suite/innodb/r/old_blob_purgeable.result b/mysql-test/suite/innodb/r/old_blob_purgeable.result new file mode 100644 index 00000000000..c6b665b55b7 --- /dev/null +++ b/mysql-test/suite/innodb/r/old_blob_purgeable.result @@ -0,0 +1,90 @@ +# +# MDEV-38056 Each of the three walks that freeze purge_sys.view across the +# dereference of an externally stored column re-establishes under the +# freeze that the version it rebuilt is still reachable. A debug keyword +# forces each of those tests to fail, so that the exit it guards is +# reachable without the race that produces it. +# +InnoDB 0 transactions not purged +SET @old_dbug= @@SESSION.debug_dbug; +# +# row_vers_impl_x_locked_purgeable: report no implicit lock. +# +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, REPEAT('x', @@innodb_page_size)); +BEGIN; +UPDATE t SET b = REPEAT('y', @@innodb_page_size) WHERE a = 1; +UPDATE t SET b = REPEAT('z', @@innodb_page_size) WHERE a = 1; +connect reader,localhost,root,,; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug='+d,row_vers_impl_x_locked_purgeable'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE SKIP LOCKED; +a +SET SESSION debug_dbug= @old_dbug; +connection default; +COMMIT; +connection reader; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE SKIP LOCKED; +a +1 +COMMIT; +connection default; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# +# row_undo_mod_sec_is_unsafe_purgeable: report the secondary index entry +# as still needed, which only makes the rollback delete-mark an entry it +# could have removed. +# +CREATE TABLE t(a INT PRIMARY KEY, pad INT, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, 0, REPEAT('x', @@innodb_page_size)); +UPDATE t SET pad = 1 WHERE a = 1; +UPDATE t SET b = REPEAT('y', @@innodb_page_size) WHERE a = 1; +BEGIN; +UPDATE t SET b = REPEAT('z', @@innodb_page_size) WHERE a = 1; +SET SESSION debug_dbug='+d,row_undo_mod_sec_is_unsafe_purgeable'; +ROLLBACK; +SET SESSION debug_dbug= @old_dbug; +SELECT a, pad, LEFT(b, 2) FROM t FORCE INDEX(b) WHERE b LIKE 'yy%'; +a pad LEFT(b, 2) +1 1 yy +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# +# row_check_index_purgeable: stop the walk and report nothing. +# +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, REPEAT('x', @@innodb_page_size)); +connect purge_control,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +UPDATE t SET b = 's' WHERE a = 1; +connect victim,localhost,root,,; +BEGIN; +UPDATE t SET b = 'q' WHERE a = 1; +connection default; +SET SESSION debug_dbug='+d,row_check_index_purgeable'; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +SET SESSION debug_dbug= @old_dbug; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +connection victim; +ROLLBACK; +disconnect purge_control; +connection default; +disconnect reader; +disconnect victim; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/old_blob_rollback.result b/mysql-test/suite/innodb/r/old_blob_rollback.result new file mode 100644 index 00000000000..0b4408bd84e --- /dev/null +++ b/mysql-test/suite/innodb/r/old_blob_rollback.result @@ -0,0 +1,54 @@ +# +# MDEV-38056 A rollback must keep purge_sys.view frozen across the +# dereference of an externally stored column of a version it rebuilt. It +# froze that view only inside trx_undo_prev_version_build(), so purge was +# free to release the BLOB pages before the caller fetched them. +# +InnoDB 0 transactions not purged +CREATE TABLE t(a INT PRIMARY KEY, pad INT, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; +INSERT INTO t VALUES (1, 0, CONCAT('x', REPEAT('x', @@innodb_page_size))); +INSERT INTO t +SELECT 100 + seq, 0, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; +connect purge_control,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +UPDATE t SET pad = 1 WHERE a = 1; +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; +connect victim,localhost,root,,; +BEGIN; +UPDATE t SET b = CONCAT('z', REPEAT('z', @@innodb_page_size)) WHERE a = 1; +SET DEBUG_SYNC='row_undo_mod_sec_is_unsafe_row_build SIGNAL parked WAIT_FOR resume EXECUTE 3'; +ROLLBACK; +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +disconnect purge_control; +connection default; +SELECT count AS upd_records_purged_while_parked FROM information_schema.innodb_metrics +WHERE name = 'purge_upd_exist_or_extern_records'; +upd_records_purged_while_parked +0 +SET DEBUG_SYNC='now SIGNAL resume'; +connection victim; +connection default; +disconnect victim; +SET DEBUG_SYNC='RESET'; +SELECT a, pad FROM t FORCE INDEX(b) WHERE b LIKE 'yy%'; +a pad +1 1 +CHECK TABLE t; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; diff --git a/mysql-test/suite/innodb/r/old_blob_updel.result b/mysql-test/suite/innodb/r/old_blob_updel.result new file mode 100644 index 00000000000..68e252c8695 --- /dev/null +++ b/mysql-test/suite/innodb/r/old_blob_updel.result @@ -0,0 +1,72 @@ +# +# MDEV-38056 As innodb.old_blob, but the version is rebuilt from the undo +# log record of an update of a record that another, committed transaction +# delete-marked. Such a record stores only the 20-byte reference, so the +# frozen purge_sys.view is the only thing that can keep the dereference +# valid. Reaching that version needs a batch to be still in progress. +# +InnoDB 0 transactions not purged +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; +INSERT INTO t VALUES (1, CONCAT('x', REPEAT('x', @@innodb_page_size))); +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; +SET GLOBAL innodb_monitor_reset_all='purge_del_mark_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_del_mark_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; +connect purge_control,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM t WHERE a = 1; +connect victim,localhost,root,,; +BEGIN; +INSERT INTO t VALUES (1, CONCAT('z', REPEAT('z', @@innodb_page_size))); +connection default; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug='+d,purge_hold_cleanup'; +disconnect purge_control; +connection default; +SET DEBUG_SYNC='now WAIT_FOR purge_batch_parked TIMEOUT 60'; +SELECT count > 0 AS del_mark_records_purged +FROM information_schema.innodb_metrics WHERE name = 'purge_del_mark_records'; +del_mark_records_purged +1 +connect reader,localhost,root,,; +SET DEBUG_SYNC='row_vers_impl_x_locked_row_build SIGNAL parked WAIT_FOR resume'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE; +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET GLOBAL debug_dbug= @old_dbug; +SET DEBUG_SYNC='now SIGNAL purge_batch_resume'; +connection victim; +COMMIT; +connection default; +SELECT count AS upd_records_purged_while_parked FROM information_schema.innodb_metrics +WHERE name = 'purge_upd_exist_or_extern_records'; +upd_records_purged_while_parked +0 +SET DEBUG_SYNC='now SIGNAL resume'; +connection victim; +connection reader; +a +1 +connection default; +disconnect reader; +disconnect victim; +SET DEBUG_SYNC='RESET'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'zz%'; +a +1 +CHECK TABLE t; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_del_mark_records'; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_del_mark_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; diff --git a/mysql-test/suite/innodb/r/skip_locked_wait_granted.result b/mysql-test/suite/innodb/r/skip_locked_wait_granted.result new file mode 100644 index 00000000000..c4c5877e5ba --- /dev/null +++ b/mysql-test/suite/innodb/r/skip_locked_wait_granted.result @@ -0,0 +1,116 @@ +# +# MDEV-40123 Assertion failure after lock wait is unblocked in SKIP LOCKED +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b INT, KEY(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3); +connect con1,localhost,root; +connect con2,localhost,root; +# The lock on the clustered index record is granted after the wait +connection con1; +BEGIN; +SELECT b FROM t1 WHERE pk=1 FOR UPDATE; +b +1 +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; +connection con2; +b +1 +2 +3 +connection con1; +SELECT pk FROM t1 WHERE pk=1 FOR UPDATE SKIP LOCKED; +pk +connection con2; +COMMIT; +# The granted lock covers a row whose non-key column was updated +connection con1; +BEGIN; +UPDATE t1 SET b=10 WHERE pk=1; +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; +connection con2; +b +10 +2 +3 +connection con1; +SELECT pk FROM t1 WHERE pk=1 FOR UPDATE SKIP LOCKED; +pk +connection con2; +COMMIT; +# The lock on the delete-marked secondary index record is granted +connection con1; +BEGIN; +DELETE FROM t1 WHERE pk=1; +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; +connection con2; +b +2 +3 +COMMIT; +# The lock is still held: the record is skipped +connection con1; +BEGIN; +SELECT b FROM t1 WHERE pk=2 FOR UPDATE; +b +2 +connection con2; +BEGIN; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +b +3 +COMMIT; +connection con1; +COMMIT; +# A deadlock is reported while waiting for the lock +CREATE TABLE t2 (x INT) ENGINE=InnoDB; +connection con1; +BEGIN; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +SELECT b FROM t1 WHERE pk=2 FOR UPDATE; +b +2 +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +SET DEBUG_SYNC='deadlock_report_before_lock_releasing SIGNAL deadlock'; +SELECT pk FROM t1 FORCE INDEX (a) WHERE a=2 FOR UPDATE; +connection default; +SET DEBUG_SYNC='now WAIT_FOR deadlock'; +SET DEBUG_SYNC='now SIGNAL go'; +connection con2; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection con1; +pk +2 +disconnect con2; +connection con1; +COMMIT; +disconnect con1; +connection default; +SET DEBUG_SYNC='RESET'; +DROP TABLE t1, t2; +# End of 11.4 tests diff --git a/mysql-test/suite/innodb/r/temp_truncate_freed_race.result b/mysql-test/suite/innodb/r/temp_truncate_freed_race.result new file mode 100644 index 00000000000..b20dbd4377c --- /dev/null +++ b/mysql-test/suite/innodb/r/temp_truncate_freed_race.result @@ -0,0 +1,31 @@ +# +# MDEV-41103 Crash in innodb.temp_truncate_freed +# +SET GLOBAL innodb_immediate_scrub_data_uncompressed=1; +SET GLOBAL innodb_max_dirty_pages_pct=0; +SET GLOBAL innodb_buffer_pool_size= 16777216; +CREATE PROCEDURE process_temp_table(end_time INT UNSIGNED) +BEGIN +WHILE UNIX_TIMESTAMP() < end_time DO +CREATE TEMPORARY TABLE t1(c1 MEDIUMTEXT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (repeat('a', 16777215)); +DROP TEMPORARY TABLE t1; +END WHILE; +END| +CREATE PROCEDURE toggle_pool_size(end_time INT UNSIGNED) +BEGIN +DECLARE CONTINUE HANDLER FOR 1221 BEGIN END; +WHILE UNIX_TIMESTAMP() < end_time DO +SET GLOBAL innodb_buffer_pool_size=16777216; +SET GLOBAL innodb_buffer_pool_size=6291456; +END WHILE; +END| +# +# Run concurrent processing to trigger possible data race +# +# +# Cleanup +# +DROP PROCEDURE process_temp_table; +DROP PROCEDURE toggle_pool_size; +# End of test diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test b/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test deleted file mode 100644 index ed160b977a4..00000000000 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test +++ /dev/null @@ -1,52 +0,0 @@ ---source include/have_innodb.inc ---source include/have_debug.inc ---source include/have_debug_sync.inc - -# -# MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value -# -CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; - -INSERT INTO t1 () VALUES (),(); ---connect (con1,localhost,root,,test) -ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; -SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; ---send -DELETE FROM t1; ---connection default -SET debug_sync= "now WAIT_FOR delete_open"; -SELECT a FROM t1; -SET debug_sync= "now SIGNAL another_open"; ---connection con1 ---reap - -# Cleanup ---disconnect con1 ---connection default -SET debug_sync= "RESET"; -DROP TABLE t1; - ---echo # ---echo # MDEV-26057 Assertion `!vcol->v_indexes.empty() in trx_undo_log_v_idx ---echo # -CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, - f3 INT AS (f2) VIRTUAL) ENGINE=InnoDB; -INSERT INTO t1(f1, f2) VALUES(1, 1); - -SET DEBUG_SYNC="alter_rollback_complete SIGNAL dml_start WAIT_FOR default_resume"; -send set STATEMENT DEBUG_DBUG="d,innodb_OOM_inplace_alter" FOR alter table t1 add index(f3), algorithm=inplace; - -connect(con1,localhost,root,,,); -SET DEBUG_SYNC="now WAIT_FOR dml_start"; -INSERT INTO t1(f1, f2) VALUES(2, 2); -SET DEBUG_SYNC="now SIGNAL default_resume"; - -connection default; ---error ER_OUT_OF_RESOURCES ---reap -connection default; -disconnect con1; -SET DEBUG_SYNC="RESET"; -SELECT * FROM t1; -CHECK TABLE t1; -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.opt b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.opt new file mode 100644 index 00000000000..a3b90c64402 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.opt @@ -0,0 +1 @@ +--innodb-buffer-pool-size=24m diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.test new file mode 100644 index 00000000000..76a72a281b0 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize_pressure.test @@ -0,0 +1,17 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/have_debug.inc + +SET @save_min=@@GLOBAL.innodb_buffer_pool_size_auto_min; +SET @save_size=@@GLOBAL.innodb_buffer_pool_size; + +SET GLOBAL innodb_buffer_pool_size_auto_min=8388608; +SET GLOBAL innodb_buffer_pool_size=25165824; +SET STATEMENT debug_dbug='+d,trigger_garbage_collection,buf_shrink_fail' FOR +SET GLOBAL innodb_buffer_pool_size=25165824; +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN=\[Note\] InnoDB: Memory pressure event failed to shrink innodb_buffer_pool_size=(16|24)m; +--source include/search_pattern_in_file.inc + +SET GLOBAL innodb_buffer_pool_size_auto_min=@save_min; +SET GLOBAL innodb_buffer_pool_size=@save_size; diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test b/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test index f1d14c45aaf..e712a43c9df 100644 --- a/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test +++ b/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc --source include/have_sequence.inc +--source include/maybe_debug.inc # We will kill and restart the server. --source include/not_embedded.inc @@ -33,3 +34,42 @@ connection default; # The LIMIT 0 works around MDEV-22889 InnoDB occasionally breaks ACID SELECT * FROM t0 LIMIT 0 LOCK IN SHARE MODE; DROP TABLE t0,t1; + +--echo # +--echo # MDEV-38942 i_s_dict_fill_sys_tables() aborts when reading +--echo # INNODB_SYS_TABLES after innodb_force_recovery +--echo # + +if ($have_debug) +{ +--disable_query_log +--disable_result_log +--let $restart_noprint=2 + +connect (con1,localhost,root,,,); +SET DEBUG_SYNC='create_table_inserted SIGNAL created WAIT_FOR ever'; +send CREATE TABLE t1 (a INT) ENGINE=InnoDB; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR created'; +SET GLOBAL innodb_log_checkpoint_now=ON; + +--let $restart_parameters= --innodb-force-recovery=4 +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc +--let $restart_parameters= +--let $shutdown_timeout= +--disable_result_log +--disable_query_log + +disconnect con1; +connection default; +SELECT name FROM information_schema.INNODB_SYS_TABLES WHERE name LIKE 'test/%'; + +--source include/restart_mysqld.inc +--disable_query_log + +--let $restart_noprint= +--enable_result_log +--enable_query_log +} diff --git a/mysql-test/suite/innodb/t/instant_alter_rollback.test b/mysql-test/suite/innodb/t/instant_alter_rollback.test index 491f63463c5..e601e3ba6ac 100644 --- a/mysql-test/suite/innodb/t/instant_alter_rollback.test +++ b/mysql-test/suite/innodb/t/instant_alter_rollback.test @@ -70,3 +70,17 @@ SELECT * FROM once; SELECT * FROM twice; SELECT * FROM thrice; DROP TABLE empty, once, twice, thrice; + +--echo # +--echo # MDEV-40319 Instant ALTER TABLE rollback corrupts virtual column +--echo # +call mtr.add_suppression("InnoDB: Cannot add field .* in table"); +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1 (a INT, b1 TEXT, b2 TEXT, b3 TEXT, b4 TEXT, + b5 TEXT, b6 TEXT, b7 TEXT, b8 TEXT, b9 TEXT, + b10 TEXT, b11 TEXT, v INT AS (a) VIRTUAL) + ENGINE=InnoDB ROW_FORMAT=COMPACT; +SET SESSION innodb_strict_mode=ON; +--error ER_TOO_BIG_ROWSIZE +ALTER TABLE t1 ADD COLUMN c INT, ALGORITHM=INSTANT; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/old_blob.test b/mysql-test/suite/innodb/t/old_blob.test new file mode 100644 index 00000000000..85799345a22 --- /dev/null +++ b/mysql-test/suite/innodb/t/old_blob.test @@ -0,0 +1,75 @@ +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_debug_sync.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-38056 An implicit-lock check must keep purge_sys.view frozen across +--echo # the dereference of an externally stored column of a version it rebuilt. +--echo # The transaction it references commits meanwhile, deregistering itself +--echo # from trx_sys before it waits for the reader's reference, which makes its +--echo # history purgeable under the reader. +--echo # + +--source include/wait_all_purged.inc + +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; + +INSERT INTO t VALUES (1, CONCAT('x', REPEAT('x', @@innodb_page_size))); + +# Filler rows keep the delete-marked entries off the leaf page holding the live +# 'z...' entry, which the reader latches; purge would block on it otherwise. +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; + +# The counter is cumulative over the lifetime of the server. +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; + +BEGIN; +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; +UPDATE t SET b = CONCAT('z', REPEAT('z', @@innodb_page_size)) WHERE a = 1; + +# The locking read references the still active transaction above and parks after +# building the previous version, before dereferencing its BLOB pointers. +connect (reader,localhost,root,,); +SET DEBUG_SYNC='row_vers_impl_x_locked_row_build SIGNAL parked WAIT_FOR resume'; +--send SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE + +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +--send COMMIT + +# Both old BLOBs must still be allocated while the reader is parked on them. +connect (con3,localhost,root,,); +--source suite/innodb/include/assert_blob_not_purged.inc +SET DEBUG_SYNC='now SIGNAL resume'; + +connection reader; +--reap + +connection default; +--reap +disconnect reader; + +# Once the reader is done, purge advances, which confirms that only the frozen +# view held it back. +connection con3; +let $wait_condition= + SELECT count >= 2 FROM information_schema.innodb_metrics + WHERE name = 'purge_upd_exist_or_extern_records'; +--source include/wait_condition.inc + +connection default; +disconnect con3; +SET DEBUG_SYNC='RESET'; +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +--disable_warnings +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/old_blob_check.test b/mysql-test/suite/innodb/t/old_blob_check.test new file mode 100644 index 00000000000..bde15c5e50d --- /dev/null +++ b/mysql-test/suite/innodb/t/old_blob_check.test @@ -0,0 +1,96 @@ +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_debug_sync.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-38056 CHECK TABLE ... EXTENDED must keep purge_sys.view frozen +--echo # across the dereference of an externally stored column of a version it +--echo # rebuilt. It reaches versions that purge_sys.view already permits to be +--echo # freed, deciding reachability from the lagging purge_sys.end_view. +--echo # + +--source include/wait_all_purged.inc + +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; + +INSERT INTO t VALUES (1, CONCAT('z', REPEAT('z', @@innodb_page_size))); + +# Filler rows keep the delete-marked 'z...' entry off the first leaf page, which +# CHECK TABLE holds while parked; purge would block on it otherwise. +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; + +# The counter is cumulative over the lifetime of the server. +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; + +# Pin a read view on the 'z...' state, so that the BLOB the update below disowns +# stays allocated until we release it. +connect (purge_control,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +# Committed update that disowns the 'z...' BLOB, which purge will free. +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; + +# An active transaction keeps the newest version invisible to CHECK TABLE, which +# is what makes it descend the version chain at all. +connect (victim,localhost,root,,); +BEGIN; +UPDATE t SET b = CONCAT('x', REPEAT('x', @@innodb_page_size)) WHERE a = 1; + +# While checking the live 'x...' entry, CHECK TABLE rebuilds the 'y...' and then +# the 'z...' version and compares the column prefix of each against it. +connect (checker,localhost,root,,); +SET DEBUG_SYNC='row_check_index_extended_match SIGNAL parked WAIT_FOR resume EXECUTE 2'; +--send CHECK TABLE t EXTENDED + +connection default; +# Hit 1: the 'y...' version, whose BLOB the active transaction above disowned and +# which is therefore not freeable. +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; + +# Hit 2: the 'z...' version, whose BLOB the committed update disowned. Release +# the read view, the last thing that kept that BLOB from being freeable. Purge +# has to remove the delete-marked 'z...' entry first, and that sits on the last +# leaf page while CHECK TABLE holds the first. +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +disconnect purge_control; + +connection default; +--source suite/innodb/include/assert_blob_not_purged.inc +SET DEBUG_SYNC='now SIGNAL resume'; + +connection checker; +--reap +disconnect checker; + +connection victim; +COMMIT; + +connection default; +disconnect victim; + +# Once CHECK TABLE is done, purge advances and frees that BLOB, which confirms +# that only the frozen view held it back. +let $wait_condition= + SELECT count >= 1 FROM information_schema.innodb_metrics + WHERE name = 'purge_upd_exist_or_extern_records'; +--source include/wait_condition.inc + +SET DEBUG_SYNC='RESET'; + +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'xx%'; +CHECK TABLE t EXTENDED; +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +--disable_warnings +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/old_blob_purgeable.test b/mysql-test/suite/innodb/t/old_blob_purgeable.test new file mode 100644 index 00000000000..aef0c365585 --- /dev/null +++ b/mysql-test/suite/innodb/t/old_blob_purgeable.test @@ -0,0 +1,111 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +--echo # +--echo # MDEV-38056 Each of the three walks that freeze purge_sys.view across the +--echo # dereference of an externally stored column re-establishes under the +--echo # freeze that the version it rebuilt is still reachable. A debug keyword +--echo # forces each of those tests to fail, so that the exit it guards is +--echo # reachable without the race that produces it. +--echo # + +--source include/wait_all_purged.inc + +SET @old_dbug= @@SESSION.debug_dbug; + +--echo # +--echo # row_vers_impl_x_locked_purgeable: report no implicit lock. +--echo # + +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, REPEAT('x', @@innodb_page_size)); + +BEGIN; +UPDATE t SET b = REPEAT('y', @@innodb_page_size) WHERE a = 1; +UPDATE t SET b = REPEAT('z', @@innodb_page_size) WHERE a = 1; + +# The implicit lock check walks the versions of the row this transaction still +# holds, and row_vers_impl_x_locked_purgeable makes it answer that the row is +# unlocked. The reader skips the row anyway, the clustered index record carrying +# the same implicit lock, so the row stays protected. +connect (reader,localhost,root,,); +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug='+d,row_vers_impl_x_locked_purgeable'; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE SKIP LOCKED; +SET SESSION debug_dbug= @old_dbug; + +connection default; +COMMIT; + +connection reader; +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE SKIP LOCKED; +COMMIT; + +connection default; +CHECK TABLE t EXTENDED; +DROP TABLE t; + +--echo # +--echo # row_undo_mod_sec_is_unsafe_purgeable: report the secondary index entry +--echo # as still needed, which only makes the rollback delete-mark an entry it +--echo # could have removed. +--echo # + +CREATE TABLE t(a INT PRIMARY KEY, pad INT, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, 0, REPEAT('x', @@innodb_page_size)); +# The pad update produces a version that merely inherits the reference to the +# 'x...' BLOB, which is what the walk below has to dereference. +UPDATE t SET pad = 1 WHERE a = 1; +UPDATE t SET b = REPEAT('y', @@innodb_page_size) WHERE a = 1; + +BEGIN; +UPDATE t SET b = REPEAT('z', @@innodb_page_size) WHERE a = 1; +SET SESSION debug_dbug='+d,row_undo_mod_sec_is_unsafe_purgeable'; +ROLLBACK; +SET SESSION debug_dbug= @old_dbug; + +SELECT a, pad, LEFT(b, 2) FROM t FORCE INDEX(b) WHERE b LIKE 'yy%'; +CHECK TABLE t EXTENDED; +DROP TABLE t; + +--echo # +--echo # row_check_index_purgeable: stop the walk and report nothing. +--echo # + +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC; +INSERT INTO t VALUES (1, REPEAT('x', @@innodb_page_size)); + +# Keep the 'x...' version reachable, so that the walk gets to dereference it. +connect (purge_control,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +# Two short values, so that only the third version down stores its column +# externally, and the walk reaches the freeze only there. Stopping that late +# costs no count: a version that the check can see was rejected higher up, so +# the record was never going to be counted, and the check still says OK. +UPDATE t SET b = 's' WHERE a = 1; + +connect (victim,localhost,root,,); +BEGIN; +UPDATE t SET b = 'q' WHERE a = 1; + +connection default; +SET SESSION debug_dbug='+d,row_check_index_purgeable'; +CHECK TABLE t EXTENDED; +SET SESSION debug_dbug= @old_dbug; +CHECK TABLE t EXTENDED; + +connection victim; +ROLLBACK; + +disconnect purge_control; + +connection default; +disconnect reader; +disconnect victim; +CHECK TABLE t EXTENDED; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/old_blob_rollback.test b/mysql-test/suite/innodb/t/old_blob_rollback.test new file mode 100644 index 00000000000..681e7789d52 --- /dev/null +++ b/mysql-test/suite/innodb/t/old_blob_rollback.test @@ -0,0 +1,99 @@ +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_debug_sync.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-38056 A rollback must keep purge_sys.view frozen across the +--echo # dereference of an externally stored column of a version it rebuilt. It +--echo # froze that view only inside trx_undo_prev_version_build(), so purge was +--echo # free to release the BLOB pages before the caller fetched them. +--echo # + +--source include/wait_all_purged.inc + +CREATE TABLE t(a INT PRIMARY KEY, pad INT, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; + +INSERT INTO t VALUES (1, 0, CONCAT('x', REPEAT('x', @@innodb_page_size))); + +# Filler rows keep the delete-marked entries off the leaf page holding the live +# 'z...' entry, which the rollback latches; purge would block on it otherwise. +INSERT INTO t +SELECT 100 + seq, 0, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; + +# The counter is cumulative over the lifetime of the server. +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; + +# Pin a read view on the 'x...' state, so that the BLOB the updates below disown +# stays allocated until we release it. +connect (purge_control,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +# Committed update that does not mention b: the version it produces inherits +# whatever reference b holds in the next newer version. +UPDATE t SET pad = 1 WHERE a = 1; +# Committed update that disowns the 'x...' BLOB, which purge will free. +UPDATE t SET b = CONCAT('y', REPEAT('y', @@innodb_page_size)) WHERE a = 1; + +connect (victim,localhost,root,,); +BEGIN; +UPDATE t SET b = CONCAT('z', REPEAT('z', @@innodb_page_size)) WHERE a = 1; + +# On ROLLBACK the walk is 'z...' -> 'y...' -> 'x...' -> 'x...' inherited. Park +# before each of the three row_build() calls. +SET DEBUG_SYNC='row_undo_mod_sec_is_unsafe_row_build SIGNAL parked WAIT_FOR resume EXECUTE 3'; +--send ROLLBACK + +connection default; +# Hit 1: the 'y...' version, whose BLOB belongs to the rolling back +# transaction and is never freeable. +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; + +# Hit 2: the 'x...' version, rebuilt from the b update's undo log record. The +# read view still pins that BLOB, so there is nothing to observe here. +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +SET DEBUG_SYNC='now SIGNAL resume'; + +# Hit 3: the version the pad update produced. Its undo log record says nothing +# about b, so it merely inherits the reference that the b update disowned, and a +# frozen purge_sys.view is the only thing that can keep the dereference valid. +# Release the read view, the last thing that kept that BLOB from being freeable. +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +disconnect purge_control; + +connection default; +--source suite/innodb/include/assert_blob_not_purged.inc +SET DEBUG_SYNC='now SIGNAL resume'; + +connection victim; +--reap + +connection default; +disconnect victim; + +# Once the rollback is over, purge advances past both committed updates, which +# confirms that only the frozen view held it back. Only the b update frees a +# BLOB, the pad update having disowned none. +let $wait_condition= + SELECT count >= 2 FROM information_schema.innodb_metrics + WHERE name = 'purge_upd_exist_or_extern_records'; +--source include/wait_condition.inc + +SET DEBUG_SYNC='RESET'; + +# The rollback reverted to the committed 'y...' value, and the indexes agree. +SELECT a, pad FROM t FORCE INDEX(b) WHERE b LIKE 'yy%'; +CHECK TABLE t; +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +--disable_warnings +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/old_blob_updel.test b/mysql-test/suite/innodb/t/old_blob_updel.test new file mode 100644 index 00000000000..4020466184f --- /dev/null +++ b/mysql-test/suite/innodb/t/old_blob_updel.test @@ -0,0 +1,118 @@ +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-38056 As innodb.old_blob, but the version is rebuilt from the undo +--echo # log record of an update of a record that another, committed transaction +--echo # delete-marked. Such a record stores only the 20-byte reference, so the +--echo # frozen purge_sys.view is the only thing that can keep the dereference +--echo # valid. Reaching that version needs a batch to be still in progress. +--echo # + +--source include/wait_all_purged.inc + +CREATE TABLE t(a INT PRIMARY KEY, b TEXT, UNIQUE(b(700))) +ENGINE=InnoDB STATS_PERSISTENT=0 ROW_FORMAT=COMPRESSED; + +INSERT INTO t VALUES (1, CONCAT('x', REPEAT('x', @@innodb_page_size))); + +# Filler rows keep the delete-marked 'x...' entry off the leaf page holding the +# live 'z...' entry, which the reader latches; purge would block on it otherwise. +INSERT INTO t +SELECT 100 + seq, CONCAT('y~', LPAD(seq, 3, '0'), REPEAT('-', 800)) +FROM seq_60_to_1; + +# The counters are cumulative over the lifetime of the server. +SET GLOBAL innodb_monitor_reset_all='purge_del_mark_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_enable='purge_del_mark_records'; +SET GLOBAL innodb_monitor_enable='purge_upd_exist_or_extern_records'; + +# Pin purge so that the DELETE below stays unpurged until we choose. +connect (purge_control,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +# T1 delete-marks the row; the 'x...' BLOB is still owned by the record. +DELETE FROM t WHERE a = 1; + +# T2 re-inserts the same PRIMARY KEY: an update of a record that T1 +# delete-marked, so the undo log record stores only the reference, no prefix. +connect (victim,localhost,root,,); +BEGIN; +INSERT INTO t VALUES (1, CONCAT('z', REPEAT('z', @@innodb_page_size))); + +# Hold the batch below open once it has purged T1, which is the window in which +# purge_sys.end_view still presents that history as reconstructible. +connection default; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug='+d,purge_hold_cleanup'; + +# Let purge see T1 and remove the delete-marked 'x...' entry: nobody holds the +# clustered index leaf yet. T2 is still active, so purge stops there. +disconnect purge_control; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR purge_batch_parked TIMEOUT 60'; + +# The batch is parked, so its last purged record is behind it and the counter is +# final. It removed the delete-marked 'x...' entry. +SELECT count > 0 AS del_mark_records_purged +FROM information_schema.innodb_metrics WHERE name = 'purge_del_mark_records'; + +# The reader references the active T2. end_view cannot see T1, so it rebuilds the +# delete-marked 'x...' version and parks before dereferencing it. +connect (reader,localhost,root,,); +SET DEBUG_SYNC='row_vers_impl_x_locked_row_build SIGNAL parked WAIT_FOR resume'; +--send SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'z%' FOR UPDATE + +connection default; +SET DEBUG_SYNC='now WAIT_FOR parked TIMEOUT 60'; +# The reader has descended, so the batch may finish. The next one cannot start +# before the reader is done anyway, the reader holding the freeze. Clear +# purge_hold_cleanup first, so that the next batch does not park. +SET GLOBAL debug_dbug= @old_dbug; +SET DEBUG_SYNC='now SIGNAL purge_batch_resume'; + +# T2 commits, making purgeable the undo log record that disowned the 'x...' BLOB, +# and then waits for the reference the parked reader holds. +connection victim; +--send COMMIT + +connection default; +--source suite/innodb/include/assert_blob_not_purged.inc + +SET DEBUG_SYNC='now SIGNAL resume'; + +connection victim; +--reap +connection reader; +--reap + +connection default; +disconnect reader; +disconnect victim; +SET DEBUG_SYNC='RESET'; + +# Once the reader is done, purge advances and frees that BLOB, which confirms +# that only the frozen view held it back. +let $wait_condition= + SELECT count >= 1 FROM information_schema.innodb_metrics + WHERE name = 'purge_upd_exist_or_extern_records'; +--source include/wait_condition.inc + +SELECT a FROM t FORCE INDEX(b) WHERE b LIKE 'zz%'; +CHECK TABLE t; +DROP TABLE t; +SET GLOBAL innodb_monitor_disable='purge_del_mark_records'; +SET GLOBAL innodb_monitor_disable='purge_upd_exist_or_extern_records'; +SET GLOBAL innodb_monitor_reset_all='purge_del_mark_records'; +SET GLOBAL innodb_monitor_reset_all='purge_upd_exist_or_extern_records'; +--disable_warnings +SET GLOBAL innodb_monitor_enable=default; +SET GLOBAL innodb_monitor_disable=default; +SET GLOBAL innodb_monitor_reset_all=default; +--enable_warnings diff --git a/mysql-test/suite/innodb/t/skip_locked_wait_granted.test b/mysql-test/suite/innodb/t/skip_locked_wait_granted.test new file mode 100644 index 00000000000..ada4f5c2586 --- /dev/null +++ b/mysql-test/suite/innodb/t/skip_locked_wait_granted.test @@ -0,0 +1,128 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +--echo # +--echo # MDEV-40123 Assertion failure after lock wait is unblocked in SKIP LOCKED +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b INT, KEY(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3); + +connect con1,localhost,root; +connect con2,localhost,root; + +--echo # The lock on the clustered index record is granted after the wait +connection con1; +BEGIN; +SELECT b FROM t1 WHERE pk=1 FOR UPDATE; + +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +send SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; + +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; + +connection con2; +reap; +connection con1; +SELECT pk FROM t1 WHERE pk=1 FOR UPDATE SKIP LOCKED; +connection con2; +COMMIT; + +--echo # The granted lock covers a row whose non-key column was updated +connection con1; +BEGIN; +UPDATE t1 SET b=10 WHERE pk=1; + +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +send SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; + +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; + +connection con2; +reap; +connection con1; +SELECT pk FROM t1 WHERE pk=1 FOR UPDATE SKIP LOCKED; +connection con2; +COMMIT; + +--echo # The lock on the delete-marked secondary index record is granted +connection con1; +BEGIN; +DELETE FROM t1 WHERE pk=1; + +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +send SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; + +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +COMMIT; +SET DEBUG_SYNC='now SIGNAL go'; + +connection con2; +reap; +COMMIT; + +--echo # The lock is still held: the record is skipped +connection con1; +BEGIN; +SELECT b FROM t1 WHERE pk=2 FOR UPDATE; + +connection con2; +BEGIN; +SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; +COMMIT; + +connection con1; +COMMIT; + +--echo # A deadlock is reported while waiting for the lock +CREATE TABLE t2 (x INT) ENGINE=InnoDB; +connection con1; +BEGIN; +# Make con1 heavier than con2, so that con2 is chosen as the deadlock victim +INSERT INTO t2 VALUES (1),(2),(3),(4),(5); +SELECT b FROM t1 WHERE pk=2 FOR UPDATE; + +connection con2; +BEGIN; +SET DEBUG_SYNC='lock_trx_handle_wait_enter SIGNAL waiting WAIT_FOR go'; +send SELECT b FROM t1 FORCE INDEX (a) ORDER BY a FOR UPDATE SKIP LOCKED; + +connection con1; +SET DEBUG_SYNC='now WAIT_FOR waiting'; +SET DEBUG_SYNC='deadlock_report_before_lock_releasing SIGNAL deadlock'; +send SELECT pk FROM t1 FORCE INDEX (a) WHERE a=2 FOR UPDATE; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR deadlock'; +SET DEBUG_SYNC='now SIGNAL go'; + +connection con2; +--error ER_LOCK_DEADLOCK +reap; + +connection con1; +reap; + +disconnect con2; +connection con1; +COMMIT; +disconnect con1; + +connection default; +SET DEBUG_SYNC='RESET'; +DROP TABLE t1, t2; + +--echo # End of 11.4 tests diff --git a/mysql-test/suite/innodb/t/temp_truncate_freed_race.opt b/mysql-test/suite/innodb/t/temp_truncate_freed_race.opt new file mode 100644 index 00000000000..95f86e59920 --- /dev/null +++ b/mysql-test/suite/innodb/t/temp_truncate_freed_race.opt @@ -0,0 +1 @@ +--innodb-buffer-pool-size-max=16m diff --git a/mysql-test/suite/innodb/t/temp_truncate_freed_race.test b/mysql-test/suite/innodb/t/temp_truncate_freed_race.test new file mode 100644 index 00000000000..610ac8c45da --- /dev/null +++ b/mysql-test/suite/innodb/t/temp_truncate_freed_race.test @@ -0,0 +1,136 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-41103 Crash in innodb.temp_truncate_freed +--echo # + +# +# Data race bug caused by unsynchronized access to +# fil_space_t::freed_ranges when mtr_t::commit() frees +# pages for a temporary tablespace. +# +# The race can be triggered by fil_space_t::flush_freed(), +# called concurrently from the page cleaner when resizing +# the buffer pool. The test attempts to reproduce that condition +# by creating, writing to, and dropping temporary tables concurrently, +# while resizing the buffer pool constantly. If successful it will +# likely terminate the server with a segfault or, on a debug build, +# possibly an assertion. +# +# This is a stress/regression test: it does not assert on any +# query result, it only requires the server to survive. It is +# to run under 10 seconds, which on tested systems only fails on +# 5-10% of runs. If it is seen to fail, but the failure cannot be +# reproduced, more reliable reproduction may be attempted by locally +# increasing the $rounds and $duration_seconds variables: total test +# runtime is the product of those. Running 8 rounds of 12 seconds +# increased failure rate on the test systems to 50% when reproducing +# the original bug. +# + +--disable_query_log +# Expected side effects of repeatedly toggling innodb_buffer_pool_size +# concurrently with heavy write activity against a deliberately tiny +# pool: a resize can be superseded by the next one before it finishes, +# and the tiny pool can occasionally have nothing evictable on demand. +call mtr.add_suppression("innodb_buffer_pool_size change aborted"); +call mtr.add_suppression("Could not free any blocks in the buffer pool"); +--enable_query_log + +--let $old_scrub= `SELECT @@global.innodb_immediate_scrub_data_uncompressed` +--let $old_dirty_pct= `SELECT @@global.innodb_max_dirty_pages_pct` +--let $old_pool_size= `SELECT @@global.innodb_buffer_pool_size` + +SET GLOBAL innodb_immediate_scrub_data_uncompressed=1; +SET GLOBAL innodb_max_dirty_pages_pct=0; +SET GLOBAL innodb_buffer_pool_size= 16777216; + +# The workload is repeated across several rounds against the same live +# server; this makes the data race more likely than a single cold-started +# attempt, presumably due to fragmentation and partially-drained +# freed_ranges backlog left over by superseded resizes from previous +# rounds. + +--let $connections= 12 +--let $rounds= 3 +--let $duration_seconds= 3 + +delimiter |; +CREATE PROCEDURE process_temp_table(end_time INT UNSIGNED) +BEGIN + WHILE UNIX_TIMESTAMP() < end_time DO + CREATE TEMPORARY TABLE t1(c1 MEDIUMTEXT) ENGINE=InnoDB; + INSERT INTO t1 VALUES (repeat('a', 16777215)); + DROP TEMPORARY TABLE t1; + END WHILE; +END| + +# Toggle between different buffer pool sizes. +# +# The continue handler is for a scenario where a resize is +# superseded by the next one before it finishes and subsequently +# fails ("innodb_buffer_pool_size change aborted"); that is expected +# and harmless here, so the test ignores it and keeps toggling. +CREATE PROCEDURE toggle_pool_size(end_time INT UNSIGNED) +BEGIN + DECLARE CONTINUE HANDLER FOR 1221 BEGIN END; + WHILE UNIX_TIMESTAMP() < end_time DO + SET GLOBAL innodb_buffer_pool_size=16777216; + SET GLOBAL innodb_buffer_pool_size=6291456; + END WHILE; +END| +delimiter ;| + +--echo # +--echo # Run concurrent processing to trigger possible data race +--echo # + +--disable_query_log +--disable_result_log + +--let $round= 1 +while ($round <= $rounds) +{ + --let $end_time= query_get_value(SELECT UNIX_TIMESTAMP() + $duration_seconds AS t, t, 1) + + --let $i= 1 + while ($i <= $connections) + { + --connect (con$i,localhost,root,,) + --connection con$i + send_eval CALL process_temp_table($end_time); + --inc $i + } + + --connection default + eval CALL toggle_pool_size($end_time); + + --let $i= 1 + while ($i <= $connections) + { + --connection con$i + --reap + --disconnect con$i + --inc $i + } + --connection default + --inc $round +} + +--enable_result_log +--enable_query_log + +--echo # +--echo # Cleanup +--echo # + +DROP PROCEDURE process_temp_table; +DROP PROCEDURE toggle_pool_size; + +--disable_query_log +eval SET GLOBAL innodb_immediate_scrub_data_uncompressed= $old_scrub; +eval SET GLOBAL innodb_max_dirty_pages_pct= $old_dirty_pct; +eval SET GLOBAL innodb_buffer_pool_size= $old_pool_size; +--enable_query_log + +--echo # End of test diff --git a/mysql-test/suite/innodb_fts/r/create.result b/mysql-test/suite/innodb_fts/r/create.result index 661cccfb39b..2eba66ac450 100644 --- a/mysql-test/suite/innodb_fts/r/create.result +++ b/mysql-test/suite/innodb_fts/r/create.result @@ -211,3 +211,11 @@ ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for sys ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index DROP TABLE t1; +# +# MDEV-40985 row_end access out of bounds in ALTER TABLE +# +CREATE TABLE t1 +(a TEXT,b INT AS(1),c INT AS(1),d INT AS(1),e INT AS(1),f INT AS(1), +FULLTEXT INDEX(a)) ENGINE=InnoDB; +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index e0049506bb6..ece19cee594 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -844,5 +844,18 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 fulltext b b 0 1 Using where DROP TABLE t1, t2; # +# MDEV-41022 Wildcard term returns no rows when combined with a +# phrase in boolean search +# +CREATE TABLE t1(f1 TEXT, FULLTEXT(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('auth code out'); +SELECT * FROM t1 WHERE MATCH(f1) AGAINST('"zzzz" aut*' IN BOOLEAN MODE); +f1 +auth code out +SELECT * FROM t1 WHERE MATCH(f1) AGAINST('"zzzz yyyy" @3 aut*' IN BOOLEAN MODE); +f1 +auth code out +DROP TABLE t1; +# # End of 10.11 tests # diff --git a/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff b/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff index b0825d0cd85..b141d4f0f9e 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff +++ b/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff @@ -1,5 +1,5 @@ --- misc_debug.result -+++ misc_debug.reject ++++ misc_debug,vers.result @@ -7,14 +7,14 @@ SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail"; @@ -51,7 +51,7 @@ # MDEV-25663 Double free of transaction during TRUNCATE # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); -@@ -65,12 +39,3 @@ +@@ -65,15 +39,6 @@ SET debug_dbug=@saved_debug_dbug; DROP TABLE t1; # End of 10.3 tests @@ -64,3 +64,6 @@ -ALTER TABLE t1 ADD FULLTEXT(f2); -ERROR HY000: Tablespace has been discarded for table `t1` -DROP TABLE t1; + # + # MDEV-40324 use-of-uninitialized-value after creation of + # FULLTEXT table failure diff --git a/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff b/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff index b0825d0cd85..6bd724a4b7f 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff +++ b/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff @@ -1,5 +1,5 @@ --- misc_debug.result -+++ misc_debug.reject ++++ misc_debug,vers_trx.result @@ -7,14 +7,14 @@ SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail"; @@ -51,7 +51,7 @@ # MDEV-25663 Double free of transaction during TRUNCATE # call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); -@@ -65,12 +39,3 @@ +@@ -65,15 +39,6 @@ SET debug_dbug=@saved_debug_dbug; DROP TABLE t1; # End of 10.3 tests @@ -64,3 +64,6 @@ -ALTER TABLE t1 ADD FULLTEXT(f2); -ERROR HY000: Tablespace has been discarded for table `t1` -DROP TABLE t1; + # + # MDEV-40324 use-of-uninitialized-value after creation of + # FULLTEXT table failure diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result index cdfc4ff489a..159e6dd33da 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug.result +++ b/mysql-test/suite/innodb_fts/r/misc_debug.result @@ -74,3 +74,11 @@ ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 ADD FULLTEXT(f2); ERROR HY000: Tablespace has been discarded for table `t1` DROP TABLE t1; +# +# MDEV-40324 use-of-uninitialized-value after creation of +# FULLTEXT table failure +# +call mtr.add_suppression("InnoDB: Failed to create FTS index table"); +SET STATEMENT DEBUG_DBUG="+d,fts_index_table_fail" FOR +CREATE TABLE t1(f1 TEXT, FULLTEXT(f1))ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t1` (errno: 168 "Unknown (generic) error from engine") diff --git a/mysql-test/suite/innodb_fts/t/create.test b/mysql-test/suite/innodb_fts/t/create.test index 9d88c1eddd4..e4f21515077 100644 --- a/mysql-test/suite/innodb_fts/t/create.test +++ b/mysql-test/suite/innodb_fts/t/create.test @@ -142,3 +142,13 @@ ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; --error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; DROP TABLE t1; + +--echo # +--echo # MDEV-40985 row_end access out of bounds in ALTER TABLE +--echo # + +CREATE TABLE t1 +(a TEXT,b INT AS(1),c INT AS(1),d INT AS(1),e INT AS(1),f INT AS(1), + FULLTEXT INDEX(a)) ENGINE=InnoDB; +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 6318f16883c..144c6611c2d 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -851,6 +851,16 @@ WHERE EXISTS ( # Cleanup DROP TABLE t1, t2; +--echo # +--echo # MDEV-41022 Wildcard term returns no rows when combined with a +--echo # phrase in boolean search +--echo # +CREATE TABLE t1(f1 TEXT, FULLTEXT(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('auth code out'); +SELECT * FROM t1 WHERE MATCH(f1) AGAINST('"zzzz" aut*' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f1) AGAINST('"zzzz yyyy" @3 aut*' IN BOOLEAN MODE); +DROP TABLE t1; + --echo # --echo # End of 10.11 tests --echo # diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test index 76b54a69f15..bfe27f2c3f4 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug.test @@ -129,3 +129,12 @@ ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 ADD FULLTEXT(f2); DROP TABLE t1; } + +--echo # +--echo # MDEV-40324 use-of-uninitialized-value after creation of +--echo # FULLTEXT table failure +--echo # +call mtr.add_suppression("InnoDB: Failed to create FTS index table"); +--error ER_CANT_CREATE_TABLE +SET STATEMENT DEBUG_DBUG="+d,fts_index_table_fail" FOR +CREATE TABLE t1(f1 TEXT, FULLTEXT(f1))ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb_gis/r/rtree_search.result b/mysql-test/suite/innodb_gis/r/rtree_search.result index d8a8d209cd3..0821b5dac51 100644 --- a/mysql-test/suite/innodb_gis/r/rtree_search.result +++ b/mysql-test/suite/innodb_gis/r/rtree_search.result @@ -250,3 +250,39 @@ count(*) drop procedure curdemo; drop table t3; drop table t1; +CREATE TABLE t1 (pt POINT NOT NULL, SPATIAL INDEX(pt)) ENGINE=InnoDB; +INSERT INTO t1 (pt) VALUES +(POINT(1,1)),(POINT(1,2)),(POINT(1,3)),(POINT(1,4)), +(POINT(2,1)),(POINT(2,2)),(POINT(2,3)),(POINT(2,4)), +(POINT(3,1)),(POINT(3,2)),(POINT(3,3)),(POINT(3,4)), +(POINT(4,1)),(POINT(4,2)),(POINT(4,3)),(POINT(4,4)), +(POINT(5,1)),(POINT(5,2)),(POINT(5,3)),(POINT(5,4)), +(POINT(6,1)),(POINT(6,2)),(POINT(6,3)),(POINT(6,4)), +(POINT(7,1)),(POINT(7,2)),(POINT(7,3)),(POINT(7,4)), +(POINT(8,1)),(POINT(8,2)),(POINT(8,3)),(POINT(8,4)), +(POINT(90,90)),(POINT(91,91)),(POINT(92,92)),(POINT(93,93)), +(POINT(94,94)),(POINT(95,95)),(POINT(96,96)),(POINT(97,97)); +EXPLAIN SELECT COUNT(*) FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range pt pt 34 NULL # Using where +connect con1,localhost,root,,test; +BEGIN; +SELECT * FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')) +FOR UPDATE; +connect con2,localhost,root,,test; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +SELECT COUNT(*) FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')); +connection con1; +ROLLBACK; +connection con2; +COUNT(*) +32 +COMMIT; +connection default; +disconnect con1; +disconnect con2; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_gis/t/rtree_search.test b/mysql-test/suite/innodb_gis/t/rtree_search.test index 6bbd84a25cf..8115dc921a1 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_search.test +++ b/mysql-test/suite/innodb_gis/t/rtree_search.test @@ -138,4 +138,53 @@ select count(*) from t3; drop procedure curdemo; drop table t3; drop table t1; +# +# MDEV-40404 : buf_page_t::init() assertion failure in rtr_init_match() +# +CREATE TABLE t1 (pt POINT NOT NULL, SPATIAL INDEX(pt)) ENGINE=InnoDB; +INSERT INTO t1 (pt) VALUES +(POINT(1,1)),(POINT(1,2)),(POINT(1,3)),(POINT(1,4)), +(POINT(2,1)),(POINT(2,2)),(POINT(2,3)),(POINT(2,4)), +(POINT(3,1)),(POINT(3,2)),(POINT(3,3)),(POINT(3,4)), +(POINT(4,1)),(POINT(4,2)),(POINT(4,3)),(POINT(4,4)), +(POINT(5,1)),(POINT(5,2)),(POINT(5,3)),(POINT(5,4)), +(POINT(6,1)),(POINT(6,2)),(POINT(6,3)),(POINT(6,4)), +(POINT(7,1)),(POINT(7,2)),(POINT(7,3)),(POINT(7,4)), +(POINT(8,1)),(POINT(8,2)),(POINT(8,3)),(POINT(8,4)), +(POINT(90,90)),(POINT(91,91)),(POINT(92,92)),(POINT(93,93)), +(POINT(94,94)),(POINT(95,95)),(POINT(96,96)),(POINT(97,97)); +--replace_column 9 # +EXPLAIN SELECT COUNT(*) FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')); + +--connect (con1,localhost,root,,test) +BEGIN; +--disable_result_log +SELECT * FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')) +FOR UPDATE; +--enable_result_log + +--connect (con2,localhost,root,,test) +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +--send +SELECT COUNT(*) FROM t1 FORCE INDEX(pt) +WHERE ST_Within(pt, ST_GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))')); + +--connection con1 +let $wait_condition= + SELECT COUNT(*)=1 FROM information_schema.innodb_trx + WHERE trx_state='LOCK WAIT'; +--source include/wait_condition.inc +ROLLBACK; + +--connection con2 +--reap +COMMIT; + +--connection default +--disconnect con1 +--disconnect con2 +DROP TABLE t1; diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 1460b665133..caa9633e9cc 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -1295,6 +1295,124 @@ COLLATION(virtual_table_from_json.property) utf8mb4_uca1400_ai_ci DROP TABLE table_with_longtext_column; DROP DATABASE collation_testing; +# +# MDEV-39969: JSON_TABLE conversion of numeric values to BIT +# +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[0,1]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$')) AS jt ORDER BY ord; +ord bit_value +1 0 +2 1 +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[0,2,255,256,0.4,0.5,1.5,1e1,1e-1]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(9) PATH '$')) AS jt ORDER BY ord; +ord bit_value +1 0 +2 2 +3 255 +4 256 +5 0 +6 1 +7 2 +8 10 +9 0 +SELECT ord, b+0 AS bit_value, b+0 = u AS matches_unsigned +FROM JSON_TABLE('[9223372036854775808,18446744073709551615]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(64) PATH '$', +u BIGINT UNSIGNED PATH '$')) AS jt ORDER BY ord; +ord bit_value matches_unsigned +1 9223372036854775808 1 +2 18446744073709551615 1 +SELECT ord, b+0 AS bit_value, i, s +FROM JSON_TABLE('[false,true]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$', +i INT PATH '$', s VARCHAR(5) PATH '$')) AS jt ORDER BY ord; +ord bit_value i s +1 0 0 false +2 1 1 true +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('["0","1",null]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(8) PATH '$')) AS jt ORDER BY ord; +ord bit_value +1 48 +2 49 +3 NULL +SELECT i, d, f = 1e100 AS real_value_matches, s, dt +FROM JSON_TABLE('[{"n":1e2,"f":1e100,"d":20260924}]', '$[*]' + COLUMNS (i INT PATH '$.n', d DECIMAL(6,2) PATH '$.n', +f DOUBLE PATH '$.f', s VARCHAR(10) PATH '$.n', +dt DATE PATH '$.d')) AS jt; +i d real_value_matches s dt +100 100.00 1 1e2 2026-09-24 +SELECT ord, b+0 AS bit_value, s +FROM JSON_TABLE(CONVERT('[false,true,0,1]' USING utf8mb4), '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$', +s VARCHAR(5) PATH '$')) AS jt ORDER BY ord; +ord bit_value s +1 0 false +2 1 true +3 0 0 +4 1 1 +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' COLUMNS (b BIT(1) PATH '$')) AS jt; +bit_value +1 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' + COLUMNS (b BIT(1) PATH '$' NULL ON ERROR)) AS jt; +bit_value +1 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT b+0 AS bit_value +FROM JSON_TABLE('[256]', '$[*]' + COLUMNS (b BIT(8) PATH '$' DEFAULT 'A' ON ERROR)) AS jt; +bit_value +255 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' + COLUMNS (b BIT(1) PATH '$' ERROR ON ERROR)) AS jt; +bit_value +1 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[-1,18446744073709551616,1e1000]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(64) PATH '$')) AS jt ORDER BY ord; +ord bit_value +1 0 +2 18446744073709551615 +3 18446744073709551615 +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +Warning 1264 Out of range value for column 'b' at row 2 +Warning 1264 Out of range value for column 'b' at row 3 +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[{},[]]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$' NULL ON ERROR)) AS jt +ORDER BY ord; +ord bit_value +1 NULL +2 NULL +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(8) PATH '$' DEFAULT 'A' ON ERROR)) AS jt; +bit_value +65 +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(1) PATH '$' ERROR ON ERROR)) AS jt; +ERROR HY000: Can't store an array or an object in the scalar column 'b' of JSON_TABLE 'jt'. +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(8) PATH '$.missing' DEFAULT 'A' ON EMPTY)) AS jt; +bit_value +65 # End of 10.11 test use test; # diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index b2ba81fb4f1..d44490084ea 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -1116,6 +1116,67 @@ SELECT COLLATION(virtual_table_from_json.property) FROM JSON_TABLE((SELECT colum DROP TABLE table_with_longtext_column; DROP DATABASE collation_testing; +--echo # +--echo # MDEV-39969: JSON_TABLE conversion of numeric values to BIT +--echo # +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[0,1]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$')) AS jt ORDER BY ord; +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[0,2,255,256,0.4,0.5,1.5,1e1,1e-1]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(9) PATH '$')) AS jt ORDER BY ord; +SELECT ord, b+0 AS bit_value, b+0 = u AS matches_unsigned +FROM JSON_TABLE('[9223372036854775808,18446744073709551615]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(64) PATH '$', + u BIGINT UNSIGNED PATH '$')) AS jt ORDER BY ord; +SELECT ord, b+0 AS bit_value, i, s +FROM JSON_TABLE('[false,true]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$', + i INT PATH '$', s VARCHAR(5) PATH '$')) AS jt ORDER BY ord; +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('["0","1",null]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(8) PATH '$')) AS jt ORDER BY ord; +SELECT i, d, f = 1e100 AS real_value_matches, s, dt +FROM JSON_TABLE('[{"n":1e2,"f":1e100,"d":20260924}]', '$[*]' + COLUMNS (i INT PATH '$.n', d DECIMAL(6,2) PATH '$.n', + f DOUBLE PATH '$.f', s VARCHAR(10) PATH '$.n', + dt DATE PATH '$.d')) AS jt; +SELECT ord, b+0 AS bit_value, s +FROM JSON_TABLE(CONVERT('[false,true,0,1]' USING utf8mb4), '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$', + s VARCHAR(5) PATH '$')) AS jt ORDER BY ord; + +# Type conversion warnings must not invoke ON ERROR. +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' COLUMNS (b BIT(1) PATH '$')) AS jt; +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' + COLUMNS (b BIT(1) PATH '$' NULL ON ERROR)) AS jt; +SELECT b+0 AS bit_value +FROM JSON_TABLE('[256]', '$[*]' + COLUMNS (b BIT(8) PATH '$' DEFAULT 'A' ON ERROR)) AS jt; +SELECT b+0 AS bit_value +FROM JSON_TABLE('[2]', '$[*]' + COLUMNS (b BIT(1) PATH '$' ERROR ON ERROR)) AS jt; +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[-1,18446744073709551616,1e1000]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(64) PATH '$')) AS jt ORDER BY ord; + +# JSON structure errors still use the configured ON ERROR response. +SELECT ord, b+0 AS bit_value +FROM JSON_TABLE('[{},[]]', '$[*]' + COLUMNS (ord FOR ORDINALITY, b BIT(1) PATH '$' NULL ON ERROR)) AS jt +ORDER BY ord; +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(8) PATH '$' DEFAULT 'A' ON ERROR)) AS jt; +--error ER_JSON_TABLE_SCALAR_EXPECTED +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(1) PATH '$' ERROR ON ERROR)) AS jt; +SELECT b+0 AS bit_value +FROM JSON_TABLE('[{}]', '$[*]' + COLUMNS (b BIT(8) PATH '$.missing' DEFAULT 'A' ON EMPTY)) AS jt; --echo # End of 10.11 test use test; diff --git a/mysql-test/suite/multi_source/mix_semisync_async.inc b/mysql-test/suite/multi_source/mix_semisync_async.inc new file mode 100644 index 00000000000..c9fad636e11 --- /dev/null +++ b/mysql-test/suite/multi_source/mix_semisync_async.inc @@ -0,0 +1,84 @@ +# Test replicating from an additional connection of semi-sync mode `$mode2` +# does not interfere with the active connection of mode `$mode1`. +# +# Pre-Conditions: +# * On connection `slave`. +# * CHANGE MASTER `master1` and `master2` set up to +# replicate from the connection with the same name. +# * None of the replication threads are running. +# * User variables `$mode1` and `$mode2` contain +# corresponding `@@rpl_semi_sync_slave_enabled` values. +# +# Post-Conditions: +# * On connection `slave`. +# * None of the replication threads are running. +# * @@default_master_connection = 'master1', +# @@rpl_semi_sync_slave_enabled = $mode2 + +--let $status_var= Rpl_semi_sync_master_clients +--let $status_var_value= 1 + + +# Start `master1` +SET @@SESSION.default_master_connection= 'master1'; +--eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= $mode1 +--source include/start_slave.inc + +# Start `master2` +SET @@SESSION.default_master_connection= 'master2'; +--eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= $mode2 +--source include/start_slave.inc + + +# TODO MDEV-40941: +# `Rpl_semi_sync_slave_status` does not refer to `@@default_master_connection`, +# but rather the most recent START SLAVE (`$mode2` in this case). +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +SET @@SESSION.default_master_connection= 'master1'; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; + + +# Verify `master2` +--connection master2 + if ($mode2) + { + --source include/wait_for_status_var.inc + } + CREATE TABLE t2 (a INT); + DROP TABLE t2; + --save_master_pos +--connection slave +--sync_with_master 0, master2 + +# Verify `master1` +--connection master1 + if ($mode1) + { + --source include/wait_for_status_var.inc + } + CREATE TABLE t1 (a INT); + --save_master_pos +--connection slave +--sync_with_master 0, master1 +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; + + +# Stop `master2` +SET @@SESSION.default_master_connection= 'master2'; +--source include/stop_slave.inc +# TODO MDEV-40941: +# `Rpl_semi_sync_slave_status` shows OFF after STOP SLAVE on any connection. +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; + +# Verify `master1` +--connection master1 + DROP TABLE t1; + SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'; + --save_master_pos +--connection slave +--sync_with_master 0, master1 +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; + +# Stop `master1` +SET @@SESSION.default_master_connection= 'master1'; +--source include/stop_slave.inc diff --git a/mysql-test/suite/multi_source/mix_semisync_async.result b/mysql-test/suite/multi_source/mix_semisync_async.result new file mode 100644 index 00000000000..29b33ea0331 --- /dev/null +++ b/mysql-test/suite/multi_source/mix_semisync_async.result @@ -0,0 +1,109 @@ +# Setup +connect master1, 127.0.0.1, root, , , $SERVER_MYPORT_1; +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 0; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 1; +SET @@SESSION.gtid_domain_id= 1; +RESET MASTER; +connect master2, 127.0.0.1, root, , , $SERVER_MYPORT_2; +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 0; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 1; +SET @@SESSION.gtid_domain_id= 2; +RESET MASTER; +connect slave, 127.0.0.1, root, , , $SERVER_MYPORT_3; +SET @@GLOBAL.gtid_slave_pos= ''; +CHANGE MASTER 'master1' TO +master_host='127.0.0.1', master_port=SERVER_MYPORT_1, master_user='root'; +CHANGE MASTER 'master2' TO +master_host='127.0.0.1', master_port=SERVER_MYPORT_2, master_user='root'; +# Test semi-sync replication during async replication +SET @@SESSION.default_master_connection= 'master1'; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; +include/start_slave.inc +SET @@SESSION.default_master_connection= 'master2'; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= 1; +include/start_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +SET @@SESSION.default_master_connection= 'master1'; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +connection master2; +CREATE TABLE t2 (a INT); +DROP TABLE t2; +connection slave; +connection master1; +CREATE TABLE t1 (a INT); +connection slave; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; +Variable_name Value +Rpl_semi_sync_slave_send_ack 2 +SET @@SESSION.default_master_connection= 'master2'; +include/stop_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +connection master1; +DROP TABLE t1; +SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 0 +connection slave; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; +Variable_name Value +Rpl_semi_sync_slave_send_ack 2 +SET @@SESSION.default_master_connection= 'master1'; +include/stop_slave.inc +# Test the other order +SET @@SESSION.default_master_connection= 'master1'; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= 1; +include/start_slave.inc +SET @@SESSION.default_master_connection= 'master2'; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; +include/start_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +SET @@SESSION.default_master_connection= 'master1'; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +connection master2; +CREATE TABLE t2 (a INT); +DROP TABLE t2; +connection slave; +connection master1; +CREATE TABLE t1 (a INT); +connection slave; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; +Variable_name Value +Rpl_semi_sync_slave_send_ack 1 +SET @@SESSION.default_master_connection= 'master2'; +include/stop_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +connection master1; +DROP TABLE t1; +SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +connection slave; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_send_ack'; +Variable_name Value +Rpl_semi_sync_slave_send_ack 2 +SET @@SESSION.default_master_connection= 'master1'; +include/stop_slave.inc +# Cleanup +RESET SLAVE 'master1' ALL; +RESET SLAVE 'master2' ALL; +disconnect slave; +connection master1; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 0; +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 1; +disconnect master1; +connection master2; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 0; +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 1; +disconnect master2; diff --git a/mysql-test/suite/multi_source/mix_semisync_async.test b/mysql-test/suite/multi_source/mix_semisync_async.test new file mode 100644 index 00000000000..8e3b035e95f --- /dev/null +++ b/mysql-test/suite/multi_source/mix_semisync_async.test @@ -0,0 +1,63 @@ +# MDEV-32947 Async conflicts with semi-sync in multi-source +# +# With a async master and a semi-sync master, +# test replication does not mix async and semi-sync regardless of order + +--source include/have_binlog_format_mixed.inc # format-agnostic +--let $orig_wait_no_slave= `SELECT @@GLOBAL.rpl_semi_sync_master_wait_no_slave` + +--echo # Setup +# Enable semi-sync on both masters; +# the slave will disable semi-sync on one of its connections. + +--connect (master1, 127.0.0.1, root, , , $SERVER_MYPORT_1) +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 0; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 1; +SET @@SESSION.gtid_domain_id= 1; +RESET MASTER; + +--connect (master2, 127.0.0.1, root, , , $SERVER_MYPORT_2) +SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= 0; +SET @@GLOBAL.rpl_semi_sync_master_enabled= 1; +SET @@SESSION.gtid_domain_id= 2; +RESET MASTER; + +--connect (slave, 127.0.0.1, root, , , $SERVER_MYPORT_3) +--disable_warnings + SET @@GLOBAL.gtid_slave_pos= ''; +--enable_warnings + +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER 'master1' TO + master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root'; +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER 'master2' TO + master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root'; + + +--echo # Test semi-sync replication during async replication +--let $mode1= 0 +--let $mode2= 1 +--source mix_semisync_async.inc + +--echo # Test the other order +--let $mode1= 1 +--let $mode2= 0 +--source mix_semisync_async.inc + + +--echo # Cleanup + +RESET SLAVE 'master1' ALL; +RESET SLAVE 'master2' ALL; +--disconnect slave + +--connection master1 + SET @@GLOBAL.rpl_semi_sync_master_enabled= 0; + --eval SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= $orig_wait_no_slave +--disconnect master1 + +--connection master2 + SET @@GLOBAL.rpl_semi_sync_master_enabled= 0; + --eval SET @@GLOBAL.rpl_semi_sync_master_wait_no_slave= $orig_wait_no_slave +--disconnect master2 diff --git a/mysql-test/suite/multi_source/rpl_filter_default_master.result b/mysql-test/suite/multi_source/rpl_filter_default_master.result new file mode 100644 index 00000000000..044e8031c8c --- /dev/null +++ b/mysql-test/suite/multi_source/rpl_filter_default_master.result @@ -0,0 +1,19 @@ +SET @saved_replicate_do_db= @@GLOBAL.replicate_do_db; +SET @saved_default_master_connection= @@SESSION.default_master_connection; +CHANGE MASTER 'name' TO master_host='127.0.0.1', master_user='root'; +SET @@GLOBAL.replicate_do_db= 'unnamed'; +SET @@SESSION.default_master_connection= 'name'; +SET @@GLOBAL.replicate_do_db= 'named'; +SELECT @@GLOBAL.name.replicate_do_db; +@@GLOBAL.name.replicate_do_db +named +SELECT @@GLOBAL.replicate_do_db; +@@GLOBAL.replicate_do_db +named +SELECT @@GLOBAL.``.replicate_do_db; +@@GLOBAL.``.replicate_do_db +unnamed +RESET SLAVE ALL; +SET @@SESSION.default_master_connection= @saved_default_master_connection; +SET @@GLOBAL.replicate_do_db= @saved_replicate_do_db; +# End of 10.11 tests diff --git a/mysql-test/suite/multi_source/rpl_filter_default_master.test b/mysql-test/suite/multi_source/rpl_filter_default_master.test new file mode 100644 index 00000000000..3693b1fd8f1 --- /dev/null +++ b/mysql-test/suite/multi_source/rpl_filter_default_master.test @@ -0,0 +1,25 @@ +--source include/not_embedded.inc + +# MDEV-40296: SELECT @@GLOBAL.replicate_do_db ignores default_master_connection + +# Setup +SET @saved_replicate_do_db= @@GLOBAL.replicate_do_db; +SET @saved_default_master_connection= @@SESSION.default_master_connection; + +CHANGE MASTER 'name' TO master_host='127.0.0.1', master_user='root'; + +SET @@GLOBAL.replicate_do_db= 'unnamed'; +SET @@SESSION.default_master_connection= 'name'; +SET @@GLOBAL.replicate_do_db= 'named'; + +SELECT @@GLOBAL.name.replicate_do_db; +SELECT @@GLOBAL.replicate_do_db; +# MDEV-40297: Explicit empty connection name +SELECT @@GLOBAL.``.replicate_do_db; + +# Cleanup +RESET SLAVE ALL; +SET @@SESSION.default_master_connection= @saved_default_master_connection; +SET @@GLOBAL.replicate_do_db= @saved_replicate_do_db; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index 26fed19e4f7..7e2633cd0c8 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -480,6 +480,9 @@ Gtid_Slave_Pos Master_last_event_time NULL Slave_last_event_time NULL Master_Slave_time_diff NULL +# +# MDEV-40996: the connection name may be given as a variable +# stop all slaves; Warnings: Note 1938 SLAVE 'slave2' stopped diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test index 5894a205480..05f04553c45 100644 --- a/mysql-test/suite/multi_source/simple.test +++ b/mysql-test/suite/multi_source/simple.test @@ -77,6 +77,12 @@ reset slave 'slave1' all; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 $read_master_log_pos $relay_log_pos $relay_log_space1 $relay_log_space2 query_vertical show all slaves status; +--echo # +--echo # MDEV-40996: the connection name may be given as a variable +--echo # +--let $conn_name= slave2 +--sync_with_master 0,$conn_name + stop all slaves; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 $read_master_log_pos $relay_log_pos $relay_log_space1 $relay_log_space2 query_vertical show all slaves status; diff --git a/mysql-test/suite/multi_source/status_vars.result b/mysql-test/suite/multi_source/status_vars.result index 7e91829ab24..6290c2445c6 100644 --- a/mysql-test/suite/multi_source/status_vars.result +++ b/mysql-test/suite/multi_source/status_vars.result @@ -52,9 +52,7 @@ Variable_name Value Slave_received_heartbeats 0 start slave; include/wait_for_slave_to_start.inc -show status like 'Slave_received_heartbeats'; -Variable_name Value -Slave_received_heartbeats 2 +include/assert.inc [Slave_received_heartbeats is non-zero for the default connection] stop slave; include/wait_for_slave_to_stop.inc set default_master_connection = 'master1'; @@ -66,9 +64,7 @@ include/wait_for_slave_to_stop.inc change master to master_heartbeat_period=2; start slave; include/wait_for_slave_to_start.inc -show status like 'Slave_received_heartbeats'; -Variable_name Value -Slave_received_heartbeats 1 +include/assert.inc [Slave_received_heartbeats is non-zero for the default connection] # # Slave_open_temp_tables should be global # diff --git a/mysql-test/suite/multi_source/status_vars.test b/mysql-test/suite/multi_source/status_vars.test index eecf129e679..b5199f4b3ba 100644 --- a/mysql-test/suite/multi_source/status_vars.test +++ b/mysql-test/suite/multi_source/status_vars.test @@ -63,20 +63,32 @@ set default_master_connection = ''; stop slave sql_thread; --source include/wait_for_slave_sql_to_stop.inc change master to master_heartbeat_period=1; +# This read is unchanged because it is against a connection that stopped and +# thus should be stable. show status like 'Slave_received_heartbeats'; start slave; --source include/wait_for_slave_to_start.inc --let $status_var = Slave_received_heartbeats --let $status_var_value = 2 -# The units are tens of seconds ---let $status_timeout = 30 +# The counter keeps advancing while the connection runs, so it can already be +# above the target when the first poll happens. An equality wait could then +# time out. +--let $status_var_comparsion = >= +# The units are tenths of seconds +--let $status_timeout = 60 --source include/wait_for_status_var.inc -show status like 'Slave_received_heartbeats'; +--let $status_var_comparsion = +# For the same reason the exact value cannot be recorded. +--let $assert_text = Slave_received_heartbeats is non-zero for the default connection +--let $assert_cond = [SHOW STATUS LIKE "Slave_received_heartbeats", Value, 1] > 0 +--source include/assert.inc stop slave; --source include/wait_for_slave_to_stop.inc set default_master_connection = 'master1'; +# This read is unchanged because it is against a connection that stopped and +# thus should be stable. show status like 'Slave_received_heartbeats'; stop slave; @@ -87,9 +99,17 @@ start slave; --let $status_var = Slave_received_heartbeats --let $status_var_value = 1 ---let $status_timeout = 30 +# The counter keeps advancing while the connection runs, so it can already be +# above the target when the first poll happens. An equality wait could then +# time out. +--let $status_var_comparsion = >= +--let $status_timeout = 60 --source include/wait_for_status_var.inc -show status like 'Slave_received_heartbeats'; +--let $status_var_comparsion = +# For the same reason the exact value cannot be recorded. +--let $assert_text = Slave_received_heartbeats is non-zero for the default connection +--let $assert_cond = [SHOW STATUS LIKE "Slave_received_heartbeats", Value, 1] > 0 +--source include/assert.inc --echo # diff --git a/mysql-test/suite/parts/inc/partition_exchange.inc b/mysql-test/suite/parts/inc/partition_exchange.inc index 95a67a339d0..63ccdf61c66 100644 --- a/mysql-test/suite/parts/inc/partition_exchange.inc +++ b/mysql-test/suite/parts/inc/partition_exchange.inc @@ -352,3 +352,149 @@ SELECT * FROM t; SELECT * FROM tp; DROP TABLE t, tp, tsp; + + +--echo # +--echo # MDEV-38757 Exchange partition fails with compound expressions +--echo # + +--echo # Test EXCHANGE PARTITION with generated columns containing AND/OR conditions +--echo # This verifies set comparison of generated column conditions during +--echo # partition exchange. + +--echo # Test 1: Generated column with OR condition +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), + PARTITION p2 VALUES IN (2)); + +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; + +INSERT INTO t1_working (userId, col1) VALUES (1, 10), (1, 50), (1, 90); + +--echo # This should succeed: EXCHANGE PARTITION with OR condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; + +SELECT id, userId, col1, vcol1 FROM t1 ORDER BY id; +DROP TABLE t1_working; +DROP TABLE t1; + +--echo # Test 2: Generated column with AND condition +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + col2 INT NOT NULL, + vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); + +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; + +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 20, 50), (1, 5, 200); + +--echo # This should succeed: EXCHANGE PARTITION with AND condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; + +SELECT id, userId, col1, col2, vcol2 FROM t1 ORDER BY id; +DROP TABLE t1_working; +DROP TABLE t1; + +--echo # Test 3: Multiple generated columns with different AND/OR combinations +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + col2 INT NOT NULL, + vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, + vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, + vcol3 TINYINT(1) GENERATED ALWAYS AS (col2 > 50 OR col2 < 10) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), + PARTITION p2 VALUES IN (2)); + +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; + +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 15, 75), (1, 90, 5), (1, 50, 200); + +--echo # This should succeed: EXCHANGE PARTITION with multiple AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; + +SELECT id, userId, col1, col2, vcol1, vcol2, vcol3 FROM t1 ORDER BY id; +DROP TABLE t1_working; +DROP TABLE t1; + +--echo # Test 4: Nested AND/OR conditions +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + col2 INT NOT NULL, + col3 INT NOT NULL, + vcol4 TINYINT(1) GENERATED ALWAYS AS ((col1 > 10 AND col2 < 100) OR col3 > 50) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); + +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; + +INSERT INTO t1_working (userId, col1, col2, col3) VALUES (1, 20, 50, 30), (1, 5, 200, 60); + +--echo # This should succeed: EXCHANGE PARTITION with nested AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; + +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +DROP TABLE t1_working; + +DROP TABLE t1; + +--echo # Test 5: Reordered condition with a duplicate term +CREATE TABLE t1 ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + col2 INT NOT NULL, + col3 INT NOT NULL, + vcol4 TINYINT(1) GENERATED ALWAYS AS + (col1 > 10 AND col2 < 100 OR col3 > 50) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); + +CREATE TABLE t1_working ( + id INT NOT NULL AUTO_INCREMENT, + userId INT NOT NULL, + col1 INT NOT NULL, + col2 INT NOT NULL, + col3 INT NOT NULL, + vcol4 TINYINT(1) GENERATED ALWAYS AS + (col3 > 50 OR col1 > 10 AND col2 < 100 OR col3 > 50) STORED, + PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +INSERT INTO t1_working (userId, col1, col2, col3) +VALUES (1, 20, 50, 30), (1, 5, 200, 60); + +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; + +DROP TABLE t1_working; +DROP TABLE t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/parts/r/mdev_40995.result b/mysql-test/suite/parts/r/mdev_40995.result new file mode 100644 index 00000000000..f187b37412d --- /dev/null +++ b/mysql-test/suite/parts/r/mdev_40995.result @@ -0,0 +1,28 @@ +# +# MDEV-40995 concurrent INSERT ... SELECT on a partitioned InnoDB table +# can leave the table-level AUTO_INCREMENT counter behind MAX(pk) +# +CREATE TABLE t1 ( +id INT AUTO_INCREMENT, +pk2 INT NOT NULL, +a INT, +PRIMARY KEY (id, pk2), +UNIQUE KEY (a, pk2) +) ENGINE=InnoDB PARTITION BY HASH(pk2) PARTITIONS 2; +INSERT INTO t1 (pk2, a) VALUES (1, 10), (1, 100), (1, 110); +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connection con1; +SET DEBUG_SYNC = 'ha_partition_get_auto_increment_after_reservation SIGNAL start_t2 WAIT_FOR t2_done EXECUTE 1'; +INSERT INTO t1 (pk2, a) SELECT pk2, a+10 FROM t1 WHERE pk2=1 ORDER BY a;; +connection con2; +SET DEBUG_SYNC = 'now WAIT_FOR start_t2'; +INSERT INTO t1 (pk2, a) VALUES (2, 200); +SET DEBUG_SYNC = 'now SIGNAL t2_done'; +connection con1; +ERROR 23000: Duplicate entry '110-1' for key 'a' +connection default; +INSERT INTO t1 (pk2, a) VALUES (2, 300); +INSERT INTO t1 (pk2, a) VALUES (2, 400); +DROP TABLE t1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/parts/r/partition_debug.result b/mysql-test/suite/parts/r/partition_debug.result index f90eb1027ad..d35d4f403dc 100644 --- a/mysql-test/suite/parts/r/partition_debug.result +++ b/mysql-test/suite/parts/r/partition_debug.result @@ -5184,3 +5184,29 @@ select * from tp2; x 12 drop table tp2; +# +# MDEV-41545 Unchecked get_clone() in ALTER of partitioned table +# crashes on out-of-memory +# +create table t1 (x int) partition by range (x) +(partition p0 values less than (10)); +insert t1 values (1); +lock tables t1 write; +set @save_dbug= @@debug_dbug; +set debug_dbug= '+d,prep_alter_part_table_get_clone_oom'; +alter table t1 add partition (partition p1 values less than (20)); +ERROR HY000: Out of memory. +set debug_dbug= @save_dbug; +select * from t1; +x +1 +unlock tables; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = MyISAM) +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/suite/parts/r/partition_exchange_innodb.result b/mysql-test/suite/parts/r/partition_exchange_innodb.result index 17f9f0c36d0..df05adfc204 100644 --- a/mysql-test/suite/parts/r/partition_exchange_innodb.result +++ b/mysql-test/suite/parts/r/partition_exchange_innodb.result @@ -373,3 +373,136 @@ a b 63 Sixty three, new 99 End of values DROP TABLE t, tp, tsp; +# +# MDEV-38757 Exchange partition fails with compound expressions +# +# Test EXCHANGE PARTITION with generated columns containing AND/OR conditions +# This verifies set comparison of generated column conditions during +# partition exchange. +# Test 1: Generated column with OR condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1) VALUES (1, 10), (1, 50), (1, 90); +# This should succeed: EXCHANGE PARTITION with OR condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, vcol1 FROM t1 ORDER BY id; +id userId col1 vcol1 +1 1 10 1 +2 1 50 0 +3 1 90 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 2: Generated column with AND condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 20, 50), (1, 5, 200); +# This should succeed: EXCHANGE PARTITION with AND condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol2 FROM t1 ORDER BY id; +id userId col1 col2 vcol2 +1 1 20 50 1 +2 1 5 200 0 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 3: Multiple generated columns with different AND/OR combinations +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +vcol3 TINYINT(1) GENERATED ALWAYS AS (col2 > 50 OR col2 < 10) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 15, 75), (1, 90, 5), (1, 50, 200); +# This should succeed: EXCHANGE PARTITION with multiple AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol1, vcol2, vcol3 FROM t1 ORDER BY id; +id userId col1 col2 vcol1 vcol2 vcol3 +1 1 15 75 1 1 1 +2 1 90 5 1 1 1 +3 1 50 200 0 0 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 4: Nested AND/OR conditions +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS ((col1 > 10 AND col2 < 100) OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2, col3) VALUES (1, 20, 50, 30), (1, 5, 200, 60); +# This should succeed: EXCHANGE PARTITION with nested AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 5: Reordered condition with a duplicate term +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col3 > 50 OR col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +INSERT INTO t1_working (userId, col1, col2, col3) +VALUES (1, 20, 50, 30), (1, 5, 200, 60); +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/suite/parts/r/partition_exchange_memory.result b/mysql-test/suite/parts/r/partition_exchange_memory.result index 9f7852aa225..ad17290325f 100644 --- a/mysql-test/suite/parts/r/partition_exchange_memory.result +++ b/mysql-test/suite/parts/r/partition_exchange_memory.result @@ -373,3 +373,136 @@ a b 63 Sixty three, new 99 End of values DROP TABLE t, tp, tsp; +# +# MDEV-38757 Exchange partition fails with compound expressions +# +# Test EXCHANGE PARTITION with generated columns containing AND/OR conditions +# This verifies set comparison of generated column conditions during +# partition exchange. +# Test 1: Generated column with OR condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1) VALUES (1, 10), (1, 50), (1, 90); +# This should succeed: EXCHANGE PARTITION with OR condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, vcol1 FROM t1 ORDER BY id; +id userId col1 vcol1 +1 1 10 1 +2 1 50 0 +3 1 90 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 2: Generated column with AND condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 20, 50), (1, 5, 200); +# This should succeed: EXCHANGE PARTITION with AND condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol2 FROM t1 ORDER BY id; +id userId col1 col2 vcol2 +1 1 20 50 1 +2 1 5 200 0 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 3: Multiple generated columns with different AND/OR combinations +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +vcol3 TINYINT(1) GENERATED ALWAYS AS (col2 > 50 OR col2 < 10) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 15, 75), (1, 90, 5), (1, 50, 200); +# This should succeed: EXCHANGE PARTITION with multiple AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol1, vcol2, vcol3 FROM t1 ORDER BY id; +id userId col1 col2 vcol1 vcol2 vcol3 +1 1 15 75 1 1 1 +2 1 90 5 1 1 1 +3 1 50 200 0 0 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 4: Nested AND/OR conditions +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS ((col1 > 10 AND col2 < 100) OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2, col3) VALUES (1, 20, 50, 30), (1, 5, 200, 60); +# This should succeed: EXCHANGE PARTITION with nested AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 5: Reordered condition with a duplicate term +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col3 > 50 OR col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +INSERT INTO t1_working (userId, col1, col2, col3) +VALUES (1, 20, 50, 30), (1, 5, 200, 60); +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/suite/parts/r/partition_exchange_myisam.result b/mysql-test/suite/parts/r/partition_exchange_myisam.result index 0dceb4537d2..0ab1007d2e2 100644 --- a/mysql-test/suite/parts/r/partition_exchange_myisam.result +++ b/mysql-test/suite/parts/r/partition_exchange_myisam.result @@ -373,3 +373,136 @@ a b 63 Sixty three, new 99 End of values DROP TABLE t, tp, tsp; +# +# MDEV-38757 Exchange partition fails with compound expressions +# +# Test EXCHANGE PARTITION with generated columns containing AND/OR conditions +# This verifies set comparison of generated column conditions during +# partition exchange. +# Test 1: Generated column with OR condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1) VALUES (1, 10), (1, 50), (1, 90); +# This should succeed: EXCHANGE PARTITION with OR condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, vcol1 FROM t1 ORDER BY id; +id userId col1 vcol1 +1 1 10 1 +2 1 50 0 +3 1 90 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 2: Generated column with AND condition +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 20, 50), (1, 5, 200); +# This should succeed: EXCHANGE PARTITION with AND condition +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol2 FROM t1 ORDER BY id; +id userId col1 col2 vcol2 +1 1 20 50 1 +2 1 5 200 0 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 3: Multiple generated columns with different AND/OR combinations +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +vcol1 TINYINT(1) GENERATED ALWAYS AS (col1 > 80 OR col1 < 20) STORED, +vcol2 TINYINT(1) GENERATED ALWAYS AS (col1 > 10 AND col2 < 100) STORED, +vcol3 TINYINT(1) GENERATED ALWAYS AS (col2 > 50 OR col2 < 10) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1), +PARTITION p2 VALUES IN (2)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2) VALUES (1, 15, 75), (1, 90, 5), (1, 50, 200); +# This should succeed: EXCHANGE PARTITION with multiple AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, vcol1, vcol2, vcol3 FROM t1 ORDER BY id; +id userId col1 col2 vcol1 vcol2 vcol3 +1 1 15 75 1 1 1 +2 1 90 5 1 1 1 +3 1 50 200 0 0 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 4: Nested AND/OR conditions +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS ((col1 > 10 AND col2 < 100) OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working LIKE t1; +ALTER TABLE t1_working REMOVE PARTITIONING; +INSERT INTO t1_working (userId, col1, col2, col3) VALUES (1, 20, 50, 30), (1, 5, 200, 60); +# This should succeed: EXCHANGE PARTITION with nested AND/OR conditions +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# Test 5: Reordered condition with a duplicate term +CREATE TABLE t1 ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci +PARTITION BY LIST (userId) +(PARTITION p1 VALUES IN (1)); +CREATE TABLE t1_working ( +id INT NOT NULL AUTO_INCREMENT, +userId INT NOT NULL, +col1 INT NOT NULL, +col2 INT NOT NULL, +col3 INT NOT NULL, +vcol4 TINYINT(1) GENERATED ALWAYS AS +(col3 > 50 OR col1 > 10 AND col2 < 100 OR col3 > 50) STORED, +PRIMARY KEY (id, userId) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +INSERT INTO t1_working (userId, col1, col2, col3) +VALUES (1, 20, 50, 30), (1, 5, 200, 60); +ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_working; +SELECT id, userId, col1, col2, col3, vcol4 FROM t1 ORDER BY id; +id userId col1 col2 col3 vcol4 +1 1 20 50 30 1 +2 1 5 200 60 1 +DROP TABLE t1_working; +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index a578d159198..9ccc5592b2c 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -232,7 +232,7 @@ DROP TABLE t1; # Bug#53676: Unexpected errors and possible table corruption on # ADD PARTITION and LOCK TABLE CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) -ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; +ENGINE = InnoDB STATS_PERSISTENT=0 PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); LOCK TABLE t1 READ; connect con2,localhost,root,,; diff --git a/mysql-test/suite/parts/t/mdev_40995-master.opt b/mysql-test/suite/parts/t/mdev_40995-master.opt new file mode 100644 index 00000000000..571c7877f11 --- /dev/null +++ b/mysql-test/suite/parts/t/mdev_40995-master.opt @@ -0,0 +1 @@ +--innodb-autoinc-lock-mode=2 diff --git a/mysql-test/suite/parts/t/mdev_40995.test b/mysql-test/suite/parts/t/mdev_40995.test new file mode 100644 index 00000000000..d00ad9e032d --- /dev/null +++ b/mysql-test/suite/parts/t/mdev_40995.test @@ -0,0 +1,41 @@ +--source include/have_debug_sync.inc +--source include/have_partition.inc +--source include/have_innodb.inc + +--echo # +--echo # MDEV-40995 concurrent INSERT ... SELECT on a partitioned InnoDB table +--echo # can leave the table-level AUTO_INCREMENT counter behind MAX(pk) +--echo # + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT, + pk2 INT NOT NULL, + a INT, + PRIMARY KEY (id, pk2), + UNIQUE KEY (a, pk2) +) ENGINE=InnoDB PARTITION BY HASH(pk2) PARTITIONS 2; + +INSERT INTO t1 (pk2, a) VALUES (1, 10), (1, 100), (1, 110); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) + +--connection con1 +SET DEBUG_SYNC = 'ha_partition_get_auto_increment_after_reservation SIGNAL start_t2 WAIT_FOR t2_done EXECUTE 1'; +--send INSERT INTO t1 (pk2, a) SELECT pk2, a+10 FROM t1 WHERE pk2=1 ORDER BY a; + +--connection con2 +SET DEBUG_SYNC = 'now WAIT_FOR start_t2'; +INSERT INTO t1 (pk2, a) VALUES (2, 200); +SET DEBUG_SYNC = 'now SIGNAL t2_done'; + +--connection con1 +--error ER_DUP_ENTRY +--reap + +--connection default +INSERT INTO t1 (pk2, a) VALUES (2, 300); +INSERT INTO t1 (pk2, a) VALUES (2, 400); + +DROP TABLE t1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/parts/t/partition_debug.test b/mysql-test/suite/parts/t/partition_debug.test index 2f8994705f3..cc181e1be77 100644 --- a/mysql-test/suite/parts/t/partition_debug.test +++ b/mysql-test/suite/parts/t/partition_debug.test @@ -161,3 +161,23 @@ set session debug_dbug=@save_dbug; show create table tp2; select * from tp2; drop table tp2; + +--echo # +--echo # MDEV-41545 Unchecked get_clone() in ALTER of partitioned table +--echo # crashes on out-of-memory +--echo # +create table t1 (x int) partition by range (x) +(partition p0 values less than (10)); +insert t1 values (1); +lock tables t1 write; +set @save_dbug= @@debug_dbug; +set debug_dbug= '+d,prep_alter_part_table_get_clone_oom'; +--error ER_OUT_OF_RESOURCES +alter table t1 add partition (partition p1 values less than (20)); +set debug_dbug= @save_dbug; +select * from t1; +unlock tables; +show create table t1; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test index 9c6bf5054f0..9cf51755b50 100644 --- a/mysql-test/suite/parts/t/partition_special_innodb.test +++ b/mysql-test/suite/parts/t/partition_special_innodb.test @@ -78,8 +78,9 @@ DROP TABLE t1; --echo # --echo # Bug#53676: Unexpected errors and possible table corruption on --echo # ADD PARTITION and LOCK TABLE +# Avoid a MDL conflict between statistics recalc and the DROP TABLE below CREATE TABLE t1 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) - ENGINE = InnoDB PARTITION BY HASH(i) PARTITIONS 2; + ENGINE = InnoDB STATS_PERSISTENT=0 PARTITION BY HASH(i) PARTITIONS 2; INSERT INTO t1 VALUES (2, 2), (3, 3), (4, 4), (5, 5); LOCK TABLE t1 READ; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_again_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_again_deny.result index 996b5646a71..7b604b88cd5 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_again_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_again_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_bad_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_bad_deny.result index 1206762e239..66994435d3b 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_bad_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_bad_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_good_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_good_deny.result index 7d4d6d7c179..b4788fcb28f 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_good_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_good_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("192.0.2.4"); +call mtr.add_suppression("Host 'santa.claus.ipv4.example.com' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_noname_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_noname_deny.result index f6156a2231e..eeb836a16ab 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_noname_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_addrinfo_noname_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_blocked.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_blocked.result index bbaa0e86d80..7a7b138ef00 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_blocked.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_blocked.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Host '192.0.2.4' is blocked because of many connection errors"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_nameinfo_again_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_nameinfo_again_deny.result index f09aa6a1560..2d17d04e354 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv4_nameinfo_again_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_nameinfo_again_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("192.0.2.4"); +call mtr.add_suppression("Host 'santa.claus.ipv4.example.com' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_again_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_again_deny.result index cb10c044c7e..41bdec66361 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_again_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_again_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_bad_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_bad_deny.result index 08f0c4b0004..b7c009d93cf 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_bad_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_bad_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_good_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_good_deny.result index 037a0a1d57f..cc0fe53aead 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_good_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_good_deny.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Host 'santa.claus.ipv6.example.com' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_noname_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_noname_deny.result index 830dcb94289..0e562be9142 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_noname_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_addrinfo_noname_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_blocked.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_blocked.result index 97f35486ce0..942acea903b 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_blocked.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_blocked.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv6_nameinfo_again_deny.result b/mysql-test/suite/perfschema/r/hostcache_ipv6_nameinfo_again_deny.result index a72ad2270f7..20da6b0e5cd 100644 --- a/mysql-test/suite/perfschema/r/hostcache_ipv6_nameinfo_again_deny.result +++ b/mysql-test/suite/perfschema/r/hostcache_ipv6_nameinfo_again_deny.result @@ -1,4 +1,5 @@ call mtr.add_suppression("2001:db8::6:6"); +call mtr.add_suppression("Host 'santa.claus.ipv6.example.com' is not allowed to connect to this MariaDB server"); flush global status; flush hosts; flush user_resources; diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_again_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_again_deny.test index 96a8dc68873..0023cb789ca 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_again_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_again_deny.test @@ -14,6 +14,7 @@ # [Warning] Host name 'santa.claus.ipv4.example.com' could not be resolved: # Temporary failure in name resolution call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_bad_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_bad_deny.test index e78a80a81a2..4d7f33972fe 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_bad_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_bad_deny.test @@ -16,6 +16,7 @@ # [Note] - 192.0.2.126 # [Note] - 192.0.2.127 call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_good_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_good_deny.test index b935c494ab1..30254608f8a 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_good_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_good_deny.test @@ -14,6 +14,7 @@ # [Warning] IP address '192.0.2.4' could not be resolved: # no reverse address mapping. call mtr.add_suppression("192.0.2.4"); +call mtr.add_suppression("Host 'santa.claus.ipv4.example.com' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_noname_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_noname_deny.test index 104d0301928..dfaba9e4b61 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_noname_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_addrinfo_noname_deny.test @@ -14,6 +14,7 @@ # [Warning] Host name 'santa.claus.ipv4.example.com' could not be resolved: # Name or service not known call mtr.add_suppression("santa.claus.ipv4.example.com"); +call mtr.add_suppression("Host '192.0.2.4' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_blocked.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_blocked.test index 4e1ecc05e54..7f7d58fc515 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_blocked.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_blocked.test @@ -13,6 +13,8 @@ --source include/have_perfschema.inc --source include/have_hostname_cache.inc +call mtr.add_suppression("Host '192.0.2.4' is blocked because of many connection errors"); + # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc --source ../include/hostcache_set_state.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_nameinfo_again_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_nameinfo_again_deny.test index f1ab2aef31d..fd70be87191 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv4_nameinfo_again_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_nameinfo_again_deny.test @@ -14,6 +14,7 @@ # [Warning] IP address '192.0.2.4' could not be resolved: # Temporary failure in name resolution call mtr.add_suppression("192.0.2.4"); +call mtr.add_suppression("Host 'santa.claus.ipv4.example.com' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_again_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_again_deny.test index faa85bb6a06..07d430c746e 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_again_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_again_deny.test @@ -15,6 +15,7 @@ # [Warning] Host name 'santa.claus.ipv6.example.com' could not be resolved: # Temporary failure in name resolution call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_bad_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_bad_deny.test index d712a4e924d..9bc19e054a4 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_bad_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_bad_deny.test @@ -17,6 +17,7 @@ # [Note] - 2001:db8::6:7e # [Note] - 2001:db8::6:7f call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_good_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_good_deny.test index 0bc34324176..a99d84d6e81 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_good_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_good_deny.test @@ -12,6 +12,8 @@ --source include/have_perfschema.inc --source include/have_hostname_cache.inc +call mtr.add_suppression("Host 'santa.claus.ipv6.example.com' is not allowed to connect to this MariaDB server"); + # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc --source ../include/hostcache_set_state.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_noname_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_noname_deny.test index 264ad05f9ca..3ec53ada6ca 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_noname_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_addrinfo_noname_deny.test @@ -15,6 +15,7 @@ # [Warning] Host name 'santa.claus.ipv6.example.com' could not be resolved: # Name or service not known call mtr.add_suppression("santa.claus.ipv6.example.com"); +call mtr.add_suppression("Host '2001:db8::6:6' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_blocked.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_blocked.test index 009ee6fb805..9b11990fe1c 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_blocked.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_blocked.test @@ -13,6 +13,8 @@ --source include/check_ipv6.inc --source include/have_perfschema.inc +call mtr.add_suppression("Host '2001:db8::6:6' is blocked because of many connection errors"); + # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc --source ../include/hostcache_set_state.inc diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv6_nameinfo_again_deny.test b/mysql-test/suite/perfschema/t/hostcache_ipv6_nameinfo_again_deny.test index 4db609a7f2c..6d46544ea5c 100644 --- a/mysql-test/suite/perfschema/t/hostcache_ipv6_nameinfo_again_deny.test +++ b/mysql-test/suite/perfschema/t/hostcache_ipv6_nameinfo_again_deny.test @@ -15,6 +15,7 @@ # [Warning] IP address '2001:db8::6:6' could not be resolved: # Temporary failure in name resolution call mtr.add_suppression("2001:db8::6:6"); +call mtr.add_suppression("Host 'santa.claus.ipv6.example.com' is not allowed to connect to this MariaDB server"); # Enforce a clean state --source ../include/wait_for_pfs_thread_count.inc diff --git a/mysql-test/suite/period/r/alter.result b/mysql-test/suite/period/r/alter.result index 2818aa85fdd..29aa304bf12 100644 --- a/mysql-test/suite/period/r/alter.result +++ b/mysql-test/suite/period/r/alter.result @@ -222,3 +222,11 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; # End of 10.5 tests +# +# MDEV-30297 Server crash / assertion failure in Compare_identifiers::operator upon dropping period with empty name +# +create table t (a int); +alter table t drop period if exists for ``; +ERROR 42000: Can't DROP PERIOD ``; check that it exists +drop table t; +# End of 10.11 tests diff --git a/mysql-test/suite/period/r/create.result b/mysql-test/suite/period/r/create.result index 2ee05d21771..e757d787390 100644 --- a/mysql-test/suite/period/r/create.result +++ b/mysql-test/suite/period/r/create.result @@ -126,8 +126,49 @@ create table t2 (s date, e date, period for `abcd123456789012345678901234567890123456789012345678901234567890` (s,e)); drop table t2; -# MDEV-32205 Server crashes in get_schema_key_period_usage_record on -# server without InnoDB +# +# MDEV-41186: 64-character multi-byte period name overflows the buffer +# +SET NAMES utf8mb4; +# No name collision: the implicit constraint keeps the full name +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, +PERIOD FOR 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好(s, e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) +FROM information_schema.CHECK_CONSTRAINTS +WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +CONSTRAINT_NAME CHAR_LENGTH(CONSTRAINT_NAME) LENGTH(CONSTRAINT_NAME) +好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好 64 192 +DROP TABLE t2; +# Name collision: the implicit constraint gets a well-formed suffixed name +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, +PERIOD FOR 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好(s, e), +CONSTRAINT 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好 CHECK (s < e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) +FROM information_schema.CHECK_CONSTRAINTS +WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +CONSTRAINT_NAME CHAR_LENGTH(CONSTRAINT_NAME) LENGTH(CONSTRAINT_NAME) +好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好_1 54 158 +好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好 64 192 +DROP TABLE t2; +SET NAMES default; +# 64-character all-ASCII period name, same collision as above: +# the generated name must still respect NAME_CHAR_LEN (64 characters) +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, +PERIOD FOR xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (s, e), +CONSTRAINT xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CHECK (s < e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) +FROM information_schema.CHECK_CONSTRAINTS +WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +CONSTRAINT_NAME CHAR_LENGTH(CONSTRAINT_NAME) LENGTH(CONSTRAINT_NAME) +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 64 64 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1 54 54 +ALTER TABLE t2 DROP CONSTRAINT `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1`; +ERROR HY000: Can't DROP CONSTRAINT `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1`. Use DROP PERIOD `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` for this +DROP TABLE t2; +# End of 10.11 tests +# +# MDEV-32205 Server crashes in get_schema_key_period_usage_record on server without InnoDB +# # Make sure innodb id disabled, but there's at least one innodb table select "yes" from information_schema.tables where engine="innodb" limit 1; yes @@ -163,3 +204,4 @@ Warning 1286 Unknown storage engine 'InnoDB' Warning 1286 Unknown storage engine 'InnoDB' Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop view v2; +# End of 11.4 tests diff --git a/mysql-test/suite/period/t/alter.test b/mysql-test/suite/period/t/alter.test index fab933eca87..f8bdfb82ba2 100644 --- a/mysql-test/suite/period/t/alter.test +++ b/mysql-test/suite/period/t/alter.test @@ -190,3 +190,14 @@ show create table t1; drop table t1; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-30297 Server crash / assertion failure in Compare_identifiers::operator upon dropping period with empty name +--echo # +create table t (a int); +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t drop period if exists for ``; + +drop table t; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/period/t/create.test b/mysql-test/suite/period/t/create.test index 072befa44f5..1df8dbf6335 100644 --- a/mysql-test/suite/period/t/create.test +++ b/mysql-test/suite/period/t/create.test @@ -106,9 +106,47 @@ create table t2 (s date, e date, period for (s,e)); drop table t2; +--echo # +--echo # MDEV-41186: 64-character multi-byte period name overflows the buffer +--echo # ---echo # MDEV-32205 Server crashes in get_schema_key_period_usage_record on ---echo # server without InnoDB +SET NAMES utf8mb4; + +--echo # No name collision: the implicit constraint keeps the full name +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, + PERIOD FOR 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好(s, e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) + FROM information_schema.CHECK_CONSTRAINTS + WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +DROP TABLE t2; + +--echo # Name collision: the implicit constraint gets a well-formed suffixed name +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, + PERIOD FOR 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好(s, e), + CONSTRAINT 好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好好 CHECK (s < e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) + FROM information_schema.CHECK_CONSTRAINTS + WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +DROP TABLE t2; +SET NAMES default; + +--echo # 64-character all-ASCII period name, same collision as above: +--echo # the generated name must still respect NAME_CHAR_LEN (64 characters) +CREATE TABLE t2 (s DATE NOT NULL, e DATE NOT NULL, + PERIOD FOR xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (s, e), + CONSTRAINT xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx CHECK (s < e)); +SELECT CONSTRAINT_NAME, CHAR_LENGTH(CONSTRAINT_NAME), LENGTH(CONSTRAINT_NAME) + FROM information_schema.CHECK_CONSTRAINTS + WHERE TABLE_NAME='t2' ORDER BY CONSTRAINT_NAME; +--error ER_PERIOD_CONSTRAINT_DROP +ALTER TABLE t2 DROP CONSTRAINT `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1`; +DROP TABLE t2; + +--echo # End of 10.11 tests + +--echo # +--echo # MDEV-32205 Server crashes in get_schema_key_period_usage_record on server without InnoDB +--echo # --echo # Make sure innodb id disabled, but there's at least one innodb table --disable_warnings @@ -135,3 +173,5 @@ drop view v1; --sorted_result select * from information_schema.key_period_usage; drop view v2; + +--echo # End of 11.4 tests diff --git a/mysql-test/suite/plugins/r/plugin_name_ascii.result b/mysql-test/suite/plugins/r/plugin_name_ascii.result new file mode 100644 index 00000000000..f1667fd9093 --- /dev/null +++ b/mysql-test/suite/plugins/r/plugin_name_ascii.result @@ -0,0 +1,51 @@ +# +# MDEV-39245: Check that plugin name is pure ASCII +# +SET NAMES utf8mb4; +# +# Case 1: INSTALL SONAME with non-ASCII plugin name should fail +# +INSTALL SONAME 'plugin_name_non_ascii'; +ERROR HY000: Plugin 'plügïn_non_ascii': name must contain only ASCII characters +# Verify mysql.plugin table is clean +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_non_ascii'; +COUNT(*) +0 +SET NAMES utf8mb4; +# +# Case 2: INSTALL PLUGIN targeting non-ASCII plugin directly should fail +# +INSTALL PLUGIN plügïn_non_ascii SONAME 'plugin_name_non_ascii'; +ERROR HY000: Plugin 'plügïn_non_ascii': name must contain only ASCII characters +# +# Case 3: INSTALL SONAME with all ASCII names should succeed +# +INSTALL SONAME 'plugin_name_ascii'; +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME IN ('ascii_plugin_one', 'ascii_plugin_two'); +PLUGIN_NAME PLUGIN_STATUS +ascii_plugin_one ACTIVE +ascii_plugin_two ACTIVE +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_ascii'; +COUNT(*) +0 +UNINSTALL SONAME 'plugin_name_ascii'; +# Verify plugins are gone after uninstall +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME IN ('ascii_plugin_one', 'ascii_plugin_two'); +PLUGIN_NAME PLUGIN_STATUS +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_ascii'; +COUNT(*) +0 +# +# Case 4: INSTALL PLUGIN with ASCII name should succeed +# +INSTALL PLUGIN ascii_plugin_one SONAME 'plugin_name_ascii'; +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME = 'ascii_plugin_one'; +PLUGIN_NAME PLUGIN_STATUS +ascii_plugin_one ACTIVE +UNINSTALL PLUGIN ascii_plugin_one; diff --git a/mysql-test/suite/plugins/t/plugin_name_ascii.opt b/mysql-test/suite/plugins/t/plugin_name_ascii.opt new file mode 100644 index 00000000000..70ba6280117 --- /dev/null +++ b/mysql-test/suite/plugins/t/plugin_name_ascii.opt @@ -0,0 +1 @@ +--plugin-maturity=stable diff --git a/mysql-test/suite/plugins/t/plugin_name_ascii.test b/mysql-test/suite/plugins/t/plugin_name_ascii.test new file mode 100644 index 00000000000..dc7ded7769e --- /dev/null +++ b/mysql-test/suite/plugins/t/plugin_name_ascii.test @@ -0,0 +1,63 @@ +--echo # +--echo # MDEV-39245: Check that plugin name is pure ASCII +--echo # + +--source include/have_utf8mb4.inc + +if (!$PLUGIN_NAME_ASCII_SO) +{ + skip plugin_name_ascii plugin not available; +} +if (!$PLUGIN_NAME_NON_ASCII_SO) +{ + skip plugin_name_non_ascii plugin not available; +} + +SET NAMES utf8mb4; + +--echo # +--echo # Case 1: INSTALL SONAME with non-ASCII plugin name should fail +--echo # +--error ER_PLUGIN_IS_NOT_LOADED +INSTALL SONAME 'plugin_name_non_ascii'; + +--echo # Verify mysql.plugin table is clean +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_non_ascii'; + +SET NAMES utf8mb4; +--echo # +--echo # Case 2: INSTALL PLUGIN targeting non-ASCII plugin directly should fail +--echo # +--error ER_PLUGIN_IS_NOT_LOADED +INSTALL PLUGIN plügïn_non_ascii SONAME 'plugin_name_non_ascii'; + +--echo # +--echo # Case 3: INSTALL SONAME with all ASCII names should succeed +--echo # +INSTALL SONAME 'plugin_name_ascii'; + +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME IN ('ascii_plugin_one', 'ascii_plugin_two'); + +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_ascii'; + +UNINSTALL SONAME 'plugin_name_ascii'; + +--echo # Verify plugins are gone after uninstall +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME IN ('ascii_plugin_one', 'ascii_plugin_two'); + +SELECT COUNT(*) FROM mysql.plugin WHERE dl='plugin_name_ascii'; + +--echo # +--echo # Case 4: INSTALL PLUGIN with ASCII name should succeed +--echo # +INSTALL PLUGIN ascii_plugin_one SONAME 'plugin_name_ascii'; + +SELECT PLUGIN_NAME, PLUGIN_STATUS +FROM information_schema.PLUGINS +WHERE PLUGIN_NAME = 'ascii_plugin_one'; + +UNINSTALL PLUGIN ascii_plugin_one; diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def index 57907210693..774750e7813 100644 --- a/mysql-test/suite/rpl/disabled.def +++ b/mysql-test/suite/rpl/disabled.def @@ -15,3 +15,4 @@ rpl_row_binlog_max_cache_size : MDEV-11092 rpl_row_index_choice : MDEV-11666 rpl_auto_increment_update_failure : disabled for now rpl_current_user : waits for MDEV-22374 fix +rpl_parallel_multi_domain_xa : (2026-07-24) MDEV-34104: waits for MDEV-32020 diff --git a/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result b/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result new file mode 100644 index 00000000000..9859c92f0f2 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result @@ -0,0 +1,17 @@ +include/master-slave.inc +[connection master] +connection slave; +CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '################################################'; +ERROR HY000: Could not initialize master info structure for '################################################'; more error messages can be found in the MariaDB error log +connection master; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +connection slave; +connection slave; +include/diff_tables.inc [master:t1, slave:t1] +CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root'; +RESET SLAVE 'new_channel' ALL; +connection master; +DROP TABLE t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_compressed_log_event_overflow.result b/mysql-test/suite/rpl/r/rpl_compressed_log_event_overflow.result index 6107508c9fc..4e8999346ff 100644 --- a/mysql-test/suite/rpl/r/rpl_compressed_log_event_overflow.result +++ b/mysql-test/suite/rpl/r/rpl_compressed_log_event_overflow.result @@ -28,12 +28,12 @@ set @@session.debug_dbug= @saved_dbug; connection slave; # Waiting for the IO thread to reject the compressed Query event include/wait_for_slave_io_error.inc [errno=1256, 1595] -# Ensure the replica rejected the event on its recorded length +# Ensure the slave rejected the event on its recorded length include/assert_grep.inc [The IO thread reported an oversized uncompressed length] -# Move the replica past the corrupt event +# Move the slave past the corrupt event include/stop_slave_sql.inc include/start_slave.inc -# Ensure replication resumes +# Ensure slavetion resumes connection master; insert into t1 values (1); include/save_master_gtid.inc @@ -54,12 +54,12 @@ set @@session.debug_dbug= @saved_dbug; connection slave; # Waiting for the IO thread to reject the compressed Write_rows event include/wait_for_slave_io_error.inc [errno=1256, 1595] -# Ensure the replica rejected the event on its recorded length +# Ensure the slave rejected the event on its recorded length include/assert_grep.inc [The IO thread reported an oversized uncompressed length] -# Move the replica past the corrupt event +# Move the slave past the corrupt event include/stop_slave_sql.inc include/start_slave.inc -# Ensure replication resumes +# Ensure slavetion resumes connection master; insert into t1 values (2); include/save_master_gtid.inc diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result index 3f62e585ad5..f7dc64a86ab 100644 --- a/mysql-test/suite/rpl/r/rpl_packet.result +++ b/mysql-test/suite/rpl/r/rpl_packet.result @@ -45,7 +45,7 @@ connection master; CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; connection slave; connection master; -INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2560'); connection slave; include/wait_for_slave_io_error.inc [errno=1153] Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' diff --git a/mysql-test/suite/rpl/r/rpl_rotate_ev_overflow.result b/mysql-test/suite/rpl/r/rpl_rotate_ev_overflow.result deleted file mode 100644 index 73b7b9ad258..00000000000 --- a/mysql-test/suite/rpl/r/rpl_rotate_ev_overflow.result +++ /dev/null @@ -1,20 +0,0 @@ -SET @saved_dbug= @@GLOBAL.debug_dbug; -SET @@GLOBAL.debug_dbug= '+d,truncate_fde_post_header_len'; -include/master-slave.inc -[connection master] -FLUSH BINARY LOGS; -CALL mtr.add_suppression('Found invalid event in binary log'); -ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error -connection slave; -START SLAVE IO_THREAD; -CALL mtr.add_suppression('Slave I/O: Relay log write failure'); -include/wait_for_slave_io_error.inc [errno=1595] -connection master; -SET @@GLOBAL.debug_dbug= @saved_dbug; -include/kill_binlog_dump_threads.inc -RESET MASTER; -connection slave; -CHANGE MASTER TO master_use_gtid=SLAVE_POS; -SET @@GLOBAL.gtid_slave_pos=''; -include/start_slave.inc -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_4_bytes.result b/mysql-test/suite/rpl/r/rpl_row_4_bytes.result deleted file mode 100644 index 0d746a7bd9c..00000000000 --- a/mysql-test/suite/rpl/r/rpl_row_4_bytes.result +++ /dev/null @@ -1,28 +0,0 @@ -include/master-slave.inc -[connection master] -connection master; -drop database if exists mysqltest1; -create database mysqltest1; -use mysqltest1; -CREATE TABLE t1 (a char(3)); -CREATE TABLE t2 (a char(3)); -insert into t1 values("ANN"); -insert into t1 values("GUI"); -insert into t2 values("LIL"); -insert into t2 values("ABE"); -insert into t2 values("ANG"); -connection slave; -use mysqltest1; -select * from t1 order by a; -a -ANN -GUI -select * from t2 order by a; -a -ABE -ANG -LIL -connection master; -DROP DATABASE mysqltest1; -connection slave; -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test b/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test new file mode 100644 index 00000000000..1cb94c87f5a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test @@ -0,0 +1,40 @@ +# +# CHANGE MASTER ... FOR CHANNEL with a name that overflows the relay +# log file name once escaped should return an error, not crash. +# +# STEPS: +# 1. Issue CHANGE MASTER ... FOR CHANNEL with a channel name that is +# within MAX_CONNECTION_NAME, but expands past the file name +# limit once escaped into the relay log file name. +# 2. Verify the statement fails with a clean error, not a crash. +# 3. Verify the server is still usable: a normal CHANGE MASTER for a +# new, short-named channel succeeds. +# +--source include/master-slave.inc + +--connection slave +--let $channel= `SELECT REPEAT('#', 48)` +--error ER_MASTER_INFO +eval CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '$channel'; + +--connection master +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +--sync_slave_with_master + +--connection slave +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root'; +RESET SLAVE 'new_channel' ALL; + +--disable_query_log +call mtr.add_suppression("Failed when trying to open logs"); +--enable_query_log + +--connection master +DROP TABLE t1; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_compressed_log_event_overflow.test b/mysql-test/suite/rpl/t/rpl_compressed_log_event_overflow.test index 29d51a823a7..36235d84f33 100644 --- a/mysql-test/suite/rpl/t/rpl_compressed_log_event_overflow.test +++ b/mysql-test/suite/rpl/t/rpl_compressed_log_event_overflow.test @@ -1,15 +1,15 @@ # -# This test verifies that a replica rejects a compressed event whose +# This test verifies that a slave rejects a compressed event whose # recorded uncompressed length is larger than the biggest packet the # server accepts. A compressed Query event and a compressed Write_rows # event are both covered, because the IO thread uncompresses each with # its own function. MDEV-39762 reported that the compressed Query event -# crashed the replica. +# crashed the slave. # # A debug injection makes the master write each of those events with # a corrupted length field. The event stays in the master's binary log # and is resent as it is, so each case moves gtid_slave_pos past it -# before checking that replication resumes. The sibling .opt file turns +# before checking that slavetion resumes. The sibling .opt file turns # on log_bin_compress, without which the master writes no compressed # events at all. # @@ -37,7 +37,7 @@ call mtr.add_suppression("Relay log write failure: could not queue event from ma --echo # Initialize test data --echo # --connection master -# t1 tracks what replicates. t2 takes the corrupt events, and the replica +# t1 tracks what slavetes. t2 takes the corrupt events, and the slave # never receives its rows. create table t1 (a int); create table t2 (a longtext); @@ -75,21 +75,21 @@ set @@session.debug_dbug= @saved_dbug; --let $slave_io_errno= 1256, 1595 --source include/wait_for_slave_io_error.inc ---echo # Ensure the replica rejected the event on its recorded length +--echo # Ensure the slave rejected the event on its recorded length --let $assert_text= The IO thread reported an oversized uncompressed length --let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err --let $assert_select= Uncompressed data size too large --let $assert_match= Uncompressed data size too large; the maximum size is 1073741824 --source include/assert_grep.inc ---echo # Move the replica past the corrupt event +--echo # Move the slave past the corrupt event --source include/stop_slave_sql.inc --disable_query_log --eval SET GLOBAL gtid_slave_pos= '$corrupt_gtid_pos' --enable_query_log --source include/start_slave.inc ---echo # Ensure replication resumes +--echo # Ensure slavetion resumes --connection master insert into t1 values (1); --source include/save_master_gtid.inc @@ -122,21 +122,21 @@ set @@session.debug_dbug= @saved_dbug; --let $slave_io_errno= 1256, 1595 --source include/wait_for_slave_io_error.inc ---echo # Ensure the replica rejected the event on its recorded length +--echo # Ensure the slave rejected the event on its recorded length --let $assert_text= The IO thread reported an oversized uncompressed length --let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err --let $assert_select= Uncompressed data size too large --let $assert_match= Uncompressed data size too large; the maximum size is 1073741824 --source include/assert_grep.inc ---echo # Move the replica past the corrupt event +--echo # Move the slave past the corrupt event --source include/stop_slave_sql.inc --disable_query_log --eval SET GLOBAL gtid_slave_pos= '$corrupt_gtid_pos' --enable_query_log --source include/start_slave.inc ---echo # Ensure replication resumes +--echo # Ensure slavetion resumes --connection master insert into t1 values (2); --source include/save_master_gtid.inc diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test index 2a5d3e4b688..4753213ba77 100644 --- a/mysql-test/suite/rpl/t/rpl_packet.test +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -92,8 +92,10 @@ sync_slave_with_master; connection master; -INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); - +# The @@slave_max_allowed_packet is configured in .opt to 1024. +# But the slave adds some extra MAX_LOG_EVENT_HEADER bytes. +# So we need a somewhat longer query to exceed the max size. +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2560'); # # Bug#42914: The slave I/O thread must stop after trying to read the above diff --git a/mysql-test/suite/rpl/t/rpl_rotate_ev_overflow.test b/mysql-test/suite/rpl/t/rpl_rotate_ev_overflow.test deleted file mode 100644 index 5a87d32773b..00000000000 --- a/mysql-test/suite/rpl/t/rpl_rotate_ev_overflow.test +++ /dev/null @@ -1,54 +0,0 @@ -# MDEV-40647 OOB read in IO Thread if the FDEv does not support Rotate Events - ---source include/have_debug.inc ---source include/have_binlog_format_mixed.inc # should be format-agnostic - -SET @saved_dbug= @@GLOBAL.debug_dbug; -SET @@GLOBAL.debug_dbug= '+d,truncate_fde_post_header_len'; ---let $rpl_skip_start_slave= 1 -# This setup will also RESET MASTER ... ---source include/master-slave.inc -# ... which means the binlog file is consistent. ---let $binlog_file= master-bin.000001 - -# Use a specific binlog position to avoid the -# test failing early from other metadata events ---let $binlog_start= query_get_value(SHOW BINLOG STATUS, Position, 1) -# Generate the Rotate Event -FLUSH BINARY LOGS; - - -# Control: SHOW BINLOG EVENTS fails as expected. -CALL mtr.add_suppression('Found invalid event in binary log'); ---disable_query_log - --error ER_ERROR_WHEN_EXECUTING_COMMAND - --eval SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start ---enable_query_log - ---connection slave ---disable_query_log - eval CHANGE MASTER TO master_use_gtid=NO, - master_log_file='$binlog_file', master_log_pos=$binlog_start; ---enable_query_log -START SLAVE IO_THREAD; -CALL mtr.add_suppression('Slave I/O: Relay log write failure'); -# ER_SLAVE_RELAY_LOG_WRITE_FAILURE ---let $slave_io_errno= 1595 -# Experiment: The IO thread should fail. ---source include/wait_for_slave_io_error.inc - -# Clean-up ---connection master -SET @@GLOBAL.debug_dbug= @saved_dbug; -# The dump thread of the failed IO thread can still hang around, which would -# make RESET MASTER fail with ER_BINLOG_IN_USE. ---source include/kill_binlog_dump_threads.inc -RESET MASTER; - ---connection slave -CHANGE MASTER TO master_use_gtid=SLAVE_POS; # restore the default ---disable_warnings - SET @@GLOBAL.gtid_slave_pos=''; # for good measure ---enable_warnings ---source include/start_slave.inc ---source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt b/mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt deleted file mode 100644 index b3f3d539d8d..00000000000 --- a/mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---loose-debug-dbug=d,"old_row_based_repl_4_byte_map_id_master" ---log-bin-use-v1-row-events=1 diff --git a/mysql-test/suite/rpl/t/rpl_row_4_bytes.test b/mysql-test/suite/rpl/t/rpl_row_4_bytes.test deleted file mode 100644 index 99755754984..00000000000 --- a/mysql-test/suite/rpl/t/rpl_row_4_bytes.test +++ /dev/null @@ -1,34 +0,0 @@ -# This test is to make sure that slaves can read a binlog containing -# table map ids stored in 4 bytes, even though we now store them in 6 -# bytes. This is for backward-compatibility. -# If the slave does not detect that the master stores the table map id -# in 4 bytes, slave will read 6 bytes, and so will read the 2 bytes of -# flags at the place where there actually is data, so the test should -# fail. - --- source include/have_binlog_format_row.inc --- source include/have_debug.inc --- source include/master-slave.inc - -connection master; ---disable_warnings -drop database if exists mysqltest1; -create database mysqltest1; ---enable_warnings -use mysqltest1; -CREATE TABLE t1 (a char(3)); -CREATE TABLE t2 (a char(3)); -insert into t1 values("ANN"); -insert into t1 values("GUI"); -insert into t2 values("LIL"); -insert into t2 values("ABE"); -insert into t2 values("ANG"); -sync_slave_with_master; -use mysqltest1; -select * from t1 order by a; -select * from t2 order by a; - -connection master; -DROP DATABASE mysqltest1; -sync_slave_with_master; ---source include/rpl_end.inc diff --git a/mysql-test/suite/sys_vars/r/gtid_slave_pos_basic.result b/mysql-test/suite/sys_vars/r/gtid_slave_pos_basic.result index 3d880418f31..5402838ed9f 100644 --- a/mysql-test/suite/sys_vars/r/gtid_slave_pos_basic.result +++ b/mysql-test/suite/sys_vars/r/gtid_slave_pos_basic.result @@ -28,6 +28,20 @@ SET GLOBAL gtid_slave_pos= '1-2-3 '; ERROR HY000: Could not parse GTID list SET GLOBAL gtid_slave_pos= '1-2-3,2-4'; ERROR HY000: Could not parse GTID list +SET GLOBAL gtid_slave_pos= '0-1-10,1-1-20,2-1-30'; +SET GLOBAL gtid_slave_pos= '0-1-110,1-1-120,,2-1-130'; +ERROR HY000: Could not parse GTID list +SELECT @@GLOBAL.gtid_slave_pos; +@@GLOBAL.gtid_slave_pos +0-1-10,1-1-20,2-1-30 +SELECT A.domain_id, A.server_id, A.seq_no +FROM mysql.gtid_slave_pos A +WHERE A.sub_id=(SELECT MAX(B.sub_id) FROM mysql.gtid_slave_pos B WHERE A.domain_id=B.domain_id) +ORDER BY A.domain_id; +domain_id server_id seq_no +0 1 10 +1 1 20 +2 1 30 SET GLOBAL gtid_slave_pos= '0-1-10,0-2-20'; ERROR HY000: GTID 0-2-20 and 0-1-10 conflict (duplicate domain id 0) SET GLOBAL gtid_slave_pos= '0-1-10,1-2-20,2-3-30,1-20-200,3-4-1'; diff --git a/mysql-test/suite/sys_vars/r/old_mode_basic.result b/mysql-test/suite/sys_vars/r/old_mode_basic.result deleted file mode 100644 index 75ff3b6d781..00000000000 --- a/mysql-test/suite/sys_vars/r/old_mode_basic.result +++ /dev/null @@ -1,341 +0,0 @@ -SET @global_start_value = @@global.old_mode; -SELECT @global_start_value; -@global_start_value -UTF8_IS_UTF8MB3 -SET @session_start_value = @@session.old_mode; -SELECT @session_start_value; -@session_start_value -UTF8_IS_UTF8MB3 -'#--------------------FN_DYNVARS_152_01------------------------#' -SET @@global.old_mode = "NO_PROGRESS_INFO"; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SET @@global.old_mode = DEFAULT; -SELECT @@global.old_mode; -@@global.old_mode -UTF8_IS_UTF8MB3 -SET @@session.old_mode = "NO_PROGRESS_INFO"; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SET @@session.old_mode = DEFAULT; -SELECT @@session.old_mode; -@@session.old_mode -UTF8_IS_UTF8MB3 -'#---------------------FN_DYNVARS_152_02-------------------------#' -SET @@global.old_mode = NULL; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'NULL' -SET @@global.old_mode = ''; -SELECT @@global.old_mode; -@@global.old_mode - -SET @@global.old_mode = ' '; -SELECT @@global.old_mode; -@@global.old_mode - -SET @@session.old_mode = NULL; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'NULL' -SET @@session.old_mode = ''; -SELECT @@session.old_mode; -@@session.old_mode - -SET @@session.old_mode = ' '; -SELECT @@session.old_mode; -@@session.old_mode - -'#--------------------FN_DYNVARS_152_03------------------------#' -SET @@global.old_mode = NO_PROGRESS_INFO; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_PROGRESS_INFO -SET @@global.old_mode = NO_DUP_KEY_WARNINGS_WITH_IGNORE; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -SET @@global.old_mode = OFF; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'OFF' -SET @@session.old_mode = NO_PROGRESS_INFO; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@session.old_mode; -@@session.old_mode -NO_PROGRESS_INFO -SET @@session.old_mode = NO_DUP_KEY_WARNINGS_WITH_IGNORE; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -SELECT @@session.old_mode; -@@session.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -SET @@session.old_mode = OFF; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'OFF' -SET @@global.old_mode = '?'; -ERROR 42000: Variable 'old_mode' can't be set to the value of '?' -SELECT @@global.old_mode; -@@global.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -'#--------------------FN_DYNVARS_152_04-------------------------#' -SET @@global.old_mode = -1; -ERROR 42000: Variable 'old_mode' can't be set to the value of '-1' -SET @@global.old_mode = ASCII; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'ASCII' -SET @@global.old_mode = NON_TRADITIONAL; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'NON_TRADITIONAL' -SET @@global.old_mode = 'OF'; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'OF' -SET @@global.old_mode = NONE; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'NONE' -SET @@session.old_mode = -1; -ERROR 42000: Variable 'old_mode' can't be set to the value of '-1' -SET @@session.old_mode = ANSI_SINGLE_QUOTES; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'ANSI_SINGLE_QUOTES' -SET @@session.old_mode = 'ON'; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'ON' -SET @@session.old_mode = 'OF'; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'OF' -SET @@session.old_mode = DISABLE; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'DISABLE' -'#-------------------FN_DYNVARS_152_05----------------------------#' -SELECT @@session.old_mode = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.SESSION_VARIABLES -WHERE VARIABLE_NAME='old_mode'; -@@session.old_mode = VARIABLE_VALUE -1 -'#----------------------FN_DYNVARS_152_06------------------------#' -SELECT @@global.old_mode = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='old_mode'; -@@global.old_mode = VARIABLE_VALUE -1 -'#---------------------FN_DYNVARS_152_07-------------------------#' -SET @@global.old_mode = 0; -SELECT @@global.old_mode; -@@global.old_mode - -SET @@global.old_mode = 1; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -SET @@global.old_mode = 2; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_PROGRESS_INFO -SET @@global.old_mode = 4; -Warnings: -Warning 1287 'ZERO_DATE_TIME_CAST' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -ZERO_DATE_TIME_CAST -SET @@global.old_mode = 6536; -ERROR 42000: Variable 'old_mode' can't be set to the value of '6536' -SELECT @@global.old_mode; -@@global.old_mode -ZERO_DATE_TIME_CAST -SET @@global.old_mode = 0.4; -ERROR 42000: Incorrect argument type to variable 'old_mode' -'#---------------------FN_DYNVARS_152_08----------------------#' -SET @@global.old_mode = TRUE; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -SET @@global.old_mode = FALSE; -SELECT @@global.old_mode; -@@global.old_mode - -'#---------------------FN_DYNVARS_152_09----------------------#' -SET old_mode = 'NO_PROGRESS_INFO'; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SET session old_mode = 1; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -SELECT @@old_mode; -@@old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE -SET global old_mode = 0; -SELECT @@global.old_mode; -@@global.old_mode - -'#---------------------FN_DYNVARS_152_10----------------------#' -SET @@session.old_mode = 'NO_PROGRESS_INFO,NO_DUP_KEY_WARNINGS_WITH_IGNORE'; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@session.old_mode; -@@session.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO -SET @@global.old_mode = 'NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO'; -Warnings: -Warning 1287 'NO_DUP_KEY_WARNINGS_WITH_IGNORE' is deprecated and will be removed in a future release -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@global.old_mode; -@@global.old_mode -NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO -SET @@session.old_mode = 'NO_PROGRESS_INFO,NO_SUCH_MODE'; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'NO_SUCH_MODE' -SET @@old_mode=','; -SELECT @@old_mode; -@@old_mode - -SET @@old_mode=',,,,NO_PROGRESS_INFO,,,'; -Warnings: -Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release -SELECT @@old_mode; -@@old_mode -NO_PROGRESS_INFO -SET @@old_mode=',,,,FOOBAR,,,,,'; -ERROR 42000: Variable 'old_mode' can't be set to the value of 'FOOBAR' -SELECT @@old_mode; -@@old_mode -NO_PROGRESS_INFO -SET @@global.old_mode = @global_start_value; -SELECT @@global.old_mode; -@@global.old_mode -UTF8_IS_UTF8MB3 -SET @@session.old_mode = @session_start_value; -SELECT @@session.old_mode; -@@session.old_mode -UTF8_IS_UTF8MB3 -# -# Beginning of 10.6 test -# -# MDEV-8334: Rename utf8 to utf8mb3 -# -# Save and display old values -SET @save_old_mode = @@OLD_MODE; -SET @save_character_set_server = @@character_set_server; -SET @save_character_set_client = @@character_set_client; -SET @save_character_set_results = @@character_set_results; -SET @save_character_set_connection = @@character_set_connection; -SET @save_character_set_filesystem = @@character_set_filesystem; -SET @save_character_set_database = @@character_set_database; -SET @save_collation_connection = @@collation_connection; -SET @save_collation_server = @@collation_server; -SET @save_collation_database = @@collation_database; -SELECT @@OLD_MODE; -@@OLD_MODE -UTF8_IS_UTF8MB3 -SELECT @@character_set_server,@@character_set_client,@@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; -@@character_set_server @@character_set_client @@character_set_results @@character_set_connection @@character_set_filesystem @@character_set_database @@collation_connection @@collation_server @@collation_database -utf8mb4 latin1 latin1 latin1 binary utf8mb4 latin1_swedish_ci utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci -# -# UTF8MB3 alias for UTF8 -# -SET @@character_set_server = utf8; -SET @@character_set_client = utf8; -SET @@character_set_results = utf8; -SET @@character_set_connection = utf8; -SET @@character_set_filesystem = utf8; -SET @@character_set_database = utf8; -SET @@collation_connection = utf8_general_ci; -SET @@collation_server = utf8_unicode_ci; -SET @@collation_database = utf8_bin; -SELECT @@character_set_server, @@character_set_client, @@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; -@@character_set_server @@character_set_client @@character_set_results @@character_set_connection @@character_set_filesystem @@character_set_database @@collation_connection @@collation_server @@collation_database -utf8mb3 utf8mb3 utf8mb3 utf8mb3 utf8mb3 utf8mb3 utf8mb3_general_ci utf8mb3_unicode_ci utf8mb3_bin -CREATE DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci'; -ALTER DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'; -CREATE TABLE tb1 (id1 INT) CHARACTER SET 'utf8' COLLATE 'utf8_bin'; -SHOW CREATE TABLE tb1; -Table Create Table -tb1 CREATE TABLE `tb1` ( - `id1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin -DROP TABLE tb1; -DROP DATABASE db1; -# -# UTF8MB4 is alias for UTF8 -# -SET @@OLD_MODE=0; -SET @@character_set_server = utf8; -SET @@character_set_client = utf8; -SET @@character_set_results = utf8; -SET @@character_set_connection = utf8; -SET @@character_set_filesystem = utf8; -SET @@character_set_database = utf8; -SET @@collation_connection = utf8_general_ci; -SET @@collation_server = utf8_unicode_ci; -SET @@collation_database = utf8_bin; -SELECT @@character_set_server, @@character_set_client, @@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; -@@character_set_server @@character_set_client @@character_set_results @@character_set_connection @@character_set_filesystem @@character_set_database @@collation_connection @@collation_server @@collation_database -utf8mb4 utf8mb4 utf8mb4 utf8mb4 utf8mb4 utf8mb4 utf8mb4_general_ci utf8mb4_unicode_ci utf8mb4_bin -CREATE DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci'; -ALTER DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'; -CREATE TABLE tb1 (id1 INT) CHARACTER SET 'utf8' COLLATE 'utf8_bin'; -SHOW CREATE TABLE tb1; -Table Create Table -tb1 CREATE TABLE `tb1` ( - `id1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin -DROP TABLE tb1; -DROP DATABASE db1; -SET @@OLD_MODE = @save_old_mode; -SET @@character_set_server = @save_character_set_server; -SET @@character_set_client = @save_character_set_client; -SET @@character_set_results = @save_character_set_results; -SET @@character_set_connection = @save_character_set_connection; -SET @@character_set_filesystem = @save_character_set_filesystem; -SET @@character_set_database = @save_character_set_database; -SET @@collation_connection = @save_collation_connection; -SET @@collation_server = @save_collation_server; -SET @@collation_database = @save_collation_database; -# -# End of 10.6 test -# -# -# Beginning of 10.9 test -# -# -# MDEV-24920: Merge "old" SQL variable to "old_mode" sql variable -# -# Checking that setting old will also set old_mode -SELECT @@OLD_MODE; -@@OLD_MODE -UTF8_IS_UTF8MB3 -SET old= 1; -Warnings: -Warning 1287 '@@old' is deprecated and will be removed in a future release. Please use '@@old_mode' instead -SELECT @@OLD_MODE; -@@OLD_MODE -NO_PROGRESS_INFO,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM -SET old= DEFAULT; -Warnings: -Warning 1287 '@@old' is deprecated and will be removed in a future release. Please use '@@old_mode' instead -SELECT @@OLD_MODE; -@@OLD_MODE -UTF8_IS_UTF8MB3 -# Checking that old_mode can be set independently as well -SELECT @@OLD_MODE; -@@OLD_MODE -UTF8_IS_UTF8MB3 -SET @save_old_mode = @@OLD_MODE; -SET @@OLD_MODE= IGNORE_INDEX_ONLY_FOR_JOIN; -Warnings: -Warning 1287 'IGNORE_INDEX_ONLY_FOR_JOIN' is deprecated and will be removed in a future release -SELECT @@OLD_MODE; -@@OLD_MODE -IGNORE_INDEX_ONLY_FOR_JOIN -SET @@OLD_MODE= COMPAT_5_1_CHECKSUM; -Warnings: -Warning 1287 'COMPAT_5_1_CHECKSUM' is deprecated and will be removed in a future release -SELECT @@OLD_MODE; -@@OLD_MODE -COMPAT_5_1_CHECKSUM -SET @@OLD_MODE= @save_old_mode; -# -# End of 10.9 test -# diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 1407bde5ab6..52fe7b62b75 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -2459,7 +2459,7 @@ VARIABLE_COMMENT Used to emulate old behavior from earlier MariaDB or MySQL vers NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY,OLD_FLUSH_STATUS,SESSION_USER_IS_USER +ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY,OLD_FLUSH_STATUS,SESSION_USER_IS_USER,X509_LENIENT_COMPARE READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OLD_PASSWORDS diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 32b989fae25..b04fe25a0c7 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2699,7 +2699,7 @@ VARIABLE_COMMENT Used to emulate old behavior from earlier MariaDB or MySQL vers NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY,OLD_FLUSH_STATUS,SESSION_USER_IS_USER +ENUM_VALUE_LIST NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO,ZERO_DATE_TIME_CAST,UTF8_IS_UTF8MB3,IGNORE_INDEX_ONLY_FOR_JOIN,COMPAT_5_1_CHECKSUM,NO_NULL_COLLATION_IDS,LOCK_ALTER_TABLE_COPY,OLD_FLUSH_STATUS,SESSION_USER_IS_USER,X509_LENIENT_COMPARE READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME OLD_PASSWORDS diff --git a/mysql-test/suite/sys_vars/t/gtid_slave_pos_basic.test b/mysql-test/suite/sys_vars/t/gtid_slave_pos_basic.test index d021e335b86..b300c81f3e0 100644 --- a/mysql-test/suite/sys_vars/t/gtid_slave_pos_basic.test +++ b/mysql-test/suite/sys_vars/t/gtid_slave_pos_basic.test @@ -24,6 +24,17 @@ SET GLOBAL gtid_slave_pos= '1-2-3 '; --error ER_INCORRECT_GTID_STATE SET GLOBAL gtid_slave_pos= '1-2-3,2-4'; +# Test that a parse error in the middle of the GTID string does not leave +# a partial updated value. +SET GLOBAL gtid_slave_pos= '0-1-10,1-1-20,2-1-30'; +--error ER_INCORRECT_GTID_STATE +SET GLOBAL gtid_slave_pos= '0-1-110,1-1-120,,2-1-130'; +SELECT @@GLOBAL.gtid_slave_pos; +SELECT A.domain_id, A.server_id, A.seq_no + FROM mysql.gtid_slave_pos A + WHERE A.sub_id=(SELECT MAX(B.sub_id) FROM mysql.gtid_slave_pos B WHERE A.domain_id=B.domain_id) + ORDER BY A.domain_id; + --error ER_DUPLICATE_GTID_DOMAIN SET GLOBAL gtid_slave_pos= '0-1-10,0-2-20'; --error ER_DUPLICATE_GTID_DOMAIN diff --git a/mysql-test/suite/sys_vars/t/max_statement_time_basic.test b/mysql-test/suite/sys_vars/t/max_statement_time_basic.test index 186589dcee2..a1b85862dc4 100644 --- a/mysql-test/suite/sys_vars/t/max_statement_time_basic.test +++ b/mysql-test/suite/sys_vars/t/max_statement_time_basic.test @@ -18,8 +18,8 @@ # * Scope & Access method # # * Data Integrity # # # -# Reference: https://kb.askmonty.org/en/how-to-limittimeout-queries/ # -# server-system-variables.html # +# Reference: # +# https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/query-optimizations/query-limits-and-timeouts # # ############################################################################### diff --git a/mysql-test/suite/sys_vars/t/old_mode_basic.test b/mysql-test/suite/sys_vars/t/old_mode_basic.test deleted file mode 100644 index 89aca99271a..00000000000 --- a/mysql-test/suite/sys_vars/t/old_mode_basic.test +++ /dev/null @@ -1,352 +0,0 @@ -#################### mysql-test\t\sql_mode_basic.test ######################### -# # -# Variable Name: old_mode # -# Scope: GLOBAL | SESSION # -# Access Type: Dynamic # -# Data Type: enumeration # -# Default Value: YES # -# Valid Values : NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO # -# # -# # -# Description: Test Cases of Dynamic System Variable old_mode # -# that checks the behavior of this variable in the following ways# -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# # -############################################################################### - ---source include/load_sysvars.inc - -################################################################ -# START OF sql_mode TESTS # -################################################################ - - -################################################################### -# Saving initial value of sql_mode in a temporary variable # -################################################################### - -SET @global_start_value = @@global.old_mode; -SELECT @global_start_value; - -SET @session_start_value = @@session.old_mode; -SELECT @session_start_value; - ---echo '#--------------------FN_DYNVARS_152_01------------------------#' -################################################################ -# Display the DEFAULT value of old_mode # -################################################################ - -SET @@global.old_mode = "NO_PROGRESS_INFO"; -SET @@global.old_mode = DEFAULT; -SELECT @@global.old_mode; - -SET @@session.old_mode = "NO_PROGRESS_INFO"; -SET @@session.old_mode = DEFAULT; -SELECT @@session.old_mode; - ---echo '#---------------------FN_DYNVARS_152_02-------------------------#' -######################################################### -# Check if NULL or empty value is accepeted # -######################################################### - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = NULL; - -# resets sql mode to nothing -SET @@global.old_mode = ''; -SELECT @@global.old_mode; - -SET @@global.old_mode = ' '; -SELECT @@global.old_mode; - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = NULL; - -SET @@session.old_mode = ''; -SELECT @@session.old_mode; - -SET @@session.old_mode = ' '; -SELECT @@session.old_mode; - - ---echo '#--------------------FN_DYNVARS_152_03------------------------#' -######################################################################## -# Change the value of old_mode to a valid value # -######################################################################## - -# sql modes ref: http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html - -# check valid values for global - -SET @@global.old_mode = NO_PROGRESS_INFO; -SELECT @@global.old_mode; -SET @@global.old_mode = NO_DUP_KEY_WARNINGS_WITH_IGNORE; -SELECT @@global.old_mode; - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = OFF; - -#check valid values for session -SET @@session.old_mode = NO_PROGRESS_INFO; -SELECT @@session.old_mode; -SET @@session.old_mode = NO_DUP_KEY_WARNINGS_WITH_IGNORE; -SELECT @@session.old_mode; - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = OFF; - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = '?'; -SELECT @@global.old_mode; - ---echo '#--------------------FN_DYNVARS_152_04-------------------------#' -########################################################################### -# Change the value of old_mode to invalid value # -########################################################################### - -# invalid values for global ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = -1; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = ASCII; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = NON_TRADITIONAL; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = 'OF'; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = NONE; - -#invalid values for session - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = -1; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = ANSI_SINGLE_QUOTES; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = 'ON'; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = 'OF'; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = DISABLE; - - ---echo '#-------------------FN_DYNVARS_152_05----------------------------#' -######################################################################### -# Check if the value in session Table matches value in variable # -######################################################################### - -SELECT @@session.old_mode = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.SESSION_VARIABLES -WHERE VARIABLE_NAME='old_mode'; - ---echo '#----------------------FN_DYNVARS_152_06------------------------#' -######################################################################### -# Check if the value in GLOBAL Table matches value in variable # -######################################################################### - -SELECT @@global.old_mode = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='old_mode'; - - ---echo '#---------------------FN_DYNVARS_152_07-------------------------#' -################################################################### -# Check if numbers can be used on variable # -################################################################### - -# test if variable accepts 0,1,2 -SET @@global.old_mode = 0; -SELECT @@global.old_mode; - -SET @@global.old_mode = 1; -SELECT @@global.old_mode; - -SET @@global.old_mode = 2; -SELECT @@global.old_mode; - -SET @@global.old_mode = 4; -SELECT @@global.old_mode; - ---Error ER_WRONG_VALUE_FOR_VAR -SET @@global.old_mode = 6536; -SELECT @@global.old_mode; - -# use of decimal values - ---Error ER_WRONG_TYPE_FOR_VAR -SET @@global.old_mode = 0.4; - ---echo '#---------------------FN_DYNVARS_152_08----------------------#' -################################################################### -# Check if TRUE and FALSE values can be used on variable # -################################################################### - -SET @@global.old_mode = TRUE; -SELECT @@global.old_mode; -SET @@global.old_mode = FALSE; -SELECT @@global.old_mode; - ---echo '#---------------------FN_DYNVARS_152_09----------------------#' -######################################################################### -# Check if old_mode can be accessed with and without @@ sign # -######################################################################### - -SET old_mode = 'NO_PROGRESS_INFO'; - -SET session old_mode = 1; -SELECT @@old_mode; - -SET global old_mode = 0; -SELECT @@global.old_mode; - ---echo '#---------------------FN_DYNVARS_152_10----------------------#' -####################################################################### -# Check if old_mode values can be combined as specified # -####################################################################### - -SET @@session.old_mode = 'NO_PROGRESS_INFO,NO_DUP_KEY_WARNINGS_WITH_IGNORE'; -SELECT @@session.old_mode; - -SET @@global.old_mode = 'NO_DUP_KEY_WARNINGS_WITH_IGNORE,NO_PROGRESS_INFO'; -SELECT @@global.old_mode; - -#try combining invalid mode with correct mode ---Error ER_WRONG_VALUE_FOR_VAR -SET @@session.old_mode = 'NO_PROGRESS_INFO,NO_SUCH_MODE'; - -#zero-length values are ok -SET @@old_mode=','; -SELECT @@old_mode; -SET @@old_mode=',,,,NO_PROGRESS_INFO,,,'; -SELECT @@old_mode; ---Error ER_WRONG_VALUE_FOR_VAR -SET @@old_mode=',,,,FOOBAR,,,,,'; -SELECT @@old_mode; - -############################## -# Restore initial value # -############################## - -SET @@global.old_mode = @global_start_value; -SELECT @@global.old_mode; - -SET @@session.old_mode = @session_start_value; -SELECT @@session.old_mode; - ---echo # ---echo # Beginning of 10.6 test ---echo # ---echo # MDEV-8334: Rename utf8 to utf8mb3 ---echo # ---echo # Save and display old values -SET @save_old_mode = @@OLD_MODE; -SET @save_character_set_server = @@character_set_server; -SET @save_character_set_client = @@character_set_client; -SET @save_character_set_results = @@character_set_results; -SET @save_character_set_connection = @@character_set_connection; -SET @save_character_set_filesystem = @@character_set_filesystem; -SET @save_character_set_database = @@character_set_database; -SET @save_collation_connection = @@collation_connection; -SET @save_collation_server = @@collation_server; -SET @save_collation_database = @@collation_database; -SELECT @@OLD_MODE; -SELECT @@character_set_server,@@character_set_client,@@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; ---echo # ---echo # UTF8MB3 alias for UTF8 ---echo # -SET @@character_set_server = utf8; -SET @@character_set_client = utf8; -SET @@character_set_results = utf8; -SET @@character_set_connection = utf8; -SET @@character_set_filesystem = utf8; -SET @@character_set_database = utf8; -SET @@collation_connection = utf8_general_ci; -SET @@collation_server = utf8_unicode_ci; -SET @@collation_database = utf8_bin; -SELECT @@character_set_server, @@character_set_client, @@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; -CREATE DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci'; -ALTER DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'; -CREATE TABLE tb1 (id1 INT) CHARACTER SET 'utf8' COLLATE 'utf8_bin'; -SHOW CREATE TABLE tb1; -DROP TABLE tb1; -DROP DATABASE db1; ---echo # ---echo # UTF8MB4 is alias for UTF8 ---echo # -SET @@OLD_MODE=0; -SET @@character_set_server = utf8; -SET @@character_set_client = utf8; -SET @@character_set_results = utf8; -SET @@character_set_connection = utf8; -SET @@character_set_filesystem = utf8; -SET @@character_set_database = utf8; -SET @@collation_connection = utf8_general_ci; -SET @@collation_server = utf8_unicode_ci; -SET @@collation_database = utf8_bin; -SELECT @@character_set_server, @@character_set_client, @@character_set_results, -@@character_set_connection, @@character_set_filesystem, @@character_set_database, -@@collation_connection, @@collation_server, @@collation_database; -CREATE DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_general_ci'; -ALTER DATABASE db1 CHARACTER SET = 'utf8' COLLATE = 'utf8_unicode_ci'; -CREATE TABLE tb1 (id1 INT) CHARACTER SET 'utf8' COLLATE 'utf8_bin'; -SHOW CREATE TABLE tb1; -DROP TABLE tb1; -DROP DATABASE db1; -SET @@OLD_MODE = @save_old_mode; -SET @@character_set_server = @save_character_set_server; -SET @@character_set_client = @save_character_set_client; -SET @@character_set_results = @save_character_set_results; -SET @@character_set_connection = @save_character_set_connection; -SET @@character_set_filesystem = @save_character_set_filesystem; -SET @@character_set_database = @save_character_set_database; -SET @@collation_connection = @save_collation_connection; -SET @@collation_server = @save_collation_server; -SET @@collation_database = @save_collation_database; ---echo # ---echo # End of 10.6 test ---echo # - ---echo # ---echo # Beginning of 10.9 test ---echo # ---echo # ---echo # MDEV-24920: Merge "old" SQL variable to "old_mode" sql variable ---echo # - ---echo # Checking that setting old will also set old_mode -SELECT @@OLD_MODE; - -SET old= 1; -SELECT @@OLD_MODE; - -SET old= DEFAULT; -SELECT @@OLD_MODE; - ---echo # Checking that old_mode can be set independently as well - -SELECT @@OLD_MODE; - -SET @save_old_mode = @@OLD_MODE; - -SET @@OLD_MODE= IGNORE_INDEX_ONLY_FOR_JOIN; -SELECT @@OLD_MODE; - -SET @@OLD_MODE= COMPAT_5_1_CHECKSUM; -SELECT @@OLD_MODE; - -SET @@OLD_MODE= @save_old_mode; - ---echo # ---echo # End of 10.9 test ---echo # -################################################################ -# END OF old_mode TESTS # -################################################################ diff --git a/mysql-test/suite/vcol/r/order_by_group_by_subst.result b/mysql-test/suite/vcol/r/order_by_group_by_subst.result index 8ae258f1cb4..c19e8381fa1 100644 --- a/mysql-test/suite/vcol/r/order_by_group_by_subst.result +++ b/mysql-test/suite/vcol/r/order_by_group_by_subst.result @@ -234,6 +234,7 @@ INDEX (a1) ) ENGINE=INNODB; SELECT * FROM t1 GROUP BY a WITH ROLLUP; a b a1 +NULL NULL NULL drop table t1; # # End of 12.1 tests diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result index f29c21acc4d..52876a09c25 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result @@ -304,8 +304,71 @@ GOOD alter table t1 drop column va; drop table t1; # -# MDEV-39081 InnoDB: tried to purge non-delete-marked record, -# assertion fails in row_purge_del_mark_error +# MDEV-36896 Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *) +# +set @old_isolation_level= @@session.tx_isolation; +set @@session.tx_isolation= 'READ-UNCOMMITTED'; +Warnings: +Warning 1287 '@@tx_isolation' is deprecated and will be removed in a future release. Please use '@@transaction_isolation' instead +create table t (a varchar(10),b int,c char(10) generated always as (a) virtual,key(b,c)) engine=innodb; +insert into t (a) values ('A'); +select * from t where b is null order by a; +a b c +A NULL A +drop table t; +create table t ( +a varchar(10), +b int, +c char(10) generated always as (a) virtual, +d int generated always as (if(a = c, 1, 0)) virtual, +key(b, c) +) engine=innodb; +insert into t (a) values ('A'); +insert into t (a, b) values ('B', 1); +select * from t where b is null order by a; +a b c d +A NULL A 1 +drop table t; +set @@session.tx_isolation= @old_isolation_level; +Warnings: +Warning 1287 '@@tx_isolation' is deprecated and will be removed in a future release. Please use '@@transaction_isolation' instead +# +# MDEV-41365 Wrong results from filesort over indexed virtual columns during a concurrent uncommitted update +# +create table t ( +pk int primary key, +f int, +v1 int as (f & 1) virtual, +v2 int as (f & 2) virtual, +key (v1) +) engine=innodb; +insert into t (pk, f) values (1, 0); +explain select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t ref v1 v1 5 const 1 Using where; Using filesort +select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; +pk f v1 v2 +1 0 0 0 +connect con1, localhost, root; +begin; +update t set f = 1 where pk = 1; +connection default; +# No filesort +select * from t force index (v1) where v1 = 0 and v2 = 0; +pk f v1 v2 +1 0 0 0 +# Filesort: must return pk=1 +select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; +pk f v1 v2 +1 0 0 0 +connection con1; +rollback; +disconnect con1; +connection default; +drop table t; +# End of 10.11 tests +# +# MDEV-39081 InnoDB: tried to purge non-delete-marked record, assertion fails in row_purge_del_mark_error # CREATE TABLE t1( pk INT AUTO_INCREMENT, @@ -323,3 +386,4 @@ connection default; COMMIT; InnoDB 0 transactions not purged DROP TABLE t1; +# End of 11.4 tests diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 366111d9654..f68e5954f16 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -600,6 +600,42 @@ SELECT (SELECT 1 FROM foo) FROM t1; ERROR 42S02: Table 'test.foo' doesn't exist INSERT INTO t1 (d1) VALUES ('2009-07-02'); DROP TABLE t1; +# +# MDEV-26820 Assertion `marked_for_read()' failed upon SELECT with VALUE(virtual column) +# +CREATE TABLE t1 (a VARCHAR(8), b VARCHAR(8) AS (REPEAT(a,1)) VIRTUAL) ENGINE=MyISAM; +INSERT INTO t1 (a) VALUES ('foo'),('bar'); +SELECT VALUE(b) FROM (SELECT * FROM t1) sq; +VALUE(b) +NULL +NULL +DROP TABLE t1; +CREATE TABLE t1 ( id uuid, vid varchar(255) GENERATED always AS (id)) engine=aria; +INSERT INTO t1 (id) values (uuid()),(uuid()),(uuid()); +SELECT VALUE( vid ) FROM (select * from t1)dt; +VALUE( vid ) +NULL +NULL +NULL +DROP TABLE t1; +# +# MDEV-28610 Assertion `marked_for_read()' failed upon range select with virtual column in index +# +CREATE TABLE t ( +a INT UNSIGNED NOT NULL DEFAULT 0, +b INT AS (a) VIRTUAL, +c TIME, +d INT, +e DATE, +f VARCHAR(1024), +PRIMARY KEY(c), +KEY(c,b,d,f(64)) +); +INSERT INTO t (c) VALUES ('00:00:00'),('00:00:04'); +SELECT c FROM t WHERE c BETWEEN '00:00:00' AND '00:00:00' ORDER BY d; +c +00:00:00 +DROP TABLE t; # End of 10.11 tests # # Start of 11.4 tests diff --git a/mysql-test/suite/vcol/r/vcol_partition_innodb.result b/mysql-test/suite/vcol/r/vcol_partition_innodb.result index c25fc7b2490..add193e6ddc 100644 --- a/mysql-test/suite/vcol/r/vcol_partition_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_partition_innodb.result @@ -1,4 +1,6 @@ SET @@session.default_storage_engine = 'InnoDB'; +set @save_stats_auto_recalc= @@global.innodb_stats_auto_recalc; +set global innodb_stats_auto_recalc= off; drop table if exists t1; # Case 1. Partitioning by RANGE based on a non-stored virtual column. CREATE TABLE t1 ( @@ -87,3 +89,4 @@ create table t1 (a int, b varchar(100) as (user())) partition by hash(b+1) parti ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed create table t1 (a int, b double as (rand())) partition by hash(b+1) partitions 3; ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +set global innodb_stats_auto_recalc= @save_stats_auto_recalc; diff --git a/mysql-test/suite/vcol/t/vcol_keys_innodb.test b/mysql-test/suite/vcol/t/vcol_keys_innodb.test index 1f4feb3204a..00e99e27229 100644 --- a/mysql-test/suite/vcol/t/vcol_keys_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.test @@ -137,8 +137,68 @@ alter table t1 drop column va; drop table t1; --echo # ---echo # MDEV-39081 InnoDB: tried to purge non-delete-marked record, ---echo # assertion fails in row_purge_del_mark_error +--echo # MDEV-36896 Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *) +--echo # + +set @old_isolation_level= @@session.tx_isolation; + +set @@session.tx_isolation= 'READ-UNCOMMITTED'; +create table t (a varchar(10),b int,c char(10) generated always as (a) virtual,key(b,c)) engine=innodb; +insert into t (a) values ('A'); +select * from t where b is null order by a; + +drop table t; + +create table t ( + a varchar(10), + b int, + c char(10) generated always as (a) virtual, + d int generated always as (if(a = c, 1, 0)) virtual, + key(b, c) +) engine=innodb; + +insert into t (a) values ('A'); +insert into t (a, b) values ('B', 1); +select * from t where b is null order by a; +drop table t; + +set @@session.tx_isolation= @old_isolation_level; + +--echo # +--echo # MDEV-41365 Wrong results from filesort over indexed virtual columns during a concurrent uncommitted update +--echo # +create table t ( + pk int primary key, + f int, + v1 int as (f & 1) virtual, + v2 int as (f & 2) virtual, + key (v1) +) engine=innodb; +insert into t (pk, f) values (1, 0); + +explain select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; +select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; + +connect con1, localhost, root; +begin; +update t set f = 1 where pk = 1; + +connection default; +--echo # No filesort +select * from t force index (v1) where v1 = 0 and v2 = 0; +--echo # Filesort: must return pk=1 +select * from t force index (v1) where v1 = 0 and v2 = 0 order by f, pk; + +connection con1; +rollback; +disconnect con1; +connection default; +drop table t; + +--echo # End of 10.11 tests + +--echo # +--echo # MDEV-39081 InnoDB: tried to purge non-delete-marked record, assertion fails in row_purge_del_mark_error --echo # CREATE TABLE t1( pk INT AUTO_INCREMENT, @@ -157,3 +217,5 @@ CONNECTION default; COMMIT; --source ../innodb/include/wait_all_purged.inc DROP TABLE t1; + +--echo # End of 11.4 tests diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index 8f9baf0502a..bf9da0e3aeb 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -578,6 +578,42 @@ SELECT (SELECT 1 FROM foo) FROM t1; INSERT INTO t1 (d1) VALUES ('2009-07-02'); DROP TABLE t1; +--echo # +--echo # MDEV-26820 Assertion `marked_for_read()' failed upon SELECT with VALUE(virtual column) +--echo # + +CREATE TABLE t1 (a VARCHAR(8), b VARCHAR(8) AS (REPEAT(a,1)) VIRTUAL) ENGINE=MyISAM; +INSERT INTO t1 (a) VALUES ('foo'),('bar'); +SELECT VALUE(b) FROM (SELECT * FROM t1) sq; + +DROP TABLE t1; + +CREATE TABLE t1 ( id uuid, vid varchar(255) GENERATED always AS (id)) engine=aria; +INSERT INTO t1 (id) values (uuid()),(uuid()),(uuid()); +SELECT VALUE( vid ) FROM (select * from t1)dt; + +DROP TABLE t1; + +--echo # +--echo # MDEV-28610 Assertion `marked_for_read()' failed upon range select with virtual column in index +--echo # + +CREATE TABLE t ( + a INT UNSIGNED NOT NULL DEFAULT 0, + b INT AS (a) VIRTUAL, + c TIME, + d INT, + e DATE, + f VARCHAR(1024), + PRIMARY KEY(c), + KEY(c,b,d,f(64)) +); +INSERT INTO t (c) VALUES ('00:00:00'),('00:00:04'); +SELECT c FROM t WHERE c BETWEEN '00:00:00' AND '00:00:00' ORDER BY d; + +# Cleanup +DROP TABLE t; + --echo # End of 10.11 tests --echo # diff --git a/mysql-test/suite/vcol/t/vcol_partition_innodb.test b/mysql-test/suite/vcol/t/vcol_partition_innodb.test index 7b8e8de25d4..881377516ac 100644 --- a/mysql-test/suite/vcol/t/vcol_partition_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_partition_innodb.test @@ -37,12 +37,17 @@ eval SET @@session.default_storage_engine = 'InnoDB'; ##### Workarounds for known open engine specific bugs -# none +# MDEV-38758: background stats recalc races with INSERT and makes +# table_rows in information_schema.partitions nondeterministic +set @save_stats_auto_recalc= @@global.innodb_stats_auto_recalc; +set global innodb_stats_auto_recalc= off; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines --source inc/vcol_partition.inc +set global innodb_stats_auto_recalc= @save_stats_auto_recalc; + #------------------------------------------------------------------------------# # Execute storage engine specific tests diff --git a/mysql-test/suite/versioning/r/debug.result b/mysql-test/suite/versioning/r/debug.result index 04f75fa350c..02bb24f85e6 100644 --- a/mysql-test/suite/versioning/r/debug.result +++ b/mysql-test/suite/versioning/r/debug.result @@ -104,3 +104,35 @@ disconnect con2; set @@timestamp= default; drop tables t1; set debug_sync= 'reset'; +# +# MDEV-41545 Unchecked get_clone() in ALTER of partitioned table +# crashes on out-of-memory +# +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' partitions 3; +set @save_dbug= @@debug_dbug; +set debug_dbug= '+d,prep_alter_part_table_get_clone_oom'; +alter table t1 partition by system_time interval 2 hour; +ERROR HY000: Out of memory. +set debug_dbug= @save_dbug; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' +PARTITIONS 3 +set debug_dbug= '+d,partition_info_get_clone_vers_oom'; +alter table t1 partition by system_time interval 2 hour; +ERROR HY000: Out of memory. +set debug_dbug= @save_dbug; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 00:00:00' +PARTITIONS 3 +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/suite/versioning/r/partition,heap.rdiff b/mysql-test/suite/versioning/r/partition,heap.rdiff index de35764d602..d137c248e39 100644 --- a/mysql-test/suite/versioning/r/partition,heap.rdiff +++ b/mysql-test/suite/versioning/r/partition,heap.rdiff @@ -221,3 +221,12 @@ # INSERT .. ON DUPLICATE KEY UPDATE (ODKU) set timestamp= unix_timestamp('2000-01-01 00:00:00'); create or replace table t1 (x int primary key) with system versioning +@@ -3663,7 +3456,7 @@ + # (except heap combination) + explain extended select max(id) from t1; + id select_type table type possible_keys key key_len ref rows filtered Extra +-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away ++1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 + Warnings: + Note 1003 select max(`test`.`t1`.`id`) AS `max(id)` from `test`.`t1` + drop tables t1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index c2a09cf7794..79f5738b666 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -373,10 +373,10 @@ set timestamp=unix_timestamp('2001-02-04 10:30:10'); update t1 set i=6 where i=5; select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; subpartition_name partition_description table_rows -p1sp0 2001-02-04 00:00:00 1 -p1sp1 2001-02-04 00:00:00 0 p0sp0 2001-02-05 00:00:00 1 p0sp1 2001-02-05 00:00:00 1 +p1sp0 2001-02-04 00:00:00 1 +p1sp1 2001-02-04 00:00:00 0 p2sp0 2001-02-06 00:00:00 0 p2sp1 2001-02-06 00:00:00 0 pnsp0 CURRENT 0 @@ -386,8 +386,8 @@ i 1 select * from t1 partition (p0); i -5 2 +5 select * from t1 partition (p2); i alter table t1 rebuild partition p0, p1, p2; @@ -396,8 +396,8 @@ i 1 select * from t1 partition (p0); i -5 2 +5 select * from t1 partition (p2); i ## pruning check @@ -409,7 +409,7 @@ i 6 explain partitions select * from t1; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t1 pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # explain partitions select * from t1 for system_time as of '2001-02-04 10:20:30'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0_p0sp0,p0_p0sp1,p2_p2sp0,p2_p2sp1,pn_pnsp0,pn_pnsp1 ALL NULL NULL NULL NULL # Using where @@ -1124,6 +1124,23 @@ update v1 set f= ''; ERROR HY000: Table 't1' was locked with a READ lock and can't be updated delete from v1; ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +# system_versioning_asof is ignored by DML, so it does not cause ER_TABLE_NOT_LOCKED_FOR_WRITE +create or replace view v1 as select * from t1; +set system_versioning_asof= '2000-01-01 00:00:00'; +select * from v1; +f +select * from v1 for update; +f +update v1 set f= ''; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0 +Warnings: +Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions +delete from v1; +affected rows: 1 +Warnings: +Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p2`) is out of LIMIT, need more HISTORY partitions +set system_versioning_asof= default; drop view v1; drop table t1; # @@ -2200,9 +2217,9 @@ t1 CREATE TABLE `t1` ( PARTITION `pn` CURRENT ENGINE = X) select * from t1; x -3 13 23 +3 select * from t1 for system_time all order by x; x 3 @@ -3626,5 +3643,304 @@ Table Op Msg_type Msg_text test.t repair status OK drop table t; set timestamp=default; +# +# MDEV-41543 Changing INTERVAL of SYSTEM_TIME partitioning does not move +# history to the new partitions +# +set time_zone= '+00:00'; +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' partitions 4; +set timestamp= unix_timestamp('2000-01-01 00:30:00'); +insert t1 values (0); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set x= 1; +set timestamp= unix_timestamp('2000-01-01 02:30:00'); +update t1 set x= 2; +select x, row_end from t1 partition (p0); +x row_end +select x, row_end from t1 partition (p1); +x row_end +0 2000-01-01 01:30:00.000000 +select x, row_end from t1 partition (p2); +x row_end +1 2000-01-01 02:30:00.000000 +# History is redistributed: p0 = [00:00, 02:00), p1 = [02:00, 04:00) +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +select x, row_end from t1 partition (p0); +x row_end +0 2000-01-01 01:30:00.000000 +select x, row_end from t1 partition (p1); +x row_end +1 2000-01-01 02:30:00.000000 +select x, row_end from t1 partition (p2); +x row_end +# Same interval: fast ALTER, no rows copied +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +set timestamp= unix_timestamp('2000-01-01 03:30:00'); +update t1 set x= 3; +select x, row_end from t1 partition (p1); +x row_end +1 2000-01-01 02:30:00.000000 +2 2000-01-01 03:30:00.000000 +# Same interval, no STARTS: it defaults to the current time, +# so the table is rebuilt +alter table t1 partition by system_time interval 2 hour; +affected rows: 4 +info: Records: 4 Duplicates: 0 Warnings: 0 +drop table t1; +# Explicit partitions +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' ( +partition p0 history, +partition p1 history, +partition p2 history, +partition pn current); +set timestamp= unix_timestamp('2000-01-01 00:30:00'); +insert t1 values (0); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set x= 1; +set timestamp= unix_timestamp('2000-01-01 02:30:00'); +update t1 set x= 2; +select x, row_end from t1 partition (p0); +x row_end +select x, row_end from t1 partition (p1); +x row_end +0 2000-01-01 01:30:00.000000 +select x, row_end from t1 partition (p2); +x row_end +1 2000-01-01 02:30:00.000000 +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +select x, row_end from t1 partition (p0); +x row_end +0 2000-01-01 01:30:00.000000 +select x, row_end from t1 partition (p1); +x row_end +1 2000-01-01 02:30:00.000000 +select x, row_end from t1 partition (p2); +x row_end +# LIMIT to INTERVAL +alter table t1 partition by system_time limit 100; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +alter table t1 partition by system_time interval 1 hour +starts '2000-01-01 00:00:00'; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +select x, row_end from t1 partition (p0); +x row_end +select x, row_end from t1 partition (p1); +x row_end +0 2000-01-01 01:30:00.000000 +select x, row_end from t1 partition (p2); +x row_end +1 2000-01-01 02:30:00.000000 +# Same interval with ADD COLUMN: the table is rebuilt +alter table t1 add y int partition by system_time interval 1 hour +starts '2000-01-01 00:00:00'; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +select x, y, row_end from t1 for system_time all order by x; +x y row_end +0 NULL 2000-01-01 01:30:00.000000 +1 NULL 2000-01-01 02:30:00.000000 +2 NULL 2106-02-07 06:28:15.999999 +# LIMIT with DROP COLUMN: the table is rebuilt +alter table t1 drop y partition by system_time limit 100; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +select x, row_end from t1 for system_time all order by x; +x row_end +0 2000-01-01 01:30:00.000000 +1 2000-01-01 02:30:00.000000 +2 2106-02-07 06:28:15.999999 +set timestamp= default; +set time_zone= default; +drop table t1; # End of 10.11 tests +# +# MDEV-17613 Read sole now-partition for non-historical versioned query +# +create table t1 ( +id int, +ts timestamp(6) generated always as row start invisible, +te timestamp(6) generated always as row end invisible, +primary key (id, te), +period for system_time (ts, te) +) with system versioning +partition by system_time interval 1 month ( +partition p0 history, partition p1 history, partition pcur current); +insert t1 values (1), (2), (0); +delete from t1 where id = 1; +select * from t1; +id +0 +2 +# Below there should be: Select tables optimized away +# (except heap combination) +explain extended select max(id) from t1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +Warnings: +Note 1003 select max(`test`.`t1`.`id`) AS `max(id)` from `test`.`t1` +# Exact COUNT(*) (MyISAM, heap) must not count history rows +select count(*) from t1; +count(*) +2 +# UPDATE without WHERE changes only current rows +update t1 set id= id + 10; +select * from t1; +id +10 +12 +select count(*) from t1 for system_time all; +count(*) +5 +# sql_safe_updates rejects DELETE without WHERE even with LIMIT, +# as for a non-versioned table +set sql_safe_updates= 1; +delete from t1 limit 1; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +set sql_safe_updates= default; +# DELETE without WHERE removes only current rows +delete from t1; +select count(*) from t1; +count(*) +0 +select count(*) from t1 for system_time all; +count(*) +5 +drop tables t1; +# Multi-table DELETE/UPDATE under sql_safe_updates: checks use the +# written WHERE and the join access types, as before +create table t1 (x int) with system versioning +partition by system_time (partition p0 history, partition pn current); +create table t2 (y int); +insert into t1 values (1), (2); +insert into t2 values (1), (2); +set sql_safe_updates= 1; +delete t1 from t1, t2; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +update t1, t2 set t1.x= t2.y; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +# LIMIT does not exempt multi-table UPDATE from the full join check +update t1, t2 set t1.x= t2.y order by t1.x limit 1; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +set sql_safe_updates= default; +drop tables t1, t2; +# As for a non-versioned table, an index on row_end does not exempt +# UPDATE/DELETE without WHERE: UPDATE needs LIMIT, DELETE is rejected +create table t1 ( +x int, +ts timestamp(6) as row start invisible, +te timestamp(6) as row end invisible, +period for system_time (ts, te), +key (te) +) with system versioning +partition by system_time (partition p0 history, partition pn current); +insert into t1 values (1), (2); +set sql_safe_updates= 1; +update t1 set x= x + 1; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +delete from t1; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +update t1 set x= x + 1 limit 1; +delete from t1 limit 1; +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +set sql_safe_updates= default; +drop table t1; +# Corner cases: outer and sysvar-set FOR SYSTEM_TIME +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (id int) +with system versioning +partition by system_time interval 1 hour +starts timestamp'2000-01-01 00:00:00' ( +partition p0 history, +partition p1 history, +partition pn current); +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set id= 2; +# implicit query reads only the current partition (id=2): +select id from t1; +id +2 +# outer FOR SYSTEM_TIME must propagate into derived t1 and read history (id=1): +select * from (select id from t1) for system_time as of timestamp'2000-01-01 01:00:00' as dt; +id +1 +# system_versioning_asof must be honored and read history (id=1): +set system_versioning_asof= '2000-01-01 01:00:00'; +select id from t1; +id +1 +set system_versioning_asof= default; +# re-execution reads only the current partition (id=2): +prepare s from 'select id from t1'; +execute s; +id +2 +execute s; +id +2 +deallocate prepare s; +create procedure sp() select id from t1; +call sp; +id +2 +call sp; +id +2 +drop procedure sp; +# the same through merged derived table and view (id=2): +create view v1 as select id from t1; +prepare s from 'select id from (select id from t1) dt'; +execute s; +id +2 +execute s; +id +2 +deallocate prepare s; +prepare s from 'select id from v1'; +execute s; +id +2 +execute s; +id +2 +deallocate prepare s; +create procedure sp() select id from (select id from t1) dt; +call sp; +id +2 +call sp; +id +2 +drop procedure sp; +drop view v1; +# re-execution with system_versioning_asof reads history (id=1): +set system_versioning_asof= '2000-01-01 01:00:00'; +prepare s from 'select id from t1'; +execute s; +id +1 +execute s; +id +1 +deallocate prepare s; +set system_versioning_asof= default; +set timestamp= default; +drop table t1; +# End of 11.4 tests set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result index a5a3f79990c..1766cdb2725 100644 --- a/mysql-test/suite/versioning/r/sysvars.result +++ b/mysql-test/suite/versioning/r/sysvars.result @@ -254,3 +254,24 @@ a DROP TABLE t1; SET system_versioning_asof= DEFAULT; # End of 10.4 tests +# +# MDEV-17613 Read sole now-partition for non-historical versioned query +# +# system_versioning_asof does not act as explicit FOR SYSTEM_TIME AS OF +create table t1 (x int) with system versioning; +insert into t1 values (1); +set system_versioning_asof= '2000-01-01 00:00:00'; +# Allowed, unlike explicit FOR SYSTEM_TIME AS OF: +select * from t1 for update; +x +select * from t1 for system_time as of timestamp'2000-01-01 00:00:00' for update; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +# Not printed as FOR SYSTEM_TIME AS OF: +explain extended select * from t1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select 1 AS `x` from dual where 0 +set system_versioning_asof= default; +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/suite/versioning/t/debug.test b/mysql-test/suite/versioning/t/debug.test index 94917f01389..4cdd6d0c804 100644 --- a/mysql-test/suite/versioning/t/debug.test +++ b/mysql-test/suite/versioning/t/debug.test @@ -106,3 +106,25 @@ set @@timestamp= default; drop tables t1; set debug_sync= 'reset'; + +--echo # +--echo # MDEV-41545 Unchecked get_clone() in ALTER of partitioned table +--echo # crashes on out-of-memory +--echo # +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' partitions 3; +set @save_dbug= @@debug_dbug; +set debug_dbug= '+d,prep_alter_part_table_get_clone_oom'; +--error ER_OUT_OF_RESOURCES +alter table t1 partition by system_time interval 2 hour; +set debug_dbug= @save_dbug; +show create table t1; +set debug_dbug= '+d,partition_info_get_clone_vers_oom'; +--error ER_OUT_OF_RESOURCES +alter table t1 partition by system_time interval 2 hour; +set debug_dbug= @save_dbug; +show create table t1; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 47f1b5f43f1..196c3641a6e 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -26,14 +26,17 @@ partition by range columns (x) ( partition p1 values less than (1000)); insert into t1 values (3), (300); +--sorted_result select * from t1; select * from t1 partition (p0); select * from t1 partition (p1); delete from t1; +--sorted_result select * from t1; select * from t1 partition (p0); select * from t1 partition (p1); +--sorted_result select * from t1 for system_time all; select * from t1 partition (p0) for system_time all; select * from t1 partition (p1) for system_time all; @@ -140,6 +143,7 @@ alter table t1 drop partition p1; --error ER_VERS_WRONG_PARTS alter table t1 drop partition p0; +--sorted_result select x from t1; --echo # rename works @@ -217,6 +221,7 @@ update t1 set x = x + 1; --source suite/versioning/wait_system_clock.inc +--sorted_result execute select_p0; execute select_pn; @@ -252,11 +257,14 @@ show create table t1; alter table t1 drop partition non_existent; insert into t1 values (1), (2), (3), (4), (5), (6); +--sorted_result select * from t1 partition (pn); delete from t1 where x < 4; delete from t1; --echo # You see warning above ^ +--sorted_result select * from t1 partition (p0); +--sorted_result select * from t1 partition (p1); insert into t1 values (7), (8); @@ -289,13 +297,17 @@ set @ts=(select partition_description from information_schema.partitions where table_schema='test' and table_name='t1' and partition_name='p0'); alter table t1 add column b int; +--sorted_result select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 add partition (partition p1 history, partition p2 history); +--sorted_result select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 drop partition p0; +--sorted_result select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; --error ER_VERS_DROP_PARTITION_INTERVAL alter table t1 drop partition p2; +--sorted_result select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; # @@ -311,7 +323,9 @@ insert t1 values (1); delete from t1; set timestamp=unix_timestamp('2001-02-04 10:20:50'); insert t1 values (2); delete from t1; +--sorted_result select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; +--sorted_result select * from t1 partition (p1); set timestamp=unix_timestamp('2001-02-04 10:20:55'); @@ -321,13 +335,16 @@ insert t1 values (4),(5); set timestamp=unix_timestamp('2001-02-04 10:30:10'); update t1 set i=6 where i=5; +--sorted_result select subpartition_name, partition_description, table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; select * from t1 partition (p1); +--sorted_result select * from t1 partition (p0); select * from t1 partition (p2); alter table t1 rebuild partition p0, p1, p2; select * from t1 partition (p1); +--sorted_result select * from t1 partition (p0); select * from t1 partition (p2); @@ -467,6 +484,7 @@ set timestamp= unix_timestamp('2001-01-01 00:00:02'); update t1 set i= i + 1; select *, row_end from t1 partition (p0); +--sorted_result select *, row_end from t1 partition (p1); set timestamp= unix_timestamp('2000-01-01 00:00:00'); @@ -485,6 +503,7 @@ update t1 set i= i + 1; set timestamp= unix_timestamp('2000-01-04 00:00:01'); update t1 set i= i + 1; +--sorted_result select *, row_end from t1 partition (p0); select *, row_end from t1 partition (p1); @@ -520,7 +539,9 @@ subpartition by key (x) subpartitions 2; insert into t1 (x) values (1), (2), (3), (4), (5); +--sorted_result select * from t1 partition (pnsp0); +--sorted_result select * from t1 partition (pnsp1); delete from t1 where x < 3; @@ -530,6 +551,7 @@ delete from t1; --echo # You see warning above ^ (no matter if nothing was deleted) select * from t1 partition (p0sp0); select * from t1 partition (p0sp1); +--sorted_result select * from t1 partition (p1sp0); select * from t1 partition (p1sp1); @@ -874,6 +896,7 @@ create or replace table t1 ( insert into t1 (x) values (1), (2), (3), (4); update t1 set a= 'foo' limit 3; update t1 set a= 'bar' limit 4; +--sorted_result select * from t1; drop table t1; @@ -931,6 +954,7 @@ create or replace table t1 (pk int primary key, f int) engine=innodb partition by key() partitions 2; insert into t1 values (1,10),(2,20); --echo # expected to hit same partition +--sorted_result select * from t1 partition (p0); alter table t1 drop system versioning; @@ -970,6 +994,17 @@ update v1 set f= ''; --error ER_TABLE_NOT_LOCKED_FOR_WRITE delete from v1; +--echo # system_versioning_asof is ignored by DML, so it does not cause ER_TABLE_NOT_LOCKED_FOR_WRITE +create or replace view v1 as select * from t1; +set system_versioning_asof= '2000-01-01 00:00:00'; +select * from v1; +select * from v1 for update; +--enable_info +update v1 set f= ''; +delete from v1; +--disable_info +set system_versioning_asof= default; + # cleanup drop view v1; drop table t1; @@ -1131,17 +1166,20 @@ replace into t1 select seq from seq_1_to_70; # Puts 60 rows into p1 replace into t1 select seq from seq_1_to_60; +--sorted_result select partition_name, table_rows from information_schema.partitions where table_name = 't1'; rollback; +--sorted_result select partition_name, table_rows from information_schema.partitions where table_name = 't1'; # Should put 10 rows into the empty partition p0 replace into t1 select seq from seq_1_to_10; +--sorted_result select partition_name, table_rows from information_schema.partitions where table_name = 't1'; @@ -1623,6 +1661,7 @@ starts '2000-01-01 00:00:00'; --replace_result $default_engine DEFAULT_ENGINE show create table t1; select * from t1 partition (p0); +--sorted_result select * from t1 partition (p1); select * from t1 partition (p2); select * from t1 partition (pn); @@ -1638,6 +1677,7 @@ update t1 set x= x + 1; update t1 set x= x + 1; --echo # You see warning above ^ select * from t1 partition (p0); +--sorted_result select * from t1 partition (p1); select * from t1 partition (p2); select * from t1 partition (p3); @@ -1792,6 +1832,7 @@ select * from tp1 for system_time all; --replace_result $default_engine X ' PAGE_CHECKSUM=1' '' show create table t1; +--sorted_result select * from t1; select * from t1 for system_time all order by x; @@ -2647,6 +2688,7 @@ eval insert into t1 (a,row_start,row_end) values ('p1', '2021-09-30', '2021-10-01 10:00:00'), ('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'), ('pn, current', '2021-09-30', $sys_time_max); +--sorted_result select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows from information_schema.partitions where table_schema='test'; drop table t1; @@ -2790,6 +2832,7 @@ update t1 set x= 3; --echo # CREATE result: row 1 got into p1 select *, row_start, row_end from t1 partition (p0); +--sorted_result select *, row_start, row_end from t1 partition (p1); flush tables; --echo # For CREATE pruning is affected by current timestamp, but SELECT works @@ -2809,6 +2852,7 @@ partition by system_time interval 1 hour ( --echo # ALTER result: row 1 got into p1 Select *, row_start, row_end from t1 partition (p0); +--sorted_result Select *, row_start, row_end from t1 partition (p1); flush tables; Explain partitions select * from t1 for system_time as of '2000-01-01 00:59:59'; @@ -2871,7 +2915,230 @@ repair table t; drop table t; set timestamp=default; +--echo # +--echo # MDEV-41543 Changing INTERVAL of SYSTEM_TIME partitioning does not move +--echo # history to the new partitions +--echo # +set time_zone= '+00:00'; +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' partitions 4; +set timestamp= unix_timestamp('2000-01-01 00:30:00'); +insert t1 values (0); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set x= 1; +set timestamp= unix_timestamp('2000-01-01 02:30:00'); +update t1 set x= 2; +select x, row_end from t1 partition (p0); +select x, row_end from t1 partition (p1); +select x, row_end from t1 partition (p2); +--echo # History is redistributed: p0 = [00:00, 02:00), p1 = [02:00, 04:00) +--enable_info +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +--disable_info +select x, row_end from t1 partition (p0); +select x, row_end from t1 partition (p1); +select x, row_end from t1 partition (p2); +--echo # Same interval: fast ALTER, no rows copied +--enable_info +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +--disable_info +set timestamp= unix_timestamp('2000-01-01 03:30:00'); +update t1 set x= 3; +select x, row_end from t1 partition (p1); +--echo # Same interval, no STARTS: it defaults to the current time, +--echo # so the table is rebuilt +--enable_info +alter table t1 partition by system_time interval 2 hour; +--disable_info +drop table t1; +--echo # Explicit partitions +create table t1 (x int) with system versioning +partition by system_time interval 1 hour +starts '2000-01-01 00:00:00' ( + partition p0 history, + partition p1 history, + partition p2 history, + partition pn current); +set timestamp= unix_timestamp('2000-01-01 00:30:00'); +insert t1 values (0); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set x= 1; +set timestamp= unix_timestamp('2000-01-01 02:30:00'); +update t1 set x= 2; +select x, row_end from t1 partition (p0); +select x, row_end from t1 partition (p1); +select x, row_end from t1 partition (p2); +--enable_info +alter table t1 partition by system_time interval 2 hour +starts '2000-01-01 00:00:00'; +--disable_info +select x, row_end from t1 partition (p0); +select x, row_end from t1 partition (p1); +select x, row_end from t1 partition (p2); +--echo # LIMIT to INTERVAL +--enable_info +alter table t1 partition by system_time limit 100; +alter table t1 partition by system_time interval 1 hour +starts '2000-01-01 00:00:00'; +--disable_info +select x, row_end from t1 partition (p0); +select x, row_end from t1 partition (p1); +select x, row_end from t1 partition (p2); +--echo # Same interval with ADD COLUMN: the table is rebuilt +--enable_info +alter table t1 add y int partition by system_time interval 1 hour +starts '2000-01-01 00:00:00'; +--disable_info +select x, y, row_end from t1 for system_time all order by x; +--echo # LIMIT with DROP COLUMN: the table is rebuilt +--enable_info +alter table t1 drop y partition by system_time limit 100; +--disable_info +select x, row_end from t1 for system_time all order by x; +set timestamp= default; +set time_zone= default; +drop table t1; + --echo # End of 10.11 tests +--echo # +--echo # MDEV-17613 Read sole now-partition for non-historical versioned query +--echo # +create table t1 ( + id int, + ts timestamp(6) generated always as row start invisible, + te timestamp(6) generated always as row end invisible, + primary key (id, te), + period for system_time (ts, te) +) with system versioning +partition by system_time interval 1 month ( + partition p0 history, partition p1 history, partition pcur current); + +insert t1 values (1), (2), (0); +delete from t1 where id = 1; +--sorted_result +select * from t1; +--echo # Below there should be: Select tables optimized away +--echo # (except heap combination) +explain extended select max(id) from t1; +--echo # Exact COUNT(*) (MyISAM, heap) must not count history rows +select count(*) from t1; +--echo # UPDATE without WHERE changes only current rows +update t1 set id= id + 10; +--sorted_result +select * from t1; +select count(*) from t1 for system_time all; +--echo # sql_safe_updates rejects DELETE without WHERE even with LIMIT, +--echo # as for a non-versioned table +set sql_safe_updates= 1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +delete from t1 limit 1; +set sql_safe_updates= default; +--echo # DELETE without WHERE removes only current rows +delete from t1; +select count(*) from t1; +select count(*) from t1 for system_time all; + +drop tables t1; + +--echo # Multi-table DELETE/UPDATE under sql_safe_updates: checks use the +--echo # written WHERE and the join access types, as before +create table t1 (x int) with system versioning +partition by system_time (partition p0 history, partition pn current); +create table t2 (y int); +insert into t1 values (1), (2); +insert into t2 values (1), (2); +set sql_safe_updates= 1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +delete t1 from t1, t2; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +update t1, t2 set t1.x= t2.y; +--echo # LIMIT does not exempt multi-table UPDATE from the full join check +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +update t1, t2 set t1.x= t2.y order by t1.x limit 1; +set sql_safe_updates= default; +drop tables t1, t2; + +--echo # As for a non-versioned table, an index on row_end does not exempt +--echo # UPDATE/DELETE without WHERE: UPDATE needs LIMIT, DELETE is rejected +create table t1 ( + x int, + ts timestamp(6) as row start invisible, + te timestamp(6) as row end invisible, + period for system_time (ts, te), + key (te) +) with system versioning +partition by system_time (partition p0 history, partition pn current); +insert into t1 values (1), (2); +set sql_safe_updates= 1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +update t1 set x= x + 1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +delete from t1; +update t1 set x= x + 1 limit 1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +delete from t1 limit 1; +set sql_safe_updates= default; +drop table t1; + +--echo # Corner cases: outer and sysvar-set FOR SYSTEM_TIME +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 (id int) +with system versioning +partition by system_time interval 1 hour +starts timestamp'2000-01-01 00:00:00' ( + partition p0 history, + partition p1 history, + partition pn current); +insert into t1 values (1); +set timestamp= unix_timestamp('2000-01-01 01:30:00'); +update t1 set id= 2; +--echo # implicit query reads only the current partition (id=2): +select id from t1; +--echo # outer FOR SYSTEM_TIME must propagate into derived t1 and read history (id=1): +select * from (select id from t1) for system_time as of timestamp'2000-01-01 01:00:00' as dt; +--echo # system_versioning_asof must be honored and read history (id=1): +set system_versioning_asof= '2000-01-01 01:00:00'; +select id from t1; +set system_versioning_asof= default; +--echo # re-execution reads only the current partition (id=2): +prepare s from 'select id from t1'; +execute s; +execute s; +deallocate prepare s; +create procedure sp() select id from t1; +call sp; +call sp; +drop procedure sp; +--echo # the same through merged derived table and view (id=2): +create view v1 as select id from t1; +prepare s from 'select id from (select id from t1) dt'; +execute s; +execute s; +deallocate prepare s; +prepare s from 'select id from v1'; +execute s; +execute s; +deallocate prepare s; +create procedure sp() select id from (select id from t1) dt; +call sp; +call sp; +drop procedure sp; +drop view v1; +--echo # re-execution with system_versioning_asof reads history (id=1): +set system_versioning_asof= '2000-01-01 01:00:00'; +prepare s from 'select id from t1'; +execute s; +execute s; +deallocate prepare s; +set system_versioning_asof= default; +set timestamp= default; +drop table t1; + +--echo # End of 11.4 tests + set global innodb_stats_persistent= @save_persistent; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test index 91dd278a2e1..de3ddf758a5 100644 --- a/mysql-test/suite/versioning/t/sysvars.test +++ b/mysql-test/suite/versioning/t/sysvars.test @@ -204,3 +204,21 @@ DROP TABLE t1; SET system_versioning_asof= DEFAULT; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-17613 Read sole now-partition for non-historical versioned query +--echo # +--echo # system_versioning_asof does not act as explicit FOR SYSTEM_TIME AS OF +create table t1 (x int) with system versioning; +insert into t1 values (1); +set system_versioning_asof= '2000-01-01 00:00:00'; +--echo # Allowed, unlike explicit FOR SYSTEM_TIME AS OF: +select * from t1 for update; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +select * from t1 for system_time as of timestamp'2000-01-01 00:00:00' for update; +--echo # Not printed as FOR SYSTEM_TIME AS OF: +explain extended select * from t1; +set system_versioning_asof= default; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/wsrep/r/wsrep_protocol_versions.result b/mysql-test/suite/wsrep/r/wsrep_protocol_versions.result index 0d2759aaa89..f81ab8cef1a 100644 --- a/mysql-test/suite/wsrep/r/wsrep_protocol_versions.result +++ b/mysql-test/suite/wsrep/r/wsrep_protocol_versions.result @@ -1,7 +1,7 @@ # Correct Galera library found show status like 'wsrep_protocol%'; Variable_name Value -wsrep_protocol_application 4 +wsrep_protocol_application 5 wsrep_protocol_gcs 6 wsrep_protocol_replicator 11 wsrep_protocol_version 11 diff --git a/mysys/charset.c b/mysys/charset.c index 2bd977bf734..22713aaccb8 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -453,6 +453,7 @@ static int add_collation(struct charset_info_st *cs) newcs->coll_name.length= cs->coll_name.length; } } + DBUG_ASSERT(!newcs->coll || newcs->coll->tailoring); cs->number= 0; cs->primary_number= 0; cs->binary_number= 0; @@ -593,6 +594,7 @@ CHARSET_INFO *default_charset_info = &my_charset_latin1; int add_compiled_collation(struct charset_info_st *cs) { DBUG_ASSERT(cs->number < array_elements(all_charsets)); + DBUG_ASSERT(cs->coll->tailoring); all_charsets[cs->number]= cs; cs->state|= MY_CS_AVAILABLE; if ((my_hash_insert(&charset_name_hash, (uchar*) cs))) @@ -624,6 +626,7 @@ int add_compiled_collation(struct charset_info_st *cs) void add_compiled_extra_collation(struct charset_info_st *cs) { DBUG_ASSERT(cs->number < array_elements(all_charsets)); + DBUG_ASSERT(cs->coll->tailoring); all_charsets[cs->number]= cs; cs->state|= MY_CS_AVAILABLE; if ((my_hash_insert(&charset_name_hash, (uchar*) cs))) diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 92e68fc36a1..aafa476c71d 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -1200,6 +1200,7 @@ dynamic_column_decimal_read(DYNAMIC_COLUMN_VALUE *store_it_here, uchar *data, size_t length) { size_t intg_len, frac_len; + ulonglong u_intg, u_frac; int intg, frac, precision, scale; dynamic_column_prepare_decimal(store_it_here); @@ -1207,18 +1208,27 @@ dynamic_column_decimal_read(DYNAMIC_COLUMN_VALUE *store_it_here, if (length == 0) return ER_DYNCOL_OK; /* value contains zero */ - intg= (int)dynamic_column_var_uint_get(data, length, &intg_len); + u_intg= dynamic_column_var_uint_get(data, length, &intg_len); data+= intg_len; - frac= (int)dynamic_column_var_uint_get(data, length - intg_len, &frac_len); + u_frac= dynamic_column_var_uint_get(data, length - intg_len, &frac_len); data+= frac_len; + /* Reject before narrowing to int, so a wrap-around can't hide a bad value */ + if (intg_len == 0 || frac_len == 0 || + u_intg > DECIMAL_MAX_POSSIBLE_PRECISION || + u_frac > DECIMAL_MAX_POSSIBLE_PRECISION) + return ER_DYNCOL_FORMAT; + intg= (int) u_intg; + frac= (int) u_frac; + /* Check the size of data is correct */ precision= intg + frac; scale= frac; - if (scale < 0 || precision <= 0 || scale > precision || + if (precision <= 0 || scale > precision || + precision > DECIMAL_MAX_POSSIBLE_PRECISION || (length - intg_len - frac_len) > (size_t) (DECIMAL_BUFF_LENGTH*sizeof(decimal_digit_t)) || - decimal_bin_size(intg + frac, frac) != + decimal_bin_size(precision, scale) != (uint) (length - intg_len - frac_len)) return ER_DYNCOL_FORMAT; diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 9d9f544721c..b96b8448424 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -549,7 +549,7 @@ int init_simple_key_cache(void *keycache_, blocks--; keycache->allocated_mem_size= blocks * keycache->key_cache_block_size; if ((keycache->block_mem= my_large_malloc(&keycache->allocated_mem_size, - MYF(0)))) + my_large_pages_flag))) { /* Allocate memory for blocks, hash_links and hash entries; diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 70b8c732ae7..e5aa4bc7ffa 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -54,7 +54,7 @@ static void *root_alloc(MEM_ROOT *root, size_t size, size_t *alloced_size, { void *ptr; *alloced_size= MY_ALIGN(size, my_system_page_size); - if ((ptr= my_virtual_mem_commit(NULL, *alloced_size))) + if ((ptr= my_virtual_mem_commit(NULL, *alloced_size, MYF(0)))) update_malloc_size(*alloced_size, MY_TEST(root->flags & ROOT_FLAG_THREAD_SPECIFIC)); return ptr; diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c index a3af01a798c..b4886aeae49 100644 --- a/mysys/my_largepage.c +++ b/mysys/my_largepage.c @@ -36,7 +36,7 @@ extern int memcntl(caddr_t, size_t, int, caddr_t, int, int); #endif /* HAVE_SOLARIS_LARGE_PAGES */ -my_bool my_use_large_pages; +READ_ONLY_SYSVAR myf my_large_pages_flag; #ifdef _WIN32 static size_t my_large_page_size; @@ -187,21 +187,23 @@ static size_t my_next_large_page_size(size_t sz, int *start) int my_init_large_pages(void) { - my_use_large_pages= 1; #ifdef _WIN32 - if (!my_obtain_privilege(SE_LOCK_MEMORY_NAME)) - { + my_large_pages_flag= my_obtain_privilege(SE_LOCK_MEMORY_NAME) + ? MY_TRY_LARGE_PAGES : 0; + if (!my_large_pages_flag) my_printf_error(EE_PERM_LOCK_MEMORY, "Lock Pages in memory access rights required for use with" " large-pages, see " "https://mariadb.com/docs/server/ha-and-performance/mariadb-memory-allocation#huge-pages" , MYF(MY_WME)); - my_use_large_pages= 0; - } my_large_page_size= GetLargePageMinimum(); #endif my_get_large_page_sizes(my_large_page_sizes); +#ifndef _WIN32 + /* my_large_pages_flag is 0 unless a usable large page size exists. */ + my_large_pages_flag= my_large_page_sizes[0] ? MY_TRY_LARGE_PAGES : 0; +#endif #ifdef HAVE_SOLARIS_LARGE_PAGES extern my_bool opt_super_large_pages; @@ -256,7 +258,7 @@ int my_init_large_pages(void) */ void my_large_page_truncate(size_t *size) { - if (my_use_large_pages) + if (my_large_pages_flag) { size_t large_page_size= 0; #ifdef _WIN32 @@ -295,13 +297,21 @@ MAP_ANON but MAP_ANONYMOUS is marked "for compatibility" */ uchar *my_large_malloc(size_t *size, myf my_flags) { uchar *ptr= NULL; + /* + Only actually attempt large pages if the caller passed + MY_TRY_LARGE_PAGES (the caller is expected to only pass what it got + from my_large_pages_flag); otherwise always do a plain allocation of + the exact requested size, so *size is never rounded up to the large + page granularity. + */ + const my_bool use_large_pages= (my_flags & MY_TRY_LARGE_PAGES) != 0; #ifdef _WIN32 DWORD alloc_type= MEM_COMMIT | MEM_RESERVE; size_t orig_size= *size; DBUG_ENTER("my_large_malloc"); - if (my_use_large_pages) + if (use_large_pages) { alloc_type|= MEM_LARGE_PAGES; /* Align block size to my_large_page_size */ @@ -312,7 +322,7 @@ uchar *my_large_malloc(size_t *size, myf my_flags) { if (my_flags & MY_WME) { - if (my_use_large_pages) + if (use_large_pages) { my_printf_error(EE_OUTOFMEMORY, "Couldn't allocate %zu bytes (MEM_LARGE_PAGES page " @@ -325,7 +335,7 @@ uchar *my_large_malloc(size_t *size, myf my_flags) my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_ERROR_LOG), *size); } } - if (my_use_large_pages) + if (use_large_pages) { *size= orig_size; ptr= VirtualAlloc(NULL, *size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -345,7 +355,7 @@ uchar *my_large_malloc(size_t *size, myf my_flags) while (1) { mapflag= MAP_PRIVATE | OS_MAP_ANON; - if (my_use_large_pages) + if (use_large_pages) { large_page_size= my_next_large_page_size(*size, &page_i); /* this might be 0, in which case we do a standard mmap */ @@ -432,16 +442,39 @@ uchar *my_large_malloc(size_t *size, myf my_flags) Special large pages allocator, with possibility to commit to allocating more memory later. Every implementation returns a zero filled buffer here. + Initial protection of returned buffer is readwrite, if MY_TRY_LARGE_PAGES + is set in my_flags or on AIX(ask Marko why), but no access otherwise. + The caller is expected to call my_virtual_mem_commit() before using memory. */ -char *my_large_virtual_alloc(size_t *size) +char *my_large_virtual_alloc(size_t *size, myf my_flags) { char *ptr; +#ifdef _AIX + int flags= MAP_PRIVATE | OS_MAP_ANON; + int prot= PROT_READ | PROT_WRITE; +#else + /* + Illumos important to have MAP_NORESERVE otherwise reserves all swap. On + innodb_buffer_pool_size_max overallocation. + Linux is controlled on sysctl vm.overcommit_memory. + */ + int flags= MAP_PRIVATE | OS_MAP_ANON | MAP_NORESERVE; + int prot= PROT_NONE; +#endif DBUG_ENTER("my_large_virtual_alloc"); - if (my_use_large_pages) + if (my_flags & MY_TRY_LARGE_PAGES) { size_t large_page_size; int page_i= 0; + /* + MY_TRY_LARGE_PAGES needs memory that is guaranteed to be usable right + away, whether or not a usable large page size is found below, so + MAP_NORESERVE does not apply here (matching the loop's own mapflag, + which never uses it either). On AIX, this is already the case. + */ + prot= PROT_READ | PROT_WRITE; + flags= MAP_PRIVATE | OS_MAP_ANON; while ((large_page_size= my_next_large_page_size(*size, &page_i)) != 0) { @@ -469,7 +502,7 @@ char *my_large_virtual_alloc(size_t *size) OS_MAP_ANON; size_t aligned_size= MY_ALIGN(*size, (size_t) large_page_size); - ptr= mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, mapflag, -1, 0); + ptr= mmap(NULL, aligned_size, prot, mapflag, -1, 0); if (ptr == MAP_FAILED) { ptr= NULL; @@ -490,24 +523,9 @@ char *my_large_virtual_alloc(size_t *size) DBUG_RETURN(ptr); } } - - my_use_large_pages= FALSE; } -# ifdef _AIX - /* On IBM AIX, my_virtual_mem_commit() relies on mprotect(2) rather than - a subsequent mmap(2) with MAP_FIXED. */ - ptr= mmap(NULL, *size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | OS_MAP_ANON, -1, 0); -# else -/* - Illumos important to have MAP_NORESERVE otherwise reserves all swap. On - innodb_buffer_pool_size_max overallocation. - Linux is controlled on sysctl vm.overcommit_memory. -*/ - ptr= mmap(NULL, *size, PROT_NONE, MAP_PRIVATE | OS_MAP_ANON | MAP_NORESERVE, - -1, 0); -# endif + ptr= mmap(NULL, *size, prot, flags, -1, 0); if (ptr == MAP_FAILED) ptr= NULL; diff --git a/mysys/my_virtual_mem.c b/mysys/my_virtual_mem.c index acd63a9b0a8..0c1ae5a7618 100644 --- a/mysys/my_virtual_mem.c +++ b/mysys/my_virtual_mem.c @@ -37,12 +37,14 @@ InnoDB, the only user of this functionality), but it's the established terminology. - We try to respect use_large_pages setting, both on Windows and Linux + The caller requests large pages by passing my_large_pages_flag in + my_flags, consistently across the reserve/commit/decommit/release + calls for a given allocation. */ -char *my_virtual_mem_reserve(size_t *size) +char *my_virtual_mem_reserve(size_t *size, myf my_flags) { #ifdef _WIN32 - DWORD flags= my_use_large_pages + DWORD flags= (my_flags & MY_TRY_LARGE_PAGES) ? MEM_LARGE_PAGES | MEM_RESERVE | MEM_COMMIT : MEM_RESERVE; char *ptr= VirtualAlloc(NULL, *size, flags, PAGE_READWRITE); @@ -55,7 +57,7 @@ char *my_virtual_mem_reserve(size_t *size) } return ptr; #else - return my_large_virtual_alloc(size); + return my_large_virtual_alloc(size, my_flags); #endif } @@ -76,12 +78,12 @@ static my_bool is_memory_committed(char *ptr, size_t size) This is compatible with the mmap / VirtualAlloc semantics. */ -char *my_virtual_mem_commit(char *ptr, size_t size) +char *my_virtual_mem_commit(char *ptr, size_t size, myf my_flags) { #ifdef _WIN32 if (!ptr) return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (my_use_large_pages) + if (my_flags & MY_TRY_LARGE_PAGES) { DBUG_ASSERT(is_memory_committed(ptr, size)); } @@ -102,7 +104,7 @@ char *my_virtual_mem_commit(char *ptr, size_t size) MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); return p == MAP_FAILED ? NULL : p; } - if (my_use_large_pages) + if (my_flags & MY_TRY_LARGE_PAGES) /* my_large_virtual_alloc() already created a read/write mapping. */; else { @@ -142,44 +144,50 @@ char *my_virtual_mem_commit(char *ptr, size_t size) return ptr; } -void my_virtual_mem_decommit(char *ptr, size_t size) +void my_virtual_mem_decommit(char *ptr, size_t size, myf my_flags) { #ifdef _WIN32 DBUG_ASSERT(is_memory_committed(ptr, size)); - if (!my_use_large_pages) +#endif + /* + For large pages, decommit is no-op, except accounting. + This mirrors virtual_mem_commit behavior. + */ + if (!(my_flags & MY_TRY_LARGE_PAGES)) { +#ifdef _WIN32 if (!VirtualFree(ptr, size, MEM_DECOMMIT)) { my_error(EE_BADMEMORYRELEASE, MYF(ME_ERROR_LOG_ONLY), ptr, size, GetLastError()); DBUG_ASSERT(0); } - } #else # ifdef _AIX - disclaim(ptr, size, DISCLAIM_ZEROMEM); + disclaim(ptr, size, DISCLAIM_ZEROMEM); # elif defined __linux__ || defined __osf__ - madvise(ptr, size, MADV_DONTNEED); /* OSF/1, Linux mimicing AIX disclaim() */ + madvise(ptr, size, MADV_DONTNEED); /* OSF/1, Linux mimicing AIX disclaim() */ # elif defined MADV_FREE_REUSABLE && defined MADV_FREE_REUSE - /* Mac OS X 10.9; undocumented in Apple macOS */ - madvise(ptr, size, MADV_FREE_REUSABLE); /* macOS mimicing AIX disclaim() */ + /* Mac OS X 10.9; undocumented in Apple macOS */ + madvise(ptr, size, MADV_FREE_REUSABLE); /* macOS mimicing AIX disclaim() */ # elif defined MADV_PURGE /* Illumos */ - madvise(ptr, size, MADV_PURGE); /* Illumos mimicing AIX disclaim() */ + madvise(ptr, size, MADV_PURGE); /* Illumos mimicing AIX disclaim() */ # elif defined MADV_FREE - /* FreeBSD, NetBSD, OpenBSD, Dragonfly BSD, OpenSolaris, Apple macOS */ - madvise(ptr, size, MADV_FREE); /* allow lazy zeroing out */ + /* FreeBSD, NetBSD, OpenBSD, Dragonfly BSD, OpenSolaris, Apple macOS */ + madvise(ptr, size, MADV_FREE); /* allow lazy zeroing out */ # elif defined MADV_DONTNEED # warning "It is unclear if madvise(MADV_DONTNEED) works as intended" - madvise(ptr, size, MADV_DONTNEED); + madvise(ptr, size, MADV_DONTNEED); # else # warning "Do not know how to decommit memory" # endif - if (mprotect(ptr, size, PROT_NONE)) - { - my_error(EE_BADMEMORYRELEASE, MYF(ME_ERROR_LOG_ONLY), ptr, size, errno); - DBUG_ASSERT(0); - } + if (mprotect(ptr, size, PROT_NONE)) + { + my_error(EE_BADMEMORYRELEASE, MYF(ME_ERROR_LOG_ONLY), ptr, size, errno); + DBUG_ASSERT(0); + } #endif + } update_malloc_size(-(longlong) size, 0); } diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c index dd4156daebd..5ca42a487c4 100644 --- a/mysys/my_winerr.c +++ b/mysys/my_winerr.c @@ -73,7 +73,7 @@ static struct errentry errtable[]= { { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ { ERROR_LOCK_FAILED, EACCES }, /* 167 */ { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */ - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ + { ERROR_FILENAME_EXCED_RANGE, ENAMETOOLONG }, /* 206 */ { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */ { ERROR_FILE_SYSTEM_LIMITATION, EFBIG }, /* 665 */ { ERROR_NO_SYSTEM_RESOURCES, ENOMEM }, /* 1450 */ diff --git a/mysys/my_winfile.cc b/mysys/my_winfile.cc index 82a60ee141b..04e89118e51 100644 --- a/mysys/my_winfile.cc +++ b/mysys/my_winfile.cc @@ -159,6 +159,20 @@ LPSECURITY_ATTRIBUTES my_win_file_secattr() } +/* + A relative path (e.g one built from the current data directory after + my_setwd()) can resolve to a full path longer than MAX_PATH even though + the path itself is short. +*/ +static bool resolved_path_too_long(const char *path) +{ + char full_path[MAX_PATH]; + DWORD full_len= GetFullPathName(path, sizeof(full_path), full_path, 0); + return full_len >= MAX_PATH || + (full_len == 0 && GetLastError() == ERROR_FILENAME_EXCED_RANGE); +} + + /* Open a file with sharing. Similar to _sopen() from libc, but allows managing share delete on win32 @@ -303,7 +317,7 @@ File my_win_sopen(const char *path, int oflag, int shflag, int pmode) filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) { DWORD last_error= GetLastError(); - if (last_error == ERROR_PATH_NOT_FOUND && strlen(path) >= MAX_PATH) + if (last_error == ERROR_PATH_NOT_FOUND && resolved_path_too_long(path)) errno= ENAMETOOLONG; else my_osmaperr(last_error); /* map error */ diff --git a/plugin/func_test/mysql-test/func_test/collation_tailoring_args.result b/plugin/func_test/mysql-test/func_test/collation_tailoring_args.result new file mode 100644 index 00000000000..81ab5d5f1a3 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/collation_tailoring_args.result @@ -0,0 +1,62 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# Arguments of collation_tailoring(): the repertoire can be passed +# as a name or as a number +# +# The numeric repertoire gives the same result as the named one +SELECT +collation_tailoring('latin1_swedish_ci', 0) = +collation_tailoring('latin1_swedish_ci', 'none') AS none_ok, +collation_tailoring('latin1_swedish_ci', 1) = +collation_tailoring('latin1_swedish_ci', 'ascii_digits') AS digits_ok, +collation_tailoring('latin1_swedish_ci', 193) = +collation_tailoring('latin1_swedish_ci', 'ascii_minus_dot_digits') +AS minus_dot_digits_ok, +collation_tailoring('latin1_swedish_ci', 7) = +collation_tailoring('latin1_swedish_ci', 'ascii_alnum') AS alnum_ok, +collation_tailoring('latin1_swedish_ci', 15) = +collation_tailoring('latin1_swedish_ci', 'ascii_ident') AS ident_ok, +collation_tailoring('latin1_swedish_ci', 223) = +collation_tailoring('latin1_swedish_ci', 'ascii') AS ascii_ok; +none_ok digits_ok minus_dot_digits_ok alnum_ok ident_ok ascii_ok +1 1 1 1 1 1 +SELECT collation_tailoring('latin1_swedish_ci', 1) AS digits, +collation_tailoring('latin1_swedish_ci', 193) AS minus_dot_digits, +collation_tailoring('latin1_swedish_ci', 7) AS alnum, +collation_tailoring('latin1_swedish_ci', 15) AS ident; +digits minus_dot_digits alnum ident +[digit7] -<.<[digit7] [digit7]<[letter7_ci] [digit7]<[letter7_ci]<_ +# An unknown repertoire name returns NULL with a warning +SELECT collation_tailoring('latin1_swedish_ci', 'unknown') IS NULL AS r1; +r1 +1 +Warnings: +Warning 1210 Incorrect arguments to collation_tailoring +SELECT collation_tailoring('latin1_swedish_ci', '') IS NULL AS r2; +r2 +1 +Warnings: +Warning 1210 Incorrect arguments to collation_tailoring +# A repertoire number with unknown bits returns NULL with a warning +SELECT collation_tailoring('latin1_swedish_ci', 1000) IS NULL AS r1; +r1 +1 +Warnings: +Warning 1210 Incorrect arguments to collation_tailoring +SELECT collation_tailoring('latin1_swedish_ci', -1) IS NULL AS r2; +r2 +1 +Warnings: +Warning 1210 Incorrect arguments to collation_tailoring +# An unknown collation name returns NULL with a warning +SELECT collation_tailoring('unknown_collation', 'ascii') IS NULL AS r1; +r1 +1 +Warnings: +Warning 1273 Unknown collation: 'unknown_collation' +# A NULL argument returns NULL without a warning +SELECT collation_tailoring('latin1_swedish_ci', NULL) IS NULL AS r1, +collation_tailoring(NULL, 'ascii') IS NULL AS r2; +r1 r2 +1 1 +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/collation_tailoring_args.test b/plugin/func_test/mysql-test/func_test/collation_tailoring_args.test new file mode 100644 index 00000000000..6ca0bc2c4db --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/collation_tailoring_args.test @@ -0,0 +1,42 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # Arguments of collation_tailoring(): the repertoire can be passed +--echo # as a name or as a number +--echo # + +--echo # The numeric repertoire gives the same result as the named one +SELECT + collation_tailoring('latin1_swedish_ci', 0) = + collation_tailoring('latin1_swedish_ci', 'none') AS none_ok, + collation_tailoring('latin1_swedish_ci', 1) = + collation_tailoring('latin1_swedish_ci', 'ascii_digits') AS digits_ok, + collation_tailoring('latin1_swedish_ci', 193) = + collation_tailoring('latin1_swedish_ci', 'ascii_minus_dot_digits') + AS minus_dot_digits_ok, + collation_tailoring('latin1_swedish_ci', 7) = + collation_tailoring('latin1_swedish_ci', 'ascii_alnum') AS alnum_ok, + collation_tailoring('latin1_swedish_ci', 15) = + collation_tailoring('latin1_swedish_ci', 'ascii_ident') AS ident_ok, + collation_tailoring('latin1_swedish_ci', 223) = + collation_tailoring('latin1_swedish_ci', 'ascii') AS ascii_ok; +SELECT collation_tailoring('latin1_swedish_ci', 1) AS digits, + collation_tailoring('latin1_swedish_ci', 193) AS minus_dot_digits, + collation_tailoring('latin1_swedish_ci', 7) AS alnum, + collation_tailoring('latin1_swedish_ci', 15) AS ident; + +--echo # An unknown repertoire name returns NULL with a warning +SELECT collation_tailoring('latin1_swedish_ci', 'unknown') IS NULL AS r1; +SELECT collation_tailoring('latin1_swedish_ci', '') IS NULL AS r2; + +--echo # A repertoire number with unknown bits returns NULL with a warning +SELECT collation_tailoring('latin1_swedish_ci', 1000) IS NULL AS r1; +SELECT collation_tailoring('latin1_swedish_ci', -1) IS NULL AS r2; + +--echo # An unknown collation name returns NULL with a warning +SELECT collation_tailoring('unknown_collation', 'ascii') IS NULL AS r1; + +--echo # A NULL argument returns NULL without a warning +SELECT collation_tailoring('latin1_swedish_ci', NULL) IS NULL AS r1, + collation_tailoring(NULL, 'ascii') IS NULL AS r2; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_big5.result b/plugin/func_test/mysql-test/func_test/ctype_big5.result new file mode 100644 index 00000000000..dc1821d80b4 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_big5.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='big5'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name big5_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name big5_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name big5_chinese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name big5_chinese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_big5.test b/plugin/func_test/mysql-test/func_test/ctype_big5.test new file mode 100644 index 00000000000..a85b797aacb --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_big5.test @@ -0,0 +1,11 @@ +--source include/have_big5.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='big5'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.result b/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.result new file mode 100644 index 00000000000..12600db0145 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.result @@ -0,0 +1,90 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# Some collations (multibyte, Unicode general_ci, etc) are declared +# to be "caseup CI" on the ASCII (or on the IDENT) range +# by my_tailoring_{ascii,ident}_caseup_ci_generic(), without detecting +# this from the collation weights. This test verifies the declaration: +# the order of the declared range must be the code point order +# after folding a-z to A-Z. +# +SET NAMES utf8mb4; +CREATE TABLE ascii_chars (n INT PRIMARY KEY); +INSERT INTO ascii_chars +WITH RECURSIVE seq(n) AS (SELECT 0 UNION ALL SELECT n+1 FROM seq WHERE n<127) +SELECT n FROM seq; +CREATE TABLE tmp_collations (cs VARCHAR(64), cl VARCHAR(64), claim VARCHAR(8)); +INSERT INTO tmp_collations +SELECT character_set_name, full_collation_name, +CASE WHEN collation_tailoring(full_collation_name, 'ascii') +LIKE '%ascii7\_caseup\_ci' THEN 'ascii' + WHEN collation_tailoring(full_collation_name, 'ascii_ident') +LIKE '%[digit7]<[letter7\_ci]<\_' THEN 'ident' + END +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY; +DELETE FROM tmp_collations WHERE claim IS NULL; +CREATE TABLE tmp_violations (cl VARCHAR(64), violations INT); +CREATE TABLE tmp_pad_violations (cl VARCHAR(64), violations INT); +CREATE PROCEDURE check_caseup_ci() +BEGIN +DECLARE done INT DEFAULT 0; +DECLARE v_cs, v_cl VARCHAR(64); +DECLARE v_claim VARCHAR(8); +DECLARE c CURSOR FOR SELECT cs, cl, claim FROM tmp_collations; +DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; +OPEN c; +read_loop: LOOP +FETCH c INTO v_cs, v_cl, v_claim; +IF done THEN LEAVE read_loop; END IF; +-- The 'ident' claim covers only 0-9, A-Z, a-z, underscore +SET @cond= IF(v_claim='ascii', '1', +'(CHAR(a.n) REGEXP ''^[0-9A-Za-z_]$'' AND CHAR(b.n) REGEXP ''^[0-9A-Za-z_]$'')'); +SET @q= CONCAT( +'INSERT INTO tmp_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', +'ascii_chars a, ascii_chars b WHERE ', @cond, ' AND ', +'((CONVERT(CHAR(a.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ' < ', +'CONVERT(CHAR(b.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ') <> ', +'(IF(a.n BETWEEN 97 AND 122, a.n-32, a.n) < ', +'IF(b.n BETWEEN 97 AND 122, b.n-32, b.n)))'); +PREPARE stmt FROM @q; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +-- Compare "ab" to "ab" followed by a character. +-- NOPAD collations: the shorter string is always less. +-- PAD collations: the shorter string is padded with spaces, +-- so the result depends on the position of the space +-- relative to the added character. +SET @cond_pad= IF(v_claim='ascii', '1', +'(CHAR(a.n) REGEXP ''^[0-9A-Za-z_]$'')'); +SET @q= CONCAT( +'INSERT INTO tmp_pad_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', +'ascii_chars a WHERE ', @cond_pad, ' AND ', +'STRCMP(CONVERT(''ab'' USING ', v_cs, ') COLLATE ', v_cl, ', ', +'CONVERT(CONCAT(''ab'', CHAR(a.n USING ascii)) USING ', v_cs, ') ', +'COLLATE ', v_cl, ') <> ', +IF(v_cl LIKE '%nopad%', '-1', 'SIGN(32 - a.n)')); +PREPARE stmt FROM @q; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END LOOP; +CLOSE c; +END; +$$ +CALL check_caseup_ci(); +# At least some collations were checked +SELECT COUNT(*) > 20 AS checked FROM tmp_violations; +checked +1 +# No violations expected +SELECT * FROM tmp_violations WHERE violations>0; +cl violations +# Padding: the same collations were checked, no violations expected +SELECT COUNT(*) = (SELECT COUNT(*) FROM tmp_violations) AS same_checked +FROM tmp_pad_violations; +same_checked +1 +SELECT * FROM tmp_pad_violations WHERE violations>0; +cl violations +DROP PROCEDURE check_caseup_ci; +DROP TABLE tmp_violations, tmp_pad_violations, tmp_collations, ascii_chars; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.test b/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.test new file mode 100644 index 00000000000..f0b1220875b --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_caseup_ci_verify.test @@ -0,0 +1,95 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # +--echo # Some collations (multibyte, Unicode general_ci, etc) are declared +--echo # to be "caseup CI" on the ASCII (or on the IDENT) range +--echo # by my_tailoring_{ascii,ident}_caseup_ci_generic(), without detecting +--echo # this from the collation weights. This test verifies the declaration: +--echo # the order of the declared range must be the code point order +--echo # after folding a-z to A-Z. +--echo # + +SET NAMES utf8mb4; + +CREATE TABLE ascii_chars (n INT PRIMARY KEY); +INSERT INTO ascii_chars + WITH RECURSIVE seq(n) AS (SELECT 0 UNION ALL SELECT n+1 FROM seq WHERE n<127) + SELECT n FROM seq; + +CREATE TABLE tmp_collations (cs VARCHAR(64), cl VARCHAR(64), claim VARCHAR(8)); +INSERT INTO tmp_collations +SELECT character_set_name, full_collation_name, + CASE WHEN collation_tailoring(full_collation_name, 'ascii') + LIKE '%ascii7\_caseup\_ci' THEN 'ascii' + WHEN collation_tailoring(full_collation_name, 'ascii_ident') + LIKE '%[digit7]<[letter7\_ci]<\_' THEN 'ident' + END +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY; +DELETE FROM tmp_collations WHERE claim IS NULL; + +CREATE TABLE tmp_violations (cl VARCHAR(64), violations INT); +CREATE TABLE tmp_pad_violations (cl VARCHAR(64), violations INT); + +DELIMITER $$; +CREATE PROCEDURE check_caseup_ci() +BEGIN + DECLARE done INT DEFAULT 0; + DECLARE v_cs, v_cl VARCHAR(64); + DECLARE v_claim VARCHAR(8); + DECLARE c CURSOR FOR SELECT cs, cl, claim FROM tmp_collations; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; + OPEN c; + read_loop: LOOP + FETCH c INTO v_cs, v_cl, v_claim; + IF done THEN LEAVE read_loop; END IF; + -- The 'ident' claim covers only 0-9, A-Z, a-z, underscore + SET @cond= IF(v_claim='ascii', '1', + '(CHAR(a.n) REGEXP ''^[0-9A-Za-z_]$'' AND CHAR(b.n) REGEXP ''^[0-9A-Za-z_]$'')'); + SET @q= CONCAT( + 'INSERT INTO tmp_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', + 'ascii_chars a, ascii_chars b WHERE ', @cond, ' AND ', + '((CONVERT(CHAR(a.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ' < ', + 'CONVERT(CHAR(b.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ') <> ', + '(IF(a.n BETWEEN 97 AND 122, a.n-32, a.n) < ', + 'IF(b.n BETWEEN 97 AND 122, b.n-32, b.n)))'); + PREPARE stmt FROM @q; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + -- Compare "ab" to "ab" followed by a character. + -- NOPAD collations: the shorter string is always less. + -- PAD collations: the shorter string is padded with spaces, + -- so the result depends on the position of the space + -- relative to the added character. + SET @cond_pad= IF(v_claim='ascii', '1', + '(CHAR(a.n) REGEXP ''^[0-9A-Za-z_]$'')'); + SET @q= CONCAT( + 'INSERT INTO tmp_pad_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', + 'ascii_chars a WHERE ', @cond_pad, ' AND ', + 'STRCMP(CONVERT(''ab'' USING ', v_cs, ') COLLATE ', v_cl, ', ', + 'CONVERT(CONCAT(''ab'', CHAR(a.n USING ascii)) USING ', v_cs, ') ', + 'COLLATE ', v_cl, ') <> ', + IF(v_cl LIKE '%nopad%', '-1', 'SIGN(32 - a.n)')); + PREPARE stmt FROM @q; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END LOOP; + CLOSE c; +END; +$$ +DELIMITER ;$$ + +CALL check_caseup_ci(); + +--echo # At least some collations were checked +SELECT COUNT(*) > 20 AS checked FROM tmp_violations; +--echo # No violations expected +SELECT * FROM tmp_violations WHERE violations>0; +--echo # Padding: the same collations were checked, no violations expected +SELECT COUNT(*) = (SELECT COUNT(*) FROM tmp_violations) AS same_checked +FROM tmp_pad_violations; +SELECT * FROM tmp_pad_violations WHERE violations>0; + +DROP PROCEDURE check_caseup_ci; +DROP TABLE tmp_violations, tmp_pad_violations, tmp_collations, ascii_chars; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_collation_tailoring_00.inc b/plugin/func_test/mysql-test/func_test/ctype_collation_tailoring_00.inc new file mode 100644 index 00000000000..a01f77a83ab --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_collation_tailoring_00.inc @@ -0,0 +1,14 @@ +--vertical_results +SELECT + full_collation_name AS name, + collation_tailoring(full_collation_name, 'none') AS none, + collation_tailoring(full_collation_name, 'ascii_digits') AS digits, + collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, + collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, + collation_tailoring(full_collation_name, 'ascii_ident') AS ident, + collation_tailoring(full_collation_name, 'ascii') AS ascii, + '---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +--horizontal_results diff --git a/plugin/func_test/mysql-test/func_test/ctype_cp932.result b/plugin/func_test/mysql-test/func_test/ctype_cp932.result new file mode 100644 index 00000000000..72e80eea1c8 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_cp932.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='cp932'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name cp932_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp932_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp932_japanese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp932_japanese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_cp932.test b/plugin/func_test/mysql-test/func_test/ctype_cp932.test new file mode 100644 index 00000000000..c43ca685405 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_cp932.test @@ -0,0 +1,11 @@ +--source include/have_cp932.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='cp932'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_digits_verify.result b/plugin/func_test/mysql-test/func_test/ctype_digits_verify.result new file mode 100644 index 00000000000..be19ca050ea --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_digits_verify.result @@ -0,0 +1,91 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# Some collations are declared to sort the ASCII digits (and, optionally, +# the minus and the dot) in the code point order: +# the tailorings on the repertoires ASCII_DIGITS +# and ASCII_MINUS_DOT_DIGITS. This test verifies the declarations: +# all pairs of the declared characters must be compared in the code +# point order (for PAD collations, also the space is checked), +# and a shorter string must be less than a longer string with +# the same prefix. +# +SET NAMES utf8mb4; +CREATE TABLE ascii_chars (n INT PRIMARY KEY); +INSERT INTO ascii_chars VALUES (32),(45),(46),(48),(49),(50),(51),(52),(53), +(54),(55),(56),(57); +CREATE TABLE tmp_collations (cs VARCHAR(64), cl VARCHAR(64), claim VARCHAR(8), +nopad INT); +INSERT INTO tmp_collations +SELECT character_set_name, full_collation_name, +CASE WHEN collation_tailoring(full_collation_name, +'ascii_minus_dot_digits') IS NOT NULL +THEN 'mdd' + WHEN collation_tailoring(full_collation_name, +'ascii_digits') IS NOT NULL +THEN 'digits' + END, +collation_tailoring(full_collation_name, 'none') LIKE '[nopad]%' +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY; +DELETE FROM tmp_collations WHERE claim IS NULL; +CREATE TABLE tmp_violations (cl VARCHAR(64), violations INT); +CREATE PROCEDURE check_digits() +BEGIN +DECLARE done INT DEFAULT 0; +DECLARE v_cs, v_cl VARCHAR(64); +DECLARE v_claim VARCHAR(8); +DECLARE v_nopad INT; +DECLARE c CURSOR FOR SELECT cs, cl, claim, nopad FROM tmp_collations; +DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; +OPEN c; +read_loop: LOOP +FETCH c INTO v_cs, v_cl, v_claim, v_nopad; +IF done THEN LEAVE read_loop; END IF; +-- The characters covered by the claim, and the space for PAD collations +SET @cond= CONCAT( +'(a.n BETWEEN 48 AND 57 OR ', +IF(v_claim='mdd', 'a.n IN (45,46) OR ', ''), +IF(v_nopad, '0', 'a.n=32'), ') AND ', +'(b.n BETWEEN 48 AND 57 OR ', +IF(v_claim='mdd', 'b.n IN (45,46) OR ', ''), +IF(v_nopad, '0', 'b.n=32'), ')'); +SET @q= CONCAT( +'INSERT INTO tmp_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', +'ascii_chars a, ascii_chars b WHERE ', @cond, ' AND ', +'((CONVERT(CHAR(a.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ' < ', +'CONVERT(CHAR(b.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ') <> ', +'(a.n < b.n))'); +PREPARE stmt FROM @q; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +-- A shorter string is less than a longer string with the same prefix +SET @q= CONCAT( +'INSERT INTO tmp_violations SELECT ''', v_cl, ''', ', +'(CONVERT(''1'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', +'CONVERT(''10'' USING ', v_cs, ') COLLATE ', v_cl, ') + ', +IF(v_claim='mdd', +CONCAT('(CONVERT(''-1'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', +'CONVERT(''-1.5'' USING ', v_cs, ') COLLATE ', v_cl, ') + ', +'(CONVERT(''1.5'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', +'CONVERT(''1.50'' USING ', v_cs, ') COLLATE ', v_cl, ')'), +'0')); +PREPARE stmt FROM @q; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +END LOOP; +CLOSE c; +END; +$$ +CALL check_digits(); +# Number of the collations with the declarations (checked) +SELECT claim, COUNT(*) AS checked FROM tmp_collations GROUP BY claim; +claim checked +digits 4 +mdd 1283 +# Violations (must be empty) +SELECT cl, SUM(violations) AS violations FROM tmp_violations +GROUP BY cl HAVING violations > 0 ORDER BY cl; +cl violations +DROP PROCEDURE check_digits; +DROP TABLE tmp_violations, tmp_collations, ascii_chars; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_digits_verify.test b/plugin/func_test/mysql-test/func_test/ctype_digits_verify.test new file mode 100644 index 00000000000..b8c147b6e17 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_digits_verify.test @@ -0,0 +1,99 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # +--echo # Some collations are declared to sort the ASCII digits (and, optionally, +--echo # the minus and the dot) in the code point order: +--echo # the tailorings on the repertoires ASCII_DIGITS +--echo # and ASCII_MINUS_DOT_DIGITS. This test verifies the declarations: +--echo # all pairs of the declared characters must be compared in the code +--echo # point order (for PAD collations, also the space is checked), +--echo # and a shorter string must be less than a longer string with +--echo # the same prefix. +--echo # + +SET NAMES utf8mb4; + +CREATE TABLE ascii_chars (n INT PRIMARY KEY); +INSERT INTO ascii_chars VALUES (32),(45),(46),(48),(49),(50),(51),(52),(53), + (54),(55),(56),(57); + +CREATE TABLE tmp_collations (cs VARCHAR(64), cl VARCHAR(64), claim VARCHAR(8), + nopad INT); +INSERT INTO tmp_collations +SELECT character_set_name, full_collation_name, + CASE WHEN collation_tailoring(full_collation_name, + 'ascii_minus_dot_digits') IS NOT NULL + THEN 'mdd' + WHEN collation_tailoring(full_collation_name, + 'ascii_digits') IS NOT NULL + THEN 'digits' + END, + collation_tailoring(full_collation_name, 'none') LIKE '[nopad]%' +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY; +DELETE FROM tmp_collations WHERE claim IS NULL; + +CREATE TABLE tmp_violations (cl VARCHAR(64), violations INT); + +DELIMITER $$; +CREATE PROCEDURE check_digits() +BEGIN + DECLARE done INT DEFAULT 0; + DECLARE v_cs, v_cl VARCHAR(64); + DECLARE v_claim VARCHAR(8); + DECLARE v_nopad INT; + DECLARE c CURSOR FOR SELECT cs, cl, claim, nopad FROM tmp_collations; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; + OPEN c; + read_loop: LOOP + FETCH c INTO v_cs, v_cl, v_claim, v_nopad; + IF done THEN LEAVE read_loop; END IF; + -- The characters covered by the claim, and the space for PAD collations + SET @cond= CONCAT( + '(a.n BETWEEN 48 AND 57 OR ', + IF(v_claim='mdd', 'a.n IN (45,46) OR ', ''), + IF(v_nopad, '0', 'a.n=32'), ') AND ', + '(b.n BETWEEN 48 AND 57 OR ', + IF(v_claim='mdd', 'b.n IN (45,46) OR ', ''), + IF(v_nopad, '0', 'b.n=32'), ')'); + SET @q= CONCAT( + 'INSERT INTO tmp_violations SELECT ''', v_cl, ''', COUNT(*) FROM ', + 'ascii_chars a, ascii_chars b WHERE ', @cond, ' AND ', + '((CONVERT(CHAR(a.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ' < ', + 'CONVERT(CHAR(b.n USING ascii) USING ', v_cs, ') COLLATE ', v_cl, ') <> ', + '(a.n < b.n))'); + PREPARE stmt FROM @q; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + -- A shorter string is less than a longer string with the same prefix + SET @q= CONCAT( + 'INSERT INTO tmp_violations SELECT ''', v_cl, ''', ', + '(CONVERT(''1'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', + 'CONVERT(''10'' USING ', v_cs, ') COLLATE ', v_cl, ') + ', + IF(v_claim='mdd', + CONCAT('(CONVERT(''-1'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', + 'CONVERT(''-1.5'' USING ', v_cs, ') COLLATE ', v_cl, ') + ', + '(CONVERT(''1.5'' USING ', v_cs, ') COLLATE ', v_cl, ' >= ', + 'CONVERT(''1.50'' USING ', v_cs, ') COLLATE ', v_cl, ')'), + '0')); + PREPARE stmt FROM @q; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END LOOP; + CLOSE c; +END; +$$ +DELIMITER ;$$ + +CALL check_digits(); + +--echo # Number of the collations with the declarations (checked) +SELECT claim, COUNT(*) AS checked FROM tmp_collations GROUP BY claim; + +--echo # Violations (must be empty) +SELECT cl, SUM(violations) AS violations FROM tmp_violations +GROUP BY cl HAVING violations > 0 ORDER BY cl; + +DROP PROCEDURE check_digits; +DROP TABLE tmp_violations, tmp_collations, ascii_chars; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_eucjpms.result b/plugin/func_test/mysql-test/func_test/ctype_eucjpms.result new file mode 100644 index 00000000000..fa3cb58074c --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_eucjpms.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='eucjpms'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name eucjpms_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name eucjpms_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name eucjpms_japanese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name eucjpms_japanese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_eucjpms.test b/plugin/func_test/mysql-test/func_test/ctype_eucjpms.test new file mode 100644 index 00000000000..cebd9ae1918 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_eucjpms.test @@ -0,0 +1,11 @@ +--source include/have_eucjpms.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='eucjpms'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_euckr.result b/plugin/func_test/mysql-test/func_test/ctype_euckr.result new file mode 100644 index 00000000000..100409d3d34 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_euckr.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='euckr'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name euckr_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name euckr_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name euckr_korean_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name euckr_korean_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_euckr.test b/plugin/func_test/mysql-test/func_test/ctype_euckr.test new file mode 100644 index 00000000000..08b0b959ddd --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_euckr.test @@ -0,0 +1,11 @@ +--source include/have_euckr.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='euckr'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_gb2312.result b/plugin/func_test/mysql-test/func_test/ctype_gb2312.result new file mode 100644 index 00000000000..0a93c3815f3 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_gb2312.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='gb2312'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name gb2312_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name gb2312_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name gb2312_chinese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name gb2312_chinese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_gb2312.test b/plugin/func_test/mysql-test/func_test/ctype_gb2312.test new file mode 100644 index 00000000000..3b5bfc3e348 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_gb2312.test @@ -0,0 +1,11 @@ +--source include/have_gb2312.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='gb2312'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_gbk.result b/plugin/func_test/mysql-test/func_test/ctype_gbk.result new file mode 100644 index 00000000000..81474e6074b --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_gbk.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='gbk'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name gbk_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name gbk_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name gbk_chinese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name gbk_chinese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_gbk.test b/plugin/func_test/mysql-test/func_test/ctype_gbk.test new file mode 100644 index 00000000000..7240becb3c9 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_gbk.test @@ -0,0 +1,11 @@ +--source include/have_gbk.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='gbk'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ldml-master.opt b/plugin/func_test/mysql-test/func_test/ctype_ldml-master.opt new file mode 100644 index 00000000000..ae57f7ec7a8 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ldml-master.opt @@ -0,0 +1,2 @@ +--character-sets-dir=$MYSQL_TEST_DIR/std_data/ldml/ +--log-error=$MYSQLTEST_VARDIR/tmp/func_test_ctype_ldml_log.err diff --git a/plugin/func_test/mysql-test/func_test/ctype_ldml.result b/plugin/func_test/mysql-test/func_test/ctype_ldml.result new file mode 100644 index 00000000000..fc9e1672440 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ldml.result @@ -0,0 +1,187 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +# +# Collations loaded at runtime from Index.xml. +# - 8bit collations get their tailoring flags detected from the +# collation weights (my_8bit_collation_flags_from_data()) +# - Unicode collations get theirs from the LDML rules (whether they +# reorder the ASCII range). +# +SELECT full_collation_name AS name, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE full_collation_name IN +('ascii2_general_ci', 'ascii2_bin', 'ascii2_general_nopad_ci', +'ascii2_nopad_bin', 'ascii2_general_inherited_ci', +'latin1_test', 'latin1_test2', 'latin1_test2_cs', +'latin1_swedish_nopad2_ci', 'latin1_space_after_letters_ci', +'utf8mb3_test_ci', 'utf8mb3_phone_ci', 'utf8mb3_5624_1', +'utf8mb3_implicit_weights_ci', +'utf8mb4_test_ci', 'utf8mb4_test_520_nopad_ci', +'utf8mb4_uca1400_test01_as_ci', +'ucs2_test_ci', 'ucs2_vn_ci', 'utf16_test_ci', 'utf32_test_ci') +ORDER BY full_collation_name; +name ascii2_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name ascii2_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ascii2_general_inherited_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ascii2_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name ascii2_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name latin1_space_after_letters_ci +digits NULL +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin1_swedish_nopad2_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name latin1_test +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin1_test2 +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin1_test2_cs +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_test_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_vn_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_test_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_test_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_5624_1 +digits NULL +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_implicit_weights_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_phone_ci +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_test_ci +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_test_520_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb4_test_ci +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_test01_as_ci +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +# +# latin1_space_after_letters_ci is a PAD collation where the space +# sorts after the letters, so "ab" is greater than "abc". It must not +# have a tailoring on ALNUM and IDENT, otherwise it would be considered +# compatible with collations where the space sorts before the letters. +# +SELECT 'ab' COLLATE latin1_swedish_ci < 'abc' AS swedish, +'ab' COLLATE latin1_space_after_letters_ci < 'abc' AS space_after; +swedish space_after +1 0 +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ldml.test b/plugin/func_test/mysql-test/func_test/ctype_ldml.test new file mode 100644 index 00000000000..27a7ca082f6 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ldml.test @@ -0,0 +1,53 @@ +--source include/have_ucs2.inc +--source include/have_utf8mb4.inc +--source include/have_utf16.inc +--source include/have_utf32.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +--echo # +--echo # Collations loaded at runtime from Index.xml. +--echo # - 8bit collations get their tailoring flags detected from the +--echo # collation weights (my_8bit_collation_flags_from_data()) +--echo # - Unicode collations get theirs from the LDML rules (whether they +--echo # reorder the ASCII range). +--echo # + +--disable_query_log +call mtr.add_suppression("Charset id.*trying to replace"); +--enable_query_log + +--vertical_results +SELECT full_collation_name AS name, + collation_tailoring(full_collation_name, 'ascii_digits') AS digits, + collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, + collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, + collation_tailoring(full_collation_name, 'ascii_ident') AS ident, + collation_tailoring(full_collation_name, 'ascii') AS ascii, + '---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE full_collation_name IN + ('ascii2_general_ci', 'ascii2_bin', 'ascii2_general_nopad_ci', + 'ascii2_nopad_bin', 'ascii2_general_inherited_ci', + 'latin1_test', 'latin1_test2', 'latin1_test2_cs', + 'latin1_swedish_nopad2_ci', 'latin1_space_after_letters_ci', + 'utf8mb3_test_ci', 'utf8mb3_phone_ci', 'utf8mb3_5624_1', + 'utf8mb3_implicit_weights_ci', + 'utf8mb4_test_ci', 'utf8mb4_test_520_nopad_ci', + 'utf8mb4_uca1400_test01_as_ci', + 'ucs2_test_ci', 'ucs2_vn_ci', 'utf16_test_ci', 'utf32_test_ci') +ORDER BY full_collation_name; +--horizontal_results + +--echo # +--echo # latin1_space_after_letters_ci is a PAD collation where the space +--echo # sorts after the letters, so "ab" is greater than "abc". It must not +--echo # have a tailoring on ALNUM and IDENT, otherwise it would be considered +--echo # compatible with collations where the space sorts before the letters. +--echo # +SELECT 'ab' COLLATE latin1_swedish_ci < 'abc' AS swedish, + 'ab' COLLATE latin1_space_after_letters_ci < 'abc' AS space_after; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.result b/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.result new file mode 100644 index 00000000000..b6a992e9ff2 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.result @@ -0,0 +1,810 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SELECT full_collation_name AS name, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.CHARACTER_SETS AS cs, +INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY AS cl +WHERE +cs.character_set_name=cl.character_set_name +AND cs.maxlen=1 +AND cs.character_set_name<>'tis620' + AND cl.collation_name NOT IN +('latin2_czech_cs','cp1250_czech_cs') +ORDER BY cs.character_set_name, cl.collation_name LIKE '%_ci', collation_name; +name armscii8_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name armscii8_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name armscii8_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name armscii8_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name ascii_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name ascii_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name ascii_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ascii_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name binary +digits NULL +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name cp1250_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp1250_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp1250_croatian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1250_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1250_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp1250_polish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1251_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp1251_general_cs +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name cp1251_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp1251_bulgarian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1251_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1251_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp1251_ukrainian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name cp1256_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp1256_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp1256_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1256_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp1257_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp1257_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp1257_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp1257_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp1257_lithuanian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name cp850_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp850_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp850_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp850_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp852_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp852_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp852_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name cp852_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name cp866_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name cp866_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name cp866_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name cp866_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name dec8_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name dec8_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name dec8_swedish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name dec8_swedish_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name geostd8_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name geostd8_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name geostd8_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name geostd8_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name greek_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name greek_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name greek_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name greek_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name hebrew_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name hebrew_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name hebrew_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name hebrew_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name hp8_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name hp8_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name hp8_english_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name hp8_english_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name keybcs2_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name keybcs2_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name keybcs2_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name keybcs2_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name koi8r_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name koi8r_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name koi8r_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name koi8r_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name koi8u_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name koi8u_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name koi8u_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name koi8u_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name latin1_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name latin1_general_cs +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name latin1_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name latin1_danish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_german1_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_german2_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_spanish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_swedish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin1_swedish_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name latin2_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name latin2_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name latin2_croatian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin2_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name latin2_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name latin2_hungarian_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name latin5_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name latin5_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name latin5_turkish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name latin5_turkish_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name latin7_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name latin7_estonian_cs +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin7_general_cs +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin7_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name latin7_general_ci +digits [digit7] +minus_dot_digits NULL +alnum NULL +ident NULL +ascii NULL +--- --- +name latin7_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name macce_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name macce_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name macce_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name macce_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name macroman_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name macroman_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name macroman_general_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name macroman_general_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name swe7_bin +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name swe7_nopad_bin +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name swe7_swedish_ci +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name swe7_swedish_nopad_ci +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- diff --git a/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.test b/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.test new file mode 100644 index 00000000000..8531de4bb33 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_simple_8bit.test @@ -0,0 +1,32 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +# +# Query only simple character sets and collations which are always +# available no matter what compilation flags are. +# Exclude compilation dependent components: +# - character set tis620 +# - collation latin2_czech_cs +# - collation cp1250_czech_cs +# + +--vertical_results +SELECT full_collation_name AS name, + collation_tailoring(full_collation_name, 'ascii_digits') AS digits, + collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, + collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, + collation_tailoring(full_collation_name, 'ascii_ident') AS ident, + collation_tailoring(full_collation_name, 'ascii') AS ascii, + '---' AS `---` +FROM INFORMATION_SCHEMA.CHARACTER_SETS AS cs, + INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY AS cl +WHERE + cs.character_set_name=cl.character_set_name + AND cs.maxlen=1 + AND cs.character_set_name<>'tis620' + AND cl.collation_name NOT IN + ('latin2_czech_cs','cp1250_czech_cs') +ORDER BY cs.character_set_name, cl.collation_name LIKE '%_ci', collation_name; + +--horizontal_results diff --git a/plugin/func_test/mysql-test/func_test/ctype_sjis.result b/plugin/func_test/mysql-test/func_test/ctype_sjis.result new file mode 100644 index 00000000000..99bd46c62bb --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_sjis.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='sjis'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name sjis_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii NULL +--- --- +name sjis_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii NULL +--- --- +name sjis_japanese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii NULL +--- --- +name sjis_japanese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii NULL +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_sjis.test b/plugin/func_test/mysql-test/func_test/ctype_sjis.test new file mode 100644 index 00000000000..4f145b26f47 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_sjis.test @@ -0,0 +1,11 @@ +--source include/have_sjis.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='sjis'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_tis620.result b/plugin/func_test/mysql-test/func_test/ctype_tis620.result new file mode 100644 index 00000000000..c7ae635562b --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_tis620.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='tis620'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name tis620_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name tis620_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name tis620_thai_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<_<[letter7_ci] +ascii ascii7_casedn_ci +--- --- +name tis620_thai_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<_<[letter7_ci] +ascii [nopad]ascii7_casedn_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_tis620.test b/plugin/func_test/mysql-test/func_test/ctype_tis620.test new file mode 100644 index 00000000000..b62a21c5e2b --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_tis620.test @@ -0,0 +1,11 @@ +--source include/have_tis620.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='tis620'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ucs2.result b/plugin/func_test/mysql-test/func_test/ctype_ucs2.result new file mode 100644 index 00000000000..45362f4710d --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ucs2.result @@ -0,0 +1,1762 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='ucs2'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name ucs2_uca1400_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_croatian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_esperanto_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_esperanto_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_esperanto_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_esperanto_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_estonian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_german2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_german2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_german2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_german2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_hungarian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_hungarian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_hungarian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_hungarian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_icelandic_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_icelandic_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_icelandic_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_icelandic_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_latvian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_persian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_persian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_persian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_persian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_polish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_polish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_polish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_polish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_romanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_romanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_romanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_romanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_roman_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_sinhala_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_sinhala_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_sinhala_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_sinhala_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_slovak_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovenian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_slovenian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_slovenian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_slovenian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_spanish2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_spanish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_spanish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_spanish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_swedish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_swedish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_swedish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_swedish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_turkish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_vietnamese_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_vietnamese_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_vietnamese_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_uca1400_vietnamese_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name ucs2_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name ucs2_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name ucs2_thai_520_w2 +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_croatian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_croatian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_czech_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_danish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_esperanto_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_esperanto_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_esperanto_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_esperanto_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_estonian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_estonian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_german2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_german2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_german2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_german2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_hungarian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_hungarian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_hungarian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_hungarian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_icelandic_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_icelandic_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_icelandic_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_icelandic_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_latvian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_latvian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_lithuanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_persian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_persian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_persian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_persian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_polish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_polish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_polish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_polish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_romanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_romanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_romanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_romanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_roman_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_roman_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_sinhala_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_sinhala_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_sinhala_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_sinhala_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_slovak_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovak_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_slovenian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_slovenian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_slovenian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_slovenian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_spanish2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_spanish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_spanish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_spanish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_spanish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_swedish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_swedish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_swedish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_swedish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_turkish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_turkish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_uca1400_vietnamese_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_vietnamese_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_vietnamese_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_uca1400_vietnamese_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name ucs2_croatian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_croatian_mysql561_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_czech_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_danish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_esperanto_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_estonian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ucs2_general_mysql500_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ucs2_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name ucs2_german2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_hungarian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_icelandic_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_latvian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_lithuanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_myanmar_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name ucs2_persian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_polish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_romanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_roman_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_sinhala_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_slovak_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_slovenian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_spanish2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_spanish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_swedish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_turkish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name ucs2_unicode_520_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name ucs2_unicode_520_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name ucs2_unicode_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_unicode_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 4.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 4.0.0]ascii7_uca_ci +--- --- +name ucs2_vietnamese_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ucs2.test b/plugin/func_test/mysql-test/func_test/ctype_ucs2.test new file mode 100644 index 00000000000..40b346bb6a9 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ucs2.test @@ -0,0 +1,11 @@ +--source include/have_ucs2.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='ucs2'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ujis.result b/plugin/func_test/mysql-test/func_test/ctype_ujis.result new file mode 100644 index 00000000000..7a01c14cfa9 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ujis.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='ujis'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name ujis_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name ujis_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name ujis_japanese_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name ujis_japanese_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_ujis.test b/plugin/func_test/mysql-test/func_test/ctype_ujis.test new file mode 100644 index 00000000000..07cbf21b3a9 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_ujis.test @@ -0,0 +1,11 @@ +--source include/have_ujis.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='ujis'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf16.result b/plugin/func_test/mysql-test/func_test/ctype_utf16.result new file mode 100644 index 00000000000..36f6ad01a95 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf16.result @@ -0,0 +1,1754 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='utf16'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name utf16_uca1400_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_croatian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_esperanto_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_esperanto_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_esperanto_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_esperanto_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_estonian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_german2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_german2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_german2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_german2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_hungarian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_hungarian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_hungarian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_hungarian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_icelandic_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_icelandic_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_icelandic_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_icelandic_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_latvian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_persian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_persian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_persian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_persian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_polish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_polish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_polish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_polish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_romanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_romanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_romanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_romanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_roman_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_sinhala_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_sinhala_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_sinhala_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_sinhala_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_slovak_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovenian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_slovenian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_slovenian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_slovenian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_spanish2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_spanish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_spanish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_spanish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_swedish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_swedish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_swedish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_swedish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_turkish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_vietnamese_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_vietnamese_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_vietnamese_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_uca1400_vietnamese_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf16_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name utf16_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf16_thai_520_w2 +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf16_uca1400_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_croatian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_croatian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_czech_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_danish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_esperanto_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_esperanto_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_esperanto_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_esperanto_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_estonian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_estonian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_german2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_german2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_german2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_german2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_hungarian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_hungarian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_hungarian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_hungarian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_icelandic_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_icelandic_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_icelandic_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_icelandic_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_latvian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_latvian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_lithuanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_persian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_persian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_persian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_persian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_polish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_polish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_polish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_polish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_romanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_romanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_romanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_romanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_roman_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_roman_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_sinhala_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_sinhala_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_sinhala_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_sinhala_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_slovak_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovak_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_slovenian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_slovenian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_slovenian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_slovenian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_spanish2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_spanish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_spanish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_spanish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_spanish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_swedish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_swedish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_swedish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_swedish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_turkish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_turkish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_uca1400_vietnamese_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_vietnamese_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_vietnamese_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_uca1400_vietnamese_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf16_croatian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_croatian_mysql561_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_czech_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_danish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_esperanto_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_estonian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf16_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name utf16_german2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_hungarian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_icelandic_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_latvian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_lithuanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_myanmar_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf16_persian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_polish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_romanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_roman_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_sinhala_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_slovak_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_slovenian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_spanish2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_spanish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_swedish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_turkish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf16_unicode_520_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf16_unicode_520_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name utf16_unicode_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf16_unicode_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 4.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 4.0.0]ascii7_uca_ci +--- --- +name utf16_vietnamese_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf16.test b/plugin/func_test/mysql-test/func_test/ctype_utf16.test new file mode 100644 index 00000000000..3ea0a0a8631 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf16.test @@ -0,0 +1,11 @@ +--source include/have_utf16.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='utf16'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf16le.result b/plugin/func_test/mysql-test/func_test/ctype_utf16le.result new file mode 100644 index 00000000000..1e6cacaa3ec --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf16le.result @@ -0,0 +1,50 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='utf16le'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name utf16le_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name utf16le_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf16le_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf16le_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf16le.test b/plugin/func_test/mysql-test/func_test/ctype_utf16le.test new file mode 100644 index 00000000000..85b71e9d521 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf16le.test @@ -0,0 +1,11 @@ +--source include/have_utf16.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='utf16le'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf32.result b/plugin/func_test/mysql-test/func_test/ctype_utf32.result new file mode 100644 index 00000000000..bacfa21fcb4 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf32.result @@ -0,0 +1,1754 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='utf32'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name utf32_uca1400_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_croatian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_esperanto_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_esperanto_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_esperanto_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_esperanto_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_estonian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_german2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_german2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_german2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_german2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_hungarian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_hungarian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_hungarian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_hungarian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_icelandic_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_icelandic_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_icelandic_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_icelandic_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_latvian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_persian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_persian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_persian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_persian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_polish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_polish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_polish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_polish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_romanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_romanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_romanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_romanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_roman_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_sinhala_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_sinhala_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_sinhala_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_sinhala_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_slovak_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovenian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_slovenian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_slovenian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_slovenian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_spanish2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_spanish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_spanish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_spanish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_swedish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_swedish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_swedish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_swedish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_turkish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_vietnamese_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_vietnamese_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_vietnamese_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_uca1400_vietnamese_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf32_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name utf32_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf32_thai_520_w2 +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf32_uca1400_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_croatian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_croatian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_czech_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_danish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_esperanto_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_esperanto_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_esperanto_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_esperanto_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_estonian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_estonian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_german2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_german2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_german2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_german2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_hungarian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_hungarian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_hungarian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_hungarian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_icelandic_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_icelandic_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_icelandic_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_icelandic_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_latvian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_latvian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_lithuanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_persian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_persian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_persian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_persian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_polish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_polish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_polish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_polish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_romanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_romanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_romanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_romanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_roman_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_roman_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_sinhala_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_sinhala_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_sinhala_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_sinhala_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_slovak_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovak_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_slovenian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_slovenian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_slovenian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_slovenian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_spanish2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_spanish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_spanish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_spanish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_spanish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_swedish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_swedish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_swedish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_swedish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_turkish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_turkish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_uca1400_vietnamese_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_vietnamese_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_vietnamese_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_uca1400_vietnamese_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf32_croatian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_croatian_mysql561_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_czech_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_danish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_esperanto_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_estonian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf32_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name utf32_german2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_hungarian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_icelandic_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_latvian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_lithuanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_myanmar_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf32_persian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_polish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_romanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_roman_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_sinhala_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_slovak_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_slovenian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_spanish2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_spanish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_swedish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_turkish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf32_unicode_520_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf32_unicode_520_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name utf32_unicode_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf32_unicode_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 4.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 4.0.0]ascii7_uca_ci +--- --- +name utf32_vietnamese_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf32.test b/plugin/func_test/mysql-test/func_test/ctype_utf32.test new file mode 100644 index 00000000000..62280f1a010 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf32.test @@ -0,0 +1,11 @@ +--source include/have_utf32.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='utf32'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.result b/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.result new file mode 100644 index 00000000000..2aeec80e0dc --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.result @@ -0,0 +1,1770 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='utf8mb3'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name utf8mb3_uca1400_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_croatian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_esperanto_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_esperanto_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_esperanto_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_esperanto_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_estonian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_german2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_german2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_german2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_german2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_hungarian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_hungarian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_hungarian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_hungarian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_icelandic_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_icelandic_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_icelandic_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_icelandic_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_latvian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_persian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_persian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_persian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_persian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_polish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_polish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_polish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_polish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_romanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_romanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_romanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_romanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_roman_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_sinhala_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_sinhala_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_sinhala_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_sinhala_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_slovak_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovenian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_slovenian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_slovenian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_slovenian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_spanish2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_spanish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_spanish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_spanish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_swedish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_swedish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_swedish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_swedish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_turkish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_vietnamese_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_vietnamese_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_vietnamese_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_uca1400_vietnamese_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb3_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name utf8mb3_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf8mb3_thai_520_w2 +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_croatian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_croatian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_czech_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_danish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_esperanto_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_esperanto_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_esperanto_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_esperanto_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_estonian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_estonian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_german2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_german2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_german2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_german2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_hungarian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_hungarian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_hungarian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_hungarian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_icelandic_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_icelandic_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_icelandic_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_icelandic_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_latvian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_latvian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_lithuanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_persian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_persian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_persian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_persian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_polish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_polish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_polish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_polish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_romanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_romanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_romanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_romanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_roman_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_roman_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_sinhala_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_sinhala_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_sinhala_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_sinhala_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_slovak_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovak_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_slovenian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_slovenian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_slovenian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_slovenian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_spanish2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_spanish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_spanish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_spanish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_spanish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_swedish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_swedish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_swedish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_swedish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_turkish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_turkish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_uca1400_vietnamese_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_vietnamese_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_vietnamese_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_uca1400_vietnamese_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb3_croatian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_croatian_mysql561_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_czech_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_danish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_esperanto_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_estonian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_general1400_as_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf8mb3_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf8mb3_general_mysql500_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf8mb3_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name utf8mb3_german2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_hungarian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_icelandic_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_latvian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_lithuanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_myanmar_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb3_persian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_polish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_romanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_roman_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_sinhala_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_slovak_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_slovenian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_spanish2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_spanish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_swedish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_turkish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb3_unicode_520_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb3_unicode_520_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb3_unicode_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_unicode_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 4.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb3_vietnamese_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.test b/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.test new file mode 100644 index 00000000000..f59bbf2872b --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf8mb3.test @@ -0,0 +1,9 @@ +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='utf8mb3'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.result b/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.result new file mode 100644 index 00000000000..9e5086b8e41 --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.result @@ -0,0 +1,2114 @@ +# +# MDEV-41246 "Illegal mix of collations" on the mysql.user view +# +SET @character_set_name='utf8mb4'; +SELECT +full_collation_name AS name, +collation_tailoring(full_collation_name, 'none') AS none, +collation_tailoring(full_collation_name, 'ascii_digits') AS digits, +collation_tailoring(full_collation_name, 'ascii_minus_dot_digits') AS minus_dot_digits, +collation_tailoring(full_collation_name, 'ascii_alnum') AS alnum, +collation_tailoring(full_collation_name, 'ascii_ident') AS ident, +collation_tailoring(full_collation_name, 'ascii') AS ascii, +'---' AS `---` +FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY +WHERE character_set_name=@character_set_name +ORDER BY collation_name LIKE '%_ci', collation_name; +name utf8mb4_uca1400_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_croatian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_esperanto_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_esperanto_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_esperanto_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_esperanto_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_estonian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_german2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_german2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_german2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_german2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_hungarian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_hungarian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_hungarian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_hungarian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_icelandic_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_icelandic_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_icelandic_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_icelandic_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_latvian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_persian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_persian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_persian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_persian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_polish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_polish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_polish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_polish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_romanian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_romanian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_romanian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_romanian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_roman_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_sinhala_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_sinhala_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_sinhala_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_sinhala_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_slovak_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovenian_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_slovenian_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_slovenian_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_slovenian_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_spanish2_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_spanish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_spanish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_spanish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_swedish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_swedish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_swedish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_swedish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_turkish_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_vietnamese_ai_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_vietnamese_as_cs +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_cs3_LowerFirst] +ident _<[digit7]<[letter7_cs3_LowerFirst] +ascii [version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_vietnamese_nopad_ai_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_vietnamese_nopad_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_0900_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf8mb4_bin +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[upper7]<[lower7] +ident [digit7]<[upper7]<_<[lower7] +ascii ascii7_bin +--- --- +name utf8mb4_cs_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_da_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_de_pb_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_eo_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_es_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_es_trad_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_et_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_hr_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_hu_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_is_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_la_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_lt_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_lv_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_nopad_bin +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[upper7]<[lower7] +ident [nopad][digit7]<[upper7]<_<[lower7] +ascii [nopad]ascii7_bin +--- --- +name utf8mb4_pl_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_ro_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_sk_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_sl_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_sv_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_thai_520_w2 +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb4_tr_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_vi_0900_as_cs +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_cs3_LowerFirst] +ident [nopad]_<[digit7]<[letter7_cs3_LowerFirst] +ascii [nopad][version 14.0.0]ascii7_uca_cs +--- --- +name utf8mb4_uca1400_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_croatian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_croatian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_czech_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_danish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_esperanto_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_esperanto_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_esperanto_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_esperanto_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_estonian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_estonian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_german2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_german2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_german2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_german2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_hungarian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_hungarian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_hungarian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_hungarian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_icelandic_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_icelandic_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_icelandic_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_icelandic_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_latvian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_latvian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_lithuanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_persian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_persian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_persian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_persian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_polish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_polish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_polish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_polish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_romanian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_romanian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_romanian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_romanian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_roman_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_roman_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_sinhala_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_sinhala_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_sinhala_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_sinhala_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_slovak_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovak_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_slovenian_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_slovenian_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_slovenian_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_slovenian_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_spanish2_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish2_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_spanish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_spanish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_spanish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_spanish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_swedish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_swedish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_swedish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_swedish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_turkish_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_turkish_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_uca1400_vietnamese_ai_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_vietnamese_as_ci +none +digits [digit7] +minus_dot_digits [version 14.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_vietnamese_nopad_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_uca1400_vietnamese_nopad_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_0900_as_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_croatian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_croatian_mysql561_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_cs_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_czech_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_danish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_da_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_de_pb_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_eo_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_esperanto_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_estonian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_es_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_es_trad_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_et_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_general1400_as_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf8mb4_general_ci +none +digits [digit7] +minus_dot_digits -<.<[digit7] +alnum [digit7]<[letter7_ci] +ident [digit7]<[letter7_ci]<_ +ascii ascii7_caseup_ci +--- --- +name utf8mb4_general_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad][digit7]<[letter7_ci]<_ +ascii [nopad]ascii7_caseup_ci +--- --- +name utf8mb4_german2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_hr_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_hungarian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_hu_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_icelandic_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_is_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_latvian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_la_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_lithuanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_lt_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_lv_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_myanmar_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb4_persian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_pl_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_polish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_romanian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_roman_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_ro_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_sinhala_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_sk_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_slovak_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_slovenian_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_sl_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_spanish2_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_spanish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_sv_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +name utf8mb4_swedish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_tr_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_turkish_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum NULL +ident NULL +ascii NULL +--- --- +name utf8mb4_unicode_520_ci +none +digits [digit7] +minus_dot_digits [version 5.2.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb4_unicode_520_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 5.2.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 5.2.0]ascii7_uca_ci +--- --- +name utf8mb4_unicode_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_unicode_nopad_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 4.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_vietnamese_ci +none +digits [digit7] +minus_dot_digits [version 4.0.0]-<.<[digit7] +alnum [digit7]<[letter7_ci] +ident _<[digit7]<[letter7_ci] +ascii [version 4.0.0]ascii7_uca_ci +--- --- +name utf8mb4_vi_0900_ai_ci +none [nopad] +digits [nopad][digit7] +minus_dot_digits [nopad][version 14.0.0]-<.<[digit7] +alnum [nopad][digit7]<[letter7_ci] +ident [nopad]_<[digit7]<[letter7_ci] +ascii [nopad][version 14.0.0]ascii7_uca_ci +--- --- +SET @character_set_name=NULL; +# End of 11.8 tests diff --git a/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.test b/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.test new file mode 100644 index 00000000000..2d89370a69c --- /dev/null +++ b/plugin/func_test/mysql-test/func_test/ctype_utf8mb4.test @@ -0,0 +1,11 @@ +--source include/have_utf8mb4.inc + +--echo # +--echo # MDEV-41246 "Illegal mix of collations" on the mysql.user view +--echo # + +SET @character_set_name='utf8mb4'; +--source ctype_collation_tailoring_00.inc +SET @character_set_name=NULL; + +--echo # End of 11.8 tests diff --git a/plugin/func_test/plugin.cc b/plugin/func_test/plugin.cc index 7c93b47e8e5..16a0d1642a8 100644 --- a/plugin/func_test/plugin.cc +++ b/plugin/func_test/plugin.cc @@ -275,6 +275,194 @@ public: } }; + + +/* + The UCA version formatted as "[version X.Y.Z]". + The version is stored in CHARSET_INFO::uca->version as a number, + e.g. 400 for 4.0.0, 520 for 5.2.0, 1400 for 14.0.0. + The major version is at most 255, the minor and patch versions are one + digit. Every number is appended with CharBuffer::append_uint8(), + which needs 3 free bytes, hence the buffer size. +*/ +class UCAVersion: public CharBuffer<24> +{ +public: + UCAVersion(uint version) + { + append("[version "_LEX_CSTRING); + append_uint8((uint8) (version / 100)); + append_char('.'); + append_uint8((uint8) ((version / 10) % 10)); + append_char('.'); + append_uint8((uint8) (version % 10)); + append_char(']'); + } +}; + + +class Item_func_collation_tailoring: public Item_str_func +{ + using Self= Item_func_collation_tailoring; +public: + + /* + A helper subclass to get my_repertoire_t from an Item + either in numeric or in string (named) format. + */ + class Repertoire: public Longlong_null + { + // Returns NULL if the name is unknown + static Longlong_null repertoire_by_name(const LEX_CSTRING &name) + { + static const struct + { + Lex_ident_charset name; + my_repertoire_t value; + } names[]= + { + {"NONE"_Lex_ident_charset, MY_REPERTOIRE_NONE}, + {"ASCII_DIGITS"_Lex_ident_charset, MY_REPERTOIRE_ASCII_DIGITS}, + {"ASCII_MINUS_DOT_DIGITS"_Lex_ident_charset, + MY_REPERTOIRE_ASCII_MINUS_DOT_DIGITS}, + {"ASCII_ALNUM"_Lex_ident_charset, MY_REPERTOIRE_ASCII_ALNUM}, + {"ASCII_IDENT"_Lex_ident_charset, MY_REPERTOIRE_ASCII_IDENT}, + {"ASCII"_Lex_ident_charset, MY_REPERTOIRE_ASCII} + }; + for (const auto &n : names) + { + if (n.name.streq(name)) + return Longlong_null(n.value); + } + return Longlong_null(); + } + public: + Repertoire(const Longlong_null &rhs) + :Longlong_null(rhs) + { } + Repertoire(Item *item) + :Longlong_null() + { + if (item->cmp_type() != STRING_RESULT) + { + *this= item->to_longlong_null(); + return; + } + String tmp; + String *repertoire= item->val_str_ascii(&tmp); + if (!repertoire) + return; + *this= repertoire_by_name(repertoire->to_lex_cstring()); + } + }; + + using Item_str_func::Item_str_func; + bool fix_length_and_dec(THD *thd) override + { + collation.set(&my_charset_utf8mb4_bin); + max_length= MAX_BLOB_WIDTH; + return false; + } + + String *val_str(String *to) override + { + String *clname= args[0]->val_str_ascii(to); + Repertoire repertoire(args[1]); + if ((null_value= (!clname || args[1]->null_value))) + return nullptr; + /* + An unknown repertoire name or a number with bits outside of + the known repertoires is a mistake in a test. + Return NULL with a warning, so it is not mixed up with "no tailoring". + */ + if (repertoire.is_null() || + ((ulonglong) repertoire.value() & + ~(ulonglong) MY_REPERTOIRE_UNICODE30)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(ME_WARNING), func_name_cstring().str); + null_value= true; + return nullptr; + } + CHARSET_INFO *cl= Charset_loader_mysys(). + get_exact_collation(ErrConvString(clname).ptr(), + MYF(0)); + if (!cl) + { + my_error(ER_UNKNOWN_COLLATION, MYF(ME_WARNING), + ErrConvString(clname).ptr()); + null_value= true; + return nullptr; + } + const my_repertoire_t rep= + static_cast(repertoire.value()); + LEX_CSTRING tr; + if ((null_value= !((tr= (cl->coll->tailoring)(cl, rep)).str))) + return nullptr; + /* + Tailorings do not depend on PAD/NOPAD, and on the UCA version. + The caller (DTCollation::aggregate_by_tailoring()) checks them + separately. Here they are shown only to display the whole picture, + the same way as they are checked there: [nopad] for NOPAD collations, + and [version X.Y.Z] for UCA collations on a repertoire with + punctuation. + */ + const bool show_uca_version= + cl->uca && + !my_repertoire_is_subset_of(rep, MY_REPERTOIRE_ASCII_IDENT); + if ((cl->state & MY_CS_NOPAD) || show_uca_version) + { + to->length(0); + to->set_charset(collation.collation); + if ((cl->state & MY_CS_NOPAD) && + to->append(STRING_WITH_LEN("[nopad]"))) + return nullptr; + if (show_uca_version && + to->append(UCAVersion(cl->uca->version).to_lex_cstring())) + return nullptr; + if (to->append(tr.str, tr.length)) + return nullptr; + return to; + } + to->set(tr.str, tr.length, collation.collation); + return to; + } + LEX_CSTRING func_name_cstring() const override + { + static LEX_CSTRING name= "collation_tailoring"_LEX_CSTRING; + return name; + } + Item *shallow_copy(THD *thd) const override + { + return get_item_copy(thd, this); + } + + class Create_func : public Create_native_func + { + public: + using Create_native_func::Create_native_func; + Item *create_native(THD *thd, const LEX_CSTRING *name, + List *item_list) override + { + uint arg_count= item_list ? item_list->elements : 0; + if (arg_count != 2) + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + return nullptr; + } + return new (thd->mem_root) Self(thd, *item_list); + } + }; + + static Plugin_function *plugin_descriptor() + { + static Create_func creator; + static Plugin_function descriptor(&creator); + return &descriptor; + } + +}; + + /*************************************************************************/ maria_declare_plugin(type_test) @@ -337,5 +525,20 @@ maria_declare_plugin(type_test) NULL, // System variables "1.0", // String version representation MariaDB_PLUGIN_MATURITY_EXPERIMENTAL // Maturity +}, +{ + MariaDB_FUNCTION_PLUGIN, // the plugin type + Item_func_collation_tailoring::plugin_descriptor(), + "collation_tailoring", // plugin name + "MariaDB Corporation", // plugin author + "Function COLLATION_TAILORING()", // the plugin description + PLUGIN_LICENSE_GPL, // the plugin license + 0, // Pointer to plugin initialization function + 0, // Pointer to plugin deinitialization function + 0x0100, // Numeric version 0xAABB means AA.BB version + NULL, // Status variables + NULL, // System variables + "1.0", // String version representation + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL // Maturity } maria_declare_plugin_end; diff --git a/plugin/handler_socket/mysql-test/handlersocket/basic.result b/plugin/handler_socket/mysql-test/handlersocket/basic.result index 4f71ad4d12c..9d9c5bc9285 100644 --- a/plugin/handler_socket/mysql-test/handlersocket/basic.result +++ b/plugin/handler_socket/mysql-test/handlersocket/basic.result @@ -12,8 +12,8 @@ plugin_description Direct access into InnoDB plugin_license BSD plugin_maturity Beta plugin_auth_version 1.1 -select * from information_schema.global_variables where variable_name like 'handlersocket%' order by variable_name; -VARIABLE_NAME VARIABLE_VALUE +select variable_name, if(variable_name like 'handlersocket_plain_secret%', 'HS_SECRET', variable_value) as variable_value from information_schema.global_variables where variable_name like 'handlersocket%' order by variable_name; +variable_name variable_value HANDLERSOCKET_ACCEPT_BALANCE 0 HANDLERSOCKET_ADDRESS HANDLERSOCKET_BACKLOG 32768 diff --git a/plugin/handler_socket/mysql-test/handlersocket/basic.test b/plugin/handler_socket/mysql-test/handlersocket/basic.test index 073ddf43aed..855784c4393 100644 --- a/plugin/handler_socket/mysql-test/handlersocket/basic.test +++ b/plugin/handler_socket/mysql-test/handlersocket/basic.test @@ -10,8 +10,8 @@ let HS_SECRET=`select @@handlersocket_plain_secret`; let HS_PORT=`select @@handlersocket_port`; --query_vertical select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description, plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket' ---replace_result $HS_SECRET HS_SECRET $HS_PORT HS_PORT -select * from information_schema.global_variables where variable_name like 'handlersocket%' order by variable_name; +--replace_result $HS_PORT HS_PORT +select variable_name, if(variable_name like 'handlersocket_plain_secret%', 'HS_SECRET', variable_value) as variable_value from information_schema.global_variables where variable_name like 'handlersocket%' order by variable_name; select length(@@handlersocket_plain_secret), @@handlersocket_plain_secret = @@handlersocket_plain_secret_wr; create table t1 (id int primary key, name varchar(100)) engine=innodb; diff --git a/plugin/plugin_name_ascii_check/CMakeLists.txt b/plugin/plugin_name_ascii_check/CMakeLists.txt new file mode 100644 index 00000000000..26f2022486d --- /dev/null +++ b/plugin/plugin_name_ascii_check/CMakeLists.txt @@ -0,0 +1,10 @@ + +MYSQL_ADD_PLUGIN(plugin_name_ascii plugin_name_ascii.cc + MODULE_ONLY + NOT_EMBEDDED + COMPONENT Test) + +MYSQL_ADD_PLUGIN(plugin_name_non_ascii plugin_name_non_ascii.cc + MODULE_ONLY + NOT_EMBEDDED + COMPONENT Test) diff --git a/plugin/plugin_name_ascii_check/plugin_name_ascii.cc b/plugin/plugin_name_ascii_check/plugin_name_ascii.cc new file mode 100644 index 00000000000..14606e1d81b --- /dev/null +++ b/plugin/plugin_name_ascii_check/plugin_name_ascii.cc @@ -0,0 +1,66 @@ +/* Copyright (c) 2024, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +/* + Test plugin: two plugins with pure ASCII names. + Used by mysql-test/suite/plugins/t/plugin_name_ascii.test +*/ + +#include + +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +#define __attribute__(A) +#endif + +static struct st_mysql_daemon plugin1_descriptor = { MYSQL_DAEMON_INTERFACE_VERSION }; +static struct st_mysql_daemon plugin2_descriptor = { MYSQL_DAEMON_INTERFACE_VERSION }; + +static int plugin1_init(void *p __attribute__((unused))) { return 0; } +static int plugin1_deinit(void *p __attribute__((unused))) { return 0; } +static int plugin2_init(void *p __attribute__((unused))) { return 0; } +static int plugin2_deinit(void *p __attribute__((unused))) { return 0; } + +maria_declare_plugin(plugin_name_ascii) +{ + MYSQL_DAEMON_PLUGIN, + &plugin1_descriptor, + "ascii_plugin_one", + "MariaDB", + "Plugin with ASCII name - one", + PLUGIN_LICENSE_GPL, + plugin1_init, + plugin1_deinit, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +}, +{ + MYSQL_DAEMON_PLUGIN, + &plugin2_descriptor, + "ascii_plugin_two", + "MariaDB", + "Plugin with ASCII name - two", + PLUGIN_LICENSE_GPL, + plugin2_init, + plugin2_deinit, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +} +maria_declare_plugin_end; diff --git a/plugin/plugin_name_ascii_check/plugin_name_non_ascii.cc b/plugin/plugin_name_ascii_check/plugin_name_non_ascii.cc new file mode 100644 index 00000000000..b5ff5539322 --- /dev/null +++ b/plugin/plugin_name_ascii_check/plugin_name_non_ascii.cc @@ -0,0 +1,85 @@ +/* Copyright (c) 2024, MariaDB Corporation. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +/* + Test plugin: two plugins with ASCII names and one with a non-ASCII name. + Used by mysql-test/suite/plugins/t/plugin_name_ascii.test + The non-ASCII plugin name "plügïn_non_ascii" is represented as raw UTF-8 literal. +*/ + +#include + +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +#define __attribute__(A) +#endif + +static struct st_mysql_daemon plugin1_descriptor = { MYSQL_DAEMON_INTERFACE_VERSION }; +static struct st_mysql_daemon plugin2_descriptor = { MYSQL_DAEMON_INTERFACE_VERSION }; +static struct st_mysql_daemon plugin3_descriptor = { MYSQL_DAEMON_INTERFACE_VERSION }; + +static int plugin1_init(void *p __attribute__((unused))) { return 0; } +static int plugin1_deinit(void *p __attribute__((unused))) { return 0; } +static int plugin2_init(void *p __attribute__((unused))) { return 0; } +static int plugin2_deinit(void *p __attribute__((unused))) { return 0; } +static int plugin3_init(void *p __attribute__((unused))) { return 0; } +static int plugin3_deinit(void *p __attribute__((unused))) { return 0; } + +maria_declare_plugin(plugin_name_non_ascii) +{ + MYSQL_DAEMON_PLUGIN, + &plugin1_descriptor, + "plugin_one", + "MariaDB", + "Plugin with ASCII name - one", + PLUGIN_LICENSE_GPL, + plugin1_init, + plugin1_deinit, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +}, +{ + MYSQL_DAEMON_PLUGIN, + &plugin2_descriptor, + "plugin_two", + "MariaDB", + "Plugin with ASCII name - two", + PLUGIN_LICENSE_GPL, + plugin2_init, + plugin2_deinit, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +}, +{ + MYSQL_DAEMON_PLUGIN, + &plugin3_descriptor, + "plügïn_non_ascii", /* "plügïn_non_ascii" in raw UTF-8 literal */ + "MariaDB", + "Plugin with non-ASCII name", + PLUGIN_LICENSE_GPL, + plugin3_init, + plugin3_deinit, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_STABLE +} +maria_declare_plugin_end; diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/r/plugin.result b/plugin/wsrep_info/mysql-test/wsrep_info/r/plugin.result index f99f27f3539..66e0825c94a 100644 --- a/plugin/wsrep_info/mysql-test/wsrep_info/r/plugin.result +++ b/plugin/wsrep_info/mysql-test/wsrep_info/r/plugin.result @@ -4,7 +4,7 @@ connection node_1; connection node_1; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID PROTOCOL_VERSION - synced primary 2 2 4 + synced primary 2 2 5 SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME; INDEX UUID NAME ADDRESS test-node-1
@@ -13,7 +13,7 @@ INDEX UUID NAME ADDRESS connection node_2; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID PROTOCOL_VERSION - synced primary 2 2 4 + synced primary 2 2 5 SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME; INDEX UUID NAME ADDRESS test-node-1
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 25f86b276f1..f3647df1171 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -234,6 +234,19 @@ get_socat_ver() fi } +check_for_socat_commonname() +{ + [ -n "${SOCAT_COMMONNAME+x}" ] && return + # Some socat builds don't register "commonname" as an option at all + # (parseopts() rejects it as unknown regardless of value), so probe + # the actual binary instead of relying on the socat version number. + if socat -hhh 2>&1 | grep -qw 'openssl-commonname'; then + SOCAT_COMMONNAME=1 + else + SOCAT_COMMONNAME=0 + fi +} + get_transfer() { if [ "$tfmt" = 'nc' ]; then @@ -434,6 +447,15 @@ get_transfer() exit 22 fi + if [ -n "$CN_option" ]; then + check_for_socat_commonname + if [ "$SOCAT_COMMONNAME" -eq 0 ]; then + wsrep_log_info \ + "socat lacks the 'commonname' option; skipping peer name verification" + CN_option="" + fi + fi + tcmd="$tcmd$CN_option$sockopt" if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then diff --git a/sql/backup.cc b/sql/backup.cc index 8184c6c3f8a..ca6d3cb6ebd 100644 --- a/sql/backup.cc +++ b/sql/backup.cc @@ -591,46 +591,53 @@ static void stop_ddl_logging() } -static inline char *add_str_to_buffer(char *ptr, const LEX_CSTRING *from) +/* + Inline (stack) part of the log record buffer; enough for typical DDL, + longer records spill over to the heap. +*/ +static constexpr size_t BACKUP_LOG_RECORD_PREALLOC= 512; + +static inline bool add_str_to_buffer(String *str, const LEX_CSTRING *from) { - if (from->length) // If length == 0, str may be 0 - memcpy(ptr, from->str, from->length); - ptr[from->length]= '\t'; - return ptr+ from->length + 1; + // If length == 0, str may be 0 + return (from->length && str->append(from->str, from->length)) || + str->append('\t'); } -static char *add_name_to_buffer(char *ptr, const LEX_CSTRING *from) +static bool add_name_to_buffer(String *str, const LEX_CSTRING *from) { - LEX_CSTRING tmp; - char buff[NAME_LEN*4]; + /* Each source byte gives at most mbmaxlen bytes, +1 for strconvert's '\0' */ + size_t max_length= from->length * my_charset_filename.mbmaxlen + 1; uint errors; - tmp.str= buff; - tmp.length= strconvert(system_charset_info, from->str, from->length, - &my_charset_filename, buff, sizeof(buff), &errors); - return add_str_to_buffer(ptr, &tmp); + if (str->reserve(max_length)) + return true; + char *to= (char*) str->end(); + str->length(str->length() + + strconvert(system_charset_info, from->str, from->length, + &my_charset_filename, to, max_length, &errors)); + return str->append('\t'); } -static char *add_id_to_buffer(char *ptr, const LEX_CUSTRING *from) +static bool add_id_to_buffer(String *str, const LEX_CUSTRING *from) { LEX_CSTRING tmp; char buff[MY_UUID_STRING_LENGTH]; if (!from->length) - return add_str_to_buffer(ptr, (LEX_CSTRING*) from); + return add_str_to_buffer(str, (LEX_CSTRING*) from); tmp.str= buff; tmp.length= MY_UUID_STRING_LENGTH; my_uuid2str(from->str, buff, 1); - return add_str_to_buffer(ptr, &tmp); + return add_str_to_buffer(str, &tmp); } -static char *add_bool_to_buffer(char *ptr, bool value) { - *(ptr++) = value ? '1' : '0'; - *(ptr++) = '\t'; - return ptr; +static bool add_bool_to_buffer(String *str, bool value) +{ + return str->append(value ? '1' : '0') || str->append('\t'); } /* @@ -657,8 +664,7 @@ void backup_log_ddl(const backup_log_info *info) mysql_mutex_unlock(&LOCK_backup_log); return; } - /* Enough place for db.table *2 + query + engine_name * 2 + tabs+ uuids */ - char buff[NAME_CHAR_LEN*4+20+40*2+10+MY_UUID_STRING_LENGTH*2], *ptr= buff; + StringBuffer buff; char timebuff[20]; struct tm current_time; LEX_CSTRING tmp_lex; @@ -674,28 +680,35 @@ void backup_log_ddl(const backup_log_info *info) current_time.tm_hour, current_time.tm_min, current_time.tm_sec); - ptr= add_str_to_buffer(ptr, &tmp_lex); + bool error= add_str_to_buffer(&buff, &tmp_lex); - ptr= add_str_to_buffer(ptr, &info->query); - ptr= add_str_to_buffer(ptr, &info->org_storage_engine_name); - ptr= add_bool_to_buffer(ptr, info->org_partitioned); - ptr= add_name_to_buffer(ptr, &info->org_database); - ptr= add_name_to_buffer(ptr, &info->org_table); - ptr= add_id_to_buffer(ptr, &info->org_table_id); + error|= add_str_to_buffer(&buff, &info->query); + error|= add_str_to_buffer(&buff, &info->org_storage_engine_name); + error|= add_bool_to_buffer(&buff, info->org_partitioned); + error|= add_name_to_buffer(&buff, &info->org_database); + error|= add_name_to_buffer(&buff, &info->org_table); + error|= add_id_to_buffer(&buff, &info->org_table_id); /* The following fields are only set in case of rename, repair or alter table */ - ptr= add_str_to_buffer(ptr, &info->new_storage_engine_name); - ptr= add_bool_to_buffer(ptr, info->new_partitioned); - ptr= add_name_to_buffer(ptr, &info->new_database); - ptr= add_name_to_buffer(ptr, &info->new_table); - ptr= add_id_to_buffer(ptr, &info->new_table_id); + error|= add_str_to_buffer(&buff, &info->new_storage_engine_name); + error|= add_bool_to_buffer(&buff, info->new_partitioned); + error|= add_name_to_buffer(&buff, &info->new_database); + error|= add_name_to_buffer(&buff, &info->new_table); + error|= add_id_to_buffer(&buff, &info->new_table_id); - ptr[-1]= '\n'; // Replace last tab with nl - if (mysql_file_write(backup_log, (uchar*) buff, (size_t) (ptr-buff), - MYF(MY_FNABP))) + if (!error) + { + buff.length(buff.length() - 1); // Remove last tab + error= buff.append('\n'); // ... and replace it with nl + } + + if (error) + backup_log_error= ENOMEM; + else if (mysql_file_write(backup_log, (const uchar*) buff.ptr(), + buff.length(), MYF(MY_FNABP))) backup_log_error= my_errno; mysql_mutex_unlock(&LOCK_backup_log); } diff --git a/sql/char_buffer.h b/sql/char_buffer.h index de8c368bf12..fb89e27ee73 100644 --- a/sql/char_buffer.h +++ b/sql/char_buffer.h @@ -91,6 +91,23 @@ public: return *this; } + // Append an unsigned 8-bit number, in decimal, without leading zeros + CharBuffer & append_uint8(uint8 nr) + { + DBUG_ASSERT(is_sane()); + if (available_size() >= 3) // The maximum number is "255" + { + if (nr >= 100) + m_buff[m_length++]= (char) ('0' + nr / 100); + if (nr >= 10) + m_buff[m_length++]= (char) ('0' + (nr / 10) % 10); + m_buff[m_length++]= (char) ('0' + nr % 10); + m_buff[m_length]= '\0'; + } + DBUG_ASSERT(is_sane()); + return *this; + } + // Append one character CharBuffer & append_char(char ch) { diff --git a/sql/deprecation.h b/sql/deprecation.h index c7517ba2422..589d902b18d 100644 --- a/sql/deprecation.h +++ b/sql/deprecation.h @@ -12,6 +12,8 @@ In the current release model, versions are released like the following 2027 13.2 13.3-LTS 14.0 14.1 2028 14.2 14.3-LTS 15.0 15.1 2029 15.2 15.3-LTS 16.0 16.1 +2030 16.2 16.3-LTS 17.0 17.1 +2031 17.2 17.3-LTS 18.0 18.1 ... A deprecated feature can be removed only when all releases when it's @@ -31,7 +33,9 @@ template static inline void check_deprecated_version(void) V <= 1005 ? MYSQL_VERSION_ID < 120000 : /* until 10.5 EOL */ V <= 1010 ? MYSQL_VERSION_ID < 130000 : /* until 10.6 EOL */ V <= 1103 ? MYSQL_VERSION_ID < 140300 : /* until 10.11 EOL */ - V <= 1107 ? MYSQL_VERSION_ID < 160000 : /* until 10.11 EOL */ + V <= 1107 ? MYSQL_VERSION_ID < 160000 : /* until 11.4 EOL */ + V <= 1202 ? MYSQL_VERSION_ID < 170000 : /* until 11.8 EOL */ + V <= 1302 ? MYSQL_VERSION_ID < 180000 : /* until 12.3 EOL */ V == 999999, /* only for sys_var::do_deprecated_warning() */ "check_deprecated_version failed" ); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index a5c4978d212..ef410b7d99b 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -397,6 +397,19 @@ Event_scheduler::start(int *err_no) if (state > INITIALIZED) goto end; + /* + Shutdown calls Events::stop() only once in close_connections(). The + scheduler thread started after that would never be stopped and + close_connections() would wait for it forever. No error needed: + the server is shutting down and @@event_scheduler staying ON without + the thread does not matter. + */ + if (abort_loop) + { + DBUG_PRINT("info", ("Shutdown in progress, not starting the scheduler")); + goto end; + } + if (!(new_thd= new THD(next_thread_id()))) { sql_print_error("Event Scheduler: Cannot initialize the scheduler thread"); diff --git a/sql/field.cc b/sql/field.cc index 7aeb777d929..0164c1b5701 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2413,7 +2413,8 @@ bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const return non-unique values 'a' and 'A'. */ DTCollation tmp(dtcollation()); - return !tmp.aggregate(item->collation) && tmp.collation == field_charset(); + return !tmp.aggregate(item->collation, 0, MY_REPERTOIRE_UNICODE30) && + tmp.collation == field_charset(); } @@ -7823,7 +7824,7 @@ Field_string::compatible_field_size(uint field_metadata, { #ifdef HAVE_REPLICATION const Check_field_param check_param = { this }; - if (rpl_master_has_bug(rli_arg, 37426, TRUE, + if (rpl_master_has_bug(rli_arg, RPL_BUG_MYSQL_37426, TRUE, check_field_for_37426, &check_param)) return FALSE; // Not compatible field sizes #endif @@ -10234,6 +10235,34 @@ int Field_bit::store(const char *from, size_t length, CHARSET_INFO *cs) } +int Field_bit::store_numeric(const char *from, size_t length, CHARSET_INFO *cs) +{ + char *end; + int error; + ulonglong nr= cs->strntoull10rnd(from, length, true, &end, &error); + int store_error= store((longlong) nr, true); + + if (unlikely(error == MY_ERRNO_ERANGE)) + { + if (!store_error) + set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); + return 1; + } + if (error == MY_ERRNO_EDOM || from == end) + { + ErrConvString str(from, length, cs); + set_warning_truncated_wrong_value("integer", str.ptr()); + return 1; + } + if (test_if_important_data(cs, end, from + length)) + { + set_warning(WARN_DATA_TRUNCATED, 1); + return 1; + } + return store_error; +} + + int Field_bit::store(double nr) { return Field_bit::store((longlong) nr, FALSE); @@ -11039,12 +11068,13 @@ bool Column_definition::check(THD *thd) char_length= (uint)length; /* - Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and - it is NOT NULL, not an AUTO_INCREMENT field. - We need to do this check here and in mysql_create_prepare_table() as + Set NO_DEFAULT_VALUE_FLAG if this field is NOT NULL and has neither + a DEFAULT value nor a default function (AUTO_INCREMENT, + DEFAULT/ON UPDATE NOW()). + We need to do this check here and in mysql_prepare_create_table() as sp_head::fill_field_definition() calls this function. */ - if (!default_value && unireg_check == Field::NONE && (flags & NOT_NULL_FLAG)) + if (!default_value && !has_default_function() && (flags & NOT_NULL_FLAG)) { /* TIMESTAMP columns get implicit DEFAULT value when @@ -11765,7 +11795,7 @@ bool Field::save_in_field_ignore_value(bool view_error_processing) void Field::register_field_in_read_map() { - if (vcol_info) + if (!stored_in_db()) { Item *vcol_item= vcol_info->expr; vcol_item->walk(&Item::register_field_in_read_map, diff --git a/sql/field.h b/sql/field.h index a8fa9c772c5..46b7177556d 100644 --- a/sql/field.h +++ b/sql/field.h @@ -657,7 +657,8 @@ public: bool cleanup_session_expr(); bool fix_and_check_expr(THD *thd, TABLE *table); bool check_access(THD *thd); - inline bool is_equal(const Virtual_column_info* vcol, bool cmp_names) const; + inline bool is_equal(const Virtual_column_info* vcol, bool cmp_names, + bool unordered_conditions= false) const; inline void print(String*); }; @@ -975,6 +976,17 @@ public: { return store(to, length, cs); } + /* + Store a number literal as text, possibly with a fraction or exponent, + rather than a binary string. Called by store_json_in_field() in JSON_TABLE + for JSON numeric values. Types whose string store uses a binary + representation can override this without changing string input. + As with store(), a nonzero result can indicate a conversion warning. + */ + virtual int store_numeric(const char *from, size_t length, CHARSET_INFO *cs) + { + return store(from, length, cs); + } virtual int store_binary(const char *to, size_t length) { return store(to, length, &my_charset_bin); @@ -5131,6 +5143,7 @@ public: int save_in_field(Field *to) override { return to->store(val_int(), true); } bool memcpy_field_possible(const Field *from) const override{ return false; } int store(const char *to, size_t length, CHARSET_INFO *charset) override; + int store_numeric(const char *from, size_t length, CHARSET_INFO *cs) override; int store(double nr) override; int store(longlong nr, bool unsigned_val) override; int store_decimal(const my_decimal *) override; @@ -5629,7 +5642,12 @@ public: bool has_default_function() const { - return unireg_check != Field::NONE; + /* + TMYSQL_COMPRESSED is not a default function, it is stored in + unireg_check only to remember that the column is COMPRESSED. + */ + return unireg_check != Field::NONE && + unireg_check != Field::TMYSQL_COMPRESSED; } Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 343ab395ffc..3760035deaa 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5981,7 +5981,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key) m_start_key.length= key_len= calculate_key_len(table, active_index, m_start_key.key, m_start_key.keypart_map); - DBUG_PRINT("info", ("have_start_key map %lu find_flag %u len %u", + DBUG_PRINT("info", ("have_start_key map %u find_flag %u len %u", m_start_key.keypart_map, m_start_key.flag, key_len)); DBUG_ASSERT(key_len); } @@ -6437,7 +6437,7 @@ int ha_partition::multi_range_key_create_key(RANGE_SEQ_IF *seq, DBUG_PRINT("info",("partition range->range_flag: %u", range->range_flag)); DBUG_PRINT("info",("partition start_key->key: %p", start_key->key)); DBUG_PRINT("info",("partition start_key->length: %u", start_key->length)); - DBUG_PRINT("info",("partition start_key->keypart_map: %lu", + DBUG_PRINT("info",("partition start_key->keypart_map: %u", start_key->keypart_map)); DBUG_PRINT("info",("partition start_key->flag: %u", start_key->flag)); @@ -6462,7 +6462,7 @@ int ha_partition::multi_range_key_create_key(RANGE_SEQ_IF *seq, end_key= &range->end_key; DBUG_PRINT("info",("partition end_key->key: %p", end_key->key)); DBUG_PRINT("info",("partition end_key->length: %u", end_key->length)); - DBUG_PRINT("info",("partition end_key->keypart_map: %lu", + DBUG_PRINT("info",("partition end_key->keypart_map: %u", end_key->keypart_map)); DBUG_PRINT("info",("partition end_key->flag: %u", end_key->flag)); if (end_key->key) @@ -11404,6 +11404,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, part_share->next_auto_inc_val+= nb_desired_values * increment; unlock_auto_increment(); + DEBUG_SYNC(ha_thd(), "ha_partition_get_auto_increment_after_reservation"); DBUG_PRINT("info", ("*first_value: %lu", (ulong) *first_value)); *nb_reserved_values= nb_desired_values; } @@ -11436,7 +11437,8 @@ void ha_partition::release_auto_increment() we can lower the reserved value. */ if (next_insert_id < next_auto_inc_val && - auto_inc_interval_for_cur_row.maximum() >= next_auto_inc_val) + auto_inc_interval_for_cur_row.maximum() >= next_auto_inc_val && + next_insert_id >= auto_inc_interval_for_cur_row.minimum()) { THD *thd= ha_thd(); /* diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9922822ea3b..23e961022f0 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1668,9 +1668,9 @@ public: ha_rows part_records(partition_element *part_elem) { DBUG_ASSERT(m_part_info); - uint32 sub_factor= m_part_info->num_subparts ? m_part_info->num_subparts : 1; - uint32 part_id= part_elem->id * sub_factor; - uint32 part_id_end= part_id + sub_factor; + uint32 part_id_end; + uint32 part_id= part_elem->bitmap_range(m_part_info->num_subparts, + part_id_end); DBUG_ASSERT(part_id_end <= m_tot_parts); ha_rows part_recs= 0; for (; part_id < part_id_end; ++part_id) diff --git a/sql/handler.h b/sql/handler.h index 3ab9e0bcd1a..8c811c2df97 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3290,7 +3290,8 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); */ inline key_part_map make_keypart_map(uint N) { - return ((key_part_map)2 << (N)) - 1; + DBUG_ASSERT(N < MAX_REF_PARTS); + return (key_part_map) my_set_bits(N + 1); } /* @@ -3299,7 +3300,9 @@ inline key_part_map make_keypart_map(uint N) */ inline key_part_map make_prev_keypart_map(uint N) { - return ((key_part_map)1 << (N)) - 1; + DBUG_ASSERT(N <= MAX_REF_PARTS); + // do NOT call my_set_bit(0), 1<<-1 is undefined/compiler/overflow dependent + return N ? (key_part_map) my_set_bits(N) : 0; } diff --git a/sql/item.cc b/sql/item.cc index c667ab01cac..e0d054f0691 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -991,7 +991,11 @@ bool Item_field::check_field_expression_processor(void *arg) bool Item_field::update_vcol_processor(void *arg) { MY_BITMAP *map= (MY_BITMAP *) arg; - if (field->vcol_info && + /* + Stored vcols are not recomputed: the caller must have their values + in the record (the engine fills them as base columns). + */ + if (!field->stored_in_db() && !bitmap_fast_test_and_set(map, field->field_index)) { field->vcol_info->expr->walk(&Item::update_vcol_processor, arg, 0); @@ -2511,15 +2515,123 @@ left_is_superset(const DTCollation *left, const DTCollation *right) left->collation->mbminlen == right->collation->mbminlen))))) return TRUE; /* Allow convert from ASCII */ - if (right->repertoire == MY_REPERTOIRE_ASCII && + if (right->repertoire_is_subset_of(MY_REPERTOIRE_ASCII) && (left->derivation < right->derivation || (left->derivation == right->derivation && - !(left->repertoire == MY_REPERTOIRE_ASCII)))) + !left->repertoire_is_subset_of(MY_REPERTOIRE_ASCII)))) return TRUE; /* Disallow conversion otherwise */ return FALSE; } + +/* + Choose an algorithmically simpler collation for use in + collation aggregation. +*/ +static bool +left_is_algorithmically_simpler(const DTCollation &left, + const DTCollation &right) +{ + /* + If only left is a character set which cannot store all ASCII characters + (e.g. swe7, see CHARSET_INFO::is_ascii_superset()), + then choose the other side even if the other side is multi-byte. + Rationale: + The constructor Item_func_conv_charset sets Item_func_conv_charset::safe + to false if conversion is done to such a character set, + even on ALNUM and IDENT repertoires. + So choosing such a side would raise "Illegal mix of collations". + */ + const bool left_ascii_superset= left.collation->is_ascii_superset(); + const bool right_ascii_superset= right.collation->is_ascii_superset(); + if (left_ascii_superset != right_ascii_superset) + return left_ascii_superset; + /* + - Between a single byte character set and a multibyte character set + choose the single byte one + - Between a simple collation (one-to-one mapping) and + a complex collation (with contractions and expansions) choose + the simple one + */ + if (left.collation->mbmaxlen != right.collation->mbmaxlen) + return left.collation->mbmaxlen < right.collation->mbmaxlen; + return left.collation->strxfrm_multiply < right.collation->strxfrm_multiply; +} + + +/* + Handle a special case: + if both collations have equal collation rules (tailoring) on + the cumulative repertoire of all aggregated arguments + (e.g. MY_REPERTOIRE_ASCII_{ALNUM|IDENT|ASCII}), + then it does not matter which side collation to use for comparison - + the result will be equal. + Note, the repertoires of the two sides are not compared with each other: + both tailorings are requested on the same cumulative_repertoire. + Examples: + SELECT _latin1'a' = _latin2'a'; + + @param dt the collation to aggregate with + @param flags MY_COLL_XXX flags; + MY_COLL_ALLOW_BY_TAILORING must be set, + otherwise this method does nothing + @param cumulative_repertoire the OR-ed repertoires of all arguments + being aggregated + + @retval false The collations are compatible on cumulative_repertoire. + Either "this" or "dt" was chosen (see + left_is_algorithmically_simpler()). Only the collation + and the derivation are set, the repertoire is not changed: + the caller merges the repertoires of both sides. + @retval true The special case is not applicable, "this" is not changed. + Note, the return value is inverted: true means failure. +*/ +bool DTCollation::aggregate_by_tailoring(const DTCollation &dt, uint flags, + my_repertoire_t cumulative_repertoire) +{ + // Collation equality should have been handled earlier in the caller + DBUG_ASSERT(collation != dt.collation); + if ((flags & MY_COLL_ALLOW_BY_TAILORING) && + /* + Explicit COLLATE clause with different collations + on both sides is an error in the SQL standard. + A side with DERIVATION_NONE is an earlier unresolved conflict + which can only be resolved by an explicit COLLATE clause. + */ + derivation != DERIVATION_EXPLICIT && + dt.derivation != DERIVATION_EXPLICIT && + derivation != DERIVATION_NONE && + dt.derivation != DERIVATION_NONE && + my_collations_equal_on_repertoire(collation, dt.collation, + cumulative_repertoire)) + { + /* + Collations are compatible on the given repertoire. + It does not matter which side to choose for comparison, both will work + and produce the same comparison result. Let's try to choose + the algorithmically simplest one, to be more deterministic. + */ + /* + Do not use set(dt) here: it would also replace the repertoire. + The repertoire is not changed here, the caller + merges the repertoires of both sides in the common ending + of DTCollation::aggregate(). + If "this" is chosen (i.e. the left side in case of a comparison + operator), then nothing needs to be done. + */ + if (left_is_algorithmically_simpler(dt, *this)) + { + // dt is simpler + collation= dt.collation; + derivation= dt.derivation; + } + return false; + } + return true; +} + + /** Aggregate two collations together taking into account their coercibility (aka derivation):. @@ -2537,6 +2649,11 @@ left_is_superset(const DTCollation *left, const DTCollation *right) Currently processed flags are: MY_COLL_ALLOW_SUPERSET_CONV - allow conversion to a superset MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value + MY_COLL_ALLOW_BY_TAILORING - if none of the above chose a winner, + allow choosing either side's collation without conversion when both + collations have equal comparison rules (tailoring) on the + cumulative_repertoire, see aggregate_by_tailoring(). + Only comparison operators pass this flag. - two EXPLICIT collations produce an error, e.g. this is wrong: CONCAT(expr1 collate latin1_swedish_ci, expr2 collate latin1_german_ci) - the side with smaller derivation value wins, @@ -2551,10 +2668,27 @@ left_is_superset(const DTCollation *left, const DTCollation *right) latin1_german1_ci_column, expr COLLATE latin1_german2_ci) @endcode + + @param dt the collation to aggregate with + @param flags MY_COLL_XXX flags, see above + @param cumulative_repertoire the OR-ed repertoires of all arguments + being aggregated (not only of the two + collations aggregated at this step). + It is used to compare tailorings + if MY_COLL_ALLOW_BY_TAILORING is set. + + @return false on success, true if the collations cannot be aggregated */ -bool DTCollation::aggregate(const DTCollation &dt, uint flags) +bool DTCollation::aggregate(const DTCollation &dt, uint flags, + my_repertoire_t cumulative_repertoire) { + /* + set(dt) replaces the repertoire of "this" with the repertoire of dt. + The repertoire of the result must include the repertoires of both sides, + otherwise it can be too narrow for the following aggregation steps. + */ + const my_repertoire_t merged_repertoire= repertoire | dt.repertoire; if (!my_charset_same(collation, dt.collation)) { /* @@ -2603,6 +2737,20 @@ bool DTCollation::aggregate(const DTCollation &dt, uint flags) { set(dt); } + /* + Here we have: + - Different character sets + - None of the sides is BINARY/VARBINARY/BLOB + - Super-set + derivation based aggregation did not find the winner + - Coercible-conversion (derivation) aggregation did not find the winner + */ + else if (!aggregate_by_tailoring(dt, flags, cumulative_repertoire)) + { + /* + Both sides have equal tailoring on the OR-ed repertoires. + The repertoires are merged in the common ending of this function. + */ + } else { // Cannot apply conversion @@ -2636,21 +2784,44 @@ bool DTCollation::aggregate(const DTCollation &dt, uint flags) dt.collation->state & MY_CS_BINSORT) return 1; if (collation->state & MY_CS_BINSORT) + { + repertoire= merged_repertoire; return 0; + } if (dt.collation->state & MY_CS_BINSORT) { set(dt); + repertoire= merged_repertoire; return 0; } - THD *thd = current_thd; - myf utf8_flag= thd ? thd->get_utf8_flag() - : global_system_variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3; - CHARSET_INFO *bin= get_charset_by_csname(collation->cs_name.str, - MY_CS_BINSORT,MYF(utf8_flag)); - set(bin, DERIVATION_NONE); + /* + Here we have: + - Equal character sets + - Equal non-explicit collation derivation + - Different collations, both non-binary + */ + /* + If both sides have equal tailoring on the OR-ed repertoires, + then aggregate_by_tailoring() chooses the collation, and the + repertoires are merged in the common ending of this function. + */ + if (aggregate_by_tailoring(dt, flags, cumulative_repertoire)) + { + /* + Postpone the decision to the upper level which may have + an explicit COLLATE clause. Set the collation to the binary + collation of this character set with DERIVATION_NONE. + */ + THD *thd = current_thd; + myf utf8_flag= thd ? thd->get_utf8_flag() + : global_system_variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3; + CHARSET_INFO *bin= get_charset_by_csname(collation->cs_name.str, + MY_CS_BINSORT,MYF(utf8_flag)); + set(bin, DERIVATION_NONE); + } } } - repertoire|= dt.repertoire; + repertoire= merged_repertoire; return 0; } @@ -2700,11 +2871,14 @@ bool Type_std_attributes::agg_item_collations(DTCollation &c, uint i; Item **arg; bool unknown_cs= 0; + my_repertoire_t cumulative_repertoire= av[0]->collation.repertoire; + for (i= 1, arg= &av[item_sep]; i < count; i++, arg+= item_sep) + cumulative_repertoire|= arg[0]->collation.repertoire; c.set(av[0]->collation); for (i= 1, arg= &av[item_sep]; i < count; i++, arg+= item_sep) { - if (c.aggregate((*arg)->collation, flags)) + if (c.aggregate((*arg)->collation, flags, cumulative_repertoire)) { if (c.derivation == DERIVATION_NONE && c.collation == &my_charset_bin) @@ -2966,13 +3140,29 @@ Item_sp::func_name_cstring(THD *thd, bool is_package_function) const return { qname.c_ptr_safe(), qname.length() }; } +/* + Free the context of a stored function call. + + note: The items on the call arena are allocated on sp_mem_root, so they + have to be destroyed before the memory root they live in is freed. +*/ + +void +Item_sp::free_call_ctx() +{ + delete func_ctx; + func_ctx= NULL; + sp_query_arena->free_items(); + free_root(&sp_mem_root, MYF(0)); + memset(&sp_mem_root, 0, sizeof(sp_mem_root)); +} + + void Item_sp::cleanup() { m_sp= NULL; - delete func_ctx; - func_ctx= NULL; - free_root(&sp_mem_root, MYF(0)); + free_call_ctx(); dummy_table->alias.free(); } @@ -3102,11 +3292,7 @@ Item_sp::execute_impl(THD *thd, Item **args, uint arg_count) if (err_status || func_ctx->quit_func) { /* Free Items allocated during function execution. */ - delete func_ctx; - func_ctx= NULL; - sp_query_arena->free_items(); - free_root(&sp_mem_root, MYF(0)); - memset(&sp_mem_root, 0, sizeof(sp_mem_root)); + free_call_ctx(); } thd->restore_sub_statement_state(&statement_state); @@ -7520,7 +7706,7 @@ Item_string::make_string_literal_concat(THD *thd, const LEX_CSTRING *str) { append(str->str, (uint32) str->length); set_name(thd, &str_value); - if (!(collation.repertoire & MY_REPERTOIRE_EXTENDED)) + if (collation.repertoire_is_subset_of(MY_REPERTOIRE_ASCII)) { // If the string has been pure ASCII so far, check the new part. CHARSET_INFO *cs= thd->variables.collation_connection; @@ -7542,7 +7728,7 @@ Item *Item_string::make_odbc_literal(THD *thd, const LEX_CSTRING *typestr) { Item_literal *res; const Type_handler *h; - if (collation.repertoire == MY_REPERTOIRE_ASCII && + if (collation.repertoire_is_subset_of(MY_REPERTOIRE_ASCII) && str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4 && (h= Type_handler::odbc_literal_type_handler(typestr)) && (res= h->create_literal_item(thd, val_str(NULL), false))) @@ -10745,6 +10931,7 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) set_field(tmp_field); // the index is important when read bits set tmp_field->field_index= field_arg->field->field_index; + tmp_field->vcol_info= field_arg->field->vcol_info; } } return FALSE; @@ -12454,10 +12641,16 @@ void Item_direct_ref_to_item::change_item(THD *thd, Item *i) bool Item::cleanup_excluding_immutables_processor (void *arg) { - if (!(get_extraction_flag() == MARKER_IMMUTABLE)) - return cleanup_processor(arg); - else + /* + basic_const_item() is also true for an Item_ref wrapping a constant, + e.g. a reference to a constant select list item of a merged derived + table. Such a ref is never marked with MARKER_IMMUTABLE, but the + function enclosing it is, so it is not cleaned up here, and + fix_fields() does not descend into items that are already fixed. + */ + if (basic_const_item() || get_extraction_flag() == MARKER_IMMUTABLE) return false; + return cleanup_processor(arg); } diff --git a/sql/item.h b/sql/item.h index b035cd11b30..618444b517c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1237,8 +1237,11 @@ public: { bool binary_cmp; /**< Make binary comparison */ bool omit_table_names; /**< Skip table and db names comparison */ - Eq_config(bool binary_cmp, bool omit_table_names= false) - : binary_cmp(binary_cmp), omit_table_names(omit_table_names) {} + bool unordered_conditions; /**< Ignore AND/OR operand order and duplicates */ + Eq_config(bool binary_cmp, bool omit_table_names= false, + bool unordered_conditions= false) + : binary_cmp(binary_cmp), omit_table_names(omit_table_names), + unordered_conditions(unordered_conditions) {} }; virtual bool eq(const Item *, const Eq_config &config) const; enum_field_types field_type() const @@ -2659,7 +2662,7 @@ public: not only numeric/datetime origin. */ if (collation.derivation == DERIVATION_NUMERIC && - collation.repertoire == MY_REPERTOIRE_ASCII && + collation.repertoire_is_subset_of(MY_REPERTOIRE_ASCII) && !(collation.collation->state & MY_CS_NONASCII) && !(tocs->state & MY_CS_NONASCII)) return false; @@ -4141,7 +4144,7 @@ public: max_length= 0; name.str= name_par ? name_par : "NULL"; name.length= strlen(name.str); - collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII); + collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_NONE); } Type type() const override { return NULL_ITEM; } bool vcol_assignment_allowed_value() const override { return true; } @@ -6138,6 +6141,7 @@ public: } LEX_CSTRING func_name_cstring(THD *thd, bool is_package_function) const; void cleanup(); + void free_call_ctx(); bool sp_check_access(THD *thd); bool execute(THD *thd, bool *null_value, Item **args, uint arg_count); bool execute_impl(THD *thd, Item **args, uint arg_count); @@ -8716,11 +8720,13 @@ bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str, int *escape); inline bool Virtual_column_info::is_equal(const Virtual_column_info* vcol, - bool omit_table_names) const + bool omit_table_names, + bool unordered_conditions) const { return type_handler() == vcol->type_handler() && is_stored() == vcol->is_stored() - && expr->eq(vcol->expr, {true, omit_table_names}); + && expr->eq(vcol->expr, + {true, omit_table_names, unordered_conditions}); } inline void Virtual_column_info::print(String* str) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1c42127ffcf..7b4883738b1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5739,6 +5739,80 @@ bool Item_cond::excl_dep_on_grouping_fields(st_select_lex *sel) } +/** + Compare two Item_cond expressions for equality. + + Distinct AND/OR items are normally not considered equal, preserving their + execution order. Some metadata comparisons can explicitly request a set + comparison because table definitions may be serialized with their + arguments reordered. + + @param item The other Item to compare with + @param config Comparison configuration + + @return true if expressions are equivalent, false otherwise +*/ +bool Item_cond::eq(const Item *item, const Eq_config &config) const +{ + if (this == item) + return true; + + if (!config.unordered_conditions) + return false; + + if (item->type() != COND_ITEM || (used_tables() & RAND_TABLE_BIT)) + return false; + + const Item_cond *item_cond= (const Item_cond *) item; + if (functype() != item_cond->functype()) + return false; + + /* + Treat the argument lists as sets. Checking both directions deliberately + ignores duplicate terms: A OR B and A OR B OR A are equivalent here. + */ + List_iterator_fast li1(const_cast&>(list)); + Item *arg1; + while ((arg1= li1++)) + { + bool found_match= false; + List_iterator_fast li2(const_cast&>(item_cond->list)); + Item *arg2; + while ((arg2= li2++)) + { + if (arg1->eq(arg2, config)) + { + found_match= true; + break; + } + } + if (!found_match) + return false; + } + + List_iterator_fast li2(const_cast&>(item_cond->list)); + Item *arg2; + while ((arg2= li2++)) + { + bool found_match= false; + List_iterator_fast li1(const_cast&>(list)); + Item *arg1; + while ((arg1= li1++)) + { + if (arg2->eq(arg1, config)) + { + found_match= true; + break; + } + } + if (!found_match) + return false; + } + + return true; +} + + void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding) { List_iterator li(list); @@ -7312,7 +7386,17 @@ void Item_equal::merge_into_list(THD *thd, List *list, if (!merge_into) { if (item->merge_with_check(thd, this, save_merged)) + { merge_into= item; + /* + If the caller doesn't set save_merged, then remove the items from the + source, which is 'this' object. That prevents an ASAN problem where + an item appearing in both lists has its memory deleted via one list + and then is later read via the other. + */ + if (!save_merged) + equal_items.empty(); + } } else { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index cf3418401f0..ba7aa8d5add 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -3452,6 +3452,7 @@ public: Item *deep_copy(THD *thd) const override; bool excl_dep_on_table(table_map tab_map) override; bool excl_dep_on_grouping_fields(st_select_lex *sel) override; + bool eq(const Item *item, const Eq_config &config) const override; private: void merge_sub_condition(List_iterator& li); diff --git a/sql/item_func.h b/sql/item_func.h index 173ffac6f3d..1ca0d991185 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -3960,6 +3960,7 @@ public: ft_handler= 0; concat_ws= 0; table= 0; // required by Item_func_match::eq() + master= 0; DBUG_VOID_RETURN; } bool is_expensive_processor(void *arg) override { return TRUE; } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 9ad628ee691..ed9a096f8be 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -2289,6 +2289,12 @@ bool Item_func_json_array::fix_length_and_dec(THD *thd) if (agg_arg_charsets_for_string_result(collation, args, arg_count)) return TRUE; + /* + The result also contains the hard-coded '[', ']', '{', '}', '"', ':', + ',' and ' ' (this is also used by JSON_OBJECT). + */ + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; + for (n_arg=0 ; n_arg < arg_count ; n_arg++) { ulonglong arg_length; @@ -4221,28 +4227,34 @@ bool Item_func_json_keys::fix_length_and_dec(THD *thd) static int check_key_in_list(String *res, const uchar *key, int key_len) { - const uchar *c= (const uchar *) res->ptr() + 2; /* beginning '["' */ - const uchar *end= (const uchar *) res->end() - 1; /* ending '"' */ + const uchar *c, *end; + + if (!res || res->length() < 2) + return 0; + + c= (const uchar *) res->ptr() + 1; + end= (const uchar *) res->end(); while (c < end) { - int n_char; - for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++) + while (c < end && *c != '"') + c++; + if (c >= end) + break; + c++; + + const uchar *key_start= c; + int n_char= 0; + while (c + n_char < end && c[n_char] != '"') { - if (c[n_char] != key[n_char]) - break; + n_char++; } - if (c[n_char] == '"') - { - if (n_char == key_len) - return 1; - } - else - { - while (c[n_char] != '"') - n_char++; - } - c+= n_char + 4; /* skip ', "' */ + + if (n_char == key_len && + (key_len == 0 || memcmp(key_start, key, key_len) == 0)) + return 1; + + c+= n_char + 1; } return 0; } @@ -4936,6 +4948,9 @@ Item_func_json_objectagg::fix_fields(THD *thd, Item **ref) if (agg_arg_charsets_for_string_result(collation, args, arg_count)) return 1; + /* The result also contains the hard-coded '{', '}', '"', ':', ',' and ' ' */ + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; + result.set_charset(collation.collation); result_field= 0; null_value= 1; @@ -5174,6 +5189,13 @@ bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value, MEM_ROOT *current_mem_root, json_engine_t *temp_je, MEM_ROOT_DYNAMIC_ARRAY *stack) { + /* + Remember the array levels for json_skip_to_level(): after ']' is + scanned, stack_p already points to the parent, where + json_skip_level() could incorrectly consume parent elements. + */ + const int js_level= json_get_level(js); + const int value_level= json_get_level(value); bool res= false; while (json_scan_next(js) == 0 && json_scan_next(value) == 0 && js->state == JST_VALUE && value->state == JST_VALUE) @@ -5182,19 +5204,21 @@ bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value, return FALSE; if (js->value_type != value->value_type) { - json_skip_current_level(js, value); + json_skip_to_level(js, js_level); + json_skip_to_level(value, value_level); return FALSE; } res= check_overlaps(js, value, true, current_mem_root, temp_je, stack); if (!res) { - json_skip_current_level(js, value); + json_skip_to_level(js, js_level); + json_skip_to_level(value, value_level); return FALSE; } } - res= (value->state == JST_ARRAY_END || value->state == JST_OBJ_END ? - TRUE : FALSE); - json_skip_current_level(js, value); + res= (js->state == JST_ARRAY_END && value->state == JST_ARRAY_END); + json_skip_to_level(js, js_level); + json_skip_to_level(value, value_level); return res; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5e324d238dd..fb8366434ec 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -809,10 +809,10 @@ bool Item_func_concat::realloc_result(String *str, uint length) const if (str->alloced_length() >= length) return false; // Alloced space is big enough, nothing to do. - if (str->alloced_length() == 0) - return str->alloc(length); - /* + A string with zero allocated capacity may still reference external data. + realloc() preserves that data, while alloc() would empty the string. + Item_func_concat::val_str() makes sure the result length does not grow higher than max_allowed_packet. So "length" is limited to 1G here. We can't say anything about the current value of str->alloced_length(), @@ -2057,6 +2057,7 @@ bool Item_func_lcase::fix_length_and_dec(THD *thd) return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->casedn_multiply(); + collation.fix_repertoire_for_case_conversion(); converter= collation.collation->cset->casedn; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); return FALSE; @@ -2068,6 +2069,7 @@ bool Item_func_ucase::fix_length_and_dec(THD *thd) return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->caseup_multiply(); + collation.fix_repertoire_for_case_conversion(); converter= collation.collation->cset->caseup; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); return FALSE; @@ -3381,6 +3383,10 @@ bool Item_func_make_set::fix_length_and_dec(THD *thd) if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) return TRUE; + /* The result also contains the hard-coded ',' separator between items. */ + if (arg_count > 2) + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; + for (uint i=1 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length(char_length); @@ -3747,6 +3753,8 @@ bool Item_func_pad::fix_length_and_dec(THD *thd) if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) return TRUE; default_pad_str(&pad_str, collation.collation); + /* The result also contains the default ' ' pad character. */ + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; } DBUG_ASSERT(collation.collation->mbmaxlen > 0); @@ -4122,7 +4130,8 @@ String *Item_func_set_collation::val_str(String *str) */ DBUG_ASSERT(my_charset_same(args[0]->collation.collation, collation.collation) || - (args[0]->collation.repertoire == MY_REPERTOIRE_ASCII && + (args[0]->collation. + repertoire_is_subset_of(MY_REPERTOIRE_ASCII) && !(collation.collation->state & MY_CS_NONASCII))); str->set_charset(collation.collation); return str; @@ -4598,6 +4607,11 @@ bool Item_func_export_set::fix_length_and_dec(THD *thd) if (agg_arg_charsets_for_string_result(collation, args + 1, MY_MIN(4, arg_count) - 1)) return TRUE; + + /* With no separator argument, the result contains the hard-coded ','. */ + if (arg_count < 4) + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; + fix_char_length(length * 64 + sep_length * 63); return FALSE; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index efc467fb022..4c44613f1ec 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1866,7 +1866,8 @@ public: bool fix_length_and_dec(THD *thd) override { m_arg0_type_handler= args[0]->type_handler(); - collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); + collation.set(default_charset(), DERIVATION_COERCIBLE, + MY_REPERTOIRE_ASCII_ALNUM); decimals=0; /* Reserve space for 16 characters for signed numeric data types: @@ -2075,6 +2076,11 @@ public: bool fix_length_and_dec(THD *thd) override { collation.set(args[0]->collation); + /* + The result also contains the quote characters and the backslash + escapes that QUOTE() adds around and inside the argument. + */ + collation.repertoire|= MY_REPERTOIRE_ASCII_NOT_IDENT; ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2 * collation.collation->mbmaxlen; // NULL argument is returned as a string "NULL" without quotes @@ -2124,17 +2130,15 @@ public: Conversion to Unicode is safe. Conversion from an expression with the ASCII repertoire to any character set that can store characters U+0000..U+007F - is safe: - - All supported multibyte character sets can store U+0000..U+007F - - All supported 7bit character sets can store U+0000..U+007F - except those marked with MY_CS_NONASCII (e.g. swe7). + (see CHARSET_INFO::is_ascii_superset()) is safe. Other kind of conversions are potentially lossy. */ safe= (args[0]->collation.collation == &my_charset_bin || cs == &my_charset_bin || (cs->state & MY_CS_UNICODE) || - (args[0]->collation.repertoire == MY_REPERTOIRE_ASCII && - (cs->mbmaxlen > 1 || !(cs->state & MY_CS_NONASCII)))); + (args[0]->collation. + repertoire_is_subset_of(MY_REPERTOIRE_ASCII) && + cs->is_ascii_superset())); } } String *val_str(String *) override; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d026b1f21aa..e706654939c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -5328,8 +5328,6 @@ bool subselect_hash_sj_engine::init(List *tmp_columns, uint subquery_id) if (!(name.str= (char*) thd->memdup(buf, name.length + 1))) DBUG_RETURN(TRUE); - result_sink->get_tmp_table_param()->materialized_subquery= true; - if (item->substype() == Item_subselect::IN_SUBS && (item->get_IN_subquery()->is_jtbm_merged)) { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index cc07a6de608..e72ad522ff7 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1456,10 +1456,7 @@ Item_sum_sp::add() void Item_sum_sp::clear() { - delete func_ctx; - func_ctx= NULL; - sp_query_arena->free_items(); - free_root(&sp_mem_root, MYF(0)); + free_call_ctx(); } const Type_handler *Item_sum_sp::type_handler() const @@ -4331,6 +4328,13 @@ Item_func_group_concat::fix_fields_impl(THD *thd, Item **ref) separator= new_separator; } + /* + The result contains not only the aggregated repertoire of the args, + but also every character of the separator. + */ + collation.repertoire|= my_string_repertoire(separator->charset(), + separator->ptr(), + separator->length()); return FALSE; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index f88c5a4a80e..6694c906180 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2340,6 +2340,7 @@ bool Item_func_date_format::fix_length_and_dec(THD *thd) { if (!is_time_format) { + locale= NULL; // Unknown yet, if the third argument is not a constant if (arg_count < 3) locale= thd->variables.lc_time_names; else if (args[2]->basic_const_item()) @@ -2355,7 +2356,14 @@ bool Item_func_date_format::fix_length_and_dec(THD *thd) decimals=0; CHARSET_INFO *cs= thd->variables.collation_connection; my_repertoire_t repertoire= arg1->collation.repertoire; - if (!thd->variables.lc_time_names->is_ascii) + /* + The result can contain locale specific names (e.g. of months and days). + Take the locale that is actually used. If the locale is passed + as a non-constant third argument, then it's not known at this point, + so assume that it can be a non-ASCII locale. + */ + if (is_time_format ? !thd->variables.lc_time_names->is_ascii : + (!locale || !locale->is_ascii)) repertoire|= MY_REPERTOIRE_EXTENDED; collation.set(cs, arg1->collation.derivation, repertoire); StringBuffer buffer; @@ -2408,7 +2416,10 @@ bool Item_func_date_format::eq(const Item *item, const Eq_config &config) const uint Item_func_date_format::format_length(const String *format) { - uint size=0; + /* A negative TIME value adds a leading minus sign. */ + uint size= (is_time_format || + args[0]->type_handler()->mysql_timestamp_type() == + MYSQL_TIMESTAMP_TIME) ? 1 : 0; const char *ptr=format->ptr(); const char *end=ptr+format->length(); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index e78796c684e..f1681d8dda1 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2791,7 +2791,13 @@ my_xpath_parse(MY_XPATH *xpath, const char *str, const char *strend) bool Item_xml_str_func::fix_length_and_dec(THD *thd) { max_length= MAX_BLOB_WIDTH; - return agg_arg_charsets_for_comparison(collation, args, arg_count); + /* + The result collation is chosen from the arguments, so + MY_COLL_ALLOW_BY_TAILORING is intentionally not passed here: + we cannot just pick the collation of one side for a string result. + */ + return agg_arg_charsets(collation, args, arg_count, + MY_COLL_CMP_CONV & ~MY_COLL_ALLOW_BY_TAILORING, 1); } diff --git a/sql/json_table.cc b/sql/json_table.cc index 25a67a5fc1b..49f78f22c8f 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -386,7 +386,7 @@ int ha_json_table::rnd_init(bool scan) /* @brief Store JSON value in an SQL field, doing necessary special conversions - for JSON's null, true, and false. + for JSON's null, true, false, and numeric values. */ static void store_json_in_field(Field *f, const json_engine_t *je) @@ -414,7 +414,10 @@ static void store_json_in_field(Field *f, const json_engine_t *je) break; }; st_append_json(&res_tmp, je->s.cs, je->value, je->value_len); - f->store((const char *) res_tmp.ptr(), (uint32) res_tmp.length(), je->s.cs); + if (je->value_type == JSON_VALUE_NUMBER) + f->store_numeric(res_tmp.ptr(), res_tmp.length(), je->s.cs); + else + f->store(res_tmp.ptr(), res_tmp.length(), je->s.cs); } diff --git a/sql/lex_ident_cli.h b/sql/lex_ident_cli.h index cba5086d0c8..5d25489bcaf 100644 --- a/sql/lex_ident_cli.h +++ b/sql/lex_ident_cli.h @@ -64,13 +64,28 @@ public: bool is_8bit() const { return m_is_8bit; } bool is_quoted() const { return m_quote != '\0'; } char quote() const { return m_quote; } - // Get string repertoire by the 8-bit flag and the character set + /* + Get the string repertoire. If the string is not 8-bit, then the string + is scanned to detect its actual repertoire (e.g. ASCII_ALNUM). + Otherwise, the full repertoire is returned. + "cs" is the client character set, which is always byte oriented + (mbminlen==1). The scan is done by Unicode code points, so it works + correctly for character sets which are not ASCII compatible, e.g. swe7: + a byte like 0x5B is LATIN CAPITAL LETTER A WITH DIAERESIS, + so it is not ASCII. + */ my_repertoire_t repertoire(CHARSET_INFO *cs) const { - return !m_is_8bit && my_charset_is_ascii_based(cs) ? - MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; + DBUG_ASSERT(cs->mbminlen == 1); + return !m_is_8bit ? my_string_repertoire(cs, str, length) : + MY_REPERTOIRE_UNICODE30; } - // Get string repertoire by the 8-bit flag, for ASCII-based character sets + + /* + Get the string repertoire by the 8-bit flag only, for ASCII-based + character sets, without scanning the string: + either the coarse MY_REPERTOIRE_ASCII or the full repertoire. + */ my_repertoire_t repertoire() const { return !m_is_8bit ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; diff --git a/sql/log.cc b/sql/log.cc index bad2e573a82..8926f6b1ba7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4509,15 +4509,15 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, Create an index file that will hold all file names uses for logging. Add new entries to the end of it. */ - myf opt= MY_UNPACK_FILENAME; + myf opt= MY_UNPACK_FILENAME | MY_SAFE_PATH; if (!index_file_name_arg) { index_file_name_arg= log_name; // Use same basename for index file - opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT; + opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_SAFE_PATH; } - fn_format(index_file_name, index_file_name_arg, mysql_data_home, - ".index", opt); - if ((index_file_nr= mysql_file_open(m_key_file_log_index, + if (!fn_format(index_file_name, index_file_name_arg, mysql_data_home, + ".index", opt) || + (index_file_nr= mysql_file_open(m_key_file_log_index, index_file_name, O_RDWR | O_CREAT | O_BINARY | O_CLOEXEC, MYF(MY_WME))) < 0 || @@ -6563,6 +6563,16 @@ MYSQL_BIN_LOG::engine_purge_logs_by_size(ulonglong max_total_size) } +/* + Three parameter state object describes the exclusive rhs of the + purgeable range (left is the past). The state modification is + guarded by LOCK_index. +*/ +static bool waiting_for_slave_to_change_binlog= 0; +static ulonglong purge_sending_new_binlog_file= 0; +static char purge_binlog_name[FN_REFLEN]; +static bool purge_warning_given= 0; + /* @param log_file_name_arg Name of log file to check @param interactive True if called by a PURGE BINLOG command. @@ -6580,12 +6590,6 @@ MYSQL_BIN_LOG::engine_purge_logs_by_size(ulonglong max_total_size) sending_new_binlog_file, cached in purge_sending_new_binlog_file, is incremented every time a slave changes to use a new binary log. */ - -static bool waiting_for_slave_to_change_binlog= 0; -static ulonglong purge_sending_new_binlog_file= 0; -static char purge_binlog_name[FN_REFLEN]; -static bool purge_warning_given= 0; - bool MYSQL_BIN_LOG::can_purge_log(const char *log_file_name_arg, bool interactive) @@ -6594,14 +6598,26 @@ MYSQL_BIN_LOG::can_purge_log(const char *log_file_name_arg, const char *reason; DBUG_ASSERT(is_relay_log || !opt_binlog_engine_hton); - if (is_active(log_file_name_arg) || - (!is_relay_log && waiting_for_slave_to_change_binlog && - purge_sending_new_binlog_file == sending_new_binlog_file && - !strcmp(log_file_name_arg, purge_binlog_name))) + mysql_mutex_assert_owner(&LOCK_index); + + if (is_active(log_file_name_arg)) { reason= "it is the current active binlog"; goto error; } + /* + If purge_sending_new_binlog_file == sending_new_binlog_file then + no dump thread has changed the state since we last computed it, + and we can re-use that state for the check. + */ + if (!interactive && !is_relay_log && waiting_for_slave_to_change_binlog && + purge_sending_new_binlog_file == sending_new_binlog_file && + !strcmp(log_file_name_arg, purge_binlog_name)) + { + reason= "it is in use by a slave thread or less than " + "'slave_connections_needed_for_purge' slaves have processed it"; + goto error; + } DBUG_ASSERT(!is_relay_log || binlog_xid_count_list.is_empty()); if (!is_relay_log) @@ -8570,7 +8586,6 @@ binlog_recover_gtid_state(rpl_binlog_state_base *state, handler_binlog_reader *reader) { String packet; - Format_description_log_event fd_event(4); if (reader) { @@ -8590,8 +8605,7 @@ binlog_recover_gtid_state(rpl_binlog_state_base *state, uchar flags2; if (Gtid_log_event::peek((uchar*) packet.ptr(), packet.length(), BINLOG_CHECKSUM_ALG_OFF, >id.domain_id, - >id.server_id, >id.seq_no, &flags2, - &fd_event)) + >id.server_id, >id.seq_no, &flags2)) return true; state->update_nolock(>id); } diff --git a/sql/log_event.cc b/sql/log_event.cc index 4042c80ca37..8d0f71f83d7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -239,7 +239,9 @@ private: static inline bool read_str(const uchar **buf, const uchar *buf_end, const char **str, uint8 *len) { - if (*buf + ((uint) **buf) >= buf_end) + if (unlikely(*buf >= buf_end)) + return 1; + if ((uint) **buf >= buf_end - *buf) return 1; *len= (uint8) **buf; *str= (char*) (*buf)+1; @@ -333,8 +335,8 @@ int binlog_buf_compress(const uchar *src, uchar *dst, uint32 len, uint32 *comlen } /* - Write the length of an event no replica can uncompress, so that a - replica's handling of one can be tested. Reaching a value this large + Write the length of an event no slave can uncompress, so that a + slave's handling of one can be tested. Reaching a value this large takes four length bytes, and the encoding above spends four only on content of 16MB or more, so the injection sets the encoding as well as the value. The compressed content still goes where those four @@ -376,8 +378,7 @@ int binlog_buf_compress(const uchar *src, uchar *dst, uint32 len, uint32 *comlen */ int -query_event_uncompress(const Format_description_log_event *description_event, - bool contain_checksum, const uchar *src, ulong src_len, +query_event_uncompress(bool contain_checksum, const uchar *src, ulong src_len, uchar* buf, ulong buf_size, bool* is_malloc, uchar **dst, ulong *newlen) { @@ -392,9 +393,8 @@ query_event_uncompress(const Format_description_log_event *description_event, DBUG_ASSERT((uchar)src[EVENT_TYPE_OFFSET] == QUERY_COMPRESSED_EVENT); - uint8 common_header_len= description_event->common_header_len; - uint8 post_header_len= - description_event->post_header_len[QUERY_COMPRESSED_EVENT-1]; + uint8 common_header_len= Format_description_log_event::common_header_len; + uint8 post_header_len= QUERY_HEADER_LEN; *is_malloc= false; @@ -413,7 +413,7 @@ query_event_uncompress(const Format_description_log_event *description_event, int32 comp_len= (int32)(len - (tmp - src) - (contain_checksum ? BINLOG_CHECKSUM_LEN : 0)); - uint32 un_len= binlog_get_uncompress_len(tmp); + uint32 un_len= binlog_get_uncompress_len(tmp, comp_len); // bad event if (unlikely(comp_len < 0 || un_len == 0)) @@ -463,11 +463,12 @@ query_event_uncompress(const Format_description_log_event *description_event, } int -row_log_event_uncompress(const Format_description_log_event *description_event, - bool contain_checksum, const uchar *src, ulong src_len, +row_log_event_uncompress(bool contain_checksum, const uchar *src, ulong src_len, uchar* buf, ulong buf_size, bool* is_malloc, uchar **dst, ulong *newlen) { + if (unlikely(src_len < LOG_EVENT_MINIMAL_HEADER_LEN)) + return ER_BINLOG_UNCOMPRESS_ERROR; Log_event_type type= (Log_event_type)(uchar)src[EVENT_TYPE_OFFSET]; ulong len= uint4korr(src + EVENT_LEN_OFFSET); const uchar *tmp= src; @@ -478,12 +479,20 @@ row_log_event_uncompress(const Format_description_log_event *description_event, return ER_BINLOG_UNCOMPRESS_ERROR; DBUG_ASSERT(LOG_EVENT_IS_ROW_COMPRESSED(type)); + DBUG_ASSERT(type == WRITE_ROWS_COMPRESSED_EVENT_V1 || + type == UPDATE_ROWS_COMPRESSED_EVENT_V1 || + type == DELETE_ROWS_COMPRESSED_EVENT_V1 || + type == WRITE_ROWS_COMPRESSED_EVENT || + type == UPDATE_ROWS_COMPRESSED_EVENT || + type == DELETE_ROWS_COMPRESSED_EVENT); + DBUG_ASSERT(WRITE_ROWS_COMPRESSED_EVENT_V1 < WRITE_ROWS_COMPRESSED_EVENT); - uint8 common_header_len= description_event->common_header_len; - uint8 post_header_len= description_event->post_header_len[type-1]; + uint8 common_header_len= Format_description_log_event::common_header_len; - tmp+= common_header_len + ROWS_HEADER_LEN_V1; - if (post_header_len == ROWS_HEADER_LEN_V2) + if (unlikely(len <= (ulong)common_header_len + ROWS_HEADER_LEN_V1 /* 8 */)) + return ER_BINLOG_UNCOMPRESS_ERROR; + tmp+= common_header_len + ROWS_HEADER_LEN_V1 /* 8 */; + if (type > DELETE_ROWS_COMPRESSED_EVENT_V1) { /* Have variable length header, check length, @@ -495,6 +504,8 @@ row_log_event_uncompress(const Format_description_log_event *description_event, uint16 var_header_len= uint2korr(tmp); DBUG_ASSERT(var_header_len >= 2); + if (unlikely(var_header_len < 2 || var_header_len > end - tmp)) + return ER_BINLOG_UNCOMPRESS_ERROR; /* skip over var-len header, extracting 'chunks' */ tmp+= var_header_len; @@ -510,21 +521,24 @@ row_log_event_uncompress(const Format_description_log_event *description_event, (type - WRITE_ROWS_COMPRESSED_EVENT_V1 + WRITE_ROWS_EVENT_V1); } - if (unlikely(end <= tmp)) + ulong width= (ulong)safe_net_field_length_ll((uchar **)&tmp, end - tmp); + if (unlikely(!tmp || width > src_len /* overflow guard */)) return ER_BINLOG_UNCOMPRESS_ERROR; - - ulong m_width= net_field_length((uchar **)&tmp); - tmp+= (m_width + 7) / 8; - + size_t bm_size= (width + 7) / 8; if (type == UPDATE_ROWS_EVENT_V1 || type == UPDATE_ROWS_EVENT) { - tmp+= (m_width + 7) / 8; + if (unlikely(2*bm_size >= (size_t)(end - tmp))) + return ER_BINLOG_UNCOMPRESS_ERROR; + tmp+= 2*bm_size; + } + else + { + if (unlikely(bm_size >= (size_t)(end - tmp))) + return ER_BINLOG_UNCOMPRESS_ERROR; + tmp+= bm_size; } - if (unlikely(end <= tmp)) - return ER_BINLOG_UNCOMPRESS_ERROR; - - uint32 un_len= binlog_get_uncompress_len(tmp); + uint32 un_len= binlog_get_uncompress_len(tmp, end - tmp); if (unlikely(un_len == 0)) return ER_BINLOG_UNCOMPRESS_ERROR; @@ -583,10 +597,12 @@ row_log_event_uncompress(const Format_description_log_event *description_event, return 0 means error. */ -uint32 binlog_get_uncompress_len(const uchar *buf) +uint32 binlog_get_uncompress_len(const uchar *buf, size_t buf_len) { uint32 len, lenlen; + if (unlikely(buf_len < 2)) + return 0; if ((buf == NULL) || ((buf[0] & 0xe0) != 0x80)) return 0; @@ -599,13 +615,22 @@ uint32 binlog_get_uncompress_len(const uchar *buf) len= buf[0]; break; case 2: - len= mi_uint2korr(buf); + if (unlikely(buf_len < 3)) + len= 0; + else + len= mi_uint2korr(buf); break; case 3: - len= mi_uint3korr(buf); + if (unlikely(buf_len < 4)) + len= 0; + else + len= mi_uint3korr(buf); break; case 4: - len= mi_uint4korr(buf); + if (unlikely(buf_len < 5)) + len= 0; + else + len= mi_uint4korr(buf); break; default: DBUG_ASSERT(lenlen >= 1 && lenlen <= 4); @@ -629,10 +654,14 @@ uint32 binlog_get_uncompress_len(const uchar *buf) int binlog_buf_uncompress(const uchar *src, uchar *dst, uint32 len, uint32 *newlen) { + if (unlikely(len < 1)) + return 1; if ((src[0] & 0x80) == 0) return 1; uint32 lenlen= src[0] & 0x07; + if (unlikely(1 + lenlen > len)) + return 1; uLongf buflen= *newlen; // zlib type uint32 alg= (src[0] & 0x70) >> 4; @@ -738,8 +767,7 @@ const char* Log_event::get_type_str() Log_event::Log_event() */ -Log_event::Log_event(const uchar *buf, - const Format_description_log_event* description_event) +Log_event::Log_event(const uchar *buf, size_t event_len) :temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE) #ifndef MYSQL_CLIENT , slave_exec_mode(SLAVE_EXEC_MODE_STRICT) @@ -748,8 +776,21 @@ Log_event::Log_event(const uchar *buf, #ifndef MYSQL_CLIENT thd= 0; #endif - when= uint4korr(buf); when_sec_part= ~0UL; + if (unlikely(event_len < LOG_EVENT_HEADER_LEN)) + { + /* + Sanity check - read_log_event() checks this already, but avoid reading + outside of buffer if some other caller forgot the check. + */ + when= 0; + server_id= 0; + data_written= 0; + log_pos= 0; + flags= 0; + return; + } + when= uint4korr(buf); server_id= uint4korr(buf + SERVER_ID_OFFSET); data_written= uint4korr(buf + EVENT_LEN_OFFSET); log_pos= uint4korr(buf + LOG_POS_OFFSET); @@ -1018,7 +1059,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, size_t event_len, Check the integrity; This is needed because handle_slave_io() doesn't check if packet is of proper length. */ - if (event_len < EVENT_LEN_OFFSET) + if (event_len < LOG_EVENT_HEADER_LEN) { *error="Sanity check failed"; // Needed to free buffer DBUG_RETURN(NULL); // general sanity check - will fail on a partial read @@ -1034,7 +1075,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, size_t event_len, if (force_opt) { event_len-= BINLOG_CHECKSUM_LEN; - ev= new Unknown_log_event(buf, fdle); + ev= new Unknown_log_event(buf, event_len); goto exit; } #endif @@ -1084,7 +1125,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, size_t event_len, if (force_opt) { event_len-= BINLOG_CHECKSUM_LEN; - ev= new Unknown_log_event(buf, fdle); + ev= new Unknown_log_event(buf, event_len); goto exit; } *error= "Event crc check failed! Most likely there is event corruption."; @@ -1096,40 +1137,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, size_t event_len, DBUG_RETURN(NULL); } - if (event_type > fdle->number_of_event_types && - event_type != FORMAT_DESCRIPTION_EVENT) { - /* - It is unsafe to use the fdle if its post_header_len - array does not include the event type. - */ - DBUG_PRINT("error", ("event type %d found, but the current " - "Format_description_log_event supports only %d event " - "types", event_type, - fdle->number_of_event_types)); - ev= NULL; - } - else - { - /* - In some previuos versions (see comment in - Format_description_log_event::Format_description_log_event(char*,...)), - event types were assigned different id numbers than in the - present version. In order to replicate from such versions to the - present version, we must map those event type id's to our event - type id's. The mapping is done with the event_type_permutation - array, which was set up when the Format_description_log_event - was read. - */ - if (fdle->event_type_permutation) - { - int new_event_type= fdle->event_type_permutation[event_type]; - DBUG_PRINT("info", ("converting event type %d to %d (%s)", - event_type, new_event_type, - get_type_str((Log_event_type)new_event_type))); - event_type= new_event_type; - } - if (alg != BINLOG_CHECKSUM_ALG_UNDEF && (event_type == FORMAT_DESCRIPTION_EVENT || alg != BINLOG_CHECKSUM_ALG_OFF)) @@ -1174,26 +1182,6 @@ Log_event *Log_event::read_log_event_no_checksum( uint event_type= buf[EVENT_TYPE_OFFSET]; - /* - In some previuos versions (see comment in - Format_description_log_event::Format_description_log_event(char*,...)), - event types were assigned different id numbers than in the - present version. In order to replicate from such versions to the - present version, we must map those event type id's to our event - type id's. The mapping is done with the event_type_permutation - array, which was set up when the Format_description_log_event - was read. - */ - if (fdle->event_type_permutation) - { - int new_event_type= fdle->event_type_permutation[event_type]; - DBUG_PRINT("info", ("converting event type %d to %d (%s)", - event_type, new_event_type, - get_type_str((Log_event_type)new_event_type))); - event_type= new_event_type; - } - - /* Create an object of Ignorable_log_event for unrecognized sub-class. So that SLAVE SQL THREAD will only update the position and continue. @@ -1203,95 +1191,92 @@ Log_event *Log_event::read_log_event_no_checksum( */ if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) { - ev= new Ignorable_log_event(buf, fdle, + ev= new Ignorable_log_event(buf, event_len, (Log_event_type)event_type, get_type_str((Log_event_type) event_type)); goto exit; } switch(event_type) { case QUERY_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Query_log_event(buf, static_cast(event_len), fdle, - QUERY_EVENT); + ev= new Query_log_event(buf, event_len, fdle, QUERY_EVENT); break; case QUERY_COMPRESSED_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Query_compressed_log_event(buf, static_cast(event_len), + ev= new Query_compressed_log_event(buf, event_len, fdle, QUERY_COMPRESSED_EVENT); break; case ROTATE_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Rotate_log_event(buf, static_cast(event_len), fdle); + ev= new Rotate_log_event(buf, event_len); break; case BINLOG_CHECKPOINT_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Binlog_checkpoint_log_event(buf, static_cast(event_len), - fdle); + ev= new Binlog_checkpoint_log_event(buf, event_len); break; case GTID_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Gtid_log_event(buf, static_cast(event_len), fdle); + ev= new Gtid_log_event(buf, event_len); break; case GTID_LIST_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Gtid_list_log_event(buf, static_cast(event_len), fdle); + ev= new Gtid_list_log_event(buf, event_len); break; case APPEND_BLOCK_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Append_block_log_event(buf, static_cast(event_len), fdle); + ev= new Append_block_log_event(buf, event_len); break; case DELETE_FILE_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Delete_file_log_event(buf, static_cast(event_len), fdle); + ev= new Delete_file_log_event(buf, event_len); break; case STOP_EVENT: - ev= new Stop_log_event(buf, fdle); + ev= new Stop_log_event(buf, event_len); break; case INTVAR_EVENT: - ev= new Intvar_log_event(buf, fdle); + ev= new Intvar_log_event(buf, event_len); break; case XID_EVENT: - ev= new Xid_log_event(buf, fdle); + ev= new Xid_log_event(buf, event_len); break; case XA_PREPARE_LOG_EVENT: - ev= new XA_prepare_log_event(buf, fdle); + ev= new XA_prepare_log_event(buf, event_len); break; case RAND_EVENT: - ev= new Rand_log_event(buf, fdle); + ev= new Rand_log_event(buf, event_len); break; case USER_VAR_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new User_var_log_event(buf, static_cast(event_len), fdle); + ev= new User_var_log_event(buf, event_len); break; case FORMAT_DESCRIPTION_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Format_description_log_event(buf, static_cast(event_len), - fdle); + ev= new Format_description_log_event(buf, event_len); break; #if defined(HAVE_REPLICATION) case WRITE_ROWS_EVENT_V1: case WRITE_ROWS_EVENT: - ev= new Write_rows_log_event(buf, event_len, fdle); + ev= new Write_rows_log_event(buf, event_len); break; case UPDATE_ROWS_EVENT_V1: case UPDATE_ROWS_EVENT: - ev= new Update_rows_log_event(buf, event_len, fdle); + ev= new Update_rows_log_event(buf, event_len); break; case DELETE_ROWS_EVENT_V1: case DELETE_ROWS_EVENT: - ev= new Delete_rows_log_event(buf, event_len, fdle); + ev= new Delete_rows_log_event(buf, event_len); break; case WRITE_ROWS_COMPRESSED_EVENT: case WRITE_ROWS_COMPRESSED_EVENT_V1: - ev= new Write_rows_compressed_log_event(buf, event_len, fdle); + ev= new Write_rows_compressed_log_event(buf, event_len); break; case UPDATE_ROWS_COMPRESSED_EVENT: case UPDATE_ROWS_COMPRESSED_EVENT_V1: - ev= new Update_rows_compressed_log_event(buf, event_len, fdle); + ev= new Update_rows_compressed_log_event(buf, event_len); break; case DELETE_ROWS_COMPRESSED_EVENT: case DELETE_ROWS_COMPRESSED_EVENT_V1: - ev= new Delete_rows_compressed_log_event(buf, event_len, fdle); + ev= new Delete_rows_compressed_log_event(buf, event_len); break; /* MySQL GTID events are ignored */ @@ -1301,41 +1286,38 @@ Log_event *Log_event::read_log_event_no_checksum( case TRANSACTION_CONTEXT_EVENT: case HEARTBEAT_LOG_EVENT_V2: // MySQL 8.0 case VIEW_CHANGE_EVENT: - ev= new Ignorable_log_event(buf, fdle, + ev= new Ignorable_log_event(buf, event_len, (Log_event_type)event_type, get_type_str((Log_event_type) event_type)); break; case TABLE_MAP_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Table_map_log_event(buf, static_cast(event_len), fdle); + ev= new Table_map_log_event(buf, event_len); break; #endif case PARTIAL_ROW_DATA_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Partial_rows_log_event(buf, static_cast(event_len), fdle); + ev= new Partial_rows_log_event(buf, event_len); break; case BEGIN_LOAD_QUERY_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Begin_load_query_log_event(buf, static_cast(event_len), - fdle); + ev= new Begin_load_query_log_event(buf, event_len); break; case EXECUTE_LOAD_QUERY_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Execute_load_query_log_event(buf, static_cast(event_len), - fdle); + ev= new Execute_load_query_log_event(buf, event_len, fdle); break; case INCIDENT_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Incident_log_event(buf, static_cast(event_len), fdle); + ev= new Incident_log_event(buf, event_len); break; case ANNOTATE_ROWS_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Annotate_rows_log_event(buf, static_cast(event_len), fdle); + ev= new Annotate_rows_log_event(buf, event_len); break; case START_ENCRYPTION_EVENT: DBUG_ASSERT(event_len <= UINT32_MAX); - ev= new Start_encryption_log_event(buf, static_cast(event_len), - fdle); + ev= new Start_encryption_log_event(buf, event_len); break; case TRANSACTION_PAYLOAD_EVENT: // MySQL 8.0 *error= @@ -1379,7 +1361,6 @@ exit: my_malloc() fail we can't return an error out of the constructor (because constructor is "void") ; so instead we leave the pointer we wanted to allocate (e.g. 'query') to 0 and we test it in is_valid(). - Same for Format_description_log_event, member 'post_header_len'. SLAVE_EVENT is never used, so it should not be read ever. */ @@ -1395,7 +1376,7 @@ exit: *error= "Found invalid event in binary log"; DBUG_RETURN(0); } - ev= new Unknown_log_event(buf, fdle); + ev= new Unknown_log_event(buf, event_len); #else if (!*error) *error= "Found invalid event in binary log"; @@ -1556,16 +1537,15 @@ code_name(int code) } #endif -#define VALIDATE_BYTES_READ(CUR_POS, START, EVENT_LEN) \ - do { \ - uchar *cur_pos= (uchar *)CUR_POS; \ - uchar *start= (uchar *)START; \ - uint len= EVENT_LEN; \ - uint bytes_read= (uint)(cur_pos - start); \ - DBUG_PRINT("info", ("Bytes read: %u event_len:%u.\n",\ - bytes_read, len)); \ - if (bytes_read >= len) \ - DBUG_VOID_RETURN; \ +#define VALIDATE_BYTES_READ(CUR_POS, BYTES, START, EVENT_LEN) \ + do { \ + const uchar *cur_pos= (uchar *)CUR_POS; \ + const size_t bytes= (size_t)BYTES; \ + const uchar *start= (uchar *)START; \ + const size_t len= EVENT_LEN; \ + size_t bytes_avail= len - (cur_pos - start); \ + if (unlikely(bytes > bytes_avail)) \ + DBUG_VOID_RETURN; \ } while (0) /** @@ -1578,7 +1558,7 @@ code_name(int code) #define CHECK_SPACE(PTR,END,CNT) \ do { \ DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \ - if ((PTR) + (CNT) > (END)) { \ + if (unlikely((PTR) + (CNT) > (END))) { \ DBUG_PRINT("info", ("query= 0")); \ query= 0; \ DBUG_VOID_RETURN; \ @@ -1589,11 +1569,11 @@ code_name(int code) /** This is used by the SQL slave thread to prepare the event before execution. */ -Query_log_event::Query_log_event(const uchar *buf, uint event_len, +Query_log_event::Query_log_event(const uchar *buf, size_t event_len, const Format_description_log_event *description_event, Log_event_type event_type) - :Log_event(buf, description_event), data_buf(0), query(NullS), +:Log_event(buf, event_len), data_buf(0), query(NullS), db(NullS), catalog_len(0), status_vars_len(0), flags2_inited(0), sql_mode_inited(0), charset_inited(0), character_set_collations({0,0}), flags2(0), @@ -1602,7 +1582,7 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, table_map_for_update(0), xid(0), gtid_flags_extra(0), sa_seq_no(0) { - ulong data_len; + size_t data_len; uint8 common_header_len, post_header_len; Log_event::Byte *start; const Log_event::Byte *end; @@ -1611,17 +1591,22 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, memset(&user, 0, sizeof(user)); memset(&host, 0, sizeof(host)); - common_header_len= description_event->common_header_len; - post_header_len= description_event->post_header_len[event_type-1]; - DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", - event_len, common_header_len, post_header_len)); + common_header_len= Format_description_log_event::common_header_len; + DBUG_ASSERT(event_type == QUERY_EVENT || + event_type == QUERY_COMPRESSED_EVENT || + event_type == EXECUTE_LOAD_QUERY_EVENT); + post_header_len= event_type == EXECUTE_LOAD_QUERY_EVENT ? + EXECUTE_LOAD_QUERY_HEADER_LEN : QUERY_HEADER_LEN; + DBUG_PRINT("info", + ("event_len: %zu common_header_len: %d post_header_len: %d", + event_len, common_header_len, post_header_len)); /* We test if the event's length is sensible, and if so we compute data_len. We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant. We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0. */ - if (event_len < (uint)(common_header_len + post_header_len)) + if (event_len < (size_t)(common_header_len + post_header_len)) DBUG_VOID_RETURN; data_len= event_len - (common_header_len + post_header_len); buf+= common_header_len; @@ -1632,15 +1617,20 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, error_code = uint2korr(buf + Q_ERR_CODE_OFFSET); status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET); + /* + Just a sanity check that we didn't typo some of all these _OFFSET + constants. + */ + DBUG_ASSERT(Q_STATUS_VARS_LEN_OFFSET + 2 == QUERY_HEADER_LEN); /* Check if status variable length is corrupt and will lead to very wrong data. We could be even more strict and require data_len to be even bigger, but this will suffice to catch most corruption errors that can lead to a crash. */ - if (status_vars_len > MY_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS)) + if (unlikely(status_vars_len > MY_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))) { - DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0", + DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%zu); query= 0", status_vars_len, data_len)); query= 0; DBUG_VOID_RETURN; @@ -1654,7 +1644,7 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, dedicated to derived events (e.g. Execute_load_query...) */ - /* variable-part: the status vars; only in MySQL 5.0 */ + /* variable-part: the status vars. */ start= (Log_event::Byte*) (buf+post_header_len); end= (const Log_event::Byte*) (start+status_vars_len); @@ -1706,6 +1696,12 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, const uchar *pos0= pos; CHECK_SPACE(pos, end, 1); uint16 count= *pos++; + if (unlikely((size_t)(1 + count*4) > + Charset_collation_map_st::binary_size_max())) + { + query= 0; + DBUG_VOID_RETURN; + } CHECK_SPACE(pos, end, count * 4); pos+= count * 4; character_set_collations= Lex_cstring((const char *) pos0, @@ -1922,26 +1918,15 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, start[data_len]= '\0'; // End query with \0 (For safetly) db= (char *)start; query= (char *)(start + db_len + 1); - q_len= data_len - db_len -1; + q_len= (uint32_t)(data_len - db_len -1); - if (data_len && (data_len < db_len || - data_len < q_len || - data_len != (db_len + q_len + 1))) + if (unlikely(data_len < db_len + 1)) { q_len= 0; query= NULL; DBUG_VOID_RETURN; } - uint32 max_length= uint32(event_len - ((end + db_len + 1) - - (buf - common_header_len))); - if (q_len != max_length || - (event_len < uint((end + db_len + 1) - (buf - common_header_len)))) - { - q_len= 0; - query= NULL; - DBUG_VOID_RETURN; - } /** Append the db length at the end of the buffer. This will be used by Query_cache::send_result_to_client() in case the query cache is On. @@ -1964,30 +1949,29 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, #endif time_t -query_event_get_end_time(const uchar *buf, - const Format_description_log_event *description_event) +query_event_get_end_time(const uchar *buf) { time_t when; DBUG_ASSERT(LOG_EVENT_IS_QUERY((Log_event_type) buf[EVENT_TYPE_OFFSET]) || LOG_EVENT_IS_LOAD_DATA((Log_event_type) buf[EVENT_TYPE_OFFSET])); when= uint4korr(buf); - buf+= description_event->common_header_len; + buf+= Format_description_log_event::common_header_len; return when + uint4korr(buf + Q_EXEC_TIME_OFFSET); } Query_compressed_log_event::Query_compressed_log_event(const uchar *buf, - uint event_len, - const Format_description_log_event - *description_event, + size_t event_len, + const Format_description_log_event *description_event, Log_event_type event_type) :Query_log_event(buf, event_len, description_event, event_type), query_buf(NULL) { if (query) { - uint32 un_len= binlog_get_uncompress_len((uchar*) query); - if (unlikely(!un_len || un_len > MAX_MAX_ALLOWED_PACKET)) + uint32 un_len= binlog_get_uncompress_len((uchar*) query, q_len); + if (unlikely(!un_len || + un_len >= 0xfffffff8 /* Protect against overflow below */)) { query= 0; return; @@ -2184,6 +2168,77 @@ Query_log_event::begin_event(String *packet, ulong ev_offset, Format_description_log_event methods ****************************************************************************/ +uint8 Format_description_log_event::byte_data_for_post_header_len[256]= { + START_V3_HEADER_LEN, // START_EVENT_V3 + QUERY_HEADER_LEN, + STOP_HEADER_LEN, + ROTATE_HEADER_LEN, + INTVAR_HEADER_LEN, + LOAD_HEADER_LEN, + SLAVE_HEADER_LEN, + CREATE_FILE_HEADER_LEN, + APPEND_BLOCK_HEADER_LEN, + EXEC_LOAD_HEADER_LEN, + DELETE_FILE_HEADER_LEN, + NEW_LOAD_HEADER_LEN, + RAND_HEADER_LEN, + USER_VAR_HEADER_LEN, + FORMAT_DESCRIPTION_HEADER_LEN, + XID_HEADER_LEN, + BEGIN_LOAD_QUERY_HEADER_LEN, + EXECUTE_LOAD_QUERY_HEADER_LEN, + TABLE_MAP_HEADER_LEN, + 0, 0, 0, // PRE_GA_{WRITE,UPDATE,DELETE}_ROWS_EVENT + ROWS_HEADER_LEN_V1, // WRITE_ROWS_EVENT_V1 + ROWS_HEADER_LEN_V1, // UPDATE_ROWS_EVENT_V1 + ROWS_HEADER_LEN_V1, // DELETE_ROWS_EVENT_V1 + INCIDENT_HEADER_LEN, + 0, // HEARTBEAT_LOG_EVENT + 0, // IGNORABLE_LOG_EVENT + 0, // ROWS_QUERY_LOG_EVENT + ROWS_HEADER_LEN_V2, // WRITE_ROWS_EVENT + ROWS_HEADER_LEN_V2, // UPDATE_ROWS_EVENT + WRITE_ROWS_EVENT, // DELETE_ROWS_EVENT + 0, // GTID_LOG_EVENT + 0, // ANONYMOUS_GTID_LOG_EVENT + 0, // PREVIOUS_GTIDS_LOG_EVENT + 0, // TRANSACTION_CONTEXT_EVENT + 0, // VIEW_CHANGE_EVENT + 0, // XA_PREPARE_LOG_EVENT + ROWS_HEADER_LEN_V2, // PARTIAL_UPDATE_ROWS_EVENT + ROWS_HEADER_LEN_V2, // TRANSACTION_PAYLOAD_EVENT + ROWS_HEADER_LEN_V2, // HEARTBEAT_LOG_EVENT_V2 + /* + HEARTBEAT_LOG_EVENT_V2=41, fill up with zeros until MARIA_EVENTS_BEGIN=160. + */ + 0, 0, 0, 0, 0, 0, 0, 0, // 42-49 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-59 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150-159 + /* Continue with MariaDB-specific events from ANNOTATE_ROWS_EVENT=160. */ + ANNOTATE_ROWS_HEADER_LEN, + BINLOG_CHECKPOINT_HEADER_LEN, + GTID_HEADER_LEN, + GTID_LIST_HEADER_LEN, + START_ENCRYPTION_HEADER_LEN, + QUERY_HEADER_LEN, // QUERY_COMPRESSED_EVENT + ROWS_HEADER_LEN_V1, // WRITE_ROWS_COMPRESSED_EVENT_V1 + ROWS_HEADER_LEN_V1, // UPDATE_ROWS_COMPRESSED_EVENT_V1 + ROWS_HEADER_LEN_V1, // DELETE_ROWS_COMPRESSED_EVENT_V1 + ROWS_HEADER_LEN_V2, // WRITE_ROWS_COMPRESSED_EVENT + ROWS_HEADER_LEN_V2, // UPDATE_ROWS_COMPRESSED_EVENT + ROWS_HEADER_LEN_V2, // DELETE_ROWS_COMPRESSED_EVENT + PARTIAL_ROWS_HEADER_LEN, +}; + /** Format_description_log_event 1st ctor. @@ -2205,7 +2260,7 @@ Format_description_log_event:: Format_description_log_event(uint8 binlog_ver, const char* server_ver, enum_binlog_checksum_alg checksum_alg) :Log_event(), created(0), binlog_version(binlog_ver), - dont_set_created(0), event_type_permutation(0), + dont_set_created(0), used_checksum_alg(checksum_alg) { switch (binlog_version) { @@ -2213,125 +2268,14 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver, memcpy(server_version, ::server_version, ST_SERVER_VER_LEN); DBUG_EXECUTE_IF("pretend_version_50034_in_binlog", strmov(server_version, "5.0.34");); - common_header_len= LOG_EVENT_HEADER_LEN; number_of_event_types= LOG_EVENT_TYPES; - /* we'll catch my_malloc() error in is_valid() */ - post_header_len=(uint8*) my_malloc(PSI_INSTRUMENT_ME, - number_of_event_types*sizeof(uint8) - + BINLOG_CHECKSUM_ALG_DESC_LEN, - MYF(0)); - /* - This long list of assignments is not beautiful, but I see no way to - make it nicer, as the right members are #defines, not array members, so - it's impossible to write a loop. - */ - if (post_header_len) - { -#ifndef DBUG_OFF - // Allows us to sanity-check that all events initialized their - // events (see the end of this 'if' block). - memset(post_header_len, 255, number_of_event_types*sizeof(uint8)); -#endif - /* Note: all event types must explicitly fill in their lengths here. */ - post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN; - post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN; - post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN; - post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN; - post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN; - post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN; - post_header_len[SLAVE_EVENT-1]= SLAVE_HEADER_LEN; - post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN; - post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN; - post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN; - post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN; - post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN; - post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN; - post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN; - post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN; - post_header_len[XID_EVENT-1]= XID_HEADER_LEN; - post_header_len[XA_PREPARE_LOG_EVENT-1]= XA_PREPARE_HEADER_LEN; - post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN; - post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN; - /* - The PRE_GA events are never be written to any binlog, but - their lengths are included in Format_description_log_event. - Hence, we need to be assign some value here, to avoid reading - uninitialized memory when the array is written to disk. - */ - post_header_len[PRE_GA_WRITE_ROWS_EVENT-1]= 0; - post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1]= 0; - post_header_len[PRE_GA_DELETE_ROWS_EVENT-1]= 0; - - post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN; - post_header_len[WRITE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - post_header_len[UPDATE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - post_header_len[DELETE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - /* - We here have the possibility to simulate a master of before we changed - the table map id to be stored in 6 bytes: when it was stored in 4 - bytes (=> post_header_len was 6). This is used to test backward - compatibility. - This code can be removed after a few months (today is Dec 21st 2005), - when we know that the 4-byte masters are not deployed anymore (check - with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes) - too. - */ - DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", - post_header_len[TABLE_MAP_EVENT-1]= - post_header_len[WRITE_ROWS_EVENT_V1-1]= - post_header_len[UPDATE_ROWS_EVENT_V1-1]= - post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;); - post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN; - post_header_len[HEARTBEAT_LOG_EVENT-1]= 0; - post_header_len[IGNORABLE_LOG_EVENT-1]= 0; - post_header_len[ROWS_QUERY_LOG_EVENT-1]= 0; - post_header_len[GTID_LOG_EVENT-1]= 0; - post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]= 0; - post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= 0; - post_header_len[TRANSACTION_CONTEXT_EVENT-1]= 0; - post_header_len[VIEW_CHANGE_EVENT-1]= 0; - post_header_len[XA_PREPARE_LOG_EVENT-1]= 0; - post_header_len[PARTIAL_UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[TRANSACTION_PAYLOAD_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[HEARTBEAT_LOG_EVENT_V2-1]= ROWS_HEADER_LEN_V2; - post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2; - - // Set header length of the reserved events to 0 - memset(post_header_len + MYSQL_EVENTS_END - 1, 0, - (MARIA_EVENTS_BEGIN - MYSQL_EVENTS_END)*sizeof(uint8)); - - // Set header lengths of Maria events - post_header_len[ANNOTATE_ROWS_EVENT-1]= ANNOTATE_ROWS_HEADER_LEN; - post_header_len[BINLOG_CHECKPOINT_EVENT-1]= - BINLOG_CHECKPOINT_HEADER_LEN; - post_header_len[GTID_EVENT-1]= GTID_HEADER_LEN; - post_header_len[GTID_LIST_EVENT-1]= GTID_LIST_HEADER_LEN; - post_header_len[START_ENCRYPTION_EVENT-1]= START_ENCRYPTION_HEADER_LEN; - - //compressed event - post_header_len[QUERY_COMPRESSED_EVENT-1]= QUERY_HEADER_LEN; - post_header_len[WRITE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[UPDATE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[DELETE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2; - post_header_len[WRITE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - post_header_len[UPDATE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - post_header_len[DELETE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1; - post_header_len[PARTIAL_ROW_DATA_EVENT-1]= PARTIAL_ROWS_HEADER_LEN; - - // Sanity-check that all post header lengths are initialized. - int i; - for (i=0; i=2 */ default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */ - post_header_len= 0; /* will make is_valid() fail */ + server_version_split.clear(); /* will make is_valid() fail */ break; } calc_server_version_split(); @@ -2359,19 +2303,16 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver, */ Format_description_log_event:: -Format_description_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* - description_event) - :Log_event(buf, description_event), binlog_version(BINLOG_VERSION), - common_header_len(0), post_header_len(NULL), event_type_permutation(0) +Format_description_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len), binlog_version(BINLOG_VERSION) { DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)"); used_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF; - if (unlikely( - event_len < LOG_EVENT_MINIMAL_HEADER_LEN + ST_POST_HEADER_LEN_OFFSET)) + if (unlikely(event_len <= + LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1)) { server_version[0]= 0; - DBUG_VOID_RETURN; + DBUG_VOID_RETURN; /* sanity check */ } buf+= LOG_EVENT_MINIMAL_HEADER_LEN; binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET); @@ -2383,34 +2324,34 @@ Format_description_log_event(const uchar *buf, uint event_len, if (unlikely(server_version[0] == 0)) DBUG_VOID_RETURN; /* sanity check */ - if (unlikely( - (common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < LOG_EVENT_MINIMAL_HEADER_LEN)) - DBUG_VOID_RETURN; /* sanity check */ - number_of_event_types= - event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_POST_HEADER_LEN_OFFSET); + size_t remain= + event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1); + if (unlikely(remain > 255)) + { + server_version[0]= 0; + DBUG_VOID_RETURN; + } + number_of_event_types= (uint8)remain; DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d", common_header_len, number_of_event_types)); - /* If alloc fails, we'll detect it in is_valid() */ calc_server_version_split(); - buf+= ST_POST_HEADER_LEN_OFFSET; if (!is_version_before_checksum(&server_version_split)) { - /* the last bytes are the checksum alg desc */ + /* the last bytes are the checksum alg desc and value (or value's room) */ if (unlikely(number_of_event_types < BINLOG_CHECKSUM_ALG_DESC_LEN)) - DBUG_VOID_RETURN; /* sanity check: But there are no last bytes. */ + { + server_version[0]= 0; + DBUG_VOID_RETURN; + } number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN; - used_checksum_alg= (enum_binlog_checksum_alg)buf[number_of_event_types]; + used_checksum_alg= (enum_binlog_checksum_alg) + buf[ST_COMMON_HEADER_LEN_OFFSET + 1 + number_of_event_types]; } else { used_checksum_alg= BINLOG_CHECKSUM_ALG_OFF; } - post_header_len= (uint8*) my_memdup(PSI_INSTRUMENT_ME, - buf, - number_of_event_types* - sizeof(*post_header_len), - MYF(0)); deduct_options_written_to_bin_log(); reset_crypto(); @@ -2571,11 +2512,10 @@ bool get_checksum_alg(const uchar *buf, size_t len, } Start_encryption_log_event:: -Start_encryption_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event) - :Log_event(buf, description_event) +Start_encryption_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len) { - if ((int)event_len == + if (event_len == (size_t) LOG_EVENT_MINIMAL_HEADER_LEN + Start_encryption_log_event::get_data_size()) { buf+= LOG_EVENT_MINIMAL_HEADER_LEN; @@ -2595,16 +2535,14 @@ Start_encryption_log_event(const uchar *buf, uint event_len, Rotate_log_event methods **************************************************************************/ -Rotate_log_event::Rotate_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* - description_event) - :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME) +Rotate_log_event::Rotate_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len) ,new_log_ident(0), flags(DUP_NAME) { DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)"); // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET - uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1]; + uint8 post_header_len= ROTATE_HEADER_LEN; uint ident_offset; - if (event_len < (uint)(LOG_EVENT_MINIMAL_HEADER_LEN + post_header_len)) + if (event_len < (size_t)(LOG_EVENT_MINIMAL_HEADER_LEN + post_header_len)) DBUG_VOID_RETURN; buf+= LOG_EVENT_MINIMAL_HEADER_LEN; pos= post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4; @@ -2623,15 +2561,12 @@ Rotate_log_event::Rotate_log_event(const uchar *buf, uint event_len, **************************************************************************/ Binlog_checkpoint_log_event::Binlog_checkpoint_log_event( - const uchar *buf, uint event_len, - const Format_description_log_event *description_event) - :Log_event(buf, description_event), binlog_file_name(0) + const uchar *buf, size_t event_len) + :Log_event(buf, event_len), binlog_file_name(0) { - uint8 header_size= description_event->common_header_len; - uint8 post_header_len= - description_event->post_header_len[BINLOG_CHECKPOINT_EVENT-1]; - if (event_len < (uint) header_size + (uint) post_header_len || - post_header_len < BINLOG_CHECKPOINT_HEADER_LEN) + uint8 header_size= Format_description_log_event::common_header_len; + uint8 post_header_len= BINLOG_CHECKPOINT_HEADER_LEN; + if (unlikely(event_len < (size_t) header_size + (size_t) post_header_len)) return; buf+= header_size; /* See uint4korr and int4store below */ @@ -2649,17 +2584,14 @@ Binlog_checkpoint_log_event::Binlog_checkpoint_log_event( Global transaction ID stuff **************************************************************************/ -Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event) - : Log_event(buf, description_event), seq_no(0), commit_id(0), +Gtid_log_event::Gtid_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), seq_no(0), commit_id(0), flags_extra(0), extra_engines(0), thread_id(0) { - uint8 header_size= description_event->common_header_len; - uint8 post_header_len= description_event->post_header_len[GTID_EVENT-1]; + uint8 header_size= Format_description_log_event::common_header_len; + uint8 post_header_len= GTID_HEADER_LEN; const uchar *buf_0= buf; - if (event_len < (uint) header_size + (uint) post_header_len || - post_header_len < GTID_HEADER_LEN) + if (unlikely(event_len < (size_t) header_size + (size_t) post_header_len)) return; buf+= header_size; @@ -2670,7 +2602,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, flags2= *(buf++); if (flags2 & FL_GROUP_COMMIT_ID) { - if (event_len < (uint)header_size + GTID_HEADER_LEN + 2) + if (unlikely(event_len < (size_t)header_size + GTID_HEADER_LEN + 2)) { seq_no= 0; // So is_valid() returns false return; @@ -2680,7 +2612,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, } if (flags2 & (FL_PREPARED_XA | FL_COMPLETED_XA)) { - if (event_len < static_cast(buf - buf_0) + 6) + if (unlikely(event_len < static_cast(buf - buf_0) + 6)) { seq_no= 0; return; @@ -2693,8 +2625,9 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, buf+= 2; long data_length= xid.bqual_length + xid.gtrid_length; - if (event_len < static_cast(buf - buf_0) + data_length || - xid.gtrid_length > MAXGTRIDSIZE || xid.bqual_length > MAXBQUALSIZE) + if (unlikely(event_len < static_cast(buf - buf_0) + data_length || + xid.gtrid_length > MAXGTRIDSIZE || + xid.bqual_length > MAXBQUALSIZE)) { xid.formatID= -1; seq_no= 0; @@ -2705,7 +2638,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, } /* the extra flags check and actions */ - if (static_cast(buf - buf_0) < event_len) + if (static_cast(buf - buf_0) < event_len) { flags_extra= *buf++; /* @@ -2714,7 +2647,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, */ if (flags_extra & FL_EXTRA_MULTI_ENGINE_E1) { - if (event_len < static_cast(buf - buf_0) + 1) + if (unlikely(event_len < static_cast(buf - buf_0) + 1)) { seq_no= 0; return; @@ -2725,7 +2658,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, } if (flags_extra & (FL_COMMIT_ALTER_E1 | FL_ROLLBACK_ALTER_E1)) { - if (event_len < static_cast(buf - buf_0) + 8) + if (unlikely(event_len < static_cast(buf - buf_0) + 8)) { seq_no= 0; return; @@ -2735,7 +2668,7 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, } if (flags_extra & FL_EXTRA_THREAD_ID && - static_cast(buf - buf_0) <= event_len + 4) + static_cast(buf - buf_0) <= event_len + 4) { thread_id= uint4korr(buf); buf+= 4; @@ -2745,14 +2678,14 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, the strict '<' part of the assert corresponds to extra zero-padded trailing bytes, */ - DBUG_ASSERT(static_cast(buf - buf_0) <= event_len); + DBUG_ASSERT(static_cast(buf - buf_0) <= event_len); /* and the last of them is tested. */ #ifdef MYSQL_SERVER #ifdef WITH_WSREP if (!WSREP_ON) #endif #endif - DBUG_ASSERT(static_cast(buf - buf_0) == event_len || + DBUG_ASSERT(static_cast(buf - buf_0) == event_len || buf_0[event_len - 1] == 0); } @@ -2773,17 +2706,14 @@ int compare_glle_gtids(const void * _gtid1, const void *_gtid2) /* GTID list. */ -Gtid_list_log_event::Gtid_list_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event) - : Log_event(buf, description_event), count(0), list(0), sub_id_list(0) +Gtid_list_log_event::Gtid_list_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), count(0), list(0), sub_id_list(0) { uint32 i; uint32 val; - uint8 header_size= description_event->common_header_len; - uint8 post_header_len= description_event->post_header_len[GTID_LIST_EVENT-1]; - if (event_len < (uint) header_size + (uint) post_header_len || - post_header_len < GTID_LIST_HEADER_LEN) + uint8 header_size= Format_description_log_event::common_header_len; + uint8 post_header_len= GTID_LIST_HEADER_LEN; + if (unlikely(event_len < (size_t) header_size + (size_t) post_header_len)) return; buf+= header_size; @@ -2791,9 +2721,10 @@ Gtid_list_log_event::Gtid_list_log_event(const uchar *buf, uint event_len, count= val & ((1<<28)-1); gl_flags= val & ((uint32)0xf << 28); buf+= 4; - if (event_len - (header_size + post_header_len) < count*element_size || + if (unlikely( + event_len - (header_size + post_header_len) < count*element_size || (!(list= (rpl_gtid *)my_malloc(PSI_INSTRUMENT_ME, - count*sizeof(*list) + (count == 0), MYF(MY_WME))))) + count*sizeof(*list) + (count == 0), MYF(MY_WME)))))) return; for (i= 0; i < count; ++i) @@ -2810,8 +2741,8 @@ Gtid_list_log_event::Gtid_list_log_event(const uchar *buf, uint event_len, if ((gl_flags & FLAG_IGN_GTIDS)) { uint32 i; - if (!(sub_id_list= (uint64 *)my_malloc(PSI_INSTRUMENT_ME, - count*sizeof(uint64), MYF(MY_WME)))) + if (unlikely(!(sub_id_list= (uint64 *) + my_malloc(PSI_INSTRUMENT_ME, count*sizeof(uint64), MYF(MY_WME))))) { my_free(list); list= NULL; @@ -2841,8 +2772,7 @@ Gtid_list_log_event::Gtid_list_log_event(const uchar *buf, uint event_len, bool Gtid_list_log_event::peek(const char *event_start, size_t event_len, enum_binlog_checksum_alg checksum_alg, - rpl_gtid **out_gtid_list, uint32 *out_list_len, - const Format_description_log_event *fdev) + rpl_gtid **out_gtid_list, uint32 *out_list_len) { const char *p; uint32 count_field, count; @@ -2859,14 +2789,17 @@ Gtid_list_log_event::peek(const char *event_start, size_t event_len, DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF || checksum_alg == BINLOG_CHECKSUM_ALG_OFF); - if (event_len < (uint32)fdev->common_header_len + GTID_LIST_HEADER_LEN) + if (unlikely(event_len < + (size_t)Format_description_log_event::common_header_len + + GTID_LIST_HEADER_LEN)) return true; - p= event_start + fdev->common_header_len; + p= event_start + Format_description_log_event::common_header_len; count_field= uint4korr(p); p+= 4; count= count_field & ((1<<28)-1); - if (event_len < (uint32)fdev->common_header_len + GTID_LIST_HEADER_LEN + - element_size * count) + if (unlikely(event_len < + (size_t)Format_description_log_event::common_header_len + + GTID_LIST_HEADER_LEN + element_size * count)) return true; if (!(gtid_list= (rpl_gtid *)my_malloc(PSI_INSTRUMENT_ME, sizeof(rpl_gtid)*count + (count == 0), MYF(MY_WME)))) @@ -2896,13 +2829,15 @@ Gtid_list_log_event::peek(const char *event_start, size_t event_len, Intvar_log_event::Intvar_log_event() */ -Intvar_log_event::Intvar_log_event(const uchar *buf, - const Format_description_log_event* description_event) - :Log_event(buf, description_event) +Intvar_log_event::Intvar_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len) { /* The Post-Header is empty. The Variable Data part begins immediately. */ - buf+= description_event->common_header_len + - description_event->post_header_len[INTVAR_EVENT-1]; + size_t header_len= + Format_description_log_event::common_header_len + INTVAR_HEADER_LEN; + if (unlikely(event_len < header_len + (1 + 8))) + return; + buf+= header_len; type= buf[I_TYPE_OFFSET]; val= uint8korr(buf+I_VAL_OFFSET); } @@ -2926,13 +2861,14 @@ const char* Intvar_log_event::get_var_type_name() Rand_log_event methods **************************************************************************/ -Rand_log_event::Rand_log_event(const uchar *buf, - const Format_description_log_event* description_event) - :Log_event(buf, description_event) +Rand_log_event::Rand_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len) { /* The Post-Header is empty. The Variable Data part begins immediately. */ - buf+= description_event->common_header_len + - description_event->post_header_len[RAND_EVENT-1]; + if (unlikely(event_len < Format_description_log_event::common_header_len + + (RAND_HEADER_LEN + 8 + 8))) + return; + buf+= Format_description_log_event::common_header_len + RAND_HEADER_LEN; seed1= uint8korr(buf+RAND_SEED1_OFFSET); seed2= uint8korr(buf+RAND_SEED2_OFFSET); } @@ -2952,13 +2888,18 @@ Rand_log_event::Rand_log_event(const uchar *buf, */ Xid_log_event:: -Xid_log_event(const uchar *buf, - const Format_description_log_event *description_event) - :Xid_apply_log_event(buf, description_event) +Xid_log_event(const uchar *buf, size_t event_len) + :Xid_apply_log_event(buf, event_len) { /* The Post-Header is empty. The Variable Data part begins immediately. */ - buf+= description_event->common_header_len + - description_event->post_header_len[XID_EVENT-1]; + size_t header_len= + Format_description_log_event::common_header_len + XID_HEADER_LEN; + if (unlikely(event_len < header_len + sizeof(xid))) + { + memset(&xid, 0, sizeof(xid)); + return; + } + buf+= header_len; memcpy((char*) &xid, buf, sizeof(xid)); } @@ -2966,36 +2907,36 @@ Xid_log_event(const uchar *buf, XA_prepare_log_event methods **************************************************************************/ XA_prepare_log_event:: -XA_prepare_log_event(const uchar *buf, - const Format_description_log_event *description_event) - :Xid_apply_log_event(buf, description_event) +XA_prepare_log_event(const uchar *buf, size_t event_len) + :Xid_apply_log_event(buf, event_len) { - buf+= description_event->common_header_len + - description_event->post_header_len[XA_PREPARE_LOG_EVENT-1]; + m_xid.formatID= -1; /* Mark invalid by default */ + size_t header_len= + Format_description_log_event::common_header_len + XA_PREPARE_HEADER_LEN; + size_t needed_len= header_len + (1 + 4 + 4 + 4); + if (unlikely(event_len < needed_len)) + return; + buf+= header_len; + static_assert(sizeof(bool) == 1); one_phase= * (bool *) buf; buf+= 1; - - m_xid.formatID= uint4korr(buf); + long loc_formatID= uint4korr(buf); buf+= 4; - m_xid.gtrid_length= uint4korr(buf); + uint32_t loc_gtid_length= uint4korr(buf); buf+= 4; - // Todo: validity here and elsewhere checks to be replaced by MDEV-21839 fixes - if (m_xid.gtrid_length <= 0 || m_xid.gtrid_length > MAXGTRIDSIZE) - { - m_xid.formatID= -1; + uint32_t loc_bqual_length= uint4korr(buf); + buf+= 4; + if (unlikely(loc_gtid_length > MAXGTRIDSIZE || + loc_bqual_length > MAXBQUALSIZE || + event_len < needed_len + loc_gtid_length + loc_bqual_length)) return; - } - m_xid.bqual_length= uint4korr(buf); - buf+= 4; - if (m_xid.bqual_length < 0 || m_xid.bqual_length > MAXBQUALSIZE) - { - m_xid.formatID= -1; - return; - } - DBUG_ASSERT(m_xid.gtrid_length + m_xid.bqual_length <= XIDDATASIZE); + DBUG_ASSERT(MAXGTRIDSIZE + MAXBQUALSIZE <= XIDDATASIZE); - memcpy(m_xid.data, buf, m_xid.gtrid_length + m_xid.bqual_length); + memcpy(m_xid.data, buf, loc_gtid_length + loc_bqual_length); + m_xid.formatID= (long)loc_formatID; /* Now mark valid */ + m_xid.gtrid_length= (long)loc_gtid_length; + m_xid.bqual_length= (long)loc_bqual_length; xid= NULL; } @@ -3025,7 +2966,7 @@ bool Log_event_data_type::unpack_optional_attributes(const char *pos, if (pos >= end) return true; uint length= (uchar) *pos++; - if (pos + length > end) + if (end - pos < length) return true; m_data_type_name= {pos, length}; pos+= length; @@ -3040,63 +2981,64 @@ bool Log_event_data_type::unpack_optional_attributes(const char *pos, User_var_log_event:: -User_var_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event) - :Log_event(buf, description_event) +User_var_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len), name(nullptr) /* invalid by default */ #ifndef MYSQL_CLIENT , deferred(false), query_id(0) #endif { bool error= false; - const uchar *const buf_start= buf; - const char *buf_end= reinterpret_cast(buf) + event_len; + const uchar *buf_end= buf + event_len; /* The Post-Header is empty. The Variable Data part begins immediately. */ - buf+= description_event->common_header_len + - description_event->post_header_len[USER_VAR_EVENT-1]; + size_t header_len= + Format_description_log_event::common_header_len + USER_VAR_HEADER_LEN; + if (unlikely(event_len < header_len + 4)) + return; + buf+= header_len; name_len= uint4korr(buf); + buf+= 4; /* Avoid reading out of buffer */ - if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len) + if (unlikely((size_t)(buf_end - buf) < name_len)) { error= true; goto err; } - name= (char *) buf + UV_NAME_LEN_SIZE; + name= (char *) buf; + buf+= name_len; /* We don't know yet is_null value, so we must assume that name_len may have the bigger value possible, is_null= True and there is no payload for val, or even that name_len is 0. */ - if (name + name_len + UV_VAL_IS_NULL > (char*) buf_end) + if (unlikely(buf_end - buf < UV_VAL_IS_NULL)) { error= true; goto err; } - buf+= UV_NAME_LEN_SIZE + name_len; is_null= (bool) *buf; + buf++; if (is_null) { val_len= 0; val= 0; } + else if (unlikely(buf_end - buf < UV_VAL_TYPE_SIZE + + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE)) + { + error= true; + goto err; + } else { - val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + + val= (char *) (buf + UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE); - - if (val > (char*) buf_end) - { - error= true; - goto err; - } - - m_type= (Item_result) buf[UV_VAL_IS_NULL]; - m_charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE); - val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + - UV_CHARSET_NUMBER_SIZE); + m_type= (Item_result) buf[0]; + m_charset_number= uint4korr(buf + UV_VAL_TYPE_SIZE); + val_len= uint4korr(buf + UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE); /** We need to check if this is from an old server @@ -3109,8 +3051,9 @@ User_var_log_event(const uchar *buf, uint event_len, Old events will not have this extra byte, thence, we keep m_is_unsigned==false. */ - const char *pos= val + val_len; - if (pos > buf_end || unpack_optional_attributes(pos, buf_end)) + if (unlikely((size_t)((const char *)buf_end - val) < val_len ) || + unlikely(unpack_optional_attributes(val + val_len, + (const char *)buf_end))) { error= true; goto err; @@ -3132,20 +3075,18 @@ err: */ Append_block_log_event:: -Append_block_log_event(const uchar *buf, uint len, - const Format_description_log_event* description_event) - :Log_event(buf, description_event),block(0) +Append_block_log_event(const uchar *buf, size_t len) + :Log_event(buf, len),block(0) { DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)"); - uint8 common_header_len= description_event->common_header_len; - uint8 append_block_header_len= - description_event->post_header_len[APPEND_BLOCK_EVENT-1]; + uint8 common_header_len= Format_description_log_event::common_header_len; + uint8 append_block_header_len= APPEND_BLOCK_HEADER_LEN; uint total_header_len= common_header_len+append_block_header_len; - if (len < total_header_len) + if (unlikely(len < total_header_len)) DBUG_VOID_RETURN; file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET); block= const_cast(buf) + total_header_len; - block_len= len - total_header_len; + block_len= (uint)(len - total_header_len); DBUG_VOID_RETURN; } @@ -3159,13 +3100,12 @@ Append_block_log_event(const uchar *buf, uint len, */ Delete_file_log_event:: -Delete_file_log_event(const uchar *buf, uint len, - const Format_description_log_event* description_event) - :Log_event(buf, description_event),file_id(0) +Delete_file_log_event(const uchar *buf, size_t len) + :Log_event(buf, len),file_id(0) { - uint8 common_header_len= description_event->common_header_len; - uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1]; - if (len < (uint)(common_header_len + delete_file_header_len)) + uint8 common_header_len= Format_description_log_event::common_header_len; + uint8 delete_file_header_len= DELETE_FILE_HEADER_LEN; + if (unlikely(len < (size_t)(common_header_len + delete_file_header_len))) return; file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET); } @@ -3176,9 +3116,8 @@ Delete_file_log_event(const uchar *buf, uint len, **************************************************************************/ Begin_load_query_log_event:: -Begin_load_query_log_event(const uchar *buf, uint len, - const Format_description_log_event* desc_event) - :Append_block_log_event(buf, len, desc_event) +Begin_load_query_log_event(const uchar *buf, size_t len) + :Append_block_log_event(buf, len) { } @@ -3189,7 +3128,7 @@ Begin_load_query_log_event(const uchar *buf, uint len, Execute_load_query_log_event:: -Execute_load_query_log_event(const uchar *buf, uint event_len, +Execute_load_query_log_event(const uchar *buf, size_t event_len, const Format_description_log_event* desc_event): Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT), file_id(0), fn_pos_start(0), fn_pos_end(0) @@ -3199,6 +3138,8 @@ Execute_load_query_log_event(const uchar *buf, uint event_len, buf+= desc_event->common_header_len; + if (unlikely(ELQ_DUP_HANDLING_OFFSET >= event_len)) + return; fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET); fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET); dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET)); @@ -3280,10 +3221,8 @@ const uchar *sql_ex_info::init(const uchar *buf, const uchar *buf_end, **************************************************************************/ -Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event - *description_event) - : Log_event(buf, description_event), +Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), m_row_count(0), #ifndef MYSQL_CLIENT m_table(NULL), @@ -3297,14 +3236,45 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, #endif { DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)"); - uint8 const common_header_len= description_event->common_header_len; + const uchar *buf_end= buf + event_len; + uint8 const common_header_len= Format_description_log_event::common_header_len; + m_cols.bitmap= 0; // Set to invalid, so it can be processed in is_valid(). + if (unlikely(event_len < common_header_len)) + DBUG_VOID_RETURN; Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET]; m_type= event_type; m_cols_ai.bitmap= 0; // Set to invalid, so it can be processed in is_valid(). - uint8 const post_header_len= description_event->post_header_len[event_type-1]; + DBUG_ASSERT(event_type == WRITE_ROWS_EVENT_V1 || + event_type == UPDATE_ROWS_EVENT_V1 || + event_type == DELETE_ROWS_EVENT_V1 || + event_type == WRITE_ROWS_EVENT || + event_type == UPDATE_ROWS_EVENT || + event_type == DELETE_ROWS_EVENT || + event_type == WRITE_ROWS_COMPRESSED_EVENT_V1 || + event_type == UPDATE_ROWS_COMPRESSED_EVENT_V1 || + event_type == DELETE_ROWS_COMPRESSED_EVENT_V1 || + event_type == WRITE_ROWS_COMPRESSED_EVENT || + event_type == UPDATE_ROWS_COMPRESSED_EVENT || + event_type == DELETE_ROWS_COMPRESSED_EVENT); + DBUG_ASSERT(WRITE_ROWS_EVENT_V1 < WRITE_ROWS_EVENT); + DBUG_ASSERT(WRITE_ROWS_COMPRESSED_EVENT_V1 < WRITE_ROWS_COMPRESSED_EVENT); + if (unlikely(!((event_type >= WRITE_ROWS_EVENT_V1 && + event_type <= DELETE_ROWS_EVENT_V1) || + (event_type >= WRITE_ROWS_EVENT && + event_type <= DELETE_ROWS_EVENT) || + (event_type >= WRITE_ROWS_COMPRESSED_EVENT_V1 && + event_type <= DELETE_ROWS_COMPRESSED_EVENT_V1) || + (event_type >= WRITE_ROWS_COMPRESSED_EVENT && + event_type <= DELETE_ROWS_COMPRESSED_EVENT)))) + DBUG_VOID_RETURN; + uint8 const post_header_len= + event_type < WRITE_ROWS_EVENT || + ( event_type >= WRITE_ROWS_COMPRESSED_EVENT_V1 && + event_type <= DELETE_ROWS_COMPRESSED_EVENT_V1) ? + ROWS_HEADER_LEN_V1 /* 8 */ : ROWS_HEADER_LEN_V2 /* 10 */; - if (event_len < (uint)(common_header_len + post_header_len)) + if (unlikely(event_len < (uint)(common_header_len + post_header_len))) DBUG_VOID_RETURN; DBUG_PRINT("enter",("event_len: %zu common_header_len: %d " @@ -3313,18 +3283,9 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, post_header_len)); const uchar *post_start= buf + common_header_len; - post_start+= RW_MAPID_OFFSET; - if (post_header_len == 6) - { - /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */ - m_table_id= uint4korr(post_start); - post_start+= 4; - } - else - { - m_table_id= (ulonglong) uint6korr(post_start); - post_start+= RW_FLAGS_OFFSET; - } + post_start+= RW_MAPID_OFFSET /* 0 */; + m_table_id= (ulonglong) uint6korr(post_start); + post_start+= RW_FLAGS_OFFSET /* 6 */; m_flags_pos= post_start - buf; m_flags= uint2korr(post_start); @@ -3340,7 +3301,7 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, var_header_len= uint2korr(post_start); /* Check length and also avoid out of buffer read */ if (var_header_len < 2 || - event_len < static_cast(var_header_len + + event_len < static_cast(var_header_len + (post_start - buf))) { m_cols.bitmap= 0; @@ -3358,13 +3319,13 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, case RW_V_EXTRAINFO_TAG: { /* Have an 'extra info' section, read it in */ - if (unlikely((end - pos) <= EXTRA_ROW_INFO_LEN_OFFSET)) + if (unlikely(end - pos <= EXTRA_ROW_INFO_LEN_OFFSET /* 2 */)) { m_cols.bitmap= 0; DBUG_VOID_RETURN; } uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET]; - if (unlikely(infoLen < EXTRA_ROW_INFO_HDR_BYTES || (end-pos) < infoLen)) + if (unlikely(infoLen < EXTRA_ROW_INFO_HDR_BYTES || end - pos < infoLen)) { m_cols.bitmap= 0; DBUG_VOID_RETURN; @@ -3394,11 +3355,17 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, uchar const *const ptr_width= var_start; uchar *ptr_after_width= (uchar*) ptr_width; DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); - m_width= net_field_length(&ptr_after_width); + m_width= (uint) + safe_net_field_length_ll(&ptr_after_width, buf_end - ptr_after_width); + if (unlikely(!ptr_after_width)) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } DBUG_PRINT("debug", ("m_width=%u", m_width)); /* Avoid reading out of buffer */ - if (ptr_after_width + (m_width + 7) / 8 > (uchar*)buf + event_len) + if (unlikely(buf_end - ptr_after_width < ((longlong)m_width + 7) / 8)) { m_cols.bitmap= NULL; DBUG_VOID_RETURN; @@ -3421,6 +3388,11 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, { DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); + if (unlikely(buf_end - ptr_after_width < ((longlong)m_width + 7) / 8)) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } /* if my_bitmap_init fails, caught in is_valid() */ if (likely(!my_bitmap_init(&m_cols_ai, m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : @@ -3480,7 +3452,7 @@ Rows_log_event::Rows_log_event(const uchar *buf, size_t event_len, void Rows_log_event::uncompress_buf() { - uint32 un_len= binlog_get_uncompress_len(m_rows_buf); + uint32 un_len= binlog_get_uncompress_len(m_rows_buf, m_rows_cur - m_rows_buf); if (unlikely(!un_len || un_len > MAX_MAX_ALLOWED_PACKET)) { /* my_bitmap_free() nulls m_cols.bitmap, which is_valid() rejects. */ @@ -3561,17 +3533,18 @@ int Rows_log_event::get_data_size() **************************************************************************/ Annotate_rows_log_event:: -Annotate_rows_log_event(const uchar *buf, - uint event_len, - const Format_description_log_event *desc) - : Log_event(buf, desc), +Annotate_rows_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), m_query_txt(0), m_query_len(0), m_save_thd_query_txt(0), m_save_thd_query_len(0), m_saved_thd_query(false), m_used_query_txt(0) { - m_query_len= event_len - desc->common_header_len; - m_query_txt= (char*) buf + desc->common_header_len; + /* Zero size query string is not valid. */ + if (unlikely(event_len <= Format_description_log_event::common_header_len)) + return; + m_query_len= (uint)(event_len - Format_description_log_event::common_header_len); + m_query_txt= (char*) buf + Format_description_log_event::common_header_len; } Annotate_rows_log_event::~Annotate_rows_log_event() @@ -3642,11 +3615,9 @@ bool Annotate_rows_log_event::is_valid() const Constructor used by slave to read the event from the binary log. */ #if defined(HAVE_REPLICATION) -Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event) +Table_map_log_event::Table_map_log_event(const uchar *buf, size_t event_len) - : Log_event(buf, description_event), + : Log_event(buf, event_len), #ifndef MYSQL_CLIENT m_table(NULL), #endif @@ -3660,9 +3631,9 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, unsigned int bytes_read= 0; DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)"); - uint8 common_header_len= description_event->common_header_len; - uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1]; - DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", + uint8 common_header_len= Format_description_log_event::common_header_len; + uint8 post_header_len= TABLE_MAP_HEADER_LEN; + DBUG_PRINT("info",("event_len: %zu common_header_len: %d post_header_len: %d", event_len, common_header_len, post_header_len)); /* @@ -3673,26 +3644,16 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, DBUG_DUMP("event buffer", (uchar*) buf, event_len); #endif - if (event_len < (uint)(common_header_len + post_header_len)) - DBUG_VOID_RETURN; + if (unlikely(event_len < (size_t)(common_header_len + post_header_len))) + DBUG_VOID_RETURN; /* With m_memory==NULL to indicate invalid */ /* Read the post-header */ const uchar *post_start= buf + common_header_len; post_start+= TM_MAPID_OFFSET; - VALIDATE_BYTES_READ(post_start, buf, event_len); - if (post_header_len == 6) - { - /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */ - m_table_id= uint4korr(post_start); - post_start+= 4; - } - else - { - DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN); - m_table_id= (ulonglong) uint6korr(post_start); - post_start+= TM_FLAGS_OFFSET; - } + DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN); + m_table_id= (ulonglong) uint6korr(post_start); + post_start+= TM_FLAGS_OFFSET; DBUG_ASSERT((m_table_id & MAX_TABLE_MAP_ID) != UINT32_MAX && (m_table_id & MAX_TABLE_MAP_ID) != 0); @@ -3704,12 +3665,12 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, /* Extract the length of the various parts from the buffer */ uchar const *const ptr_dblen= (uchar const*)vpart + 0; - VALIDATE_BYTES_READ(ptr_dblen, buf, event_len); + VALIDATE_BYTES_READ(ptr_dblen, 1, buf, event_len); m_dblen= *(uchar*) ptr_dblen; + VALIDATE_BYTES_READ(ptr_dblen + 1, m_dblen + 1 + 1, buf, event_len); /* Length of database name + counter + terminating null */ uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2; - VALIDATE_BYTES_READ(ptr_tbllen, buf, event_len); m_tbllen= *(uchar*) ptr_tbllen; /* @@ -3720,13 +3681,18 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, if (unlikely(m_dblen > NAME_LEN || m_tbllen > NAME_LEN)) DBUG_VOID_RETURN; + VALIDATE_BYTES_READ(ptr_tbllen + 1, m_tbllen + 1, buf, event_len); /* Length of table name + counter + terminating null */ uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2; uchar *ptr_after_colcnt= (uchar*) ptr_colcnt; - VALIDATE_BYTES_READ(ptr_after_colcnt, buf, event_len); - m_colcnt= net_field_length(&ptr_after_colcnt); + m_colcnt= (ulong) + safe_net_field_length_ll(&ptr_after_colcnt, + event_len - (ptr_after_colcnt - buf)); DBUG_EXECUTE_IF("corrupt_table_map_colcnt_read", m_colcnt= (1 << 20);); + if (unlikely(!ptr_after_colcnt) || + unlikely(m_colcnt > event_len - (ptr_after_colcnt - buf))) + DBUG_VOID_RETURN; DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld", (ulong) m_dblen, (long) (ptr_dblen - vpart), @@ -3752,17 +3718,21 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, */ const_cast(m_dbnam)[m_dblen]= '\0'; const_cast(m_tblnam)[m_tbllen]= '\0'; - if (unlikely(ptr_after_colcnt + m_colcnt > buf + event_len)) - { - my_free(m_memory); - m_memory= NULL; - DBUG_VOID_RETURN; - } memcpy(m_coltype, ptr_after_colcnt, m_colcnt); ptr_after_colcnt= ptr_after_colcnt + m_colcnt; - VALIDATE_BYTES_READ(ptr_after_colcnt, buf, event_len); - m_field_metadata_size= net_field_length(&ptr_after_colcnt); + m_field_metadata_size= (ulong) + safe_net_field_length_ll(&ptr_after_colcnt, + event_len - (ptr_after_colcnt - buf )); + if (unlikely(!ptr_after_colcnt)) + { + /* + This is apparently supporting ancient MySQL <= 5.1 events where the + metadata is not there, should probably be replaced by rejecting the + event as invalid. + */ + goto done; + } DBUG_EXECUTE_IF("corrupt_table_map_field_metadata_size_read", m_field_metadata_size= (1 << 20);); @@ -3788,7 +3758,8 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, &m_null_bits, num_null_bytes, &m_field_metadata, m_field_metadata_size, NULL); - if (unlikely(ptr_after_colcnt + m_field_metadata_size > buf + event_len)) + if (unlikely(!m_meta_memory || + m_field_metadata_size > event_len - (ptr_after_colcnt-buf))) { my_free(m_meta_memory); m_meta_memory= NULL; @@ -3798,7 +3769,7 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, } memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size); ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size; - if (unlikely(ptr_after_colcnt + num_null_bytes > buf + event_len)) + if (unlikely(num_null_bytes > event_len - (ptr_after_colcnt - buf))) { my_free(m_meta_memory); m_meta_memory= NULL; @@ -3822,15 +3793,21 @@ Table_map_log_event::Table_map_log_event(const uchar *buf, uint event_len, /* After null_bits field, there are some new fields for extra metadata. */ if (bytes_read < event_len) { - m_optional_metadata_len= event_len - bytes_read; + m_optional_metadata_len= (unsigned int)(event_len - bytes_read); m_optional_metadata= static_cast(my_malloc(PSI_INSTRUMENT_ME, m_optional_metadata_len, MYF(MY_WME))); memcpy(m_optional_metadata, ptr_after_colcnt, m_optional_metadata_len); } } +done: #ifdef MYSQL_SERVER if (!m_table) DBUG_VOID_RETURN; + /* + This appears to be dead code incorrectly merged in MDEV-20477 Merge binlog + extended metadata support from the upstream "MDEV-20477 Merge binlog + extended metadata support from the upstream". + */ binlog_type_info_array= thd->alloc(m_table->s->fields); for (uint i= 0; i < m_table->s->fields; i++) binlog_type_info_array[i]= m_table->field[i]->binlog_type_info(); @@ -3879,16 +3856,16 @@ static void parse_default_charset(Table_map_log_event::Optional_metadata_fields: unsigned char* p= field; unsigned char* end= field + length; - default_charset.default_charset= net_field_length(&p); - if (unlikely(p > end)) + default_charset.default_charset= (uint)safe_net_field_length_ll(&p, length); + if (unlikely(!p)) return; while (p < end) { - unsigned int col_index= net_field_length(&p); - if (unlikely(p > end)) + unsigned int col_index= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; - unsigned int col_charset= net_field_length(&p); - if (unlikely(p > end)) + unsigned int col_charset= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; default_charset.charset_pairs.push_back(std::make_pair(col_index, @@ -3911,8 +3888,8 @@ static void parse_column_charset(std::vector &vec, while (p < end) { - unsigned int charset= net_field_length(&p); - if (unlikely(p > end)) + unsigned int charset= (uint)safe_net_field_length_ll(&p, length); + if (unlikely(!p)) return; vec.push_back(charset); } @@ -3931,8 +3908,8 @@ static bool parse_column_name(MEM_ROOT *root, LEX_CSTRING *name, { for (uchar *end= field+length; field < end ; name++) { - uint name_length= net_field_length(&field); - if (unlikely(field + name_length > end)) + uint name_length= (uint)safe_net_field_length_ll(&field, end - field); + if (unlikely(!field || name_length > end - field)) return 1; if (!(name->str= strmake_root(root, (char*) field, name_length))) return 1; @@ -3963,15 +3940,15 @@ static void parse_set_str_value(std::vector end)) + unsigned int count= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; vec.push_back(std::vector()); for (unsigned int i= 0; i < count; i++) { - unsigned len1= net_field_length(&p); - if (unlikely(p + len1 > end)) + unsigned len1= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p || len1 > end - p)) return; vec.back().push_back(std::string(reinterpret_cast(p), len1)); p+= len1; @@ -3994,8 +3971,8 @@ static void parse_geometry_type(std::vector &vec, while (p < end) { - unsigned int geom_type= net_field_length(&p); - if (unlikely(p > end)) + unsigned int geom_type= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; vec.push_back(geom_type); } @@ -4020,8 +3997,8 @@ static void parse_simple_pk(std::vector end)) + unsigned int col_index= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; vec.push_back(std::make_pair(col_index, (unsigned int) 0)); } @@ -4046,11 +4023,11 @@ static void parse_pk_with_prefix(std::vector end)) + unsigned int col_index= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; - unsigned int col_prefix= net_field_length(&p); - if (unlikely(p > end)) + unsigned int col_prefix= (uint)safe_net_field_length_ll(&p, end - p); + if (unlikely(!p)) return; vec.push_back(std::make_pair(col_index, col_prefix)); } @@ -4078,7 +4055,9 @@ Optional_metadata_fields(MEM_ROOT *root, uint master_columns, // Get length and move field to the value. field++; - len= net_field_length(&field); + len= (uint)safe_net_field_length_ll(&field, metadata_end - field); + if (unlikely(!field || metadata_end - field < len)) + break; if (only_column_names && type != COLUMN_NAME) continue; @@ -4149,18 +4128,14 @@ error: Constructor used by slave to read the event from the binary log. */ #ifdef HAVE_REPLICATION -Write_rows_log_event::Write_rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event - *description_event) -: Rows_log_event(buf, event_len, description_event) +Write_rows_log_event::Write_rows_log_event(const uchar *buf, size_t event_len) +: Rows_log_event(buf, event_len) { } Write_rows_compressed_log_event::Write_rows_compressed_log_event( - const uchar *buf, size_t event_len, - const Format_description_log_event - *description_event) -: Write_rows_log_event(buf, event_len, description_event) + const uchar *buf, size_t event_len) +: Write_rows_log_event(buf, event_len) { uncompress_buf(); } @@ -4175,18 +4150,14 @@ Write_rows_compressed_log_event::Write_rows_compressed_log_event( Constructor used by slave to read the event from the binary log. */ #ifdef HAVE_REPLICATION -Delete_rows_log_event::Delete_rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event - *description_event) - : Rows_log_event(buf, event_len, description_event) +Delete_rows_log_event::Delete_rows_log_event(const uchar *buf, size_t event_len) + : Rows_log_event(buf, event_len) { } Delete_rows_compressed_log_event::Delete_rows_compressed_log_event( - const uchar *buf, size_t event_len, - const Format_description_log_event - *description_event) - : Delete_rows_log_event(buf, event_len, description_event) + const uchar *buf, size_t event_len) + : Delete_rows_log_event(buf, event_len) { uncompress_buf(); } @@ -4206,47 +4177,36 @@ Update_rows_log_event::~Update_rows_log_event() Constructor used by slave to read the event from the binary log. */ #ifdef HAVE_REPLICATION -Update_rows_log_event::Update_rows_log_event( - const uchar *buf, size_t event_len, - const Format_description_log_event *description_event) - : Rows_log_event(buf, event_len, description_event) +Update_rows_log_event::Update_rows_log_event(const uchar *buf, size_t event_len) + : Rows_log_event(buf, event_len) { } Update_rows_compressed_log_event::Update_rows_compressed_log_event( - const uchar *buf, size_t event_len, - const Format_description_log_event *description_event) - : Update_rows_log_event(buf, event_len, description_event) + const uchar *buf, size_t event_len) + : Update_rows_log_event(buf, event_len) { uncompress_buf(); } #endif -Incident_log_event::Incident_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *descr_event) - : Log_event(buf, descr_event) +Incident_log_event::Incident_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), + m_incident(INCIDENT_NONE) /* invalid by default */ { DBUG_ENTER("Incident_log_event::Incident_log_event"); - uint8 const common_header_len= - descr_event->common_header_len; - uint8 const post_header_len= - descr_event->post_header_len[INCIDENT_EVENT-1]; + uint8 const common_header_len= Format_description_log_event::common_header_len; + uint8 const post_header_len= INCIDENT_HEADER_LEN; - DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d", + DBUG_PRINT("info",("event_len: %zu; common_header_len: %d; post_header_len: %d", event_len, common_header_len, post_header_len)); m_message.str= NULL; m_message.length= 0; int incident_number= uint2korr(buf + common_header_len); - if (incident_number >= INCIDENT_COUNT || - incident_number <= INCIDENT_NONE) - { - // If the incident is not recognized, this binlog event is - // invalid. If we set incident_number to INCIDENT_NONE, the - // invalidity will be detected by is_valid(). - m_incident= INCIDENT_NONE; + if (unlikely(incident_number >= INCIDENT_COUNT || + incident_number <= INCIDENT_NONE)) DBUG_VOID_RETURN; - } m_incident= static_cast(incident_number); uchar const *ptr= buf + common_header_len + post_header_len; uchar const *const str_end= buf + event_len; @@ -4271,49 +4231,46 @@ Incident_log_event::Incident_log_event(const uchar *buf, uint event_len, } -Partial_rows_log_event::Partial_rows_log_event( - const uchar *buf, uint event_len, - const Format_description_log_event *description_event) - : Log_event(buf, description_event), metadata_written(0), rows_event(NULL) +Partial_rows_log_event::Partial_rows_log_event(const uchar *buf, size_t event_len) + : Log_event(buf, event_len), + flags2(0), seq_no(0) /* mark invalid by default */, total_fragments(0), + metadata_written(0), rows_event(NULL) { DBUG_ENTER("Partial_rows_log_event::Partial_rows_log_even(const uchar*,uint,...)"); - uint8 common_header_len= description_event->common_header_len; - uint8 post_header_len= description_event->post_header_len[PARTIAL_ROW_DATA_EVENT-1]; - DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", + uint8 common_header_len= Format_description_log_event::common_header_len; + uint8 post_header_len= PARTIAL_ROWS_HEADER_LEN /* 9 */; + DBUG_PRINT("info",("event_len: %zu common_header_len: %d post_header_len: %d", event_len, common_header_len, post_header_len)); - DBUG_ASSERT(post_header_len == PARTIAL_ROWS_HEADER_LEN); - - if (event_len < (uint)(common_header_len + post_header_len)) - DBUG_VOID_RETURN; + if (unlikely(event_len < (size_t)(common_header_len + post_header_len))) + DBUG_VOID_RETURN; start_offset= common_header_len + PARTIAL_ROWS_HEADER_LEN; ev_buffer_base= buf; end_offset= event_len; /* Read the post-header */ + VALIDATE_BYTES_READ(buf, common_header_len + 9, buf, event_len); const uchar *post_start= buf + common_header_len; - VALIDATE_BYTES_READ(post_start, buf, event_len); total_fragments= uint4korr(post_start); post_start+= 4; - VALIDATE_BYTES_READ(post_start, buf, event_len); seq_no= uint4korr((post_start)); post_start+= 4; - VALIDATE_BYTES_READ(post_start, buf, event_len); DBUG_ASSERT(seq_no <= total_fragments); + if (unlikely(seq_no > total_fragments)) + DBUG_VOID_RETURN; flags2= *(post_start++); - VALIDATE_BYTES_READ(post_start, buf, event_len); if (flags2 & FL_ORIG_EVENT_SIZE) { DBUG_ASSERT(seq_no == 1); + VALIDATE_BYTES_READ(post_start, 8, buf, event_len); original_event_size= uint8korr((post_start)); post_start+= 8; start_offset+= 8; - VALIDATE_BYTES_READ(post_start, buf, event_len); DBUG_ASSERT(original_event_size); } @@ -4321,7 +4278,7 @@ Partial_rows_log_event::Partial_rows_log_event( post_start so far only has read header data, no data from the rows event itself. Ensure there is still data for the rows event. */ - DBUG_ASSERT(static_cast(post_start - ev_buffer_base) < event_len); + DBUG_ASSERT(static_cast(post_start - ev_buffer_base) < event_len); DBUG_VOID_RETURN; } @@ -4396,11 +4353,10 @@ Incident_log_event::description() const } -Ignorable_log_event::Ignorable_log_event(const uchar *buf, - const Format_description_log_event - *descr_event, +Ignorable_log_event::Ignorable_log_event(const uchar *buf, size_t event_len, + Log_event_type event_type, const char *event_name) - :Log_event(buf, descr_event), number((int) (uchar) buf[EVENT_TYPE_OFFSET]), + :Log_event(buf, event_len), number(event_type), description(event_name) { DBUG_ENTER("Ignorable_log_event::Ignorable_log_event"); diff --git a/sql/log_event.h b/sql/log_event.h index 5599dc42591..8c73aa60747 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -156,6 +156,26 @@ class String; #define NUM_LOAD_DELIM_STRS 5 + +/* + Master-side bugs that we work-around with rpl_master_has_bug(). + Each define is a bit number (0, 1, 2, ...) set in + Relay_log_info::rpl_master_bug_bitmask. + These bit numbers are internal-only, can be changed (eg. to drop a bug + work-around for ancient version) without concern for backwards compatibility. +*/ +enum enum_rpl_master_bug_ids { + RPL_BUG_MYSQL_24432, + RPL_BUG_MYSQL_33029, + RPL_BUG_MYSQL_37426, + RPL_BUG_MDEV_29621, + RPL_BUG_END /* To check size of Relay_log_info::rpl_master_bug_bitmask */ +}; + +/* Must be large enough to hold all enum_rpl_master_bug_ids bits. */ +typedef uint32_t rpl_bug_id_t; + + /* The following is the max table_map_id. This is limited by that we are using 6 bytes for it in replication @@ -238,16 +258,19 @@ class String; 1 + 1 + 255 /* type, length, catalog */ + \ 1 + 4 /* type, auto_increment */ + \ 1 + 6 /* type, charset */ + \ + 1 + Charset_collation_map_st::binary_size_max() \ + /* type, map */ + \ 1 + 1 + 255 /* type, length, time_zone */ + \ + 1 + 1 + 255 + 1/* type, length, catalog, \0 */ + \ 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ 1 + 8 /* type, table_map_for_update */ + \ 1 + 4 /* type, master_data_written */ + \ + 1 + 1 + 16 + 1 + 60 \ + /* type, user_len, user, host_len, host */ + \ 1 + 3 /* type, sec_part of NOW() */ + \ - 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */ + \ - 1 + 2 + 8 /* type, flags3, seq_no */ + \ - 1 + Charset_collation_map_st::binary_size_max() \ - /* type, map */ \ + 1 + 8 /* type, (query) xid */ + \ + 1 + 1 + 8 /* type, flags3, sa_seq_no */ \ ) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ @@ -1627,8 +1650,7 @@ public: { return (cache_type == Log_event::EVENT_NO_CACHE); } - Log_event(const uchar *buf, const Format_description_log_event - *description_event); + Log_event(const uchar *buf, size_t event_len); virtual ~Log_event() { free_temp_buf();} void register_temp_buf(uchar* buf, bool must_free) { @@ -2330,7 +2352,7 @@ public: #endif Query_log_event(); - Query_log_event(const uchar *buf, uint event_len, + Query_log_event(const uchar *buf, size_t event_len, const Format_description_log_event *description_event, Log_event_type event_type); ~Query_log_event() @@ -2404,7 +2426,7 @@ class Query_compressed_log_event:public Query_log_event{ protected: Log_event::Byte* query_buf; // point to the uncompressed query public: - Query_compressed_log_event(const uchar *buf, uint event_len, + Query_compressed_log_event(const uchar *buf, size_t event_len, const Format_description_log_event *description_event, Log_event_type event_type); ~Query_compressed_log_event() @@ -2504,9 +2526,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Start_encryption_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event); + Start_encryption_log_event(const uchar *buf, size_t event_len); bool is_valid() const override { return crypto_scheme == 1; } @@ -2546,7 +2566,7 @@ protected: public: Version() { - m_ver[0]= m_ver[1]= m_ver[2]= '\0'; + clear(); } Version(uchar v0, uchar v1, uchar v2) { @@ -2555,6 +2575,10 @@ public: m_ver[2]= v2; } Version(const char *version, const char **endptr); + void clear() + { + m_ver[0]= m_ver[1]= m_ver[2]= '\0'; + } const uchar& operator [] (size_t i) const { DBUG_ASSERT(i < 3); @@ -2617,13 +2641,16 @@ public: LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN). */ - uint8 common_header_len; + static constexpr uint8 common_header_len= LOG_EVENT_HEADER_LEN; uint8 number_of_event_types; /* The list of post-headers' lengths followed - by the checksum alg description byte + by the checksum alg description byte. + + NOTE: This is only to be able to write this data into events for backwards + compatibility. This list is no longer used in new code. */ - uint8 *post_header_len; + static uint8 byte_data_for_post_header_len[256]; class master_version_split: public Version { public: enum {KIND_MYSQL, KIND_MARIADB}; @@ -2637,7 +2664,6 @@ public: } }; master_version_split server_version_split; - const uint8 *event_type_permutation; uint32 options_written_to_bin_log; /* The checksum algorithm used in the binlog or relaylog following this @@ -2646,15 +2672,10 @@ public: */ enum_binlog_checksum_alg used_checksum_alg; - Format_description_log_event(uint8 binlog_ver, const char* server_ver= 0, + Format_description_log_event(uint8 binlog_ver, const char* server_ver=0, enum_binlog_checksum_alg checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF); - Format_description_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event); - ~Format_description_log_event() - { - my_free(post_header_len); - } + Format_description_log_event(const uchar *buf, size_t event_len); + ~Format_description_log_event() { } Log_event_type get_type_code() override { return FORMAT_DESCRIPTION_EVENT;} my_off_t get_header_len(my_off_t) override { return LOG_EVENT_MINIMAL_HEADER_LEN; } @@ -2667,14 +2688,10 @@ public: #else bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - bool header_is_valid() const - { - return common_header_len >= LOG_EVENT_MINIMAL_HEADER_LEN && post_header_len; - } bool is_valid() const override { - return header_is_valid() && server_version_split.version_is_valid(); + return server_version_split.version_is_valid(); } int get_data_size() override @@ -2769,8 +2786,7 @@ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg, bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Intvar_log_event(const uchar *buf, - const Format_description_log_event *description_event); + Intvar_log_event(const uchar *buf, size_t event_len); ~Intvar_log_event() = default; Log_event_type get_type_code() override { return INTVAR_EVENT;} const char* get_var_type_name(); @@ -2852,8 +2868,7 @@ class Rand_log_event: public Log_event bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Rand_log_event(const uchar *buf, - const Format_description_log_event *description_event); + Rand_log_event(const uchar *buf, size_t event_len); ~Rand_log_event() = default; Log_event_type get_type_code() override { return RAND_EVENT;} int get_data_size() override { return 16; /* sizeof(ulonglong) * 2*/ } @@ -2881,9 +2896,8 @@ public: Xid_apply_log_event(THD* thd_arg): Log_event(thd_arg, 0, TRUE) {} #endif - Xid_apply_log_event(const uchar *buf, - const Format_description_log_event *description_event): - Log_event(buf, description_event) {} + Xid_apply_log_event(const uchar *buf, size_t event_len): + Log_event(buf, event_len) {} ~Xid_apply_log_event() = default; bool is_valid() const override { return 1; } @@ -2934,8 +2948,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Xid_log_event(const uchar *buf, - const Format_description_log_event *description_event); + Xid_log_event(const uchar *buf, size_t event_len); ~Xid_log_event() = default; Log_event_type get_type_code() override { return XID_EVENT;} int get_data_size() override { return sizeof(xid); } @@ -3082,8 +3095,7 @@ public: #else bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - XA_prepare_log_event(const uchar *buf, - const Format_description_log_event *description_event); + XA_prepare_log_event(const uchar *buf, size_t event_len); ~XA_prepare_log_event() = default; Log_event_type get_type_code() override { return XA_PREPARE_LOG_EVENT; } bool is_valid() const override { return m_xid.formatID != -1; } @@ -3153,8 +3165,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - User_var_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *description_event); + User_var_log_event(const uchar *buf, size_t event_len); ~User_var_log_event() = default; Log_event_type get_type_code() override { return USER_VAR_EVENT;} #ifdef MYSQL_SERVER @@ -3203,9 +3214,8 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Stop_log_event(const uchar *buf, - const Format_description_log_event *description_event): - Log_event(buf, description_event) + Stop_log_event(const uchar *buf, size_t event_len): + Log_event(buf, event_len) {} ~Stop_log_event() = default; Log_event_type get_type_code() override { return STOP_EVENT;} @@ -3299,8 +3309,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Rotate_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event); + Rotate_log_event(const uchar *buf, size_t event_len); ~Rotate_log_event() { if (flags & DUP_NAME) @@ -3338,9 +3347,7 @@ public: #else bool print(FILE *file, PRINT_EVENT_INFO *print_event_info) override; #endif - Binlog_checkpoint_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event); + Binlog_checkpoint_log_event(const uchar *buf, size_t event_len); ~Binlog_checkpoint_log_event() { my_free(binlog_file_name); } Log_event_type get_type_code() override { return BINLOG_CHECKPOINT_EVENT;} int get_data_size() override @@ -3556,8 +3563,7 @@ public: #else bool print(FILE *file, PRINT_EVENT_INFO *print_event_info) override; #endif - Gtid_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *description_event); + Gtid_log_event(const uchar *buf, size_t event_len); ~Gtid_log_event() = default; Log_event_type get_type_code() override { return GTID_EVENT; } int get_data_size() override @@ -3585,7 +3591,7 @@ public: static bool peek(const uchar *event_start, size_t event_len, enum_binlog_checksum_alg checksum_alg, uint32 *domain_id, uint32 *server_id, uint64 *seq_no, - uchar *flags2, const Format_description_log_event *fdev); + uchar *flags2); #endif }; @@ -3682,8 +3688,7 @@ public: #else bool print(FILE *file, PRINT_EVENT_INFO *print_event_info) override; #endif - Gtid_list_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *description_event); + Gtid_list_log_event(const uchar *buf, size_t event_len); ~Gtid_list_log_event() { my_free(list); my_free(sub_id_list); } Log_event_type get_type_code() override { return GTID_LIST_EVENT; } int get_data_size() override { @@ -3702,9 +3707,8 @@ public: enum_skip_reason do_shall_skip(rpl_group_info *rgi) override; #endif static bool peek(const char *event_start, size_t event_len, - enum_binlog_checksum_alg checksum_alg, - rpl_gtid **out_gtid_list, uint32 *out_list_len, - const Format_description_log_event *fdev); + enum enum_binlog_checksum_alg checksum_alg, + rpl_gtid **out_gtid_list, uint32 *out_list_len); }; @@ -3742,9 +3746,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) override; #endif - Append_block_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event); + Append_block_log_event(const uchar *buf, size_t event_len); ~Append_block_log_event() = default; Log_event_type get_type_code() override { return APPEND_BLOCK_EVENT;} int get_data_size() override { return block_len + APPEND_BLOCK_HEADER_LEN ;} @@ -3784,8 +3786,7 @@ public: bool enable_local); #endif - Delete_file_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event); + Delete_file_log_event(const uchar *buf, size_t event_len); ~Delete_file_log_event() = default; Log_event_type get_type_code() override { return DELETE_FILE_EVENT;} int get_data_size() override { return DELETE_FILE_HEADER_LEN ;} @@ -3823,9 +3824,7 @@ public: int get_create_or_append() const override; #endif /* HAVE_REPLICATION */ #endif - Begin_load_query_log_event(const uchar *buf, uint event_len, - const Format_description_log_event - *description_event); + Begin_load_query_log_event(const uchar *buf, size_t event_len); ~Begin_load_query_log_event() = default; Log_event_type get_type_code() override { return BEGIN_LOAD_QUERY_EVENT; } private: @@ -3881,7 +3880,7 @@ public: bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, const char *local_fname); #endif - Execute_load_query_log_event(const uchar *buf, uint event_len, + Execute_load_query_log_event(const uchar *buf, size_t event_len, const Format_description_log_event *description_event); ~Execute_load_query_log_event() = default; @@ -3911,14 +3910,8 @@ class Unknown_log_event: public Log_event { public: enum { UNKNOWN, ENCRYPTED } what; - /* - Even if this is an unknown event, we still pass description_event to - Log_event's ctor, this way we can extract maximum information from the - event's header (the unique ID for example). - */ - Unknown_log_event(const uchar *buf, - const Format_description_log_event *description_event): - Log_event(buf, description_event), what(UNKNOWN) + Unknown_log_event(const uchar *buf, size_t event_len): + Log_event(buf, event_len), what(UNKNOWN) {} /* constructor for hopelessly corrupted events */ Unknown_log_event(): Log_event(), what(ENCRYPTED) {} @@ -3948,8 +3941,7 @@ public: #ifndef MYSQL_CLIENT Annotate_rows_log_event(THD*, bool using_trans, bool direct); #endif - Annotate_rows_log_event(const uchar *buf, uint event_len, - const Format_description_log_event*); + Annotate_rows_log_event(const uchar *buf, size_t event_len); ~Annotate_rows_log_event(); int get_data_size() override; @@ -4609,8 +4601,7 @@ public: bool is_transactional); #endif #ifdef HAVE_REPLICATION - Table_map_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *description_event); + Table_map_log_event(const uchar *buf, size_t event_len); #endif ~Table_map_log_event(); @@ -4621,8 +4612,7 @@ public: return new table_def(m_coltype, m_colcnt, m_field_metadata, m_field_metadata_size, m_null_bits, m_flags, 0, 0); } - int rewrite_db(const char* new_name, size_t new_name_len, - const Format_description_log_event*); + int rewrite_db(const char* new_name, size_t new_name_len); #endif ulonglong get_table_id() const { return m_table_id; } const char *get_table_name() const { return m_tblnam; } @@ -4982,8 +4972,7 @@ protected: MY_BITMAP const *cols, bool is_transactional, Log_event_type event_type); #endif - Rows_log_event(const uchar *row_data, size_t event_len, - const Format_description_log_event *description_event); + Rows_log_event(const uchar *row_data, size_t event_len); void uncompress_buf(); #ifdef MYSQL_CLIENT @@ -5212,8 +5201,7 @@ public: bool is_transactional); #endif #ifdef HAVE_REPLICATION - Write_rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Write_rows_log_event(const uchar *buf, size_t event_len); #endif #if defined(MYSQL_SERVER) static bool binlog_row_logging_function(THD *thd, TABLE *table, @@ -5266,8 +5254,7 @@ public: bool write(Log_event_writer *writer) override; #endif #ifdef HAVE_REPLICATION - Write_rows_compressed_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Write_rows_compressed_log_event(const uchar *buf, size_t event_len); #endif private: #if defined(MYSQL_CLIENT) @@ -5303,8 +5290,7 @@ public: ~Update_rows_log_event() override; #ifdef HAVE_REPLICATION - Update_rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Update_rows_log_event(const uchar *buf, size_t event_len); #endif #ifdef MYSQL_SERVER @@ -5356,8 +5342,7 @@ public: bool write(Log_event_writer *writer) override; #endif #ifdef HAVE_REPLICATION - Update_rows_compressed_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Update_rows_compressed_log_event(const uchar *buf, size_t event_len); #endif private: #if defined(MYSQL_CLIENT) @@ -5395,8 +5380,7 @@ public: Delete_rows_log_event(THD*, TABLE*, ulonglong, bool is_transactional); #endif #ifdef HAVE_REPLICATION - Delete_rows_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Delete_rows_log_event(const uchar *buf, size_t event_len); #endif #ifdef MYSQL_SERVER static bool binlog_row_logging_function(THD *thd, TABLE *table, @@ -5448,8 +5432,7 @@ public: bool write(Log_event_writer *writer) override; #endif #ifdef HAVE_REPLICATION - Delete_rows_compressed_log_event(const uchar *buf, size_t event_len, - const Format_description_log_event *description_event); + Delete_rows_compressed_log_event(const uchar *buf, size_t event_len); #endif private: #if defined(MYSQL_CLIENT) @@ -5541,8 +5524,7 @@ public: bool write_data_body(Log_event_writer *writer) override; #endif - Incident_log_event(const uchar *buf, uint event_len, - const Format_description_log_event *descr_event); + Incident_log_event(const uchar *buf, size_t event_len); virtual ~Incident_log_event(); @@ -5604,8 +5586,8 @@ public: } #endif - Ignorable_log_event(const uchar *buf, - const Format_description_log_event *descr_event, + Ignorable_log_event(const uchar *buf, size_t event_len, + Log_event_type event_type, const char *event_name); virtual ~Ignorable_log_event(); @@ -5883,9 +5865,7 @@ public: end_offset(end_offset), ev_buffer_base(NULL), rows_event(rows_event){}; #endif /* MYSQL_SERVER */ - Partial_rows_log_event( - const uchar *buf, uint event_len, - const Format_description_log_event *description_event); + Partial_rows_log_event(const uchar *buf, size_t event_len); ~Partial_rows_log_event() {} @@ -5944,8 +5924,7 @@ class Heartbeat_log_event: public Log_event { public: uint8 hb_flags; - Heartbeat_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event); + Heartbeat_log_event(const uchar *buf, size_t event_len); Log_event_type get_type_code() override { return HEARTBEAT_LOG_EVENT; } bool is_valid() const override { @@ -6222,21 +6201,17 @@ int binlog_buf_compress(const uchar *src, uchar *dst, uint32 len, int binlog_buf_uncompress(const uchar *src, uchar *dst, uint32 len, uint32 *newlen); uint32 binlog_get_compress_len(uint32 len); -uint32 binlog_get_uncompress_len(const uchar *buf); +uint32 binlog_get_uncompress_len(const uchar *buf, size_t buf_len); -int query_event_uncompress(const Format_description_log_event *description_event, - bool contain_checksum, +int query_event_uncompress(bool contain_checksum, const uchar *src, ulong src_len, uchar *buf, ulong buf_size, bool* is_malloc, uchar **dst, ulong *newlen); -int row_log_event_uncompress(const Format_description_log_event - *description_event, - bool contain_checksum, +int row_log_event_uncompress(bool contain_checksum, const uchar *src, ulong src_len, uchar* buf, ulong buf_size, bool *is_malloc, uchar **dst, ulong *newlen); -time_t query_event_get_end_time( - const uchar *buf, const Format_description_log_event *description_event); +time_t query_event_get_end_time(const uchar *buf); bool is_parallel_retry_error(rpl_group_info *rgi, int err); diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 5676a142f1d..501711577fd 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -1700,32 +1700,27 @@ bool Log_event::print_base64(IO_CACHE* file, switch (ev_type) { case WRITE_ROWS_EVENT: ptr[EVENT_TYPE_OFFSET]= DELETE_ROWS_EVENT; - ev= new Delete_rows_log_event(ptr, tmp_size, - glob_description_event); + ev= new Delete_rows_log_event(ptr, tmp_size); ev->change_to_flashback_event(print_event_info, ptr, ev_type); break; case WRITE_ROWS_EVENT_V1: ptr[EVENT_TYPE_OFFSET]= DELETE_ROWS_EVENT_V1; - ev= new Delete_rows_log_event(ptr, tmp_size, - glob_description_event); + ev= new Delete_rows_log_event(ptr, tmp_size); ev->change_to_flashback_event(print_event_info, ptr, ev_type); break; case DELETE_ROWS_EVENT: ptr[EVENT_TYPE_OFFSET]= WRITE_ROWS_EVENT; - ev= new Write_rows_log_event(ptr, tmp_size, - glob_description_event); + ev= new Write_rows_log_event(ptr, tmp_size); ev->change_to_flashback_event(print_event_info, ptr, ev_type); break; case DELETE_ROWS_EVENT_V1: ptr[EVENT_TYPE_OFFSET]= WRITE_ROWS_EVENT_V1; - ev= new Write_rows_log_event(ptr, tmp_size, - glob_description_event); + ev= new Write_rows_log_event(ptr, tmp_size); ev->change_to_flashback_event(print_event_info, ptr, ev_type); break; case UPDATE_ROWS_EVENT: case UPDATE_ROWS_EVENT_V1: - ev= new Update_rows_log_event(ptr, tmp_size, - glob_description_event); + ev= new Update_rows_log_event(ptr, tmp_size); ev->change_to_flashback_event(print_event_info, ptr, ev_type); break; default: @@ -1783,43 +1778,37 @@ bool Log_event::print_base64(IO_CACHE* file, case WRITE_ROWS_EVENT: case WRITE_ROWS_EVENT_V1: { - ev= new Write_rows_log_event(ptr, size, - glob_description_event); + ev= new Write_rows_log_event(ptr, size); break; } case DELETE_ROWS_EVENT: case DELETE_ROWS_EVENT_V1: { - ev= new Delete_rows_log_event(ptr, size, - glob_description_event); + ev= new Delete_rows_log_event(ptr, size); break; } case UPDATE_ROWS_EVENT: case UPDATE_ROWS_EVENT_V1: { - ev= new Update_rows_log_event(ptr, size, - glob_description_event); + ev= new Update_rows_log_event(ptr, size); break; } case WRITE_ROWS_COMPRESSED_EVENT: case WRITE_ROWS_COMPRESSED_EVENT_V1: { - ev= new Write_rows_compressed_log_event(ptr, size, - glob_description_event); + ev= new Write_rows_compressed_log_event(ptr, size); break; } case UPDATE_ROWS_COMPRESSED_EVENT: case UPDATE_ROWS_COMPRESSED_EVENT_V1: { - ev= new Update_rows_compressed_log_event(ptr, size, - glob_description_event); + ev= new Update_rows_compressed_log_event(ptr, size); break; } case DELETE_ROWS_COMPRESSED_EVENT: case DELETE_ROWS_COMPRESSED_EVENT_V1: { - ev= new Delete_rows_compressed_log_event(ptr, size, - glob_description_event); + ev= new Delete_rows_compressed_log_event(ptr, size); break; } default: @@ -3081,13 +3070,12 @@ err: other - Error */ -int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len, - const Format_description_log_event* desc) +int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len) { DBUG_ENTER("Table_map_log_event::rewrite_db"); DBUG_ASSERT(temp_buf); - uint header_len= MY_MIN(desc->common_header_len, + uint header_len= MY_MIN(Format_description_log_event::common_header_len, LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN; int len_diff; @@ -3700,8 +3688,7 @@ bool Write_rows_compressed_log_event::print(FILE *file, uchar *new_buf; ulong len; bool is_malloc = false; - if(!row_log_event_uncompress(glob_description_event, - read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, + if(!row_log_event_uncompress(read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len)) { @@ -3737,8 +3724,7 @@ bool Delete_rows_compressed_log_event::print(FILE *file, uchar *new_buf; ulong len; bool is_malloc = false; - if(!row_log_event_uncompress(glob_description_event, - read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, + if(!row_log_event_uncompress(read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len)) { @@ -3774,8 +3760,7 @@ Update_rows_compressed_log_event::print(FILE *file, uchar *new_buf; ulong len; bool is_malloc= false; - if(!row_log_event_uncompress(glob_description_event, - read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, + if(!row_log_event_uncompress(read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len)) { diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 0c86f74e24c..d8cf96f07bf 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -2433,7 +2433,8 @@ Query_log_event::peek_is_commit_rollback(const uchar *event_start, DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF || checksum_alg == BINLOG_CHECKSUM_ALG_OFF); - if (event_len < LOG_EVENT_HEADER_LEN + QUERY_HEADER_LEN || event_len < 9) + if (unlikely(event_len < LOG_EVENT_HEADER_LEN + QUERY_HEADER_LEN || + event_len < 9)) return false; return !memcmp(event_start + (event_len-7), "\0COMMIT", 7) || !memcmp(event_start + (event_len-9), "\0ROLLBACK", 9); @@ -2481,7 +2482,7 @@ Format_description_log_event::to_packet(String *packet) *p++= common_header_len; if (!DBUG_IF("truncate_fde_post_header_len")) { - memcpy(p, post_header_len, number_of_event_types); + memcpy(p, byte_data_for_post_header_len, number_of_event_types); p+= number_of_event_types; } @@ -2649,6 +2650,14 @@ int Format_description_log_event::do_apply_event(rpl_group_info *rgi) copy_crypto_data(rli->relay_log.description_event_for_exec); delete rli->relay_log.description_event_for_exec; rli->relay_log.description_event_for_exec= this; + /* + The start of the relay log has our own generated format description + event followed by the real format description from the master. + Don't re-compute the bug bitmask from the generated event so we don't + leave a window where a wrong value is temporarily set. + */ + if (!is_relay_log_event()) + rli->calc_master_bug_bitmask(this); } DBUG_RETURN(ret); @@ -3018,7 +3027,7 @@ bool Gtid_log_event::peek(const uchar *event_start, size_t event_len, enum_binlog_checksum_alg checksum_alg, uint32 *domain_id, uint32 *server_id, uint64 *seq_no, - uchar *flags2, const Format_description_log_event *fdev) + uchar *flags2) { const uchar *p; @@ -3033,10 +3042,12 @@ Gtid_log_event::peek(const uchar *event_start, size_t event_len, DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF || checksum_alg == BINLOG_CHECKSUM_ALG_OFF); - if (event_len < (uint32)fdev->common_header_len + GTID_HEADER_LEN) + if (unlikely(event_len < + (uint32)Format_description_log_event::common_header_len + + GTID_HEADER_LEN)) return true; *server_id= uint4korr(event_start + SERVER_ID_OFFSET); - p= event_start + fdev->common_header_len; + p= event_start + Format_description_log_event::common_header_len; *seq_no= uint8korr(p); p+= 8; *domain_id= uint4korr(p); @@ -7831,8 +7842,8 @@ int Rows_log_event::update_sequence() (table_rgi && !(table_rgi->gtid_ev_flags2 & Gtid_log_event::FL_DDL) && !(old_master= - rpl_master_has_bug(thd_rgi->rli, - 29621, FALSE, FALSE, FALSE, TRUE)))) + rpl_master_has_bug(thd_rgi->rli, RPL_BUG_MDEV_29621, FALSE, + NULL, NULL)))) { /* This event come from a setval function executed on the master. Update the sequence next_number and round, like we do with setval() @@ -9004,12 +9015,12 @@ void Ignorable_log_event::pack_info(Protocol *protocol) #endif #if defined(HAVE_REPLICATION) -Heartbeat_log_event::Heartbeat_log_event(const uchar *buf, uint event_len, - const Format_description_log_event* description_event) - :Log_event(buf, description_event), ident_len(0), log_ident(NULL) +Heartbeat_log_event::Heartbeat_log_event(const uchar *buf, size_t event_len) + :Log_event(buf, event_len), ident_len(0), log_ident(NULL) { + uint8 header_size= Format_description_log_event::common_header_len; uint sub_header_len= (log_pos == 0) ? HB_SUB_HEADER_LEN : 0; - uint all_headers_len= description_event->common_header_len + sub_header_len; + uint all_headers_len= header_size + sub_header_len; /* The comparison is <= rather than <, so an event whose length stops exactly @@ -9030,7 +9041,7 @@ Heartbeat_log_event::Heartbeat_log_event(const uchar *buf, uint event_len, return; if (log_pos == 0) - log_pos= uint8korr(buf + description_event->common_header_len); + log_pos= uint8korr(buf + header_size); log_ident= buf + all_headers_len; ident_len= event_len - all_headers_len; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index e64b81aece8..d490430ea01 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -776,26 +776,33 @@ static handle_proxy_header_result handle_proxy_header(NET *net) { /* proxy-protocol-networks variable needs to be set to allow this remote address */ my_printf_error(ER_HOST_NOT_PRIVILEGED, "Proxy header is not accepted from %s", - MYF(0), thd->main_security_ctx.ip); + MYF(global_system_variables.log_warnings > 1 ? ME_ERROR_LOG : 0), + thd->main_security_ctx.ip); return ABORT; } if (parse_proxy_protocol_header(net, &peer_info)) { /* Failed to parse proxy header*/ - my_printf_error(ER_UNKNOWN_ERROR, "Failed to parse proxy header", MYF(0)); + my_printf_error(ER_UNKNOWN_ERROR, "Failed to parse proxy header", + MYF(global_system_variables.log_warnings > 1 ? ME_ERROR_LOG : 0)); return ABORT; } if (peer_info.is_local_command) /* proxy header indicates LOCAL connection, no action necessary */ return RETRY; - /* Change peer address in THD and ACL structures.*/ + /* + Change peer address in THD and ACL structures. Defer the host checks + - see parse_client_handshake_packet(). + */ uint host_errors= 0; net->using_proxy_protocol= NET_PROXY_PROTOCOL; handle_proxy_header_result res= (handle_proxy_header_result) thd_set_peer_addr(thd, &(peer_info.peer_addr), - NULL, peer_info.port, false, &host_errors); + NULL, peer_info.port, + HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP, + &host_errors); if (host_errors) net->using_proxy_protocol |= NET_PROXY_PROTOCOL_CONNECT_ERRORS; return res; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c8d1d8da84e..74edaee4dc7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4078,7 +4078,7 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len) struct st_part_prune_param; struct st_part_opt_info; -typedef void (*mark_full_part_func)(partition_info*, uint32); +typedef void (*mark_full_part_func)(struct st_part_prune_param*, uint32); /* Partition pruning operation context @@ -4139,6 +4139,12 @@ typedef struct st_part_prune_param /* Iterator to be used to obtain the "current" set of used partitions */ PARTITION_ITERATOR part_iter; + /* + Initialized bitmap of read_partitions size. + find_used_partitions() will save the set of used partitions here. + */ + MY_BITMAP parts_bitmap; + /* Initialized bitmap of num_subparts size */ MY_BITMAP subparts_bitmap; @@ -4154,7 +4160,6 @@ static int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar, SEL_IMERGE *imerge); static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar, List &merges); -static void mark_all_partitions_as_used(partition_info *part_info); #ifndef DBUG_OFF static void print_partitioning_index(KEY_PART *parts, KEY_PART *parts_end); @@ -4171,13 +4176,30 @@ static void dbug_print_singlepoint_range(SEL_ARG **start, uint num); @param table Table to perform partition pruning for @param pprune_cond Condition to use for partition pruning + @param[in] part_info->read_partitions + Candidate partitions to scan; normally all partitions (or the + PARTITION() set) + + @param[out] part_info->read_partitions + Narrowed to the partitions that may hold records matching the + condition. For a versioned table with history partitions + accessed without FOR SYSTEM_TIME, PARTITION() and + @@system_versioning_asof, also narrowed to the now-partition, + with or without a condition. Never widened. + @note This function assumes that lock_partitions are setup when it is invoked. The function analyzes the condition, finds partitions that need to be used to retrieve the records that match the condition, and - marks them as used by setting appropriate bit in part_info->read_partitions - In the worst case all partitions are marked as used. If the table is not - yet locked, it will also unset bits in part_info->lock_partitions that is - not set in read_partitions. + narrows part_info->read_partitions to them. + If the table is not yet locked, it will also unset bits in + part_info->lock_partitions that is not set in read_partitions. + + The matching set is computed independently of the incoming + read_partitions/lock_partitions: the analysis walks the whole partition + list (or only the value interval derived from the condition for + range-capable partitioning), and the result is then intersected into + read_partitions. A restriction already present in read_partitions + therefore narrows the outcome but does not reduce the pruning work. This function returns promptly if called for non-partitioned table. @@ -4195,11 +4217,40 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) if (!part_info) DBUG_RETURN(FALSE); /* not a partitioned table */ - if (!pprune_cond) + /* + Read only now_part, as vers_setup_conds() did not add the row_end condition. + Done here as prune_partitions() runs on each execution, also for merged + derived tables and views, for which vers_setup_conds() is not called + again. + */ + if (TABLE_LIST *tl= table->pos_in_table_list) { - mark_all_partitions_as_used(part_info); - DBUG_RETURN(FALSE); + if (part_info->vers_info && !tl->partition_names && + !tl->vers_conditions.was_set() && !tl->vers_conditions.from_sysvar) + { + DBUG_ASSERT(part_info->vers_info->initialized()); + uint32 end; + const uint32 start= + part_info->vers_info->now_part->bitmap_range(part_info->num_subparts, + end); + for (uint32 i= 0; i < part_info->read_partitions.n_bits; i++) + if (i < start || i >= end) + bitmap_clear_bit(&part_info->read_partitions, i); + } } + + /* + Must be a subset of the locked partitions. + lock_partitions contains the partitions marked by explicit partition + selection (... t PARTITION (pX) ...) and we must only use partitions + within that set. read_partitions may be wider on entry: e.g. + check_insert_or_replace_autoincrement() sets all bits for + INSERT/REPLACE ... SELECT. Done before the early returns below. + */ + bitmap_intersect(&part_info->read_partitions, &part_info->lock_partitions); + + if (!pprune_cond) + DBUG_RETURN(FALSE); PART_PRUNE_PARAM prune_param; MEM_ROOT alloc; @@ -4215,7 +4266,6 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) if (create_partition_index_description(&prune_param)) { - mark_all_partitions_as_used(part_info); free_root(&alloc,MYF(0)); // Return memory & allocator DBUG_RETURN(FALSE); } @@ -4240,7 +4290,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) thd->no_errors=1; // Don't warn about NULL thd->mem_root=&alloc; - bitmap_clear_all(&part_info->read_partitions); + bitmap_clear_all(&prune_param.parts_bitmap); prune_param.key= prune_param.range_param.key_parts; SEL_TREE *tree; @@ -4317,20 +4367,15 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) all_used: retval= FALSE; // some partitions are used - mark_all_partitions_as_used(prune_param.part_info); + goto all_used_end; end: + bitmap_intersect(&prune_param.part_info->read_partitions, + &prune_param.parts_bitmap); +all_used_end: dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets); thd->no_errors=0; thd->mem_root= range_par->old_root; free_root(&alloc,MYF(0)); // Return memory & allocator - /* - Must be a subset of the locked partitions. - lock_partitions contains the partitions marked by explicit partition - selection (... t PARTITION (pX) ...) and we must only use partitions - within that set. - */ - bitmap_intersect(&prune_param.part_info->read_partitions, - &prune_param.part_info->lock_partitions); /* If not yet locked, also prune partitions to lock if not UPDATEing partition key fields. This will also prune lock_partitions if we are under @@ -4396,20 +4441,21 @@ static void store_selargs_to_rec(PART_PRUNE_PARAM *ppar, SEL_ARG **start, /* Mark a partition as used in the case when there are no subpartitions */ -static void mark_full_partition_used_no_parts(partition_info* part_info, +static void mark_full_partition_used_no_parts(PART_PRUNE_PARAM *ppar, uint32 part_id) { DBUG_ENTER("mark_full_partition_used_no_parts"); DBUG_PRINT("enter", ("Mark partition %u as used", part_id)); - bitmap_set_bit(&part_info->read_partitions, part_id); + bitmap_set_bit(&ppar->parts_bitmap, part_id); DBUG_VOID_RETURN; } /* Mark a partition as used in the case when there are subpartitions */ -static void mark_full_partition_used_with_parts(partition_info *part_info, +static void mark_full_partition_used_with_parts(PART_PRUNE_PARAM *ppar, uint32 part_id) { + partition_info *part_info= ppar->part_info; uint32 start= part_id * part_info->num_subparts; uint32 end= start + part_info->num_subparts; DBUG_ENTER("mark_full_partition_used_with_parts"); @@ -4417,7 +4463,7 @@ static void mark_full_partition_used_with_parts(partition_info *part_info, for (; start != end; start++) { DBUG_PRINT("info", ("1:Mark subpartition %u as used", start)); - bitmap_set_bit(&part_info->read_partitions, start); + bitmap_set_bit(&ppar->parts_bitmap, start); } DBUG_VOID_RETURN; } @@ -4445,7 +4491,7 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar, MY_BITMAP all_merges; uint bitmap_bytes; my_bitmap_map *bitmap_buf; - uint n_bits= ppar->part_info->read_partitions.n_bits; + uint n_bits= ppar->parts_bitmap.n_bits; bitmap_bytes= bitmap_buffer_size(n_bits); if (!(bitmap_buf= (my_bitmap_map*) alloc_root(ppar->range_param.mem_root, bitmap_bytes))) @@ -4471,15 +4517,15 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar, } if (res != -1) - bitmap_intersect(&all_merges, &ppar->part_info->read_partitions); + bitmap_intersect(&all_merges, &ppar->parts_bitmap); if (bitmap_is_clear_all(&all_merges)) return 0; - bitmap_clear_all(&ppar->part_info->read_partitions); + bitmap_clear_all(&ppar->parts_bitmap); } - memcpy(ppar->part_info->read_partitions.bitmap, all_merges.bitmap, + memcpy(ppar->parts_bitmap.bitmap, all_merges.bitmap, bitmap_bytes); return 1; } @@ -4632,6 +4678,8 @@ int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar, SEL_IMERGE *imerge) -1 Couldn't infer any partition pruning "intervals" from the passed SEL_ARG* tree (which means that all partitions should be marked as used) Marking partitions as used is the responsibility of the caller. + + The set of used partitions is saved in PART_PRUNE_PARAM::parts_bitmap. */ static @@ -4850,7 +4898,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) { for (uint i= 0; i < ppar->part_info->num_subparts; i++) if (bitmap_is_set(&ppar->subparts_bitmap, i)) - bitmap_set_bit(&ppar->part_info->read_partitions, + bitmap_set_bit(&ppar->parts_bitmap, part_id * ppar->part_info->num_subparts + i); } goto pop_and_go_right; @@ -4912,7 +4960,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) != NOT_A_PARTITION_ID) { - bitmap_set_bit(&part_info->read_partitions, + bitmap_set_bit(&ppar->parts_bitmap, part_id * part_info->num_subparts + subpart_id); } res= 1; /* Some partitions were marked as used */ @@ -4967,7 +5015,7 @@ process_next_key_part: while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) != NOT_A_PARTITION_ID) { - ppar->mark_full_partition_used(ppar->part_info, part_id); + ppar->mark_full_partition_used(ppar, part_id); found= TRUE; } res= MY_TEST(found); @@ -4996,13 +5044,6 @@ pop_and_go_right: } -static void mark_all_partitions_as_used(partition_info *part_info) -{ - bitmap_copy(&(part_info->read_partitions), - &(part_info->lock_partitions)); -} - - /* Check if field types allow to construct partitioning index description @@ -5107,6 +5148,15 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) !(ppar->is_subpart_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)* total_parts))) return TRUE; + + { + my_bitmap_map *buf; + uint32 bufsize= bitmap_buffer_size(part_info->read_partitions.n_bits); + if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize))) + return TRUE; + my_bitmap_init(&ppar->parts_bitmap, buf, + part_info->read_partitions.n_bits); + } if (ppar->subpart_fields) { diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc index 452a6864f06..f944a7ac119 100644 --- a/sql/opt_range_mrr.cc +++ b/sql/opt_range_mrr.cc @@ -50,7 +50,7 @@ typedef struct st_sel_arg_range_seq KEY_PART *key_parts; SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */ - RANGE_SEQ_ENTRY stack[MAX_REF_PARTS]; + RANGE_SEQ_ENTRY stack[MAX_REF_PARTS+1]; int i; /* Index of last used element in the above array */ bool at_start; /* TRUE <=> The traversal has just started */ diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 7fc5319702c..342c5a6db0c 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -7057,7 +7057,7 @@ bool JOIN::choose_tableless_subquery_plan() */ if (zero_result_cause) { - if (!implicit_grouping) + if (!implicit_grouping && select_lex->olap != ROLLUP_TYPE) { /* Both group by queries and non-group by queries without aggregate diff --git a/sql/partition_element.h b/sql/partition_element.h index 795a7a1d56f..ef1d6121596 100644 --- a/sql/partition_element.h +++ b/sql/partition_element.h @@ -170,6 +170,19 @@ public: DBUG_ASSERT(ev->col_val_array); return ev->col_val_array[idx]; } + + /* + Leaf-bitmap (read/lock_partitions) range covered by this top-level + partition: a single bit if not subpartitioned, num_subparts bits + otherwise. Returns the first bit; bit_no_end receives one past the last. + */ + uint32 bitmap_range(uint num_subparts, uint32 &bit_no_end) const + { + uint32 sub_factor= num_subparts ? num_subparts : 1; + uint32 first= id * sub_factor; + bit_no_end= first + sub_factor; + return first; + } }; #endif /* PARTITION_ELEMENT_INCLUDED */ diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 7666997dc5e..75fab657619 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -120,7 +120,11 @@ partition_info *partition_info::get_clone(THD *thd, bool empty_data_and_index_fi if (part_type == VERSIONING_PARTITION && vers_info) { // clone Vers_part_info; set now_part, hist_part + DBUG_EXECUTE_IF("partition_info_get_clone_vers_oom", + DBUG_SET("+d,simulate_out_of_memory");); clone->vers_info= new (mem_root) Vers_part_info(*vers_info); + if (!clone->vers_info) + DBUG_RETURN(NULL); List_iterator it(clone->partitions); while ((part= it++)) { @@ -1031,10 +1035,9 @@ void partition_info::vers_check_limit(THD *thd) of partitions. */ #ifndef DBUG_OFF - const uint32 sub_factor= num_subparts ? num_subparts : 1; - uint32 part_id= vers_info->hist_part->id * sub_factor; - const uint32 part_id_end __attribute__((unused)) = part_id + sub_factor; - DBUG_ASSERT(part_id_end <= num_parts * sub_factor); + uint32 part_id_end; + vers_info->hist_part->bitmap_range(num_subparts, part_id_end); + DBUG_ASSERT(part_id_end <= get_tot_partitions()); #endif ha_partition *hp= (ha_partition*)(table->file); diff --git a/sql/partition_info.h b/sql/partition_info.h index b76033042a1..af0418b5417 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -50,15 +50,11 @@ struct Vers_part_info : public Sql_alloc hist_part(NULL) { } - Vers_part_info& operator= (const Vers_part_info &src) - { - interval= src.interval; - limit= src.limit; - auto_hist= src.auto_hist; - now_part= src.now_part; - hist_part= src.hist_part; - return *this; - } + /* + now_part and hist_part point to partition_element of a specific + partition_info, they must not be copied to another one. + */ + Vers_part_info& operator= (const Vers_part_info &src)= delete; bool initialized() { if (now_part) @@ -84,6 +80,10 @@ struct Vers_part_info : public Sql_alloc /* TODO: equivalent intervals like 1 hour and 60 mins should be considered equal */ return start == rhs.start && type == rhs.type && !memcmp(&step, &rhs.step, sizeof(INTERVAL)); } + bool operator!=(const interval_t &rhs) const + { + return !(*this == rhs); + } } interval; ulonglong limit; bool auto_hist; diff --git a/sql/proxy_protocol.cc b/sql/proxy_protocol.cc index e4fbb068244..8f16ce65b53 100644 --- a/sql/proxy_protocol.cc +++ b/sql/proxy_protocol.cc @@ -178,7 +178,7 @@ bool has_proxy_protocol_header(NET *net) */ int parse_proxy_protocol_header(NET *net, proxy_peer_info *peer_info) { - uchar hdr[MAX_PROXY_HEADER_LEN]; + uchar hdr[MAX_PROXY_HEADER_LEN + 1]; /* +1 for the NUL terminator */ size_t pos= 0; DBUG_ASSERT(!net->compress); diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 430e4a4bfc6..9cb0ea559bb 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -699,6 +699,26 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, */ suspended_wfc= thd->suspend_subsequent_commits(); thd->lex->reset_n_backup_query_tables_list(&lex_backup); + + /* + Clear OPTION_NOT_AUTOCOMMIT/OPTION_BEGIN *before* opening the table below, + not after. A storage engine may register itself into the "all" + transaction as part of the table open/lock (e.g. InnoDB's + external_lock()), depending on those bits. Clearing them only after the + table is open is too late: the engine has already registered into "all" + using the still-set bits, and since this is meant to be a standalone + autocommit-style write, nothing will later issue the matching "all"-level + commit to clear that registration and the performance-schema transaction + handle, and it leaks into whatever runs on this THD next. + */ + if (!in_transaction) + { + DBUG_PRINT("info", ("resetting OPTION_BEGIN")); + thd->variables.option_bits&= + ~(ulonglong)(OPTION_NOT_AUTOCOMMIT |OPTION_BEGIN |OPTION_BIN_LOG | + OPTION_GTID_BEGIN); + } + tlist.init_one_table(&MYSQL_SCHEMA_NAME, >id_pos_table_name, NULL, TL_WRITE); if ((err= open_and_lock_tables(thd, &tlist, FALSE, 0))) goto end; @@ -714,14 +734,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, thd->wsrep_ignore_table= true; // Do not replicate mysql.gtid_slave_pos table #endif - if (!in_transaction) - { - DBUG_PRINT("info", ("resetting OPTION_BEGIN")); - thd->variables.option_bits&= - ~(ulonglong)(OPTION_NOT_AUTOCOMMIT |OPTION_BEGIN |OPTION_BIN_LOG | - OPTION_GTID_BEGIN); - } - else + if (in_transaction) thd->variables.option_bits&= ~(ulonglong)OPTION_BIN_LOG; bitmap_set_all(table->write_set); @@ -1411,6 +1424,7 @@ rpl_slave_state::load(THD *thd, const char *state_from_master, size_t len, } if (state_from_master == end) return 0; + int err= 0; for (;;) { rpl_gtid gtid; @@ -1421,14 +1435,26 @@ rpl_slave_state::load(THD *thd, const char *state_from_master, size_t len, !(sub_id= next_sub_id(gtid.domain_id)) || record_gtid(thd, >id, sub_id, false, in_statement, &hton) || update(gtid.domain_id, gtid.server_id, sub_id, gtid.seq_no, hton, NULL)) - return 1; + { + err= 1; + break; + } if (state_from_master == end) break; if (*state_from_master != ',') - return 1; + { + err= 1; + break; + } ++state_from_master; } - return 0; + + if (unlikely(err)) + trans_rollback(thd); + else + err= trans_commit(thd); + + return err; } diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index d34d7325bee..48c877adffd 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1099,7 +1099,8 @@ bool Master_info_index::remove_master_info(Master_info *mi, bool clear_log_files /* This code is only executed when change_master() failes to create a new master info */ // Delete any temporary relay log files that could have been created by change_master() - mi->rli.relay_log.reset_logs(current_thd, 0, (rpl_gtid*) 0, 0, 0); + if (mi->rli.relay_log.is_open()) + mi->rli.relay_log.reset_logs(current_thd, 0, (rpl_gtid*) 0, 0, 0); /* Delete master-'connection'.info */ create_logfile_name_with_suffix(tmp_name, sizeof(tmp_name), diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 36a627fbd6b..e8189855cbe 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -111,8 +111,7 @@ typedef struct st_rows_event_tracker my_off_t last_seen; bool stmt_end_seen; void update(const char *file_name, my_off_t pos, - const uchar *buf, - const Format_description_log_event *fdle); + const uchar *buf); void reset(); bool check_and_report(const char* file_name, my_off_t pos); } Rows_event_tracker; @@ -350,6 +349,7 @@ class Master_info: public Master_info_file, public Slave_reporting_capability it must be ignored similarly to the replicate-same-server-id rule. */ bool do_accept_own_server_id= false; + bool semi_sync_enabled= false; /* Set to 1 when semi_sync is enabled. Set to 0 if there is any transmit problems to the slave, in which case any furter semi-sync reply is diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index bf2498ab1b5..02e0bbd546a 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -55,6 +55,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery, const char* thread_name) event_relay_log_pos(0), log_space_total(0), ignore_log_space_limit(0), sql_thread_caught_up(true), last_master_timestamp(0), newest_master_timestamp(0), slave_timestamp(0), + rpl_master_bug_bitmask(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_driver_thd(), gtid_skip_flag(GTID_SKIP_NOT), inited(0), abort_slave(0), stop_for_until(0), @@ -664,6 +665,12 @@ int init_relay_log_pos(Relay_log_info* rli,const char* log, goto err; delete rli->relay_log.description_event_for_exec; rli->relay_log.description_event_for_exec= fdev; + /* + The read_relay_log_description_event() returns the real FD from the + master found near the start of the relay log. Initialize the bitmask + of any known bugs in that master version. + */ + rli->calc_master_bug_bitmask(fdev); } my_b_seek(rli->cur_log,(off_t)pos); DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%llu rli->event_relay_log_pos=%llu", @@ -2582,4 +2589,159 @@ bool Relay_log_info::flush() DBUG_RETURN(error); } + +struct st_version_range_for_one_bug { + rpl_bug_id_t bug_id; + uint bug_num; + bool mysql_bug; // Else Mariadb MDEV + Version introduced_in; // first version with bug + Version fixed_in; // first version with fix +}; +static struct st_version_range_for_one_bug versions_for_all_bugs[]= +{ + /* + Sorted with the most recent server version first, since this is the version + that will be printed in any error messages. + */ + /* MySQL bugs. */ + {RPL_BUG_MYSQL_24432, 24432, true, { 5, 1, 12 }, { 5, 1, 17 } }, + {RPL_BUG_MYSQL_24432, 24432, true, { 5, 0, 24 }, { 5, 0, 38 } }, + {RPL_BUG_MYSQL_33029, 33029, true, { 5, 1, 0 }, { 5, 1, 12 } }, + {RPL_BUG_MYSQL_33029, 33029, true, { 5, 0, 0 }, { 5, 0, 58 } }, + {RPL_BUG_MYSQL_37426, 37426, true, { 5, 1, 0 }, { 5, 1, 26 } }, + /* MariaDB bugs (MDEV-nnnnn). */ + {RPL_BUG_MDEV_29621, 29621, false, { 10, 11,1 }, { 10, 11,3 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 10,1 }, { 10, 10,4 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 9, 2 }, { 10, 9, 6 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 8, 4 }, { 10, 8, 8 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 7, 5 }, { 10, 7, 9 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 6, 9 }, { 10, 6, 13 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 5, 17 }, { 10, 5, 20 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 4, 26 }, { 10, 4, 29 } }, + {RPL_BUG_MDEV_29621, 29621, false, { 10, 3, 36 }, { 10, 3, 39 } }, +}; + + +/** + Detect, based on the version in format description event, any bugs on the + master that we have a work-around for on the slave. Calculate a bitmask + for this with a bit set for any detected bug. +*/ +void +Relay_log_info::calc_master_bug_bitmask(const Format_description_log_event * + fd_event) +{ + const Version &master_ver= fd_event->server_version_split; + uint all_size= + sizeof(versions_for_all_bugs)/sizeof(versions_for_all_bugs[0]); + rpl_bug_id_t bitmask= 0; + for (uint i= 0; i < all_size; i++) + { + const Version &introduced_in= versions_for_all_bugs[i].introduced_in; + const Version &fixed_in= versions_for_all_bugs[i].fixed_in; + if (introduced_in <= master_ver && fixed_in > master_ver) + { + bitmask|= (1 << versions_for_all_bugs[i].bug_id); + } + } + rpl_master_bug_bitmask.store(bitmask, std::memory_order_relaxed); +} + + +/** + Detects, based on version of master's format description event, if master + has a certain bug. The bitset of bugs was pre-calculated by + Relay_log_info::calc_master_bug_bitmask(). + + The bitset is read out of the Relay_log_info without locking. However this + is ok, as the set of master bugs can only change with a master server + restart, and we do not replicate in parallel events crossing a master + restart (as identified by its restart format description event). + + @param rli The Relay_log_info contains the pre-computed bug bitset. + @param bug_id Identifier of the bug as defined in enum_rpl_master_bug_ids. + @param report bool report error message. + + @param pred Predicate function that will be called with @c param to + check for the bug. If the function return @c true, the bug is present, + otherwise, it is not. + + @param param State passed to @c pred function. + + @return TRUE if master has the bug, FALSE if it does not. +*/ +bool +rpl_master_has_bug_ext(const Relay_log_info *rli, rpl_bug_id_t bug_id, + bool report, + bool (*pred)(const void *), const void *param) +{ + rpl_bug_id_t mask= + rli->rpl_master_bug_bitmask.load(std::memory_order_relaxed); + if (!(mask & (1 << bug_id))) + return false; + if (pred != NULL && !(*pred)(param)) + return false; + if (!report) + return true; + uint all_size= + sizeof(versions_for_all_bugs)/sizeof(versions_for_all_bugs[0]); + for (uint i= 0; i < all_size; i++) + { + const Version &fixed_in= versions_for_all_bugs[i].fixed_in; + if (versions_for_all_bugs[i].bug_id == bug_id) + { + const char *bug_source= versions_for_all_bugs[i].mysql_bug ? + "http://bugs.mysql.com/bug.php?id=" : + "https://jira.mariadb.org/browse/MDEV-"; + // a short message for SHOW SLAVE STATUS (message length constraints). + my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from" + " %s%u" + " so slave stops; check error log on slave" + " for more info", MYF(0), bug_source, + versions_for_all_bugs[i].bug_num); + // a verbose message for the error log. + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, NULL, + "Master's version is earlier than %d.%d.%d," + " it is probable that master suffers from this bug:" + " %s%u" + " and thus replicating the current binary log event" + " may make the slave's data become different from the" + " master's data." + " To take no risk, slave refuses to replicate" + " this event and stops." + " We recommend that all updates be stopped on the" + " master and slave, that the data of both be" + " manually synchronized," + " that master's binary logs be deleted," + " that master be upgraded to a version at least" + " equal to '%d.%d.%d'. Then replication can be" + " restarted.", + fixed_in[0], fixed_in[1], fixed_in[2], + bug_source, + versions_for_all_bugs[i].bug_num, + fixed_in[0], fixed_in[1], fixed_in[2]); + return true; + } + } + DBUG_ASSERT(0 /* Impossible, as bitmap calculated from the same table. */); + my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from a serious bug" + " so slave stops", MYF(0)); + rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, NULL, + "Master's version is old," + " it is probable that master suffers from a serious bug" + " and thus replicating the current binary log event" + " may make the slave's data become different from the" + " master's data." + " To take no risk, slave refuses to replicate" + " this event and stops." + " We recommend that all updates be stopped on the" + " master and slave, that the data of both be" + " manually synchronized," + " that master's binary logs be deleted," + " that master be upgraded to a recent version" + " Then replication can be" + " restarted."); + return true; +} + #endif diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index e0e3d107c15..38053e12df0 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -296,6 +296,20 @@ public: then set to when + exec_time -1 of the first seen event. */ time_t slave_timestamp; + + /** + Bitmask of bugs present in the master version of the current + description_event_for_exec. Of atomic type, since it is written when + applying master's format description events, and read concurrently without + locking from parallel replication worker threads. Though note that the + value will only change during a master restart, and we do not replicate + events concurrently across such restart event, so the value will not change + in practice while worker threads are working. + */ + std::atomic rpl_master_bug_bitmask; + static_assert(sizeof(rpl_bug_id_t) > ((RPL_BUG_END - 1) >> 3), + "rpl_master_bug_bitmask too small to hold all bits"); + void clear_until_condition(); /** Reset the delay. @@ -573,6 +587,7 @@ public: int32 get_sql_delay() { return sql_delay; } void set_sql_delay(int32 _sql_delay) { sql_delay= _sql_delay; } time_t get_sql_delay_end() { return sql_delay_end; } + void calc_master_bug_bitmask(const Format_description_log_event * fd_event); rpl_gtid last_seen_gtid; ulong last_trans_retry_count; private: @@ -1154,4 +1169,19 @@ int event_group_new_gtid(rpl_group_info *rgi, Gtid_log_event *gev); void delete_or_keep_event_post_apply(rpl_group_info *rgi, Log_event_type typ, Log_event *ev); +bool +rpl_master_has_bug_ext(const Relay_log_info *rli, rpl_bug_id_t bug_id, + bool report, + bool (*pred)(const void *), const void *param); +static inline bool +rpl_master_has_bug(const Relay_log_info *rli, rpl_bug_id_t bug_id, + bool report, bool (*pred)(const void *), const void *param) +{ + rpl_bug_id_t mask= + rli->rpl_master_bug_bitmask.load(std::memory_order_relaxed); + if (likely(!(mask & (1 << bug_id)))) + return false; + return rpl_master_has_bug_ext(rli, bug_id, report, pred, param); +} + #endif /* RPL_RLI_H */ diff --git a/sql/rpl_utility_server.cc b/sql/rpl_utility_server.cc index b5678ee6016..aee330660f7 100644 --- a/sql/rpl_utility_server.cc +++ b/sql/rpl_utility_server.cc @@ -776,9 +776,8 @@ static void show_sql_type(const Conv_source &src, const Field &dst, acceptable according to the current settings. @param order The computed order of the conversion needed. - @param rli The relay log info data structure: for error reporting. */ -static bool is_conversion_ok(enum_conv_type type, const Relay_log_info *rli, +static bool is_conversion_ok(enum_conv_type type, ulonglong type_conversion_options) { DBUG_ENTER("is_conversion_ok"); @@ -953,7 +952,7 @@ table_def::compatible_with(THD *thd, rpl_group_info *rgi, Conv_source source(field_handler, field_metadata(col), field->charset()); enum_conv_type convtype= can_convert_field_to(field, source, rli, Conv_param(m_flags)); - if (is_conversion_ok(convtype, rli, slave_type_conversions_options)) + if (is_conversion_ok(convtype, slave_type_conversions_options)) { DBUG_PRINT("debug", ("Checking column %d -" " field '%s' can be converted - order: %d", diff --git a/sql/semisync_slave.cc b/sql/semisync_slave.cc index 32e53dab758..45e03fa6f4c 100644 --- a/sql/semisync_slave.cc +++ b/sql/semisync_slave.cc @@ -46,7 +46,8 @@ int rpl_semi_sync_enabled(THD *thd, SHOW_VAR *var, void *buff, system_status_var *status_var, enum_var_type scope) { - local_semi_sync_enabled= repl_semisync_slave.get_slave_enabled(); + //TODO MDEV-40941 + local_semi_sync_enabled= repl_semisync_slave.m_slave_enabled; var->type= SHOW_BOOL; var->value= (char*) &local_semi_sync_enabled; return 0; @@ -55,14 +56,14 @@ int rpl_semi_sync_enabled(THD *thd, SHOW_VAR *var, void *buff, int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, unsigned long total_len, - int *semi_flags, + Master_info *mi, const uchar **payload, unsigned long *payload_len) { int read_res = 0; DBUG_ENTER("Repl_semi_sync_slave::slave_read_sync_header"); - if (get_slave_enabled()) + if (get_slave_enabled(mi)) { if (!DBUG_IF("semislave_corrupt_log") && header[0] == k_packet_magic_num) @@ -76,9 +77,9 @@ int Repl_semi_sync_slave::slave_read_sync_header(const uchar *header, semi_sync_need_reply)); if (semi_sync_need_reply) - *semi_flags |= SEMI_SYNC_NEED_ACK; + mi->semi_ack |= SEMI_SYNC_NEED_ACK; if (is_delay_master()) - *semi_flags |= SEMI_SYNC_SLAVE_DELAY_SYNC; + mi->semi_ack |= SEMI_SYNC_SLAVE_DELAY_SYNC; } else { @@ -111,7 +112,7 @@ void Repl_semi_sync_slave::slave_start(Master_info *mi) */ bool semi_sync= global_rpl_semi_sync_slave_enabled; - set_slave_enabled(semi_sync); + set_slave_enabled(mi, semi_sync); mi->semi_sync_reply_enabled= 0; sql_print_information("Slave I/O thread: Start %s replication to\ @@ -127,7 +128,7 @@ void Repl_semi_sync_slave::slave_start(Master_info *mi) void Repl_semi_sync_slave::slave_stop(Master_info *mi) { - if (get_slave_enabled()) + if (get_slave_enabled(mi)) { #ifdef ENABLED_DEBUG_SYNC /* @@ -144,7 +145,7 @@ void Repl_semi_sync_slave::slave_stop(Master_info *mi) kill_connection(mi); } - set_slave_enabled(0); + set_slave_enabled(mi, 0); } void Repl_semi_sync_slave::slave_reconnect(Master_info *mi) @@ -153,7 +154,7 @@ void Repl_semi_sync_slave::slave_reconnect(Master_info *mi) Start semi-sync either if it globally enabled or if was enabled before the reconnect. */ - if (global_rpl_semi_sync_slave_enabled || get_slave_enabled()) + if (global_rpl_semi_sync_slave_enabled || get_slave_enabled(mi)) slave_start(mi); } @@ -215,7 +216,7 @@ int Repl_semi_sync_slave::request_transmit(Master_info *mi) MYSQL_ROW row; const char *query; - if (!get_slave_enabled()) + if (!get_slave_enabled(mi)) return 0; query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'"; @@ -223,7 +224,7 @@ int Repl_semi_sync_slave::request_transmit(Master_info *mi) !(res= mysql_store_result(mysql))) { sql_print_error("Execution failed on master: %s, error :%s", query, mysql_error(mysql)); - set_slave_enabled(0); + set_slave_enabled(mi, 0); return 1; } @@ -234,7 +235,7 @@ int Repl_semi_sync_slave::request_transmit(Master_info *mi) if (!row) sql_print_warning("Master server does not support semi-sync, " "fallback to asynchronous replication"); - set_slave_enabled(0); + set_slave_enabled(mi, 0); mysql_free_result(res); return 0; } @@ -253,7 +254,7 @@ int Repl_semi_sync_slave::request_transmit(Master_info *mi) if (mysql_real_query(mysql, query, (ulong)strlen(query))) { sql_print_error("%s on master failed", query); - set_slave_enabled(0); + set_slave_enabled(mi, 0); return 1; } mi->semi_sync_reply_enabled= 1; @@ -276,7 +277,7 @@ int Repl_semi_sync_slave::slave_reply(Master_info *mi) int reply_res = 0; size_t name_len = strlen(binlog_filename); DBUG_ENTER("Repl_semi_sync_slave::slave_reply"); - DBUG_ASSERT(get_slave_enabled() && mi->semi_sync_reply_enabled); + DBUG_ASSERT(get_slave_enabled(mi) && mi->semi_sync_reply_enabled); /* Prepare the buffer of the reply. */ reply_buffer[REPLY_MAGIC_NUM_OFFSET] = k_packet_magic_num; diff --git a/sql/semisync_slave.h b/sql/semisync_slave.h index 79949067de8..776891e1e09 100644 --- a/sql/semisync_slave.h +++ b/sql/semisync_slave.h @@ -17,6 +17,7 @@ #ifndef SEMISYNC_SLAVE_H #define SEMISYNC_SLAVE_H +#ifdef HAVE_REPLICATION #include "semisync.h" #include "my_global.h" @@ -45,12 +46,12 @@ public: */ int init_object(); - inline bool get_slave_enabled() { - return m_slave_enabled; + inline bool get_slave_enabled(Master_info *mi) { + return mi->semi_sync_enabled; } - void set_slave_enabled(bool enabled) { - m_slave_enabled = enabled; + void set_slave_enabled(Master_info *mi, bool enabled) { + m_slave_enabled= mi->semi_sync_enabled= enabled; } inline bool is_delay_master(){ @@ -71,8 +72,8 @@ public: * Input: * header - (IN) packet header pointer * total_len - (IN) total packet length: metadata + payload - * semi_flags - (IN) store flags: SEMI_SYNC_SLAVE_DELAY_SYNC and - SEMI_SYNC_NEED_ACK + * mi - (IN) store flags: SEMI_SYNC_SLAVE_DELAY_SYNC and + SEMI_SYNC_NEED_ACK, to Master_info::semi_ack * payload - (IN) payload: the replication event * payload_len - (IN) payload length * @@ -80,7 +81,7 @@ public: * 0: success; non-zero: error */ int slave_read_sync_header(const uchar *header, unsigned long total_len, - int *semi_flags, + Master_info *mi, const uchar **payload, unsigned long *payload_len); /* A slave replies to the master indicating its replication process. It @@ -94,10 +95,11 @@ public: int request_transmit(Master_info *mi); void kill_connection(Master_info *mi); + /// @deprecated For `Rpl_semi_sync_slave_status` compatibility only + bool m_slave_enabled; private: /* True when init_object has been called */ bool m_init_done; - bool m_slave_enabled; /* semi-sync is enabled on the slave */ bool m_delay_master; unsigned int m_kill_conn_timeout; }; @@ -115,4 +117,5 @@ extern unsigned long long rpl_semi_sync_slave_send_ack; extern int rpl_semi_sync_enabled(THD *thd, SHOW_VAR *var, void *buff, system_status_var *status_var, enum_var_type scope); +#endif /* HAVE_REPLICATION */ #endif /* SEMISYNC_SLAVE_H */ diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 873675d6ea4..a403ac540fa 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -220,7 +220,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) { my_safe_printf_stderr("%s", "The information page at " - "https://mariadb.com/docs/server/reference/product-development/mariadb-fault-finding/how-to-produce-a-full-stack-trace-for-mariadbd" + "https://mariadb.com/docs/server/reference/product-development/mariadb-fault-finding/how-to-produce-a-full-stack-trace-for-mariadbd\n" "contains instructions to obtain a better version of the backtrace below.\n" "Following these instructions will help MariaDB developers provide a fix quicker.\n\n" "Attempting backtrace. Include this in the bug report.\n" diff --git a/sql/slave.cc b/sql/slave.cc index abe0650616a..f90dc741ef5 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4816,7 +4816,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); if (repl_semisync_slave. slave_read_sync_header((const uchar*) mysql->net.read_pos + 1, event_len, - &(mi->semi_ack), &event_buf, &event_len)) + mi, &event_buf, &event_len)) { mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER_THD(thd, ER_SLAVE_FATAL_ERROR), @@ -4873,7 +4873,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); goto err; } - if (repl_semisync_slave.get_slave_enabled() && + if (repl_semisync_slave.get_slave_enabled(mi) && mi->semi_sync_reply_enabled && (mi->semi_ack & SEMI_SYNC_NEED_ACK)) { @@ -4917,7 +4917,7 @@ Stopping slave I/O thread due to out-of-memory error from master"); master info only when ack is needed. This may lead to at least one group transaction delay but affords better performance improvement. */ - (!repl_semisync_slave.get_slave_enabled() || + (!repl_semisync_slave.get_slave_enabled(mi) || (!(mi->semi_ack & SEMI_SYNC_SLAVE_DELAY_SYNC) || (mi->semi_ack & (SEMI_SYNC_NEED_ACK)))) && (DBUG_IF("failed_flush_master_info") || @@ -6024,17 +6024,6 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) goto err; case ROTATE_EVENT: { - /* - This is normally done in Log_event::read_log_event(), - but we bypass it here because it's expensive and costs dynamic memory. - */ - if (unlikely(ROTATE_EVENT > - mi->rli.relay_log.description_event_for_queue->number_of_event_types)) - { - // The current FDE does not support `ROTATE_EVENT`. - error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; - goto err; - } /* RSC_1 and RSC_2 below rewrite the fake Rotate (the one that opens a connection, naming the binary log file the dump starts in; the file @@ -6076,8 +6065,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) } Rotate_log_event rev(buf, event_has_checksum ? - event_len - BINLOG_CHECKSUM_LEN : event_len, - mi->rli.relay_log.description_event_for_queue); + event_len - BINLOG_CHECKSUM_LEN : event_len); bool master_changed= false; bool maybe_crashed= false; // Exclude server start scenario @@ -6306,8 +6294,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) Heartbeat_log_event hb(buf, mi->rli.relay_log.relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_OFF ? - event_len - BINLOG_CHECKSUM_LEN : event_len, - mi->rli.relay_log.description_event_for_queue); + event_len - BINLOG_CHECKSUM_LEN : event_len); if (!hb.is_valid()) { error= ER_SLAVE_HEARTBEAT_FAILURE; @@ -6433,8 +6420,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) if (Gtid_log_event::peek(buf, event_len, checksum_alg, &event_gtid.domain_id, &event_gtid.server_id, - &event_gtid.seq_no, >id_flag, - rli->relay_log.description_event_for_queue)) + &event_gtid.seq_no, >id_flag)) { error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; goto err; @@ -6601,7 +6587,7 @@ dbug_gtid_accept: */ mi->do_accept_own_server_id= (s_id == global_system_variables.server_id && - repl_semisync_slave.get_slave_enabled() && opt_gtid_strict_mode && + repl_semisync_slave.get_slave_enabled(mi) && opt_gtid_strict_mode && mi->using_gtid != Master_info::USE_GTID_NO && !mysql_bin_log.check_strict_gtid_sequence(event_gtid.domain_id, event_gtid.server_id, @@ -6616,8 +6602,7 @@ dbug_gtid_accept: case QUERY_COMPRESSED_EVENT: inc_pos= event_len; if ((error= - query_event_uncompress(rli->relay_log.description_event_for_queue, - checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, + query_event_uncompress(checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, buf, event_len, new_buf_arr, sizeof(new_buf_arr), &is_malloc, &new_buf, &event_len))) @@ -6641,8 +6626,7 @@ dbug_gtid_accept: inc_pos = event_len; { if ((error= - row_log_event_uncompress(rli->relay_log.description_event_for_queue, - checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, + row_log_event_uncompress(checksum_alg == BINLOG_CHECKSUM_ALG_CRC32, buf, event_len, new_buf_arr, sizeof(new_buf_arr), &is_malloc, &new_buf, &event_len))) @@ -6673,9 +6657,7 @@ dbug_gtid_accept: is_rows_event= true; mi->rows_event_tracker.update(mi->master_log_name, mi->master_log_pos, - buf, - mi->rli.relay_log. - description_event_for_queue); + buf); DBUG_EXECUTE_IF("simulate_stmt_end_rows_event_loss", { @@ -6952,8 +6934,7 @@ dbug_gtid_accept: if (LOG_EVENT_IS_QUERY((Log_event_type) buf[EVENT_TYPE_OFFSET]) || LOG_EVENT_IS_LOAD_DATA((Log_event_type) buf[EVENT_TYPE_OFFSET])) { - time_t end_time= query_event_get_end_time( - buf, rli->relay_log.description_event_for_queue); + time_t end_time= query_event_get_end_time(buf); set_if_bigger(rli->newest_master_timestamp, end_time); } else if (((Log_event_type) buf[EVENT_TYPE_OFFSET]) == XID_EVENT) @@ -7869,104 +7850,6 @@ end: } -/** - Detects, based on master's version (as found in the relay log), if master - has a certain bug. - @param rli Relay_log_info which tells the master's version - @param bug_id Number of the bug as found in bugs.mysql.com - @param report bool report error message, default TRUE - - @param pred Predicate function that will be called with @c param to - check for the bug. If the function return @c true, the bug is present, - otherwise, it is not. - - @param param State passed to @c pred function. - - @return TRUE if master has the bug, FALSE if it does not. -*/ -bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, - bool (*pred)(const void *), const void *param, - bool maria_master) -{ - struct st_version_range_for_one_bug { - uint bug_id; - Version introduced_in; // first version with bug - Version fixed_in; // first version with fix - }; - static struct st_version_range_for_one_bug versions_for_their_bugs[]= - { - {24432, { 5, 0, 24 }, { 5, 0, 38 } }, - {24432, { 5, 1, 12 }, { 5, 1, 17 } }, - {33029, { 5, 0, 0 }, { 5, 0, 58 } }, - {33029, { 5, 1, 0 }, { 5, 1, 12 } }, - {37426, { 5, 1, 0 }, { 5, 1, 26 } }, - }; - static struct st_version_range_for_one_bug versions_for_our_bugs[]= - { - {29621, { 10, 3, 36 }, { 10, 3, 39 } }, - {29621, { 10, 4, 26 }, { 10, 4, 29 } }, - {29621, { 10, 5, 17 }, { 10, 5, 20 } }, - {29621, { 10, 6, 9 }, { 10, 6, 13 } }, - {29621, { 10, 7, 5 }, { 10, 7, 9 } }, - {29621, { 10, 8, 4 }, { 10, 8, 8 } }, - {29621, { 10, 9, 2 }, { 10, 9, 6 } }, - {29621, { 10, 10,1 }, { 10, 10,4 } }, - {29621, { 10, 11,1 }, { 10, 11,3 } }, - }; - const Version &master_ver= - rli->relay_log.description_event_for_exec->server_version_split; - struct st_version_range_for_one_bug* versions_for_all_bugs= maria_master ? - versions_for_our_bugs : versions_for_their_bugs; - uint all_size= maria_master ? - sizeof(versions_for_our_bugs)/sizeof(*versions_for_our_bugs) : - sizeof(versions_for_their_bugs)/sizeof(*versions_for_their_bugs); - - for (uint i= 0; i < all_size; i++) - { - const Version &introduced_in= versions_for_all_bugs[i].introduced_in; - const Version &fixed_in= versions_for_all_bugs[i].fixed_in; - if ((versions_for_all_bugs[i].bug_id == bug_id) && - introduced_in <= master_ver && - fixed_in > master_ver && - (pred == NULL || (*pred)(param))) - { - const char *bug_source= maria_master ? - "https://jira.mariadb.org/browse/MDEV-" : - "http://bugs.mysql.com/bug.php?id="; - if (!report) - return TRUE; - // a short message for SHOW SLAVE STATUS (message length constraints) - my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from" - " %s%u" - " so slave stops; check error log on slave" - " for more info", MYF(0), bug_source, bug_id); - // a verbose message for the error log - rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, NULL, - "According to the master's version ('%s')," - " it is probable that master suffers from this bug:" - " %s%u" - " and thus replicating the current binary log event" - " may make the slave's data become different from the" - " master's data." - " To take no risk, slave refuses to replicate" - " this event and stops." - " We recommend that all updates be stopped on the" - " master and slave, that the data of both be" - " manually synchronized," - " that master's binary logs be deleted," - " that master be upgraded to a version at least" - " equal to '%d.%d.%d'. Then replication can be" - " restarted.", - rli->relay_log.description_event_for_exec->server_version, - bug_source, - bug_id, - fixed_in[0], fixed_in[1], fixed_in[2]); - return TRUE; - } - } - return FALSE; -} - /** BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12 exclusive, if one statement in a SP generated AUTO_INCREMENT value @@ -7982,25 +7865,23 @@ bool rpl_master_erroneous_autoinc(THD *thd) if (thd->rgi_slave) { DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;); - return rpl_master_has_bug(thd->rgi_slave->rli, 33029, FALSE, NULL, NULL); + return rpl_master_has_bug(thd->rgi_slave->rli, RPL_BUG_MYSQL_33029, FALSE, + NULL, NULL); } return FALSE; } -static bool get_row_event_stmt_end(const uchar *buf, - const Format_description_log_event *fdle) +static bool get_row_event_stmt_end(const uchar *buf) { - uint8 const common_header_len= fdle->common_header_len; - Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET]; - - uint8 const post_header_len= fdle->post_header_len[event_type-1]; + uint8 const common_header_len= + Format_description_log_event::common_header_len; const uchar *flag_start= buf + common_header_len; /* The term 4 below signifies that master is of 'an intermediate source', see Rows_log_event::Rows_log_event. */ - flag_start += RW_MAPID_OFFSET + ((post_header_len == 6) ? 4 : RW_FLAGS_OFFSET); + flag_start += RW_MAPID_OFFSET + RW_FLAGS_OFFSET; return (uint2korr(flag_start) & Rows_log_event::STMT_END_F) != 0; } @@ -8026,8 +7907,7 @@ void Rows_event_tracker::reset() */ void Rows_event_tracker::update(const char *file_name, my_off_t pos, - const uchar *buf, - const Format_description_log_event *fdle) + const uchar *buf) { DBUG_ENTER("Rows_event_tracker::update"); if (!first_seen) @@ -8037,7 +7917,7 @@ void Rows_event_tracker::update(const char *file_name, my_off_t pos, } last_seen= pos; DBUG_ASSERT(stmt_end_seen == 0); // We can only have one - stmt_end_seen= get_row_event_stmt_end(buf, fdle); + stmt_end_seen= get_row_event_stmt_end(buf); DBUG_VOID_RETURN; }; diff --git a/sql/slave.h b/sql/slave.h index 4347f6b1720..cdc44d9ce1d 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -228,9 +228,6 @@ bool show_master_info(THD* thd, Master_info* mi, bool full); bool show_all_master_info(THD* thd); void show_binlog_info_get_fields(THD *thd, List *field_list); bool show_binlog_info(THD* thd); -bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, - bool (*pred)(const void *), const void *param, - bool maria_master= false); bool rpl_master_erroneous_autoinc(THD* thd); const char *print_slave_db_safe(const char *db); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 696b7959ca2..7c323f94e7a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -587,6 +587,7 @@ sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent, m_thd_root(NULL), m_thd(NULL), m_pcont(new (&main_mem_root) sp_pcontext()), + m_pcont_list(NULL), m_cont_level(0) { mem_root= &main_mem_root; @@ -910,6 +911,17 @@ sp_head::~sp_head() for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) delete i; delete_dynamic(&m_instr); + + /* + Free the parse contexts iteratively, freeing them recursively overran + the thread stack on deeply nested BEGIN blocks. + */ + for (sp_pcontext *ctx= m_pcont_list; ctx; ) + { + sp_pcontext *next= ctx->m_next_pcont; + delete ctx; + ctx= next; + } delete m_pcont; free_items(); @@ -1718,7 +1730,8 @@ sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value, { DBUG_ASSERT(args); Row_definition_list defs; - m_pcont->retrieve_field_definitions(&defs); + if (m_pcont->retrieve_field_definitions(thd, &defs)) + return NULL; if (defs.adjust_formal_params_to_actual_params(thd, args)) return NULL; return rcontext_create(thd, ret_value, &defs, true); @@ -1729,7 +1742,8 @@ sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value, Item **args, uint arg_count) { Row_definition_list defs; - m_pcont->retrieve_field_definitions(&defs); + if (m_pcont->retrieve_field_definitions(thd, &defs)) + return NULL; if (defs.adjust_formal_params_to_actual_params(thd, args, arg_count)) return NULL; return rcontext_create(thd, ret_value, &defs, true); @@ -1834,8 +1848,8 @@ sp_head::execute_trigger(THD *thd, thd->set_n_backup_active_arena(&call_arena, &backup_arena); Row_definition_list defs; - m_pcont->retrieve_field_definitions(&defs); - if (!(nctx= rcontext_create(thd, NULL, &defs, false))) + if (m_pcont->retrieve_field_definitions(thd, &defs) || + !(nctx= rcontext_create(thd, NULL, &defs, false))) { err_status= TRUE; goto err_with_cleanup; diff --git a/sql/sp_head.h b/sql/sp_head.h index af569eb782b..b505298163a 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1008,6 +1008,16 @@ public: sp_pcontext *get_parse_context() { return m_pcont; } + /* + Remember a parse context of this routine, so that ~sp_head frees the + whole tree iteratively instead of recursing down sp_pcontext's children + */ + void remember_pcontext(sp_pcontext *ctx) + { + ctx->m_next_pcont= m_pcont_list; + m_pcont_list= ctx; + } + /* Check EXECUTE access: - in case of a standalone routine, for the routine itself @@ -1028,6 +1038,7 @@ protected: THD *m_thd; ///< Set if we have reset mem_root sp_pcontext *m_pcont; ///< Parse context + sp_pcontext *m_pcont_list; ///< Head of context list, freed by ~sp_head List m_lex; ///< Temp. store for the other lex DYNAMIC_ARRAY m_instr; ///< The "instructions" diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 5d6948268f8..6aa98a883db 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -19,6 +19,7 @@ #include "unireg.h" #include "sp_pcontext.h" #include "sp_head.h" +#include "sql_parse.h" bool sp_condition_value::equals(const sp_condition_value *cv) const { @@ -96,7 +97,7 @@ void sp_pcontext::init(uint var_offset, sp_pcontext::sp_pcontext() : Sql_alloc(), m_max_var_index(0), m_max_cursor_index(0), - m_parent(NULL), m_pboundary(0), + m_parent(NULL), m_next_pcont(NULL), m_pboundary(0), m_vars(PSI_INSTRUMENT_MEM), m_case_expr_ids(PSI_INSTRUMENT_MEM), m_conditions(PSI_INSTRUMENT_MEM), m_cursors(PSI_INSTRUMENT_MEM), m_handlers(PSI_INSTRUMENT_MEM), @@ -109,7 +110,7 @@ sp_pcontext::sp_pcontext() sp_pcontext::sp_pcontext(sp_pcontext *prev, sp_pcontext::enum_scope scope) : Sql_alloc(), m_max_var_index(0), m_max_cursor_index(0), - m_parent(prev), m_pboundary(0), + m_parent(prev), m_next_pcont(NULL), m_pboundary(0), m_vars(PSI_INSTRUMENT_MEM), m_case_expr_ids(PSI_INSTRUMENT_MEM), m_conditions(PSI_INSTRUMENT_MEM), m_cursors(PSI_INSTRUMENT_MEM), m_handlers(PSI_INSTRUMENT_MEM), @@ -121,19 +122,16 @@ sp_pcontext::sp_pcontext(sp_pcontext *prev, sp_pcontext::enum_scope scope) } -sp_pcontext::~sp_pcontext() -{ - for (size_t i= 0; i < m_children.elements(); ++i) - delete m_children.at(i); -} - - -sp_pcontext *sp_pcontext::push_context(THD *thd, sp_pcontext::enum_scope scope) +sp_pcontext *sp_pcontext::push_context(THD *thd, sp_head *sphead, + sp_pcontext::enum_scope scope) { sp_pcontext *child= new (thd->mem_root) sp_pcontext(this, scope); if (child) + { m_children.append(child); + sphead->remember_pcontext(child); + } return child; } @@ -671,9 +669,12 @@ const sp_pcursor *sp_pcontext::find_cursor(const LEX_CSTRING *name, } -void sp_pcontext::retrieve_field_definitions( - List *field_def_lst) const +bool sp_pcontext::retrieve_field_definitions( + THD *thd, List *field_def_lst) const { + if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL)) + return true; + size_t next_child_idx= 0; size_t next_variable_idx= 0; @@ -683,15 +684,16 @@ void sp_pcontext::retrieve_field_definitions( { // No variables left, just retrieve the remaining children contexts for (size_t i= next_child_idx; i < m_children.elements(); ++i) - m_children.at(i)->retrieve_field_definitions(field_def_lst); - return; + if (m_children.at(i)->retrieve_field_definitions(thd, field_def_lst)) + return true; + return false; } if (next_child_idx >= m_children.elements()) { // No child contexts left, just retrieve the remaining variables for (size_t i= next_variable_idx; i < m_vars.elements(); ++i) field_def_lst->push_back(&m_vars.at(i)->field_def); - return; + return false; } sp_variable *next_variable= m_vars.at(next_variable_idx); @@ -740,11 +742,13 @@ void sp_pcontext::retrieve_field_definitions( DBUG_ASSERT(next_child_idx + 1 < m_children.elements() ? next_child->after_last_variable_offset() <= next_variable->offset : next_child->after_last_variable_offset() == next_variable->offset); - next_child->retrieve_field_definitions(field_def_lst); + if (next_child->retrieve_field_definitions(thd, field_def_lst)) + return true; next_child_idx++; } } + return false; } diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index f0d0c26cfb0..081afa83cf0 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -369,9 +369,13 @@ public: /// - for error checking (e.g. to check correct number of parameters); /// - to resolve SQL-handlers. +class sp_head; + class sp_pcontext : public Sql_alloc, public sp_type_def_list { + friend class sp_head; + public: enum enum_scope { @@ -414,15 +418,19 @@ public: public: sp_pcontext(); - ~sp_pcontext(); + /* + No destructor: sp_head owns the tree and frees it. Freeing the children + here recursed and overran the thread stack on deeply nested BEGIN blocks + */ /// Create and push a new context in the tree. - /// @param thd thread context. - /// @param scope scope of the new parsing context. + /// @param thd thread context. + /// @param sphead the routine owning the tree, which remembers the new node. + /// @param scope scope of the new parsing context. /// @return the node created. - sp_pcontext *push_context(THD *thd, enum_scope scope); + sp_pcontext *push_context(THD *thd, sp_head *sphead, enum_scope scope); /// Pop a node from the parsing context tree. /// @return the parent node. @@ -522,8 +530,11 @@ public: /// Retrieve full type information about SP-variables in this parsing /// context and its children. /// + /// @param thd thread context. /// @param field_def_lst[out] Container to store type information. - void retrieve_field_definitions(List *field_def_lst) const; + /// @return true on error, in which case field_def_lst is incomplete. + bool retrieve_field_definitions(THD *thd, + List *field_def_lst) const; /// Find SP-variable by name. /// @@ -793,6 +804,9 @@ private: /// Parent context. sp_pcontext *m_parent; + /// Next context in the sp_head's single linked list of all contexts. + sp_pcontext *m_next_pcont; + /// An index of the first SP-variable in this parsing context. The index /// belongs to a runtime table of SP-variables. /// diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index de8a27c99a8..8b1998aad86 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -14539,6 +14539,18 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, return packet_error; } + /* Deferred host check from thd_set_peer_addr(), raised here instead, + now that SSL (if requested) has already been negotiated. */ + if (net->using_proxy_protocol & + (NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED | NET_PROXY_PROTOCOL_HOST_BLOCKED)) + { + myf flag= MYF(global_system_variables.log_warnings > 1 ? ME_ERROR_LOG : 0); + uint err= (net->using_proxy_protocol & NET_PROXY_PROTOCOL_HOST_BLOCKED) ? + ER_HOST_IS_BLOCKED : ER_HOST_NOT_PRIVILEGED; + my_error(err, flag, thd->main_security_ctx.host_or_ip); + return packet_error; + } + if (client_capabilities & CLIENT_PROTOCOL_41) { thd->max_client_packet_length= uint4korr(net->read_pos+4); @@ -14905,6 +14917,76 @@ static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio, mpvio_info(mpvio->auth_info.thd->net.vio, info); } +#ifdef HAVE_OPENSSL +/* + Whether the linked library's X509_NAME_oneline() backslash-escapes a + literal '/' or '+' inside an RDN value. True for OpenSSL >= 3.0.0. + False for OpenSSL < 3.0 and WolfSSL, which never escapes (reported + upstream: wolfSSL/wolfssl#11392). +*/ +#if !defined(HAVE_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L +#define X509_LIB_ESCAPES_SEPARATORS 1 +#else +#define X509_LIB_ESCAPES_SEPARATORS 0 +#endif + +/** + Compare two X509_NAME_oneline() strings where only one side may carry + a backslash-escape before a literal '/' or '+'. + + @param escaped name that may contain a backslash before '/' or '+' + @param raw name that never does + + @return same sign convention as strcmp() +*/ +static int x509_cmp_escaped_raw(const char *escaped, const char *raw) +{ + for (;;) + { + if (*escaped == '\\' && (escaped[1] == '/' || escaped[1] == '+')) + escaped++; + if (*escaped != *raw) + return (unsigned char) *escaped - (unsigned char) *raw; + if (*escaped == '\0') + return 0; + escaped++; + raw++; + } +} + +/** + Compare a REQUIRE ISSUER/SUBJECT value against a certificate's + X509_NAME_oneline() rendering. + + strcmp(), unless that fails and lenient is set: then fall back to + x509_cmp_escaped_raw(), applied to whichever side the currently-linked + library's own escaping puts the backslash on. lenient is opt-in + (old_mode=X509_LENIENT_COMPARE), since it reintroduces ambiguity + between an escaped literal '/' or '+' and a real separator. + + @param stored the REQUIRE ISSUER/SUBJECT value from ACL_USER + @param cert X509_NAME_oneline() of the connecting certificate + @param lenient @@old_mode & OLD_MODE_X509_LENIENT_COMPARE + + @return 0 if they match, non-zero otherwise +*/ +static int my_x509_oneline_cmp(const char *stored, const char *cert, + bool lenient) +{ + int c; + if (!stored || !cert) + return stored != cert; + c= strcmp(stored, cert); + if (!c || !lenient) + return c; +#if X509_LIB_ESCAPES_SEPARATORS + return x509_cmp_escaped_raw(cert, stored); /* cert is canonically escaped */ +#else + return x509_cmp_escaped_raw(stored, cert); /* cert never escapes */ +#endif +} +#endif /* HAVE_OPENSSL */ + static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) { #ifdef HAVE_OPENSSL @@ -14966,13 +15048,15 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) /* Prepare certificate (if exists) */ if (!(cert= SSL_get_peer_certificate(ssl))) return 1; + bool x509_lenient_compare= + (thd->variables.old_behavior & OLD_MODE_X509_LENIENT_COMPARE) != 0; /* If X509 issuer is specified, we check it... */ if (acl_user->x509_issuer[0]) { char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); DBUG_PRINT("info", ("comparing issuers: '%s' and '%s'", acl_user->x509_issuer, ptr)); - if (strcmp(acl_user->x509_issuer, ptr)) + if (my_x509_oneline_cmp(acl_user->x509_issuer, ptr, x509_lenient_compare)) { if (global_system_variables.log_warnings) sql_print_information("X509 issuer mismatch: should be '%s' " @@ -14989,7 +15073,7 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); DBUG_PRINT("info", ("comparing subjects: '%s' and '%s'", acl_user->x509_subject, ptr)); - if (strcmp(acl_user->x509_subject, ptr)) + if (my_x509_oneline_cmp(acl_user->x509_subject, ptr, x509_lenient_compare)) { if (global_system_variables.log_warnings) sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", @@ -15238,7 +15322,18 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) errors.m_auth_plugin= 1; break; case CR_AUTH_HANDSHAKE: - errors.m_handshake= 1; + /* + A deferred PROXY host-check rejection lands here as a generic + handshake failure; attribute it like the check itself would + have, not as m_handshake - that feeds max_connect_errors, which + host-privilege/host-blocked failures never did. + */ + if (thd->net.using_proxy_protocol & NET_PROXY_PROTOCOL_HOST_BLOCKED) + errors.m_host_blocked= 1; + else if (thd->net.using_proxy_protocol & NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED) + errors.m_host_acl= 1; + else + errors.m_handshake= 1; break; case CR_AUTH_USER_CREDENTIALS: errors.m_authentication= 1; diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 5456b03f2a7..8975a3eb0e2 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -34,25 +34,6 @@ */ static int check_event_type(int type, Relay_log_info *rli) { - Format_description_log_event *fd_event= - rli->relay_log.description_event_for_exec; - - /* - Convert event type id of certain old versions (see comment in - Format_description_log_event::Format_description_log_event(char*,...)). - */ - if (fd_event && fd_event->event_type_permutation) - { -#ifdef DBUG_TRACE - int new_type= fd_event->event_type_permutation[type]; - DBUG_PRINT("info", - ("converting event type %d to %d (%s)", - type, new_type, - Log_event::get_type_str((Log_event_type)new_type))); -#endif - type= fd_event->event_type_permutation[type]; - } - switch (type) { case START_EVENT_V3: diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1a8e98e6ec8..a13f9150b9b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1713,7 +1713,6 @@ void THD::cleanup(void) #ifdef WITH_WSREP if (wsrep_cs().state() != wsrep::client_state::s_none) wsrep_cs().cleanup(); - wsrep_client_thread= false; #endif /* WITH_WSREP */ DEBUG_SYNC(this, "THD_cleanup_after_set_killed"); @@ -2850,7 +2849,7 @@ THD::make_string_literal(const char *str, size_t length, if (!length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL)) return new (mem_root) Item_null(this, 0, variables.collation_connection); if (!charset_is_collation_connection && - (repertoire != MY_REPERTOIRE_ASCII || + (!my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII) || !my_charset_is_ascii_based(variables.collation_connection))) { LEX_STRING to; @@ -4894,7 +4893,6 @@ void TMP_TABLE_PARAM::init() table_charset= 0; precomputed_group_by= 0; bit_fields_as_long= 0; - materialized_subquery= 0; force_not_null_cols= 0; skip_create_table= 0; tmp_name= "temptable"; // Name of temp table on disk diff --git a/sql/sql_class.h b/sql/sql_class.h index 85edbbcc45a..ba2f497f1c5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -220,6 +220,7 @@ enum enum_binlog_row_image { #define OLD_MODE_LOCK_ALTER_TABLE_COPY (1 << 7) #define OLD_MODE_OLD_FLUSH_STATUS (1 << 8) #define OLD_MODE_SESSION_USER_IS_USER (1 << 9) +#define OLD_MODE_X509_LENIENT_COMPARE (1 << 10) /* 10.11: 1<<7, 11.4: 1<<8 */ #define OLD_MODE_DEFAULT_VALUE OLD_MODE_UTF8_IS_UTF8MB3 @@ -7005,8 +7006,6 @@ public: bool using_outer_summary_function; CHARSET_INFO *table_charset; bool schema_table; - /* TRUE if the temp table is created for subquery materialization. */ - bool materialized_subquery; /* TRUE if all columns of the table are guaranteed to be non-nullable */ bool force_not_null_cols; /* @@ -7034,7 +7033,7 @@ public: :copy_field(0), group_parts(0), group_length(0), group_null_parts(0), using_outer_summary_function(0), - schema_table(0), materialized_subquery(0), force_not_null_cols(0), + schema_table(0), force_not_null_cols(0), precomputed_group_by(0), group_concat(0), force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0) { diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index d4664d39ee0..ffdc96529a6 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -931,19 +931,19 @@ bool init_new_connection_handler_thread() @param addr peer address (can be NULL, if 'ip' is set) @param ip peer address as string (can be NULL if 'addr' is set) @param port peer port - @param check_proxy_networks if true, and host is in - 'proxy_protocol_networks' list, skip - "host not privileged" check + @param mode see host_check_mode @param[out] host_errors - number of connect errors for this host - @retval 0 ok, 1 error + @retval 0 ok, or (mode == HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP) host + check failed and the error is deferred - see host_check_mode + @retval 1 error */ int thd_set_peer_addr(THD *thd, sockaddr_storage *addr, const char *ip, uint port, - bool check_proxy_networks, + host_check_mode mode, uint *host_errors) { *host_errors= 0; @@ -1015,7 +1015,14 @@ int thd_set_peer_addr(THD *thd, if (rc == RC_BLOCKED_HOST) { /* HOST_CACHE stats updated by ip_to_hostname(). */ - my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip); + if (mode == HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP) + { + thd->net.using_proxy_protocol|= NET_PROXY_PROTOCOL_HOST_BLOCKED; + return 0; + } + my_error(ER_HOST_IS_BLOCKED, + MYF(global_system_variables.log_warnings > 1 ? ME_ERROR_LOG : 0), + thd->main_security_ctx.host_or_ip); return 1; } } @@ -1024,12 +1031,19 @@ int thd_set_peer_addr(THD *thd, thd->main_security_ctx.host : "unknown host"), (thd->main_security_ctx.ip ? thd->main_security_ctx.ip : "unknown ip"))); - if ((!check_proxy_networks || !is_proxy_protocol_allowed((struct sockaddr *) addr)) + if ((mode == HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP || + !is_proxy_protocol_allowed((struct sockaddr *) addr)) && acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip)) { /* HOST_CACHE stats updated by acl_check_host(). */ - my_error(ER_HOST_NOT_PRIVILEGED, MYF(0), - thd->main_security_ctx.host_or_ip); + if (mode == HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP) + { + thd->net.using_proxy_protocol|= NET_PROXY_PROTOCOL_HOST_NOT_PRIVILEGED; + return 0; + } + my_error(ER_HOST_NOT_PRIVILEGED, + MYF(global_system_variables.log_warnings > 1 ? ME_ERROR_LOG : 0), + thd->main_security_ctx.host_or_ip); return 1; } return 0; @@ -1146,7 +1160,7 @@ static int check_connection(THD *thd) } if (thd_set_peer_addr(thd, &net->vio->remote, ip, peer_port, - true, &connect_errors)) + HOST_CHECK_MODE_DEFAULT, &connect_errors)) { statistic_increment(aborted_connects_preauth, &LOCK_status); return 1; @@ -1300,6 +1314,7 @@ void end_connection(THD *thd) wsrep_after_command_ignore_result(thd); } wsrep_close(thd); + thd->wsrep_client_thread= false; #endif /* WITH_WSREP */ if (thd->user_connect) { diff --git a/sql/sql_connect.h b/sql/sql_connect.h index b456fc68ce9..93ddf26f1f1 100644 --- a/sql/sql_connect.h +++ b/sql/sql_connect.h @@ -100,9 +100,20 @@ bool thd_init_client_charset(THD *thd, uint cs_number); void setup_connection_thread_globals(THD *thd); bool thd_prepare_connection(THD *thd); bool thd_is_connection_alive(THD *thd); +enum host_check_mode +{ + /* An address in proxy_protocol_networks is exempt (the real check + happens later, on the client address from its PROXY header); + failure is raised immediately. */ + HOST_CHECK_MODE_DEFAULT, + /* Checking the real client address learned from a parsed PROXY + header: failure is deferred until the client's handshake response + is parsed, completing SSL first if requested. */ + HOST_CHECK_MODE_PROXY_PROTOCOL_CLIENT_IP +}; int thd_set_peer_addr(THD *thd, sockaddr_storage *addr, const char *ip, uint port, - bool check_proxy_networks, + host_check_mode mode, uint *host_errors); void prepare_new_connection_state(THD* thd); diff --git a/sql/sql_const.h b/sql/sql_const.h index e51d4d18807..f059f8cb10f 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -32,7 +32,6 @@ #define MAX_FIELD_NAME (NAME_LEN+1) /* Max column name length +1 */ #define MAX_SYS_VAR_LENGTH 32 #define MAX_KEY MAX_INDEXES /* Max used keys */ -#define MAX_REF_PARTS 32 /* Max parts used as ref */ /* Maximum length of the data part of an index lookup key. diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 35fac2bad28..71842f55163 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -424,7 +424,9 @@ static my_bool put_dbopt(const char *dbname, Schema_specification_st *create) if (create->schema_comment) { - strmov(opt->comment.str, create->schema_comment->str); + DBUG_ASSERT(create->schema_comment->length <= DATABASE_COMMENT_MAXLEN); + strmake(opt->comment.str, create->schema_comment->str, + create->schema_comment->length); opt->comment.length= create->schema_comment->length; } @@ -475,6 +477,12 @@ static bool write_db_opt(THD *thd, const char *path, ER_TOO_LONG_DATABASE_COMMENT, thd->lex->name.str)) return error; + + const size_t byte_len= MY_MIN(create->schema_comment->length, + (size_t) DATABASE_COMMENT_MAXLEN); + create->schema_comment->length= + Well_formed_prefix(system_charset_info, create->schema_comment->str, + byte_len).length(); } if (thd->lex->sql_command == SQLCOM_ALTER_DB && @@ -510,9 +518,14 @@ static bool write_db_opt(THD *thd, const char *path, "\n", NullS) - buf); if (create->schema_comment) - length= (ulong) (strxnmov(buf+length, sizeof(buf)-1-length, - "comment=", create->schema_comment->str, - "\n", NullS) - buf); + { + DBUG_ASSERT(create->schema_comment->length <= DATABASE_COMMENT_MAXLEN); + char *pos= strmov(buf+length, "comment="); + pos= strmake(pos, create->schema_comment->str, + create->schema_comment->length); + *pos++= '\n'; + length= (ulong) (pos - buf); + } /* Error is written by mysql_file_write */ if (!mysql_file_write(file, (uchar*) buf, length, MYF(MY_NABP+MY_WME))) @@ -587,6 +600,7 @@ int load_db_opt(THD *thd, const char *path, Schema_specification_st *create) while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1])) pos--; *pos=0; + char const *line_end= pos; if ((pos= strchr(buf, '='))) { if (!strncmp(buf,"default-character-set", (pos-buf))) @@ -618,7 +632,25 @@ int load_db_opt(THD *thd, const char *path, Schema_specification_st *create) } } else if (!strncmp(buf, "comment", (pos-buf))) - create->schema_comment= thd->make_clex_string(pos+1, strlen(pos+1)); + { + const LEX_CSTRING raw_comment= {pos + 1, + (size_t) (line_end - (pos + 1))}; + const size_t byte_len= MY_MIN(raw_comment.length, + (size_t) DATABASE_COMMENT_MAXLEN); + const size_t comment_len= + Well_formed_prefix(system_charset_info, raw_comment.str, + byte_len).length(); + if (comment_len < raw_comment.length) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_TOO_LONG_DATABASE_COMMENT, + "Comment in database options file '%-.256s' " + "is too long (max = %u), truncated", + path, (uint) DATABASE_COMMENT_MAXLEN); + } + create->schema_comment= thd->make_clex_string(raw_comment.str, + comment_len); + } } } /* diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 5332b32d70a..29182513e52 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -1198,11 +1198,6 @@ void Explain_select::print_explain_json(Explain_query *query, writer->add_member("outer_ref_condition"); write_item(writer, outer_ref_cond); } - if (pseudo_bits_cond) - { - writer->add_member("pseudo_bits_condition"); - write_item(writer, pseudo_bits_cond); - } /* we do not print HAVING which always evaluates to TRUE */ if (having || (having_value == Item::COND_FALSE)) diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 7a1ee391161..26efd10e9d9 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -248,7 +248,6 @@ public: /* Expensive constant condition */ Item *exec_const_cond; Item *outer_ref_cond; - Item *pseudo_bits_cond; /* HAVING condition */ Item *having; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index c5131e529f9..04c852faf3b 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -61,6 +61,8 @@ #include "sql_base.h" // insert_fields #include "sql_select.h" #include "transaction.h" +#include "sql_acl.h" // check_grant_all_columns +#include "sql_parse.h" // check_table_access #define HANDLER_TABLES_HASH_SIZE 120 @@ -341,8 +343,17 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) open_ltable() or open_table() because we would like to be able to open a temporary table. */ - error= (thd->open_temporary_tables(tables) || - open_tables(thd, &tables, &counter, 0)); + error= thd->open_temporary_tables(tables); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* + Privileges could have changed since HANDLER OPEN. They are checked + again only when the table is reopened (e.g. after FLUSH TABLES or + ALTER TABLE); an open handler is not affected by REVOKE. + */ + if (!error && reopen && !tables->table) + error= check_table_access(thd, SELECT_ACL, tables, FALSE, 1, FALSE); +#endif + error= error || open_tables(thd, &tables, &counter, 0); if (unlikely(error)) goto err; @@ -357,6 +368,25 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) goto err; } +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* + HANDLER READ returns all columns, so with only column-level grants + SELECT is required on each of them (as for SELECT *). On reopen the + table could have got new columns. Temporary tables need no grants + (and are not checked on reopen). INVISIBLE_SYSTEM and INVISIBLE_FULL + columns are skipped: they need no column grant for SELECT either + (MDEV-14853) and the long unique hash is computed from columns that + are checked. + */ + if (!table->s->tmp_table && !(table->grant.privilege & SELECT_ACL)) + { + Field_iterator_table_ref field_it; + field_it.set(tables); + if (check_grant_all_columns(thd, SELECT_ACL, &field_it)) + goto err; + } +#endif + DBUG_PRINT("info",("clone_tickets start")); for (TABLE_LIST *table_list= tables; table_list; table_list= table_list->next_global) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 60668384b3e..a13731461ee 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -956,7 +956,8 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, if (thd->rgi_slave && (info.handle_duplicates == DUP_UPDATE) && (table->next_number_field != NULL) && - rpl_master_has_bug(thd->rgi_slave->rli, 24432, TRUE, NULL, NULL)) + rpl_master_has_bug(thd->rgi_slave->rli, RPL_BUG_MYSQL_24432, + TRUE, NULL, NULL)) goto abort; #endif @@ -4420,7 +4421,8 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) if (thd->rgi_slave && (info.handle_duplicates == DUP_UPDATE) && (table->next_number_field != NULL) && - rpl_master_has_bug(thd->rgi_slave->rli, 24432, TRUE, NULL, NULL)) + rpl_master_has_bug(thd->rgi_slave->rli, RPL_BUG_MYSQL_24432, + TRUE, NULL, NULL)) DBUG_RETURN(1); #endif @@ -5502,8 +5504,12 @@ bool select_create::send_eof() if (!table->s->tmp_table) { #ifdef WITH_WSREP + // For partitioned tables need to look implementing hton + const handlerton* ht= table->file->partition_ht() ? + table->file->partition_ht() : + table->file->ht; if (WSREP(thd) && - table->file->ht->db_type == DB_TYPE_INNODB) + ht->db_type == DB_TYPE_INNODB) { if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID) { diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index c8948995c6a..08f9ffe6c71 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -4091,7 +4091,7 @@ void bka_range_seq_key_info(void *init_params, uint *length, { TABLE_REF *ref= &(((JOIN_CACHE*)init_params)->join_tab->ref); *length= ref->key_length; - *map= (key_part_map(1) << ref->key_parts) - 1; + *map= make_prev_keypart_map(ref->key_parts); } @@ -4156,7 +4156,7 @@ bool bka_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range) key_range *start_key= &range->start_key; if ((start_key->length= cache->get_next_key((uchar **) &start_key->key))) { - start_key->keypart_map= (1 << ref->key_parts) - 1; + start_key->keypart_map= make_prev_keypart_map(ref->key_parts); start_key->flag= HA_READ_KEY_EXACT; range->end_key= *start_key; range->end_key.flag= HA_READ_AFTER_KEY; @@ -4637,7 +4637,7 @@ bool bkah_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range) key_range *start_key= &range->start_key; if ((start_key->length= cache->get_next_key((uchar **) &start_key->key))) { - start_key->keypart_map= (1 << ref->key_parts) - 1; + start_key->keypart_map= make_prev_keypart_map(ref->key_parts); start_key->flag= HA_READ_KEY_EXACT; range->end_key= *start_key; range->end_key.flag= HA_READ_AFTER_KEY; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fcc5faa2b85..01528030e24 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -7920,7 +7920,7 @@ bool LEX::sp_handler_declaration_init(THD *thd, int type) { sp_handler *h= spcont->add_handler(thd, (sp_handler::enum_type) type); - spcont= spcont->push_context(thd, sp_pcontext::HANDLER_SCOPE); + spcont= spcont->push_context(thd, sphead, sp_pcontext::HANDLER_SCOPE); sp_instr_hpush_jump *i= new (thd->mem_root) sp_instr_hpush_jump(sphead->instructions(), spcont, h); @@ -7972,14 +7972,14 @@ void LEX::sp_block_init_package_body(THD *thd) { spcont->push_label(thd, &empty_clex_str, sphead->instructions(), sp_label::BEGIN); - spcont= spcont->push_context(thd, sp_pcontext::PACKAGE_BODY_SCOPE); + spcont= spcont->push_context(thd, sphead, sp_pcontext::PACKAGE_BODY_SCOPE); } void LEX::sp_block_init(THD *thd, const LEX_CSTRING *label) { spcont->push_label(thd, label, sphead->instructions(), sp_label::BEGIN); - spcont= spcont->push_context(thd, sp_pcontext::REGULAR_SCOPE); + spcont= spcont->push_context(thd, sphead, sp_pcontext::REGULAR_SCOPE); } @@ -11728,23 +11728,62 @@ SELECT_LEX_UNIT *LEX::add_tail_to_query_expression_body(SELECT_LEX_UNIT *unit, } +/** + Push the select that a non-empty tail of a parenthesized query primary + is parsed in. + + If the tail has ORDER BY and the primary already has its own ORDER BY or + LIMIT, the primary is wrapped into a derived table here, before the tail + is parsed, and the wrapper is pushed. Window functions, window specs and + subqueries in the tail's ORDER BY are attached to the current select + while they are parsed, so they must be parsed in the select that will + own the ORDER BY. + + @return the pushed select, NULL on error +*/ + +SELECT_LEX * +LEX::push_select_for_ext_parens_tail(SELECT_LEX_UNIT *unit, + bool tail_has_order) +{ + SELECT_LEX *sel= unit->first_select()->next_select() ? unit->fake_select_lex : + unit->first_select(); + if (tail_has_order && sel->is_set_query_expr_tail) + { + if (!(sel= wrap_unit_into_derived(unit)) || !create_unit(sel)) + return NULL; + } + if (push_select(sel)) + return NULL; + return sel; +} + + /** Add non-empty tail to a parenthesized query primary + + @param tail_sel the select returned by push_select_for_ext_parens_tail() */ SELECT_LEX_UNIT * LEX::add_tail_to_query_expression_body_ext_parens(SELECT_LEX_UNIT *unit, - Lex_order_limit_lock *l) + Lex_order_limit_lock *l, + SELECT_LEX *tail_sel) { - SELECT_LEX *sel= unit->first_select()->next_select() ? unit->fake_select_lex : - unit->first_select(); + SELECT_LEX *sel= tail_sel; DBUG_ASSERT(l != NULL); pop_select(); - if (sel->is_set_query_expr_tail) + if (sel->master_unit() != unit) { - if (!l->order_list && !sel->limit_params.explicit_limit) + /* Already wrapped by push_select_for_ext_parens_tail() */ + DBUG_ASSERT(l->order_list); + } + else if (sel->is_set_query_expr_tail) + { + DBUG_ASSERT(!l->order_list); + if (!sel->limit_params.explicit_limit) l->order_list= &sel->order_list; else { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7445e3361e6..4577f3069ab 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -5006,9 +5006,12 @@ public: bool parsed_multi_operand_query_expression_body(SELECT_LEX_UNIT *unit); SELECT_LEX_UNIT *add_tail_to_query_expression_body(SELECT_LEX_UNIT *unit, Lex_order_limit_lock *l); + SELECT_LEX *push_select_for_ext_parens_tail(SELECT_LEX_UNIT *unit, + bool tail_has_order); SELECT_LEX_UNIT * add_tail_to_query_expression_body_ext_parens(SELECT_LEX_UNIT *unit, - Lex_order_limit_lock *l); + Lex_order_limit_lock *l, + SELECT_LEX *tail_sel); SELECT_LEX_UNIT *parsed_body_ext_parens_primary(SELECT_LEX_UNIT *unit, SELECT_LEX *primary, enum sub_select_type unit_type, diff --git a/sql/sql_locale.h b/sql/sql_locale.h index 50d4837e577..d991d4d35da 100644 --- a/sql/sql_locale.h +++ b/sql/sql_locale.h @@ -69,7 +69,7 @@ public: errmsgs(errmsgs_par) {} my_repertoire_t repertoire() const - { return is_ascii ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_EXTENDED; } + { return is_ascii ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; } /* Get a non-abbreviated month name by index @param month - the month index 0..11 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 75599cc8f1b..816f46cfea0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3245,6 +3245,11 @@ static bool prepare_db_action(THD *thd, privilege_t want_access, bool Sql_cmd_show_routine_code::execute(THD *thd) { sp_head *sp; +#ifdef WITH_WSREP + if (WSREP_CLIENT(thd) && + wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_SHOW)) + return true; +#endif /* WITH_WSREP */ if (m_handler->sp_cache_routine(thd, m_name, &sp)) return true; if (!sp || sp->show_routine_code(thd)) @@ -5514,6 +5519,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) There is no need to check for table permissions here, because if a user has no permissions to read a table, he won't be able to open it (with SQLCOM_HA_OPEN) in the first place. + On implicit reopen mysql_ha_open() checks privileges again. */ unit->set_limit(select_lex); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 09c033f8b32..c7ecf7c4148 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5227,8 +5227,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, { MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &thd->locked_tables_list.m_locked_tables_root; + DBUG_EXECUTE_IF("prep_alter_part_table_get_clone_oom", + DBUG_SET("+d,simulate_out_of_memory");); saved_part_info= tab_part_info->get_clone(thd); thd->mem_root= old_root; + if (!saved_part_info) + goto err; saved_part_info->read_partitions= tab_part_info->read_partitions; saved_part_info->lock_partitions= tab_part_info->lock_partitions; saved_part_info->bitmaps_are_initialized= tab_part_info->bitmaps_are_initialized; @@ -6093,12 +6097,20 @@ the generated partition syntax in a correct manner. tab_part_info != part_info && part_info->part_type == VERSIONING_PARTITION && part_info->num_parts == 0) { - if (part_info->vers_info->interval.is_set() && ( - !tab_part_info->vers_info->interval.is_set() || - part_info->vers_info->interval == tab_part_info->vers_info->interval)) + if (alter_info->flags || + (part_info->vers_info->interval.is_set() && + (!tab_part_info->vers_info->interval.is_set() || + part_info->vers_info->interval != + tab_part_info->vers_info->interval))) { - /* If interval is changed we can not do fast alter */ - tab_part_info= tab_part_info->get_clone(thd); + /* + Fast alter changes only partitioning options. It cannot be done + if the interval is changed or the table definition is changed. + */ + DBUG_EXECUTE_IF("prep_alter_part_table_get_clone_oom", + DBUG_SET("+d,simulate_out_of_memory");); + if (!(tab_part_info= tab_part_info->get_clone(thd))) + DBUG_RETURN(TRUE); } else { @@ -6106,7 +6118,10 @@ the generated partition syntax in a correct manner. *fast_alter_table= true; table->mark_table_for_reopen(); } - *tab_part_info->vers_info= *part_info->vers_info; + /* Keep now_part and hist_part of the existing partitions */ + tab_part_info->vers_info->interval= part_info->vers_info->interval; + tab_part_info->vers_info->limit= part_info->vers_info->limit; + tab_part_info->vers_info->auto_hist= part_info->vers_info->auto_hist; thd->work_part_info= part_info= tab_part_info; *partition_changed= true; } @@ -7039,21 +7054,19 @@ error: SYNOPSIS write_log_completed() - lpt Struct containing parameters + log_state DDL log entries + dont_crash Not used RETURN VALUES - TRUE Error - FALSE Success + NONE */ /* TODO: Partitioning atomic DDL refactoring: this should be replaced with ddl_log_complete(). */ -static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, - bool dont_crash) +static void write_log_completed(DDL_LOG_STATE *log_state, bool dont_crash) { - partition_info *part_info= lpt->part_info; - DDL_LOG_MEMORY_ENTRY *log_entry= part_info->execute_entry; + DDL_LOG_MEMORY_ENTRY *log_entry= log_state->execute_entry; DBUG_ENTER("write_log_completed"); DBUG_ASSERT(log_entry); @@ -7069,11 +7082,11 @@ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, */ ; } - release_part_info_log_entries(part_info->list); - release_part_info_log_entries(part_info->execute_entry); + release_part_info_log_entries(log_state->list); + release_part_info_log_entries(log_state->execute_entry); mysql_mutex_unlock(&LOCK_gdl); - part_info->execute_entry= NULL; - part_info->list= NULL; + log_state->execute_entry= NULL; + log_state->list= NULL; DBUG_VOID_RETURN; } @@ -7082,7 +7095,7 @@ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, Release all log entries SYNOPSIS release_log_entries() - part_info Partition info struct + log_state DDL log entries RETURN VALUES NONE */ @@ -7091,14 +7104,14 @@ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, TODO: Partitioning atomic DDL refactoring: this should be replaced with ddl_log_release_entries(). */ -static void release_log_entries(partition_info *part_info) +static void release_log_entries(DDL_LOG_STATE *log_state) { mysql_mutex_lock(&LOCK_gdl); - release_part_info_log_entries(part_info->list); - release_part_info_log_entries(part_info->execute_entry); + release_part_info_log_entries(log_state->list); + release_part_info_log_entries(log_state->execute_entry); mysql_mutex_unlock(&LOCK_gdl); - part_info->list= NULL; - part_info->execute_entry= NULL; + log_state->list= NULL; + log_state->execute_entry= NULL; } @@ -7192,7 +7205,8 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool reopen) { THD *thd= lpt->thd; - partition_info *part_info= lpt->part_info->get_clone(thd); + /* Closing the table may free lpt->part_info, keep its DDL log entries */ + DDL_LOG_STATE log_state= *lpt->part_info; TABLE *table= lpt->table; DBUG_ENTER("handle_alter_part_error"); DBUG_ASSERT(table->needs_reopen()); @@ -7236,15 +7250,14 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, if (!reopen) DBUG_VOID_RETURN; - if (part_info->list && - ddl_log_execute_entry(thd, part_info->list->entry_pos)) + if (log_state.list && + ddl_log_execute_entry(thd, log_state.list->entry_pos)) { /* We couldn't recover from error, most likely manual interaction is required. */ - write_log_completed(lpt, FALSE); - release_log_entries(part_info); + write_log_completed(&log_state, FALSE); if (!action_completed) { if (drop_partition) @@ -7310,7 +7323,7 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, } else { - release_log_entries(part_info); + release_log_entries(&log_state); if (!action_completed) { /* @@ -7661,7 +7674,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT("drop_partition_7") || mysql_drop_partitions(lpt) || ERROR_INJECT("drop_partition_8") || - (write_log_completed(lpt, FALSE), FALSE) || + (write_log_completed(lpt->part_info, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || @@ -7831,7 +7844,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, log_partition_alter_to_ddl_log(lpt) || (frm_install= FALSE, FALSE) || ERROR_INJECT("add_partition_9") || - (write_log_completed(lpt, FALSE), FALSE) || + (write_log_completed(lpt->part_info, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || @@ -7924,7 +7937,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT("change_partition_10") || mysql_rename_partitions(lpt) || ERROR_INJECT("change_partition_11") || - (write_log_completed(lpt, FALSE), FALSE) || + (write_log_completed(lpt->part_info, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index aeb3279afe4..b0d65455115 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -248,7 +248,7 @@ bool compare_table_with_partition(THD *thd, TABLE *table, TABLE *part_table, the same, so any table using data/index_file_name will fail. */ if (mysql_compare_tables(table, &part_alter_info, &part_create_info, - &metadata_equal)) + &metadata_equal, true)) { my_error(ER_TABLES_DIFFERENT_METADATA, MYF(0)); DBUG_RETURN(TRUE); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index e2fd228fc3b..e07b7804f66 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1141,6 +1141,21 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) DBUG_RETURN(tmp); } +static inline bool plugin_should_be_skipped(const struct st_maria_plugin *p, + const struct st_plugin_dl *plugin_dl, + const LEX_CSTRING *name) +{ + if (p->type < 0 || p->type >= MYSQL_MAX_PLUGIN_TYPE_NUM) + return true; + if (p->type == MYSQL_UDF_PLUGIN || + (p->type == MariaDB_PASSWORD_VALIDATION_PLUGIN && + plugin_dl->mariaversion == 0)) + return true; + if (name->str && + !Lex_ident_plugin(*name).streq(LEX_CSTRING{p->name, strlen(p->name)})) + return true; + return false; +} /* NOTE @@ -1167,23 +1182,35 @@ static enum install_status plugin_add(MEM_ROOT *tmp_root, bool if_not_exists, fix_dl_name(tmp_root, dl); if (! (tmp.plugin_dl= plugin_dl_add(dl, MyFlags))) DBUG_RETURN(INSTALL_FAIL_NOT_OK); + + /* Pre-validation: ensure plugin name of all plugins or the plugin to be installed are in pure ASCII */ + for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++) + { + if (plugin_should_be_skipped(plugin, tmp.plugin_dl, name)) + continue; + + if (MY_REPERTOIRE_EXTENDED & + my_string_repertoire(&my_charset_latin1, + plugin->name, strlen(plugin->name))) + { + my_printf_error(ER_PLUGIN_IS_NOT_LOADED, + "Plugin '%s': name must contain only ASCII characters", + MyFlags, plugin->name); + plugin_dl_del(tmp.plugin_dl); + DBUG_RETURN(INSTALL_FAIL_NOT_OK); + } + } + /* Find plugin by name */ for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++) { + + if (plugin_should_be_skipped(plugin, tmp.plugin_dl, name)) + continue; + tmp.name.str= (char *)plugin->name; tmp.name.length= strlen(plugin->name); - if (plugin->type < 0 || plugin->type >= MYSQL_MAX_PLUGIN_TYPE_NUM) - continue; // invalid plugin type - - if (plugin->type == MYSQL_UDF_PLUGIN || - (plugin->type == MariaDB_PASSWORD_VALIDATION_PLUGIN && - tmp.plugin_dl->mariaversion == 0)) - continue; // unsupported plugin type - - if (name->str && !Lex_ident_plugin(*name).streq(tmp.name)) - continue; // plugin name doesn't match - if (!name->str && (maybe_dupe= plugin_find_internal(&tmp.name, MYSQL_ANY_PLUGIN))) { @@ -1701,6 +1728,13 @@ int plugin_init(int *argc, char **argv, int flags) bzero(&tmp, sizeof(tmp)); tmp.plugin= plugin; tmp.name= tmp_plugin_name; + if (MY_REPERTOIRE_EXTENDED & + my_string_repertoire(&my_charset_latin1, + tmp.name.str, tmp.name.length)) + { + print_init_failed_error(&tmp); + goto err_unlock; + } tmp.state= 0; tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON; DBUG_ASSERT(!mandatory || diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 0d27528913e..2cd0e69a4e5 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -58,6 +58,16 @@ #define OPTION_BIG_SELECTS (1ULL << 9) // THD, user #define OPTION_LOG_OFF (1ULL << 10) // THD, user #define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user +/* + This flag has two effects: + 1. Include all select list columns in the temporary table. Do not skip + constant expressions or expressions that include aggregate functions. + 2. For items in select list, do NOT set item->result_field to point to + item's image field in the created temporary table. + + Roughly speaking, TMP_TABLE_ALL_COLUMNS is NOT used for temporary tables + that do GROUP BY operation, and used for most other tables. +*/ #define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern #define OPTION_WARNINGS (1ULL << 13) // THD, user #define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 2ded98e029c..6d7f4283dcb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1996,8 +1996,7 @@ gtid_state_from_pos(const char *name, uint32 offset, if (unlikely(get_checksum_alg((uchar*) packet.ptr(), packet.length(), ¤t_checksum_alg) || !(tmp= new Format_description_log_event((uchar*)packet.ptr(), - packet.length(), - fdev)))) + packet.length())))) { errormsg= "Corrupt Format_description event found or out-of-memory " "while searching for old-style position in binlog"; @@ -2013,7 +2012,7 @@ gtid_state_from_pos(const char *name, uint32 offset, { sele_len -= BINLOG_CHECKSUM_LEN; } - Start_encryption_log_event sele((uchar*) packet.ptr(), sele_len, fdev); + Start_encryption_log_event sele((uchar*) packet.ptr(), sele_len); if (fdev->start_decryption(&sele)) { errormsg= "Could not start decryption of binlog."; @@ -2063,7 +2062,7 @@ gtid_state_from_pos(const char *name, uint32 offset, } status= Gtid_list_log_event::peek(packet.ptr(), packet.length(), current_checksum_alg, - >id_list, &list_len, fdev); + >id_list, &list_len); if (unlikely(status)) { errormsg= "Error reading Gtid_list_log_event while searching " @@ -2091,8 +2090,7 @@ gtid_state_from_pos(const char *name, uint32 offset, uchar flags2; if (unlikely(Gtid_log_event::peek((uchar*) packet.ptr(), packet.length(), current_checksum_alg, >id.domain_id, - >id.server_id, >id.seq_no, &flags2, - fdev))) + >id.server_id, >id.seq_no, &flags2))) { errormsg= "Corrupt gtid_log_event found while scanning binlog to find " "initial slave position"; @@ -2229,7 +2227,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type, if (ev_offset > len || Gtid_list_log_event::peek(packet->ptr()+ev_offset, len - ev_offset, current_checksum_alg, - >id_list, &list_len, info->fdev)) + >id_list, &list_len)) { info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; return "Failed to read Gtid_list_log_event: corrupt binlog"; @@ -2258,7 +2256,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type, Gtid_log_event::peek((uchar*) packet->ptr()+ev_offset, len - ev_offset, current_checksum_alg, &event_gtid.domain_id, &event_gtid.server_id, - &event_gtid.seq_no, &flags2, info->fdev)) + &event_gtid.seq_no, &flags2)) { info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; return "Failed to read Gtid_log_event: corrupt binlog"; @@ -3066,7 +3064,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, Format_description_log_event *tmp; if (!(tmp= new Format_description_log_event((uchar*) packet->ptr() + ev_offset, - ev_len, info->fdev))) + ev_len))) { info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; info->errmsg= CORRUPT_FDE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5cdfbb02146..9c5de904ce3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -562,7 +562,7 @@ void JOIN::init(THD *thd_arg, List &fields_arg, first_select= sub_select; group_sent= 0; - outer_ref_cond= pseudo_bits_cond= NULL; + outer_ref_cond= NULL; in_to_exists_where= NULL; in_to_exists_having= NULL; emb_sjm_nest= NULL; @@ -978,6 +978,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) { vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp; type= (vers_system_time_t) in.type; + from_sysvar= (type != SYSTEM_TIME_UNSPECIFIED); delete_history= false; start.unit= VERS_TIMESTAMP; if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL) @@ -1300,6 +1301,21 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) DBUG_RETURN(-1); } +#ifdef WITH_PARTITION_STORAGE_ENGINE + partition_info *part_info= table->table->part_info; + if (part_info && part_info->vers_info && + !table->partition_names && + !vers_conditions.was_set() && + !vers_conditions.from_sysvar) + { + /* + No row_end condition: prune_partitions() restricts read_partitions + to now_part on each execution, with the same conditions. + */ + vers_conditions.set_all(); + } +#endif + if (vers_conditions.is_set()) { if (vers_conditions.was_set() && @@ -7489,7 +7505,7 @@ static bool add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field) MDEV-24931: For materialized derived tables, don't add hash-join KEYUSE entries beyond max_key_parts(). Excess entries would cause generate_derived_keys_for_table() to build a key with more parts - than key_part_map (64 bits) or Bitmap<64> can represent. + than key_part_map can represent. */ if (form->pos_in_table_list && form->pos_in_table_list->is_materialized_derived()) @@ -11563,8 +11579,8 @@ double table_after_join_selectivity(JOIN *join, uint idx, JOIN_TAB *s, */ if (!is_hash_join_key_no(key) && table->opt_range_keys.is_set(key)) { - key_part_map quick_key_map= (key_part_map(1) << - table->opt_range[key].key_parts) - 1; + key_part_map quick_key_map= + make_prev_keypart_map(table->opt_range[key].key_parts); if (s->type == JT_RANGE || (table->opt_range[key].rows && (table->const_key_parts[key] & 1))) { @@ -12114,9 +12130,11 @@ double recompute_join_cost_with_limit(const JOIN *join, bool skip_sorting, /* Handle possible rounding errors when partial_join_cost==pos->read_time*fraction: + The rounding error grows with the cost, so the tolerance is taken + in proportion to it. Catch larger negatives, proceed with non-negative cost. */ - DBUG_ASSERT(partial_join_cost >= -DBL_EPSILON); + DBUG_ASSERT(partial_join_cost >= -DBL_EPSILON*pos->read_time*fraction); if (partial_join_cost < 0.0) partial_join_cost= 0.0; @@ -13826,8 +13844,9 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, are_tables_local(join_tab, curr->used_tables)) break; } - if (curr == keyuse) - key_parts++; + if (curr == keyuse && + ++key_parts >= MAX_REF_PARTS) + break; } } first_keyuse= FALSE; @@ -13880,6 +13899,13 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, } } } + if (add_key_part && + (uint) (key_part_info - keyinfo->key_part) >= key_parts) + { + /* Key is full (capped at MAX_REF_PARTS above); not used by ref */ + keyuse->keypart= NO_KEYPART; + add_key_part= FALSE; + } if (add_key_part) { Field *field= table->field[keyuse->keypart]; @@ -13991,6 +14017,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, } keyuse++; } while (keyuse->table == table && keyuse->key == key); + DBUG_ASSERT(keyparts <= MAX_REF_PARTS); if (!keyparts && allow_full_scan) { @@ -14068,7 +14095,10 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, Item *real= (keyuse->val)->real_item(); if (keyuse->null_rejecting && (real->type() == Item::FIELD_ITEM) && ((Item_field*)real)->field->maybe_null()) + { + DBUG_ASSERT(i < MAX_REF_PARTS); j->ref.null_rejecting|= (key_part_map)1 << i; + } keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; j->ref.uses_splitting |= (keyuse->validity_ref != NULL); @@ -14283,6 +14313,7 @@ static void add_not_null_conds(JOIN *join) { for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) { + DBUG_ASSERT(keypart < MAX_REF_PARTS); if (tab->ref.null_rejecting & ((key_part_map)1 << keypart)) { Item *item= tab->ref.items[keypart]; @@ -14592,6 +14623,26 @@ bool build_tmp_join_prefix_cond(JOIN *join, JOIN_TAB *last_tab, Item **ret) } +/* + Find the last top level table in the join order that is neither + const nor a materialized semijoin nest. Return its index in + join->join_tab, or a value below join->const_tables when no such + table exists. +*/ + +static uint +get_last_top_base_tab_idx(const JOIN *join) +{ + uint i; + for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--) + { + if (!join->join_tab[i].bush_children) + break; + } + return i; +} + + static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { @@ -14605,6 +14656,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) "attached_conditions_computation"); add_not_null_conds(join); table_map used_tables; + + /* Step #1 and Step #2 both decide from this index. */ + const uint last_top_base_tab_idx= get_last_top_base_tab_idx(join); + /* Step #1: Extract constant condition - Extract and check the constant part of the WHERE @@ -14670,40 +14725,36 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) join->exec_const_cond= const_cond; } - if (join->table_count != join->const_tables) { - COND *outer_ref_cond= make_cond_for_table(thd, cond, - join->const_table_map | - OUTER_REF_TABLE_BIT, - OUTER_REF_TABLE_BIT, - -1, FALSE, FALSE); - if (outer_ref_cond) + /* + Collect the conjuncts that are checked once for each execution + of the query, before the join reads a table that is not const. + Each refers to at least one pseudo table in pseudo_bits and to + no table that is not const. + + A conjunct that refers to a column of an outer query is always + collected, because that column has one value for each + execution. rand() takes a new value on each call, and a + conjunct that calls it is checked for each row of the last top + level table that is neither const nor a materialized semijoin + nest. When no such table exists, the join returns at most one + row, and its rand() conjuncts are collected here. + */ + table_map pseudo_bits= OUTER_REF_TABLE_BIT; + if (last_top_base_tab_idx < join->const_tables) + pseudo_bits= PSEUDO_TABLE_BITS; + COND *pseudo_cond= make_cond_for_table(thd, cond, + join->const_table_map | + pseudo_bits, + pseudo_bits, + -1, FALSE, FALSE); + if (pseudo_cond) { - add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond); - join->outer_ref_cond= outer_ref_cond; + add_cond_and_fix(thd, &pseudo_cond, join->outer_ref_cond); + join->outer_ref_cond= pseudo_cond; Json_writer_object trace(thd); - trace.add("outer_ref_cond", outer_ref_cond); - } - else if (thd->is_error()) - DBUG_RETURN(1); - } - else - { - COND *pseudo_bits_cond= - make_cond_for_table(thd, cond, - join->const_table_map | - PSEUDO_TABLE_BITS, - PSEUDO_TABLE_BITS, - -1, FALSE, FALSE); - if (pseudo_bits_cond) - { - add_cond_and_fix(thd, &pseudo_bits_cond, - join->pseudo_bits_cond); - join->pseudo_bits_cond= pseudo_bits_cond; - - Json_writer_object trace(thd); - trace.add("pseudo_bits_cond", pseudo_bits_cond); + trace.add("outer_ref_cond", pseudo_cond); } else if (thd->is_error()) DBUG_RETURN(1); @@ -14716,13 +14767,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) */ uint i; - for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--) - { - if (!join->join_tab[i].bush_children) - break; - } - uint last_top_base_tab_idx= i; - table_map save_used_tables= 0; used_tables=((select->const_tables=join->const_table_map) | OUTER_REF_TABLE_BIT | RAND_TABLE_BIT); @@ -18179,6 +18223,10 @@ return_zero_rows(JOIN *join, select_result *result, List *tables, { join->thd->limit_found_rows= 0; } + else + { + join->thd->limit_found_rows= send_row ? 1 : 0; + } if (!(result->send_result_set_metadata(*fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))) @@ -22530,6 +22578,8 @@ bool Create_tmp_table::add_fields(THD *thd, if (type == Item::SUM_FUNC_ITEM && !m_group && !m_save_sum_fields) { /* Can't calc group yet */ Item_sum *sum_item= (Item_sum *) item; + /* There is actually no need to clear result_field */ + DBUG_ASSERT(!sum_item->result_field); sum_item->result_field=0; for (uint i= 0 ; i < sum_item->get_arg_count() ; i++) { @@ -22616,26 +22666,25 @@ bool Create_tmp_table::add_fields(THD *thd, { Item_sum *agg_item= (Item_sum *) item; /* - Update the result field only if it has never been set, or if the - created temporary table is not to be used for subquery - materialization. + Set agg_item->result_field to point to its image in the temporary + table. Do this only when this temporary table is created without + TMP_TABLE_ALL_COLUMNS flag (and so not_all_columns=true). - The reason is that for subqueries that require - materialization as part of their plan, we create the - 'external' temporary table needed for IN execution, after - the 'internal' temporary table needed for grouping. Since - both the external and the internal temporary tables are - created for the same list of SELECT fields of the subquery, - setting 'result_field' for each invocation of - create_tmp_table overrides the previous value of - 'result_field'. + In this case, the temporary table will be read by going through the + select list and its item->result_field pointers. The most common + examples of this are GROUP BY operation and buffering for + SQL_BUFFER_RESULT). - The condition below prevents the creation of the external - temp table to override the 'result_field' that was set for - the internal temp table. + Note that SELECT has one "select list" but may be processed with + multiple temporary tables. It is therefore important to only set + result_field to point to the right temporary table. + That's why we assert here that we don't set it twice. */ - if (!agg_item->result_field || !param->materialized_subquery) + if (not_all_columns) + { + DBUG_ASSERT(!agg_item->result_field); agg_item->result_field= new_field; + } } tmp_from_field++; @@ -24244,12 +24293,11 @@ do_select(JOIN *join, Procedure *procedure) HAVING will be checked after processing aggregate functions, But WHERE should checked here (we alredy have read tables). Notice that make_join_select() splits all conditions in this case - into two groups exec_const_cond and outer_ref_cond. - If join->table_count == join->const_tables then it is - sufficient to check only the condition pseudo_bits_cond. + into two groups exec_const_cond and outer_ref_cond. exec_const_cond + is checked before the join starts, and it is sufficient to check + only the condition outer_ref_cond. */ - DBUG_ASSERT(join->outer_ref_cond == NULL); - if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_bool()) + if (!join->outer_ref_cond || join->outer_ref_cond->val_bool()) { // HAVING will be checked by end_select error= (*end_select)(join, 0, 0); @@ -26288,6 +26336,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) join->fields. */ List *fields= join_tab ? (join_tab-1)->fields : join->fields; + bool empty_set_send_rollup_total= false; DBUG_ENTER("end_send_group"); if (!join->items3.is_null() && join->current_ref_ptrs != join->items3) @@ -26299,7 +26348,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) if (!join->group_sent && (join->first_record || - (end_of_records && !join->group && !join->group_optimized_away))) + join->need_empty_set_row(end_of_records, + &empty_set_send_rollup_total))) { table_map cleared_tables= (table_map) 0; if (join->procedure) @@ -26355,7 +26405,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) join->send_records++; join->group_sent= true; } - if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && error <= 0)) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && + !empty_set_send_rollup_total && error <= 0)) { if (join->rollup_send_data((uint) (idx+1))) error= 1; @@ -26675,13 +26726,15 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { TABLE *table= join_tab->table; int idx= -1; + bool empty_set_send_rollup_total= false; DBUG_ENTER("end_write_group"); join->accepted_rows++; if (!join->first_record || end_of_records || (idx=test_if_group_changed(join->group_fields)) >= 0) { - if (join->first_record || (end_of_records && !join->group)) + if (join->first_record || + join->need_empty_set_row(end_of_records, &empty_set_send_rollup_total)) { table_map cleared_tables= (table_map) 0; if (join->procedure) @@ -26706,7 +26759,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); } - if (unlikely(join->rollup.state != ROLLUP::STATE_NONE)) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && + !empty_set_send_rollup_total)) { if (unlikely(join->rollup_write_data((uint) (idx+1), join_tab->tmp_table_param, @@ -31362,6 +31416,7 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, store_key **key_ref= ref.key_copy; for (uint kp= 0; kp < ref.key_parts; kp++) { + DBUG_ASSERT(kp < MAX_REF_PARTS); if ((key_part_map(1) << kp) & ref.const_ref_part_map) { if (!(eta->ref_list.append_str(thd->mem_root, "const"))) @@ -31822,7 +31877,6 @@ int JOIN::save_explain_data_intern(Explain_query *output, xpl_sel->exec_const_cond= exec_const_cond; xpl_sel->outer_ref_cond= outer_ref_cond; - xpl_sel->pseudo_bits_cond= pseudo_bits_cond; if (tmp_having) xpl_sel->having= tmp_having; else @@ -34514,9 +34568,9 @@ void JOIN::init_join_cache_and_keyread() depends on are automatically added to the read_set - because they're needed to calculate the vcol. But if we're doing keyread, vcol is taken - from the index, not calculated, and base columns do not need to be - in the read set. To ensure this we try to set the read_set to only - the key-parts of the indexes. + from the index, not calculated. The below call adds the key-parts + to the read_set, and for virtual columns also adds any base columns + they depend on. Another side effect of this is Lets say you have a query @@ -34527,7 +34581,8 @@ void JOIN::init_join_cache_and_keyread() c, which is not a problem as we read all the columns from the index tuple. */ - table->mark_index_columns(table->file->keyread, table->read_set); + bitmap_clear_all(table->read_set); + table->mark_index_columns_for_read(table->file->keyread); /* Also mark in the read_set vcol fields whose "extra" index coverings contain the keyread key, so that they are included diff --git a/sql/sql_select.h b/sql/sql_select.h index 8700e0f6df6..7996b93ec96 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1657,8 +1657,15 @@ public: ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select COND *conds; // ---"--- Item *conds_history; // store WHERE for explain - COND *outer_ref_cond; /// *join_list; ///< list of joined tables in reverse order COND_EQUAL *cond_equal; @@ -1853,12 +1860,27 @@ public: void cleanup(bool full); void clear(table_map *cleared_tables); void inline clear_sum_funcs(); + bool need_empty_set_row(bool end_of_records, + bool *empty_set_send_rollup_total) const + { + *empty_set_send_rollup_total= + end_of_records && !first_record && rollup.state != ROLLUP::STATE_NONE; + return (end_of_records && !first_record && !group && + !group_optimized_away) || + *empty_set_send_rollup_total; + } bool send_row_on_empty_set() { - return (do_send_rows && implicit_grouping && !group_optimized_away && + return (do_send_rows && + (select_lex->olap == ROLLUP_TYPE || + (implicit_grouping && !group_optimized_away)) && having_value != Item::COND_FALSE); } - bool empty_result() { return (zero_result_cause && !implicit_grouping); } + bool empty_result() + { + return (zero_result_cause && !implicit_grouping && + select_lex->olap != ROLLUP_TYPE); + } bool change_result(select_result *new_result, select_result *old_result); bool is_top_level_join() const { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6b233ea8051..b9f9b87c7b4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5552,7 +5552,21 @@ static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, bool conflict= false; char *real_end= end; if (round == 1 && own_name_base) - *end++= '_'; + { + /* + A '_' plus a numeric suffix is appended from here on, so truncate + on a character boundary to make room, both in bytes (to stay + inside buff) and in characters (so the result still respects + NAME_CHAR_LEN) -- but only now that a suffix is actually needed. + */ + size_t avail= sizeof(buff) - (1 + MY_INT32_NUM_DECIMAL_DIGITS + 1); + size_t avail_chars= NAME_CHAR_LEN - (1 + MY_INT32_NUM_DECIMAL_DIGITS); + end= buff + Well_formed_prefix(system_charset_info, buff, + MY_MIN(size_t(end - buff), avail), + avail_chars) + .length(); + *end++= '_'; + } // if own_base_name provided, try it first if (round != 0 || !own_name_base) real_end= int10_to_str((*nr)++, end, 10); @@ -7715,13 +7729,17 @@ static void update_altered_table(const Alter_inplace_info &ha_alter_info, second table. @param[in] create_info Create options for the second table. @param[out] metadata_equal Result of comparison. + @param[in] compare_vcol_expr_as_sets + Ignore AND/OR order and duplicate terms in + generated column expressions. @retval true error @retval false success */ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, - HA_CREATE_INFO *create_info, bool *metadata_equal) + HA_CREATE_INFO *create_info, bool *metadata_equal, + bool compare_vcol_expr_as_sets) { DBUG_ENTER("mysql_compare_tables"); @@ -7790,7 +7808,8 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, { if (!tmp_new_field->field->vcol_info) DBUG_RETURN(false); - if (!field->vcol_info->is_equal(tmp_new_field->field->vcol_info, true)) + if (!field->vcol_info->is_equal(tmp_new_field->field->vcol_info, + true, compare_vcol_expr_as_sets)) DBUG_RETURN(false); } diff --git a/sql/sql_table.h b/sql/sql_table.h index 647771151c9..b1496e858d6 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -169,7 +169,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, - bool *metadata_equal); + bool *metadata_equal, + bool compare_vcol_expr_as_sets); bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, class Recreate_info *recreate_info, bool table_copy); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 91c9c375a96..a65c42f2a71 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -746,4 +746,18 @@ const char *dbug_which_mem_root(THD *thd, void *ptr) return "Unknown"; } + +/* Return how much memory was malloc'ed for this mem_root */ +size_t dbug_get_mem_root_alloc_size(const MEM_ROOT *mem_root) +{ + size_t total=0; + const USED_MEM *ptrs[]= {mem_root->free, mem_root->used, NULL}; + for (const USED_MEM **p= ptrs; *p; p++) + { + for (const USED_MEM *block= *p; block; block= block->next) + total += block->size; + } + return total; +} + #endif diff --git a/sql/sql_test.h b/sql/sql_test.h index ce154ed9954..5cda32662bb 100644 --- a/sql/sql_test.h +++ b/sql/sql_test.h @@ -52,6 +52,9 @@ const char *dbug_print_row(TABLE *table, const uchar *rec); bool dbug_is_mem_on_mem_root(const MEM_ROOT *mem_root, void *ptr); const char *dbug_which_mem_root(THD *thd, void *ptr); +/* Return how much memory was malloc'ed for this mem_root */ +size_t dbug_get_mem_root_alloc_size(const MEM_ROOT *mem_root); + #else // A dummy implementation is used in release builds inline const char *dbug_print_item(Item *item) { return NULL; } diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 253854fcd19..adaae9f01aa 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -894,6 +894,12 @@ static bool cmp_row_types(Item* item1, Item* item2) { Item *inner= item1->element_index(i); Item *outer= item2->element_index(i); + /* + A table value constructor cannot have a ROW as a column, so an IN + predicate with a nested ROW cannot be converted. + */ + if (inner->cols() != 1 || outer->cols() != 1) + return true; if (!inner->type_handler()->subquery_type_allows_materialization(inner, outer, true)) diff --git a/sql/sql_type.cc b/sql/sql_type.cc index eb6ff5b4234..4e9db270fbb 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2363,6 +2363,22 @@ Type_handler_int_result::make_num_distinct_aggregator_field(MEM_ROOT *mem_root, } +Field * +Type_handler_hex_hybrid::make_num_distinct_aggregator_field( + MEM_ROOT *mem_root, const Item *item) const +{ + /* + Hex and bit literals have unsigned integer values in numeric aggregates. + Their max_length is a byte count, not a DOUBLE(M,0) display width. + */ + return new (mem_root) + Field_longlong(NULL, item->max_length, + (uchar *) (item->maybe_null() ? "" : 0), + item->maybe_null() ? 1 : 0, Field::NONE, + &item->name, 0, true /* unsigned */); +} + + /***********************************************************************/ Field *Type_handler_tiny::make_conversion_table_field(MEM_ROOT *root, diff --git a/sql/sql_type.h b/sql/sql_type.h index 40694237404..6ac47611768 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3078,17 +3078,25 @@ public: @@character_set_connection MY_COLL_DISALLOW_NONE - don't allow return DERIVATION_NONE (e.g. when aggregating for comparison) + MY_COLL_ALLOW_BY_TAILORING - allow choosing either side's collation + without conversion, when both collations + have an equal tailoring on the repertoire + of the aggregated arguments (see + DTCollation::aggregate_by_tailoring()) MY_COLL_CMP_CONV - combination of MY_COLL_ALLOW_CONV and MY_COLL_DISALLOW_NONE + and MY_COLL_ALLOW_BY_TAILORING */ #define MY_COLL_ALLOW_SUPERSET_CONV 1 #define MY_COLL_ALLOW_COERCIBLE_CONV 2 #define MY_COLL_DISALLOW_NONE 4 #define MY_COLL_ALLOW_NUMERIC_CONV 8 +#define MY_COLL_ALLOW_BY_TAILORING 16 #define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV) -#define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE) +#define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE | \ + MY_COLL_ALLOW_BY_TAILORING) #define MY_REPERTOIRE_NUMERIC MY_REPERTOIRE_ASCII @@ -3161,6 +3169,9 @@ enum Derivation */ class DTCollation { + + bool aggregate_by_tailoring(const DTCollation &dt, uint flags, + my_repertoire_t cumulative_repertoire); public: CHARSET_INFO *collation; enum Derivation derivation; @@ -3171,6 +3182,39 @@ public: repertoire= cs->state & MY_CS_PUREASCII ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; } + + /* + Case conversion (e.g. LOWER, UPPER) turns ASCII upper case letters + into lower case ones and vice versa, so the result can contain letters + of both cases if the argument contained letters of any case. + In Turkish collations, ASCII letters can also be converted to non-ASCII + ones: LOWER('I') returns the dotless 'i' (U+0131) and UPPER('i') returns + the dotted 'I' (U+0130). + */ + void fix_repertoire_for_case_conversion() + { + if (repertoire & MY_REPERTOIRE_ASCII_LETTERS) + { + repertoire|= MY_REPERTOIRE_ASCII_LETTERS; + if ((collation->casefold && + collation->casefold->can_convert_to_non_ascii_on_casefolding) || + (collation->to_lower && collation->to_lower['I'] != 'i') || + (collation->to_upper && collation->to_upper['i'] != 'I')) + repertoire|= MY_REPERTOIRE_EXTENDED; + } + } + + /* + Check if all characters of this repertoire belong to the given repertoire, + e.g. repertoire_is_subset_of(MY_REPERTOIRE_ASCII) means "only ASCII". + Note, do not use "repertoire == MY_REPERTOIRE_ASCII" for this purpose, + as repertoire values are sets of bits. + */ + bool repertoire_is_subset_of(my_repertoire_t repertoire_arg) const + { + return my_repertoire_is_subset_of(repertoire, repertoire_arg); + } + DTCollation() { collation= &my_charset_bin; @@ -3236,9 +3280,13 @@ public: } void set(Derivation derivation_arg) { derivation= derivation_arg; } - bool aggregate(const DTCollation &dt, uint flags= 0); - bool set(DTCollation &dt1, DTCollation &dt2, uint flags= 0) - { set(dt1); return aggregate(dt2, flags); } + bool aggregate(const DTCollation &dt, uint flags, + my_repertoire_t cumulative_repertoire); + bool set(DTCollation &dt1, DTCollation &dt2, uint flags) + { + set(dt1); + return aggregate(dt2, flags, dt1.repertoire | dt2.repertoire); + } bool merge_charset_and_collation(Sql_used *used, const Charset_collation_map_st &map, CHARSET_INFO *cs, @@ -3540,7 +3588,8 @@ public: { uint flags= MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV | - MY_COLL_DISALLOW_NONE; + MY_COLL_DISALLOW_NONE | + MY_COLL_ALLOW_BY_TAILORING; return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep); } @@ -7436,6 +7485,8 @@ class Type_handler_hex_hybrid: public Type_handler_varchar { public: virtual ~Type_handler_hex_hybrid() = default; + Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const + override; const Type_handler *cast_to_int_type_handler() const override; bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, Type_handler_hybrid_field_type *h, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4d87b47a2c1..5ae95321a77 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1832,7 +1832,8 @@ rule: fetch_first_clause %type - query_expression_tail + query_expression_tail_with_order + query_expression_tail_no_order opt_query_expression_tail order_or_limit opt_order_or_limit @@ -9281,12 +9282,26 @@ query_expression_body_ext: } | query_expression_body_ext_parens { - Lex->push_select(!$1->first_select()->next_select() ? - $1->first_select() : $1->fake_select_lex); + if (!($$= + Lex->push_select_for_ext_parens_tail($1, true))) + MYSQL_YYABORT; } - query_expression_tail + query_expression_tail_with_order { - if (!($$= Lex->add_tail_to_query_expression_body_ext_parens($1, $3))) + if (!($$= Lex->add_tail_to_query_expression_body_ext_parens( + $1, $3, $2))) + MYSQL_YYABORT; + } + | query_expression_body_ext_parens + { + if (!($$= + Lex->push_select_for_ext_parens_tail($1, false))) + MYSQL_YYABORT; + } + query_expression_tail_no_order + { + if (!($$= Lex->add_tail_to_query_expression_body_ext_parens( + $1, $3, $2))) MYSQL_YYABORT; } ; @@ -13330,8 +13345,43 @@ opt_order_limit_lock: | order_limit_lock { $$= $1; } ; -query_expression_tail: - order_limit_lock +/* + The tail of a parenthesized query expression body is split on whether it + starts with ORDER BY, so that the select owning the tail can be chosen + before the tail is parsed (see LEX::push_select_for_ext_parens_tail()). +*/ + +query_expression_tail_with_order: + order_clause opt_limit_clause opt_select_lock_type + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= $1; + $$->limit= $2; + $$->lock= $3; + } + ; + +query_expression_tail_no_order: + limit_clause opt_select_lock_type + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= NULL; + $$->limit= $1; + $$->lock= $2; + } + | select_lock_type + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= NULL; + $$->limit.clear(); + $$->lock= $1; + } ; opt_query_expression_tail: diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2c2d744f5d3..0d8908567c6 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4186,6 +4186,7 @@ static const char *old_mode_names[]= "LOCK_ALTER_TABLE_COPY", // 7: deprecated since 11.3 "OLD_FLUSH_STATUS", // 8: deprecated since 11.5 "SESSION_USER_IS_USER", // 9: deprecated since 11.7 + "X509_LENIENT_COMPARE", // 10: deprecated since 13.1 0 }; @@ -4211,6 +4212,10 @@ static bool old_mode_deprecated(sys_var *self, THD *thd, set_var *var) for (; i <= 9; i++) if ((1ULL<(thd, old_mode_names[i]); + for (; i <= 10; i++) + if ((1ULL<(thd, old_mode_names[i]); + DBUG_ASSERT(old_mode_names[i] == 0); // all modes were used up above return false; } @@ -5976,6 +5981,9 @@ Sys_var_rpl_filter::global_value_ptr(THD *thd, Master_info *mi; Rpl_filter *rpl_filter; + if (!base_name->str) + base_name= &thd->variables.default_master_connection; + mysql_mutex_unlock(&LOCK_global_system_variables); mi= get_master_info(base_name, !base_name->length ? Sql_condition::WARN_LEVEL_ERROR : diff --git a/sql/table.cc b/sql/table.cc index 130fbcd8087..4c28df1cbe6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8003,7 +8003,7 @@ inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap) } -inline void TABLE::mark_index_columns_for_read(uint index) +void TABLE::mark_index_columns_for_read(uint index) { do_mark_index_columns(this, index, read_set, true); } @@ -8732,7 +8732,7 @@ bool TABLE::alloc_keys(uint key_count) { memmove(new_key_info, s->key_info, sizeof(*key_info) * s->total_keys); memmove(new_const_key_parts, const_key_parts, - s->total_keys * sizeof(const_key_parts)); + s->total_keys * sizeof *const_key_parts); } s->key_info= key_info= new_key_info; const_key_parts= new_const_key_parts; @@ -9593,6 +9593,16 @@ int TABLE::update_virtual_field(Field *vf, bool ignore_warnings) Query_arena backup_arena; Counting_error_handler count_errors; Suppress_warnings_error_handler warning_handler; + /* + Do not use tmp_set here: it may be the active read_set (filesort, + keyread), and the engine may call this in the middle of a scan. + */ + MY_BITMAP done_vcols; + const uint bitmap_size= bitmap_buffer_size(s->fields); + my_bitmap_map *done_buf= (my_bitmap_map *) my_safe_alloca(bitmap_size); + if (!done_buf) + DBUG_RETURN(1); + my_bitmap_init(&done_vcols, done_buf, s->fields); in_use->push_internal_handler(&count_errors); bool abort_on_warning= ignore_warnings; if (ignore_warnings) @@ -9607,8 +9617,8 @@ int TABLE::update_virtual_field(Field *vf, bool ignore_warnings) TABLE::update_virtual_fields(handler *, enum_vcol_update_mode). */ in_use->set_n_backup_active_arena(expr_arena, &backup_arena); - bitmap_clear_all(&tmp_set); - vf->vcol_info->expr->walk(&Item::update_vcol_processor, &tmp_set, 0); + vf->vcol_info->expr->walk(&Item::update_vcol_processor, &done_vcols, 0); + my_safe_afree(done_buf, bitmap_size); DBUG_FIX_WRITE_SET(vf, write_set); vf->vcol_info->expr->save_in_field(vf, 0); DBUG_RESTORE_WRITE_SET(vf, write_set); diff --git a/sql/table.h b/sql/table.h index 8994b16e893..6bfce6dbbdd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2383,11 +2383,47 @@ public: struct vers_select_conds_t { + /* + Effective system-time selection used to build the actual row condition + (row_start/row_end predicate). is_set() tests it against SYSTEM_TIME_UNSPECIFIED. + set_all() forces it to SYSTEM_TIME_ALL in three situations: + + 1) once the row_start/row_end predicate for the requested time has been + generated and attached to the query - marking it applied so a later pass + or the next prepared-statement execution neither rebuilds nor re-applies + it (guarded by "if (type == SYSTEM_TIME_ALL) continue"); + + 2) a versioned table whose history is stored in partitions is queried with + an explicit PARTITION(...) clause - the named partitions are read as-is, + without a versioning predicate; + + 3) the same kind of table accessed without FOR SYSTEM_TIME, PARTITION(...) + and @@system_versioning_asof - + read_partitions is narrowed to the now-partition, which takes the place + of the row_end predicate. + */ vers_system_time_t type; + /* + Originally requested system-time selection, set by init() from an explicit + FOR SYSTEM_TIME or DELETE HISTORY clause, or copied with the conditions of + an outer derived table or view. Unlike 'type' it is NOT overwritten by + set_all(), so it still reflects the request after the predicate has been + applied. + Tested by was_set(); used by print() to reconstruct the FOR SYSTEM_TIME + clause. + */ vers_system_time_t orig_type; bool used:1; bool delete_history:1; bool has_param:1; + /* + Set by init_from_sysvar() when @@system_versioning_asof supplied the + selection. Tested to keep the now-partition narrowing off, so the query + still reads history. Unlike orig_type it affects neither print() nor + the write lock check, and it persists to prepared-statement + re-execution, where init_from_sysvar() is skipped. + */ + bool from_sysvar:1; Vers_history_point start; Vers_history_point end; Lex_ident_column name; @@ -2404,6 +2440,7 @@ struct vers_select_conds_t used= false; delete_history= false; has_param= false; + from_sysvar= false; start.empty(); end.empty(); } @@ -2419,6 +2456,7 @@ struct vers_select_conds_t delete_history= (type == SYSTEM_TIME_HISTORY || type == SYSTEM_TIME_BEFORE); has_param= false; + from_sysvar= false; start= _start; end= _end; name= _name; diff --git a/sql/winmain.cc b/sql/winmain.cc index 694e62e87d5..79bf6dde5f6 100644 --- a/sql/winmain.cc +++ b/sql/winmain.cc @@ -56,6 +56,7 @@ #include #include #include +#include "message.h" static SERVICE_STATUS svc_status{SERVICE_WIN32_OWN_PROCESS}; static SERVICE_STATUS_HANDLE svc_status_handle; @@ -109,13 +110,27 @@ static void report_svc_status(DWORD current_state, DWORD exit_code, DWORD wait_h SetServiceStatus(svc_status_handle, &svc_status); } +/* Fits fixed text + command name + service name(MAX_PATH) + error code. */ +#define SVC_REPORT_BUFSIZE (MAX_PATH + 128) + /* Report unexpected errors. */ -static void svc_report_event(const char *svc_name, const char *command) +static void svc_report_event(const char *service_name, const char *command, + DWORD error) { - char buffer[80]; - sprintf_s(buffer, "mariadb service %s, %s failed with %d", - svc_name, command, GetLastError()); + char buffer[SVC_REPORT_BUFSIZE]; + snprintf(buffer, sizeof(buffer), + "mariadb service %s, %s failed with error %lu", + service_name ? service_name : "", command, error); OutputDebugString(buffer); + + HANDLE event= RegisterEventSource(NULL, "MariaDB"); + if (event) + { + const char *strings[]= {buffer}; + ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, + strings, NULL); + DeregisterEventSource(event); + } } /* @@ -147,12 +162,13 @@ static void WINAPI svc_ctrl_handle(DWORD cntrl) static void WINAPI svc_main(DWORD svc_argc, char **svc_argv) { /* Register the handler function for the service */ - char *name= svc_argv[0]; + svc_name= svc_argv[0]; - svc_status_handle= RegisterServiceCtrlHandler(name, svc_ctrl_handle); + svc_status_handle= RegisterServiceCtrlHandler(svc_name, svc_ctrl_handle); if (!svc_status_handle) { - svc_report_event(name, "RegisterServiceCtrlHandler"); + DWORD error= GetLastError(); + svc_report_event(svc_name, "RegisterServiceCtrlHandler", error); return; } report_svc_status(SERVICE_START_PENDING, NO_ERROR, 0); @@ -161,7 +177,7 @@ static void WINAPI svc_main(DWORD svc_argc, char **svc_argv) mysqld_set_service_status_callback(report_svc_status); /* This would add service name entry to load_defaults.*/ - mysqld_win_set_service_name(name); + mysqld_win_set_service_name(svc_name); /* Do not pass the service name parameter (last on the command line) @@ -172,45 +188,24 @@ static void WINAPI svc_main(DWORD svc_argc, char **svc_argv) } /* - This start the service. Sometimes it will fail, because - currently we do not know for sure whether we run as service or not. + This start the service. We currently do not know for sure + whether we run as service or not. If this fails, the fallback is to run as normal process. */ -static int run_as_service(char *name) +static int run_as_service() { - SERVICE_TABLE_ENTRY stb[]= {{name, svc_main}, {0, 0}}; + char service_name[]= ""; + SERVICE_TABLE_ENTRY stb[]= {{service_name, svc_main}, {0, 0}}; if (!StartServiceCtrlDispatcher(stb)) { - assert(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT); + DWORD error= GetLastError(); + if (error != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) + svc_report_event("", "StartServiceCtrlDispatcher", error); return -1; } return 0; } -/* - Check for valid existing service name. - Part of our guesswork, whether we run as service or not. -*/ -static bool is_existing_service(const char *name) -{ - if (strchr(name, '\\') || strchr(name, '/')) - { - /* Invalid characters in service name */ - return false; - } - - SC_HANDLE sc_service= 0, scm= 0; - bool ret= ((scm= OpenSCManager(0, 0, SC_MANAGER_ENUMERATE_SERVICE)) != 0) && - ((sc_service= OpenService(scm, name, SERVICE_QUERY_STATUS)) != 0); - - if (sc_service) - CloseServiceHandle(sc_service); - if (scm) - CloseServiceHandle(scm); - - return ret; -} - /* If service name is not given to --install/--remove it is assumed to be "MySQL" (traditional handling) @@ -268,10 +263,8 @@ __declspec(dllexport) int mysqld_win_main(int argc, char **argv) return remove_service(get_svc_name(argv[2])); /* Try to run as service, and fallback to mysqld_main(), if this fails */ - svc_name= argv[argc - 1]; - if (is_existing_service(svc_name) && !run_as_service(svc_name)) + if (!run_as_service()) return 0; - svc_name= 0; /* Run as normal program.*/ return mysqld_main(argc, argv); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 27bba02ee92..b80506e340b 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -120,11 +120,10 @@ my_bool wsrep_incremental_data_collection= 0; // Incremental data collection bool wsrep_new_cluster= false; // Bootstrap the cluster? int wsrep_slave_count_change= 0; // No. of appliers to stop/start int wsrep_to_isolation= 0; // No. of active TO isolation threads -// -// NOTE : MySQL Cluster has max_protocol version 7 -// thus protocol versions 5-7 are reserved for compatibility. +// 5: CHAR write set key values are normalized to the number of characters +// the column holds, see wsrep_store_string_key_val() +long wsrep_max_protocol_version= 5; // Maximum protocol version to use // -long wsrep_max_protocol_version= 4; // Maximum protocol version to use long int wsrep_protocol_version= wsrep_max_protocol_version; ulong wsrep_trx_fragment_unit= WSREP_FRAG_BYTES; // unit for fragment size @@ -2017,7 +2016,6 @@ static bool wsrep_prepare_key_for_isolation(const char* db, case 2: case 3: case 4: - // For MySQL Galera Cluster migration case 5: case 6: case 7: @@ -2200,7 +2198,6 @@ bool wsrep_prepare_key(const uchar* cache_key, size_t cache_key_len, case 2: case 3: case 4: - // For MySQL Galera Cluster migration case 5: case 6: case 7: diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc index 0ede84e4cf9..ca8c01e71d2 100644 --- a/sql/wsrep_server_service.cc +++ b/sql/wsrep_server_service.cc @@ -228,11 +228,18 @@ void Wsrep_server_service::log_view( static_cast(high_priority_service); /* Update global system variables */ mysql_mutex_lock(&LOCK_global_system_variables); + /* The negotiated protocol version gates the writeset format, so it must be + picked up regardless of wsrep_auto_increment_control. Leaving it at this + node's own maximum would make a node in a cluster that settled on an older + version keep emitting the newer format. */ + if (view.own_index() >= 0) + { + wsrep_protocol_version= view.protocol_version(); + } if (wsrep_auto_increment_control && view.own_index() >= 0) { global_system_variables.auto_increment_offset= view.own_index() + 1; global_system_variables.auto_increment_increment= view.members().size(); - wsrep_protocol_version= view.protocol_version(); } mysql_mutex_unlock(&LOCK_global_system_variables); diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 42a8078d78b..6ead04e6454 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -1344,30 +1344,38 @@ static ssize_t sst_prepare_mysqldump (const char* addr_in, if (ret > 0 && ret < s) { *addr_out= tmp; + } + else + { + if (ret > 0) /* buffer too short */ ret= -EMSGSIZE; + free (tmp); + WSREP_ERROR ("Could not prepare state transfer request: " + "adding default port failed: %zd.", ret); return ret; } - if (ret > 0) /* buffer too short */ ret= -EMSGSIZE; - free (tmp); } else { ret= -ENOMEM; + WSREP_ERROR ("Could not prepare state transfer request: " + "adding default port failed: %zd.", ret); + return ret; } - - WSREP_ERROR ("Could not prepare state transfer request: " - "adding default port failed: %zd.", ret); } else { *addr_out= addr_in; } pthread_t monitor; - ret = mysql_thread_create (key_wsrep_sst_joiner_monitor, &monitor, NULL, wsrep_sst_joiner_monitor_thread, NULL); + int thread_ret= mysql_thread_create (key_wsrep_sst_joiner_monitor, &monitor, + NULL, wsrep_sst_joiner_monitor_thread, + NULL); - if (ret) + if (thread_ret) { - WSREP_ERROR("sst_prepare_other(): mysql_thread_create() failed: %d (%s)", - ret, strerror(ret)); - return -ret; + WSREP_ERROR("sst_prepare_mysqldump(): mysql_thread_create() failed: " + "%d (%s)", thread_ret, strerror(thread_ret)); + if (*addr_out != addr_in) free ((char*) *addr_out); + return -thread_ret; } sst_joiner_completed= false; diff --git a/storage/connect/global.h b/storage/connect/global.h index a7dd1117a79..3e7c222fc7e 100644 --- a/storage/connect/global.h +++ b/storage/connect/global.h @@ -220,6 +220,7 @@ DllExport bool AllocSarea(PGLOBAL, size_t); DllExport void FreeSarea(PGLOBAL); DllExport BOOL PlugSubSet(void *, size_t); DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t); +DllExport size_t PlugSubAllocLeft(PGLOBAL, void *); DllExport char *PlugDup(PGLOBAL g, const char *str); DllExport void htrc(char const *fmt, ...); DllExport void xtrc(uint, char const* fmt, ...); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 0f0a008af60..5379eb38cbd 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -2875,6 +2875,36 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) return filp; } // end of CondFilter +/***********************************************************************/ +/* Return true if appending addlen more bytes (plus the terminating */ +/* null) to the Body/Having buffer designated by ishav would still */ +/* fit within its actually reserved capacity (filp->Blen/Hlen). */ +/***********************************************************************/ +static bool CondFilFits(PCFIL filp, bool ishav, size_t addlen) +{ + char *s= ishav ? filp->Having : filp->Body; + size_t smax= ishav ? filp->Hlen : filp->Blen; + + return strlen(s) + addlen < smax; +} // end of CondFilFits + +/***********************************************************************/ +/* Append add to the Body/Having buffer designated by ishav, but only */ +/* if it still fits. Return false, leaving the buffer unchanged, when */ +/* it does not: the caller then gives up pushing the condition down. */ +/***********************************************************************/ +static bool CondFilCat(PCFIL filp, bool ishav, const char *add) +{ + char *s= ishav ? filp->Having : filp->Body; + size_t len= strlen(s); + + if (!CondFilFits(filp, ishav, strlen(add))) + return false; + + strcpy(s + len, add); + return true; +} // end of CondFilCat + /***********************************************************************/ /* Check the WHERE condition and return a MYSQL/ODBC/JDBC/WQL filter. */ /***********************************************************************/ @@ -2920,12 +2950,18 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) const Item *subitem; pb0= pb1= body + strlen(body); - strcpy(pb0, "("); + + if (!CondFilCat(filp, false, "(")) + return NULL; + pb2= pb1 + 1; if (havg) { ph0= ph1= havg + strlen(havg); - strcpy(ph0, "("); + + if (!CondFilCat(filp, true, "(")) + return NULL; + ph2= ph1 + 1; } // endif havg @@ -2942,13 +2978,19 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) } else { if (filp->Bd) { pb1= pb2 + strlen(pb2); - strcpy(pb1, GetValStr(vop, false)); + + if (!CondFilCat(filp, false, GetValStr(vop, false))) + return NULL; + pb2= pb1 + strlen(pb1); } // endif Bd if (filp->Hv) { ph1= ph2 + strlen(ph2); - strcpy(ph1, GetValStr(vop, false)); + + if (!CondFilCat(filp, true, GetValStr(vop, false))) + return NULL; + ph2= ph1 + strlen(ph1); } // endif Hv @@ -2961,6 +3003,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) return NULL; if (bb) { + // Overwrites the trailing operator, so this cannot grow the buffer strcpy(pb1, ")"); filp->Bd= bb; } else @@ -2973,6 +3016,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) *pb0= 0; *ph0= 0; } else if (bh) { + // Overwrites the trailing operator, so this cannot grow the buffer strcpy(ph1, ")"); filp->Hv= bh; } else @@ -3091,10 +3135,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) htrc("Field type=%d\n", pField->field->type()); htrc("Field_type=%d\n", args[i]->field_type()); } // endif trace - if (tty == TYPE_AM_MYSQL && !(x || ismul)) - strcat((ishav ? havg : body), strColumn.ptr()); - else - strcat((ishav ? havg : body), fnm); + if (!CondFilCat(filp, ishav, (tty == TYPE_AM_MYSQL && !(x || ismul)) ? + strColumn.ptr() : fnm)) + return NULL; } else if (args[i]->type() == COND::FUNC_ITEM) { if (tty == TYPE_AM_MYSQL) { if (!CheckCond(g, filp, args[i])) @@ -3133,6 +3176,14 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) char *s= (ishav) ? havg : body; uint j, k, n; + /* + A literal value (e.g. a string constant) can be arbitrarily large. + Refuse to push this condition down rather than write past the end of + the pre-allocated buffer; let the caller do the filtering instead. + */ + if (!CondFilFits(filp, ishav, (size_t)res->length() * 2 + 32)) + return NULL; + // Append the value to the filter switch (args[i]->field_type()) { case MYSQL_TYPE_TIMESTAMP: @@ -3242,14 +3293,17 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) } // endif's Type if (!x) { - char *s= (ishav) ? havg : body; + const char *add= NULL; if (!i) - strcat(s, GetValStr(vop, neg)); + add= GetValStr(vop, neg); else if (vop == OP_XX && i == 1) - strcat(s, " AND "); + add= " AND "; else if (vop == OP_IN) - strcat(s, (i == condf->argument_count() - 1) ? ")" : ","); + add= (i == condf->argument_count() - 1) ? ")" : ","; + + if (add && !CondFilCat(filp, ishav, add)) + return NULL; } // endif x @@ -3320,12 +3374,20 @@ const COND *ha_connect::cond_push(const COND *cond) if (rc == RC_INFO) { filp->Having= (char*)PlugSubAlloc(g, NULL, 256); *filp->Having= 0; + filp->Hlen= 256; // HAVING's own dedicated reservation } else if (rc == RC_FX) goto fin; filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); *filp->Body= 0; + /* + Body is not (or minimally) pre-reserved; it relies on whatever is + left in the work area (Sarea). Record that true remaining capacity so + CheckCond can refuse to grow Body past the allocated work area. + */ + filp->Blen= PlugSubAllocLeft(g, NULL); + if (CheckCond(g, filp, cond)) { if (filp->Having && strlen(filp->Having) > 255) goto fin; // Memory collapse diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp index c6265c6fb79..0ceae223966 100644 --- a/storage/connect/javaconn.cpp +++ b/storage/connect/javaconn.cpp @@ -218,6 +218,111 @@ void JAVAConn::ResetJVM(void) } // end of ResetJVM +#if defined(_WIN32) +/* + Remember the error of a JVM probe. Only the first error that is not + "not found" is kept, so that e.g. a wrong bitness is not hidden by the + next probe. err is initially ERROR_MOD_NOT_FOUND. +*/ +static void set_jvm_error(DWORD *err, DWORD error) +{ + if (*err == ERROR_MOD_NOT_FOUND || *err == ERROR_PATH_NOT_FOUND) + *err= error; +} + + +/* Check the snprintf() result for a truncated path; record the error. */ +static bool path_fits(int len, size_t size, DWORD *err) +{ + if (len < int(size)) + return true; + set_jvm_error(err, ERROR_FILENAME_EXCED_RANGE); + return false; +} + + +/* Load jvm.dll from the path. */ +static HMODULE load_jvm(const char *path, DWORD *err) +{ + HMODULE h; + + if (!(h= LoadLibrary(path))) + set_jvm_error(err, GetLastError()); + return h; +} + + +/* Read a string value from HKLM, a missing value is not an error. */ +static bool get_registry_string(const char *key, const char *name, char *buf, + DWORD size, DWORD *err) +{ + LSTATUS rc= RegGetValue(HKEY_LOCAL_MACHINE, key, name, + RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ, NULL, buf, + &size); + if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) + set_jvm_error(err, rc == ERROR_MORE_DATA ? ERROR_FILENAME_EXCED_RANGE : rc); + return rc == ERROR_SUCCESS; +} + + +/* + Load jvm.dll from a JDK or JRE home. Like java.exe, prefer "server" (the + only JVM since JDK 9) over "client", also in the jre subdirectory of JDK 8. +*/ +static HMODULE load_jvm_from_home(const char *home, DWORD *err) +{ + static const char *dirs[]= + { + "\\bin\\server", "\\bin\\client", "\\jre\\bin\\server", "\\jre\\bin\\client" + }; + char path[MAX_PATH]; + HMODULE h= NULL; + + for (uint i= 0; !h && i < array_elements(dirs); i++) + { + if (path_fits(snprintf(path, sizeof(path), "%s%s\\jvm.dll", home, dirs[i]), + sizeof(path), err)) + h= load_jvm(path, err); + } + return h; +} + + +/* + Load jvm.dll using the registry keys of Java installers: JavaSoft\{JDK|JRE} + has CurrentVersion, naming a subkey with RuntimeLib (JRE) or JavaHome. + JDK 8 used the longer key names. +*/ +static HMODULE load_jvm_from_registry(DWORD *err) +{ + static const char *keys[]= + { + "SOFTWARE\\JavaSoft\\JDK", "SOFTWARE\\JavaSoft\\JRE", + "SOFTWARE\\JavaSoft\\Java Development Kit", + "SOFTWARE\\JavaSoft\\Java Runtime Environment" + }; + HMODULE h= NULL; + + for (uint i= 0; !h && i < array_elements(keys); i++) + { + char version[MAX_PATH], subkey[MAX_PATH], path[MAX_PATH]; + + if (!get_registry_string(keys[i], "CurrentVersion", version, + sizeof(version), err)) + continue; + + if (!path_fits(snprintf(subkey, sizeof(subkey), "%s\\%s", keys[i], version), + sizeof(subkey), err)) + continue; + if (get_registry_string(subkey, "RuntimeLib", path, sizeof(path), err)) + h= load_jvm(path, err); + if (!h && get_registry_string(subkey, "JavaHome", path, sizeof(path), err)) + h= load_jvm_from_home(path, err); + } + return h; +} +#endif /* _WIN32 */ + /***********************************************************************/ /* Dynamically link the JVM library. */ /* The purpose of this function is to allow using the CONNECT plugin */ @@ -225,61 +330,38 @@ void JAVAConn::ResetJVM(void) /***********************************************************************/ bool JAVAConn::GetJVM(PGLOBAL g) { - int ntry; - if (!LibJvm) { - char soname[512]; - #if defined(_WIN32) - for (ntry = 0; !LibJvm && ntry < 3; ntry++) { - if (!ntry && JvmPath) { - snprintf(soname, sizeof(soname), "%s\\jvm.dll", JvmPath); + DWORD err = ERROR_MOD_NOT_FOUND; + char path[MAX_PATH]; - ntry = 3; // No other try - } else if (ntry < 2 && getenv("JAVA_HOME")) { - safe_strcpy(soname, sizeof(soname), getenv("JAVA_HOME")); + const char *what = "jvm.dll (set JAVA_HOME or connect_jvm_path)"; - if (ntry == 1) - safe_strcat(soname, sizeof(soname), "\\jre"); + if (JvmPath) { + // An explicitly configured path is exclusive, no fallback + what = JvmPath; + if (path_fits(snprintf(path, sizeof(path), "%s\\jvm.dll", JvmPath), + sizeof(path), &err)) + LibJvm = load_jvm(path, &err); + } else { + const char *home = getenv("JAVA_HOME"); - safe_strcat(soname, sizeof(soname), "\\bin\\client\\jvm.dll"); - } else { - // Try to find it through the registry - char version[16]; - char javaKey[64] = "SOFTWARE\\JavaSoft\\Java Runtime Environment"; - LONG rc; - DWORD BufferSize = 16; + if (home && *home) + LibJvm = load_jvm_from_home(home, &err); - safe_strcpy(soname, sizeof(soname), "jvm.dll"); // In case it fails - - if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion", - RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) { - safe_strcat(javaKey, sizeof(javaKey), "\\"); - safe_strcat(javaKey, sizeof(javaKey), version); - BufferSize = sizeof(soname); - - if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib", - RRF_RT_ANY, NULL, (PVOID)&soname, &BufferSize)) != ERROR_SUCCESS) - printf("RegGetValue: rc=%ld\n", rc); - - } // endif rc - - ntry = 3; // Try this only once - } // endelse - - // Load the desired shared library - LibJvm = LoadLibrary(soname); - } // endfor ntry + if (!LibJvm) + LibJvm = load_jvm_from_registry(&err); + } // Get the needed entries if (!LibJvm) { char buf[256]; - DWORD rc = GetLastError(); + DWORD rc = err; FormatMessage(FORMAT_MESSAGE_FLAGS, NULL, rc, 0, (LPTSTR)buf, sizeof(buf), NULL); snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR)": %s", rc, - soname, buf); + what, buf); } else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm, "JNI_CreateJavaVM"))) { snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM"); @@ -300,6 +382,8 @@ bool JAVAConn::GetJVM(PGLOBAL g) #endif // _DEBUG } // endif LibJvm #else // !_WIN32 + char soname[FN_REFLEN]; + int ntry; const char *error = NULL; for (ntry = 0; !LibJvm && ntry < 2; ntry++) { diff --git a/storage/connect/mysql-test/connect/r/filter.result b/storage/connect/mysql-test/connect/r/filter.result new file mode 100644 index 00000000000..1295c08411b --- /dev/null +++ b/storage/connect/mysql-test/connect/r/filter.result @@ -0,0 +1,24 @@ +# +# MDEV-41193: ASAN heap-buffer-overflow in ha_connect::CheckCond after select from Connect table +# +CREATE TABLE t1 ( id INT, val varchar(500)) engine=myisam; +INSERT INTO t1 VALUES (1,'hello'),(2,'world'); +SET SESSION connect_work_size = 4194304; +SET SESSION connect_xtrace = 'QUERY'; +CREATE TABLE t2 ( id INT, val varchar(500) +) ENGINE=CONNECT table_type=MYSQL +CONNECTION='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1'; +SELECT COUNT(*) FROM t2 WHERE val = REPEAT('A', 4300000); +COUNT(*) +0 +FOUND 1 /Query=SELECT `val` FROM `t1`/ in mysqld.1.err +SELECT COUNT(*) FROM t2 WHERE val = REPEAT('A', 4300000) AND id = 1; +COUNT(*) +0 +FOUND 1 /Query=SELECT `id`, `val` FROM `t1` WHERE \(`id`= 1\)/ in mysqld.1.err +SELECT COUNT(*) FROM t2 WHERE id = 1 AND val = REPEAT('A', 4300000); +COUNT(*) +0 +FOUND 2 /Query=SELECT `id`, `val` FROM `t1` WHERE \(`id`= 1\)/ in mysqld.1.err +DROP TABLE t2, t1; +# End of 10.11 tests diff --git a/storage/connect/mysql-test/connect/t/filter.test b/storage/connect/mysql-test/connect/t/filter.test new file mode 100644 index 00000000000..8b6a594a229 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/filter.test @@ -0,0 +1,49 @@ +--echo # +--echo # MDEV-41193: ASAN heap-buffer-overflow in ha_connect::CheckCond after select from Connect table +--echo # + +--source include/not_embedded.inc + +CREATE TABLE t1 ( id INT, val varchar(500)) engine=myisam; +INSERT INTO t1 VALUES (1,'hello'),(2,'world'); + +# Shrink the CONNECT work area (Sarea) to the minimum allowed size so the +# unbounded write in CheckCond() reaches past the actual malloc'd buffer +# instead of merely wasting slack inside the (much larger) default 64MB area. +SET SESSION connect_work_size = 4194304; # 4MB, SZWMIN in ha_connect.cc +SET SESSION connect_xtrace = 'QUERY'; + +# CONNECT external table (type=MYSQL) wrapping the local/self table. +# connect_cond_push is ON by default, so a SELECT with WHERE will invoke +# ha_connect::cond_push() -> CheckCond(). CONNECTION can simply point back +# at this same instance, no real remote server is needed. +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval CREATE TABLE t2 ( id INT, val varchar(500) +) ENGINE=CONNECT table_type=MYSQL + CONNECTION='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; + +# WHERE val = '<4.3MB string>' forces CheckCond() to append the +# entire constant (byte-escaped) into filp->Body, which now lives inside the +# 4MB Sarea, overflowing it. +--disable_ps_protocol +SELECT COUNT(*) FROM t2 WHERE val = REPEAT('A', 4300000); +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN=Query=SELECT `val` FROM `t1` +--source include/search_pattern_in_file.inc + +# WHERE val = '<4.3MB string> AND id = 1 should pass WHERE id = 1 in the filter +# and skip the long string. +SELECT COUNT(*) FROM t2 WHERE val = REPEAT('A', 4300000) AND id = 1; +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN=Query=SELECT `id`, `val` FROM `t1` WHERE \(`id`= 1\) +--source include/search_pattern_in_file.inc + +SELECT COUNT(*) FROM t2 WHERE id = 1 AND val = REPEAT('A', 4300000); +--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN=Query=SELECT `id`, `val` FROM `t1` WHERE \(`id`= 1\) +--source include/search_pattern_in_file.inc +--enable_ps_protocol + +DROP TABLE t2, t1; + +--echo # End of 10.11 tests diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp index 9b6323e62bd..7a1ad0c90fc 100644 --- a/storage/connect/plugutil.cpp +++ b/storage/connect/plugutil.cpp @@ -600,6 +600,16 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) return (memp); } /* end of PlugSubAlloc */ +/***********************************************************************/ +/* Return the number of bytes still free (unreserved) in a pool. */ +/***********************************************************************/ +size_t PlugSubAllocLeft(PGLOBAL g, void *memp) +{ + PPOOLHEADER pph = (PPOOLHEADER)((memp) ? memp : g->Sarea); + + return pph->FreeBlk; +} /* end of PlugSubAllocLeft */ + /***********************************************************************/ /* Program for sub-allocating and copying a string in a storage area. */ /***********************************************************************/ diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index f0b3358ae44..aa27953748f 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -48,6 +48,8 @@ CONDFIL::CONDFIL(uint idx, AMT type) Hv = false; Body = NULL, Having = NULL; + Blen = 0; + Hlen = 0; } // end of CONDFIL constructor /***********************************************************************/ diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h index 01af43c5a4d..63f9260e367 100644 --- a/storage/connect/tabext.h +++ b/storage/connect/tabext.h @@ -46,6 +46,8 @@ class CONDFIL : public BLOCK { bool Hv; char *Body; char *Having; + size_t Blen; // Usable size of the Body buffer + size_t Hlen; // Usable size of the Having buffer }; // end of class CONDFIL /***********************************************************************/ diff --git a/storage/duckdb/cmake/duckdb.cmake b/storage/duckdb/cmake/duckdb.cmake index 3987960b4a2..22c4ba7579d 100644 --- a/storage/duckdb/cmake/duckdb.cmake +++ b/storage/duckdb/cmake/duckdb.cmake @@ -104,7 +104,10 @@ ExternalProject_Add(duckdb_build -DBUILD_TPCE=OFF -DEXTENSION_STATIC_BUILD=1 "-DDUCKDB_EXTENSION_CONFIGS=${CMAKE_CURRENT_SOURCE_DIR}/cmake/duckdb_extensions.cmake" - "-DCMAKE_CXX_FLAGS=${_DUCKDB_EXTRA_CXX_FLAGS}" + "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} ${_DUCKDB_EXTRA_CXX_FLAGS}" + "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}" + "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}" + "-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}" -DENABLE_SANITIZER=${ADDRESS_SANITIZER} -DENABLE_UBSAN=${UB_SANITIZER} -DOVERRIDE_GIT_DESCRIBE=${_DUCKDB_GIT_DESCRIBE} diff --git a/storage/duckdb/ha_duckdb.cc b/storage/duckdb/ha_duckdb.cc index 96442413cb0..4242378ecc0 100644 --- a/storage/duckdb/ha_duckdb.cc +++ b/storage/duckdb/ha_duckdb.cc @@ -1165,6 +1165,15 @@ int ha_duckdb::external_lock(THD *thd, int lock_type) DBUG_ENTER("ha_duckdb::external_lock"); if (lock_type != F_UNLCK) { + /* DuckDB has no row locks: reject SELECT ... FOR UPDATE / LOCK IN SHARE MODE. */ + if (thd_sql_command(thd) == SQLCOM_SELECT && + (table->reginfo.lock_type == TL_READ_WITH_SHARED_LOCKS || + table->reginfo.lock_type >= TL_FIRST_WRITE)) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "locking SELECT"); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + /* DuckDB does not support XA transactions. Reject DML early. */ if (myduck::reject_xa_if_active(thd)) DBUG_RETURN(HA_ERR_WRONG_COMMAND); diff --git a/storage/duckdb/mysql-test/duckdb/r/duckdb_sql_syntax.result b/storage/duckdb/mysql-test/duckdb/r/duckdb_sql_syntax.result index a46a1766f74..3bda1811423 100644 --- a/storage/duckdb/mysql-test/duckdb/r/duckdb_sql_syntax.result +++ b/storage/duckdb/mysql-test/duckdb/r/duckdb_sql_syntax.result @@ -1,6 +1,7 @@ CREATE TABLE t1 (id INT PRIMARY KEY, col1 INT, col2 INT); SELECT id, col1, col2 FROM t1 GROUP BY id, col1, col2 WITH ROLLUP; id col1 col2 +NULL NULL NULL ALTER TABLE t1 ENGINE=DuckDB; SELECT id, col1, col2 FROM t1 GROUP BY id, col1, col2 WITH ROLLUP; id col1 col2 diff --git a/storage/duckdb/mysql-test/duckdb/r/select_for_update.result b/storage/duckdb/mysql-test/duckdb/r/select_for_update.result new file mode 100644 index 00000000000..dc41c28fb88 --- /dev/null +++ b/storage/duckdb/mysql-test/duckdb/r/select_for_update.result @@ -0,0 +1,7 @@ +CREATE TABLE t (id INT PRIMARY KEY, v INT) ENGINE=DuckDB; +INSERT INTO t VALUES (1, 1),(2, 2); +SELECT v FROM t WHERE id=1 FOR UPDATE; +ERROR 42000: This version of MariaDB doesn't yet support 'locking SELECT' +SELECT v FROM t WHERE id=1 LOCK IN SHARE MODE; +ERROR 42000: This version of MariaDB doesn't yet support 'locking SELECT' +DROP TABLE t; diff --git a/storage/duckdb/mysql-test/duckdb/t/alter_default_debug.test b/storage/duckdb/mysql-test/duckdb/t/alter_default_debug.test index 7ebcc4d25ed..a1a5cec984c 100644 --- a/storage/duckdb/mysql-test/duckdb/t/alter_default_debug.test +++ b/storage/duckdb/mysql-test/duckdb/t/alter_default_debug.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE t(id INT PRIMARY KEY, a INT, b INT, c INT) ENGINE = DuckDB; INSERT INTO t VALUES(1, 1, 1, 1); diff --git a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column.test b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column.test index 2e5076e8b19..0ae239d698c 100644 --- a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column.test +++ b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo #################### --echo # TEST FOR INSTANT # --echo #################### diff --git a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column_copy.test b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column_copy.test index dd862e488dc..2a88f36f9c8 100644 --- a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column_copy.test +++ b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_column_copy.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo ################# --echo # TEST FOR COPY # --echo ################# diff --git a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_index.test b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_index.test index 5d08f86baa4..8df5bdd951b 100644 --- a/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_index.test +++ b/storage/duckdb/mysql-test/duckdb/t/alter_duckdb_index.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo #################### --echo # TEST FOR INSTANT # --echo #################### diff --git a/storage/duckdb/mysql-test/duckdb/t/alter_engine_duckdb.test b/storage/duckdb/mysql-test/duckdb/t/alter_engine_duckdb.test index 6240c455bf7..7d047686055 100644 --- a/storage/duckdb/mysql-test/duckdb/t/alter_engine_duckdb.test +++ b/storage/duckdb/mysql-test/duckdb/t/alter_engine_duckdb.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc SET GLOBAL duckdb_copy_ddl_in_batch=ON; --source ../include/alter_engine_duckdb.inc diff --git a/storage/duckdb/mysql-test/duckdb/t/batch_disconnect.test b/storage/duckdb/mysql-test/duckdb/t/batch_disconnect.test index 0ef4f782ea7..6a4de6d2282 100644 --- a/storage/duckdb/mysql-test/duckdb/t/batch_disconnect.test +++ b/storage/duckdb/mysql-test/duckdb/t/batch_disconnect.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log SET @saved_duckdb_dml_in_batch = @@GLOBAL.duckdb_dml_in_batch; diff --git a/storage/duckdb/mysql-test/duckdb/t/batch_rollback.test b/storage/duckdb/mysql-test/duckdb/t/batch_rollback.test index 94bf421487c..60bc3e591d6 100644 --- a/storage/duckdb/mysql-test/duckdb/t/batch_rollback.test +++ b/storage/duckdb/mysql-test/duckdb/t/batch_rollback.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log SET @saved_duckdb_dml_in_batch = @@GLOBAL.duckdb_dml_in_batch; diff --git a/storage/duckdb/mysql-test/duckdb/t/bugfix_crash_after_commit_error.test b/storage/duckdb/mysql-test/duckdb/t/bugfix_crash_after_commit_error.test index da058f62026..bc6757d2401 100644 --- a/storage/duckdb/mysql-test/duckdb/t/bugfix_crash_after_commit_error.test +++ b/storage/duckdb/mysql-test/duckdb/t/bugfix_crash_after_commit_error.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --skip TODO create table t1(id int primary key) engine = duckdb; diff --git a/storage/duckdb/mysql-test/duckdb/t/bugfix_temp_and_system_database.test b/storage/duckdb/mysql-test/duckdb/t/bugfix_temp_and_system_database.test index 420fd8c26aa..e802f5c4c35 100644 --- a/storage/duckdb/mysql-test/duckdb/t/bugfix_temp_and_system_database.test +++ b/storage/duckdb/mysql-test/duckdb/t/bugfix_temp_and_system_database.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # DuckDB has default databases named 'temp' and 'system', if we try to create # schema named 'temp' or 'system', we get an error. diff --git a/storage/duckdb/mysql-test/duckdb/t/charset_and_collation.test b/storage/duckdb/mysql-test/duckdb/t/charset_and_collation.test index 54ea1077c1d..38ee163154c 100644 --- a/storage/duckdb/mysql-test/duckdb/t/charset_and_collation.test +++ b/storage/duckdb/mysql-test/duckdb/t/charset_and_collation.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # --echo # check collation config when execute --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/create_table_column.test b/storage/duckdb/mysql-test/duckdb/t/create_table_column.test index fadf29f6c0d..4d56714c484 100644 --- a/storage/duckdb/mysql-test/duckdb/t/create_table_column.test +++ b/storage/duckdb/mysql-test/duckdb/t/create_table_column.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc # file: duckdb_create_table.test # # Test case for creating tables with various MySQL field types in DuckDB. diff --git a/storage/duckdb/mysql-test/duckdb/t/create_table_column_timestamp.test b/storage/duckdb/mysql-test/duckdb/t/create_table_column_timestamp.test index ffdc20b657d..1b9ecfc4bcd 100644 --- a/storage/duckdb/mysql-test/duckdb/t/create_table_column_timestamp.test +++ b/storage/duckdb/mysql-test/duckdb/t/create_table_column_timestamp.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --source include/have_debug.inc --disable_query_log diff --git a/storage/duckdb/mysql-test/duckdb/t/create_table_constraint.test b/storage/duckdb/mysql-test/duckdb/t/create_table_constraint.test index 3875082690b..cccf1e06d35 100644 --- a/storage/duckdb/mysql-test/duckdb/t/create_table_constraint.test +++ b/storage/duckdb/mysql-test/duckdb/t/create_table_constraint.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --source include/have_debug.inc diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_join.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_join.test index 0806df98e96..facf513363f 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_join.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_join.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # Cross-engine join: DuckDB + InnoDB via _mdb_scan replacement scan --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow.test index 5ba8e936e3e..c0ef2086739 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --source include/have_sequence.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_dup.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_dup.test index d572787dfa0..b19b13d33d1 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_dup.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_dup.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # --echo # Cross-engine RYOW: the same external table referenced more than once. diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_limit.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_limit.test index 84cc677bd9c..c7daf2b5e3c 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_limit.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_ryow_limit.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --source include/have_sequence.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_union.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_union.test index 0ae97958ccd..d303b974cb0 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_union.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_union.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # Cross-engine UNION: DuckDB + InnoDB via select_handler unit pushdown --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/cross_engine_where.test b/storage/duckdb/mysql-test/duckdb/t/cross_engine_where.test index 51102d6b29f..4736fb64a97 100644 --- a/storage/duckdb/mysql-test/duckdb/t/cross_engine_where.test +++ b/storage/duckdb/mysql-test/duckdb/t/cross_engine_where.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --source include/have_sequence.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/decimal_high_precision.test b/storage/duckdb/mysql-test/duckdb/t/decimal_high_precision.test index 3570bf4a2db..ec7bb24c7bd 100644 --- a/storage/duckdb/mysql-test/duckdb/t/decimal_high_precision.test +++ b/storage/duckdb/mysql-test/duckdb/t/decimal_high_precision.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/decimal_precision_all_possibilities.test b/storage/duckdb/mysql-test/duckdb/t/decimal_precision_all_possibilities.test index 1ec9348e5d0..2ea44599475 100644 --- a/storage/duckdb/mysql-test/duckdb/t/decimal_precision_all_possibilities.test +++ b/storage/duckdb/mysql-test/duckdb/t/decimal_precision_all_possibilities.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc set global duckdb_dml_in_batch = OFF; --source ../include/decimal_precision_all_possibilities.inc diff --git a/storage/duckdb/mysql-test/duckdb/t/dml_delete.test b/storage/duckdb/mysql-test/duckdb/t/dml_delete.test index d822cb86b29..0c49ad96e63 100644 --- a/storage/duckdb/mysql-test/duckdb/t/dml_delete.test +++ b/storage/duckdb/mysql-test/duckdb/t/dml_delete.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # DuckDB DELETE operations test --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/dml_update.test b/storage/duckdb/mysql-test/duckdb/t/dml_update.test index 681c86315a9..360dcfc1436 100644 --- a/storage/duckdb/mysql-test/duckdb/t/dml_update.test +++ b/storage/duckdb/mysql-test/duckdb/t/dml_update.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # DuckDB UPDATE operations test --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/drop_database.test b/storage/duckdb/mysql-test/duckdb/t/drop_database.test index 9f3ed4955b0..75877300a67 100644 --- a/storage/duckdb/mysql-test/duckdb/t/drop_database.test +++ b/storage/duckdb/mysql-test/duckdb/t/drop_database.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # DuckDB DROP DATABASE operations test --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_add_backticks.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_add_backticks.test index a38ef13a7a9..e354231ed18 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_add_backticks.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_add_backticks.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc SET GLOBAL duckdb_require_primary_key=OFF; --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_agg_func.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_agg_func.test index 8a97c539156..bc50c1bf8cd 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_agg_func.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_agg_func.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE t_innodb ( id INT PRIMARY KEY, diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_allow_encryption.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_allow_encryption.test index f0144c977ee..8f7ba7574ed 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_allow_encryption.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_allow_encryption.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --disable_warnings DROP DATABASE IF EXISTS encryption_test; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_alter_table_engine.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_alter_table_engine.test index 52a5cdb78d6..80ef3297927 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_alter_table_engine.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_alter_table_engine.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # --echo # Test DDL: alter table engine = innodb from duckdb tables diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_appender_allocator_flush_threshold.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_appender_allocator_flush_threshold.test index d3d8a8a2b77..3a154d82679 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_appender_allocator_flush_threshold.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_appender_allocator_flush_threshold.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc SHOW GLOBAL VARIABLES LIKE "duckdb_appender_allocator_flush_threshold"; SELECT run_in_duckdb("FROM duckdb_settings() WHERE name = 'allocator_flush_threshold'"); diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_auto_increment.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_auto_increment.test index 4648aa05efa..b0614b1992e 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_auto_increment.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_auto_increment.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log CREATE DATABASE IF NOT EXISTS db_autoinc CHARACTER SET utf8mb4; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_bit_string.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_bit_string.test index f7c8543a54d..22e82e4c3e5 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_bit_string.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_bit_string.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE t1 (id INT PRIMARY KEY, col1 VARCHAR(100)) ENGINE=DuckDB; CREATE TABLE t2 (id INT PRIMARY KEY, col1 BLOB) ENGINE=DuckDB; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_collate.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_collate.test index 1d29484ce32..c575cbc9201 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_collate.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_collate.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --disable_query_log --disable_warnings DROP TABLE IF EXISTS t1; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_cte.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_cte.test index c714205c845..b0210d0b558 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_cte.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_cte.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc CREATE DATABASE IF NOT EXISTS duckdb_cte; USE duckdb_cte; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_db_table_strconvert.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_db_table_strconvert.test index 884e10f721f..0d50b5a1c9b 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_db_table_strconvert.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_db_table_strconvert.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc # Test for escape characters in the table name or database name. --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_ddl_during_transaction.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_ddl_during_transaction.test index 1d192f2e214..b0146bf54cb 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_ddl_during_transaction.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_ddl_during_transaction.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo ########################################################################### --echo # Prepare diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_default_expr.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_default_expr.test index c5a8ae25ec3..15cc00024f8 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_default_expr.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_default_expr.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log CREATE DATABASE IF NOT EXISTS db_default_expr CHARACTER SET utf8mb4; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_default_value_injection.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_default_value_injection.test index 170e8b809c6..8713fecb3f5 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_default_value_injection.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_default_value_injection.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # --echo # MDEV-40610: an unescaped column DEFAULT string must not inject DuckDB SQL diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_fix_sql.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_fix_sql.test index 38acb142797..a005b802703 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_fix_sql.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_fix_sql.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE fake_innodb_table (id INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO fake_innodb_table VALUES (0); diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_json.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_json.test index 7bd522a04f7..f607d971e4f 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_json.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_json.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE t1_innodb (id INT PRIMARY KEY, col1 JSON) ENGINE=InnoDB; CREATE TABLE t1_duckdb (id INT PRIMARY KEY, col1 JSON) ENGINE=DuckDB; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_kill.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_kill.test index a9344b6be5b..2915977740b 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_kill.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_kill.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --source include/have_debug.inc --source include/have_debug_sync.inc diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_monitor.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_monitor.test index f8fad1d37b1..4e9627f958a 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_monitor.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_monitor.test @@ -1,7 +1,6 @@ --source ../include/have_duckdb.inc # MDEV-40449: MSan reports use-of-uninitialized-value in # duckdb::JemallocExtension::ThreadFlush (false positive from uninstrumented jemalloc). ---source include/not_msan.inc # # DuckDB monitoring status variables test. diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_numeric_func.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_numeric_func.test index 3d0fdaf1ac8..5f992cb23b5 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_numeric_func.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_numeric_func.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # 1. CONV(), CRC32(), MOD, DIV, TRUNCATE() is not support yet. # 2. The RAND() function in duckdb and mysql uses different random number generation algorithms, so it cannot support the seed argument. diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_refuse_xa.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_refuse_xa.test index 4489a54fd33..0e34bd12c61 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_refuse_xa.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_refuse_xa.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(5)) ENGINE=duckdb; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_require_primary_key.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_require_primary_key.test index f972509960a..cc8ffb15acb 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_require_primary_key.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_require_primary_key.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_set_operation.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_set_operation.test index 04db6e8cc53..e245e7c9575 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_set_operation.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_set_operation.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc CREATE TABLE t1 (id INT PRIMARY KEY, col1 INT) ENGINE=DuckDB; INSERT INTO t1 VALUES (1, 1), (2, 1), (3, 2), (4, 2); CREATE TABLE t2 (id INT PRIMARY KEY, col1 INT) ENGINE=DuckDB; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_mode.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_mode.test index 772254a650e..baeca66b9db 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_mode.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_mode.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo --echo 1. ONLY_FULL_GROUP_BY diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_syntax.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_syntax.test index aee922d26f1..c9db95ddd25 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_syntax.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_sql_syntax.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc # WITH ROLLUP CREATE TABLE t1 (id INT PRIMARY KEY, col1 INT, col2 INT); SELECT id, col1, col2 FROM t1 GROUP BY id, col1, col2 WITH ROLLUP; diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_string_func.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_string_func.test index 59489ef568b..a14478edc65 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_string_func.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_string_func.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # 1. In Duckdb, some string function does not support blob fields as input # 2. Regex-related functions are basically incompatible, and regex functions will be processed uniformly in the future. diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func.test index 8a57fd81aa5..bc437121db8 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # Compared with MySQL, duckdb's date functions generally have the following incompatibilities: # 1. Conversion between integer type and date/timestamp/time type diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func_unsupported.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func_unsupported.test index 61b390edfd7..0c21437ed4d 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func_unsupported.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_time_func_unsupported.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # Unsupported / incompatible date-time functions for DuckDB pushdown. # This is the companion of duckdb_time_func.test which keeps only the diff --git a/storage/duckdb/mysql-test/duckdb/t/duckdb_uuid.test b/storage/duckdb/mysql-test/duckdb/t/duckdb_uuid.test index c65fca8b8a5..161d588487f 100644 --- a/storage/duckdb/mysql-test/duckdb/t/duckdb_uuid.test +++ b/storage/duckdb/mysql-test/duckdb/t/duckdb_uuid.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --source include/have_sequence.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/feature_duckdb_data_type.test b/storage/duckdb/mysql-test/duckdb/t/feature_duckdb_data_type.test index 06f0163991b..e21b2cb311e 100644 --- a/storage/duckdb/mysql-test/duckdb/t/feature_duckdb_data_type.test +++ b/storage/duckdb/mysql-test/duckdb/t/feature_duckdb_data_type.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # Feature ORC data type test # Prepare diff --git a/storage/duckdb/mysql-test/duckdb/t/ha_duckdb.test b/storage/duckdb/mysql-test/duckdb/t/ha_duckdb.test index 14c5ce546ec..ffdfff0e07e 100644 --- a/storage/duckdb/mysql-test/duckdb/t/ha_duckdb.test +++ b/storage/duckdb/mysql-test/duckdb/t/ha_duckdb.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # Basic DuckDB handler test: DDL and DML operations --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/mdev_40379.test b/storage/duckdb/mysql-test/duckdb/t/mdev_40379.test index 82a48ceac59..0c21a7d0c60 100644 --- a/storage/duckdb/mysql-test/duckdb/t/mdev_40379.test +++ b/storage/duckdb/mysql-test/duckdb/t/mdev_40379.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc # # MDEV-40379: Assertion failure in CreateTableConvertor::translate # upon CREATE TEMPORARY TABLE with ENGINE=DuckDB diff --git a/storage/duckdb/mysql-test/duckdb/t/mdev_40651.test b/storage/duckdb/mysql-test/duckdb/t/mdev_40651.test index 08624224661..5be863f0401 100644 --- a/storage/duckdb/mysql-test/duckdb/t/mdev_40651.test +++ b/storage/duckdb/mysql-test/duckdb/t/mdev_40651.test @@ -1,6 +1,5 @@ --source ../include/have_duckdb.inc --source include/have_partition.inc ---source include/not_msan.inc # MDEV-40651: keep DuckDB DDL atomic and preserve implicit defaults. CREATE TABLE t (c1 INT KEY) ENGINE=DuckDB; diff --git a/storage/duckdb/mysql-test/duckdb/t/mdev_40957.test b/storage/duckdb/mysql-test/duckdb/t/mdev_40957.test index 1909a4c3c5f..0eb1da4bfa7 100644 --- a/storage/duckdb/mysql-test/duckdb/t/mdev_40957.test +++ b/storage/duckdb/mysql-test/duckdb/t/mdev_40957.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log --disable_warnings diff --git a/storage/duckdb/mysql-test/duckdb/t/mixed_dml.test b/storage/duckdb/mysql-test/duckdb/t/mixed_dml.test index b555c1ff9e4..d25a7879178 100644 --- a/storage/duckdb/mysql-test/duckdb/t/mixed_dml.test +++ b/storage/duckdb/mysql-test/duckdb/t/mixed_dml.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_query_log --disable_warnings diff --git a/storage/duckdb/mysql-test/duckdb/t/pushdown_rewrite.test b/storage/duckdb/mysql-test/duckdb/t/pushdown_rewrite.test index d01a7e29a9e..bfc8cbf4750 100644 --- a/storage/duckdb/mysql-test/duckdb/t/pushdown_rewrite.test +++ b/storage/duckdb/mysql-test/duckdb/t/pushdown_rewrite.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --disable_warnings DROP DATABASE IF EXISTS pushdown_rewrite; diff --git a/storage/duckdb/mysql-test/duckdb/t/rename_duckdb_table.test b/storage/duckdb/mysql-test/duckdb/t/rename_duckdb_table.test index 2511b3b41c1..6ea744b0fd0 100644 --- a/storage/duckdb/mysql-test/duckdb/t/rename_duckdb_table.test +++ b/storage/duckdb/mysql-test/duckdb/t/rename_duckdb_table.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --echo # --echo # 1) Prepare diff --git a/storage/duckdb/mysql-test/duckdb/t/run_in_duckdb_access.test b/storage/duckdb/mysql-test/duckdb/t/run_in_duckdb_access.test index 1e7afdabdfa..268b9858205 100644 --- a/storage/duckdb/mysql-test/duckdb/t/run_in_duckdb_access.test +++ b/storage/duckdb/mysql-test/duckdb/t/run_in_duckdb_access.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc SET @saved_allow_run_in_duckdb = @@GLOBAL.duckdb_allow_run_in_duckdb; # The suite enables duckdb_allow_run_in_duckdb globally (suite.opt), and MTR may diff --git a/storage/duckdb/mysql-test/duckdb/t/select_for_update.test b/storage/duckdb/mysql-test/duckdb/t/select_for_update.test new file mode 100644 index 00000000000..7d845e40e14 --- /dev/null +++ b/storage/duckdb/mysql-test/duckdb/t/select_for_update.test @@ -0,0 +1,11 @@ +--source ../include/have_duckdb.inc + +CREATE TABLE t (id INT PRIMARY KEY, v INT) ENGINE=DuckDB; +INSERT INTO t VALUES (1, 1),(2, 2); + +--error ER_NOT_SUPPORTED_YET +SELECT v FROM t WHERE id=1 FOR UPDATE; + +--error ER_NOT_SUPPORTED_YET +SELECT v FROM t WHERE id=1 LOCK IN SHARE MODE; +DROP TABLE t; diff --git a/storage/duckdb/mysql-test/duckdb/t/space_reclaim.test b/storage/duckdb/mysql-test/duckdb/t/space_reclaim.test index 2748253d487..f23b82603fd 100644 --- a/storage/duckdb/mysql-test/duckdb/t/space_reclaim.test +++ b/storage/duckdb/mysql-test/duckdb/t/space_reclaim.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc --source include/have_sequence.inc --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/streaming_select.test b/storage/duckdb/mysql-test/duckdb/t/streaming_select.test index 4999fa997d5..bf4e0d8fffc 100644 --- a/storage/duckdb/mysql-test/duckdb/t/streaming_select.test +++ b/storage/duckdb/mysql-test/duckdb/t/streaming_select.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --source include/have_sequence.inc --disable_warnings diff --git a/storage/duckdb/mysql-test/duckdb/t/supported_copy_ddl.test b/storage/duckdb/mysql-test/duckdb/t/supported_copy_ddl.test index ad37d55159b..97069c1b09f 100644 --- a/storage/duckdb/mysql-test/duckdb/t/supported_copy_ddl.test +++ b/storage/duckdb/mysql-test/duckdb/t/supported_copy_ddl.test @@ -1,5 +1,4 @@ --source ../include/have_duckdb.inc ---source include/not_msan.inc # Test for DDL which are supported by DuckDB using COPY algorithm --echo # --echo # RENAME TABLE WITH DIFFERENT DATABASES diff --git a/storage/duckdb/mysql-test/duckdb/t/system_timezone.test b/storage/duckdb/mysql-test/duckdb/t/system_timezone.test index 1d034ce0d6e..59aa9d106a5 100644 --- a/storage/duckdb/mysql-test/duckdb/t/system_timezone.test +++ b/storage/duckdb/mysql-test/duckdb/t/system_timezone.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --source ../include/have_mysqld_safe.inc # 1) Set valiables to be used in parameters of mysqld_safe. diff --git a/storage/duckdb/mysql-test/duckdb/t/transaction.test b/storage/duckdb/mysql-test/duckdb/t/transaction.test index 84688d7a379..7f080ce7456 100644 --- a/storage/duckdb/mysql-test/duckdb/t/transaction.test +++ b/storage/duckdb/mysql-test/duckdb/t/transaction.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # DuckDB transaction tests --echo # diff --git a/storage/duckdb/mysql-test/duckdb/t/truncate_and_maintenance_duckdb_table.test b/storage/duckdb/mysql-test/duckdb/t/truncate_and_maintenance_duckdb_table.test index d3f9ee37e4d..3c2108ff356 100644 --- a/storage/duckdb/mysql-test/duckdb/t/truncate_and_maintenance_duckdb_table.test +++ b/storage/duckdb/mysql-test/duckdb/t/truncate_and_maintenance_duckdb_table.test @@ -1,4 +1,3 @@ ---source include/not_msan.inc --echo # --echo # 1) PREPARE --echo # diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index cbdad7bf91d..befe801252e 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -862,7 +862,7 @@ public: { m_num_fds= 0; - if (my_use_large_pages) + if (my_large_pages_flag) return false; static_assert(array_elements(m_fds) == (array_elements(m_triggers) + 1), @@ -1085,8 +1085,12 @@ inline void buf_pool_t::garbage_collect() noexcept do { - if (shrink(size)) - { + switch (shrink(size)) { + case SHRINK_IN_PROGRESS: + continue; + case SHRINK_ABORT: + goto aborted; + case SHRINK_DONE: const size_t old_blocks{n_blocks}; n_blocks= n_blocks_new; @@ -1113,6 +1117,7 @@ inline void buf_pool_t::garbage_collect() noexcept } while (time(nullptr) - start < 15); + aborted: ut_ad(size_in_bytes > size_in_bytes_requested); n_blocks_to_withdraw= 0; first_to_withdraw= nullptr; @@ -1129,7 +1134,7 @@ inline void buf_pool_t::garbage_collect() noexcept mysql_mutex_unlock(&mutex); sql_print_information("InnoDB: Memory pressure event failed to shrink" - " innodb_buffer_pool_size=%zum", old_size); + " innodb_buffer_pool_size=%zum", old_size >> 20); ut_d(validate()); } #endif @@ -1377,7 +1382,7 @@ bool buf_pool_t::create() noexcept retry: { NUMA_MEMPOLICY_INTERLEAVE_IN_SCOPE; - memory_unaligned= my_virtual_mem_reserve(&size); + memory_unaligned= my_virtual_mem_reserve(&size, my_large_pages_flag); if (memory_unaligned); #if defined __aarch64__ || defined __riscv || defined __mips__ || defined __loongarch64 else if (size_in_bytes_max_default != 0 && @@ -1436,7 +1441,7 @@ bool buf_pool_t::create() noexcept PSI_MEMORY_CALL(memory_alloc)(mem_key_buf_buf_pool, actual_size, &owner); #endif #ifndef _AIX - if (!my_virtual_mem_commit(memory, actual_size)) + if (!my_virtual_mem_commit(memory, actual_size, my_large_pages_flag)) { my_virtual_mem_release(memory_unaligned, size_unaligned); memory= nullptr; @@ -1625,7 +1630,7 @@ void buf_pool_t::close() noexcept owner= nullptr; #endif os_total_large_mem_allocated-= size; - my_virtual_mem_decommit(memory, size); + my_virtual_mem_decommit(memory, size, my_large_pages_flag); my_virtual_mem_release(memory_unaligned, size_unaligned); memory= nullptr; memory_unaligned= nullptr; @@ -2044,7 +2049,7 @@ inline void buf_pool_t::shrunk(size_t size, size_t reduced) noexcept guess before we invoke my_virtual_mem_decommit() below. */ latch.unlock(); } - my_virtual_mem_decommit(memory + size, reduced); + my_virtual_mem_decommit(memory + size, reduced, my_large_pages_flag); #ifdef UNIV_PFS_MEMORY PSI_MEMORY_CALL(memory_free)(mem_key_buf_buf_pool, reduced, owner); #endif @@ -2055,7 +2060,7 @@ ATTRIBUTE_COLD void buf_pool_t::resize(size_t size, THD *thd) noexcept ut_ad(this == &buf_pool); mysql_mutex_assert_owner(&LOCK_global_system_variables); ut_ad(size <= size_in_bytes_max); - if (my_use_large_pages) + if (my_large_pages_flag) { my_error(ER_VARIABLE_IS_READONLY, MYF(0), "InnoDB", "innodb_buffer_pool_size", "large_pages=0"); @@ -2102,7 +2107,8 @@ ATTRIBUTE_COLD void buf_pool_t::resize(size_t size, THD *thd) noexcept if (n_blocks_removed <= 0) { - if (!my_virtual_mem_commit(memory + old_size, size - old_size)) + if (!my_virtual_mem_commit(memory + old_size, size - old_size, + my_large_pages_flag)) { mysql_mutex_unlock(&mutex); sql_print_error("InnoDB: Cannot commit innodb_buffer_pool_size=%zum;" diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index d8976dec669..db75d556ae2 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -687,6 +687,9 @@ dict_sys_tables_rec_read( if (rec_get_deleted_flag(rec, 0)) { ut_ad(id); if (trx_id) { + if (heap) { + mem_heap_free(heap); + } return READ_NOT_FOUND; } } @@ -2176,7 +2179,8 @@ Do not load any columns or indexes. @param[in] rec SYS_TABLES record @param[out,own] table table, or nullptr @return error message -@retval nullptr on success */ +@retval nullptr on success, or if the record is not visible, in +which case *table will be nullptr */ const char *dict_load_table_low(mtr_t *mtr, bool uncommitted, const rec_t *rec, dict_table_t **table) { diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 405e5fb1c64..1838b703918 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2368,6 +2368,9 @@ void fil_crypt_set_thread_cnt(const uint new_cnt) } pthread_cond_broadcast(&fil_crypt_threads_cond); + /* Thread waiting on fil_crypt_iops_cond too. They must + be woken as well */ + pthread_cond_broadcast(&fil_crypt_iops_cond); while (srv_n_fil_crypt_threads_started != srv_n_fil_crypt_threads) { my_cond_wait(&fil_crypt_cond, diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 7797d007aa3..d5dfa4db1f7 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1907,6 +1907,11 @@ dberr_t fil_space_t::rename(const char *path, bool log, bool replace) noexcept if (!log) { + ut_ad(!replace); + ut_d(os_file_type_t type); + ut_d(bool exists); + ut_ad(os_file_status(path, &exists, &type)); + ut_ad(!exists); if (!os_file_rename(innodb_data_file_key, old_path, path)) return DB_ERROR; mysql_mutex_lock(&fil_system.mutex); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 1e4a1040f6e..4f8c91f2788 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1963,6 +1963,10 @@ fts_create_one_index_table( dict_table_add_system_columns(new_table, heap); error = row_create_table_for_mysql(new_table, trx); + DBUG_EXECUTE_IF("fts_index_table_fail", + trx->rollback(); + error = DB_FAIL;); + if (error == DB_SUCCESS) { dict_index_t* index = dict_mem_index_create( new_table, "FTS_INDEX_TABLE_IND", diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 0faf23aa6e9..22b6530b449 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -2861,8 +2861,12 @@ fts_query_phrase_search( func_exit: mem_heap_free(heap); - /* Don't need it anymore. */ + /* Don't need it anymore. + Reset the phrase/proximity flag to avoid the subsequent + wildcard term in the same boolean query would take the + exact word lookup path in fts_query_cache() */ query->matched = NULL; + query->flags = 0; return(query->error); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4c7535a96b8..8e044e7ba98 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3738,7 +3738,7 @@ static int innodb_init_params() const size_t innodb_buffer_pool_size= buf_pool.size_in_bytes_requested; if (innodb_buffer_pool_size > buf_pool.size_in_bytes_max || - my_use_large_pages /* large_pages=ON fixes innodb_buffer_pool_size */) + my_large_pages_flag /* large_pages=ON fixes innodb_buffer_pool_size */) buf_pool.size_in_bytes_max= ut_calc_align(innodb_buffer_pool_size, innodb_buffer_pool_extent_size); @@ -6230,6 +6230,37 @@ ha_innobase::close() /* The following accessor functions should really be inside MySQL code! */ #ifdef WITH_WSREP +/** Pick the charset struct of a charset number, for the write set key +encoding. Since the MySQL function get_charset may be slow before Bar +removes the mutex operation there, we first look at 2 common charsets +directly. +@param charset_number number of the charset +@return the charset, never NULL */ +static +CHARSET_INFO* +wsrep_get_charset(uint charset_number) +{ + if (charset_number == default_charset_info->number) { + return default_charset_info; + } + + if (charset_number == my_charset_latin1.number) { + return &my_charset_latin1; + } + + CHARSET_INFO* 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); + ut_a(0); + } + + return charset; +} + size_t wsrep_normalize_string( int mysql_type, /* in: MySQL type */ @@ -6238,7 +6269,9 @@ wsrep_normalize_string( unsigned char* out_str, /* out: normalized string */ size_t str_length, /* in: data field length, not UNIV_SQL_NULL */ - size_t buf_length) /* in: total str buffer length */ + size_t buf_length, /* in: total str buffer length, + out_str holds one byte more */ + bool* truncated) /* out: weights did not fit */ { size_t ret_length= str_length; @@ -6257,28 +6290,7 @@ wsrep_normalize_string( case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_VARCHAR: { - CHARSET_INFO* charset; - - /* Use the charset number to pick the right charset struct for - the comparison. Since the MySQL function get_charset may be - slow before Bar removes the mutex operation there, we first - look at 2 common charsets directly. */ - - if (charset_number == default_charset_info->number) { - charset = default_charset_info; - } else if (charset_number == my_charset_latin1.number) { - charset = &my_charset_latin1; - } else { - 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); - ut_a(0); - } - } + CHARSET_INFO* charset = wsrep_get_charset(charset_number); if (wsrep_protocol_version < 3) { ret_length = charset->strnxfrm( @@ -6289,11 +6301,24 @@ wsrep_normalize_string( /* strnxfrm will expand the destination string, protocols < 3 truncated the normalized string protocols >= 3 gets full normalized string + + One byte over the limit is asked for, so that a + value whose weights do not fit can be told apart + from one that fills the room exactly. The key + keeps the first buf_length bytes either way. */ ret_length = charset->strnxfrm( - out_str, buf_length, + out_str, buf_length + 1, uint(str_length), str, str_length, 0) .m_result_length; + + if (ret_length > buf_length) { + ret_length = buf_length; + + if (truncated) { + *truncated = true; + } + } } break; @@ -6324,6 +6349,166 @@ wsrep_normalize_string( return ret_length; } + +/** Store the write set key value of a string column. + +Both write set key paths come here, so that one and the same column value +always produces one and the same key: wsrep_store_key_val_for_row() has the +value in the MySQL record format and wsrep_rec_get_foreign_key() has it as +InnoDB stored it, and a CHAR is not padded the same way in the two. + +From protocol version 5 on, the MySQL record pads a CHAR to +n_chars * mbmaxlen bytes, while InnoDB in a compact row format and a +variable length character set strips that padding down to but not below +n_chars bytes; as that compares a byte count against a character count, a +value holding multi byte characters is left with fewer than n_chars +characters. See row_mysql_store_col_in_innobase_format(). Both forms are +brought to exactly n_chars characters here, which also makes the key +independent of the row format. The normalization itself is always done with +WSREP_MAX_SUPPORTED_KEY_LENGTH as the buffer length, and only the copy into +out_str is limited by the space the caller has left, because strnxfrm +truncates to the length it is given and the key of a column must not depend +on how much room the columns before it happened to leave. + +Before protocol version 5 the two paths did neither of those and disagreed +for a CHAR in a variable length character set. That is kept here so that a +node still speaking the older protocol produces the same keys as before. +Note that the old paths did not agree on the strnxfrm buffer length either, +3072 on one and 3500 on the other; both get WSREP_MAX_SUPPORTED_KEY_LENGTH +here, which only makes a difference for a value whose normalized form is +longer than 3072 bytes, where the two never produced the same key anyway. + +@param mysql_type MySQL type of the column +@param charset_number number of the charset of the column +@param n_chars characters the column holds, 0 if it is not a CHAR +@param str column value +@param str_length length of str in bytes +@param out_str buffer for the key value +@param out_length space left in out_str +@param mysql_format str is in the MySQL record format, where a CHAR is + padded to more characters than the column holds; + before protocol 5 that was cut back here +@return number of bytes written to out_str */ +size_t +wsrep_store_string_key_val( + int mysql_type, + uint charset_number, + size_t n_chars, + const unsigned char* str, + size_t str_length, + unsigned char* out_str, + ulint out_length, + bool mysql_format, + bool* truncated) +{ + unsigned char normalized[WSREP_MAX_SUPPORTED_KEY_LENGTH + 2]; + size_t len; + + if (wsrep_protocol_version < 5) { + CHARSET_INFO* cs = wsrep_get_charset(charset_number); + + if (mysql_format && str_length > 0 && cs->mbmaxlen > 1) { + int error; + + str_length = my_well_formed_length( + cs, (const char*) str, + (const char*) str + str_length, + str_length / cs->mbmaxlen, &error); + } + + len = wsrep_normalize_string(mysql_type, charset_number, str, + normalized, str_length, + WSREP_MAX_SUPPORTED_KEY_LENGTH, + truncated); + } else { + unsigned char padded[REC_VERSION_56_MAX_INDEX_COL_LEN + 1]; + + if (n_chars) { + CHARSET_INFO* cs = wsrep_get_charset(charset_number); + int error; + + /* Cut to at most n_chars characters ... */ + str_length = my_well_formed_length( + cs, (const char*) str, + (const char*) str + str_length, n_chars, + &error); + + /* ... and pad back up to n_chars where InnoDB had + stripped the padding. mbminlen is 1 for every + character set whose CHAR padding InnoDB strips, so + the pad character is one 0x20. */ + const size_t chars = cs->numchars( + (const char*) str, + (const char*) str + str_length); + + if (chars < n_chars) { + const size_t pad = n_chars - chars; + + ut_ad(cs->mbminlen == 1); + ut_a(str_length + pad <= sizeof padded); + + memcpy(padded, str, str_length); + memset(padded + str_length, 0x20, pad); + str = padded; + str_length += pad; + } + } + + len = wsrep_normalize_string(mysql_type, charset_number, str, + normalized, str_length, + WSREP_MAX_SUPPORTED_KEY_LENGTH, + truncated); + } + + if (len > out_length) { + len = out_length; + + if (truncated) { + *truncated = true; + } + } + + memcpy(out_str, normalized, len); + + return len; +} + +/** Tell the client that a write set key was cut to the key buffer size. +@param thd session the key belongs to +@param table_name table the key was built for, either db.table or the + InnoDB internal db/table */ +void +wsrep_warn_key_truncated(THD* thd, const char* table_name) +{ + char name[NAME_LEN * 2 + 2]; + size_t len= strlen(table_name); + + if (len >= sizeof name) { + len= sizeof name - 1; + } + + memcpy(name, table_name, len); + name[len]= '\0'; + + /* The InnoDB internal name is db/table, the server says db.table. */ + if (char* slash= strchr(name, '/')) { + *slash= '.'; + } + + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_TOO_LONG_KEY, + "WSREP: Write set key for table '%s' was cut to " + "%d bytes. Rows whose key values are equal up to " + "that length produce the same key and conflict in " + "certification.", + name, WSREP_MAX_SUPPORTED_KEY_LENGTH); + + if (global_system_variables.log_warnings > 1) { + WSREP_WARN("Write set key for table '%s' was cut to %d bytes: %s", + name, WSREP_MAX_SUPPORTED_KEY_LENGTH, + wsrep_thd_query(thd)); + } +} #endif /* WITH_WSREP */ /******************************************************************//** @@ -6611,7 +6796,8 @@ wsrep_store_key_val_for_row( format) */ uint buff_len,/*!< in: buffer length */ const uchar* record, - bool* key_is_null)/*!< out: full key was null */ + bool* key_is_null,/*!< out: full key was null */ + bool* truncated) /*!< out: key did not fit buff */ { KEY* key_info = table->key_info + keynr; KEY_PART_INFO* key_part = key_info->key_part; @@ -6625,24 +6811,36 @@ wsrep_store_key_val_for_row( *key_is_null = true; for (; key_part != end; key_part++) { - uchar normalized[REC_VERSION_56_MAX_INDEX_COL_LEN+1]; + /* One byte over the limit passed to + wsrep_normalize_string(), which asks strnxfrm() for it to + tell a value that was cut from one that fits exactly. Sized + for the VARCHAR branch below, which normalizes up to + WSREP_MAX_SUPPORTED_KEY_LENGTH bytes to agree with + wsrep_rec_get_foreign_key()'s wsrep_store_string_key_val(); + the BLOB branch asks for less. */ + uchar normalized[WSREP_MAX_SUPPORTED_KEY_LENGTH+2]; bool part_is_null= false; if (key_part->null_bit) { - if (buff_space > 0) { - if (record[key_part->null_offset] - & key_part->null_bit) { - *buff = 1; - part_is_null = true; - } else { - *buff = 0; - } - buff++; - buff_space--; - } else { - fprintf (stderr, "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); + if (buff_space == 0) { + /* Not even the null flag byte fits. A column + after this one must not be stored either, the + same way wsrep_rec_get_foreign_key() stops at + the first column that does not fit at all. */ + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); + *truncated = true; + break; } + if (record[key_part->null_offset] + & key_part->null_bit) { + *buff = 1; + part_is_null = true; + } else { + *buff = 0; + } + buff++; + buff_space--; } if (!part_is_null) *key_is_null = false; @@ -6655,14 +6853,18 @@ wsrep_store_key_val_for_row( if (part_is_null) { size_t true_len= key_len + 2; - if (true_len > buff_space) { - fprintf (stderr, - "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); + bool cut = true_len > buff_space; + if (cut) { + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); true_len = buff_space; + *truncated = true; } buff += true_len; buff_space -= true_len; + if (cut) { + break; + } continue; } const CHARSET_INFO* cs = field->charset(); @@ -6701,13 +6903,18 @@ wsrep_store_key_val_for_row( true_len = sizeof(normalized) - 1; } - /* Normalize string if is not empty string */ + /* Normalize string if is not empty string. The limit + matches wsrep_store_string_key_val(), which + wsrep_rec_get_foreign_key() uses for this same MySQL + type, so the two keys agree past REC_VERSION_56_MAX_ + INDEX_COL_LEN and up to WSREP_MAX_SUPPORTED_KEY_LENGTH. */ 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); + WSREP_MAX_SUPPORTED_KEY_LENGTH, + truncated); } if (wsrep_protocol_version > 1) { @@ -6716,15 +6923,20 @@ wsrep_store_key_val_for_row( only len first bytes after the 2 length bytes contain actual data. The rest of the space was reset to zero in the bzero() call above. */ - if (true_len > buff_space) { - WSREP_DEBUG ( - "write set key truncated for: %s\n", - wsrep_thd_query(thd)); + bool cut = true_len > buff_space; + if (cut) { + WSREP_DEBUG("write set key truncated " + "for: %s", + wsrep_thd_query(thd)); true_len = buff_space; + *truncated = true; } memcpy(buff, normalized, true_len); buff += true_len; buff_space -= true_len; + if (cut) { + break; + } } else { buff += key_len; } @@ -6741,15 +6953,19 @@ wsrep_store_key_val_for_row( if (part_is_null) { size_t true_len= key_len + 2; - if (true_len > buff_space) { - fprintf (stderr, - "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); + bool cut = true_len > buff_space; + if (cut) { + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); true_len = buff_space; + *truncated = true; } buff += true_len; buff_space -= true_len; + if (cut) { + break; + } continue; } @@ -6796,21 +7012,26 @@ wsrep_store_key_val_for_row( true_len= wsrep_normalize_string( mysql_type, cs->number, blob_data, normalized, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); + REC_VERSION_56_MAX_INDEX_COL_LEN, + truncated); } /* Note that we always reserve the maximum possible length of the BLOB prefix in the key value. */ if (wsrep_protocol_version > 1) { - if (true_len > buff_space) { - fprintf (stderr, - "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); + bool cut = true_len > buff_space; + if (cut) { + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); true_len = buff_space; + *truncated = true; } memcpy(buff, normalized, true_len); buff += true_len; buff_space -= true_len; + if (cut) { + break; + } } else { buff += key_len; } @@ -6822,15 +7043,19 @@ wsrep_store_key_val_for_row( if (part_is_null) { size_t true_len= key_part->length; - if (true_len > buff_space) { - fprintf (stderr, - "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); + bool cut = true_len > buff_space; + if (cut) { + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); true_len = buff_space; + *truncated = true; } buff += true_len; buff_space -= true_len; + if (cut) { + break; + } continue; } @@ -6841,58 +7066,107 @@ wsrep_store_key_val_for_row( /* Character set for the field is defined only to fields whose type is string and real field type is not enum or set. For these fields check - if character set is multi byte. */ + if character set is multi byte. + + Fields that InnoDB stores as DATA_BINARY, + DATA_FIXBINARY or DATA_BLOB must not be collated + here: their bytes are opaque. Note that data types + implemented on top of Field_fbt (UUID, INET6, INET4) + report type() == MYSQL_TYPE_STRING and charset() == + my_charset_numeric (i.e. latin1), while their values + are plain binary and InnoDB maps them to + DATA_FIXBINARY. The binary test below mirrors + get_innobase_type_from_mysql_type(). + + Skipping the collation changes the key bytes on the + wire, so it is gated on protocol version 5. Below + that version the value is still collated, and + wsrep_rec_get_foreign_key() collates the matching + reference key the same way, so the two agree in a + cluster that has not fully upgraded yet. */ + bool cut = false; if (real_type != MYSQL_TYPE_ENUM && real_type != MYSQL_TYPE_SET + && (wsrep_protocol_version < 5 + || (!field->binary() + && field->key_type() + != HA_KEYTYPE_BINARY)) && ( mysql_type == MYSQL_TYPE_VAR_STRING || mysql_type == MYSQL_TYPE_STRING)) { const CHARSET_INFO* cs= field->charset(); - /* For multi byte character sets we need to - calculate the true length of the key */ - - if (true_len > 0 && cs->mbmaxlen > 1) { - int error; - - true_len= my_well_formed_length(cs, - (const char *)src_start, - (const char *)src_start - + true_len, - (true_len / cs->mbmaxlen), - &error); - } + /* Only a whole CHAR column is brought to the + number of characters it holds. A prefix key + part is not a column value and is never + matched against a foreign key. */ + const size_t n_chars= + (mysql_type == MYSQL_TYPE_STRING + && key_part->length + == field->pack_length()) + ? key_part->length / cs->mbmaxlen : 0; /* 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); + const bool was_truncated= *truncated; + true_len= wsrep_store_string_key_val( + mysql_type, cs->number, n_chars, + src_start, true_len, + (uchar*) buff, buff_space, true, + truncated); + cut = !was_truncated && *truncated; } else { ut_ad(src_start == nullptr); } - - if (true_len > buff_space) { - fprintf (stderr, - "WSREP: key truncated: %s\n", - wsrep_thd_query(thd)); - true_len = buff_space; - } - memcpy(buff, normalized, true_len); } else { - /* Copy only if there is data */ - if (true_len) { - ut_ad(src_start); - memcpy(buff, src_start, true_len); + unsigned unsigned_flag; + const uint8_t mtype + = get_innobase_type_from_mysql_type( + &unsigned_flag, field); + /* A whole number, float or double is read out + of the record as one unit elsewhere + (wsrep_rec_get_foreign_key()), so a cut + version of it is not a shorter version of the + same value, it is a different one. Leave it + out of the key entirely instead, the same way + that function does, rather than let the two + keys disagree past this point. */ + if ((mtype == DATA_INT + || mtype == DATA_FLOAT + || mtype == DATA_DOUBLE) + && true_len > buff_space) { + WSREP_DEBUG("key truncated: %s", + wsrep_thd_query(thd)); + *truncated = true; + true_len = 0; + cut = true; } else { - ut_ad(src_start == nullptr); + if (true_len > buff_space) { + WSREP_DEBUG( + "key truncated: %s", + wsrep_thd_query(thd)); + true_len = buff_space; + *truncated = true; + cut = true; + } + + /* 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; + if (cut) { + break; + } } } @@ -9953,7 +10227,11 @@ wsrep_append_foreign_key( return DB_ERROR; } - byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; + /* One byte for the index ordinal at key[0], the key itself, and one + spare byte: wsrep_rec_get_foreign_key() may normalize a column + straight into this buffer, and wsrep_normalize_string() asks + strnxfrm() for one byte over the limit to detect a cut value. */ + byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+2] = {'\0'}; ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH; dict_index_t *idx_target = (referenced) ? @@ -9974,9 +10252,31 @@ wsrep_append_foreign_key( ut_a(idx); key[0] = byte(i); + bool key_truncated = false; + rcode = wsrep_rec_get_foreign_key( &key[1], &len, rec, index, idx, - wsrep_protocol_version > 1); + wsrep_protocol_version > 1, &key_truncated); + + if (key_truncated) { + wsrep_warn_key_truncated( + thd, + (referenced + ? foreign->referenced_table->name.m_name + : foreign->foreign_table->name.m_name)); + + /* Under strict mode THD::raise_condition() turned the + warning into an error. Fail the row so that the error + reaches the client, the same way the row key path does. + + DB_ERROR is not an option here: row_mysql_handle_errors() + does not know it and ends in ib::fatal(). The error the + client sees is the one already in the diagnostics area, + the code below only rolls the statement back. */ + if (thd->is_error()) { + return DB_TOO_BIG_RECORD; + } + } if (rcode != DB_SUCCESS) { WSREP_ERROR( @@ -10180,6 +10480,8 @@ ha_innobase::wsrep_append_keys( DBUG_RETURN(0); } + bool key_truncated = false; + if (wsrep_protocol_version == 0) { char keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; char *key = &keyval[0]; @@ -10187,7 +10489,7 @@ ha_innobase::wsrep_append_keys( auto len = wsrep_store_key_val_for_row( thd, table, 0, key, WSREP_MAX_SUPPORTED_KEY_LENGTH, - record0, &is_null); + record0, &is_null, &key_truncated); if (!is_null) { rcode = wsrep_append_key( @@ -10246,14 +10548,15 @@ ha_innobase::wsrep_append_keys( auto len0 = wsrep_store_key_val_for_row( thd, table, i, key0, WSREP_MAX_SUPPORTED_KEY_LENGTH, - record0, &is_null0); + record0, &is_null0, &key_truncated); if (record1) { bool is_null1; auto len1= wsrep_store_key_val_for_row( thd, table, i, key1, WSREP_MAX_SUPPORTED_KEY_LENGTH, - record1, &is_null1); + record1, &is_null1, + &key_truncated); if (is_null0 != is_null1 || len0 != len1 || @@ -10301,6 +10604,21 @@ ha_innobase::wsrep_append_keys( } } + if (key_truncated) { + char qualified[NAME_LEN * 2 + 2]; + snprintf(qualified, sizeof qualified, "%s.%s", + table_share->db.str, table_share->table_name.str); + wsrep_warn_key_truncated(thd, qualified); + + /* Under strict mode THD::raise_condition() turned the + warning into an error. An INSERT clears the diagnostics area + again once the row is written, so tell the caller that the + row failed and let the error stand. */ + if (thd->is_error()) { + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } + } + /* if no PK, calculate hash of full row, to be the key value */ if (!key_appended && wsrep_certify_nonPK) { uchar digest[16]; @@ -10918,12 +11236,16 @@ create_index( & HA_REVERSE_SORT); } + /* On failure, row_create_index_for_mysql() may roll + back the dictionary transaction, which will remove + the table from the cache and free it. */ + const ulint table_flags = table->flags; DBUG_RETURN(convert_error_code_to_mysql( row_create_index_for_mysql( index, trx, NULL, fil_encryption_t(o.encryption), uint32_t(o.encryption_key_id)), - table->flags, NULL)); + table_flags, NULL)); } ulint ind_type = 0; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 44e5d8eabd2..93440501dd8 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1203,8 +1203,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx index->lock.free(); dict_mem_index_free(index); } - for (unsigned i = old_n_v_cols; i--; ) { - old_v_cols[i].~dict_v_col_t(); + for (unsigned i = instant_table->n_v_cols; i--; ) { + instant_table->v_cols[i].~dict_v_col_t(); } if (instant_table->fts) { instant_table->fts->~fts_t(); @@ -4297,20 +4297,19 @@ created_clustered: if (add_fts_doc_idx) { index_def_t* index = indexdef++; - uint nfields = 1; - - if (altered_table->versioned()) - ++nfields; + const uint nfields = altered_table->versioned() + 1; index->fields = static_cast( - mem_heap_alloc(heap, sizeof(*index->fields) * nfields)); + mem_heap_alloc(heap, nfields * sizeof *index->fields)); index->n_fields = nfields; index->fields[0].col_no = fts_doc_id_col; index->fields[0].prefix_len = 0; index->fields[0].descending = false; index->fields[0].is_v_col = false; if (nfields == 2) { - index->fields[1].col_no - = altered_table->s->vers.end_fieldno; + /* FTS_DOC_ID_INDEX(FTS_DOC_ID,row_end) */ + index->fields[1].col_no = innodb_col_no( + altered_table->field[ + altered_table->s->vers.end_fieldno]); index->fields[1].prefix_len = 0; index->fields[1].descending = false; index->fields[1].is_v_col = false; diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index e6bdfbfb527..af327ab460b 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -4484,7 +4484,8 @@ static int i_s_sys_error_handling(int err, THD *thd) @param rec record to read from (nullptr=use the dict_sys cache) @param table the converted dict_table_t @return error message -@retval nullptr on success */ +@retval nullptr on success, or if the record is not visible, in +which case *table will be nullptr*/ static const char *i_s_sys_tables_rec(const btr_pcur_t &pcur, mtr_t *mtr, const rec_t *rec, dict_table_t **table) { @@ -4547,7 +4548,7 @@ i_s_sys_tables_fill_table( } const char* err_msg; - dict_table_t* table_rec; + dict_table_t* table_rec = nullptr; /* Create and populate a dict_table_t structure with information from SYS_TABLES row */ @@ -4555,20 +4556,18 @@ i_s_sys_tables_fill_table( mtr.commit(); dict_sys.unlock(); - if (!err_msg) { + if (err_msg) { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_CANT_FIND_SYSTEM_REC, "%s", + err_msg); + } else if (table_rec) { err = i_s_dict_fill_sys_tables( thd, table_rec, tables->table); if (err) { err = i_s_sys_error_handling(err, thd); - if (table_rec) { - dict_mem_table_free(table_rec); - } + dict_mem_table_free(table_rec); goto func_exit; } - } else { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, "%s", - err_msg); } if (table_rec) { diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index d3115bbcacd..5b44e36f920 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -639,7 +639,12 @@ public: void init(uint32_t state, page_id_t id, uint16_t ssize) noexcept { ut_ad(state < REMOVE_HASH || state >= UNFIXED); - ut_ad(!lock.is_locked_or_waiting()); + /* A latch would mean that some thread is still using the block under + its previous identity. The exception is rtr_init_match(): the MEMORY + block that it re-initializes is private to the current thread, which + is holding page.lock on it so that lock_rec_lock() can be invoked on + the records that were copied into it. */ + ut_ad(!lock.is_locked_or_waiting() || (state == MEMORY && lock.have_x())); id_= id; oldest_modification_= 0; ut_d(in_free_list= false); @@ -1189,7 +1194,7 @@ public: /** The minimum allowed innodb_buffer_pool_size in garbage_collect() */ size_t size_in_bytes_auto_min; #endif -#if SIZEOF_SIZE_T < 8 || defined _AIX || defined HAVE_valgrind +#if SIZEOF_SIZE_T < 8 || defined _AIX || defined HAVE_valgrind || defined __SANITIZE_THREAD__ /* In constrained environments, innodb_buffer_pool_size_max will default to the initial innodb_buffer_pool_size, that is, by default, it will not be possible to increase innodb_buffer_pool_size. @@ -1198,7 +1203,12 @@ public: allocation would be backed by one or more copies of shadow bits of the same size that could be allocated and initialized even for dummy mappings created by mmap(2) with PROT_NONE. We do not want significant - overhead beyond the actual innodb_buffer_pool_size. */ + overhead beyond the actual innodb_buffer_pool_size. + + The ThreadSanitizer in GCC 16.2.0 targeting AMD64 is allocating + more than 100 TiB of virtual address space, which would make the + InnoDB 8 TiB allocation fail. + */ static constexpr size_t size_in_bytes_max_default{0}, size_in_bytes_max_minimum{0}; #else diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 0133051f7a8..69a09bdb92b 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -49,6 +49,7 @@ Created 1/8/1996 Heikki Tuuri #include "fil0crypt.h" #include "mysql_com.h" #include "lex_ident.h" +#include "my_base.h" #include #include #include diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 0476e52cbb4..cdf4713f9d6 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -159,12 +159,42 @@ innobase_convert_from_id( should be at least 3 * strlen(to) + 1 */ #ifdef WITH_WSREP +/** Normalize a column value into its collation weights. +out_str must hold buf_length + 1 bytes: one byte over the limit is asked +from strnxfrm() so that a value whose weights do not fit can be told apart +from one that fills the room exactly. The extra byte is never part of the +key, the result is cut back to buf_length. +@param truncated set to true if the weights did not fit buf_length, left + alone otherwise; may be NULL */ 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); + ulint buf_length, + bool* truncated= NULL); + +/** Store the write set key value of a string column. Used by both write set +key paths, so that one and the same column value always produces one and the +same key. See the definition in ha_innodb.cc. +@param truncated set to true if the normalized value did not fit out_str, + left alone otherwise; may be NULL */ +size_t wsrep_store_string_key_val(int mysql_type, + uint charset_number, + size_t n_chars, + const unsigned char* str, + size_t str_length, + unsigned char* out_str, + ulint out_length, + bool mysql_format, + bool* truncated= NULL); + +/** Tell the client that a write set key was cut to the key buffer size. +Two rows whose key values are equal up to the cut produce the same key and +conflict in certification although they are different rows. +@param thd session the key belongs to +@param table_name table the key was built for */ +void wsrep_warn_key_truncated(THD* thd, const char* table_name); #endif /* WITH_WSREP */ /** Get high resolution timestamp for the current query start time. diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 1a2795d4ecc..686cb30cc58 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -1267,7 +1267,8 @@ int wsrep_rec_get_foreign_key( const rec_t* rec, /* in: physical record */ dict_index_t* index_for, /* in: index for foreign table */ dict_index_t* index_ref, /* in: index for referenced table */ - ibool new_protocol); /* in: protocol > 1 */ + ibool new_protocol, /* in: protocol > 1 */ + bool* truncated= NULL); /* out: key did not fit buf */ #endif /* WITH_WSREP */ #include "rem0rec.inl" diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index a76658bbee9..abf8f71f75d 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -488,9 +488,6 @@ public: /** @return purge_sys.view or purge_sys.end_view */ inline const ReadViewBase &view() const; - - /** @return whether this is part of CHECK TABLE ... EXTENDED */ - bool is_extended() const noexcept { return latch < END_VIEW; } }; struct end_view_guard diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 98e26d24657..4ad46dce53f 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -689,8 +689,6 @@ static struct /** Maintains the last opened defer file name along with lsn */ struct item { - /** Log sequence number of latest add() called by fil_name_process() */ - lsn_t lsn; /** File name from the FILE_ record */ std::string file_name; /** whether a FILE_DELETE record was encountered */ @@ -705,9 +703,8 @@ static struct /** Add the deferred space only if it is latest one @param space space identifier - @param f_name file name - @param lsn log sequence number of the FILE_ record */ - void add(uint32_t space, const std::string &f_name, lsn_t lsn) + @param f_name file name */ + void add(uint32_t space, const std::string &f_name) { mysql_mutex_assert_owner(&recv_sys.mutex); const char *filename= f_name.c_str(); @@ -726,46 +723,12 @@ static struct char *fil_path= fil_make_filepath(nullptr, {filename, strlen(filename)}, IBD, false); - const item defer{lsn, fil_path, false}; + const item defer{fil_path, false}; ut_free(fil_path); - /* The file name must be unique. Keep the one with the latest LSN. */ - auto d= defers.begin(); - - while (d != defers.end()) - { - if (d->second.file_name != defer.file_name) - ++d; - else if (d->first == space) - { - /* Neither the file name nor the tablespace ID changed. - Update the LSN if needed. */ - if (d->second.lsn < lsn) - d->second.lsn= lsn; - return; - } - else if (d->second.lsn < lsn) - { - /* Reset the old tablespace name in recovered spaces list */ - recv_spaces_t::iterator it{recv_spaces.find(d->first)}; - if (it != recv_spaces.end() && - it->second.name == d->second.file_name) - it->second.name = ""; - defers.erase(d++); - } - else - { - ut_ad(d->second.lsn != lsn); - return; /* A later tablespace already has this name. */ - } - } - auto p= defers.emplace(space, defer); - if (!p.second && p.first->second.lsn <= lsn) - { - p.first->second.lsn= lsn; + if (!p.second) p.first->second.file_name= defer.file_name; - } /* Add the newly added deferred space and change the file name */ recv_spaces_t::iterator it{recv_spaces.find(space)}; if (it != recv_spaces.end()) @@ -813,43 +776,31 @@ retry: const uint32_t space_id{d->first}; recv_sys_t::map::iterator p{recv_sys.pages.lower_bound({space_id,0})}; - if (d->second.deleted || - p == recv_sys.pages.end() || p->first.space() != space_id) + if (d->second.deleted) { - /* We found a FILE_DELETE record for the tablespace, or - there were no buffered records. Either way, we must create a - dummy tablespace with the latest known name, - for dict_drop_index_tree(). */ + /* We found a FILE_DELETE record for the tablespace. */ recv_sys.pages_it_invalidate(space_id); while (p != recv_sys.pages.end() && p->first.space() == space_id) { ut_ad(!p->second.being_processed); - recv_sys_t::map::iterator r= p++; + recv_sys_t::map::iterator r{p++}; recv_sys.erase(r); } + } + else if (p == recv_sys.pages.end() || p->first.space() != space_id) + { + /* There were no buffered records. We must create a + dummy tablespace with the latest known name, + for dict_drop_index_tree(). */ recv_spaces_t::iterator it{recv_spaces.find(space_id)}; - if (it != recv_spaces.end()) - { - const std::string *name= &d->second.file_name; - if (d->second.deleted) - { - const auto r= renamed_spaces.find(space_id); - if (r != renamed_spaces.end()) - name= &r->second; - bool exists; - os_file_type_t ftype; - if (!os_file_status(name->c_str(), &exists, &ftype) || !exists) - goto processed; - } - if (create(it, *name, static_cast - (1U << FSP_FLAGS_FCRC32_POS_MARKER | - FSP_FLAGS_FCRC32_PAGE_SSIZE()), nullptr, 0)) - mysql_mutex_unlock(&fil_system.mutex); - } + if (it != recv_spaces.end() && + create(it, d->second.file_name, static_cast + (1U << FSP_FLAGS_FCRC32_POS_MARKER | + FSP_FLAGS_FCRC32_PAGE_SSIZE()), nullptr, 0)) + mysql_mutex_unlock(&fil_system.mutex); } else space= recv_sys.recover_deferred(p, d->second.file_name, free_block); -processed: auto e= d++; defers.erase(e); if (!space) @@ -888,31 +839,7 @@ processed: fil_space_t *space= fil_space_t::create(it->first, flags, false, crypt_data); ut_ad(space); - const char *filename= name.c_str(); - if (srv_operation == SRV_OPERATION_RESTORE) - { - if (const char *tbl_name= strrchr(filename, '/')) - { - while (--tbl_name > filename && *tbl_name != '/'); - if (tbl_name > filename) - filename= tbl_name + 1; - } - } - pfs_os_file_t handle= OS_FILE_CLOSED; - if (srv_operation == SRV_OPERATION_RESTORE) - { - /* During mariadb-backup --backup, a table could be renamed, - created and dropped, and we may be missing the file at this - point of --prepare. Try to create the file if it does not exist - already. If the file exists, we'll pass handle=OS_FILE_CLOSED - and the file will be opened normally in fil_space_t::acquire() - inside recv_sys_t::recover_deferred(). */ - bool success; - handle= os_file_create(innodb_data_file_key, filename, - OS_FILE_CREATE_SILENT, - OS_DATA_FILE, false, &success); - } - space->add(filename, handle, size, false, false); + space->add(name.c_str(), OS_FILE_CLOSED, size, false, false); space->recv_size= it->second.size; space->size_in_header= size; return space; @@ -1229,10 +1156,11 @@ inline size_t recv_sys_t::files_size() @param[in] space_id the tablespace ID @param[in] ftype FILE_CREATE, FILE_MODIFY, FILE_DELETE, or FILE_RENAME -@param[in] lsn lsn of the redo log -@param[in] if_exists whether to check if the tablespace exists */ -static void fil_name_process(const char *name, ulint len, uint32_t space_id, - mfile_type_t ftype, lsn_t lsn, bool if_exists) +@param[in] if_exists whether to check if the tablespace exists +@return the file name mapping */ +static file_name_t & +fil_name_process(const char *name, ulint len, uint32_t space_id, + mfile_type_t ftype, bool if_exists) { ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || srv_operation == SRV_OPERATION_RESTORE @@ -1334,8 +1262,7 @@ rename: } if (ftype == FILE_CREATE) { - f.create_lsn = lsn; - break; + goto deferred_create; } if (s == FIL_LOAD_ID_CHANGED) { @@ -1365,11 +1292,8 @@ rename: if (d && ftype == FILE_RENAME && f.create_lsn) { goto rename; } - /* Skip the deferred spaces - when lsn is already processed */ if (!if_exists) { - deferred_spaces.add( - space_id, fname.name.c_str(), lsn); + goto deferred_create; } break; case FIL_LOAD_INVALID: @@ -1394,9 +1318,17 @@ rename: " due to innodb_force_recovery", int(len), name, space_id); } - } else if (ftype == FILE_CREATE && !f.space) { - f.create_lsn = lsn; + } else if (ftype == FILE_CREATE) { +deferred_create: + /* fil_ibd_create() writes FILE_MODIFY followed by FILE_CREATE. + fil_ibd_load() may have found a valid file when processing the + FILE_MODIFY record. */ + if (!f.space) { + deferred_spaces.add(space_id, fname.name.c_str()); + } } + + return f; } void recv_sys_t::close_files() @@ -2635,7 +2567,12 @@ bool recv_sys_t::parse_store_if_exists(uint32_t space_id) const noexcept if (!size) return false; } - else if (!deferred_spaces.find(space_id)) + else if (const auto d= deferred_spaces.find(space_id)) + { + if (d->deleted) + return false; + } + else return false; return true; @@ -2835,15 +2772,14 @@ log_parse_file(const page_id_t id, bool if_exists, break; } - fil_name_process(reinterpret_cast(l), fnend - l, space_id, - fn2 ? FILE_MODIFY : mfile_type_t(b & 0xf0), - recv_sys.start_lsn, if_exists); + file_name_t &fname= + fil_name_process(reinterpret_cast(l), fnend - l, space_id, + fn2 ? FILE_MODIFY : mfile_type_t(b & 0xf0), if_exists); if (fn2) { fil_name_process(reinterpret_cast(fn2), fn2end - fn2, - space_id, mfile_type_t(b & 0xf0), - recv_sys.start_lsn, if_exists); + space_id, mfile_type_t(b & 0xf0), if_exists); if (recv_sys.file_checkpoint) { const char *name= reinterpret_cast(fn2); @@ -2853,6 +2789,8 @@ log_parse_file(const page_id_t id, bool if_exists, r.first->second= std::string{name, len}; } } + else if ((b & 0xf0) == FILE_CREATE) + fname.create_lsn= recv_sys.start_lsn; if (recv_sys.is_corrupt_fs()) return recv_sys_t::GOT_EOF; @@ -4550,28 +4488,28 @@ recv_validate_tablespace(bool rescan, bool& missing_tablespace) const uint32_t space = p->first.space(); if (space == TRX_SYS_SPACE || srv_is_undo_tablespace(space)) { next: - p++; + if (++p == recv_sys.pages.end()) { + break; + } + if (p->first.space() == space) { + goto next; + } continue; } - recv_spaces_t::iterator i = recv_spaces.find(space); - ut_ad(i != recv_spaces.end()); - if (deferred_spaces.find(space)) { /* Skip redo logs belonging to incomplete tablespaces */ goto next; } + recv_spaces_t::iterator i = recv_spaces.find(space); + ut_ad(i != recv_spaces.end()); + switch (i->second.status) { case file_name_t::NORMAL: goto next; case file_name_t::MISSING: - if (srv_operation != SRV_OPERATION_NORMAL) { - } else if (const lsn_t c = i->second.create_lsn) { - deferred_spaces.add(space, i->second.name, c); - goto next; - } err = recv_init_missing_space(err, i); i->second.status = file_name_t::DELETED; /* fall through */ @@ -4785,13 +4723,13 @@ inline void log_t::set_recovered() noexcept inline bool recv_sys_t::validate_checkpoint() const noexcept { const lsn_t last_checkpoint_lsn{log_sys.last_checkpoint_lsn}; - if (lsn >= file_checkpoint && lsn >= last_checkpoint_lsn) + if (scanned_lsn >= file_checkpoint && scanned_lsn >= last_checkpoint_lsn) return false; sql_print_error("InnoDB: The log was only scanned up to " LSN_PF ", while the current LSN at the " "time of the latest checkpoint " LSN_PF " was " LSN_PF "!", - lsn, last_checkpoint_lsn, file_checkpoint); + scanned_lsn, last_checkpoint_lsn, file_checkpoint); return true; } @@ -4860,11 +4798,7 @@ func_exit: parser[true] = get_parse_mmap(); recv_scan_log(false, parser); if (recv_needed_recovery) { -read_only_recovery: - sql_print_warning("InnoDB: innodb_read_only" - " prevents crash recovery"); - err = DB_READ_ONLY; - goto func_exit; + goto read_only_recovery; } if (recv_sys.is_corrupt_log()) { sql_print_error("InnoDB: Log scan aborted at LSN " @@ -4883,19 +4817,27 @@ read_only_recovery: } rescan = recv_scan_log(false, parser); - if (srv_read_only_mode && recv_needed_recovery) { - goto read_only_recovery; - } - if ((recv_sys.is_corrupt_log() && !srv_force_recovery) - || recv_sys.is_corrupt_fs()) { + || recv_sys.is_corrupt_fs() + || recv_sys.validate_checkpoint()) { goto err_exit; } } + ut_ad(recv_sys.scanned_lsn >= recv_sys.lsn); + ut_ad(recv_sys.scanned_lsn == recv_sys.lsn || rescan); log_sys.set_recovered_lsn(recv_sys.scanned_lsn); if (recv_needed_recovery) { + if (srv_read_only_mode) { +read_only_recovery: + sql_print_warning("InnoDB: innodb_read_only" + " prevents crash recovery"); + err = DB_READ_ONLY; + goto func_exit; + + } + bool missing_tablespace = false; err = recv_init_crash_recovery_spaces( @@ -4952,58 +4894,45 @@ read_only_recovery: } ut_ad(srv_force_recovery <= SRV_FORCE_NO_UNDO_LOG_SCAN); - - if (rescan) { - recv_scan_log(true, parser); - if ((recv_sys.is_corrupt_log() - && !srv_force_recovery) - || recv_sys.is_corrupt_fs()) { - goto err_exit; - } - - /* In case of multi-batch recovery, - redo log for the last batch is not - applied yet. */ - ut_d(recv_sys.after_apply = false); - } } else { ut_ad(recv_sys.pages.empty()); } - if (!log_sys.is_recoverable()) { - } else if (recv_sys.validate_checkpoint()) { -err_exit: - err = DB_ERROR; - goto func_exit; - } - - if (!srv_read_only_mode && log_sys.is_recoverable()) { - log_sys.set_recovered(); - } - DBUG_EXECUTE_IF("before_final_redo_apply", goto err_exit;); mysql_mutex_lock(&recv_sys.mutex); - if (UNIV_UNLIKELY(recv_sys.scanned_lsn != recv_sys.lsn) - && log_sys.is_recoverable()) { - ut_ad("log parsing error" == 0); - mysql_mutex_unlock(&recv_sys.mutex); - err = DB_CORRUPTION; - goto func_exit; - } - recv_sys.apply_log_recs = true; ut_d(recv_no_log_write = srv_operation == SRV_OPERATION_RESTORE || srv_operation == SRV_OPERATION_RESTORE_EXPORT); if (srv_operation == SRV_OPERATION_NORMAL) { err = recv_rename_files(); } - mysql_mutex_unlock(&recv_sys.mutex); + if (err != DB_SUCCESS) { + goto func_exit; + } + + if (rescan) { + recv_scan_log(true, parser); + if ((recv_sys.is_corrupt_log() && !srv_force_recovery) + || recv_sys.is_corrupt_fs()) { +err_exit: + err = DB_ERROR; + goto func_exit; + } + + /* In case of multi-batch recovery, redo log + for the last batch is not applied yet. */ + ut_d(recv_sys.after_apply = false); + } + + ut_ad(recv_sys.scanned_lsn == recv_sys.lsn); + recv_sys.apply_log_recs = true; + log_sys.set_recovered(); + /* The database is now ready to start almost normal processing of user transactions: transaction rollbacks and the application of the log records in the hash table can be run in background. */ - if (err == DB_SUCCESS && deferred_spaces.reinit_all() - && !srv_force_recovery) { + if (deferred_spaces.reinit_all() && !srv_force_recovery) { err = DB_CORRUPTION; } diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 356c2f62412..ed9f62e7f8a 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -514,8 +514,11 @@ void mtr_t::commit() ut_ad(!m_freed_pages->empty()); ut_ad(m_freed_space == fil_system.temp_space); ut_ad(!m_trim_pages); - for (const auto &range : *m_freed_pages) - m_freed_space->add_free_range(range); + { + std::lock_guard freed_lock(m_freed_space->freed_range_mutex); + for (const auto &range : *m_freed_pages) + m_freed_space->add_free_range(range); + } delete m_freed_pages; m_freed_pages= nullptr; m_freed_space= nullptr; diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 6494c5e21b9..4f04f1b45c2 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1378,10 +1378,6 @@ os_file_rename_func( os_file_type_t type; bool exists; - /* New path must not exist. */ - ut_ad(os_file_status(newpath, &exists, &type)); - ut_ad(!exists); - /* Old path must exist. */ ut_ad(os_file_status(oldpath, &exists, &type)); ut_ad(exists); @@ -2293,10 +2289,6 @@ os_file_rename_func( os_file_type_t type; bool exists; - /* New path must not exist. */ - ut_ad(os_file_status(newpath, &exists, &type)); - ut_ad(!exists); - /* Old path must exist. */ ut_ad(os_file_status(oldpath, &exists, &type)); ut_ad(exists); diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 95a7faa1299..8a162e0d792 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -2667,6 +2667,63 @@ rec_offs_make_nth_extern( } #ifdef WITH_WSREP # include "ha_prototypes.h" +# include /* wsrep_protocol_version */ + +/** Room left in a write set key buffer for one column. + +A column that does not fit is cut, the same way wsrep_store_key_val_for_row() +cuts the matching row key, so that the two keys still agree. Failing here +instead fails the statement, and the caller turns the error into a fatal one. + +A nullable column spends one byte on the null flag. A SQL NULL value writes +only that flag byte and nothing else, so it needs just the one byte. A +non-NULL value needs the flag byte, if any, plus at least one more byte for +the value itself, or, for a column that cannot be cut, all of it. + +A fixed-length column (DATA_INT, DATA_FLOAT, DATA_DOUBLE) cannot be cut: the +caller reads it out of the record as a whole number, float or double and +copies it as one unit, so a partial value is not a shorter version of it, it +is a different value, or for FLOAT and DOUBLE not even a valid one, one that +mach_float_read()/mach_double_read() reads past to build regardless. Such a +column is only ever written whole; otherwise it is left out of the key the +same way a value that does not fit at all is, one flag byte or nothing. + +@param buf_len size of the key buffer +@param key_len bytes of the key written so far +@param len length of the column in the record, UNIV_SQL_NULL if it is + SQL NULL +@param col_ref column of the referenced index +@param fixed_len the column cannot be cut: only its full length fits it, + anything less does not +@param[out] space bytes left for the value of this column, the null flag + already taken off +@return false if not even the flag byte (SQL NULL), one byte of the value + (otherwise), or, for a column that cannot be cut, all of it, fits; + true otherwise */ +static +bool +wsrep_fk_key_space_left( + ulint buf_len, + ulint key_len, + ulint len, + const dict_col_t* col_ref, + bool fixed_len, + ulint* space) +{ + const ulint flag_len = (len == UNIV_SQL_NULL + || !(col_ref->prtype & DATA_NOT_NULL)) + ? 1 : 0; + const ulint left = buf_len - key_len; + const ulint needed = flag_len + + (len == UNIV_SQL_NULL ? 0 : fixed_len ? len : 1); + + if (left < needed) { + return false; + } + + *space = left - flag_len; + return true; +} int wsrep_rec_get_foreign_key( @@ -2675,7 +2732,8 @@ wsrep_rec_get_foreign_key( const rec_t* rec, /* in: physical record */ dict_index_t* index_for, /* in: index in foreign table */ dict_index_t* index_ref, /* in: index in referenced table */ - ibool new_protocol) /* in: protocol > 1 */ + ibool new_protocol, /* in: protocol > 1 */ + bool* truncated) /* out: key did not fit buf */ { const byte* data; ulint len; @@ -2699,11 +2757,11 @@ wsrep_rec_get_foreign_key( ut_ad(rec); key_parts = dict_index_get_n_unique_in_tree(index_for); - for (i = 0; - i < key_parts && - (index_for->type & DICT_CLUSTERED || i < key_parts - 1); + for (i = 0; + i < key_parts && + (index_for->type & DICT_CLUSTERED || i < key_parts - 1); i++) { - dict_field_t* field_f = + dict_field_t* field_f = dict_index_get_nth_field(index_for, i); const dict_col_t* col_f = dict_field_get_col(field_f); dict_field_t* field_r = @@ -2712,13 +2770,40 @@ wsrep_rec_get_foreign_key( ut_ad(!rec_offs_nth_default(offsets, i)); data = rec_get_nth_field(rec, offsets, i, &len); - if (key_len + ((len != UNIV_SQL_NULL) ? len + 1 : 1) > - *buf_len) { - fprintf(stderr, - "WSREP: FK key len exceeded " - ULINTPF " " ULINTPF " " ULINTPF "\n", - key_len, len, *buf_len); - goto err_out; + + ulint space; + /* Only the new protocol reads these three types out of the + record as a whole number, float or double (the switch below, + under new_protocol); the old protocol normalizes every type + as a string, which already cuts to whatever *buf_len allows + on its own. */ + const bool fixed_len = new_protocol + && (col_f->mtype == DATA_INT + || col_f->mtype == DATA_FLOAT + || col_f->mtype == DATA_DOUBLE); + + if (!wsrep_fk_key_space_left(*buf_len, key_len, len, col_r, + fixed_len, &space)) { + /* Not even one byte of this column fits, or it + cannot be cut and not all of it fits. */ + if (truncated) { + *truncated = true; + } + break; + } + + if (len != UNIV_SQL_NULL && len > space) { + /* Only the raw copy branches below need this: the + string branches are given the room they have and cut + the normalized value themselves. A fixed_len column + must not be cut to a length of its own, so it must not + reach here: wsrep_fk_key_space_left() already + guaranteed the whole of it fits. */ + ut_ad(!fixed_len); + len = space; + if (truncated) { + *truncated = true; + } } if (len == UNIV_SQL_NULL) { @@ -2734,7 +2819,7 @@ wsrep_rec_get_foreign_key( (int)(col_f->prtype & DATA_MYSQL_TYPE_MASK), dtype_get_charset_coll(col_f->prtype), data, buf, static_cast(len), - static_cast(*buf_len)); + static_cast(*buf_len), truncated); } else { /* new protocol */ if (!(col_r->prtype & DATA_NOT_NULL)) { *buf++ = 0; @@ -2760,16 +2845,53 @@ wsrep_rec_get_foreign_key( } case DATA_VARCHAR: case DATA_VARMYSQL: - case DATA_CHAR: - case DATA_MYSQL: - len = wsrep_normalize_string( + len = wsrep_store_string_key_val( (int)(col_f->prtype & DATA_MYSQL_TYPE_MASK), dtype_get_charset_coll(col_f->prtype), - data, buf, len, *buf_len); + 0, data, len, buf, + space, false, truncated); break; + case DATA_CHAR: + case DATA_MYSQL: + /* A CHAR is stored with the space padding + InnoDB happened to leave on it, which is not + what the MySQL record holds. Pass the number + of characters the column has so that both + forms end up as the same key. */ + len = wsrep_store_string_key_val( + (int)(col_f->prtype & DATA_MYSQL_TYPE_MASK), + dtype_get_charset_coll(col_f->prtype), + col_f->mbmaxlen + ? col_f->len / col_f->mbmaxlen : 0, + data, len, buf, + space, false, truncated); + break; + case DATA_FIXBINARY: + if (wsrep_protocol_version < 5 + && !(col_f->prtype + & DATA_BINARY_TYPE)) { + /* A UUID, INET6 or INET4 column is + stored as fixed length binary, but + below protocol version 5 + wsrep_store_key_val_for_row() still + collates the row key of the parent + with the character set of the field. + Collate the reference key the same + way, so that the two match in a + cluster that has not fully upgraded + yet. */ + len = wsrep_normalize_string( + (int)(col_f->prtype + & DATA_MYSQL_TYPE_MASK), + dtype_get_charset_coll( + col_f->prtype), + data, buf, len, space, + truncated); + break; + } + /* fall through */ case DATA_BLOB: case DATA_BINARY: - case DATA_FIXBINARY: case DATA_GEOMETRY: memcpy(buf, data, len); break; @@ -2777,12 +2899,14 @@ wsrep_rec_get_foreign_key( case DATA_FLOAT: { float f = mach_float_read(data); + ut_ad(len == sizeof(float)); memcpy(buf, &f, sizeof(float)); } break; case DATA_DOUBLE: { double d = mach_double_read(data); + ut_ad(len == sizeof(double)); memcpy(buf, &d, sizeof(double)); } break; @@ -2803,11 +2927,5 @@ wsrep_rec_get_foreign_key( *buf_len = key_len; return DB_SUCCESS; - - err_out: - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } - return DB_ERROR; } #endif // WITH_WSREP diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 8f234cbd6c4..6bf149388bb 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -4018,6 +4018,24 @@ void UndorecApplier::log_update(const dtuple_t &tuple, rec_offs_make_valid(copy_rec, clust_index, true, offsets); mtr.commit(); + /* row_log_table_get_pk() below dereferences the externally stored + columns of prev_version, with neither a page latch nor a frozen + purge_sys.view. Two properties keep those pages allocated: + + (a) trx_t::apply_log() runs before trx_t::write_serialisation_history(), + so this transaction is still registered in trx_sys and its undo log is + not yet in the history list. purge_sys.view therefore cannot see it. + + (b) get_old_rec() stops at the version this undo log record wrote, and + this transaction holds an exclusive lock on the record. The page latch + is already released here, but that lock is not, until past the + serialisation point (a) rests on, so every version above that one is + this transaction's own. The oldest writer applied is therefore this + transaction, and whatever disowned a reference that prev_version holds + is that writer or a newer one, none of which purge can reach. + + Deferring the call past the serialisation, or walking below this + transaction's own version, would break the argument. */ clust_index->lock.s_lock(SRW_LOCK_CALL); /* Recheck whether clustered index online log has been cleared */ if (clust_index->online_log) diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 5c35b372ba3..6fc2bf9cac4 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2080,6 +2080,8 @@ row_create_table_for_mysql( que_run_threads(thr); + DEBUG_SYNC_C("create_table_inserted"); + dberr_t err = trx->error_state; if (err != DB_SUCCESS) { diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index adc73ee8d6a..5af4a9ff8a8 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -686,7 +686,8 @@ nochange_index: rec_offs_comp(clust_offsets))) { row_ext_t* ext; - /* The stack of versions is locked by mtr. + /* The stack of versions is locked by mtr, and + purge_sys.view is frozen for the whole batch. Thus, it is safe to fetch the prefixes for externally stored columns. */ row = row_build(ROW_COPY_POINTERS, clust_index, diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 200db205a43..2ebec2e28ab 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3518,6 +3518,13 @@ Row_sel_get_clust_rec_for_mysql::operator()( LOCK_REC_NOT_GAP, thr); + if (err == DB_LOCK_WAIT && prebuilt->skip_locked) { + /* Cancel the lock wait, unless the lock was granted + meanwhile; then continue with a normal locking read + of clust_rec. */ + err = lock_trx_handle_wait(trx); + } + switch (err) { case DB_SUCCESS: case DB_SUCCESS_LOCKED_REC: @@ -5554,9 +5561,6 @@ requires_clust_rec: &offsets, &heap, need_vrow ? &vrow : NULL, &mtr); - if (err == DB_LOCK_WAIT && prebuilt->skip_locked) { - err = lock_trx_handle_wait(trx); - } switch (err) { case DB_SUCCESS: if (clust_rec == NULL) { @@ -6538,24 +6542,63 @@ rec_loop: check_latest_version: /* In CHECK TABLE...EXTENDED, always check if the secondary index record matches the latest clustered index record - version, no matter if it is visible in our own read view. - - If the latest clustered index version is delete-marked and - purgeable, it is not safe to fetch any BLOBs for column prefix - indexes because they may already have been freed. */ - if (rec_trx_id && - rec_get_deleted_flag(clust_rec, - prebuilt->table->not_redundant()) && - purge_sys.is_purgeable(rec_trx_id)) - goto did_not_find; - + version, no matter if it is visible in our own read view. */ if (!clust_offsets) clust_offsets= rec_get_offsets(clust_rec, clust_index, nullptr, clust_index->n_core_fields, ULINT_UNDEFINED, &heap); - err= row_check_index_match(prebuilt, - clust_rec, clust_index, clust_offsets, - rec, index, offsets); + + /* If the latest clustered index version is delete-marked and + purgeable, it is not safe to fetch any BLOBs for column prefix + indexes because they may already have been freed. Where anything + will be dereferenced, freeze purge_sys.view across the test and + the fetch, so that purge cannot start freeing in between. + + The freeze deliberately spans the whole comparison, not only the + fetch: row_check_index_match() dereferences one field at a time, + and for an index over a virtual column it evaluates the column + expression as well. Purge stays blocked for as long as that + takes. + + A record that is not delete-marked owns all its externally stored + columns, and purge frees no reference that a record still owns, so + only a delete-marked one needs the freeze. The delete-mark cannot + change while this mini-transaction holds the page latch. + + DB_TRX_ID stays out of that choice. It is 0 on a delete-marked + record that IMPORT TABLESPACE could not remove, and such a record + still needs the freeze, its references having been disowned to a + version that purge may free. Where it is 0 there is no transaction + to ask about, which is what both tests below need. */ + { + const bool deleted= + rec_get_deleted_flag(clust_rec, prebuilt->table->not_redundant()); + + if (!deleted || !rec_offs_any_extern(clust_offsets) || + DBUG_IF("purge_no_blob_freeze")) + { + /* purge_no_blob_freeze sends a record that does have externally + stored columns here as well, which is how the fetch below behaved + before it was protected. */ + if (deleted && rec_trx_id && purge_sys.is_purgeable(rec_trx_id)) + goto did_not_find; + + err= row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + } + else + { + purge_sys_t::view_guard freeze{purge_sys_t::view_guard::VIEW}; + + if (rec_trx_id && freeze.view().changes_visible(rec_trx_id)) + goto did_not_find; + + err= row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + } + } switch (err) { default: @@ -6627,6 +6670,9 @@ rec_loop: for (;;) { + /* The writer of clust_rec, whose undo log record rebuilds the next + version. Read before clust_rec is replaced by it below. */ + const trx_id_t version_trx_id= rec_trx_id; mem_heap_t *prev_heap= vers_heap; vers_heap= mem_heap_create(1024); err= trx_undo_prev_version_build(clust_rec, @@ -6695,13 +6741,67 @@ rec_loop: if (&view != &trx->read_view) { /* It is not safe to fetch BLOBs of committed delete-marked - records that may have been freed in purge. */ - err= clust_rec_deleted && rec_trx_id && - purge_sys.is_purgeable(rec_trx_id) - ? DB_SUCCESS_LOCKED_REC - : row_check_index_match(prebuilt, - clust_rec, clust_index, clust_offsets, - rec, index, offsets); + records that may have been freed in purge. Where anything will + be dereferenced, freeze purge_sys.view across the test and the + fetch, so that purge cannot start freeing in between. As at + check_latest_version, the freeze deliberately spans the whole + comparison, which fetches one field at a time and may evaluate + a virtual column expression. */ + const bool extern_cols= rec_offs_any_extern(clust_offsets); + + if (!extern_cols || DBUG_IF("purge_no_blob_freeze")) + { + /* purge_no_blob_freeze sends a version that does have + externally stored columns here as well, which is how the + fetch below behaved before it was protected. */ + if (extern_cols) + DEBUG_SYNC_C("row_check_index_extended_match"); + err= clust_rec_deleted && rec_trx_id && + purge_sys.is_purgeable(rec_trx_id) + ? DB_SUCCESS_LOCKED_REC + : row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + } + else + { + purge_sys_t::view_guard freeze{purge_sys_t::view_guard::VIEW}; + + /* Confirm that purge cannot see the writer of the version + clust_rec was rebuilt from. Unlike every other walk over old + versions, this one decides reachability from the lagging + purge_sys.end_view, so it does reach history that purge is + already free to remove. + + Where it does, stop and report nothing. The orphan reports + of the other exits are calibrated on purge_sys.end_view, + while this test speaks about purge_sys.view, which is ahead + of it. Feeding a decision of the one into a gate of the + other could raise an error for a record that is not + delete-marked and is nonetheless sound. No report is lost + for good: as soon as end_view reaches the same point, + trx_undo_prev_version_build() reports missing history, and + a record that is truly unmatchable is flagged then. + + row_check_index_purgeable forces this branch, which is + otherwise reached only when the view advances between the + walk starting and the freeze. */ + if (freeze.view().changes_visible(version_trx_id) || + DBUG_IF("row_check_index_purgeable")) + { + ut_ad(!found_in_view); + goto free_vers_heap; + } + + DEBUG_SYNC_C("row_check_index_extended_match"); + + err= clust_rec_deleted && rec_trx_id && + freeze.view().changes_visible(rec_trx_id) + ? DB_SUCCESS_LOCKED_REC + : row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + } switch (err) { default: @@ -6719,6 +6819,7 @@ rec_loop: visible_trx_id= rec_trx_id; found_in_view= !clust_rec_deleted; } + free_vers_heap: mem_heap_free(vers_heap); if (!found_in_view) goto did_not_find; diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index cd30090d437..8161d8cd987 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -520,6 +520,11 @@ static bool row_undo_mod_sec_is_unsafe(const rec_t *rec, dict_index_t *index, version = rec; for (;;) { + /* The writer of version, whose undo log record rebuilds the + next one. Read before the heap holding version is freed. */ + const trx_id_t version_trx_id = row_get_rec_trx_id( + version, clust_index, clust_offsets); + heap2 = heap; heap = mem_heap_create(1024); vrow = NULL; @@ -566,12 +571,54 @@ nochange_index: if (!rec_get_deleted_flag(prev_version, comp)) { row_ext_t* ext; - /* The stack of versions is locked by mtr. - Thus, it is safe to fetch the prefixes for - externally stored columns. */ - row = row_build(ROW_COPY_POINTERS, clust_index, - prev_version, clust_offsets, - NULL, NULL, NULL, &ext, heap); + const bool extern_cols = + rec_offs_any_extern(clust_offsets); + + if (!extern_cols + || DBUG_IF("purge_no_blob_freeze")) { + /* Nothing to dereference: the stack of + versions being locked by mtr is enough. + purge_no_blob_freeze sends a version that does + have externally stored columns here as well, + which is how the dereference below behaved + before it was protected. */ + if (extern_cols) { + DEBUG_SYNC_C( + "row_undo_mod_sec_is_unsafe_row_build"); + } + row = row_build(ROW_COPY_POINTERS, clust_index, + prev_version, clust_offsets, + NULL, NULL, NULL, &ext, heap); + } else { + /* Freeze purge_sys.view across the + dereference and confirm that purge cannot see + the writer of version, the oldest one this + walk has applied. If it can, stop and report + the secondary index entry as still needed, + which is the conservative answer. Only the + dereference needs the freeze: the prefixes end + up copied into heap. */ + purge_sys_t::view_guard freeze{ + purge_sys_t::view_guard::VIEW}; + + /* row_undo_mod_sec_is_unsafe_purgeable forces + this branch, which is otherwise reached only + when the view advances between the walk + starting and the freeze. */ + if (freeze.view().changes_visible( + version_trx_id) + || DBUG_IF( + "row_undo_mod_sec_is_unsafe_purgeable")) { + break; + } + + DEBUG_SYNC_C( + "row_undo_mod_sec_is_unsafe_row_build"); + + row = row_build(ROW_COPY_POINTERS, clust_index, + prev_version, clust_offsets, + NULL, NULL, NULL, &ext, heap); + } if (dict_index_has_virtual(index)) { ut_ad(cur_vrow); diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 25025a8d611..f70314281d9 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -253,13 +253,47 @@ not_locked: prev_trx_id = row_get_rec_trx_id(prev_version, clust_index, clust_offsets); - /* The stack of versions is locked by mtr. Thus, it - is safe to fetch the prefixes for externally stored - columns. */ + const bool extern_cols = rec_offs_any_extern(clust_offsets); - row = row_build(ROW_COPY_POINTERS, clust_index, prev_version, - clust_offsets, - NULL, NULL, NULL, &ext, heap); + if (!extern_cols || DBUG_IF("purge_no_blob_freeze")) { + /* Nothing to dereference: the stack of versions + being locked by mtr is enough. + purge_no_blob_freeze sends a version that does + have externally stored columns here as well, + which is how the dereference below behaved + before it was protected. */ + if (extern_cols) { + DEBUG_SYNC_C( + "row_vers_impl_x_locked_row_build"); + } + row = row_build(ROW_COPY_POINTERS, clust_index, + prev_version, clust_offsets, + NULL, NULL, NULL, &ext, heap); + } else { + /* Freeze purge_sys.view across the dereference and + confirm that purge has not seen trx, which wrote + every undo log record this walk applies (the loop + only continues while prev_trx_id is trx->id). If it + has, trx is committed and holds no implicit lock. + Only the dereference needs the freeze: the prefixes + end up copied into heap. */ + purge_sys_t::view_guard freeze{ + purge_sys_t::view_guard::VIEW}; + + /* row_vers_impl_x_locked_purgeable forces this + branch, which is otherwise reached only when trx + commits between the walk starting and the freeze. */ + if (freeze.view().changes_visible(trx->id) + || DBUG_IF("row_vers_impl_x_locked_purgeable")) { + goto not_locked; + } + + DEBUG_SYNC_C("row_vers_impl_x_locked_row_build"); + + row = row_build(ROW_COPY_POINTERS, clust_index, + prev_version, clust_offsets, + NULL, NULL, NULL, &ext, heap); + } if (dict_index_has_virtual(index)) { if (vrow) { diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 2c7e58e7c2e..a0f17cacb1a 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -40,6 +40,7 @@ Created 3/26/1996 Heikki Tuuri #include "trx0rseg.h" #include "trx0trx.h" #include "dict0load.h" +#include "debug_sync.h" #include #include #include "log.h" @@ -1528,6 +1529,26 @@ ulint trx_purge(trx_t *trx, ulint n_tasks, ulint history_size) noexcept trx_purge_close_tables(thd, nullptr, true); } +#ifdef ENABLED_DEBUG_SYNC + /* Hold the batch open between its last purged record and the advance of + purge_sys.head and purge_sys.end_view, which is the window where a reader + that goes by end_view can still reach history this batch has removed. That + window is not otherwise accessible from a test, because it opens and closes + within this function. + + Only a batch that purged something opens it, and parking one that did not + would stop the batch a test is waiting for. Whoever sets purge_hold_cleanup + must release the batch: until then it keeps this thread, and the undo pages + the batch handled. */ + if (n_work) + DBUG_EXECUTE_IF("purge_hold_cleanup", + debug_sync_set_action + (current_thd, + STRING_WITH_LEN("now SIGNAL purge_batch_parked " + "WAIT_FOR purge_batch_resume")); + ); +#endif + purge_sys.batch_cleanup(head); MONITOR_INC_VALUE(MONITOR_PURGE_INVOKED, 1); diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index b95806718b9..90072341a97 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -2245,16 +2245,19 @@ static dberr_t trx_undo_prev_version(const rec_t *rec, dict_index_t *index, cannot have purged the BLOBs referenced by that version yet). - This function does not fetch any BLOBs. The callers might, by - possibly invoking row_ext_create() via row_build(). However, - they should have all needed information in the *old_vers - returned by this function. This is because *old_vers is based - on the transaction undo log records. The function - trx_undo_page_fetch_ext() will write BLOB prefixes to the - transaction undo log that are at least as long as the longest - possible column prefix in a secondary index. Thus, secondary - index entries for *old_vers can be constructed without - dereferencing any BLOB pointers. */ + This function does not fetch any BLOBs, but the callers might, + by invoking row_ext_create() via row_build(). Both (a) and (b) + are statements about purge_sys.view, and they cover a reference + that the version merely inherited only if no transaction whose + undo log record was applied on the way down is visible to that + view, because one of those records disowned the reference. Such + a caller must therefore freeze purge_sys.view across the + dereference, by holding purge_sys.latch or by being a purge task, + and establish that condition under the freeze. Testing the + oldest writer applied suffices: a newer version can only have + been written once the older writer released the exclusive lock on + the record, so a view that sees a newer writer saw the older one + end before the view was created. */ ptr = trx_undo_rec_skip_row_ref(ptr, index); @@ -2270,18 +2273,12 @@ static dberr_t trx_undo_prev_version(const rec_t *rec, dict_index_t *index, records in secondary indexes, it normally covers some history that is already being purged. This is safe as long as the undo log records have not been freed yet. + Whether the externally stored columns of the version + built here may still be dereferenced is left to the + caller, the only one that knows whether it will + dereference any and can test that atomically with it. - However, BLOBs are only safe to access as long as the - purge_sys.view does not permit them to be freed. The - check.latch will freeze the purge_sys.view by blocking - purge_sys.clone_oldest_view() at the start of - trx_purge() or by blocking purge_sys.batch_cleanup() - at the end of trx_purge(). */ - if (check.is_extended() && purge_sys.is_purgeable(trx_id)) { - return DB_SUCCESS; - } - - /* We should confirm the existence of disowned external data, + We should confirm the existence of disowned external data, if the previous version record is delete marked. If the trx_id of the previous record is seen by purge view, we should treat it as missing history, because the disowned external data diff --git a/storage/maria/aria_pack.c b/storage/maria/aria_pack.c index f4368b99f99..8b5b5e19b71 100644 --- a/storage/maria/aria_pack.c +++ b/storage/maria/aria_pack.c @@ -3030,6 +3030,8 @@ static void flush_bits(void) int bits; ulonglong bit_buffer; + if (file_buffer.bits == BITS_SAVED) /* Nothing to write */ + return; bits= file_buffer.bits & ~7; bit_buffer= file_buffer.bitbucket >> bits; bits= BITS_SAVED - bits; diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 9d8d972e9f7..8af4835dfdb 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -3516,7 +3516,7 @@ my_bool translog_walk_filenames(const char *directory, for (i= 0; i < dirp->number_of_files; i++) { char *file= dirp->dir_entry[i].name; - if (strncmp(file, "aria_log.", 10) == 0 && + if (strncmp(file, "aria_log.", 9) == 0 && file[10] >= '0' && file[10] <= '9' && file[11] >= '0' && file[11] <= '9' && file[12] >= '0' && file[12] <= '9' && diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 624804767c8..ccdfbc43989 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -861,7 +861,8 @@ size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem, /* Allocate memory for cache page buffers */ pagecache->mem_size= blocks * pagecache->block_size; if ((pagecache->block_mem= - my_large_malloc(&pagecache->mem_size, MYF(MY_WME)))) + my_large_malloc(&pagecache->mem_size, + MYF(MY_WME) | my_large_pages_flag))) { /* Allocate memory for blocks, hash_links and hash entries; diff --git a/storage/maria/ma_range.c b/storage/maria/ma_range.c index cd8751cdd9a..ec2c27e27c8 100644 --- a/storage/maria/ma_range.c +++ b/storage/maria/ma_range.c @@ -20,6 +20,7 @@ #include "maria_def.h" #include "ma_rt_index.h" +#include "my_bit.h" static ha_rows _ma_record_pos(MARIA_HA *,const uchar *, key_part_map, enum ha_rkey_function, ulonglong *); @@ -143,11 +144,12 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key_data, key_buff= info->lastkey_buff+info->s->base.max_key_length; _ma_pack_key(info, &key, inx, key_buff, key_data, keypart_map, (HA_KEYSEG**) 0); + DBUG_ASSERT(key.keyinfo->keysegs); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, &key);); nextflag=maria_read_vec[search_flag]; /* Indicate if we're doing a search on a key prefix */ - if (((((key_part_map)1) << key.keyinfo->keysegs) - 1) != keypart_map) + if ((key_part_map) my_set_bits(key.keyinfo->keysegs) != keypart_map) nextflag |= SEARCH_PART_KEY; /* diff --git a/storage/mroonga/lib/mrn_count_skip_checker.cpp b/storage/mroonga/lib/mrn_count_skip_checker.cpp index cd22be31ef2..5b37601b08a 100644 --- a/storage/mroonga/lib/mrn_count_skip_checker.cpp +++ b/storage/mroonga/lib/mrn_count_skip_checker.cpp @@ -283,7 +283,7 @@ namespace mrn { } else { GRN_LOG(ctx_, GRN_LOG_DEBUG, "[mroonga][count-skip][false] " - "field's index are out of key part map: %u:%lu: <%s>:<%s>", + "field's index are out of key part map: %u:%u: <%s>:<%s>", i, target_key_part_map_, *(field->table_name), diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 6659011b6c5..b4cef753366 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -2939,6 +2939,9 @@ static void flush_bits(void) int bits; ulonglong bit_buffer; + if (file_buffer.bits == BITS_SAVED) /* Nothing to write */ + return; + bits= file_buffer.bits & ~7; if (bits != BITS_SAVED) { diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt index ddca7d156f3..30a8e82739a 100644 --- a/storage/rocksdb/CMakeLists.txt +++ b/storage/rocksdb/CMakeLists.txt @@ -11,6 +11,7 @@ at maximising storage efficiency while maintaining InnoDB-like performance." PAR MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-range-loop-construct) MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-invalid-offsetof) +MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-redundant-move) MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-effc++ DEBUG RELWITHDEBINFO) MACRO(SKIP_ROCKSDB_PLUGIN msg) diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 33b11170286..6d80985adba 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -8379,8 +8379,7 @@ bool ha_rocksdb::is_using_full_key(key_part_map keypart_map, uint actual_key_parts) { return (keypart_map == HA_WHOLE_KEY) || - (keypart_map == ((key_part_map(1) << actual_key_parts) - - 1)); + (keypart_map == make_prev_keypart_map(actual_key_parts)); } /* @@ -8555,9 +8554,8 @@ int ha_rocksdb::index_read_map_impl(uchar *const buf, const uchar *const key, if (active_index != table->s->primary_key && table->key_info[active_index].flags & HA_NOSAME && find_flag == HA_READ_KEY_EXACT && using_full_key) { - key_part_map tmp_map = (key_part_map(1) << table->key_info[active_index] - .user_defined_key_parts) - - 1; + key_part_map tmp_map = make_prev_keypart_map(table->key_info[active_index] + .user_defined_key_parts); packed_size = kd.pack_index_tuple(table, m_pack_buffer, m_sk_packed_tuple, m_record_buffer, key, tmp_map); if (table->key_info[active_index].user_defined_key_parts != diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index ea3d2978cf0..f524127d4c6 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -1389,8 +1389,8 @@ int spider_db_append_key_columns( start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", spider_user_defined_key_parts(key_info))); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); if (!start_key_part_map) DBUG_RETURN(0); @@ -1536,9 +1536,9 @@ int spider_db_append_key_where_internal( } DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", key_info ? spider_user_defined_key_parts(key_info) : 0)); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); - DBUG_PRINT("info", ("spider end_key_part_map=%lu", end_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); + DBUG_PRINT("info", ("spider end_key_part_map=%u", end_key_part_map)); #ifndef DBUG_OFF MY_BITMAP *tmp_map = dbug_tmp_use_all_columns(table, &table->read_set); @@ -1562,7 +1562,7 @@ int spider_db_append_key_where_internal( another_key = start_key; tgt_key_part_map = end_key_part_map; } - DBUG_PRINT("info", ("spider tgt_key_part_map=%lu", tgt_key_part_map)); + DBUG_PRINT("info", ("spider tgt_key_part_map=%u", tgt_key_part_map)); if (start_key_part_map == end_key_part_map) result_list->use_both_key = TRUE; @@ -1584,7 +1584,7 @@ int spider_db_append_key_where_internal( key_part++, key_count++ ) { - DBUG_PRINT("info", ("spider tgt_key_part_map=%lu", tgt_key_part_map)); + DBUG_PRINT("info", ("spider tgt_key_part_map=%u", tgt_key_part_map)); bool rev = key_part->key_part_flag & HA_REVERSE_SORT; store_length = key_part->store_length; field = key_part->field; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index c485b3f6b81..eb875d18c28 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -7789,8 +7789,8 @@ int spider_mbase_handler::append_key_column_types( start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", spider_user_defined_key_parts(key_info))); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); if (!start_key_part_map) DBUG_RETURN(0); @@ -7856,8 +7856,8 @@ int spider_mbase_handler::append_key_join_columns_for_bka( start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", spider_user_defined_key_parts(key_info))); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); if (!start_key_part_map) DBUG_RETURN(0); @@ -9515,8 +9515,8 @@ int spider_mbase_handler::append_key_column_values( start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", spider_user_defined_key_parts(key_info))); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); if (!start_key_part_map) DBUG_RETURN(0); @@ -9594,8 +9594,8 @@ int spider_mbase_handler::append_key_column_values_with_name( start_key_part_map = start_key->keypart_map & full_key_part_map; DBUG_PRINT("info", ("spider spider_user_defined_key_parts=%u", spider_user_defined_key_parts(key_info))); - DBUG_PRINT("info", ("spider full_key_part_map=%lu", full_key_part_map)); - DBUG_PRINT("info", ("spider start_key_part_map=%lu", start_key_part_map)); + DBUG_PRINT("info", ("spider full_key_part_map=%u", full_key_part_map)); + DBUG_PRINT("info", ("spider start_key_part_map=%u", start_key_part_map)); if (!start_key_part_map) DBUG_RETURN(0); diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index a51b534131f..430a16da5ce 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -361,13 +361,18 @@ void dispcset(FILE *f,CHARSET_INFO *cs) { fprintf(f,"{\n"); fprintf(f," %d,%d,%d,\n",cs->number,0,0); - fprintf(f," MY_CS_COMPILED%s%s%s%s%s%s,\n", + fprintf(f," MY_CS_COMPILED%s%s%s%s%s%s%s%s%s%s,\n", cs->state & MY_CS_BINSORT ? "|MY_CS_BINSORT" : "", cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "", cs->state & MY_CS_CSSORT ? "|MY_CS_CSSORT" : "", cs->state & MY_CS_PUREASCII ? "|MY_CS_PUREASCII" : "", cs->state & MY_CS_NONASCII ? "|MY_CS_NONASCII" : "", - cs->state & MY_CS_NOPAD ? "|MY_CS_NOPAD" : ""); + cs->state & MY_CS_NOPAD ? "|MY_CS_NOPAD" : "", + cs->state & MY_CS_ASCII_CASEUP_CI ? "|MY_CS_ASCII_CASEUP_CI" : "", + cs->state & MY_CS_IDENT_CASEUP_CI ? "|MY_CS_IDENT_CASEUP_CI" : "", + cs->state & MY_CS_DIGITS_STD ? "|MY_CS_DIGITS_STD" : "", + cs->state & MY_CS_ASCII_MINUS_DOT_DIGITS ? + "|MY_CS_ASCII_MINUS_DOT_DIGITS" : ""); if (cs->coll_name.str) { diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index dd9da47a5a1..e90dc35c81d 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -807,7 +807,8 @@ static MY_CASEFOLD_INFO my_casefold_big5= { 0xFFFF, my_casefold_pages_big5, - NULL /* ws */ + NULL, /* ws */ + FALSE }; @@ -6681,6 +6682,15 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)), } +/* + big5_chinese_ci and big5_chinese_nopad_ci have + an irregularity on the punctuation - the backtick + sign is sorted as equal to E: + Dd= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; +} + + +typedef struct +{ + uchar first; + uchar last; +} uchar_range_t; + +static const uchar_range_t range0_control_punct= {0x00,0x2F}; /* NULL.. '/' */ +static const uchar_range_t range1_digits= {0x30,0x39}; /* '0' .. '9' */ +static const uchar_range_t range2_punct= {0x3A,0x40}; /* ':' .. '@' */ +static const uchar_range_t range3_upper= {0x41,0x5A}; /* 'A' .. 'Z' */ +static const uchar_range_t range4_punct= {0x5B,0x60}; /* '[' .. '`' */ +static const uchar_range_t range6_punct= {0x7B,0x7F}; /* '{' .. DEL */ + + +static my_bool my_check_binary_order(CHARSET_INFO *cs, uint ch1, uint ch2) +{ + uint ch; + for (ch= ch1 + 1; ch <= ch2; ch++) + { + uint weight_prev= cs->sort_order[ch - 1]; + uint weight_curr= cs->sort_order[ch]; + if (weight_prev >= weight_curr) + { + return TRUE; + } + } + return FALSE; +} + + +static my_bool my_check_range_binary_order(CHARSET_INFO *cs, + const uchar_range_t range) +{ + return my_check_binary_order(cs, range.first, range.last); +} + + +static my_bool my_check_range2_order(CHARSET_INFO *cs, + const uchar_range_t range1, + const uchar_range_t range2) +{ + if (cs->sort_order[range1.last] < cs->sort_order[range2.first]) + return FALSE; + return TRUE; +} + + +static my_bool my_check_case_insensitive(CHARSET_INFO *cs) +{ + uint ch; + for (ch= 'a'; ch <= 'z'; ch++) + { + uint ch_upper= my_ascii_toupper(ch); + if (cs->sort_order[ch_upper] != cs->sort_order[ch]) + return TRUE; + } + return FALSE; +} + + + + +/* + Detect MY_CS_DIGITS_STD and MY_CS_ASCII_MINUS_DOT_DIGITS from sort_order: + - The digits are sorted in the code point order, and for PAD collations + the space sorts before the digits. + - The minus (0x2D) < the dot (0x2E) < the digits. + For PAD collations, the space sorts before the minus. + This does not depend on the order of the letters and on the case + sensitivity. It can be used for any collation having sort_order, + including multi-byte collations. +*/ +static uint my_8bit_collation_digit_flags_from_data(CHARSET_INFO *cs) +{ + uint flags= 0; + if (cs->sort_order && + ((cs->state & MY_CS_NOPAD) || + cs->sort_order[' '] < cs->sort_order[range1_digits.first]) && + !my_check_range_binary_order(cs, range1_digits)) + { + flags|= MY_CS_DIGITS_STD; + if (((cs->state & MY_CS_NOPAD) || + cs->sort_order[' '] < cs->sort_order['-']) && + cs->sort_order['-'] < cs->sort_order['.'] && + cs->sort_order['.'] < cs->sort_order[range1_digits.first]) + flags|= MY_CS_ASCII_MINUS_DOT_DIGITS; + } + return flags; +} + + /* Check if case sensitive sort order: A < a < B. We need MY_CS_FLAG for regex library, and for case sensitivity flag for 5.0 client protocol, - to support isCaseSensitive() method in JDBC driver + to support isCaseSensitive() method in JDBC driver. + + Also detect the MY_CS_ASCII_CASEUP_CI and MY_CS_IDENT_CASEUP_CI flags. + It's needed to return a collation tailoring + from cs->coll->tailoring(), for collation aggregation. + The flags are detected from the weights of the 7bit ASCII characters: + - The collation is case insensitive: weights of a-z are equal to + weights of A-Z. This alone does not tell the direction of the case + conversion, so it is not enough. + - The letters are sorted at the positions of the UPPER case letters, i.e. + digits < letters < underscore. This means that a-z are converted + to A-Z (a collation converting A-Z to a-z would sort letters after + the underscore, and would not pass this check). + This is checked by: + sort_order['9'] < sort_order['A'] and sort_order['Z'] < sort_order['_'] + together with the strictly increasing order of the digits and of A-Z. + - For PAD collations the space sorts before the digits, as the shorter + string is padded with spaces for comparison. + - For MY_CS_ASCII_CASEUP_CI, additionally all other ASCII characters + (control characters and punctuation) are sorted in the code point order + inside their own ranges, and the ranges are sorted in the code point + order relative to the digits and the letters. + If the first three conditions are satisfied, but the fourth one is not, + then only MY_CS_IDENT_CASEUP_CI is set (the order of the digits, letters + and the underscore is regular, punctuation can have irregularities). */ uint my_8bit_collation_flags_from_data(CHARSET_INFO *cs) { @@ -1533,6 +1654,57 @@ uint my_8bit_collation_flags_from_data(CHARSET_INFO *cs) if (cs->sort_order && cs->sort_order['A'] < cs->sort_order['a'] && cs->sort_order['a'] < cs->sort_order['B']) flags|= MY_CS_CSSORT; + + /* + If any of the flags describing the repertoires (CASEUP, DIGITS, + MINUS_DOT_DIGITS) is already set in cs->state, then it's a built-in + collation from ctype-extra.c, which has all the flags detected + by conf_to_src. No need to detect the flags again. + */ + if (cs->state & MY_CS_REPERTOIRE_FLAGS) + return flags; + + flags|= my_8bit_collation_digit_flags_from_data(cs); + + /* + If MY_CS_CSSORT is in "flags", then it can not be MY_CS_ASCII_CASEUP_CI + or MY_CS_IDENT_CASEUP_CI. + */ + if (cs->sort_order && + !(flags & MY_CS_CSSORT)) + { + if (cs->sort_order[range3_upper.last] < cs->sort_order[0x5F] && + /* + PAD collations pad a shorter string with spaces for comparison, + e.g. "ab" is compared to "abc" as "ab " to "abc". + So the space must sort before the digits and the letters, + even if the compared strings do not contain spaces. + */ + ((cs->state & MY_CS_NOPAD) || + cs->sort_order[' '] < cs->sort_order[range1_digits.first]) && + !my_check_range2_order(cs, range1_digits, range3_upper) && + !my_check_range_binary_order(cs, range1_digits) && + !my_check_range_binary_order(cs, range3_upper) && + !my_check_case_insensitive(cs)) + { + if (!my_check_range2_order(cs, range0_control_punct, range1_digits) && + !my_check_range2_order(cs, range1_digits, range2_punct) && + !my_check_range2_order(cs, range2_punct, range3_upper) && + !my_check_range2_order(cs, range3_upper, range4_punct) && + !my_check_range2_order(cs, range4_punct, range6_punct) && + !my_check_range_binary_order(cs, range0_control_punct) && + !my_check_range_binary_order(cs, range2_punct) && + !my_check_range_binary_order(cs, range4_punct) && + !my_check_range_binary_order(cs, range6_punct)) + { + flags|= MY_CS_ASCII_CASEUP_CI; + } + else + { + flags|= MY_CS_IDENT_CASEUP_CI; + } + } + } return flags; } @@ -2186,6 +2358,13 @@ my_strxfrm_pad_desc_and_reverse_nopad(CHARSET_INFO *cs, } +static LEX_CSTRING my_tailoring_8bit(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + return my_tailoring_simple_ci_by_flags(repertoire, self->state); +} + + MY_CHARSET_HANDLER my_charset_8bit_handler= { my_cset_init_8bit, @@ -2236,7 +2415,8 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler = my_max_str_8bit_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_8bit }; @@ -2257,5 +2437,6 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_nopad_ci_handler = my_max_str_8bit_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_8bit }; diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index ce839e025fe..500dc78d7d8 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -1077,7 +1077,8 @@ static MY_CASEFOLD_INFO my_casefold_sjis= { 0xFFFF, my_casefold_pages_sjis, - NULL /* ws */ + NULL, /* ws */ + FALSE }; @@ -34017,6 +34018,30 @@ my_wc_to_printable_sjis(CHARSET_INFO *cs, my_wc_t wc, } +/* + sjis_bin and sjis_nopad_bin reorder ASCII punctuation characters + over _bin collations. + So a special virtual function is needed. +*/ +/* + No irregularities on the ALNUM and IDENT ranges. + ASCII punctuation characters are reordered. +*/ +static LEX_CSTRING my_tailoring_sjis_bin(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_AZ_az, /* ALNUM */ + my_tailoring_str_ident_09_AZ_underscore_az, /* IDENT */ + {0,0} /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + /* sjis_chinese_ci and sjis_bin sort character blocks in this order: 1. [00..7F] - 7BIT characters (ASCII) @@ -34075,7 +34100,8 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_japanese_ci= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ident_caseup_ci_generic }; @@ -34096,7 +34122,8 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_bin= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_sjis_bin }; @@ -34117,7 +34144,8 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_japanese_nopad_ci= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ident_caseup_ci_generic }; @@ -34138,7 +34166,8 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_nopad_bin= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_sjis_bin }; diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index a4fab9ed4fc..afbbcf9ac53 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -890,6 +890,19 @@ int my_wc_mb_tis620(CHARSET_INFO *cs __attribute__((unused)), } +/* + tis620_thai_ci and tis620_thai_nopad_ci fold upper case letters + to lower case and then compare by the code point on the entire ASCII range. + Thai specific rules (leading vowels, level 2 characters) affect + only non-ASCII characters. +*/ +static LEX_CSTRING my_tailoring_tis620_thai_ci(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + return my_tailoring_ascii_casedn_ci(repertoire); +} + + static MY_COLLATION_HANDLER my_collation_ci_handler = { NULL, /* init */ @@ -907,7 +920,8 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_max_str_8bit_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_tis620_thai_ci }; static MY_COLLATION_HANDLER my_collation_nopad_ci_handler = @@ -927,7 +941,8 @@ static MY_COLLATION_HANDLER my_collation_nopad_ci_handler = my_max_str_8bit_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_tis620_thai_ci }; static MY_CHARSET_HANDLER my_charset_handler= @@ -978,7 +993,7 @@ struct charset_info_st my_charset_tis620_thai_ci= to_upper_tis620, sort_order_tis620, NULL, /* uca */ - NULL, /* tab_to_uni */ + cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ NULL, /* casefold */ NULL, /* state_map */ @@ -1008,7 +1023,7 @@ struct charset_info_st my_charset_tis620_bin= to_upper_tis620, NULL, /* sort_order */ NULL, /* uca */ - NULL, /* tab_to_uni */ + cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ NULL, /* casefold */ NULL, /* state_map */ @@ -1039,7 +1054,7 @@ struct charset_info_st my_charset_tis620_thai_nopad_ci= to_upper_tis620, sort_order_tis620, NULL, /* uca */ - NULL, /* tab_to_uni */ + cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ NULL, /* casefold */ NULL, /* state_map */ @@ -1070,7 +1085,7 @@ struct charset_info_st my_charset_tis620_nopad_bin= to_upper_tis620, NULL, /* sort_order */ NULL, /* uca */ - NULL, /* tab_to_uni */ + cs_to_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ NULL, /* casefold */ NULL, /* state_map */ diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index fd09c72c836..5a3dca31aca 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -32659,6 +32659,9 @@ typedef struct my_coll_rules_st MY_COLL_RULE *rule; /* Rule array */ MY_CHARSET_LOADER *loader; my_coll_shift_method shift_after_method; + my_bool with_anomalies_on_ascii_range; + my_bool with_anomalies_on_digits; + my_bool with_anomalies_on_dot_minus; } MY_COLL_RULES; @@ -32686,6 +32689,34 @@ my_coll_rules_realloc(MY_COLL_RULES *rules, size_t n) } +/** + Check if a rule touches the ASCII range, and its parts, + and set the corresponding flags in the rule container: + - with_anomalies_on_ascii_range: any character in U+0000..U+007F + - with_anomalies_on_digits: any of the digits 0..9 + - with_anomalies_on_dot_minus: any of the dot (.) and the minus (-) + A contraction is checked character by character. +*/ +static void +my_coll_rules_check_ascii_anomalies(MY_COLL_RULES *rules, + const MY_COLL_RULE *rule) +{ + uint j; + DBUG_ASSERT(array_elements(rule->curr) == MY_UCA_MAX_CONTRACTION); + for (j= 0 ; j < array_elements(rule->curr) && rule->curr[j]; j++) + { + my_wc_t wc= rule->curr[j]; + if (wc > 0x007F) + continue; + rules->with_anomalies_on_ascii_range= TRUE; + if (wc >= '0' && wc <= '9') + rules->with_anomalies_on_digits= TRUE; + else if (wc == '.' || wc == '-') + rules->with_anomalies_on_dot_minus= TRUE; + } +} + + /** Append one new rule to a rule array @@ -32701,6 +32732,7 @@ my_coll_rules_add(MY_COLL_RULES *rules, MY_COLL_RULE *rule) if (my_coll_rules_realloc(rules, rules->nrules + 1)) return -1; rules->rule[rules->nrules++]= rule[0]; + my_coll_rules_check_ascii_anomalies(rules, rule); return 0; } @@ -34779,6 +34811,14 @@ create_tailoring(struct charset_info_st *cs, else if (!cs->levels_for_order) my_ci_set_strength(cs, 1); + if (!rules.with_anomalies_on_ascii_range) + cs->state|= MY_CS_ASCII_STD_UCA; + if (!rules.with_anomalies_on_digits) + { + cs->state|= MY_CS_DIGITS_STD; + if (!rules.with_anomalies_on_dot_minus) + cs->state|= MY_CS_ASCII_MINUS_DOT_DIGITS; + } if (my_collation_id_is_mysql_uca0900(cs->number)) { @@ -39426,4 +39466,73 @@ LEX_CSTRING my_ci_get_collation_name_uca(CHARSET_INFO *cs, return cs->coll_name; } + +static LEX_CSTRING my_tailoring_uca_ci(my_repertoire_t repertoire) +{ + static const LEX_CSTRING ascii_uca_ci= + {STRING_WITH_LEN("ascii7_uca_ci")}; + + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_AaZz_ci, /* ALNUM */ + my_tailoring_str_ident_underscore_09_AaZz_ci, /* IDENT */ + ascii_uca_ci /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +static LEX_CSTRING my_tailoring_uca_cs(my_repertoire_t repertoire) +{ + static const LEX_CSTRING ascii_uca_cs= + {STRING_WITH_LEN("ascii7_uca_cs")}; + + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_aAzZ3_cs, /* ALNUM */ + my_tailoring_str_ident_underscore_09_aAzZ3_cs, /* IDENT */ + ascii_uca_cs /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +/* + Detect a correct tailoring of a UCA collation taking into account: + - The requested repertoire + - Anomalies on the ASCII range + - Case sensitivity + + The PAD/NOPAD attribute and the UCA version are not taken into account: + the returned tailoring does not depend on them. The caller, + DTCollation::aggregate_by_tailoring(), compares MY_CS_NOPAD of the + collations, and the UCA versions on the repertoires with punctuation. +*/ + +LEX_CSTRING my_tailoring_uca(CHARSET_INFO *cs, my_repertoire_t repertoire) +{ + if (repertoire != MY_REPERTOIRE_NONE && + !(cs->state & MY_CS_ASCII_STD_UCA)) + { + /* + Anomalies on the ASCII letter range. + The digits can still be sorted in the standard way. + */ + return my_tailoring_by_digit_flags(repertoire, cs->state); + } + + /* + In UCA case sensitive collations case difference is + on the third (tertiary) level. If MY_STRXFRM_LEVEL3 is not given in + levels_for_order, then we have a case insensitive collation. + */ + return (cs->levels_for_order & MY_STRXFRM_LEVEL3) ? + my_tailoring_uca_cs(repertoire) : + my_tailoring_uca_ci(repertoire); +} + #endif /* HAVE_UCA_COLLATIONS */ diff --git a/strings/ctype-uca.h b/strings/ctype-uca.h index 8b6e3f71ef0..b14f5adce4e 100644 --- a/strings/ctype-uca.h +++ b/strings/ctype-uca.h @@ -193,4 +193,6 @@ LEX_CSTRING my_ci_get_collation_name_uca(CHARSET_INFO *cs, my_collation_name_mode_t mode); +LEX_CSTRING my_tailoring_uca(CHARSET_INFO *self, my_repertoire_t repertoire); + #endif /* CTYPE_UCA_H */ diff --git a/strings/ctype-uca.inl b/strings/ctype-uca.inl index 471ae8595ac..97eee225858 100644 --- a/strings/ctype-uca.inl +++ b/strings/ctype-uca.inl @@ -1029,7 +1029,8 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler)= my_max_str_mb_simple, my_ci_get_id_uca, my_ci_get_collation_name_uca, - my_ci_eq_collation_uca + my_ci_eq_collation_uca, + my_tailoring_uca }; @@ -1055,7 +1056,8 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_nopad)= my_max_str_mb_simple, my_ci_get_id_uca, my_ci_get_collation_name_uca, - my_ci_eq_collation_uca + my_ci_eq_collation_uca, + my_tailoring_uca }; @@ -1079,7 +1081,8 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_multilevel)= my_max_str_mb_simple, my_ci_get_id_uca, my_ci_get_collation_name_uca, - my_ci_eq_collation_uca + my_ci_eq_collation_uca, + my_tailoring_uca }; @@ -1103,7 +1106,8 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_nopad_multilevel)= my_max_str_mb_simple, my_ci_get_id_uca, my_ci_get_collation_name_uca, - my_ci_eq_collation_uca + my_ci_eq_collation_uca, + my_tailoring_uca }; diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 6321081c813..8cc608bfb82 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1502,7 +1502,8 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -1523,7 +1524,8 @@ static MY_COLLATION_HANDLER my_collation_utf16_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -1544,7 +1546,8 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -1565,7 +1568,8 @@ static MY_COLLATION_HANDLER my_collation_utf16_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -1853,7 +1857,8 @@ static MY_COLLATION_HANDLER my_collation_utf16le_general_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -1874,7 +1879,8 @@ static MY_COLLATION_HANDLER my_collation_utf16le_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -1895,7 +1901,8 @@ static MY_COLLATION_HANDLER my_collation_utf16le_general_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -1916,7 +1923,8 @@ static MY_COLLATION_HANDLER my_collation_utf16le_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -2630,7 +2638,8 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -2651,7 +2660,8 @@ static MY_COLLATION_HANDLER my_collation_utf32_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -2672,7 +2682,8 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -2693,7 +2704,8 @@ static MY_COLLATION_HANDLER my_collation_utf32_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -3195,7 +3207,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -3216,7 +3229,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_mysql500_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -3237,7 +3251,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -3258,7 +3273,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -3279,7 +3295,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index cb72ca19664..251dc13b71b 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67141,7 +67141,8 @@ static MY_CASEFOLD_INFO my_casefold_info_ujis= { 0x0FFFF, my_casefold_pages_ujis, - NULL /* ws */ + NULL, /* ws */ + FALSE }; @@ -67261,7 +67262,8 @@ static MY_COLLATION_HANDLER my_collation_ujis_japanese_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -67282,7 +67284,8 @@ static MY_COLLATION_HANDLER my_collation_ujis_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -67303,7 +67306,8 @@ static MY_COLLATION_HANDLER my_collation_ujis_japanese_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -67324,7 +67328,8 @@ static MY_COLLATION_HANDLER my_collation_ujis_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; diff --git a/strings/ctype-unidata.c b/strings/ctype-unidata.c index 77bec5418c4..70535d42932 100644 --- a/strings/ctype-unidata.c +++ b/strings/ctype-unidata.c @@ -40,7 +40,8 @@ MY_CASEFOLD_INFO my_casefold_default= { 0xFFFF, my_u300_casefold_index, - weight_general_ci_index + weight_general_ci_index, + FALSE }; @@ -56,7 +57,8 @@ MY_CASEFOLD_INFO my_casefold_turkish= { 0xFFFF, my_u300tr_casefold_index, - weight_general_ci_index + weight_general_ci_index, + TRUE }; @@ -68,7 +70,8 @@ MY_CASEFOLD_INFO my_casefold_mysql500= { 0xFFFF, my_u300_casefold_index, - weight_general_mysql500_ci_index + weight_general_mysql500_ci_index, + FALSE }; @@ -77,7 +80,8 @@ MY_CASEFOLD_INFO my_casefold_unicode520= { 0x10FFFF, my_u520_casefold_index, - NULL + NULL, + FALSE }; @@ -85,7 +89,8 @@ MY_CASEFOLD_INFO my_casefold_unicode1400= { 0x10FFFF, my_u1400_casefold_index, - NULL + NULL, + FALSE }; @@ -93,5 +98,6 @@ MY_CASEFOLD_INFO my_casefold_unicode1400tr= { 0x10FFFF, my_u1400tr_casefold_index, - NULL + NULL, + TRUE }; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 527d880f6d3..4e1ef7b5daa 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -865,7 +865,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general1400_as_ci_handler= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -918,7 +919,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -939,7 +941,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_mysql500_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -960,7 +963,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -981,7 +985,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_nopad_ci_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -1002,7 +1007,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_bin_generic }; @@ -1357,7 +1363,10 @@ static MY_COLLATION_HANDLER my_collation_cs_handler = my_propagate_simple, my_min_str_mb_simple, my_max_str_mb_simple, - my_ci_eq_collation_generic + my_ci_get_id_generic, + my_ci_get_collation_name_generic, + my_ci_eq_collation_generic, + my_tailoring_none }; struct charset_info_st my_charset_utf8mb3_general_cs= @@ -2676,7 +2685,8 @@ static MY_COLLATION_HANDLER my_collation_filename_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_none }; static MY_CHARSET_HANDLER my_charset_filename_handler= @@ -3125,7 +3135,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_general_ci_handler= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -3146,7 +3157,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_utf8mb4_bin + my_ci_eq_collation_utf8mb4_bin, + my_tailoring_bin_generic }; @@ -3167,7 +3179,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_general_nopad_ci_handler= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; @@ -3188,7 +3201,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_nopad_bin_handler = my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_utf8mb4_bin + my_ci_eq_collation_utf8mb4_bin, + my_tailoring_bin_generic }; @@ -3285,7 +3299,8 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_general1400_as_ci_handler= my_max_str_mb_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_ascii_caseup_ci_generic }; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 257c206db5d..dae1ca5023d 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -694,6 +694,18 @@ my_like_range_win1250ch(CHARSET_INFO *cs __attribute__((unused)), } +/* + cp1250_czech_cs: the minus, the dot and the digits are sorted + in the code point order (verified on strings made of them and spaces), + even though the letters are sorted by the Czech multi-pass algorithm. +*/ +static LEX_CSTRING my_tailoring_cp1250_czech_cs(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + return my_tailoring_by_digit_flags(repertoire, MY_CS_ASCII_MINUS_DOT_DIGITS); +} + + static MY_COLLATION_HANDLER my_collation_czech_cs_handler = { NULL, /* init */ @@ -711,7 +723,8 @@ static MY_COLLATION_HANDLER my_collation_czech_cs_handler = my_max_str_8bit_simple, my_ci_get_id_generic, my_ci_get_collation_name_generic, - my_ci_eq_collation_generic + my_ci_eq_collation_generic, + my_tailoring_cp1250_czech_cs }; diff --git a/strings/ctype.c b/strings/ctype.c index 052452c169e..85f4068afc6 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -843,27 +843,53 @@ my_parse_charset_xml(MY_CHARSET_LOADER *loader, const char *buf, size_t len) } +/* + Return a repertoire the given character belongs to. +*/ +static inline uint my_uint_repertoire_generic(uint ch) +{ + if (ch > 0x7F) + return MY_REPERTOIRE_EXTENDED; + if (ch >= 'A' && ch <= 'Z') + return MY_REPERTOIRE_ASCII_LETTERS_UPPER; + if (ch >= 'a' && ch <= 'z') + return MY_REPERTOIRE_ASCII_LETTERS_LOWER; + if (ch >= '0' && ch <= '9') + return MY_REPERTOIRE_ASCII_DIGITS; + if (ch == '_') + return MY_REPERTOIRE_ASCII_UNDERSCORE; + if (ch == '.') + return MY_REPERTOIRE_ASCII_DOT; + if (ch == '-') + return MY_REPERTOIRE_ASCII_MINUS; + return MY_REPERTOIRE_ASCII_NOT_IDENT; +} + + uint my_string_repertoire_8bit(CHARSET_INFO *cs, const char *str, size_t length) { const char *strend; + uint res= 0; if ((cs->state & MY_CS_NONASCII) && length > 0) return MY_REPERTOIRE_UNICODE30; if (!str) // Avoid UBSAN nullptr-with-offset - return MY_REPERTOIRE_ASCII; + return MY_REPERTOIRE_NONE; for (strend= str + length; str < strend; str++) { - if (((uchar) *str) > 0x7F) - return MY_REPERTOIRE_UNICODE30; + uint byte_repertoire= my_uint_repertoire_generic((uchar) *str); + res|= byte_repertoire; + if (res == MY_REPERTOIRE_UNICODE30) + return res; } - return MY_REPERTOIRE_ASCII; + return res; } static void my_string_metadata_init(MY_STRING_METADATA *metadata) { - metadata->repertoire= MY_REPERTOIRE_ASCII; + metadata->repertoire= MY_REPERTOIRE_NONE; metadata->char_length= 0; } @@ -885,8 +911,8 @@ my_string_metadata_get_mb(MY_STRING_METADATA *metadata, int mblen= my_ci_mb_wc(cs, &wc, (const uchar *) str, (const uchar *) strend); if (mblen > 0) /* Assigned character */ { - if (wc > 0x7F) - metadata->repertoire|= MY_REPERTOIRE_EXTENDED; + uint wc_repertoire= my_uint_repertoire_generic((uint) wc); + metadata->repertoire|= wc_repertoire; str+= mblen; } else if (mblen == MY_CS_ILSEQ) /* Bad byte sequence */ @@ -933,6 +959,7 @@ my_string_metadata_get(MY_STRING_METADATA *metadata, my_repertoire_t my_string_repertoire(CHARSET_INFO *cs, const char *str, size_t length) { + uint res= 0; if (cs->mbminlen == 1 && !(cs->state & MY_CS_NONASCII)) { return my_string_repertoire_8bit(cs, str, length); @@ -942,15 +969,28 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, size_t length) const char *strend= str + length; my_wc_t wc; int chlen; - for (; - (chlen= my_ci_mb_wc(cs, &wc, (uchar*) str, (uchar*) strend)) > 0; - str+= chlen) + uint wc_repertoire; + for (; str < strend; str+= chlen) { - if (wc > 0x7F) - return MY_REPERTOIRE_UNICODE30; + chlen= my_ci_mb_wc(cs, &wc, (uchar*) str, (uchar*) strend); + if (chlen <= 0) + { + /* + A bad byte sequence, an unassigned character, + or an incomplete character at the end of the string. + Do not stop with the repertoire found so far, which can even be + MY_REPERTOIRE_NONE (compatible with everything): the rest of + the string is unknown, so it can contain any characters. + */ + return (my_repertoire_t) (res | MY_REPERTOIRE_EXTENDED); + } + wc_repertoire= my_uint_repertoire_generic((uint) wc); + res|= wc_repertoire; + if (res == MY_REPERTOIRE_UNICODE30) + return res; } } - return MY_REPERTOIRE_ASCII; + return res; } @@ -1431,6 +1471,37 @@ my_bool my_ci_eq_collation_generic(CHARSET_INFO *self, CHARSET_INFO *other) } +/* + A tailoring() handler for collations which cannot be proven compatible + with any other collation on any non-empty repertoire. + It returns the null tailoring {0,0} for every repertoire except + MY_REPERTOIRE_NONE. On the empty repertoire there are no characters + to disagree on, so it returns the shared empty-repertoire tailoring. +*/ +LEX_CSTRING my_tailoring_none(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + const LEX_CSTRING res={0,0}; + if (repertoire == MY_REPERTOIRE_NONE) + return my_tailoring_str_empty; + return res; +} + + +LEX_CSTRING my_tailoring_bin_generic(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_AZ_az, /* ALNUM */ + my_tailoring_str_ident_09_AZ_underscore_az, /* IDENT */ + my_tailoring_str_ascii_bin /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + /* Allocate a memory block for a new charset_info_st together with its name and its comment in a single once_alloc() call. @@ -1461,3 +1532,245 @@ struct charset_info_st *my_ci_alloc(MY_CHARSET_LOADER *loader, return csinfo; } + + +/* + The empty repertoire (MY_REPERTOIRE_NONE) has no characters to disagree + on, so any two collations are trivially compatible on it. Every + my_collation_handler_st::tailoring() implementation returns this shared + singleton for MY_REPERTOIRE_NONE, regardless of how incompatible + the two collations otherwise are. +*/ +const LEX_CSTRING my_tailoring_str_empty= + {STRING_WITH_LEN("")}; + + +/*** ASCII digits repertoire ***/ + +/* + Collations with MY_CS_DIGITS_STD, including those which have irregular + order of the letters: the digits 0..9 are sorted in the code point order. +*/ +const LEX_CSTRING my_tailoring_str_digits= + {STRING_WITH_LEN("[digit7]")}; + + +/*** ASCII minus, dot and digits repertoire ***/ + +const LEX_CSTRING my_tailoring_str_minus_dot_digits= + {STRING_WITH_LEN("-<.<[digit7]")}; + + +/*** ALNUM repertoires ***/ + +/* Most _ci collations - both UCA and non-UCA */ +const LEX_CSTRING my_tailoring_str_alnum_09_AaZz_ci= + {STRING_WITH_LEN("[digit7]<[letter7_ci]")}; + + +/* + Most UCA case sensitive _cs collations: + case difference of the third level with lower letter preference +*/ +const LEX_CSTRING my_tailoring_str_alnum_09_aAzZ3_cs= + {STRING_WITH_LEN("[digit7]<[letter7_cs3_LowerFirst]")}; + +/* Most _bin collations */ +const LEX_CSTRING my_tailoring_str_alnum_09_AZ_az= + {STRING_WITH_LEN("[digit7]<[upper7]<[lower7]")}; + + +/*** IDENT repertoires ***/ + +/* Most UCA _ci collations */ +const LEX_CSTRING my_tailoring_str_ident_underscore_09_AaZz_ci= + {STRING_WITH_LEN("_<[digit7]<[letter7_ci]")}; + +/* + Most UCA case sensitive _cs collations: + case difference of the third level with lower letter preference +*/ +const LEX_CSTRING my_tailoring_str_ident_underscore_09_aAzZ3_cs= + {STRING_WITH_LEN("_<[digit7]<[letter7_cs3_LowerFirst]")}; + +/* Most non-UCA _ci collations */ +const LEX_CSTRING my_tailoring_str_ident_09_AaZz_ci_underscore= + {STRING_WITH_LEN("[digit7]<[letter7_ci]<_")}; + +/* Collations folding to lower case, e.g. tis620_thai_ci */ +const LEX_CSTRING my_tailoring_str_ident_09_underscore_AaZz_ci= + {STRING_WITH_LEN("[digit7]<_<[letter7_ci]")}; + +/* Most _bin collations */ +const LEX_CSTRING my_tailoring_str_ident_09_AZ_underscore_az= + {STRING_WITH_LEN("[digit7]<[upper7]<_<[lower7]")}; + +/*** ASCII repertoires ***/ +const LEX_CSTRING my_tailoring_str_ascii_caseup_ci= + {STRING_WITH_LEN("ascii7_caseup_ci")}; + +const LEX_CSTRING my_tailoring_str_ascii_casedn_ci= + {STRING_WITH_LEN("ascii7_casedn_ci")}; + +const LEX_CSTRING my_tailoring_str_ascii_bin= + {STRING_WITH_LEN("ascii7_bin")}; + + +/*** Repertoires for simple collations ***/ +static LEX_CSTRING my_tailoring_ascii_caseup_ci(my_repertoire_t repertoire) +{ + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_AaZz_ci, /* ALNUM */ + my_tailoring_str_ident_09_AaZz_ci_underscore, /* IDENT */ + my_tailoring_str_ascii_caseup_ci /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +/* + A tailoring for collations which fold upper case letters to lower case + and then compare by the code point on the entire ASCII range, + e.g. tis620_thai_ci. Unlike caseup collations, punctuation between + the upper and the lower letters ([ \ ] ^ _ `) sorts before the letters. +*/ +LEX_CSTRING my_tailoring_ascii_casedn_ci(my_repertoire_t repertoire) +{ + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + my_tailoring_str_minus_dot_digits, /* MINUS_DOT_DIGITS */ + my_tailoring_str_alnum_09_AaZz_ci, /* ALNUM */ + my_tailoring_str_ident_09_underscore_AaZz_ci, /* IDENT */ + my_tailoring_str_ascii_casedn_ci /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +static LEX_CSTRING my_tailoring_ident_caseup_ci(my_repertoire_t repertoire, + uint flags) +{ + const LEX_CSTRING nl= {0,0}; + const MY_TAILORING_SET set= + { + my_tailoring_str_digits, /* DIGITS */ + /* MINUS_DOT_DIGITS: irregularities are possible on ASCII punctuation */ + (flags & MY_CS_ASCII_MINUS_DOT_DIGITS) ? + my_tailoring_str_minus_dot_digits : nl, + my_tailoring_str_alnum_09_AaZz_ci, /* ALNUM */ + my_tailoring_str_ident_09_AaZz_ci_underscore, /* IDENT */ + nl /* ASCII: Irregularities are possible on ASCII punctuation */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +/* + A tailoring for collations which are known to sort the digits 0..9 + regularly (MY_CS_DIGITS_STD), and optionally the minus and the dot + (MY_CS_ASCII_MINUS_DOT_DIGITS), but have no tailorings on wider + repertoires. +*/ +LEX_CSTRING my_tailoring_by_digit_flags(my_repertoire_t repertoire, uint flags) +{ + const LEX_CSTRING nl= {0,0}; + const MY_TAILORING_SET set= + { + (flags & (MY_CS_DIGITS_STD | MY_CS_ASCII_MINUS_DOT_DIGITS)) ? + my_tailoring_str_digits : nl, /* DIGITS */ + /* MINUS_DOT_DIGITS */ + (flags & MY_CS_ASCII_MINUS_DOT_DIGITS) ? + my_tailoring_str_minus_dot_digits : nl, + nl, /* ALNUM */ + nl, /* IDENT */ + nl /* ASCII */ + }; + return my_tailoring_by_set_and_repertoire(&set, repertoire); +} + + +LEX_CSTRING my_tailoring_simple_ci_by_flags(my_repertoire_t repertoire, + uint flags) +{ + const LEX_CSTRING nl= {0,0}; + if (flags & MY_CS_ASCII_CASEUP_CI) + return my_tailoring_ascii_caseup_ci(repertoire); + if (flags & MY_CS_IDENT_CASEUP_CI) + return my_tailoring_ident_caseup_ci(repertoire, flags); + if (flags & (MY_CS_DIGITS_STD | MY_CS_ASCII_MINUS_DOT_DIGITS)) + return my_tailoring_by_digit_flags(repertoire, flags); + if (repertoire == MY_REPERTOIRE_NONE) + return my_tailoring_str_empty; + return nl; +} + + +/* + Check if two collations compare strings consisting of characters + of the given repertoire in the same way, so they can be mutually + replaced in a comparison operator. + + Equal tailorings are necessary, but not sufficient: + - PAD and NOPAD collations compare trailing spaces differently. + - The order of ASCII punctuation depends on the UCA version + (e.g. UCA-6.2.0 moved GRAVE ACCENT and CIRCUMFLEX ACCENT + after PERCENT SIGN). So UCA collations of different versions are + not compatible on the repertoire which includes this punctuation. + The version is not a part of the tailoring string. + + @return 0 The collations are not known to be equal on the repertoire + @return 1 The collations are equal on the repertoire +*/ +my_bool my_collations_equal_on_repertoire(CHARSET_INFO *cs1, CHARSET_INFO *cs2, + my_repertoire_t repertoire) +{ + LEX_CSTRING t1, t2; + if ((cs1->state & MY_CS_NOPAD) != (cs2->state & MY_CS_NOPAD)) + return FALSE; + if (!my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII_IDENT) && + cs1->uca && cs2->uca && cs1->uca->version != cs2->uca->version) + return FALSE; + t1= (cs1->coll->tailoring)(cs1, repertoire); + t2= (cs2->coll->tailoring)(cs2, repertoire); + return t1.str && t2.str && t1.str == t2.str; +} + + +/* + A tailoring() handler for collations (e.g. multibyte or Unicode + *_general_ci) which do not have MY_CS_ASCII_CASEUP_CI in CHARSET_INFO::state + but are known to have no irregularities on the ASCII repertoire. + The flag is supplied here, on behalf of the collation, rather than + taken from self->state. +*/ +LEX_CSTRING my_tailoring_ascii_caseup_ci_generic(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + return my_tailoring_simple_ci_by_flags(repertoire, MY_CS_ASCII_CASEUP_CI); +} + + +/* + Like my_tailoring_ascii_caseup_ci_generic(), but for collations which + are known to have no irregularities on the IDENT repertoire only + (but possibly have irregularities on ASCII punctuation), + e.g. big5_chinese_ci, gbk_chinese_ci, gb2312_chinese_ci. + Supplies MY_CS_IDENT_CASEUP_CI. + These collations also sort the minus, the dot and the digits in the code + point order (MY_CS_ASCII_MINUS_DOT_DIGITS, MY_CS_DIGITS_STD), + so these flags are supplied too. This is checked by the func_test + test ctype_digits_verify. Do not use this handler for a collation + which does not sort -.0123456789 in this way. +*/ +LEX_CSTRING my_tailoring_ident_caseup_ci_generic(CHARSET_INFO *self, + my_repertoire_t repertoire) +{ + return my_tailoring_simple_ci_by_flags(repertoire, + MY_CS_IDENT_CASEUP_CI | + MY_CS_DIGITS_STD | + MY_CS_ASCII_MINUS_DOT_DIGITS); +} diff --git a/strings/json_normalize.c b/strings/json_normalize.c index 6852251cbfb..2722e4b4ff6 100644 --- a/strings/json_normalize.c +++ b/strings/json_normalize.c @@ -1165,7 +1165,7 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *curre json_norm_parse_end: dynstr_free(&key); - return err; + return err || je->s.error; } static int @@ -1201,6 +1201,10 @@ json_norm_build(struct json_norm_value *root, return err; } } + else + { + while(json_scan_next(je) == 0) /*no-op*/; + } return err; } @@ -1253,15 +1257,10 @@ json_normalize(DYNAMIC_STRING *result, in_size= strlen(s_utf8); } - - if ((json_valid(in, in_size, &my_charset_utf8mb4_bin, temp_je) == 0)) - { - err= 1; - goto json_normalize_end; - } - err= json_norm_build(&root, in, in_size, &my_charset_utf8mb4_bin, current_mem_root, temp_je, stack); + if (root.type == JSON_VALUE_UNINITIALIZED || temp_je->s.error) + err= 1; if (err) goto json_normalize_end; diff --git a/strings/strings_def.h b/strings/strings_def.h index 62b27ba5e7e..e1136a023d5 100644 --- a/strings/strings_def.h +++ b/strings/strings_def.h @@ -197,6 +197,16 @@ my_strxfrm_pad_desc_and_reverse_nopad(CHARSET_INFO *cs, uint my_8bit_charset_flags_from_data(CHARSET_INFO *cs); uint my_8bit_collation_flags_from_data(CHARSET_INFO *cs); +/* + The flags which tell about the order of ASCII characters. + They are detected by my_8bit_collation_flags_from_data(), and stored + in ctype-extra.c for compiled collations. +*/ +#define MY_CS_REPERTOIRE_FLAGS (MY_CS_ASCII_CASEUP_CI | \ + MY_CS_IDENT_CASEUP_CI | \ + MY_CS_DIGITS_STD | \ + MY_CS_ASCII_MINUS_DOT_DIGITS) + /* Macros for hashing characters */ @@ -246,6 +256,12 @@ uint my_casefold_multiply_2(CHARSET_INFO *cs); my_bool my_ci_eq_collation_generic(CHARSET_INFO *self, CHARSET_INFO *other); +LEX_CSTRING my_tailoring_none(CHARSET_INFO *self, + my_repertoire_t repertoire); + +LEX_CSTRING my_tailoring_bin_generic(CHARSET_INFO *self, + my_repertoire_t repertoire); + struct charset_info_st *my_ci_alloc(MY_CHARSET_LOADER *loader, const LEX_CSTRING name, LEX_CSTRING *out_name, @@ -266,4 +282,142 @@ extern const char charset_name_ucs2[]; extern const char charset_name_utf8mb4[]; #define charset_name_utf8mb4_length 7 + +/* + Some common tailoring strings for tailoring based optimization. + Used inside my_collation_handler_st::tailoring() virtual functions. + See comments in /include/m_ctype.h near the "tailoring" function declaration. + + Tailorings are compared by the pointer value of the string, + so tailoring() implementations in strings/ must return these constants. + The declarations below can be moved to m_ctype.h later, when + implementations outside of strings/ need these constants. + Tailoring strings do not depend on PAD/NOPAD: the collations with + different MY_CS_NOPAD are never considered compatible by the caller. +*/ +/* Tailoring strings for the empty (MY_REPERTOIRE_NONE) repertoire */ +extern const LEX_CSTRING my_tailoring_str_empty; + + +/*** Tailoring strings for the ASCII digits repertoire */ + +/* All collations with MY_CS_DIGITS_STD: digits 0..9 in the code point order */ +extern const LEX_CSTRING my_tailoring_str_digits; + + +/*** Tailoring strings for the ASCII minus, dot and digits repertoire */ + +/* + All collations with MY_CS_ASCII_MINUS_DOT_DIGITS: + the minus < the dot < the digits 0..9 in the code point order +*/ +extern const LEX_CSTRING my_tailoring_str_minus_dot_digits; + + +/*** Tailoring strings for ALNUM repertoires */ + +/* Most _ci collations - both UCA and non-UCA */ +extern const LEX_CSTRING my_tailoring_str_alnum_09_AaZz_ci; + +/* Most UCA case sensitive collations */ +extern const LEX_CSTRING my_tailoring_str_alnum_09_aAzZ3_cs; + +/* Most _bin collations */ +extern const LEX_CSTRING my_tailoring_str_alnum_09_AZ_az; + + +/* Tailoring strings for IDENT repertoires */ + +/* Most UCA case insensitive collations */ +extern const LEX_CSTRING my_tailoring_str_ident_underscore_09_AaZz_ci; + +/* Most UCA case sensitive collations */ +extern const LEX_CSTRING my_tailoring_str_ident_underscore_09_aAzZ3_cs; + +/* Most simple _ci collations */ +extern const LEX_CSTRING my_tailoring_str_ident_09_AaZz_ci_underscore; + +/* Collations folding to lower case, e.g. tis620_thai_ci */ +extern const LEX_CSTRING my_tailoring_str_ident_09_underscore_AaZz_ci; + +/* Most _bin collations */ +extern const LEX_CSTRING my_tailoring_str_ident_09_AZ_underscore_az; + + +/* Tailoring strings for ASCII repertoires */ + +extern const LEX_CSTRING my_tailoring_str_ascii_caseup_ci; + +extern const LEX_CSTRING my_tailoring_str_ascii_casedn_ci; + +extern const LEX_CSTRING my_tailoring_str_ascii_bin; + + +/* + The tailorings of a family of collations on the repertoires + DIGITS, MINUS_DOT_DIGITS, ALNUM, IDENT and ASCII. {0,0} means that + the collations have no tailoring on the repertoire. +*/ +typedef struct my_tailoring_set_st +{ + const LEX_CSTRING digits; + const LEX_CSTRING minus_dot_digits; + const LEX_CSTRING alnum; + const LEX_CSTRING ident; + const LEX_CSTRING ascii; +} MY_TAILORING_SET; + + +/* + Get the tailoring from a set by the repertoire: + - MY_REPERTOIRE_NONE: the shared empty tailoring + - A subset of DIGITS, MINUS_DOT_DIGITS, ALNUM, IDENT, ASCII: + the tailoring of the narrowest + repertoire which includes the requested one + - Otherwise, or if the set has no tailoring on the repertoire: {0,0} +*/ +static inline LEX_CSTRING +my_tailoring_by_set_and_repertoire(const MY_TAILORING_SET *set, + my_repertoire_t repertoire) +{ + const LEX_CSTRING nl= {0,0}; + if (repertoire == MY_REPERTOIRE_NONE) + return my_tailoring_str_empty; + if (my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII_DIGITS)) + return set->digits; + if (my_repertoire_is_subset_of(repertoire, + MY_REPERTOIRE_ASCII_MINUS_DOT_DIGITS)) + return set->minus_dot_digits; + if (my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII_ALNUM)) + return set->alnum; + if (my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII_IDENT)) + return set->ident; + if (my_repertoire_is_subset_of(repertoire, MY_REPERTOIRE_ASCII)) + return set->ascii; + return nl; +} + + +/* Get a tailoring string by repertoire and flag */ +LEX_CSTRING my_tailoring_simple_ci_by_flags(my_repertoire_t repertoire, + uint flags); + +/* + Get a tailoring of collations by MY_CS_DIGITS_STD and + MY_CS_ASCII_MINUS_DOT_DIGITS. + It is used for collations which do not have tailorings on wider repertoires. +*/ +LEX_CSTRING my_tailoring_by_digit_flags(my_repertoire_t repertoire, uint flags); + +/* Get a tailoring of collations folding to lower case, e.g. tis620_thai_ci */ +LEX_CSTRING my_tailoring_ascii_casedn_ci(my_repertoire_t repertoire); + +/* Virtual functions for my_collation_handler_st::tailoring() */ +LEX_CSTRING my_tailoring_ascii_caseup_ci_generic(CHARSET_INFO *self, + my_repertoire_t repertoire); + +LEX_CSTRING my_tailoring_ident_caseup_ci_generic(CHARSET_INFO *self, + my_repertoire_t repertoire); + + #endif /*STRINGS_DEF_INCLUDED */ diff --git a/support-files/wsrep_notify.sh b/support-files/wsrep_notify.sh index 19ffec95863..04323058957 100755 --- a/support-files/wsrep_notify.sh +++ b/support-files/wsrep_notify.sh @@ -4,40 +4,44 @@ # It will create 'wsrep' schema and two tables in it: 'membership' and 'status' # and fill them on every membership or node status change. # -# Edit parameters below to specify the address and login to server: +# Edit parameters below to specify the address and login to server. +# Each can also be set via a WSREP_NOTIFY_* environment variable (used by +# the test suite so it can drive this same script instead of a copy of it). # -USER='root' -PSWD='rootpass' +USER="${WSREP_NOTIFY_USER-root}" +PSWD="${WSREP_NOTIFY_PSWD-rootpass}" # # If these parameters are not set, then the values # passed by the server are taken: # -HOST="127.0.0.1" -PORT=3306 +HOST="${WSREP_NOTIFY_HOST-127.0.0.1}" +PORT="${WSREP_NOTIFY_PORT-3306}" # # Edit parameters below to specify SSL parameters: # -ssl_cert="" -ssl_key="" -ssl_ca="" -ssl_capath="" -ssl_cipher="" -ssl_crl="" -ssl_crlpath="" -ssl_verify_server_cert=0 +ssl_cert="${WSREP_NOTIFY_SSL_CERT-}" +ssl_key="${WSREP_NOTIFY_SSL_KEY-}" +ssl_ca="${WSREP_NOTIFY_SSL_CA-}" +ssl_capath="${WSREP_NOTIFY_SSL_CAPATH-}" +ssl_cipher="${WSREP_NOTIFY_SSL_CIPHER-}" +ssl_crl="${WSREP_NOTIFY_SSL_CRL-}" +ssl_crlpath="${WSREP_NOTIFY_SSL_CRLPATH-}" +ssl_verify_server_cert="${WSREP_NOTIFY_SSL_VERIFY_SERVER_CERT-0}" # # Client executable path: # -CLIENT="mysql" +CLIENT="${WSREP_NOTIFY_CLIENT-mysql}" # # Name of schema and tables: # -SCHEMA="wsrep" +SCHEMA="${WSREP_NOTIFY_SCHEMA-wsrep}" MEMB_TABLE="$SCHEMA.membership" STATUS_TABLE="$SCHEMA.status" WSREP_ON='SET wsrep_on=ON' WSREP_OFF='SET wsrep_on=OFF' +# quote_sql() output relies on backslash escapes being honoured +SQL_MODE="SET SESSION sql_mode=REPLACE(@@sql_mode,'NO_BACKSLASH_ESCAPES','')" BEGIN="CREATE SCHEMA IF NOT EXISTS $SCHEMA; CREATE TABLE IF NOT EXISTS $MEMB_TABLE ( @@ -58,27 +62,31 @@ END="COMMIT; $WSREP_ON" configuration_change() { - echo "$WSREP_OFF; DROP SCHEMA IF EXISTS $SCHEMA; $BEGIN;" + printf '%s\n' "$SQL_MODE; $WSREP_OFF; DROP SCHEMA IF EXISTS $SCHEMA; $BEGIN;" - local idx=0 + local idx=0 id rest name addr IFS=',' - for NODE in $(echo "$MEMBERS" | sed s/,/\ /g) + # MEMBERS is "id/name/addr,..."; addr may itself contain '/' or '[]' + set -f + for NODE in $MEMBERS do - echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " - # Don't forget to properly quote string values - echo "'$NODE'" | sed s/\\//\',\'/g - echo ");" + id=${NODE%%/*} + rest=${NODE#*/} + name=${rest%%/*} + addr=${rest#*/} + printf '%s\n' "INSERT INTO $MEMB_TABLE VALUES ($idx, '$(quote_sql "$id")', '$(quote_sql "$name")', '$(quote_sql "$addr")');" idx=$(( $idx+1 )) done + set +f - echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" + printf '%s\n' "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$(quote_sql "$STATUS")', '$(quote_sql "$CLUSTER_UUID")', $PRIMARY);" - echo "$END;" + printf '%s\n' "$END;" } status_update() { - echo "$WSREP_OFF; $BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;" + printf '%s\n' "$SQL_MODE; $WSREP_OFF; $BEGIN; UPDATE $STATUS_TABLE SET status='$(quote_sql "$STATUS")'; $END;" } trim_string() @@ -99,10 +107,19 @@ trim_string() fi else local pattern="[[:space:]${2:-}]" - echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g" + printf '%s\n' "$1" | sed -E "s/^$pattern+|$pattern+\$//g" fi } +# Escape a value for embedding in a single-quoted SQL string literal. +# Backslash must be escaped first, or a trailing backslash would swallow +# the closing quote. Quotes are doubled so even with NO_BACKSLASH_ESCAPES +# they can't end the literal early. +quote_sql() +{ + printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e "s/'/''/g" +} + COM='status_update' # not a configuration change by default STATUS="" @@ -168,31 +185,30 @@ ssl_crl=$(trim_string "$ssl_crl"); ssl_crlpath=$(trim_string "$ssl_crlpath"); ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); -SSL_PARAM="" - -if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] -then - SSL_PARAM=' --ssl' - [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" - [ -n "$ssl_cert" ] && SSL_PARAM="$SSL_PARAM --ssl-cert='$ssl_cert'" - [ -n "$ssl_ca" ] && SSL_PARAM="$SSL_PARAM --ssl-ca='$ssl_ca'" - [ -n "$ssl_capath" ] && SSL_PARAM="$SSL_PARAM --ssl-capath='$ssl_capath'" - [ -n "$ssl_cipher" ] && SSL_PARAM="$SSL_PARAM --ssl-cipher='$ssl_cipher'" - [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" - [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" - if [ -n "$ssl_verify_server_cert" ]; then - if [ "$ssl_verify_server_cert" != "0" -o \ - "$ssl_verify_server_cert" = "on" ] - then - SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" - fi - fi -fi - case "$STATUS" in 'joined' | 'donor' | 'synced') - "$COM" | eval "$CLIENT" -B "-u'$USER'"${PSWD:+" -p'$PSWD'"}\ - "-h'$HOST'" "-P$PORT"$SSL_PARAM + set -- -B -u"$USER" -h"$HOST" -P"$PORT" + + if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] + then + set -- "$@" --ssl + [ -n "$ssl_key" ] && set -- "$@" --ssl-key="$ssl_key" + [ -n "$ssl_cert" ] && set -- "$@" --ssl-cert="$ssl_cert" + [ -n "$ssl_ca" ] && set -- "$@" --ssl-ca="$ssl_ca" + [ -n "$ssl_capath" ] && set -- "$@" --ssl-capath="$ssl_capath" + [ -n "$ssl_cipher" ] && set -- "$@" --ssl-cipher="$ssl_cipher" + [ -n "$ssl_crl" ] && set -- "$@" --ssl-crl="$ssl_crl" + [ -n "$ssl_crlpath" ] && set -- "$@" --ssl-crlpath="$ssl_crlpath" + if [ -n "$ssl_verify_server_cert" ]; then + if [ "$ssl_verify_server_cert" != "0" -o \ + "$ssl_verify_server_cert" = "on" ] + then + set -- "$@" --ssl-verify-server-cert + fi + fi + fi + + "$COM" | MYSQL_PWD="$PSWD" exec "$CLIENT" "$@" ;; *) # The node might be shutting down or not initialized diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 446b3a9c9e5..0f81108ba52 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20946,12 +20946,14 @@ static void proxy_send_handshake_error(const char *client_ip) } /* - Connect through PROXY protocol, advertising 'client_ip' as the client. - On success returns the connection (caller closes it); on failure returns NULL - and stores the client error code in *out_errno. + Connect through PROXY protocol, advertising 'client_ip' as the client, + optionally requiring SSL. On success returns the connection (caller + closes it); on failure returns NULL and stores the client error code + in *out_errno. */ static MYSQL *proxy_connect_as(const char *client_ip, const char *user, - const char *passwd, unsigned int *out_errno) + const char *passwd, my_bool use_ssl, + unsigned int *out_errno) { MYSQL *m= mysql_client_init(NULL); char header[128]; @@ -20962,6 +20964,8 @@ static MYSQL *proxy_connect_as(const char *client_ip, const char *user, v6 ? "TCP6" : "TCP4", client_ip, v6 ? "::1" : "127.0.0.1", opt_port); mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header, strlen(header)); mysql_optionsv(m, MYSQL_OPT_PROTOCOL, &proto); + if (use_ssl) + mysql_ssl_set(m, NULL, NULL, NULL, NULL, NULL); if (!mysql_real_connect(m, opt_host, user, passwd, NULL, opt_port, NULL, 0)) { if (out_errno) @@ -20981,6 +20985,7 @@ static MYSQL *proxy_connect_as(const char *client_ip, const char *user, */ static void test_proxy_header_connect_errors_reset() { +#ifndef DBUG_OFF const char *client_ip= "192.0.2.50"; char query[256]; unsigned int conn_errno= 0; @@ -20989,6 +20994,13 @@ static void test_proxy_header_connect_errors_reset() myheader("test_proxy_header_connect_errors_reset"); + /* Force a deterministic "unresolvable" outcome; see hostname.cc. */ + rc= mysql_query(mysql, "SET @save_debug_dbug= @@global.debug_dbug"); + myquery(rc); + rc= mysql_query(mysql, + "SET GLOBAL debug_dbug='+d,getnameinfo_error_noname'"); + myquery(rc); + rc= mysql_query(mysql, "SET @saved_max_connect_errors= @@global.max_connect_errors"); myquery(rc); @@ -21005,7 +21017,7 @@ static void test_proxy_header_connect_errors_reset() /* max_connect_errors handshake errors block the host. */ for (i= 0; i < 3; i++) proxy_send_handshake_error(client_ip); - m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + m= proxy_connect_as(client_ip, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m == NULL && conn_errno == ER_HOST_IS_BLOCKED); rc= mysql_query(mysql, "FLUSH HOSTS"); @@ -21016,7 +21028,7 @@ static void test_proxy_header_connect_errors_reset() proxy_send_handshake_error(client_ip); /* Below the limit: must connect, and this success must reset the counter. */ - m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + m= proxy_connect_as(client_ip, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m != NULL); mysql_close(m); @@ -21025,7 +21037,7 @@ static void test_proxy_header_connect_errors_reset() proxy_send_handshake_error(client_ip); proxy_send_handshake_error(client_ip); - m= proxy_connect_as(client_ip, "u", "password", &conn_errno); + m= proxy_connect_as(client_ip, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m != NULL); /* ER_HOST_IS_BLOCKED with unfixed MDEV-25817 */ mysql_close(m); @@ -21037,6 +21049,9 @@ static void test_proxy_header_connect_errors_reset() myquery(rc); rc= mysql_query(mysql, "FLUSH HOSTS"); myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL debug_dbug= @save_debug_dbug"); + myquery(rc); +#endif /* !DBUG_OFF */ } /* @@ -21078,7 +21093,7 @@ static void test_proxy_header_proxy_host_connect_errors_reset() max_connect_errors of them block it. */ for (i= 0; i < 3; i++) proxy_send_handshake_error(NULL); - m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + m= proxy_connect_as(proxied_client, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m == NULL && conn_errno == ER_HOST_IS_BLOCKED); rc= mysql_query(mysql, "FLUSH HOSTS"); @@ -21089,7 +21104,7 @@ static void test_proxy_header_proxy_host_connect_errors_reset() proxy_send_handshake_error(NULL); /* Success: client has no errors, so this must reset the proxy host's two. */ - m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + m= proxy_connect_as(proxied_client, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m != NULL); mysql_close(m); @@ -21097,7 +21112,7 @@ static void test_proxy_header_proxy_host_connect_errors_reset() proxy_send_handshake_error(NULL); proxy_send_handshake_error(NULL); - m= proxy_connect_as(proxied_client, "u", "password", &conn_errno); + m= proxy_connect_as(proxied_client, "u", "password", FALSE, &conn_errno); DIE_UNLESS(m != NULL); /* ER_HOST_IS_BLOCKED if proxy host not reset */ mysql_close(m); @@ -21113,6 +21128,94 @@ static void test_proxy_header_proxy_host_connect_errors_reset() #endif /* !DBUG_OFF */ } +/* + MDEV-40967: a host that fails the check on its PROXY-derived address + must still be rejected with ER_HOST_NOT_PRIVILEGED when SSL isn't even + requested. This plain case already worked before the fix too - it is + baseline coverage, not the regression case; see + test_proxy_header_ssl_host_denied() for that. +*/ +static void test_proxy_header_host_denied() +{ + const char *client_ip= "192.0.2.222"; + unsigned int conn_errno= 0; + MYSQL *m; + + myheader("test_proxy_header_host_denied"); + + m= proxy_connect_as(client_ip, "root", "", FALSE, &conn_errno); + DIE_UNLESS(m == NULL); + DIE_UNLESS(conn_errno == ER_HOST_NOT_PRIVILEGED); +} + +/* + MDEV-40967: repeated ER_HOST_NOT_PRIVILEGED rejections via the deferred + path must never count toward max_connect_errors - the pre-deferral, + immediate check never did either, since a host with no matching grant + did nothing resembling a failed handshake. +*/ +static void test_proxy_header_host_denied_not_counted() +{ +#ifndef DBUG_OFF + const char *client_ip= "192.0.2.224"; + unsigned int conn_errno= 0; + int rc, i; + MYSQL *m; + + myheader("test_proxy_header_host_denied_not_counted"); + + rc= mysql_query(mysql, "SET @save_debug_dbug= @@global.debug_dbug"); + myquery(rc); + rc= mysql_query(mysql, + "SET GLOBAL debug_dbug='+d,getnameinfo_error_noname'"); + myquery(rc); + + rc= mysql_query(mysql, + "SET @save_max_connect_errors= @@global.max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "SET @@global.max_connect_errors=3"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + + /* More attempts than max_connect_errors: every one must still be + ER_HOST_NOT_PRIVILEGED, never ER_HOST_IS_BLOCKED. */ + for (i= 0; i < 5; i++) + { + m= proxy_connect_as(client_ip, "root", "", FALSE, &conn_errno); + DIE_UNLESS(m == NULL); + DIE_UNLESS(conn_errno == ER_HOST_NOT_PRIVILEGED); + } + + rc= mysql_query(mysql, + "SET @@global.max_connect_errors=@save_max_connect_errors"); + myquery(rc); + rc= mysql_query(mysql, "FLUSH HOSTS"); + myquery(rc); + rc= mysql_query(mysql, "SET GLOBAL debug_dbug= @save_debug_dbug"); + myquery(rc); +#endif /* !DBUG_OFF */ +} + +/* + MDEV-40967: same deferred rejection as test_proxy_header_host_denied(), + but with the client requesting (and completing) SSL - the actual + regression case: before the fix, the host check ran before the SSL + handshake, corrupting it. +*/ +static void test_proxy_header_ssl_host_denied() +{ + const char *client_ip= "192.0.2.223"; + unsigned int conn_errno= 0; + MYSQL *m; + + myheader("test_proxy_header_ssl_host_denied"); + + m= proxy_connect_as(client_ip, "root", "", TRUE, &conn_errno); + DIE_UNLESS(m == NULL); + DIE_UNLESS(conn_errno == ER_HOST_NOT_PRIVILEGED); +} + static void test_proxy_header() { myheader("test_proxy_header"); @@ -21125,6 +21228,9 @@ static void test_proxy_header() test_proxy_header_dbug_remote_connection(); test_proxy_header_connect_errors_reset(); test_proxy_header_proxy_host_connect_errors_reset(); + test_proxy_header_host_denied(); + test_proxy_header_host_denied_not_counted(); + test_proxy_header_ssl_host_denied(); } diff --git a/unittest/mysys/ma_dyncol-t.c b/unittest/mysys/ma_dyncol-t.c index a58d2d8d127..5819c272bca 100644 --- a/unittest/mysys/ma_dyncol-t.c +++ b/unittest/mysys/ma_dyncol-t.c @@ -772,6 +772,51 @@ static void test_overlong_int(DYNAMIC_COLUMN_TYPE type, const char *msg) mariadb_dyncol_free(&str); } +/* + A crafted record can encode a decimal's intg/frac digit count as a + var-uint wide enough that narrowing it to int wraps around into a + small, in-range value (2^32+1 truncates to 1 on 32-bit int). The + decoder must reject the value using its full width, before narrowing. + See MDEV-41144. +*/ +static void test_decimal_precision_overflow() +{ + DYNAMIC_COLUMN str; + DYNAMIC_COLUMN bad; + DYNAMIC_COLUMN_VALUE val, res; + uint column_nr= 1; + int rc; + char num[]= "5"; + char *end= num + 1; + /* var-uint encoding of 2^32+1, which truncates to 1 as a 32-bit int */ + const uchar wide_intg[]= {0x81, 0x80, 0x80, 0x80, 0x10}; + + mariadb_dyncol_prepare_decimal(&val); + string2decimal(num, &val.x.decimal.value, &end); + + rc= mariadb_dyncol_create_many_num(&str, 1, &column_nr, &val, 1); + ok(rc == ER_DYNCOL_OK, "create decimal"); + + /* + decimal "5" is stored as the last 3 bytes of the record: a 1-byte + intg (1), a 1-byte frac (0) and 1 byte of binary payload. Replace + the 1-byte intg with a 5-byte encoding of the same truncated value. + */ + bad.length= str.length - 3 + sizeof(wide_intg) + 2; + bad.max_length= bad.length; + bad.alloc_increment= 0; + bad.str= (char *) malloc(bad.length); + memcpy(bad.str, str.str, str.length - 3); + memcpy(bad.str + str.length - 3, wide_intg, sizeof(wide_intg)); + memcpy(bad.str + str.length - 3 + sizeof(wide_intg), str.str + str.length - 2, 2); + + rc= mariadb_dyncol_get_num(&bad, column_nr, &res); + ok(rc == ER_DYNCOL_FORMAT, "wide intg varint rejected"); + + free(bad.str); + mariadb_dyncol_free(&str); +} + #define BIG_STRING_SIZE (1024*1024) int main(int argc __attribute__((unused)), char **argv) @@ -780,7 +825,7 @@ int main(int argc __attribute__((unused)), char **argv) char *big_string= (char *)malloc(BIG_STRING_SIZE); MY_INIT(argv[0]); - plan(72); + plan(74); if (!big_string) exit(1); @@ -916,6 +961,7 @@ int main(int argc __attribute__((unused)), char **argv) test_mdev_9773(); test_overlong_int(DYN_COL_UINT, "uint"); test_overlong_int(DYN_COL_INT, "sint"); + test_decimal_precision_overflow(); my_end(0); return exit_status(); diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c index 0e563ea7626..52a720d9d54 100644 --- a/unittest/strings/strings-t.c +++ b/unittest/strings/strings-t.c @@ -1735,6 +1735,62 @@ static int test_mb_wc_filename_truncated() } +/* + my_string_repertoire() must not return a repertoire which is a subset + of ASCII (e.g. MY_REPERTOIRE_NONE, which is compatible with everything) + for a string with a bad byte sequence, an unassigned character, or + an incomplete character: the characters of such strings are unknown. +*/ +typedef struct +{ + CHARSET_INFO *cs; + const char *str; + size_t length; + my_repertoire_t expected_at_least; /* Bits that must be set */ + my_bool ascii_only; /* Is the result a subset of ASCII? */ +} STRING_REPERTOIRE_PARAM; + + +static int test_string_repertoire() +{ +#define LOWER MY_REPERTOIRE_ASCII_LETTERS_LOWER +#define EXT MY_REPERTOIRE_EXTENDED + static const STRING_REPERTOIRE_PARAM param[]= + { + /* Valid strings */ + {&my_charset_utf16_general_ci, "\0a\0b", 4, LOWER, TRUE}, + {&my_charset_utf16_general_ci, "\0\xE9", 2, EXT, FALSE}, + {&my_charset_ucs2_general_ci, "\0a", 2, LOWER, TRUE}, + {&my_charset_utf32_general_ci, "\0\0\0a", 4, LOWER, TRUE}, + /* A lone high surrogate */ + {&my_charset_utf16_general_ci, "\xD8\0", 2, EXT, FALSE}, + /* ASCII characters followed by a lone high surrogate */ + {&my_charset_utf16_general_ci, "\0a\xD8\0", 4, EXT, FALSE}, + /* An incomplete character at the end */ + {&my_charset_utf16_general_ci, "\0a\0", 3, EXT, FALSE}, + /* A code point beyond U+10FFFF */ + {&my_charset_utf32_general_ci, "\0\x11\0\0", 4, EXT, FALSE} + }; +#undef LOWER +#undef EXT + size_t i; + int failed= 0; + for (i= 0; i < array_elements(param); i++) + { + const STRING_REPERTOIRE_PARAM *p= ¶m[i]; + my_repertoire_t rep= my_string_repertoire(p->cs, p->str, p->length); + if ((rep & p->expected_at_least) != p->expected_at_least || + my_repertoire_is_subset_of(rep, MY_REPERTOIRE_ASCII) != p->ascii_only) + { + diag("my_string_repertoire() failed for %s, test #%d: %d", + p->cs->coll_name.str, (int) i, (int) rep); + failed++; + } + } + return failed; +} + + /* MDEV-41556: my_strntoull10rnd() must always set *error, also when a signed value equals LONGLONG_MIN exactly. Pre-set "error" to a non-zero value, so @@ -1816,6 +1872,10 @@ int main(int ac, char **av) ok(test_mb_wc_filename_truncated() == 0, "filename decoder does not read past the end pointer"); + diag("Testing my_string_repertoire() for strings with bad characters"); + ok(test_string_repertoire() == 0, + "my_string_repertoire() does not return ASCII for bad strings"); + diag("Testing my_ci_strntoull10rnd() error output"); ok(test_strntoull10rnd_error_set() == 0, "my_ci_strntoull10rnd() always sets error"); diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 54eba05c67e..fb997957341 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -28,58 +28,71 @@ ENDIF() STRING(TOLOWER "${CMAKE_C_COMPILER_ARCHITECTURE_ID}" WIX_ARCH) -SET(WIX_BIN_PATHS) -FOREACH(WIX_VER 3.14 3.13 3.12 3.11) - LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles}/WiX Toolset v${WIX_VER}/bin") - LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles} (x86)/WiX Toolset v${WIX_VER}/bin") -ENDFOREACH() -FIND_PATH(WIX_DIR heat.exe ${WIX_BIN_PATHS}) -IF(NOT WIX_DIR) - CANT_BUILD_MSI("WiX version 3.11 or later not found") +# Two WiX toolsets are supported - legacy v3.x (candle.exe/light.exe), +# which is the default, and modern, newer than v3 (single wix.exe). +# WXS sources are authored in v3 format, the modern toolset builds them +# after on-the-fly "wix convert". Use -DWITH_WIX3=OFF for modern WiX, +# it is used if found, v3 is the fallback. +OPTION(WITH_WIX3 "Build MSI with legacy WiX v3 toolset, OFF for modern WiX" ON) + +# WiX 7 and later need the Open Source Maintenance Fee EULA to be accepted, +# see https://wixtoolset.org/osmf/ . It is never accepted implicitly. +OPTION(WIX_ACCEPT_EULA "Accept the WiX EULA, if WiX asks for it" OFF) + +IF(WITH_WIX3) + UNSET(WIX_EXECUTABLE CACHE) +ELSE() + SET(WIX_MODERN_PATHS "$ENV{USERPROFILE}/.dotnet/tools") + FILE(GLOB WIX_INSTALL_DIRS "$ENV{ProgramFiles}/WiX Toolset v*/bin") + IF(WIX_INSTALL_DIRS) + # Newest version first + LIST(SORT WIX_INSTALL_DIRS COMPARE NATURAL ORDER DESCENDING) + LIST(APPEND WIX_MODERN_PATHS ${WIX_INSTALL_DIRS}) + ENDIF() + FIND_PROGRAM(WIX_EXECUTABLE wix PATHS ${WIX_MODERN_PATHS}) + IF(WIX_EXECUTABLE) + EXECUTE_PROCESS(COMMAND "${WIX_EXECUTABLE}" --version + OUTPUT_VARIABLE WIX_VERSION_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE WIX_VERSION_RESULT) + STRING(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" WIX_VERSION "${WIX_VERSION_OUTPUT}") + IF(WIX_VERSION_RESULT OR NOT WIX_VERSION) + MESSAGE(WARNING "Can't determine version of ${WIX_EXECUTABLE}, ignoring it") + UNSET(WIX_EXECUTABLE CACHE) + ENDIF() + ENDIF() ENDIF() +IF(NOT WIX_EXECUTABLE) + SET(WIX_BIN_PATHS) + FOREACH(WIX_VER 3.14 3.13 3.12 3.11) + LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles}/WiX Toolset v${WIX_VER}/bin") + LIST(APPEND WIX_BIN_PATHS "$ENV{ProgramFiles} (x86)/WiX Toolset v${WIX_VER}/bin") + ENDFOREACH() + FIND_PATH(WIX_DIR heat.exe ${WIX_BIN_PATHS}) + IF(NOT WIX_DIR) + IF(WITH_WIX3) + CANT_BUILD_MSI("WiX version 3.11 or later not found, use -DWITH_WIX3=OFF for modern WiX") + ELSE() + CANT_BUILD_MSI("neither modern WiX (wix.exe) nor WiX version 3.11 or later found") + ENDIF() + ENDIF() -GET_FILENAME_COMPONENT(WIX_SDK_DIR ../SDK/ ABSOLUTE BASE_DIR ${WIX_DIR} CACHE) -FIND_LIBRARY(WIX_WCAUTIL_LIBRARY - wcautil - PATHS - ${WIX_SDK_DIR}/VS2017/lib/${WIX_ARCH} - ${WIX_SDK_DIR}/VS2015/lib/${WIX_ARCH} - ) + FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) + IF(NOT CANDLE_EXECUTABLE) + CANT_BUILD_MSI("candle.exe not found") + ENDIF() -IF(NOT WIX_WCAUTIL_LIBRARY) - CANT_BUILD_MSI("wcautil.lib not found for ${WIX_ARCH}") + FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) + IF(NOT LIGHT_EXECUTABLE) + CANT_BUILD_MSI("light.exe not found") + ENDIF() ENDIF() -FIND_LIBRARY(WIX_DUTIL_LIBRARY - dutil - PATHS - ${WIX_SDK_DIR}/VS2017/lib/${WIX_ARCH} - ${WIX_SDK_DIR}/VS2015/lib/${WIX_ARCH} - ) - -IF(NOT WIX_DUTIL_LIBRARY) - CANT_BUILD_MSI("dutil.lib not found for ${WIX_ARCH}") -ENDIF() - -FIND_PATH(WIX_INCLUDE_DIR - wcautil.h PATHS - ${WIX_SDK_DIR}/VS2017/inc - ${WIX_SDK_DIR}/VS2015/inc - ${WIX_SDK_DIR}/inc) - -IF(NOT WIX_INCLUDE_DIR) - CANT_BUILD_MSI("wcautil.h not found for ${WIX_ARCH}") -ENDIF() - -FIND_PROGRAM(CANDLE_EXECUTABLE candle ${WIX_DIR}) -IF(NOT CANDLE_EXECUTABLE) - CANT_BUILD_MSI("candle.exe not found") -ENDIF() - -FIND_PROGRAM(LIGHT_EXECUTABLE light ${WIX_DIR}) -IF(NOT LIGHT_EXECUTABLE) - CANT_BUILD_MSI("light.exe not found") +IF(WIX_EXECUTABLE) + MESSAGE_ONCE(wix "MSI: using WiX ${WIX_VERSION} (${WIX_EXECUTABLE})") +ELSEIF(CAN_BUILD_MSI) + MESSAGE_ONCE(wix "MSI: using WiX 3 (${WIX_DIR})") ENDIF() SET(CPACK_WIX_PACKAGE_BASE_NAME "MariaDB") @@ -172,6 +185,9 @@ ENDIF() ADD_CUSTOM_TARGET( MSI COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} + -DWIX_EXECUTABLE="${WIX_EXECUTABLE}" + -DWIX_VERSION="${WIX_VERSION}" + -DWIX_ACCEPT_EULA="${WIX_ACCEPT_EULA}" -DCANDLE_EXECUTABLE="${CANDLE_EXECUTABLE}" -DCMAKE_CFG_INTDIR="${CMAKE_CFG_INTDIR}" -DCMAKE_FULL_VER="${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" diff --git a/win/packaging/ca/CMakeLists.txt b/win/packaging/ca/CMakeLists.txt index 652b76de11f..ea5f2c3a28b 100644 --- a/win/packaging/ca/CMakeLists.txt +++ b/win/packaging/ca/CMakeLists.txt @@ -15,11 +15,11 @@ SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql ${CMAKE_CURRENT_SOURCE_DIR} ${WIX_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql ${CMAKE_CURRENT_SOURCE_DIR}) # Custom action should not depend on C runtime, since we do not know if CRT is installed. ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES} ${CMAKE_SOURCE_DIR}/sql/winservice.c) # Static linking with CRT, because it is called when MSVC libraries are not yet there, SET_TARGET_PROPERTIES(wixca PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreaded) -TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} msi version ws2_32) +TARGET_LINK_LIBRARIES(wixca msi version ws2_32 shell32 advapi32) diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp index 3551eb3a77a..1520a983e28 100644 --- a/win/packaging/ca/CustomAction.cpp +++ b/win/packaging/ca/CustomAction.cpp @@ -25,11 +25,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ #include #include #include -#include -#include #include #include #include +#include #include #include #include @@ -44,17 +43,45 @@ using namespace std; #define ONE_MB 1048576 -UINT ExecRemoveDataDirectory(wchar_t *dir) + +/* + Limits of property values. Values that go to fixed size APIs, or have + natural limits elsewhere, are rejected if they are longer, instead of + being silently truncated. +*/ +/* The longest service name accepted by CreateService() */ +static const size_t MAX_SERVICENAME_LEN= 256; +/* TCP port has 5 digits at most */ +static const size_t MAX_PORT_LEN= 5; +/* Innodb buffer pool size is a number of megabytes */ +static const size_t MAX_BUFFERPOOLSIZE_LEN= 15; +/* Directory is listed with FindFirstFile(), "*.*" has to fit into MAX_PATH */ +static const size_t MAX_DIRECTORY_LEN= MAX_PATH - 4; +/* + The password ends up in a command line, which is limited to 32767 + characters, and escaping at most doubles it. +*/ +static const size_t MAX_PASSWORD_LEN= 8192; + +UINT ExecRemoveDataDirectory(std::wstring dir) { - /* Strip stray backslash */ - DWORD len = (DWORD)wcslen(dir); - if(len > 0 && dir[len-1]==L'\\') - dir[len-1] = 0; + /* Strip stray backslash */ + if (!dir.empty() && dir.back() == L'\\') + dir.pop_back(); + if (dir.empty()) + return ERROR_INVALID_PARAMETER; + + /* + pFrom is a list of names, every name ends with NUL, and the list ends + with one more. The explicit NUL, together with the one that string + always has, makes it a list of a single name. + */ + dir.push_back(L'\0'); SHFILEOPSTRUCTW fileop; fileop.hwnd= NULL; /* no status display */ fileop.wFunc= FO_DELETE; /* delete operation */ - fileop.pFrom= dir; /* source file name as double null terminated string */ + fileop.pFrom= dir.c_str(); /* source file name, double null terminated */ fileop.pTo= NULL; /* no destination needed */ fileop.fFlags= FOF_NOCONFIRMATION|FOF_SILENT; /* do not prompt the user */ @@ -65,111 +92,143 @@ UINT ExecRemoveDataDirectory(wchar_t *dir) return SHFileOperationW(&fileop); } +// Write a message to the MSI log +static void WriteMsiLog(MSIHANDLE hInstall, const wchar_t *str) +{ + PMSIHANDLE hRecord= MsiCreateRecord(1); + if (hRecord) + { + MsiRecordSetStringW(hRecord, 0, str); + MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord); + } +} + +// Log a formatted message, prefixed with the function name, to the MSI log. +static void LogMessage(MSIHANDLE hInstall, const char *function, + const wchar_t *format, ...) +{ + wchar_t buf[1024]; + int prefix_len= _snwprintf_s(buf, _TRUNCATE, L"MariaDB_CA %S:", function); + if (prefix_len < 0) + prefix_len= 0; + va_list args; + va_start(args, format); + _vsnwprintf_s(buf + prefix_len, ARRAYSIZE(buf) - prefix_len, _TRUNCATE, + format, args); + va_end(args); + WriteMsiLog(hInstall, buf); +} + +/* Needs hInstall in scope, the format has to be a wide string literal. */ +#define Log(...) LogMessage(hInstall, __FUNCTION__, __VA_ARGS__) + +/* + Get the value of an MSI property, whatever its length is. + A property that is not set has an empty value. + + Returns false (and logs) if the value can't be retrieved. Callers must not + use the property then, a truncated value, e.g path, is worse than no value. +*/ +static bool GetProperty(MSIHANDLE hInstall, const wchar_t *name, + std::wstring &value) +{ + wchar_t buf[MAX_PATH]; + DWORD len= MAX_PATH; + UINT er= MsiGetPropertyW(hInstall, name, buf, &len); + if (er == ERROR_SUCCESS) + { + value.assign(buf, len); + return true; + } + if (er == ERROR_MORE_DATA) + { + /* len is the required length, without the terminating NUL */ + std::wstring tmp(len + 1, L'\0'); + len++; + er= MsiGetPropertyW(hInstall, name, &tmp[0], &len); + if (er == ERROR_SUCCESS) + { + tmp.resize(len); + value.swap(tmp); + return true; + } + } + Log(L"Cannot get property %s, error %u", name, er); + value.clear(); + return false; +} extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - wchar_t dir[MAX_PATH]; - DWORD len = MAX_PATH; + std::wstring dir; + UINT er; - hr = WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + Log(L"Initialized."); - MsiGetPropertyW(hInstall, L"CustomActionData", dir, &len); + /* Never delete, if the directory is not known for sure. */ + if (!GetProperty(hInstall, L"CustomActionData", dir) || dir.empty()) + { + Log(L"Directory to remove is not known, nothing is removed"); + return ERROR_INSTALL_FAILURE; + } er= ExecRemoveDataDirectory(dir); - WcaLog(LOGMSG_STANDARD, "SHFileOperation returned %d", er); -LExit: - return WcaFinalize(er); + Log(L"Removing %s returned %u", dir.c_str(), er); + return er; } /* - Escape command line parameter fpr pass to CreateProcess(). + Escape command line parameter for pass to CreateProcess(). - We assume out has enough space to include encoded string - 2*wcslen(in) is enough. - - It is assumed that called will add double quotation marks before and after - the string. + The caller adds double quotation marks before and after the string, so + the backslashes at the end of the string are always escaped, the + closing quotation mark would be taken as escaped otherwise. */ -static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen) +static std::wstring EscapeCommandLine(const std::wstring &in) { - const wchar_t special_chars[]=L" \t\n\v\""; - bool needs_escaping= false; - size_t pos; - - for(size_t i=0; i< sizeof(special_chars) -1; i++) + std::wstring out; + for (size_t i= 0;; i++) { - if (wcschr(in, special_chars[i])) - { - needs_escaping = true; - break; - } - } - - if(!needs_escaping) - { - wcscpy_s(out, buflen, in); - return; - } - - pos= 0; - for(int i = 0 ; ; i++) - { - size_t n_backslashes = 0; - wchar_t c; - while (in[i] == L'\\') + size_t n_backslashes= 0; + while (i < in.length() && in[i] == L'\\') { i++; n_backslashes++; } - c= in[i]; - if (c == 0) + if (i == in.length()) { /* Escape all backslashes, but let the terminating double quotation mark that caller adds be interpreted as a metacharacter. */ - for(size_t j= 0; j < 2*n_backslashes;j++) - { - out[pos++]=L'\\'; - } + out.append(2*n_backslashes, L'\\'); break; } - else if (c == L'"') + + if (in[i] == L'"') { /* Escape all backslashes and the following double quotation mark. */ - for(size_t j= 0; j < 2*n_backslashes + 1; j++) - { - out[pos++]=L'\\'; - } - out[pos++]= L'"'; + out.append(2*n_backslashes + 1, L'\\'); + out.push_back(L'"'); } else { /* Backslashes aren't special here. */ - for (size_t j=0; j < n_backslashes; j++) - out[pos++] = L'\\'; - - out[pos++]= c; + out.append(n_backslashes, L'\\'); + out.push_back(in[i]); } } - out[pos++]= 0; + return out; } -bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) { - wchar_t wildcard[MAX_PATH+3]; +bool IsDirectoryEmptyOrNonExisting(const std::wstring &dir) { WIN32_FIND_DATAW data; HANDLE h; - wcscpy_s(wildcard, MAX_PATH, dir); - wcscat_s(wildcard, MAX_PATH, L"*.*"); bool empty= true; - h= FindFirstFile(wildcard, &data); + h= FindFirstFileW((dir + L"*.*").c_str(), &data); if (h != INVALID_HANDLE_VALUE) { for (;;) @@ -179,7 +238,7 @@ bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) { empty= false; break; } - if (!FindNextFile(h, &data)) + if (!FindNextFileW(h, &data)) break; } FindClose(h); @@ -189,27 +248,28 @@ bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) { extern "C" UINT __stdcall CheckInstallDirectory(MSIHANDLE hInstall) { - HRESULT hr= S_OK; - UINT er= ERROR_SUCCESS; - wchar_t *path= 0; + std::wstring path; - hr= WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaGetFormattedString(L"[INSTALLDIR]", &path); - if (!IsDirectoryEmptyOrNonExisting(path)) + if (!GetProperty(hInstall, L"INSTALLDIR", path)) + return ERROR_INSTALL_FAILURE; + + if (path.length() > MAX_DIRECTORY_LEN) + { + MsiSetPropertyW(hInstall, L"INSTALLDIRERROR", + L"Installation directory path is too long"); + } + else if (!IsDirectoryEmptyOrNonExisting(path)) { wchar_t msg[2*MAX_PATH]; - swprintf(msg,countof(msg), L"Installation directory '%s' exists and is not empty. Choose a " - "different install directory",path); - WcaSetProperty(L"INSTALLDIRERROR", msg); - goto LExit; + swprintf(msg,ARRAYSIZE(msg), L"Installation directory '%s' exists and is not empty. Choose a " + "different install directory",path.c_str()); + MsiSetPropertyW(hInstall,L"INSTALLDIRERROR", msg); } - - WcaSetProperty(L"INSTALLDIRERROR", L""); - -LExit: - ReleaseStr(path); - return WcaFinalize(er); + else + { + MsiSetPropertyW(hInstall, L"INSTALLDIRERROR", L""); + } + return ERROR_SUCCESS; } /* @@ -223,61 +283,53 @@ LExit: */ extern "C" UINT __stdcall CheckDataDirectory(MSIHANDLE hInstall) { - HRESULT hr= S_OK; - UINT er= ERROR_SUCCESS; - wchar_t datadir[MAX_PATH]; - DWORD len= MAX_PATH; - bool empty; - wchar_t *path= 0; + std::wstring datadir; + std::wstring installdir; - MsiGetPropertyW(hInstall, L"DATADIR", datadir, &len); - hr= WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + if (!GetProperty(hInstall, L"DATADIR", datadir) || + !GetProperty(hInstall, L"INSTALLDIR", installdir)) + return ERROR_INSTALL_FAILURE; - WcaLog(LOGMSG_STANDARD, "Checking files in %S", datadir); - empty= IsDirectoryEmptyOrNonExisting(datadir); - if (empty) - WcaLog(LOGMSG_STANDARD, "DATADIR is empty or non-existent"); - else - WcaLog(LOGMSG_STANDARD, "DATADIR is NOT empty"); - - if (!empty) + Log(L"Checking files in %s", datadir.c_str()); + if (datadir.length() > MAX_DIRECTORY_LEN) { - WcaSetProperty(L"DATADIRERROR", L"data directory exist and not empty"); - goto LExit; + MsiSetPropertyW(hInstall, L"DATADIRERROR", + L"data directory path is too long"); + return ERROR_SUCCESS; } - WcaSetProperty(L"DATADIRERROR", L""); - - WcaGetFormattedString(L"[INSTALLDIR]",&path); - if (path && !wcsicmp(datadir, path)) + if (!IsDirectoryEmptyOrNonExisting(datadir)) { - WcaSetProperty(L"DATADIRERROR", L"data directory can not be " + Log(L"DATADIR is NOT empty"); + MsiSetPropertyW(hInstall, L"DATADIRERROR", + L"data directory exists and is not empty"); + return ERROR_SUCCESS; + } + Log(L"DATADIR is empty or non-existent"); + MsiSetPropertyW(hInstall, L"DATADIRERROR", L""); + Log(L"INSTALLDIR check"); + + if (!_wcsicmp(datadir.c_str(), installdir.c_str())) + { + MsiSetPropertyW(hInstall, L"DATADIRERROR", L"data directory can not be " L"installation root directory"); - ReleaseStr(path); - goto LExit; + return ERROR_SUCCESS; } for (auto dir : - {L"[INSTALLDIR]bin\\", L"[INSTALLDIR]include\\", - L"[INSTALLDIR]lib\\", L"[INSTALLDIR]share\\"}) + {L"bin\\", L"include\\", + L"lib\\", L"share\\"}) { - WcaGetFormattedString(dir, &path); - if (path && !wcsnicmp(datadir, path, wcslen(path))) + std::wstring localpath= installdir + dir; + if (!_wcsnicmp(datadir.c_str(), localpath.c_str(), localpath.length())) { - const wchar_t *subdir= dir + sizeof("[INSTALLDIR]") - 1; wchar_t msg[MAX_PATH]= L"data directory conflicts with '"; - wcsncat_s(msg, subdir, wcslen(subdir) - 1); + wcsncat_s(msg, dir, wcslen(dir) - 1); wcscat_s(msg, L"' directory, which is part of this installation"); - WcaSetProperty(L"DATADIRERROR", msg); - ReleaseStr(path); - goto LExit; + MsiSetPropertyW(hInstall, L"DATADIRERROR", msg); + return ERROR_SUCCESS; } - ReleaseStr(path); - path= 0; } -LExit: - return WcaFinalize(er); + return ERROR_SUCCESS; } @@ -317,7 +369,9 @@ bool ExecRemoveService(const wchar_t *name) { ret= false; } + DWORD error= GetLastError(); CloseServiceHandle(manager); + SetLastError(error); return ret; } @@ -425,6 +479,13 @@ wchar_t *strip_quotes(wchar_t *s) } +/* Uninstall does not touch the service and the data directory then */ +static void KeepServiceAndData(MSIHANDLE hInstall) +{ + MsiSetPropertyW(hInstall, L"SERVICENAME", L""); + MsiSetPropertyW(hInstall, L"CLEANUPDATA", L""); +} + /* Checks for consistency of service configuration. @@ -449,10 +510,11 @@ wchar_t *strip_quotes(wchar_t *s) */ void CheckServiceConfig( - wchar_t *my_servicename, /* SERVICENAME property in this installation*/ - wchar_t *datadir, /* DATADIR property in this installation*/ - wchar_t *bindir, /* INSTALLDIR\bin */ - wchar_t *other_servicename, /* Service to check against */ + MSIHANDLE hInstall, /* MSI handle */ + const wchar_t *my_servicename, /* SERVICENAME property in this installation*/ + const wchar_t *datadir, /* DATADIR property in this installation*/ + const wchar_t *bindir, /* INSTALLDIR\bin */ + const wchar_t *other_servicename, /* Service to check against */ QUERY_SERVICE_CONFIGW * config /* Other service's config */ ) { @@ -462,29 +524,29 @@ void CheckServiceConfig( int numargs; wchar_t **argv= CommandLineToArgvW(commandline, &numargs); wchar_t current_datadir_buf[MAX_PATH]={0}; - wchar_t normalized_current_datadir[MAX_PATH+1]; + wchar_t normalized_current_datadir[MAX_PATH+1]= {0}; wchar_t *current_datadir; wchar_t *defaults_file; bool is_my_service; - WcaLog(LOGMSG_VERBOSE, "CommandLine= %S", commandline); + Log(L"CommandLine= %s", commandline); if(!argv || !argv[0] || ! wcsstr(argv[0], L"mysqld")) { goto end; } - WcaLog(LOGMSG_STANDARD, "MySQL/MariaDB service %S found: CommandLine= %S", + Log(L"MySQL/MariaDB service %s found: CommandLine= %s", other_servicename, commandline); if (wcsstr(argv[0], bindir)) { - WcaLog(LOGMSG_STANDARD, "executable under bin directory"); + Log(L"executable under bin directory"); same_bindir = true; } is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0); if(!is_my_service) { - WcaLog(LOGMSG_STANDARD, "service does not match current service"); + Log(L"service does not match current service"); /* TODO probably the best thing possible would be to add temporary row to MSI ServiceConfig table with remove on uninstall @@ -492,10 +554,9 @@ void CheckServiceConfig( } else if (!same_bindir) { - WcaLog(LOGMSG_STANDARD, - "Service name matches, but not the executable path directory, mine is %S", + Log(L"Service name matches, but not the executable path directory, mine is %s", bindir); - WcaSetProperty(L"SERVICENAME", L""); + MsiSetPropertyW(hInstall,L"SERVICENAME", L""); } /* Check if data directory is used */ @@ -508,17 +569,16 @@ void CheckServiceConfig( defaults_file= argv[1]+16; defaults_file= strip_quotes(defaults_file); - WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file); + Log(L"parsed defaults file is %s", defaults_file); if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir, MAX_PATH, defaults_file) == 0) { - WcaLog(LOGMSG_STANDARD, - "Cannot find datadir in ini file '%S'", defaults_file); + Log(L"Cannot find datadir in ini file '%s'", defaults_file); goto end; } - WcaLog(LOGMSG_STANDARD, "datadir from defaults-file is %S", current_datadir); + Log(L"datadir from defaults-file is %s", current_datadir); strip_quotes(current_datadir); /* Convert to Windows path */ @@ -526,16 +586,15 @@ void CheckServiceConfig( NULL)) { /* Add backslash to be compatible with directory formats in MSI */ - wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1); - WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'", + wcscat_s(normalized_current_datadir, L"\\"); + Log(L"normalized current datadir is '%s'", normalized_current_datadir); } if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir) { - WcaLog(LOGMSG_STANDARD, - "database directory from current installation, but different mysqld.exe"); - WcaSetProperty(L"CLEANUPDATA", L""); + Log(L"database directory from current installation, but different mysqld.exe"); + MsiSetPropertyW(hInstall,L"CLEANUPDATA", L""); } end: @@ -565,12 +624,11 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) { static BYTE buf[256*1024]; /* largest possible buffer for EnumServices */ static char config_buffer[8*1024]; /*largest buffer for QueryServiceConfig */ - HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; - wchar_t *servicename= NULL; - wchar_t *datadir= NULL; - wchar_t *bindir=NULL; - + std::wstring servicename; + std::wstring datadir; + std::wstring installdir; + std::wstring bindir; SC_HANDLE scm = NULL; ULONG bufsize = sizeof(buf); ULONG bufneed = 0x00; @@ -578,22 +636,34 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) LPENUM_SERVICE_STATUS_PROCESS info = NULL; BOOL ok; - hr = WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + Log(L"Initialized."); + /* + Do not guess. Without INSTALLDIR, bindir would be just "bin\", which + would match services of other installations. + */ + if (!GetProperty(hInstall, L"SERVICENAME", servicename) || + !GetProperty(hInstall, L"DATADIR", datadir) || + !GetProperty(hInstall, L"INSTALLDIR", installdir) || + installdir.empty()) + { + Log(L"SERVICENAME, DATADIR or INSTALLDIR is not known, service and data " + L"are kept"); + KeepServiceAndData(hInstall); + return ERROR_INSTALL_FAILURE; + } + /* INSTALLDIR ends with backslash */ + bindir= installdir + L"bin\\"; - WcaGetProperty(L"SERVICENAME", &servicename); - WcaGetProperty(L"DATADIR", &datadir); - WcaGetFormattedString(L"[INSTALLDIR]bin\\", &bindir); - - WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S", - servicename, datadir, bindir); + Log(L"SERVICENAME=%s, DATADIR=%s, bindir=%s", servicename.c_str(), + datadir.c_str(), bindir.c_str()); scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); if (scm == NULL) { - ExitOnFailure(E_FAIL, "OpenSCManager failed"); + Log(L"OpenSCManager failed with %u", GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; } ok = EnumServicesStatusExW( scm, @@ -608,8 +678,9 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) NULL); if(!ok) { - WcaLog(LOGMSG_STANDARD, "last error %d", GetLastError()); - ExitOnFailure(E_FAIL, "EnumServicesStatusExW failed"); + Log(L"EnumServicesStatusExW failed with %u", GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; } info = (LPENUM_SERVICE_STATUS_PROCESS)buf; for (ULONG i=0; i < num_services; i++) @@ -618,7 +689,7 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) SERVICE_QUERY_CONFIG); if (!service) continue; - WcaLog(LOGMSG_VERBOSE, "Checking Service %S", info[i].lpServiceName); + Log(L"Checking Service %s", info[i].lpServiceName); QUERY_SERVICE_CONFIGW *config= (QUERY_SERVICE_CONFIGW *)(void *)config_buffer; DWORD needed; @@ -627,19 +698,17 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall) CloseServiceHandle(service); if (ok) { - CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName, - config); + CheckServiceConfig(hInstall, servicename.c_str(), datadir.c_str(), + bindir.c_str(), info[i].lpServiceName, config); } } LExit: + if(er) + KeepServiceAndData(hInstall); if(scm) CloseServiceHandle(scm); - - ReleaseStr(servicename); - ReleaseStr(datadir); - ReleaseStr(bindir); - return WcaFinalize(er); + return er; } /* @@ -678,48 +747,48 @@ static constexpr unsigned long long minBufferpoolMB= 20; */ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) { - wchar_t ServiceName[MAX_PATH]={0}; - wchar_t SkipNetworking[MAX_PATH]={0}; - wchar_t QuickConfig[MAX_PATH]={0}; - wchar_t Password[MAX_PATH]={0}; - wchar_t EscapedPassword[2*MAX_PATH+2]; - wchar_t Port[6]; - wchar_t BufferPoolSize[16]; - DWORD PortLen=6; - bool haveInvalidPort=false; + std::wstring ServiceName; + std::wstring SkipNetworking; + std::wstring QuickConfig; + std::wstring Password; + std::wstring EscapedPassword; + std::wstring Port; + std::wstring BufferPoolSize; + wchar_t invalidValueMsg[256]; const wchar_t *ErrorMsg=0; - HRESULT hr= S_OK; + bool tooLong= false; UINT er= ERROR_SUCCESS; - DWORD ServiceNameLen = MAX_PATH; - DWORD QuickConfigLen = MAX_PATH; - DWORD PasswordLen= MAX_PATH; - DWORD SkipNetworkingLen= MAX_PATH; - hr = WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + Log(L"Initialized."); - - MsiGetPropertyW (hInstall, L"SERVICENAME", ServiceName, &ServiceNameLen); - if(ServiceName[0]) + if (!GetProperty(hInstall, L"SERVICENAME", ServiceName) || + !GetProperty(hInstall, L"PASSWORD", Password) || + !GetProperty(hInstall, L"SKIPNETWORKING", SkipNetworking) || + !GetProperty(hInstall, L"PORT", Port) || + !GetProperty(hInstall, L"STDCONFIG", QuickConfig) || + !GetProperty(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize)) { - if(ServiceNameLen > 256) + er= ERROR_INSTALL_FAILURE; + ErrorMsg= L"Internal error, can't read installation properties."; + goto LExit; + } + + if(!ServiceName.empty()) + { + if(ServiceName.length() > MAX_SERVICENAME_LEN) { ErrorMsg= L"Invalid service name. The maximum length is 256 characters."; + tooLong= true; goto LExit; } - for(DWORD i=0; i< ServiceNameLen;i++) + if(ServiceName.find_first_of(L"\\/'\"") != std::wstring::npos) { - if(ServiceName[i] == L'\\' || ServiceName[i] == L'/' - || ServiceName[i]=='\'' || ServiceName[i] ==L'"') - { - ErrorMsg = - L"Invalid service name. Forward slash and back slash are forbidden." - L"Single and double quotes are also not permitted."; - goto LExit; - } + ErrorMsg = + L"Invalid service name. Forward slash and back slash are forbidden. " + L"Single and double quotes are also not permitted."; + goto LExit; } - if(CheckServiceExists(ServiceName)) + if(CheckServiceExists(ServiceName.c_str())) { ErrorMsg= L"A service with the same name already exists. " @@ -728,37 +797,38 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) } } - MsiGetPropertyW (hInstall, L"PASSWORD", Password, &PasswordLen); - EscapeCommandLine(Password, EscapedPassword, - sizeof(EscapedPassword)/sizeof(EscapedPassword[0])); - MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword); - - MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking, - &SkipNetworkingLen); - MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen); - - if(SkipNetworking[0]==0 && Port[0] != 0) + if(Password.length() > MAX_PASSWORD_LEN) { - /* Strip spaces */ - for(DWORD i=PortLen-1; i > 0; i--) - { - if(Port[i]== ' ') - Port[i] = 0; - } + ErrorMsg= L"The password is too long. The maximum length is 8192 characters."; + tooLong= true; + goto LExit; + } + EscapedPassword= EscapeCommandLine(Password); + MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword.c_str()); - if(PortLen > 5 || PortLen <= 3) + if(SkipNetworking.empty() && !Port.empty()) + { + bool haveInvalidPort= false; + + /* Strip trailing spaces */ + while(!Port.empty() && Port.back() == L' ') + Port.pop_back(); + + if(Port.length() > MAX_PORT_LEN || Port.length() < 4) haveInvalidPort = true; else { - for (DWORD i=0; i< PortLen && Port[i] != 0;i++) + for (wchar_t c : Port) { - if(Port[i] < '0' || Port[i] >'9') + if(c < L'0' || c > L'9') { haveInvalidPort=true; break; } } } + if(!haveInvalidPort && _wtoi(Port.c_str()) > 65535) + haveInvalidPort= true; if (haveInvalidPort) { ErrorMsg = @@ -766,7 +836,7 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) goto LExit; } - unsigned short port = (unsigned short)_wtoi(Port); + unsigned short port = (unsigned short)_wtoi(Port.c_str()); if (!IsPortFree(port)) { ErrorMsg = @@ -776,43 +846,35 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) } } - MsiGetPropertyW (hInstall, L"STDCONFIG", QuickConfig, &QuickConfigLen); - if(QuickConfig[0] !=0) + if(!QuickConfig.empty()) { MEMORYSTATUSEX memstatus; memstatus.dwLength =sizeof(memstatus); - wchar_t invalidValueMsg[256]; if (!GlobalMemoryStatusEx(&memstatus)) { - WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx", - GetLastError()); - er= ERROR_INSTALL_FAILURE; - goto LExit; - } - DWORD BufferPoolSizeLen= 16; - MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize, &BufferPoolSizeLen); - /* Strip spaces */ - for(DWORD i=BufferPoolSizeLen-1; i > 0; i--) - { - if(BufferPoolSize[i]== ' ') - BufferPoolSize[i] = 0; + Log(L"Error %u from GlobalMemoryStatusEx", GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; } + /* Strip trailing spaces */ + while(!BufferPoolSize.empty() && BufferPoolSize.back() == L' ') + BufferPoolSize.pop_back(); + unsigned long long availableMemory= GetMaxBufferSize(memstatus.ullTotalPhys)/ONE_MB; swprintf_s(invalidValueMsg, L"Invalid buffer pool size. Please use a number between %llu and %llu", minBufferpoolMB, availableMemory); - if (BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15 || !BufferPoolSize[0]) + if (BufferPoolSize.empty() || BufferPoolSize.length() > MAX_BUFFERPOOLSIZE_LEN) { ErrorMsg= invalidValueMsg; goto LExit; } - BufferPoolSize[BufferPoolSizeLen]=0; - MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize); + MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize.c_str()); wchar_t *end; - unsigned long long sz = wcstoull(BufferPoolSize, &end, 10); + unsigned long long sz = wcstoull(BufferPoolSize.c_str(), &end, 10); if (sz > availableMemory || sz < minBufferpoolMB || *end) { if (*end == 0) @@ -839,7 +901,17 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) } LExit: MsiSetPropertyW (hInstall, L"WarningText", ErrorMsg); - return WcaFinalize(er); + /* + Only the full UI shows the message. Without it, do not go on with a value + that was not accepted, e.g an empty password instead of a too long one. + */ + if (ErrorMsg && tooLong && + MsiEvaluateConditionW(hInstall, L"UILevel < 5") == MSICONDITION_TRUE) + { + Log(L"%s", ErrorMsg); + er= ERROR_INSTALL_FAILURE; + } + return er; } /* @@ -851,30 +923,41 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall) { unsigned long long InnodbBufferPoolSize= 256; unsigned long long InnodbLogFileSize= 100; - wchar_t buff[MAX_PATH]; + std::wstring BufferPoolSizeParam; + wchar_t buff[32]; UINT er = ERROR_SUCCESS; - HRESULT hr= S_OK; MEMORYSTATUSEX memstatus; - DWORD BufferPoolsizeParamLen = MAX_PATH; - hr = WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + Log(L"Initialized."); /* Check if bufferpoolsize parameter was given on the command line*/ - MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff, &BufferPoolsizeParamLen); - - if (BufferPoolsizeParamLen && buff[0]) + if (!GetProperty(hInstall, L"BUFFERPOOLSIZE", BufferPoolSizeParam)) { - WcaLog(LOGMSG_STANDARD, "BUFFERPOOLSIZE=%S, len=%u",buff, BufferPoolsizeParamLen); - InnodbBufferPoolSize= _wtoi64(buff); + er= ERROR_INSTALL_FAILURE; + goto LExit; + } + + while (!BufferPoolSizeParam.empty() && BufferPoolSizeParam.back() == L' ') + BufferPoolSizeParam.pop_back(); + if (BufferPoolSizeParam.length() > MAX_BUFFERPOOLSIZE_LEN || + BufferPoolSizeParam.find_first_not_of(L"0123456789") != std::wstring::npos) + { + Log(L"Invalid BUFFERPOOLSIZE %s is ignored, the default is used", + BufferPoolSizeParam.c_str()); + BufferPoolSizeParam.clear(); + } + + if (!BufferPoolSizeParam.empty()) + { + Log(L"BUFFERPOOLSIZE=%s, len=%u", BufferPoolSizeParam.c_str(), + (unsigned)BufferPoolSizeParam.length()); + InnodbBufferPoolSize= _wtoi64(BufferPoolSizeParam.c_str()); } else { memstatus.dwLength = sizeof(memstatus); if (!GlobalMemoryStatusEx(&memstatus)) { - WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx", - GetLastError()); + Log(L"Error %u from GlobalMemoryStatusEx",GetLastError()); er= ERROR_INSTALL_FAILURE; goto LExit; } @@ -898,37 +981,30 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall) MsiSetPropertyW(hInstall, L"LOGFILESIZE", buff); LExit: - return WcaFinalize(er); + return er; } -static BOOL FindErrorLog(const wchar_t *dir, wchar_t * ErrorLogFile, size_t ErrorLogLen) +static bool FindErrorLog(const std::wstring &dir, std::wstring &ErrorLogFile) { - WIN32_FIND_DATA FindFileData; - HANDLE hFind; - wchar_t name[MAX_PATH]; - wcsncpy_s(name,dir, MAX_PATH); - wcsncat_s(name,L"\\*.err", MAX_PATH); - hFind = FindFirstFileW(name,&FindFileData); - if (hFind != INVALID_HANDLE_VALUE) - { - _snwprintf(ErrorLogFile, ErrorLogLen, - L"%s\\%s",dir, FindFileData.cFileName); - FindClose(hFind); - return TRUE; - } - return FALSE; + WIN32_FIND_DATAW FindFileData; + HANDLE hFind= FindFirstFileW((dir + L"\\*.err").c_str(), &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + return false; + ErrorLogFile= dir + L"\\" + FindFileData.cFileName; + FindClose(hFind); + return true; } -static void DumpErrorLog(const wchar_t *dir) +static void DumpErrorLog(MSIHANDLE hInstall, const std::wstring &dir) { - wchar_t filepath[MAX_PATH]; - if (!FindErrorLog(dir, filepath, MAX_PATH)) + std::wstring filepath; + if (!FindErrorLog(dir, filepath)) return; - FILE *f= _wfopen(filepath, L"r"); + FILE *f= _wfopen(filepath.c_str(), L"r"); if (!f) return; char buf[2048]; - WcaLog(LOGMSG_STANDARD,"=== dumping error log %S === ",filepath); + Log(L"=== dumping error log %s === ",filepath.c_str()); while (fgets(buf, sizeof(buf), f)) { /* Strip off EOL chars. */ @@ -937,55 +1013,46 @@ static void DumpErrorLog(const wchar_t *dir) buf[--len]= 0; if (len > 0 && buf[len-1] == '\r') buf[--len]= 0; - WcaLog(LOGMSG_STANDARD,"%s",buf); + Log(L"%S",buf); } fclose(f); - WcaLog(LOGMSG_STANDARD,"=== end of error log ==="); + Log(L"=== end of error log ==="); } /* Remove service and data directory created by CreateDatabase operation */ extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall) { - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - wchar_t* service= 0; - wchar_t* dir= 0; - wchar_t data[2*MAX_PATH]; - DWORD len= MAX_PATH; + std::wstring data; + std::wstring service; + std::wstring dir; - hr = WcaInitialize(hInstall, __FUNCTION__); - ExitOnFailure(hr, "Failed to initialize"); - WcaLog(LOGMSG_STANDARD, "Initialized."); + Log(L"Initialized."); - MsiGetPropertyW(hInstall, L"CustomActionData", data, &len); + if (!GetProperty(hInstall, L"CustomActionData", data)) + return ERROR_INSTALL_FAILURE; /* Property is encoded as [SERVICENAME]\[DBLOCATION] */ - if(data[0] == L'\\') + size_t pos= data.find(L'\\'); + if (pos == std::wstring::npos) { - dir= data+1; + service= data; } else { - service= data; - dir= wcschr(data, '\\'); - if (dir) - { - *dir=0; - dir++; - } + service= data.substr(0, pos); + dir= data.substr(pos + 1); } - if(service) + if(!service.empty() && !ExecRemoveService(service.c_str())) + Log(L"Cannot remove service %s, error %u", service.c_str(), GetLastError()); + if(!dir.empty()) { - ExecRemoveService(service); + DumpErrorLog(hInstall,dir); + UINT rc= ExecRemoveDataDirectory(dir); + if (rc) + Log(L"Cannot remove directory %s, error %u", dir.c_str(), rc); } - if(dir) - { - DumpErrorLog(dir); - ExecRemoveDataDirectory(dir); - } -LExit: - return WcaFinalize(er); + return ERROR_SUCCESS; } @@ -993,15 +1060,12 @@ LExit: Enables/disables optional "Launch upgrade wizard" checkbox at the end of installation */ -#define MAX_VERSION_PROPERTY_SIZE 64 - extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) { - HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; - wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE]; - char installDir[MAX_PATH]; - DWORD size =MAX_VERSION_PROPERTY_SIZE; + std::wstring installerVersion; + std::wstring installDirW; + char installDir[MAX_PATH]= ""; int installerMajorVersion, installerMinorVersion, installerPatchVersion; bool upgradableServiceFound=false; LPENUM_SERVICE_STATUS_PROCESSW info; @@ -1010,35 +1074,29 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) BOOL ok; SC_HANDLE scm = NULL; - hr = WcaInitialize(hInstall, __FUNCTION__); - WcaLog(LOGMSG_STANDARD, "Initialized."); - if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size) - != ERROR_SUCCESS) + Log(L"Initialized."); + if (!GetProperty(hInstall, L"ProductVersion", installerVersion) || + !GetProperty(hInstall, L"INSTALLDIR", installDirW)) { - hr = HRESULT_FROM_WIN32(GetLastError()); - ExitOnFailure(hr, "MsiGetPropertyW failed"); + er= ERROR_INSTALL_FAILURE; + goto LExit; } - if (swscanf(installerVersion,L"%d.%d.%d", + if (swscanf(installerVersion.c_str(),L"%d.%d.%d", &installerMajorVersion, &installerMinorVersion, &installerPatchVersion) !=3) { assert(FALSE); } - - size= MAX_PATH; - if (MsiGetPropertyA(hInstall,"INSTALLDIR", installDir, &size) - != ERROR_SUCCESS) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - ExitOnFailure(hr, "MsiGetPropertyW failed"); - } + /* Same conversion as for mysqld_exe in winservice.c, to compare with it */ + wcstombs(installDir, installDirW.c_str(), MAX_PATH - 1); scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); if (scm == NULL) { - hr = HRESULT_FROM_WIN32(GetLastError()); - ExitOnFailure(hr,"OpenSCManager failed"); + Log(L"OpenSCManager failed with %u", GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; } static BYTE buf[64*1024]; @@ -1051,8 +1109,9 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL); if(!ok) { - hr = HRESULT_FROM_WIN32(GetLastError()); - ExitOnFailure(hr,"EnumServicesStatusEx failed"); + Log(L"EnumServicesStatusEx failed with %u", GetLastError()); + er= ERROR_INSTALL_FAILURE; + goto LExit; } info = (LPENUM_SERVICE_STATUS_PROCESSW)buf; @@ -1078,9 +1137,9 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) Only look for services that have mysqld.exe outside of the current installation directory. */ - if(installDir[0] == 0 || strstr(props.mysqld_exe,installDir) == 0) + if(installDir[0] == 0 || strstr(props.mysqld_exe, installDir) == 0) { - WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d", + Log(L"found service %s, major=%d, minor=%d", info[i].lpServiceName, props.version_major, props.version_minor); if(props.version_major < installerMajorVersion || (props.version_major == installerMajorVersion && @@ -1107,28 +1166,12 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) LExit: if(scm) CloseServiceHandle(scm); - return WcaFinalize(er); + return er; } - -/* DllMain - Initialize and cleanup WiX custom action utils */ -extern "C" BOOL WINAPI DllMain( - __in HINSTANCE hInst, - __in ULONG ulReason, - __in LPVOID - ) +/* Fail on purpose, to test rollback. Scheduled with TESTFAIL=1 in msiexec */ +extern "C" UINT __stdcall FakeFailure(MSIHANDLE hInstall) { - switch(ulReason) - { - case DLL_PROCESS_ATTACH: - WcaGlobalInitialize(hInst); - break; - - case DLL_PROCESS_DETACH: - WcaGlobalFinalize(); - break; - } - - return TRUE; + Log(L"Failing on purpose"); + return ERROR_INSTALL_FAILURE; } - diff --git a/win/packaging/ca/CustomAction.def b/win/packaging/ca/CustomAction.def index c18a0d92058..153079e6fd4 100644 --- a/win/packaging/ca/CustomAction.def +++ b/win/packaging/ca/CustomAction.def @@ -9,3 +9,4 @@ CheckDataDirectory CheckDBInUse CheckServiceUpgrades CheckInstallDirectory +FakeFailure diff --git a/win/packaging/create_msi.cmake b/win/packaging/create_msi.cmake index 20b139cf5d1..efd2cee4fd0 100644 --- a/win/packaging/create_msi.cmake +++ b/win/packaging/create_msi.cmake @@ -368,45 +368,145 @@ CONFIGURE_FILE(${SRCDIR}/mysql_server.wxs.in CONFIGURE_FILE(${SRCDIR}/extra.wxs.in ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs) -SET(EXTRA_CANDLE_ARGS "$ENV{EXTRA_CANDLE_ARGS}") +# Stop, if a WiX command failed. "what" tells which one. +FUNCTION(CHECK_WIX_RESULT result what) + IF(NOT "${result}" STREQUAL "0") + MESSAGE(FATAL_ERROR "${what} failed, exit code ${result}") + ENDIF() +ENDFUNCTION() -SET(EXTRA_LIGHT_ARGS -cc . -reusecab) -IF("$ENV{EXTRA_LIGHT_ARGS}") - SET(EXTRA_LIGHT_ARGS "$ENV{EXTRA_LIGHT_ARGS}") -ENDIF() - -FILE(REMOVE mysql_server.wixobj extra.wixobj) STRING(REPLACE " " ";" EXTRA_WIX_PREPROCESSOR_FLAGS_LIST ${EXTRA_WIX_PREPROCESSOR_FLAGS}) -EXECUTE_PROCESS( - COMMAND ${CANDLE_EXECUTABLE} - ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST} - ${CANDLE_ARCH} - -ext WixUtilExtension - -ext WixFirewallExtension - mysql_server.wxs - ${EXTRA_CANDLE_ARGS} -) -EXECUTE_PROCESS( - COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH} - ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST} - -ext WixUtilExtension - -ext WixFirewallExtension - ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs - ${EXTRA_CANDLE_ARGS} -) +IF(WIX_EXECUTABLE) + # WiX with the EULA check (7 and later) fails every command with WIX7015 + # until the EULA is accepted. Accept it only if asked to (WIX_ACCEPT_EULA) + # and only if WiX complains, "extension list" is the first command to try. + SET(WIX_EULA_ARGS) + EXECUTE_PROCESS( + COMMAND ${WIX_EXECUTABLE} extension list --global + OUTPUT_VARIABLE WIX_EXTENSION_LIST ERROR_VARIABLE WIX_EXTENSION_LIST + RESULT_VARIABLE res) + IF(WIX_EXTENSION_LIST MATCHES "WIX7015") + IF(NOT WIX_ACCEPT_EULA) + MESSAGE(FATAL_ERROR "${WIX_EXECUTABLE} requires its EULA to be accepted, " + "see https://wixtoolset.org/osmf/ . Use -DWIX_ACCEPT_EULA=ON to accept it") + ENDIF() + STRING(REGEX MATCH "^[0-9]+" WIX_MAJOR_VERSION "${WIX_VERSION}") + SET(WIX_EULA_ARGS -acceptEula wix${WIX_MAJOR_VERSION}) + EXECUTE_PROCESS( + COMMAND ${WIX_EXECUTABLE} ${WIX_EULA_ARGS} extension list --global + OUTPUT_VARIABLE WIX_EXTENSION_LIST ERROR_VARIABLE WIX_EXTENSION_LIST + RESULT_VARIABLE res) + ENDIF() + # With no extensions yet, "extension list" prints nothing and exits with 2. + # A failure that prints something is a real one, e.g missing .NET runtime. + IF(NOT "${res}" STREQUAL "0" AND NOT "${WIX_EXTENSION_LIST}" STREQUAL "") + MESSAGE(FATAL_ERROR + "wix extension list failed, exit code ${res}\n${WIX_EXTENSION_LIST}") + ENDIF() -IF(VCRedist_MSM) - SET(SILENCE_VCREDIST_MSM_WARNINGS -sice:ICE82 -sice:ICE03) + # Modern WiX. Convert wxs sources from v3 to the current XML schema first. + # Conversion messages are noisy, only show them if conversion fails. + SET(WIX_CONVERT_FILES mysql_server.wxs extra.wxs) + FOREACH(third_party ${WITH_THIRD_PARTY}) + LIST(APPEND WIX_CONVERT_FILES ${third_party}.wxi ${third_party}_feature.wxi) + ENDFOREACH() + # Note: "wix convert" exit code is the number of messages, not an error + # indicator. Look for real errors in the output instead. WIX0070 is a + # harmless advisory about removed TARGETDIR DirectoryRef (standard + # directories referenced from it are just promoted to top level). + EXECUTE_PROCESS( + COMMAND ${WIX_EXECUTABLE} ${WIX_EULA_ARGS} convert ${WIX_CONVERT_FILES} + OUTPUT_VARIABLE convert_output ERROR_VARIABLE convert_output + RESULT_VARIABLE res) + STRING(REGEX REPLACE "[^\n]*WIX0070[^\n]*" "" convert_errors "${convert_output}") + IF(convert_errors MATCHES "error WIX" + OR (res AND NOT convert_output MATCHES "\\[Converted\\]")) + MESSAGE(FATAL_ERROR "wix convert failed: ${res}\n${convert_output}") + ENDIF() + + # Extensions are versioned, must match the toolset version, and need + # to be added (downloaded from nuget.org) before first use. + SET(WIX_EXTENSIONS + WixToolset.UI.wixext + WixToolset.Util.wixext + WixToolset.Firewall.wixext) + SET(WIX_EXTENSION_ARGS) + FOREACH(ext ${WIX_EXTENSIONS}) + IF(NOT WIX_EXTENSION_LIST MATCHES "${ext}[/ ]+${WIX_VERSION}") + EXECUTE_PROCESS( + COMMAND ${WIX_EXECUTABLE} ${WIX_EULA_ARGS} extension add --global ${ext}/${WIX_VERSION} + RESULT_VARIABLE res) + CHECK_WIX_RESULT("${res}" "wix extension add ${ext}/${WIX_VERSION}") + ENDIF() + LIST(APPEND WIX_EXTENSION_ARGS -ext "${ext}/${WIX_VERSION}") + ENDFOREACH() + + # wix.exe needs the -d flag and the definition as separate arguments + SET(WIX_DEFINE_ARGS) + FOREACH(flag ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST}) + STRING(REGEX REPLACE "^-d" "" def "${flag}") + LIST(APPEND WIX_DEFINE_ARGS -d "${def}") + ENDFOREACH() + + EXECUTE_PROCESS( + COMMAND ${WIX_EXECUTABLE} ${WIX_EULA_ARGS} build + -arch ${Platform} + ${WIX_DEFINE_ARGS} + ${WIX_EXTENSION_ARGS} + -sw1103 + -cabcache . + mysql_server.wxs extra.wxs + -out ${CPACK_PACKAGE_FILE_NAME}.msi + RESULT_VARIABLE res + ) + CHECK_WIX_RESULT("${res}" "wix build") +ELSE() + SET(EXTRA_CANDLE_ARGS "$ENV{EXTRA_CANDLE_ARGS}") + + SET(EXTRA_LIGHT_ARGS -cc . -reusecab) + IF("$ENV{EXTRA_LIGHT_ARGS}") + SET(EXTRA_LIGHT_ARGS "$ENV{EXTRA_LIGHT_ARGS}") + ENDIF() + + FILE(REMOVE mysql_server.wixobj extra.wixobj) + EXECUTE_PROCESS( + COMMAND ${CANDLE_EXECUTABLE} + ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST} + ${CANDLE_ARCH} + -ext WixUtilExtension + -ext WixFirewallExtension + mysql_server.wxs + ${EXTRA_CANDLE_ARGS} + RESULT_VARIABLE res + ) + CHECK_WIX_RESULT("${res}" "candle mysql_server.wxs") + + EXECUTE_PROCESS( + COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH} + ${EXTRA_WIX_PREPROCESSOR_FLAGS_LIST} + -ext WixUtilExtension + -ext WixFirewallExtension + ${CMAKE_CURRENT_BINARY_DIR}/extra.wxs + ${EXTRA_CANDLE_ARGS} + RESULT_VARIABLE res + ) + CHECK_WIX_RESULT("${res}" "candle extra.wxs") + + IF(VCRedist_MSM) + SET(SILENCE_VCREDIST_MSM_WARNINGS -sice:ICE82 -sice:ICE03) + ENDIF() + + EXECUTE_PROCESS( + COMMAND ${LIGHT_EXECUTABLE} -v -ext WixUIExtension -ext WixUtilExtension + -ext WixFirewallExtension -sice:ICE61 -sw1103 ${SILENCE_VCREDIST_MSM_WARNINGS} + mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi + ${EXTRA_LIGHT_ARGS} + RESULT_VARIABLE res + ) + CHECK_WIX_RESULT("${res}" "light") ENDIF() -EXECUTE_PROCESS( - COMMAND ${LIGHT_EXECUTABLE} -v -ext WixUIExtension -ext WixUtilExtension - -ext WixFirewallExtension -sice:ICE61 -sw1103 ${SILENCE_VCREDIST_MSM_WARNINGS} - mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi - ${EXTRA_LIGHT_ARGS} -) - IF(SIGNCODE) SEPARATE_ARGUMENTS(SIGNTOOL_PARAMETERS WINDOWS_COMMAND "${SIGNTOOL_PARAMETERS}") EXECUTE_PROCESS( diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index bf8fe00d107..16a61513158 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -45,8 +45,7 @@ - - + @@ -416,6 +415,8 @@ + + @@ -657,17 +658,10 @@ Running mariadb-install-db.exe - - - - +