From fd247cc21fbc975fbc7f20ef2c4e722f13552330 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 26 Apr 2023 15:27:01 +0400 Subject: [PATCH] MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() This patch also fixes: MDEV-33050 Build-in schemas like oracle_schema are accent insensitive MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 MDEV-33088 Cannot create triggers in the database `MYSQL` MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 - Removing the virtual function strnncoll() from MY_COLLATION_HANDLER - Adding a wrapper function CHARSET_INFO::streq(), to compare two strings for equality. For now it calls strnncoll() internally. In the future it will turn into a virtual function. - Adding new accent sensitive case insensitive collations: - utf8mb4_general1400_as_ci - utf8mb3_general1400_as_ci They implement accent sensitive case insensitive comparison. The weight of a character is equal to the code point of its upper case variant. These collations use Unicode-14.0.0 casefolding data. The result of my_charset_utf8mb3_general1400_as_ci.strcoll() is very close to the former my_charset_utf8mb3_general_ci.strcasecmp() There is only a difference in a couple dozen rare characters, because: - the switch from "tolower" to "toupper" comparison, to make utf8mb3_general1400_as_ci closer to utf8mb3_general_ci - the switch from Unicode-3.0.0 to Unicode-14.0.0 This difference should be tolarable. See the list of affected characters in the MDEV description. Note, utf8mb4_general1400_as_ci correctly handles non-BMP characters! Unlike utf8mb4_general_ci, it does not treat all BMP characters as equal. - Adding classes representing names of the file based database objects: Lex_ident_db Lex_ident_table Lex_ident_trigger Their comparison collation depends on the underlying file system case sensitivity and on --lower-case-table-names and can be either my_charset_bin or my_charset_utf8mb3_general1400_as_ci. - Adding classes representing names of other database objects, whose names have case insensitive comparison style, using my_charset_utf8mb3_general1400_as_ci: Lex_ident_column Lex_ident_sys_var Lex_ident_user_var Lex_ident_sp_var Lex_ident_ps Lex_ident_i_s_table Lex_ident_window Lex_ident_func Lex_ident_partition Lex_ident_with_element Lex_ident_rpl_filter Lex_ident_master_info Lex_ident_host Lex_ident_locale Lex_ident_plugin Lex_ident_engine Lex_ident_server Lex_ident_savepoint Lex_ident_charset engine_option_value::Name - All the mentioned Lex_ident_xxx classes implement a method streq(): if (ident1.streq(ident2)) do_equal(); This method works as a wrapper for CHARSET_INFO::streq(). - Changing a lot of "LEX_CSTRING name" to "Lex_ident_xxx name" in class members and in function/method parameters. - Replacing all calls like system_charset_info->coll->strcasecmp(ident1, ident2) to ident1.streq(ident2) - Taking advantage of the c++11 user defined literal operator for LEX_CSTRING (see m_strings.h) and Lex_ident_xxx (see lex_ident.h) data types. Use example: const Lex_ident_column primary_key_name= "PRIMARY"_Lex_ident_column; is now a shorter version of: const Lex_ident_column primary_key_name= Lex_ident_column({STRING_WITH_LEN("PRIMARY")}); --- client/mysql.cc | 6 +- client/mysqlcheck.c | 10 +- client/mysqldump.cc | 45 +- client/mysqlshow.c | 2 +- include/ft_global.h | 2 - include/m_ctype.h | 50 +- include/m_string.h | 9 + mysql-test/main/ctype_like_range.result | 15 + mysql-test/main/ctype_like_range.test | 18 + .../ctype_utf8mb3_geeral1400_as_ci.result | 25 + .../main/ctype_utf8mb3_geeral1400_as_ci.test | 25 + ..._utf8mb4_general1400_as_ci_casefold.result | 2984 +++++++++++++++++ ...pe_utf8mb4_general1400_as_ci_casefold.test | 15 + .../ctype_utf8mb4_general1400_as_ci_ws.result | 1482 ++++++++ .../ctype_utf8mb4_general1400_as_ci_ws.test | 39 + mysql-test/main/identifier.result | 128 + mysql-test/main/identifier.test | 154 + mysql-test/main/identifier_partition.result | 50 + mysql-test/main/identifier_partition.test | 49 + mysql-test/main/lowercase_table.result | 17 + mysql-test/main/lowercase_table.test | 23 + mysql-test/main/lowercase_table2.result | 8 + mysql-test/main/lowercase_table2.test | 13 + mysql-test/main/lowercase_table4.result | 0 mysql-test/main/lowercase_table5.result | 137 + mysql-test/main/lowercase_table5.test | 133 + mysql-test/main/subselect.test | 1 + mysql-test/main/view_grant.result | 31 + mysql-test/main/view_grant.test | 26 + .../oracle/r/lower_case_table_names.result | 9 + .../oracle/t/lower_case_table_names.opt | 1 + .../oracle/t/lower_case_table_names.test | 9 + mysql-test/suite/csv/lowercase_table0.result | 15 + mysql-test/suite/csv/lowercase_table0.test | 16 + .../funcs/r/db_alter_collate_ascii.result | 2 + .../funcs/r/db_alter_collate_utf8.result | 2 + .../suite/innodb_fts/r/innodb-fts-ddl.result | 9 +- .../suite/innodb_fts/t/innodb-fts-ddl.test | 11 +- mysql-test/suite/unit/disabled.def | 12 + mysys/charset-def.c | 2 + mysys/charset.c | 6 +- mysys/hash.c | 5 +- mysys/my_access.c | 2 +- mysys/my_getopt.c | 29 +- plugin/feedback/sender_thread.cc | 2 +- plugin/func_test/plugin.cc | 4 +- plugin/locale_info/locale_info.cc | 2 +- plugin/qc_info/qc_info.cc | 2 +- plugin/versioning/versioning.cc | 1 - sql/create_options.cc | 37 +- sql/create_options.h | 27 +- sql/ddl_log.cc | 33 +- sql/debug_sync.cc | 91 +- sql/field.cc | 18 +- sql/field.h | 38 +- sql/grant.cc | 4 +- sql/ha_partition.cc | 33 +- sql/handler.cc | 98 +- sql/handler.h | 43 +- sql/item.cc | 92 +- sql/item.h | 44 +- sql/item_create.cc | 25 +- sql/item_create.h | 2 +- sql/item_func.cc | 36 +- sql/item_func.h | 4 - sql/item_strfunc.cc | 12 +- sql/item_strfunc.h | 40 +- sql/item_windowfunc.cc | 9 +- sql/json_table.cc | 3 +- sql/lex_ident.h | 377 ++- sql/lex_string.h | 35 +- sql/log.cc | 11 +- sql/mysqld.cc | 22 +- sql/mysqld.h | 4 +- sql/opt_subselect.cc | 6 +- sql/opt_trace.cc | 9 +- sql/partition_element.h | 5 +- sql/partition_info.cc | 92 +- sql/partition_info.h | 18 +- sql/procedure.cc | 15 +- sql/rpl_filter.cc | 7 +- sql/rpl_mi.cc | 3 +- sql/set_var.cc | 49 +- sql/set_var.h | 6 +- sql/slave.cc | 5 +- sql/sp.cc | 30 +- sql/sp.h | 6 - sql/sp_head.cc | 44 +- sql/sp_head.h | 5 +- sql/sp_pcontext.cc | 27 +- sql/sp_pcontext.h | 32 +- sql/sp_rcontext.cc | 12 +- sql/sql_acl.cc | 759 +++-- sql/sql_acl.h | 44 +- sql/sql_alter.cc | 18 +- sql/sql_alter.h | 11 +- sql/sql_base.cc | 240 +- sql/sql_base.h | 16 +- sql/sql_class.cc | 61 +- sql/sql_class.h | 105 +- sql/sql_connect.cc | 17 +- sql/sql_cte.cc | 6 +- sql/sql_cte.h | 8 +- sql/sql_cursor.cc | 5 +- sql/sql_db.cc | 38 +- sql/sql_handler.cc | 11 +- sql/sql_i_s.h | 24 +- sql/sql_insert.cc | 2 +- sql/sql_lex.cc | 82 +- sql/sql_lex.h | 25 +- sql/sql_locale.cc | 232 +- sql/sql_locale.h | 7 +- sql/sql_parse.cc | 86 +- sql/sql_partition.cc | 58 +- sql/sql_partition.h | 22 +- sql/sql_partition_admin.cc | 9 +- sql/sql_plugin.cc | 34 +- sql/sql_rename.cc | 41 +- sql/sql_schema.cc | 2 +- sql/sql_schema.h | 9 +- sql/sql_select.cc | 38 +- sql/sql_sequence.cc | 7 +- sql/sql_servers.cc | 4 +- sql/sql_show.cc | 297 +- sql/sql_statistics.cc | 18 +- sql/sql_statistics.h | 2 +- sql/sql_table.cc | 439 ++- sql/sql_table.h | 5 +- sql/sql_trigger.cc | 57 +- sql/sql_trigger.h | 18 +- sql/sql_truncate.cc | 12 +- sql/sql_type.cc | 6 +- sql/sql_udf.cc | 5 +- sql/sql_view.cc | 21 +- sql/sql_window.cc | 35 +- sql/sql_window.h | 8 +- sql/sql_yacc.yy | 89 +- sql/structs.h | 18 +- sql/sys_vars.cc | 9 +- sql/table.cc | 156 +- sql/table.h | 90 +- sql/temporary_tables.cc | 31 +- sql/transaction.cc | 18 +- sql/tztime.cc | 2 +- sql/unireg.cc | 2 +- sql/vers_string.h | 81 - sql/wsrep_mysqld.cc | 11 +- storage/blackhole/ha_blackhole.cc | 3 +- storage/connect/connect.cc | 1 - storage/connect/ha_connect.cc | 2 - storage/csv/ha_tina.cc | 3 +- storage/federatedx/federatedx_pushdown.cc | 18 +- storage/innobase/dict/dict0crea.cc | 13 +- storage/innobase/dict/dict0dict.cc | 143 +- storage/innobase/dict/dict0load.cc | 8 +- storage/innobase/dict/dict0mem.cc | 10 +- storage/innobase/dict/dict0stats.cc | 38 +- storage/innobase/fsp/fsp0space.cc | 4 +- storage/innobase/fts/fts0fts.cc | 31 +- storage/innobase/handler/ha_innodb.cc | 122 +- storage/innobase/handler/ha_innodb.h | 8 +- storage/innobase/handler/handler0alter.cc | 165 +- storage/innobase/include/dict0dict.h | 8 +- storage/innobase/include/dict0mem.h | 22 +- storage/innobase/include/fts0fts.h | 7 +- storage/innobase/include/ha_prototypes.h | 9 - storage/innobase/pars/pars0pars.cc | 12 +- storage/innobase/row/row0import.cc | 2 +- storage/innobase/row/row0ins.cc | 5 +- storage/innobase/row/row0merge.cc | 4 +- storage/innobase/row/row0quiesce.cc | 8 +- storage/mroonga/ha_mroonga.cpp | 12 +- storage/perfschema/ha_perfschema.cc | 27 +- storage/perfschema/pfs_engine_table.cc | 26 +- storage/perfschema/pfs_engine_table.h | 18 +- storage/perfschema/pfs_server.cc | 32 +- storage/perfschema/pfs_server.h | 4 +- storage/perfschema/pfs_variable.cc | 20 +- storage/rocksdb/ha_rocksdb.cc | 8 +- storage/rocksdb/rdb_datadic.cc | 13 +- storage/sequence/sequence.cc | 10 +- storage/spider/spd_db_mysql.cc | 6 +- storage/spider/spd_table.cc | 4 +- strings/ctype-big5.c | 4 - strings/ctype-bin.c | 10 - strings/ctype-cp932.c | 4 - strings/ctype-czech.c | 1 - strings/ctype-euc_kr.c | 4 - strings/ctype-eucjpms.c | 4 - strings/ctype-gb2312.c | 4 - strings/ctype-gbk.c | 4 - strings/ctype-latin1.c | 1 - strings/ctype-mb.c | 37 - strings/ctype-simple.c | 2 - strings/ctype-sjis.c | 4 - strings/ctype-tis620.c | 2 - strings/ctype-uca.inl | 4 - strings/ctype-ucs2.c | 27 - strings/ctype-ujis.c | 4 - strings/ctype-unidata.h | 31 +- strings/ctype-utf8.c | 564 ++-- strings/ctype-win1250ch.c | 1 - strings/strcoll.inl | 32 +- strings/string.doc | 5 - 204 files changed, 8971 insertions(+), 3202 deletions(-) create mode 100644 mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.result create mode 100644 mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.test create mode 100644 mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.result create mode 100644 mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.test create mode 100644 mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.result create mode 100644 mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.test create mode 100644 mysql-test/main/identifier.result create mode 100644 mysql-test/main/identifier.test create mode 100644 mysql-test/main/identifier_partition.result create mode 100644 mysql-test/main/identifier_partition.test mode change 100755 => 100644 mysql-test/main/lowercase_table2.result mode change 100755 => 100644 mysql-test/main/lowercase_table4.result create mode 100644 mysql-test/suite/compat/oracle/r/lower_case_table_names.result create mode 100644 mysql-test/suite/compat/oracle/t/lower_case_table_names.opt create mode 100644 mysql-test/suite/compat/oracle/t/lower_case_table_names.test create mode 100644 mysql-test/suite/csv/lowercase_table0.result create mode 100644 mysql-test/suite/csv/lowercase_table0.test create mode 100644 mysql-test/suite/unit/disabled.def delete mode 100644 sql/vers_string.h diff --git a/client/mysql.cc b/client/mysql.cc index 9ef1b75d5bd..d87c0b73aaa 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -207,9 +207,9 @@ static void my_vidattr(chtype attrs) #endif #ifdef FN_NO_CASE_SENSE -#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B)) +#define cmp_database(A,B) my_strcasecmp_latin1((A), (B)) #else -#define cmp_database(cs,A,B) strcmp((A),(B)) +#define cmp_database(A,B) strcmp((A),(B)) #endif #include "completion_hash.h" @@ -4764,7 +4764,7 @@ com_use(String *buffer __attribute__((unused)), char *line) */ get_current_db(); - if (!current_db || cmp_database(charset_info, current_db,tmp)) + if (!current_db || cmp_database(current_db, tmp)) { if (one_database) { diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index d3bacad93bd..1465385bd63 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -247,6 +247,12 @@ static char *fix_table_name(char *dest, char *src); int what_to_do = 0; +static inline int cmp_database(const char *a, const char *b) +{ + return my_strcasecmp_latin1(a, b); +} + + static void usage(void) { DBUG_ENTER("usage"); @@ -869,10 +875,10 @@ static int use_db(char *database) DBUG_ENTER("use_db"); if (mysql_get_server_version(sock) >= FIRST_INFORMATION_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, database, INFORMATION_SCHEMA_DB_NAME)) + !cmp_database(database, INFORMATION_SCHEMA_DB_NAME)) DBUG_RETURN(1); if (mysql_get_server_version(sock) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, database, PERFORMANCE_SCHEMA_DB_NAME)) + !cmp_database(database, PERFORMANCE_SCHEMA_DB_NAME)) DBUG_RETURN(1); if (mysql_select_db(sock, database)) { diff --git a/client/mysqldump.cc b/client/mysqldump.cc index 1b05e45f478..98a6579df66 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -658,6 +658,19 @@ static int dump_tablespaces_for_databases(char** databases); static int dump_tablespaces(char* ts_where); static void print_comment(FILE *, my_bool, const char *, ...); + +static inline int cmp_database(const char *a, const char *b) +{ + return my_strcasecmp_latin1(a, b); +} + + +static inline int cmp_table(const char *a, const char *b) +{ + return my_strcasecmp_latin1(a, b); +} + + /* Print the supplied message if in verbose mode @@ -2993,10 +3006,10 @@ static uint dump_routines_for_db(char *db) static inline my_bool general_log_or_slow_log_tables(const char *db, const char *table) { - return (!my_strcasecmp(charset_info, db, "mysql")) && - (!my_strcasecmp(charset_info, table, "general_log") || - !my_strcasecmp(charset_info, table, "slow_log") || - !my_strcasecmp(charset_info, table, "transaction_registry")); + return (!cmp_database(db, "mysql")) && + (!cmp_table(table, "general_log") || + !cmp_table(table, "slow_log") || + !cmp_table(table, "transaction_registry")); } /* get_sequence_structure-- retrieves sequence structure, prints out corresponding @@ -4165,8 +4178,8 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, discarding SHOW CREATE EVENT statements generation. The myslq.event table data should be skipped too. */ - if (!opt_events && !my_strcasecmp(&my_charset_latin1, db, "mysql") && - !my_strcasecmp(&my_charset_latin1, table, "event")) + if (!opt_events && !cmp_database(db, "mysql") && + !cmp_table(table, "event")) { verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n"); DBUG_VOID_RETURN; @@ -5430,15 +5443,15 @@ static int dump_all_databases() while ((row= mysql_fetch_row(tableres))) { if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + !cmp_database(row[0], INFORMATION_SCHEMA_DB_NAME)) continue; if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) + !cmp_database(row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], SYS_SCHEMA_DB_NAME)) + !cmp_database(row[0], SYS_SCHEMA_DB_NAME)) continue; if (include_database(row[0])) @@ -5458,15 +5471,15 @@ static int dump_all_databases() while ((row= mysql_fetch_row(tableres))) { if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + !cmp_database(row[0], INFORMATION_SCHEMA_DB_NAME)) continue; if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) + !cmp_database(row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, row[0], SYS_SCHEMA_DB_NAME)) + !cmp_database(row[0], SYS_SCHEMA_DB_NAME)) continue; if (include_database(row[0])) @@ -5676,7 +5689,7 @@ static int dump_all_tables_in_db(char *database) char hash_key[2*NAME_LEN+2]; /* "db.tablename" */ char *afterdot; my_bool transaction_registry_table_exists= 0; - int using_mysql_db= !my_strcasecmp(charset_info, database, "mysql"); + int using_mysql_db= !cmp_database(database, "mysql"); DBUG_ENTER("dump_all_tables_in_db"); afterdot= strmov(hash_key, database); @@ -5787,7 +5800,7 @@ static int dump_all_tables_in_db(char *database) after 'UNLOCK TABLES' query is executed on the session, get the table structure from server and dump it in the file. */ - if (using_mysql_db && !my_strcasecmp(charset_info, table, "transaction_registry")) + if (using_mysql_db && !cmp_table(table, "transaction_registry")) transaction_registry_table_exists= 1; } } @@ -6070,9 +6083,9 @@ static int dump_selected_tables(char *db, char **table_names, int tables) /* Can't LOCK TABLES in I_S / P_S, so don't try. */ if (lock_tables && !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) && + !cmp_database(db, INFORMATION_SCHEMA_DB_NAME)) && !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME))) + !cmp_database(db, PERFORMANCE_SCHEMA_DB_NAME))) { if (mysql_real_query(mysql, lock_tables_query.str, (ulong)lock_tables_query.length-1)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index ddaa65ace3b..1de8c7eb9bd 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -413,7 +413,7 @@ list_dbs(MYSQL *mysql,const char *wild) if (wild && mysql_num_rows(result) == 1) { row= mysql_fetch_row(result); - if (!my_strcasecmp(&my_charset_latin1, row[0], wild)) + if (!my_strcasecmp_latin1(row[0], wild)) { mysql_free_result(result); if (opt_status) diff --git a/include/ft_global.h b/include/ft_global.h index 9f2d52610ba..7ce7a21edd2 100644 --- a/include/ft_global.h +++ b/include/ft_global.h @@ -56,8 +56,6 @@ struct _ft_vft_ext #define FTS_ORDERED_RESULT (1LL << 1) #define FTS_DOCID_IN_RESULT (1LL << 2) -#define FTS_DOC_ID_COL_NAME "FTS_DOC_ID" - #ifndef FT_CORE struct st_ft_info { diff --git a/include/m_ctype.h b/include/m_ctype.h index 8159e9ce7ee..33362045284 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -547,8 +547,6 @@ struct my_collation_handler_st const char *wildstr,const char *wildend, int escape,int w_one, int w_many); - int (*strcasecmp)(CHARSET_INFO *, const char *, const char *); - uint (*instr)(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, @@ -804,6 +802,17 @@ struct charset_info_st #ifdef __cplusplus /* Character set routines */ + + /* Make sure the comparison operand is valid. */ + static bool is_valid_string(const LEX_CSTRING &str) + { + /* + LEX_CSTRING::str can be NULL, but only if LEX_CSTRING::length is 0. + Does not have to be a 0-terminated string. + */ + return str.str != NULL || str.length == 0; + } + bool use_mb() const { return mbmaxlen > 1; @@ -1027,6 +1036,26 @@ struct charset_info_st return state & MY_CS_COMPILED; } + /* + Compare two strings for equality. + There may be a separate more optimized virtual function streq() in + MY_COLLATION_HANDLER eventually. For now it's a wrapper for strnncoll(). + */ + my_bool streq(const LEX_CSTRING a, const LEX_CSTRING b) const + { + return 0 == strnncoll(a, b, FALSE); + } + + int strnncoll(const LEX_CSTRING a, const LEX_CSTRING b, + my_bool b_is_prefix= FALSE) const + { + DBUG_ASSERT(is_valid_string(a)); + DBUG_ASSERT(is_valid_string(b)); + return (coll->strnncoll)(this, + (const uchar *) a.str, a.length, + (const uchar *) b.str, b.length, b_is_prefix); + } + int strnncoll(const uchar *a, size_t alen, const uchar *b, size_t blen, my_bool b_is_prefix= FALSE) const { @@ -1392,6 +1421,10 @@ extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_latin1_nopad; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_filename; extern MYSQL_PLUGIN_IMPORT struct charset_info_st my_charset_utf8mb3_general_ci; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st + my_charset_utf8mb3_general1400_as_ci; +extern MYSQL_PLUGIN_IMPORT struct charset_info_st + my_charset_utf8mb4_general1400_as_ci; extern struct charset_info_st my_charset_big5_bin; extern struct charset_info_st my_charset_big5_chinese_ci; @@ -1658,7 +1691,6 @@ extern size_t my_caseup_ujis(CHARSET_INFO *, extern size_t my_casedn_ujis(CHARSET_INFO *, const char *src, size_t srclen, char *dst, size_t dstlen); -extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *); int my_wildcmp_mb(CHARSET_INFO *, const char *str,const char *str_end, @@ -1677,9 +1709,6 @@ int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many); -int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), - const char *s, const char *t); - void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)), const uchar *key, size_t len,ulong *nr1, ulong *nr2); @@ -1838,7 +1867,6 @@ size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, #define my_binary_compare(s) ((s)->state & MY_CS_BINSORT) #define use_strnxfrm(s) ((s)->state & MY_CS_STRNXFRM) #define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d), 0)) -#define my_strcasecmp(s, a, b) ((s)->coll->strcasecmp((s), (a), (b))) /** Detect if the leftmost character in a string is a valid multi-byte character @@ -1886,6 +1914,14 @@ my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e, } +static inline int +my_strcasecmp_latin1(const char *a, const char *b) +{ + return my_strcasecmp_8bit(&my_charset_latin1, a, b); +} + + + /* XXX: still need to take care of this one */ #ifdef MY_CHARSET_TIS620 #error The TIS620 charset is broken at the moment. Tell tim to fix it. diff --git a/include/m_string.h b/include/m_string.h index fcbb3769192..cff89a660d9 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -220,6 +220,15 @@ template inline constexpr const char *_swl_check(T s) typedef struct st_mysql_const_lex_string LEX_CSTRING; +#ifdef __cplusplus +static inline constexpr +LEX_CSTRING operator"" _LEX_CSTRING(const char *str, size_t length) +{ + return LEX_CSTRING{str, length}; +} +#endif /* __cplusplus */ + + /* A variant with const and unsigned */ struct st_mysql_const_unsigned_lex_string { diff --git a/mysql-test/main/ctype_like_range.result b/mysql-test/main/ctype_like_range.result index e5e5e61126b..ec54d95540a 100644 --- a/mysql-test/main/ctype_like_range.result +++ b/mysql-test/main/ctype_like_range.result @@ -4477,3 +4477,18 @@ DROP TABLE t1; # # End of 10.2 tests # +# +# Start of 11.5 tests +# +# +# MDEV-33806 Server crashes when executing Admin SQL/DML after setting character_set_collations to utf8mb3_general1400_as_ci +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general1400_as_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MAX(a,40)) FROM t1 ORDER BY a; +a HEX(LIKE_RANGE_MAX(a,40)) +111% 313131EFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBFEFBFBF20 +DROP TABLE t1; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/ctype_like_range.test b/mysql-test/main/ctype_like_range.test index 3055abe5f59..7f00964ddb7 100644 --- a/mysql-test/main/ctype_like_range.test +++ b/mysql-test/main/ctype_like_range.test @@ -197,3 +197,21 @@ DROP TABLE t1; --echo # --echo # End of 10.2 tests --echo # + + +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-33806 Server crashes when executing Admin SQL/DML after setting character_set_collations to utf8mb3_general1400_as_ci +--echo # + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general1400_as_ci); +INSERT INTO t1 VALUES ('111%'); +SELECT a, HEX(LIKE_RANGE_MAX(a,40)) FROM t1 ORDER BY a; +DROP TABLE t1; + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.result b/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.result new file mode 100644 index 00000000000..ee5f019b2c0 --- /dev/null +++ b/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.result @@ -0,0 +1,25 @@ +# +# Start of 11.5 tests +# +# +# MDEV-33806 Server crashes when executing Admin SQL/DML after setting character_set_collations to utf8mb3_general1400_as_ci +# +CREATE TABLE t1(a CHAR (32),KEY (a)) DEFAULT CHARSET=utf8mb3 COLLATE utf8mb3_general1400_as_ci; +SELECT * FROM t1 WHERE a LIKE 'a%'; +a +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE a LIKE 'a%'; +a +a +FOR i IN 0..32 +DO +INSERT INTO t1 VALUES (CONCAT('b', i)); +END FOR; +$$ +SELECT * FROM t1 WHERE a LIKE 'a%'; +a +a +DROP TABLE t1; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.test b/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.test new file mode 100644 index 00000000000..405e3326885 --- /dev/null +++ b/mysql-test/main/ctype_utf8mb3_geeral1400_as_ci.test @@ -0,0 +1,25 @@ +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-33806 Server crashes when executing Admin SQL/DML after setting character_set_collations to utf8mb3_general1400_as_ci +--echo # + +CREATE TABLE t1(a CHAR (32),KEY (a)) DEFAULT CHARSET=utf8mb3 COLLATE utf8mb3_general1400_as_ci; +SELECT * FROM t1 WHERE a LIKE 'a%'; +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE a LIKE 'a%'; +DELIMITER $$; +FOR i IN 0..32 +DO + INSERT INTO t1 VALUES (CONCAT('b', i)); +END FOR; +$$ +DELIMITER ;$$ +SELECT * FROM t1 WHERE a LIKE 'a%'; +DROP TABLE t1; + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.result b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.result new file mode 100644 index 00000000000..21ad396fe52 --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.result @@ -0,0 +1,2984 @@ +# +# Start of 11.5 tests +# +# +# MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +# +SET NAMES utf8mb4 COLLATE utf8mb4_general1400_as_ci; +EXECUTE IMMEDIATE SFORMAT(' +CREATE VIEW v_bmp AS +SELECT + seq AS codepoint, + LPAD(HEX(seq),4,''0'') AS codepoint_hex4, + CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c +FROM + seq_0_to_65535', @@character_set_connection, @@collation_connection); +SELECT COLLATION(c) FROM v_bmp LIMIT 1; +COLLATION(c) +utf8mb4_general1400_as_ci +# +# BMP character summary +# +SELECT +BINARY(c)=BINARY(LOWER(c)) AS `Bc=BLc`, +BINARY(c)=BINARY(UPPER(c)) AS `Bc=BUc`, +c=LOWER(c) AS `c=L(c)`, +c=UPPER(c) AS `c=U(c)`, +c LIKE LOWER(c) AS `c~~L(c)`, +c LIKE UPPER(c) AS `c~~U(c)`, +COUNT(*), +IF(BINARY(c)=BINARY(LOWER(c)) AND BINARY(c)=BINARY(UPPER(c)),'', +LEFT(GROUP_CONCAT(c ORDER BY codepoint), 20)) AS example +FROM v_bmp +GROUP BY 1, 2, 3, 4, 5, 6; +Bc=BLc Bc=BUc c=L(c) c=U(c) c~~L(c) c~~U(c) COUNT(*) example +0 0 1 1 1 1 4 Dž,Lj,Nj,Dz +0 1 0 1 0 1 6 İ,ϴ,ẞ,Ω,K,Å +0 1 1 1 1 1 1163 A,B,C,D,E,F,G,H,I,J, +1 0 1 1 1 1 1186 a,b,c,d,e,f,g,h,i,j, +1 1 1 1 1 1 63177 +# +# BMP characters with upper/lower mapping +# +SELECT +codepoint_hex4, +HEX(CAST(LOWER(c) AS CHAR CHARACTER SET ucs2)), +HEX(CAST(UPPER(c) AS CHAR CHARACTER SET ucs2)) +FROM v_bmp +WHERE BINARY(c)<>BINARY(LOWER(c)) OR BINARY(c)<>BINARY(UPPER(c)); +codepoint_hex4 HEX(CAST(LOWER(c) AS CHAR CHARACTER SET ucs2)) HEX(CAST(UPPER(c) AS CHAR CHARACTER SET ucs2)) +0041 0061 0041 +0042 0062 0042 +0043 0063 0043 +0044 0064 0044 +0045 0065 0045 +0046 0066 0046 +0047 0067 0047 +0048 0068 0048 +0049 0069 0049 +004A 006A 004A +004B 006B 004B +004C 006C 004C +004D 006D 004D +004E 006E 004E +004F 006F 004F +0050 0070 0050 +0051 0071 0051 +0052 0072 0052 +0053 0073 0053 +0054 0074 0054 +0055 0075 0055 +0056 0076 0056 +0057 0077 0057 +0058 0078 0058 +0059 0079 0059 +005A 007A 005A +0061 0061 0041 +0062 0062 0042 +0063 0063 0043 +0064 0064 0044 +0065 0065 0045 +0066 0066 0046 +0067 0067 0047 +0068 0068 0048 +0069 0069 0049 +006A 006A 004A +006B 006B 004B +006C 006C 004C +006D 006D 004D +006E 006E 004E +006F 006F 004F +0070 0070 0050 +0071 0071 0051 +0072 0072 0052 +0073 0073 0053 +0074 0074 0054 +0075 0075 0055 +0076 0076 0056 +0077 0077 0057 +0078 0078 0058 +0079 0079 0059 +007A 007A 005A +00B5 00B5 039C +00C0 00E0 00C0 +00C1 00E1 00C1 +00C2 00E2 00C2 +00C3 00E3 00C3 +00C4 00E4 00C4 +00C5 00E5 00C5 +00C6 00E6 00C6 +00C7 00E7 00C7 +00C8 00E8 00C8 +00C9 00E9 00C9 +00CA 00EA 00CA +00CB 00EB 00CB +00CC 00EC 00CC +00CD 00ED 00CD +00CE 00EE 00CE +00CF 00EF 00CF +00D0 00F0 00D0 +00D1 00F1 00D1 +00D2 00F2 00D2 +00D3 00F3 00D3 +00D4 00F4 00D4 +00D5 00F5 00D5 +00D6 00F6 00D6 +00D8 00F8 00D8 +00D9 00F9 00D9 +00DA 00FA 00DA +00DB 00FB 00DB +00DC 00FC 00DC +00DD 00FD 00DD +00DE 00FE 00DE +00E0 00E0 00C0 +00E1 00E1 00C1 +00E2 00E2 00C2 +00E3 00E3 00C3 +00E4 00E4 00C4 +00E5 00E5 00C5 +00E6 00E6 00C6 +00E7 00E7 00C7 +00E8 00E8 00C8 +00E9 00E9 00C9 +00EA 00EA 00CA +00EB 00EB 00CB +00EC 00EC 00CC +00ED 00ED 00CD +00EE 00EE 00CE +00EF 00EF 00CF +00F0 00F0 00D0 +00F1 00F1 00D1 +00F2 00F2 00D2 +00F3 00F3 00D3 +00F4 00F4 00D4 +00F5 00F5 00D5 +00F6 00F6 00D6 +00F8 00F8 00D8 +00F9 00F9 00D9 +00FA 00FA 00DA +00FB 00FB 00DB +00FC 00FC 00DC +00FD 00FD 00DD +00FE 00FE 00DE +00FF 00FF 0178 +0100 0101 0100 +0101 0101 0100 +0102 0103 0102 +0103 0103 0102 +0104 0105 0104 +0105 0105 0104 +0106 0107 0106 +0107 0107 0106 +0108 0109 0108 +0109 0109 0108 +010A 010B 010A +010B 010B 010A +010C 010D 010C +010D 010D 010C +010E 010F 010E +010F 010F 010E +0110 0111 0110 +0111 0111 0110 +0112 0113 0112 +0113 0113 0112 +0114 0115 0114 +0115 0115 0114 +0116 0117 0116 +0117 0117 0116 +0118 0119 0118 +0119 0119 0118 +011A 011B 011A +011B 011B 011A +011C 011D 011C +011D 011D 011C +011E 011F 011E +011F 011F 011E +0120 0121 0120 +0121 0121 0120 +0122 0123 0122 +0123 0123 0122 +0124 0125 0124 +0125 0125 0124 +0126 0127 0126 +0127 0127 0126 +0128 0129 0128 +0129 0129 0128 +012A 012B 012A +012B 012B 012A +012C 012D 012C +012D 012D 012C +012E 012F 012E +012F 012F 012E +0130 0069 0130 +0131 0131 0049 +0132 0133 0132 +0133 0133 0132 +0134 0135 0134 +0135 0135 0134 +0136 0137 0136 +0137 0137 0136 +0139 013A 0139 +013A 013A 0139 +013B 013C 013B +013C 013C 013B +013D 013E 013D +013E 013E 013D +013F 0140 013F +0140 0140 013F +0141 0142 0141 +0142 0142 0141 +0143 0144 0143 +0144 0144 0143 +0145 0146 0145 +0146 0146 0145 +0147 0148 0147 +0148 0148 0147 +014A 014B 014A +014B 014B 014A +014C 014D 014C +014D 014D 014C +014E 014F 014E +014F 014F 014E +0150 0151 0150 +0151 0151 0150 +0152 0153 0152 +0153 0153 0152 +0154 0155 0154 +0155 0155 0154 +0156 0157 0156 +0157 0157 0156 +0158 0159 0158 +0159 0159 0158 +015A 015B 015A +015B 015B 015A +015C 015D 015C +015D 015D 015C +015E 015F 015E +015F 015F 015E +0160 0161 0160 +0161 0161 0160 +0162 0163 0162 +0163 0163 0162 +0164 0165 0164 +0165 0165 0164 +0166 0167 0166 +0167 0167 0166 +0168 0169 0168 +0169 0169 0168 +016A 016B 016A +016B 016B 016A +016C 016D 016C +016D 016D 016C +016E 016F 016E +016F 016F 016E +0170 0171 0170 +0171 0171 0170 +0172 0173 0172 +0173 0173 0172 +0174 0175 0174 +0175 0175 0174 +0176 0177 0176 +0177 0177 0176 +0178 00FF 0178 +0179 017A 0179 +017A 017A 0179 +017B 017C 017B +017C 017C 017B +017D 017E 017D +017E 017E 017D +017F 017F 0053 +0180 0180 0243 +0181 0253 0181 +0182 0183 0182 +0183 0183 0182 +0184 0185 0184 +0185 0185 0184 +0186 0254 0186 +0187 0188 0187 +0188 0188 0187 +0189 0256 0189 +018A 0257 018A +018B 018C 018B +018C 018C 018B +018E 01DD 018E +018F 0259 018F +0190 025B 0190 +0191 0192 0191 +0192 0192 0191 +0193 0260 0193 +0194 0263 0194 +0195 0195 01F6 +0196 0269 0196 +0197 0268 0197 +0198 0199 0198 +0199 0199 0198 +019A 019A 023D +019C 026F 019C +019D 0272 019D +019E 019E 0220 +019F 0275 019F +01A0 01A1 01A0 +01A1 01A1 01A0 +01A2 01A3 01A2 +01A3 01A3 01A2 +01A4 01A5 01A4 +01A5 01A5 01A4 +01A6 0280 01A6 +01A7 01A8 01A7 +01A8 01A8 01A7 +01A9 0283 01A9 +01AC 01AD 01AC +01AD 01AD 01AC +01AE 0288 01AE +01AF 01B0 01AF +01B0 01B0 01AF +01B1 028A 01B1 +01B2 028B 01B2 +01B3 01B4 01B3 +01B4 01B4 01B3 +01B5 01B6 01B5 +01B6 01B6 01B5 +01B7 0292 01B7 +01B8 01B9 01B8 +01B9 01B9 01B8 +01BC 01BD 01BC +01BD 01BD 01BC +01BF 01BF 01F7 +01C4 01C6 01C4 +01C5 01C6 01C4 +01C6 01C6 01C4 +01C7 01C9 01C7 +01C8 01C9 01C7 +01C9 01C9 01C7 +01CA 01CC 01CA +01CB 01CC 01CA +01CC 01CC 01CA +01CD 01CE 01CD +01CE 01CE 01CD +01CF 01D0 01CF +01D0 01D0 01CF +01D1 01D2 01D1 +01D2 01D2 01D1 +01D3 01D4 01D3 +01D4 01D4 01D3 +01D5 01D6 01D5 +01D6 01D6 01D5 +01D7 01D8 01D7 +01D8 01D8 01D7 +01D9 01DA 01D9 +01DA 01DA 01D9 +01DB 01DC 01DB +01DC 01DC 01DB +01DD 01DD 018E +01DE 01DF 01DE +01DF 01DF 01DE +01E0 01E1 01E0 +01E1 01E1 01E0 +01E2 01E3 01E2 +01E3 01E3 01E2 +01E4 01E5 01E4 +01E5 01E5 01E4 +01E6 01E7 01E6 +01E7 01E7 01E6 +01E8 01E9 01E8 +01E9 01E9 01E8 +01EA 01EB 01EA +01EB 01EB 01EA +01EC 01ED 01EC +01ED 01ED 01EC +01EE 01EF 01EE +01EF 01EF 01EE +01F1 01F3 01F1 +01F2 01F3 01F1 +01F3 01F3 01F1 +01F4 01F5 01F4 +01F5 01F5 01F4 +01F6 0195 01F6 +01F7 01BF 01F7 +01F8 01F9 01F8 +01F9 01F9 01F8 +01FA 01FB 01FA +01FB 01FB 01FA +01FC 01FD 01FC +01FD 01FD 01FC +01FE 01FF 01FE +01FF 01FF 01FE +0200 0201 0200 +0201 0201 0200 +0202 0203 0202 +0203 0203 0202 +0204 0205 0204 +0205 0205 0204 +0206 0207 0206 +0207 0207 0206 +0208 0209 0208 +0209 0209 0208 +020A 020B 020A +020B 020B 020A +020C 020D 020C +020D 020D 020C +020E 020F 020E +020F 020F 020E +0210 0211 0210 +0211 0211 0210 +0212 0213 0212 +0213 0213 0212 +0214 0215 0214 +0215 0215 0214 +0216 0217 0216 +0217 0217 0216 +0218 0219 0218 +0219 0219 0218 +021A 021B 021A +021B 021B 021A +021C 021D 021C +021D 021D 021C +021E 021F 021E +021F 021F 021E +0220 019E 0220 +0222 0223 0222 +0223 0223 0222 +0224 0225 0224 +0225 0225 0224 +0226 0227 0226 +0227 0227 0226 +0228 0229 0228 +0229 0229 0228 +022A 022B 022A +022B 022B 022A +022C 022D 022C +022D 022D 022C +022E 022F 022E +022F 022F 022E +0230 0231 0230 +0231 0231 0230 +0232 0233 0232 +0233 0233 0232 +023A 2C65 023A +023B 023C 023B +023C 023C 023B +023D 019A 023D +023E 2C66 023E +023F 023F 2C7E +0240 0240 2C7F +0241 0242 0241 +0242 0242 0241 +0243 0180 0243 +0244 0289 0244 +0245 028C 0245 +0246 0247 0246 +0247 0247 0246 +0248 0249 0248 +0249 0249 0248 +024A 024B 024A +024B 024B 024A +024C 024D 024C +024D 024D 024C +024E 024F 024E +024F 024F 024E +0250 0250 2C6F +0251 0251 2C6D +0252 0252 2C70 +0253 0253 0181 +0254 0254 0186 +0256 0256 0189 +0257 0257 018A +0259 0259 018F +025B 025B 0190 +025C 025C A7AB +0260 0260 0193 +0261 0261 A7AC +0263 0263 0194 +0265 0265 A78D +0266 0266 A7AA +0268 0268 0197 +0269 0269 0196 +026A 026A A7AE +026B 026B 2C62 +026C 026C A7AD +026F 026F 019C +0271 0271 2C6E +0272 0272 019D +0275 0275 019F +027D 027D 2C64 +0280 0280 01A6 +0282 0282 A7C5 +0283 0283 01A9 +0287 0287 A7B1 +0288 0288 01AE +0289 0289 0244 +028A 028A 01B1 +028B 028B 01B2 +028C 028C 0245 +0292 0292 01B7 +029D 029D A7B2 +029E 029E A7B0 +0345 0345 0399 +0370 0371 0370 +0371 0371 0370 +0372 0373 0372 +0373 0373 0372 +0376 0377 0376 +0377 0377 0376 +037B 037B 03FD +037C 037C 03FE +037D 037D 03FF +037F 03F3 037F +0386 03AC 0386 +0388 03AD 0388 +0389 03AE 0389 +038A 03AF 038A +038C 03CC 038C +038E 03CD 038E +038F 03CE 038F +0391 03B1 0391 +0392 03B2 0392 +0393 03B3 0393 +0394 03B4 0394 +0395 03B5 0395 +0396 03B6 0396 +0397 03B7 0397 +0398 03B8 0398 +0399 03B9 0399 +039A 03BA 039A +039B 03BB 039B +039C 03BC 039C +039D 03BD 039D +039E 03BE 039E +039F 03BF 039F +03A0 03C0 03A0 +03A1 03C1 03A1 +03A3 03C3 03A3 +03A4 03C4 03A4 +03A5 03C5 03A5 +03A6 03C6 03A6 +03A7 03C7 03A7 +03A8 03C8 03A8 +03A9 03C9 03A9 +03AA 03CA 03AA +03AB 03CB 03AB +03AC 03AC 0386 +03AD 03AD 0388 +03AE 03AE 0389 +03AF 03AF 038A +03B1 03B1 0391 +03B2 03B2 0392 +03B3 03B3 0393 +03B4 03B4 0394 +03B5 03B5 0395 +03B6 03B6 0396 +03B7 03B7 0397 +03B8 03B8 0398 +03B9 03B9 0399 +03BA 03BA 039A +03BB 03BB 039B +03BC 03BC 039C +03BD 03BD 039D +03BE 03BE 039E +03BF 03BF 039F +03C0 03C0 03A0 +03C1 03C1 03A1 +03C2 03C2 03A3 +03C3 03C3 03A3 +03C4 03C4 03A4 +03C5 03C5 03A5 +03C6 03C6 03A6 +03C7 03C7 03A7 +03C8 03C8 03A8 +03C9 03C9 03A9 +03CA 03CA 03AA +03CB 03CB 03AB +03CC 03CC 038C +03CD 03CD 038E +03CE 03CE 038F +03CF 03D7 03CF +03D0 03D0 0392 +03D1 03D1 0398 +03D5 03D5 03A6 +03D6 03D6 03A0 +03D7 03D7 03CF +03D8 03D9 03D8 +03D9 03D9 03D8 +03DA 03DB 03DA +03DB 03DB 03DA +03DC 03DD 03DC +03DD 03DD 03DC +03DE 03DF 03DE +03DF 03DF 03DE +03E0 03E1 03E0 +03E1 03E1 03E0 +03E2 03E3 03E2 +03E3 03E3 03E2 +03E4 03E5 03E4 +03E5 03E5 03E4 +03E6 03E7 03E6 +03E7 03E7 03E6 +03E8 03E9 03E8 +03E9 03E9 03E8 +03EA 03EB 03EA +03EB 03EB 03EA +03EC 03ED 03EC +03ED 03ED 03EC +03EE 03EF 03EE +03EF 03EF 03EE +03F0 03F0 039A +03F1 03F1 03A1 +03F2 03F2 03F9 +03F3 03F3 037F +03F4 03B8 03F4 +03F5 03F5 0395 +03F7 03F8 03F7 +03F8 03F8 03F7 +03F9 03F2 03F9 +03FA 03FB 03FA +03FB 03FB 03FA +03FD 037B 03FD +03FE 037C 03FE +03FF 037D 03FF +0400 0450 0400 +0401 0451 0401 +0402 0452 0402 +0403 0453 0403 +0404 0454 0404 +0405 0455 0405 +0406 0456 0406 +0407 0457 0407 +0408 0458 0408 +0409 0459 0409 +040A 045A 040A +040B 045B 040B +040C 045C 040C +040D 045D 040D +040E 045E 040E +040F 045F 040F +0410 0430 0410 +0411 0431 0411 +0412 0432 0412 +0413 0433 0413 +0414 0434 0414 +0415 0435 0415 +0416 0436 0416 +0417 0437 0417 +0418 0438 0418 +0419 0439 0419 +041A 043A 041A +041B 043B 041B +041C 043C 041C +041D 043D 041D +041E 043E 041E +041F 043F 041F +0420 0440 0420 +0421 0441 0421 +0422 0442 0422 +0423 0443 0423 +0424 0444 0424 +0425 0445 0425 +0426 0446 0426 +0427 0447 0427 +0428 0448 0428 +0429 0449 0429 +042A 044A 042A +042B 044B 042B +042C 044C 042C +042D 044D 042D +042E 044E 042E +042F 044F 042F +0430 0430 0410 +0431 0431 0411 +0432 0432 0412 +0433 0433 0413 +0434 0434 0414 +0435 0435 0415 +0436 0436 0416 +0437 0437 0417 +0438 0438 0418 +0439 0439 0419 +043A 043A 041A +043B 043B 041B +043C 043C 041C +043D 043D 041D +043E 043E 041E +043F 043F 041F +0440 0440 0420 +0441 0441 0421 +0442 0442 0422 +0443 0443 0423 +0444 0444 0424 +0445 0445 0425 +0446 0446 0426 +0447 0447 0427 +0448 0448 0428 +0449 0449 0429 +044A 044A 042A +044B 044B 042B +044C 044C 042C +044D 044D 042D +044E 044E 042E +044F 044F 042F +0450 0450 0400 +0451 0451 0401 +0452 0452 0402 +0453 0453 0403 +0454 0454 0404 +0455 0455 0405 +0456 0456 0406 +0457 0457 0407 +0458 0458 0408 +0459 0459 0409 +045A 045A 040A +045B 045B 040B +045C 045C 040C +045D 045D 040D +045E 045E 040E +045F 045F 040F +0460 0461 0460 +0461 0461 0460 +0462 0463 0462 +0463 0463 0462 +0464 0465 0464 +0465 0465 0464 +0466 0467 0466 +0467 0467 0466 +0468 0469 0468 +0469 0469 0468 +046A 046B 046A +046B 046B 046A +046C 046D 046C +046D 046D 046C +046E 046F 046E +046F 046F 046E +0470 0471 0470 +0471 0471 0470 +0472 0473 0472 +0473 0473 0472 +0474 0475 0474 +0475 0475 0474 +0476 0477 0476 +0477 0477 0476 +0478 0479 0478 +0479 0479 0478 +047A 047B 047A +047B 047B 047A +047C 047D 047C +047D 047D 047C +047E 047F 047E +047F 047F 047E +0480 0481 0480 +0481 0481 0480 +048A 048B 048A +048B 048B 048A +048C 048D 048C +048D 048D 048C +048E 048F 048E +048F 048F 048E +0490 0491 0490 +0491 0491 0490 +0492 0493 0492 +0493 0493 0492 +0494 0495 0494 +0495 0495 0494 +0496 0497 0496 +0497 0497 0496 +0498 0499 0498 +0499 0499 0498 +049A 049B 049A +049B 049B 049A +049C 049D 049C +049D 049D 049C +049E 049F 049E +049F 049F 049E +04A0 04A1 04A0 +04A1 04A1 04A0 +04A2 04A3 04A2 +04A3 04A3 04A2 +04A4 04A5 04A4 +04A5 04A5 04A4 +04A6 04A7 04A6 +04A7 04A7 04A6 +04A8 04A9 04A8 +04A9 04A9 04A8 +04AA 04AB 04AA +04AB 04AB 04AA +04AC 04AD 04AC +04AD 04AD 04AC +04AE 04AF 04AE +04AF 04AF 04AE +04B0 04B1 04B0 +04B1 04B1 04B0 +04B2 04B3 04B2 +04B3 04B3 04B2 +04B4 04B5 04B4 +04B5 04B5 04B4 +04B6 04B7 04B6 +04B7 04B7 04B6 +04B8 04B9 04B8 +04B9 04B9 04B8 +04BA 04BB 04BA +04BB 04BB 04BA +04BC 04BD 04BC +04BD 04BD 04BC +04BE 04BF 04BE +04BF 04BF 04BE +04C0 04CF 04C0 +04C1 04C2 04C1 +04C2 04C2 04C1 +04C3 04C4 04C3 +04C4 04C4 04C3 +04C5 04C6 04C5 +04C6 04C6 04C5 +04C7 04C8 04C7 +04C8 04C8 04C7 +04C9 04CA 04C9 +04CA 04CA 04C9 +04CB 04CC 04CB +04CC 04CC 04CB +04CD 04CE 04CD +04CE 04CE 04CD +04CF 04CF 04C0 +04D0 04D1 04D0 +04D1 04D1 04D0 +04D2 04D3 04D2 +04D3 04D3 04D2 +04D4 04D5 04D4 +04D5 04D5 04D4 +04D6 04D7 04D6 +04D7 04D7 04D6 +04D8 04D9 04D8 +04D9 04D9 04D8 +04DA 04DB 04DA +04DB 04DB 04DA +04DC 04DD 04DC +04DD 04DD 04DC +04DE 04DF 04DE +04DF 04DF 04DE +04E0 04E1 04E0 +04E1 04E1 04E0 +04E2 04E3 04E2 +04E3 04E3 04E2 +04E4 04E5 04E4 +04E5 04E5 04E4 +04E6 04E7 04E6 +04E7 04E7 04E6 +04E8 04E9 04E8 +04E9 04E9 04E8 +04EA 04EB 04EA +04EB 04EB 04EA +04EC 04ED 04EC +04ED 04ED 04EC +04EE 04EF 04EE +04EF 04EF 04EE +04F0 04F1 04F0 +04F1 04F1 04F0 +04F2 04F3 04F2 +04F3 04F3 04F2 +04F4 04F5 04F4 +04F5 04F5 04F4 +04F6 04F7 04F6 +04F7 04F7 04F6 +04F8 04F9 04F8 +04F9 04F9 04F8 +04FA 04FB 04FA +04FB 04FB 04FA +04FC 04FD 04FC +04FD 04FD 04FC +04FE 04FF 04FE +04FF 04FF 04FE +0500 0501 0500 +0501 0501 0500 +0502 0503 0502 +0503 0503 0502 +0504 0505 0504 +0505 0505 0504 +0506 0507 0506 +0507 0507 0506 +0508 0509 0508 +0509 0509 0508 +050A 050B 050A +050B 050B 050A +050C 050D 050C +050D 050D 050C +050E 050F 050E +050F 050F 050E +0510 0511 0510 +0511 0511 0510 +0512 0513 0512 +0513 0513 0512 +0514 0515 0514 +0515 0515 0514 +0516 0517 0516 +0517 0517 0516 +0518 0519 0518 +0519 0519 0518 +051A 051B 051A +051B 051B 051A +051C 051D 051C +051D 051D 051C +051E 051F 051E +051F 051F 051E +0520 0521 0520 +0521 0521 0520 +0522 0523 0522 +0523 0523 0522 +0524 0525 0524 +0525 0525 0524 +0526 0527 0526 +0527 0527 0526 +0528 0529 0528 +0529 0529 0528 +052A 052B 052A +052B 052B 052A +052C 052D 052C +052D 052D 052C +052E 052F 052E +052F 052F 052E +0531 0561 0531 +0532 0562 0532 +0533 0563 0533 +0534 0564 0534 +0535 0565 0535 +0536 0566 0536 +0537 0567 0537 +0538 0568 0538 +0539 0569 0539 +053A 056A 053A +053B 056B 053B +053C 056C 053C +053D 056D 053D +053E 056E 053E +053F 056F 053F +0540 0570 0540 +0541 0571 0541 +0542 0572 0542 +0543 0573 0543 +0544 0574 0544 +0545 0575 0545 +0546 0576 0546 +0547 0577 0547 +0548 0578 0548 +0549 0579 0549 +054A 057A 054A +054B 057B 054B +054C 057C 054C +054D 057D 054D +054E 057E 054E +054F 057F 054F +0550 0580 0550 +0551 0581 0551 +0552 0582 0552 +0553 0583 0553 +0554 0584 0554 +0555 0585 0555 +0556 0586 0556 +0561 0561 0531 +0562 0562 0532 +0563 0563 0533 +0564 0564 0534 +0565 0565 0535 +0566 0566 0536 +0567 0567 0537 +0568 0568 0538 +0569 0569 0539 +056A 056A 053A +056B 056B 053B +056C 056C 053C +056D 056D 053D +056E 056E 053E +056F 056F 053F +0570 0570 0540 +0571 0571 0541 +0572 0572 0542 +0573 0573 0543 +0574 0574 0544 +0575 0575 0545 +0576 0576 0546 +0577 0577 0547 +0578 0578 0548 +0579 0579 0549 +057A 057A 054A +057B 057B 054B +057C 057C 054C +057D 057D 054D +057E 057E 054E +057F 057F 054F +0580 0580 0550 +0581 0581 0551 +0582 0582 0552 +0583 0583 0553 +0584 0584 0554 +0585 0585 0555 +0586 0586 0556 +10A0 2D00 10A0 +10A1 2D01 10A1 +10A2 2D02 10A2 +10A3 2D03 10A3 +10A4 2D04 10A4 +10A5 2D05 10A5 +10A6 2D06 10A6 +10A7 2D07 10A7 +10A8 2D08 10A8 +10A9 2D09 10A9 +10AA 2D0A 10AA +10AB 2D0B 10AB +10AC 2D0C 10AC +10AD 2D0D 10AD +10AE 2D0E 10AE +10AF 2D0F 10AF +10B0 2D10 10B0 +10B1 2D11 10B1 +10B2 2D12 10B2 +10B3 2D13 10B3 +10B4 2D14 10B4 +10B5 2D15 10B5 +10B6 2D16 10B6 +10B7 2D17 10B7 +10B8 2D18 10B8 +10B9 2D19 10B9 +10BA 2D1A 10BA +10BB 2D1B 10BB +10BC 2D1C 10BC +10BD 2D1D 10BD +10BE 2D1E 10BE +10BF 2D1F 10BF +10C0 2D20 10C0 +10C1 2D21 10C1 +10C2 2D22 10C2 +10C3 2D23 10C3 +10C4 2D24 10C4 +10C5 2D25 10C5 +10C7 2D27 10C7 +10CD 2D2D 10CD +10D0 10D0 1C90 +10D1 10D1 1C91 +10D2 10D2 1C92 +10D3 10D3 1C93 +10D4 10D4 1C94 +10D5 10D5 1C95 +10D6 10D6 1C96 +10D7 10D7 1C97 +10D8 10D8 1C98 +10D9 10D9 1C99 +10DA 10DA 1C9A +10DB 10DB 1C9B +10DC 10DC 1C9C +10DD 10DD 1C9D +10DE 10DE 1C9E +10DF 10DF 1C9F +10E0 10E0 1CA0 +10E1 10E1 1CA1 +10E2 10E2 1CA2 +10E3 10E3 1CA3 +10E4 10E4 1CA4 +10E5 10E5 1CA5 +10E6 10E6 1CA6 +10E7 10E7 1CA7 +10E8 10E8 1CA8 +10E9 10E9 1CA9 +10EA 10EA 1CAA +10EB 10EB 1CAB +10EC 10EC 1CAC +10ED 10ED 1CAD +10EE 10EE 1CAE +10EF 10EF 1CAF +10F0 10F0 1CB0 +10F1 10F1 1CB1 +10F2 10F2 1CB2 +10F3 10F3 1CB3 +10F4 10F4 1CB4 +10F5 10F5 1CB5 +10F6 10F6 1CB6 +10F7 10F7 1CB7 +10F8 10F8 1CB8 +10F9 10F9 1CB9 +10FA 10FA 1CBA +10FD 10FD 1CBD +10FE 10FE 1CBE +10FF 10FF 1CBF +13A0 AB70 13A0 +13A1 AB71 13A1 +13A2 AB72 13A2 +13A3 AB73 13A3 +13A4 AB74 13A4 +13A5 AB75 13A5 +13A6 AB76 13A6 +13A7 AB77 13A7 +13A8 AB78 13A8 +13A9 AB79 13A9 +13AA AB7A 13AA +13AB AB7B 13AB +13AC AB7C 13AC +13AD AB7D 13AD +13AE AB7E 13AE +13AF AB7F 13AF +13B0 AB80 13B0 +13B1 AB81 13B1 +13B2 AB82 13B2 +13B3 AB83 13B3 +13B4 AB84 13B4 +13B5 AB85 13B5 +13B6 AB86 13B6 +13B7 AB87 13B7 +13B8 AB88 13B8 +13B9 AB89 13B9 +13BA AB8A 13BA +13BB AB8B 13BB +13BC AB8C 13BC +13BD AB8D 13BD +13BE AB8E 13BE +13BF AB8F 13BF +13C0 AB90 13C0 +13C1 AB91 13C1 +13C2 AB92 13C2 +13C3 AB93 13C3 +13C4 AB94 13C4 +13C5 AB95 13C5 +13C6 AB96 13C6 +13C7 AB97 13C7 +13C8 AB98 13C8 +13C9 AB99 13C9 +13CA AB9A 13CA +13CB AB9B 13CB +13CC AB9C 13CC +13CD AB9D 13CD +13CE AB9E 13CE +13CF AB9F 13CF +13D0 ABA0 13D0 +13D1 ABA1 13D1 +13D2 ABA2 13D2 +13D3 ABA3 13D3 +13D4 ABA4 13D4 +13D5 ABA5 13D5 +13D6 ABA6 13D6 +13D7 ABA7 13D7 +13D8 ABA8 13D8 +13D9 ABA9 13D9 +13DA ABAA 13DA +13DB ABAB 13DB +13DC ABAC 13DC +13DD ABAD 13DD +13DE ABAE 13DE +13DF ABAF 13DF +13E0 ABB0 13E0 +13E1 ABB1 13E1 +13E2 ABB2 13E2 +13E3 ABB3 13E3 +13E4 ABB4 13E4 +13E5 ABB5 13E5 +13E6 ABB6 13E6 +13E7 ABB7 13E7 +13E8 ABB8 13E8 +13E9 ABB9 13E9 +13EA ABBA 13EA +13EB ABBB 13EB +13EC ABBC 13EC +13ED ABBD 13ED +13EE ABBE 13EE +13EF ABBF 13EF +13F0 13F8 13F0 +13F1 13F9 13F1 +13F2 13FA 13F2 +13F3 13FB 13F3 +13F4 13FC 13F4 +13F5 13FD 13F5 +13F8 13F8 13F0 +13F9 13F9 13F1 +13FA 13FA 13F2 +13FB 13FB 13F3 +13FC 13FC 13F4 +13FD 13FD 13F5 +1C80 1C80 0412 +1C81 1C81 0414 +1C82 1C82 041E +1C83 1C83 0421 +1C84 1C84 0422 +1C85 1C85 0422 +1C86 1C86 042A +1C87 1C87 0462 +1C88 1C88 A64A +1C90 10D0 1C90 +1C91 10D1 1C91 +1C92 10D2 1C92 +1C93 10D3 1C93 +1C94 10D4 1C94 +1C95 10D5 1C95 +1C96 10D6 1C96 +1C97 10D7 1C97 +1C98 10D8 1C98 +1C99 10D9 1C99 +1C9A 10DA 1C9A +1C9B 10DB 1C9B +1C9C 10DC 1C9C +1C9D 10DD 1C9D +1C9E 10DE 1C9E +1C9F 10DF 1C9F +1CA0 10E0 1CA0 +1CA1 10E1 1CA1 +1CA2 10E2 1CA2 +1CA3 10E3 1CA3 +1CA4 10E4 1CA4 +1CA5 10E5 1CA5 +1CA6 10E6 1CA6 +1CA7 10E7 1CA7 +1CA8 10E8 1CA8 +1CA9 10E9 1CA9 +1CAA 10EA 1CAA +1CAB 10EB 1CAB +1CAC 10EC 1CAC +1CAD 10ED 1CAD +1CAE 10EE 1CAE +1CAF 10EF 1CAF +1CB0 10F0 1CB0 +1CB1 10F1 1CB1 +1CB2 10F2 1CB2 +1CB3 10F3 1CB3 +1CB4 10F4 1CB4 +1CB5 10F5 1CB5 +1CB6 10F6 1CB6 +1CB7 10F7 1CB7 +1CB8 10F8 1CB8 +1CB9 10F9 1CB9 +1CBA 10FA 1CBA +1CBD 10FD 1CBD +1CBE 10FE 1CBE +1CBF 10FF 1CBF +1D79 1D79 A77D +1D7D 1D7D 2C63 +1D8E 1D8E A7C6 +1E00 1E01 1E00 +1E01 1E01 1E00 +1E02 1E03 1E02 +1E03 1E03 1E02 +1E04 1E05 1E04 +1E05 1E05 1E04 +1E06 1E07 1E06 +1E07 1E07 1E06 +1E08 1E09 1E08 +1E09 1E09 1E08 +1E0A 1E0B 1E0A +1E0B 1E0B 1E0A +1E0C 1E0D 1E0C +1E0D 1E0D 1E0C +1E0E 1E0F 1E0E +1E0F 1E0F 1E0E +1E10 1E11 1E10 +1E11 1E11 1E10 +1E12 1E13 1E12 +1E13 1E13 1E12 +1E14 1E15 1E14 +1E15 1E15 1E14 +1E16 1E17 1E16 +1E17 1E17 1E16 +1E18 1E19 1E18 +1E19 1E19 1E18 +1E1A 1E1B 1E1A +1E1B 1E1B 1E1A +1E1C 1E1D 1E1C +1E1D 1E1D 1E1C +1E1E 1E1F 1E1E +1E1F 1E1F 1E1E +1E20 1E21 1E20 +1E21 1E21 1E20 +1E22 1E23 1E22 +1E23 1E23 1E22 +1E24 1E25 1E24 +1E25 1E25 1E24 +1E26 1E27 1E26 +1E27 1E27 1E26 +1E28 1E29 1E28 +1E29 1E29 1E28 +1E2A 1E2B 1E2A +1E2B 1E2B 1E2A +1E2C 1E2D 1E2C +1E2D 1E2D 1E2C +1E2E 1E2F 1E2E +1E2F 1E2F 1E2E +1E30 1E31 1E30 +1E31 1E31 1E30 +1E32 1E33 1E32 +1E33 1E33 1E32 +1E34 1E35 1E34 +1E35 1E35 1E34 +1E36 1E37 1E36 +1E37 1E37 1E36 +1E38 1E39 1E38 +1E39 1E39 1E38 +1E3A 1E3B 1E3A +1E3B 1E3B 1E3A +1E3C 1E3D 1E3C +1E3D 1E3D 1E3C +1E3E 1E3F 1E3E +1E3F 1E3F 1E3E +1E40 1E41 1E40 +1E41 1E41 1E40 +1E42 1E43 1E42 +1E43 1E43 1E42 +1E44 1E45 1E44 +1E45 1E45 1E44 +1E46 1E47 1E46 +1E47 1E47 1E46 +1E48 1E49 1E48 +1E49 1E49 1E48 +1E4A 1E4B 1E4A +1E4B 1E4B 1E4A +1E4C 1E4D 1E4C +1E4D 1E4D 1E4C +1E4E 1E4F 1E4E +1E4F 1E4F 1E4E +1E50 1E51 1E50 +1E51 1E51 1E50 +1E52 1E53 1E52 +1E53 1E53 1E52 +1E54 1E55 1E54 +1E55 1E55 1E54 +1E56 1E57 1E56 +1E57 1E57 1E56 +1E58 1E59 1E58 +1E59 1E59 1E58 +1E5A 1E5B 1E5A +1E5B 1E5B 1E5A +1E5C 1E5D 1E5C +1E5D 1E5D 1E5C +1E5E 1E5F 1E5E +1E5F 1E5F 1E5E +1E60 1E61 1E60 +1E61 1E61 1E60 +1E62 1E63 1E62 +1E63 1E63 1E62 +1E64 1E65 1E64 +1E65 1E65 1E64 +1E66 1E67 1E66 +1E67 1E67 1E66 +1E68 1E69 1E68 +1E69 1E69 1E68 +1E6A 1E6B 1E6A +1E6B 1E6B 1E6A +1E6C 1E6D 1E6C +1E6D 1E6D 1E6C +1E6E 1E6F 1E6E +1E6F 1E6F 1E6E +1E70 1E71 1E70 +1E71 1E71 1E70 +1E72 1E73 1E72 +1E73 1E73 1E72 +1E74 1E75 1E74 +1E75 1E75 1E74 +1E76 1E77 1E76 +1E77 1E77 1E76 +1E78 1E79 1E78 +1E79 1E79 1E78 +1E7A 1E7B 1E7A +1E7B 1E7B 1E7A +1E7C 1E7D 1E7C +1E7D 1E7D 1E7C +1E7E 1E7F 1E7E +1E7F 1E7F 1E7E +1E80 1E81 1E80 +1E81 1E81 1E80 +1E82 1E83 1E82 +1E83 1E83 1E82 +1E84 1E85 1E84 +1E85 1E85 1E84 +1E86 1E87 1E86 +1E87 1E87 1E86 +1E88 1E89 1E88 +1E89 1E89 1E88 +1E8A 1E8B 1E8A +1E8B 1E8B 1E8A +1E8C 1E8D 1E8C +1E8D 1E8D 1E8C +1E8E 1E8F 1E8E +1E8F 1E8F 1E8E +1E90 1E91 1E90 +1E91 1E91 1E90 +1E92 1E93 1E92 +1E93 1E93 1E92 +1E94 1E95 1E94 +1E95 1E95 1E94 +1E9B 1E9B 1E60 +1E9E 00DF 1E9E +1EA0 1EA1 1EA0 +1EA1 1EA1 1EA0 +1EA2 1EA3 1EA2 +1EA3 1EA3 1EA2 +1EA4 1EA5 1EA4 +1EA5 1EA5 1EA4 +1EA6 1EA7 1EA6 +1EA7 1EA7 1EA6 +1EA8 1EA9 1EA8 +1EA9 1EA9 1EA8 +1EAA 1EAB 1EAA +1EAB 1EAB 1EAA +1EAC 1EAD 1EAC +1EAD 1EAD 1EAC +1EAE 1EAF 1EAE +1EAF 1EAF 1EAE +1EB0 1EB1 1EB0 +1EB1 1EB1 1EB0 +1EB2 1EB3 1EB2 +1EB3 1EB3 1EB2 +1EB4 1EB5 1EB4 +1EB5 1EB5 1EB4 +1EB6 1EB7 1EB6 +1EB7 1EB7 1EB6 +1EB8 1EB9 1EB8 +1EB9 1EB9 1EB8 +1EBA 1EBB 1EBA +1EBB 1EBB 1EBA +1EBC 1EBD 1EBC +1EBD 1EBD 1EBC +1EBE 1EBF 1EBE +1EBF 1EBF 1EBE +1EC0 1EC1 1EC0 +1EC1 1EC1 1EC0 +1EC2 1EC3 1EC2 +1EC3 1EC3 1EC2 +1EC4 1EC5 1EC4 +1EC5 1EC5 1EC4 +1EC6 1EC7 1EC6 +1EC7 1EC7 1EC6 +1EC8 1EC9 1EC8 +1EC9 1EC9 1EC8 +1ECA 1ECB 1ECA +1ECB 1ECB 1ECA +1ECC 1ECD 1ECC +1ECD 1ECD 1ECC +1ECE 1ECF 1ECE +1ECF 1ECF 1ECE +1ED0 1ED1 1ED0 +1ED1 1ED1 1ED0 +1ED2 1ED3 1ED2 +1ED3 1ED3 1ED2 +1ED4 1ED5 1ED4 +1ED5 1ED5 1ED4 +1ED6 1ED7 1ED6 +1ED7 1ED7 1ED6 +1ED8 1ED9 1ED8 +1ED9 1ED9 1ED8 +1EDA 1EDB 1EDA +1EDB 1EDB 1EDA +1EDC 1EDD 1EDC +1EDD 1EDD 1EDC +1EDE 1EDF 1EDE +1EDF 1EDF 1EDE +1EE0 1EE1 1EE0 +1EE1 1EE1 1EE0 +1EE2 1EE3 1EE2 +1EE3 1EE3 1EE2 +1EE4 1EE5 1EE4 +1EE5 1EE5 1EE4 +1EE6 1EE7 1EE6 +1EE7 1EE7 1EE6 +1EE8 1EE9 1EE8 +1EE9 1EE9 1EE8 +1EEA 1EEB 1EEA +1EEB 1EEB 1EEA +1EEC 1EED 1EEC +1EED 1EED 1EEC +1EEE 1EEF 1EEE +1EEF 1EEF 1EEE +1EF0 1EF1 1EF0 +1EF1 1EF1 1EF0 +1EF2 1EF3 1EF2 +1EF3 1EF3 1EF2 +1EF4 1EF5 1EF4 +1EF5 1EF5 1EF4 +1EF6 1EF7 1EF6 +1EF7 1EF7 1EF6 +1EF8 1EF9 1EF8 +1EF9 1EF9 1EF8 +1EFA 1EFB 1EFA +1EFB 1EFB 1EFA +1EFC 1EFD 1EFC +1EFD 1EFD 1EFC +1EFE 1EFF 1EFE +1EFF 1EFF 1EFE +1F00 1F00 1F08 +1F01 1F01 1F09 +1F02 1F02 1F0A +1F03 1F03 1F0B +1F04 1F04 1F0C +1F05 1F05 1F0D +1F06 1F06 1F0E +1F07 1F07 1F0F +1F08 1F00 1F08 +1F09 1F01 1F09 +1F0A 1F02 1F0A +1F0B 1F03 1F0B +1F0C 1F04 1F0C +1F0D 1F05 1F0D +1F0E 1F06 1F0E +1F0F 1F07 1F0F +1F10 1F10 1F18 +1F11 1F11 1F19 +1F12 1F12 1F1A +1F13 1F13 1F1B +1F14 1F14 1F1C +1F15 1F15 1F1D +1F18 1F10 1F18 +1F19 1F11 1F19 +1F1A 1F12 1F1A +1F1B 1F13 1F1B +1F1C 1F14 1F1C +1F1D 1F15 1F1D +1F20 1F20 1F28 +1F21 1F21 1F29 +1F22 1F22 1F2A +1F23 1F23 1F2B +1F24 1F24 1F2C +1F25 1F25 1F2D +1F26 1F26 1F2E +1F27 1F27 1F2F +1F28 1F20 1F28 +1F29 1F21 1F29 +1F2A 1F22 1F2A +1F2B 1F23 1F2B +1F2C 1F24 1F2C +1F2D 1F25 1F2D +1F2E 1F26 1F2E +1F2F 1F27 1F2F +1F30 1F30 1F38 +1F31 1F31 1F39 +1F32 1F32 1F3A +1F33 1F33 1F3B +1F34 1F34 1F3C +1F35 1F35 1F3D +1F36 1F36 1F3E +1F37 1F37 1F3F +1F38 1F30 1F38 +1F39 1F31 1F39 +1F3A 1F32 1F3A +1F3B 1F33 1F3B +1F3C 1F34 1F3C +1F3D 1F35 1F3D +1F3E 1F36 1F3E +1F3F 1F37 1F3F +1F40 1F40 1F48 +1F41 1F41 1F49 +1F42 1F42 1F4A +1F43 1F43 1F4B +1F44 1F44 1F4C +1F45 1F45 1F4D +1F48 1F40 1F48 +1F49 1F41 1F49 +1F4A 1F42 1F4A +1F4B 1F43 1F4B +1F4C 1F44 1F4C +1F4D 1F45 1F4D +1F51 1F51 1F59 +1F53 1F53 1F5B +1F55 1F55 1F5D +1F57 1F57 1F5F +1F59 1F51 1F59 +1F5B 1F53 1F5B +1F5D 1F55 1F5D +1F5F 1F57 1F5F +1F60 1F60 1F68 +1F61 1F61 1F69 +1F62 1F62 1F6A +1F63 1F63 1F6B +1F64 1F64 1F6C +1F65 1F65 1F6D +1F66 1F66 1F6E +1F67 1F67 1F6F +1F68 1F60 1F68 +1F69 1F61 1F69 +1F6A 1F62 1F6A +1F6B 1F63 1F6B +1F6C 1F64 1F6C +1F6D 1F65 1F6D +1F6E 1F66 1F6E +1F6F 1F67 1F6F +1F70 1F70 1FBA +1F71 1F71 1FBB +1F72 1F72 1FC8 +1F73 1F73 1FC9 +1F74 1F74 1FCA +1F75 1F75 1FCB +1F76 1F76 1FDA +1F77 1F77 1FDB +1F78 1F78 1FF8 +1F79 1F79 1FF9 +1F7A 1F7A 1FEA +1F7B 1F7B 1FEB +1F7C 1F7C 1FFA +1F7D 1F7D 1FFB +1F80 1F80 1F88 +1F81 1F81 1F89 +1F82 1F82 1F8A +1F83 1F83 1F8B +1F84 1F84 1F8C +1F85 1F85 1F8D +1F86 1F86 1F8E +1F87 1F87 1F8F +1F88 1F80 1F88 +1F89 1F81 1F89 +1F8A 1F82 1F8A +1F8B 1F83 1F8B +1F8C 1F84 1F8C +1F8D 1F85 1F8D +1F8E 1F86 1F8E +1F8F 1F87 1F8F +1F90 1F90 1F98 +1F91 1F91 1F99 +1F92 1F92 1F9A +1F93 1F93 1F9B +1F94 1F94 1F9C +1F95 1F95 1F9D +1F96 1F96 1F9E +1F97 1F97 1F9F +1F98 1F90 1F98 +1F99 1F91 1F99 +1F9A 1F92 1F9A +1F9B 1F93 1F9B +1F9C 1F94 1F9C +1F9D 1F95 1F9D +1F9E 1F96 1F9E +1F9F 1F97 1F9F +1FA0 1FA0 1FA8 +1FA1 1FA1 1FA9 +1FA2 1FA2 1FAA +1FA3 1FA3 1FAB +1FA4 1FA4 1FAC +1FA5 1FA5 1FAD +1FA6 1FA6 1FAE +1FA7 1FA7 1FAF +1FA8 1FA0 1FA8 +1FA9 1FA1 1FA9 +1FAA 1FA2 1FAA +1FAB 1FA3 1FAB +1FAC 1FA4 1FAC +1FAD 1FA5 1FAD +1FAE 1FA6 1FAE +1FAF 1FA7 1FAF +1FB0 1FB0 1FB8 +1FB1 1FB1 1FB9 +1FB3 1FB3 1FBC +1FB8 1FB0 1FB8 +1FB9 1FB1 1FB9 +1FBA 1F70 1FBA +1FBB 1F71 1FBB +1FBC 1FB3 1FBC +1FBE 1FBE 0399 +1FC3 1FC3 1FCC +1FC8 1F72 1FC8 +1FC9 1F73 1FC9 +1FCA 1F74 1FCA +1FCB 1F75 1FCB +1FCC 1FC3 1FCC +1FD0 1FD0 1FD8 +1FD1 1FD1 1FD9 +1FD8 1FD0 1FD8 +1FD9 1FD1 1FD9 +1FDA 1F76 1FDA +1FDB 1F77 1FDB +1FE0 1FE0 1FE8 +1FE1 1FE1 1FE9 +1FE5 1FE5 1FEC +1FE8 1FE0 1FE8 +1FE9 1FE1 1FE9 +1FEA 1F7A 1FEA +1FEB 1F7B 1FEB +1FEC 1FE5 1FEC +1FF3 1FF3 1FFC +1FF8 1F78 1FF8 +1FF9 1F79 1FF9 +1FFA 1F7C 1FFA +1FFB 1F7D 1FFB +1FFC 1FF3 1FFC +2126 03C9 2126 +212A 006B 212A +212B 00E5 212B +2132 214E 2132 +214E 214E 2132 +2160 2170 2160 +2161 2171 2161 +2162 2172 2162 +2163 2173 2163 +2164 2174 2164 +2165 2175 2165 +2166 2176 2166 +2167 2177 2167 +2168 2178 2168 +2169 2179 2169 +216A 217A 216A +216B 217B 216B +216C 217C 216C +216D 217D 216D +216E 217E 216E +216F 217F 216F +2170 2170 2160 +2171 2171 2161 +2172 2172 2162 +2173 2173 2163 +2174 2174 2164 +2175 2175 2165 +2176 2176 2166 +2177 2177 2167 +2178 2178 2168 +2179 2179 2169 +217A 217A 216A +217B 217B 216B +217C 217C 216C +217D 217D 216D +217E 217E 216E +217F 217F 216F +2183 2184 2183 +2184 2184 2183 +24B6 24D0 24B6 +24B7 24D1 24B7 +24B8 24D2 24B8 +24B9 24D3 24B9 +24BA 24D4 24BA +24BB 24D5 24BB +24BC 24D6 24BC +24BD 24D7 24BD +24BE 24D8 24BE +24BF 24D9 24BF +24C0 24DA 24C0 +24C1 24DB 24C1 +24C2 24DC 24C2 +24C3 24DD 24C3 +24C4 24DE 24C4 +24C5 24DF 24C5 +24C6 24E0 24C6 +24C7 24E1 24C7 +24C8 24E2 24C8 +24C9 24E3 24C9 +24CA 24E4 24CA +24CB 24E5 24CB +24CC 24E6 24CC +24CD 24E7 24CD +24CE 24E8 24CE +24CF 24E9 24CF +24D0 24D0 24B6 +24D1 24D1 24B7 +24D2 24D2 24B8 +24D3 24D3 24B9 +24D4 24D4 24BA +24D5 24D5 24BB +24D6 24D6 24BC +24D7 24D7 24BD +24D8 24D8 24BE +24D9 24D9 24BF +24DA 24DA 24C0 +24DB 24DB 24C1 +24DC 24DC 24C2 +24DD 24DD 24C3 +24DE 24DE 24C4 +24DF 24DF 24C5 +24E0 24E0 24C6 +24E1 24E1 24C7 +24E2 24E2 24C8 +24E3 24E3 24C9 +24E4 24E4 24CA +24E5 24E5 24CB +24E6 24E6 24CC +24E7 24E7 24CD +24E8 24E8 24CE +24E9 24E9 24CF +2C00 2C30 2C00 +2C01 2C31 2C01 +2C02 2C32 2C02 +2C03 2C33 2C03 +2C04 2C34 2C04 +2C05 2C35 2C05 +2C06 2C36 2C06 +2C07 2C37 2C07 +2C08 2C38 2C08 +2C09 2C39 2C09 +2C0A 2C3A 2C0A +2C0B 2C3B 2C0B +2C0C 2C3C 2C0C +2C0D 2C3D 2C0D +2C0E 2C3E 2C0E +2C0F 2C3F 2C0F +2C10 2C40 2C10 +2C11 2C41 2C11 +2C12 2C42 2C12 +2C13 2C43 2C13 +2C14 2C44 2C14 +2C15 2C45 2C15 +2C16 2C46 2C16 +2C17 2C47 2C17 +2C18 2C48 2C18 +2C19 2C49 2C19 +2C1A 2C4A 2C1A +2C1B 2C4B 2C1B +2C1C 2C4C 2C1C +2C1D 2C4D 2C1D +2C1E 2C4E 2C1E +2C1F 2C4F 2C1F +2C20 2C50 2C20 +2C21 2C51 2C21 +2C22 2C52 2C22 +2C23 2C53 2C23 +2C24 2C54 2C24 +2C25 2C55 2C25 +2C26 2C56 2C26 +2C27 2C57 2C27 +2C28 2C58 2C28 +2C29 2C59 2C29 +2C2A 2C5A 2C2A +2C2B 2C5B 2C2B +2C2C 2C5C 2C2C +2C2D 2C5D 2C2D +2C2E 2C5E 2C2E +2C2F 2C5F 2C2F +2C30 2C30 2C00 +2C31 2C31 2C01 +2C32 2C32 2C02 +2C33 2C33 2C03 +2C34 2C34 2C04 +2C35 2C35 2C05 +2C36 2C36 2C06 +2C37 2C37 2C07 +2C38 2C38 2C08 +2C39 2C39 2C09 +2C3A 2C3A 2C0A +2C3B 2C3B 2C0B +2C3C 2C3C 2C0C +2C3D 2C3D 2C0D +2C3E 2C3E 2C0E +2C3F 2C3F 2C0F +2C40 2C40 2C10 +2C41 2C41 2C11 +2C42 2C42 2C12 +2C43 2C43 2C13 +2C44 2C44 2C14 +2C45 2C45 2C15 +2C46 2C46 2C16 +2C47 2C47 2C17 +2C48 2C48 2C18 +2C49 2C49 2C19 +2C4A 2C4A 2C1A +2C4B 2C4B 2C1B +2C4C 2C4C 2C1C +2C4D 2C4D 2C1D +2C4E 2C4E 2C1E +2C4F 2C4F 2C1F +2C50 2C50 2C20 +2C51 2C51 2C21 +2C52 2C52 2C22 +2C53 2C53 2C23 +2C54 2C54 2C24 +2C55 2C55 2C25 +2C56 2C56 2C26 +2C57 2C57 2C27 +2C58 2C58 2C28 +2C59 2C59 2C29 +2C5A 2C5A 2C2A +2C5B 2C5B 2C2B +2C5C 2C5C 2C2C +2C5D 2C5D 2C2D +2C5E 2C5E 2C2E +2C5F 2C5F 2C2F +2C60 2C61 2C60 +2C61 2C61 2C60 +2C62 026B 2C62 +2C63 1D7D 2C63 +2C64 027D 2C64 +2C65 2C65 023A +2C66 2C66 023E +2C67 2C68 2C67 +2C68 2C68 2C67 +2C69 2C6A 2C69 +2C6A 2C6A 2C69 +2C6B 2C6C 2C6B +2C6C 2C6C 2C6B +2C6D 0251 2C6D +2C6E 0271 2C6E +2C6F 0250 2C6F +2C70 0252 2C70 +2C72 2C73 2C72 +2C73 2C73 2C72 +2C75 2C76 2C75 +2C76 2C76 2C75 +2C7E 023F 2C7E +2C7F 0240 2C7F +2C80 2C81 2C80 +2C81 2C81 2C80 +2C82 2C83 2C82 +2C83 2C83 2C82 +2C84 2C85 2C84 +2C85 2C85 2C84 +2C86 2C87 2C86 +2C87 2C87 2C86 +2C88 2C89 2C88 +2C89 2C89 2C88 +2C8A 2C8B 2C8A +2C8B 2C8B 2C8A +2C8C 2C8D 2C8C +2C8D 2C8D 2C8C +2C8E 2C8F 2C8E +2C8F 2C8F 2C8E +2C90 2C91 2C90 +2C91 2C91 2C90 +2C92 2C93 2C92 +2C93 2C93 2C92 +2C94 2C95 2C94 +2C95 2C95 2C94 +2C96 2C97 2C96 +2C97 2C97 2C96 +2C98 2C99 2C98 +2C99 2C99 2C98 +2C9A 2C9B 2C9A +2C9B 2C9B 2C9A +2C9C 2C9D 2C9C +2C9D 2C9D 2C9C +2C9E 2C9F 2C9E +2C9F 2C9F 2C9E +2CA0 2CA1 2CA0 +2CA1 2CA1 2CA0 +2CA2 2CA3 2CA2 +2CA3 2CA3 2CA2 +2CA4 2CA5 2CA4 +2CA5 2CA5 2CA4 +2CA6 2CA7 2CA6 +2CA7 2CA7 2CA6 +2CA8 2CA9 2CA8 +2CA9 2CA9 2CA8 +2CAA 2CAB 2CAA +2CAB 2CAB 2CAA +2CAC 2CAD 2CAC +2CAD 2CAD 2CAC +2CAE 2CAF 2CAE +2CAF 2CAF 2CAE +2CB0 2CB1 2CB0 +2CB1 2CB1 2CB0 +2CB2 2CB3 2CB2 +2CB3 2CB3 2CB2 +2CB4 2CB5 2CB4 +2CB5 2CB5 2CB4 +2CB6 2CB7 2CB6 +2CB7 2CB7 2CB6 +2CB8 2CB9 2CB8 +2CB9 2CB9 2CB8 +2CBA 2CBB 2CBA +2CBB 2CBB 2CBA +2CBC 2CBD 2CBC +2CBD 2CBD 2CBC +2CBE 2CBF 2CBE +2CBF 2CBF 2CBE +2CC0 2CC1 2CC0 +2CC1 2CC1 2CC0 +2CC2 2CC3 2CC2 +2CC3 2CC3 2CC2 +2CC4 2CC5 2CC4 +2CC5 2CC5 2CC4 +2CC6 2CC7 2CC6 +2CC7 2CC7 2CC6 +2CC8 2CC9 2CC8 +2CC9 2CC9 2CC8 +2CCA 2CCB 2CCA +2CCB 2CCB 2CCA +2CCC 2CCD 2CCC +2CCD 2CCD 2CCC +2CCE 2CCF 2CCE +2CCF 2CCF 2CCE +2CD0 2CD1 2CD0 +2CD1 2CD1 2CD0 +2CD2 2CD3 2CD2 +2CD3 2CD3 2CD2 +2CD4 2CD5 2CD4 +2CD5 2CD5 2CD4 +2CD6 2CD7 2CD6 +2CD7 2CD7 2CD6 +2CD8 2CD9 2CD8 +2CD9 2CD9 2CD8 +2CDA 2CDB 2CDA +2CDB 2CDB 2CDA +2CDC 2CDD 2CDC +2CDD 2CDD 2CDC +2CDE 2CDF 2CDE +2CDF 2CDF 2CDE +2CE0 2CE1 2CE0 +2CE1 2CE1 2CE0 +2CE2 2CE3 2CE2 +2CE3 2CE3 2CE2 +2CEB 2CEC 2CEB +2CEC 2CEC 2CEB +2CED 2CEE 2CED +2CEE 2CEE 2CED +2CF2 2CF3 2CF2 +2CF3 2CF3 2CF2 +2D00 2D00 10A0 +2D01 2D01 10A1 +2D02 2D02 10A2 +2D03 2D03 10A3 +2D04 2D04 10A4 +2D05 2D05 10A5 +2D06 2D06 10A6 +2D07 2D07 10A7 +2D08 2D08 10A8 +2D09 2D09 10A9 +2D0A 2D0A 10AA +2D0B 2D0B 10AB +2D0C 2D0C 10AC +2D0D 2D0D 10AD +2D0E 2D0E 10AE +2D0F 2D0F 10AF +2D10 2D10 10B0 +2D11 2D11 10B1 +2D12 2D12 10B2 +2D13 2D13 10B3 +2D14 2D14 10B4 +2D15 2D15 10B5 +2D16 2D16 10B6 +2D17 2D17 10B7 +2D18 2D18 10B8 +2D19 2D19 10B9 +2D1A 2D1A 10BA +2D1B 2D1B 10BB +2D1C 2D1C 10BC +2D1D 2D1D 10BD +2D1E 2D1E 10BE +2D1F 2D1F 10BF +2D20 2D20 10C0 +2D21 2D21 10C1 +2D22 2D22 10C2 +2D23 2D23 10C3 +2D24 2D24 10C4 +2D25 2D25 10C5 +2D27 2D27 10C7 +2D2D 2D2D 10CD +A640 A641 A640 +A641 A641 A640 +A642 A643 A642 +A643 A643 A642 +A644 A645 A644 +A645 A645 A644 +A646 A647 A646 +A647 A647 A646 +A648 A649 A648 +A649 A649 A648 +A64A A64B A64A +A64B A64B A64A +A64C A64D A64C +A64D A64D A64C +A64E A64F A64E +A64F A64F A64E +A650 A651 A650 +A651 A651 A650 +A652 A653 A652 +A653 A653 A652 +A654 A655 A654 +A655 A655 A654 +A656 A657 A656 +A657 A657 A656 +A658 A659 A658 +A659 A659 A658 +A65A A65B A65A +A65B A65B A65A +A65C A65D A65C +A65D A65D A65C +A65E A65F A65E +A65F A65F A65E +A660 A661 A660 +A661 A661 A660 +A662 A663 A662 +A663 A663 A662 +A664 A665 A664 +A665 A665 A664 +A666 A667 A666 +A667 A667 A666 +A668 A669 A668 +A669 A669 A668 +A66A A66B A66A +A66B A66B A66A +A66C A66D A66C +A66D A66D A66C +A680 A681 A680 +A681 A681 A680 +A682 A683 A682 +A683 A683 A682 +A684 A685 A684 +A685 A685 A684 +A686 A687 A686 +A687 A687 A686 +A688 A689 A688 +A689 A689 A688 +A68A A68B A68A +A68B A68B A68A +A68C A68D A68C +A68D A68D A68C +A68E A68F A68E +A68F A68F A68E +A690 A691 A690 +A691 A691 A690 +A692 A693 A692 +A693 A693 A692 +A694 A695 A694 +A695 A695 A694 +A696 A697 A696 +A697 A697 A696 +A698 A699 A698 +A699 A699 A698 +A69A A69B A69A +A69B A69B A69A +A722 A723 A722 +A723 A723 A722 +A724 A725 A724 +A725 A725 A724 +A726 A727 A726 +A727 A727 A726 +A728 A729 A728 +A729 A729 A728 +A72A A72B A72A +A72B A72B A72A +A72C A72D A72C +A72D A72D A72C +A72E A72F A72E +A72F A72F A72E +A732 A733 A732 +A733 A733 A732 +A734 A735 A734 +A735 A735 A734 +A736 A737 A736 +A737 A737 A736 +A738 A739 A738 +A739 A739 A738 +A73A A73B A73A +A73B A73B A73A +A73C A73D A73C +A73D A73D A73C +A73E A73F A73E +A73F A73F A73E +A740 A741 A740 +A741 A741 A740 +A742 A743 A742 +A743 A743 A742 +A744 A745 A744 +A745 A745 A744 +A746 A747 A746 +A747 A747 A746 +A748 A749 A748 +A749 A749 A748 +A74A A74B A74A +A74B A74B A74A +A74C A74D A74C +A74D A74D A74C +A74E A74F A74E +A74F A74F A74E +A750 A751 A750 +A751 A751 A750 +A752 A753 A752 +A753 A753 A752 +A754 A755 A754 +A755 A755 A754 +A756 A757 A756 +A757 A757 A756 +A758 A759 A758 +A759 A759 A758 +A75A A75B A75A +A75B A75B A75A +A75C A75D A75C +A75D A75D A75C +A75E A75F A75E +A75F A75F A75E +A760 A761 A760 +A761 A761 A760 +A762 A763 A762 +A763 A763 A762 +A764 A765 A764 +A765 A765 A764 +A766 A767 A766 +A767 A767 A766 +A768 A769 A768 +A769 A769 A768 +A76A A76B A76A +A76B A76B A76A +A76C A76D A76C +A76D A76D A76C +A76E A76F A76E +A76F A76F A76E +A779 A77A A779 +A77A A77A A779 +A77B A77C A77B +A77C A77C A77B +A77D 1D79 A77D +A77E A77F A77E +A77F A77F A77E +A780 A781 A780 +A781 A781 A780 +A782 A783 A782 +A783 A783 A782 +A784 A785 A784 +A785 A785 A784 +A786 A787 A786 +A787 A787 A786 +A78B A78C A78B +A78C A78C A78B +A78D 0265 A78D +A790 A791 A790 +A791 A791 A790 +A792 A793 A792 +A793 A793 A792 +A794 A794 A7C4 +A796 A797 A796 +A797 A797 A796 +A798 A799 A798 +A799 A799 A798 +A79A A79B A79A +A79B A79B A79A +A79C A79D A79C +A79D A79D A79C +A79E A79F A79E +A79F A79F A79E +A7A0 A7A1 A7A0 +A7A1 A7A1 A7A0 +A7A2 A7A3 A7A2 +A7A3 A7A3 A7A2 +A7A4 A7A5 A7A4 +A7A5 A7A5 A7A4 +A7A6 A7A7 A7A6 +A7A7 A7A7 A7A6 +A7A8 A7A9 A7A8 +A7A9 A7A9 A7A8 +A7AA 0266 A7AA +A7AB 025C A7AB +A7AC 0261 A7AC +A7AD 026C A7AD +A7AE 026A A7AE +A7B0 029E A7B0 +A7B1 0287 A7B1 +A7B2 029D A7B2 +A7B3 AB53 A7B3 +A7B4 A7B5 A7B4 +A7B5 A7B5 A7B4 +A7B6 A7B7 A7B6 +A7B7 A7B7 A7B6 +A7B8 A7B9 A7B8 +A7B9 A7B9 A7B8 +A7BA A7BB A7BA +A7BB A7BB A7BA +A7BC A7BD A7BC +A7BD A7BD A7BC +A7BE A7BF A7BE +A7BF A7BF A7BE +A7C0 A7C1 A7C0 +A7C1 A7C1 A7C0 +A7C2 A7C3 A7C2 +A7C3 A7C3 A7C2 +A7C4 A794 A7C4 +A7C5 0282 A7C5 +A7C6 1D8E A7C6 +A7C7 A7C8 A7C7 +A7C8 A7C8 A7C7 +A7C9 A7CA A7C9 +A7CA A7CA A7C9 +A7D0 A7D1 A7D0 +A7D1 A7D1 A7D0 +A7D6 A7D7 A7D6 +A7D7 A7D7 A7D6 +A7D8 A7D9 A7D8 +A7D9 A7D9 A7D8 +A7F5 A7F6 A7F5 +A7F6 A7F6 A7F5 +AB53 AB53 A7B3 +AB70 AB70 13A0 +AB71 AB71 13A1 +AB72 AB72 13A2 +AB73 AB73 13A3 +AB74 AB74 13A4 +AB75 AB75 13A5 +AB76 AB76 13A6 +AB77 AB77 13A7 +AB78 AB78 13A8 +AB79 AB79 13A9 +AB7A AB7A 13AA +AB7B AB7B 13AB +AB7C AB7C 13AC +AB7D AB7D 13AD +AB7E AB7E 13AE +AB7F AB7F 13AF +AB80 AB80 13B0 +AB81 AB81 13B1 +AB82 AB82 13B2 +AB83 AB83 13B3 +AB84 AB84 13B4 +AB85 AB85 13B5 +AB86 AB86 13B6 +AB87 AB87 13B7 +AB88 AB88 13B8 +AB89 AB89 13B9 +AB8A AB8A 13BA +AB8B AB8B 13BB +AB8C AB8C 13BC +AB8D AB8D 13BD +AB8E AB8E 13BE +AB8F AB8F 13BF +AB90 AB90 13C0 +AB91 AB91 13C1 +AB92 AB92 13C2 +AB93 AB93 13C3 +AB94 AB94 13C4 +AB95 AB95 13C5 +AB96 AB96 13C6 +AB97 AB97 13C7 +AB98 AB98 13C8 +AB99 AB99 13C9 +AB9A AB9A 13CA +AB9B AB9B 13CB +AB9C AB9C 13CC +AB9D AB9D 13CD +AB9E AB9E 13CE +AB9F AB9F 13CF +ABA0 ABA0 13D0 +ABA1 ABA1 13D1 +ABA2 ABA2 13D2 +ABA3 ABA3 13D3 +ABA4 ABA4 13D4 +ABA5 ABA5 13D5 +ABA6 ABA6 13D6 +ABA7 ABA7 13D7 +ABA8 ABA8 13D8 +ABA9 ABA9 13D9 +ABAA ABAA 13DA +ABAB ABAB 13DB +ABAC ABAC 13DC +ABAD ABAD 13DD +ABAE ABAE 13DE +ABAF ABAF 13DF +ABB0 ABB0 13E0 +ABB1 ABB1 13E1 +ABB2 ABB2 13E2 +ABB3 ABB3 13E3 +ABB4 ABB4 13E4 +ABB5 ABB5 13E5 +ABB6 ABB6 13E6 +ABB7 ABB7 13E7 +ABB8 ABB8 13E8 +ABB9 ABB9 13E9 +ABBA ABBA 13EA +ABBB ABBB 13EB +ABBC ABBC 13EC +ABBD ABBD 13ED +ABBE ABBE 13EE +ABBF ABBF 13EF +FF21 FF41 FF21 +FF22 FF42 FF22 +FF23 FF43 FF23 +FF24 FF44 FF24 +FF25 FF45 FF25 +FF26 FF46 FF26 +FF27 FF47 FF27 +FF28 FF48 FF28 +FF29 FF49 FF29 +FF2A FF4A FF2A +FF2B FF4B FF2B +FF2C FF4C FF2C +FF2D FF4D FF2D +FF2E FF4E FF2E +FF2F FF4F FF2F +FF30 FF50 FF30 +FF31 FF51 FF31 +FF32 FF52 FF32 +FF33 FF53 FF33 +FF34 FF54 FF34 +FF35 FF55 FF35 +FF36 FF56 FF36 +FF37 FF57 FF37 +FF38 FF58 FF38 +FF39 FF59 FF39 +FF3A FF5A FF3A +FF41 FF41 FF21 +FF42 FF42 FF22 +FF43 FF43 FF23 +FF44 FF44 FF24 +FF45 FF45 FF25 +FF46 FF46 FF26 +FF47 FF47 FF27 +FF48 FF48 FF28 +FF49 FF49 FF29 +FF4A FF4A FF2A +FF4B FF4B FF2B +FF4C FF4C FF2C +FF4D FF4D FF2D +FF4E FF4E FF2E +FF4F FF4F FF2F +FF50 FF50 FF30 +FF51 FF51 FF31 +FF52 FF52 FF32 +FF53 FF53 FF33 +FF54 FF54 FF34 +FF55 FF55 FF35 +FF56 FF56 FF36 +FF57 FF57 FF37 +FF58 FF58 FF38 +FF59 FF59 FF39 +FF5A FF5A FF3A +# +# BMP characters with a non-trivial upper/lower mapping +# +SELECT +codepoint_hex4 as hex4, +HEX(CAST(LOWER(c) AS CHAR CHARACTER SET ucs2)) AS hex4_l, +HEX(CAST(UPPER(c) AS CHAR CHARACTER SET ucs2)) AS hex4_u, +c=LOWER(c) AS `c=L`, +c=UPPER(c) AS `c=U`, +c LIKE LOWER(c) AS `c~~L`, +c LIKE UPPER(c) AS `c~~U`, +c, +LOWER(c) AS `L(c)`, +UPPER(c) AS `U(c)` +FROM v_bmp +WHERE NOT ( +(BINARY(c)=BINARY(LOWER(c)) OR BINARY(c)=BINARY(UPPER(c))) AND +c = LOWER(c) AND +c = UPPER(c) AND +c LIKE UPPER(c) AND +c LIKE LOWER(c) +); +hex4 hex4_l hex4_u c=L c=U c~~L c~~U c L(c) U(c) +0130 0069 0130 0 1 0 1 İ i İ +01C5 01C6 01C4 1 1 1 1 Dž dž DŽ +01C8 01C9 01C7 1 1 1 1 Lj lj LJ +01CB 01CC 01CA 1 1 1 1 Nj nj NJ +01F2 01F3 01F1 1 1 1 1 Dz dz DZ +03F4 03B8 03F4 0 1 0 1 ϴ θ ϴ +1E9E 00DF 1E9E 0 1 0 1 ẞ ß ẞ +2126 03C9 2126 0 1 0 1 Ω ω Ω +212A 006B 212A 0 1 0 1 K k K +212B 00E5 212B 0 1 0 1 Å å Å +DROP VIEW v_bmp; +EXECUTE IMMEDIATE SFORMAT(' +CREATE VIEW v_supplementary AS +SELECT + seq AS codepoint, + LPAD(HEX(seq),8,''0'') AS codepoint_hex8, + CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c +FROM + seq_65536_to_1114111', @@character_set_connection, @@collation_connection); +SELECT COLLATION(c) FROM v_supplementary LIMIT 1; +COLLATION(c) +utf8mb4_general1400_as_ci +SELECT +codepoint_hex8, +HEX(CAST(LOWER(c) AS CHAR CHARACTER SET utf32)), +HEX(CAST(UPPER(c) AS CHAR CHARACTER SET utf32)) +FROM v_supplementary +WHERE BINARY(c)<>BINARY(LOWER(c)) OR BINARY(c)<>BINARY(UPPER(c)); +codepoint_hex8 HEX(CAST(LOWER(c) AS CHAR CHARACTER SET utf32)) HEX(CAST(UPPER(c) AS CHAR CHARACTER SET utf32)) +00010400 00010428 00010400 +00010401 00010429 00010401 +00010402 0001042A 00010402 +00010403 0001042B 00010403 +00010404 0001042C 00010404 +00010405 0001042D 00010405 +00010406 0001042E 00010406 +00010407 0001042F 00010407 +00010408 00010430 00010408 +00010409 00010431 00010409 +0001040A 00010432 0001040A +0001040B 00010433 0001040B +0001040C 00010434 0001040C +0001040D 00010435 0001040D +0001040E 00010436 0001040E +0001040F 00010437 0001040F +00010410 00010438 00010410 +00010411 00010439 00010411 +00010412 0001043A 00010412 +00010413 0001043B 00010413 +00010414 0001043C 00010414 +00010415 0001043D 00010415 +00010416 0001043E 00010416 +00010417 0001043F 00010417 +00010418 00010440 00010418 +00010419 00010441 00010419 +0001041A 00010442 0001041A +0001041B 00010443 0001041B +0001041C 00010444 0001041C +0001041D 00010445 0001041D +0001041E 00010446 0001041E +0001041F 00010447 0001041F +00010420 00010448 00010420 +00010421 00010449 00010421 +00010422 0001044A 00010422 +00010423 0001044B 00010423 +00010424 0001044C 00010424 +00010425 0001044D 00010425 +00010426 0001044E 00010426 +00010427 0001044F 00010427 +00010428 00010428 00010400 +00010429 00010429 00010401 +0001042A 0001042A 00010402 +0001042B 0001042B 00010403 +0001042C 0001042C 00010404 +0001042D 0001042D 00010405 +0001042E 0001042E 00010406 +0001042F 0001042F 00010407 +00010430 00010430 00010408 +00010431 00010431 00010409 +00010432 00010432 0001040A +00010433 00010433 0001040B +00010434 00010434 0001040C +00010435 00010435 0001040D +00010436 00010436 0001040E +00010437 00010437 0001040F +00010438 00010438 00010410 +00010439 00010439 00010411 +0001043A 0001043A 00010412 +0001043B 0001043B 00010413 +0001043C 0001043C 00010414 +0001043D 0001043D 00010415 +0001043E 0001043E 00010416 +0001043F 0001043F 00010417 +00010440 00010440 00010418 +00010441 00010441 00010419 +00010442 00010442 0001041A +00010443 00010443 0001041B +00010444 00010444 0001041C +00010445 00010445 0001041D +00010446 00010446 0001041E +00010447 00010447 0001041F +00010448 00010448 00010420 +00010449 00010449 00010421 +0001044A 0001044A 00010422 +0001044B 0001044B 00010423 +0001044C 0001044C 00010424 +0001044D 0001044D 00010425 +0001044E 0001044E 00010426 +0001044F 0001044F 00010427 +000104B0 000104D8 000104B0 +000104B1 000104D9 000104B1 +000104B2 000104DA 000104B2 +000104B3 000104DB 000104B3 +000104B4 000104DC 000104B4 +000104B5 000104DD 000104B5 +000104B6 000104DE 000104B6 +000104B7 000104DF 000104B7 +000104B8 000104E0 000104B8 +000104B9 000104E1 000104B9 +000104BA 000104E2 000104BA +000104BB 000104E3 000104BB +000104BC 000104E4 000104BC +000104BD 000104E5 000104BD +000104BE 000104E6 000104BE +000104BF 000104E7 000104BF +000104C0 000104E8 000104C0 +000104C1 000104E9 000104C1 +000104C2 000104EA 000104C2 +000104C3 000104EB 000104C3 +000104C4 000104EC 000104C4 +000104C5 000104ED 000104C5 +000104C6 000104EE 000104C6 +000104C7 000104EF 000104C7 +000104C8 000104F0 000104C8 +000104C9 000104F1 000104C9 +000104CA 000104F2 000104CA +000104CB 000104F3 000104CB +000104CC 000104F4 000104CC +000104CD 000104F5 000104CD +000104CE 000104F6 000104CE +000104CF 000104F7 000104CF +000104D0 000104F8 000104D0 +000104D1 000104F9 000104D1 +000104D2 000104FA 000104D2 +000104D3 000104FB 000104D3 +000104D8 000104D8 000104B0 +000104D9 000104D9 000104B1 +000104DA 000104DA 000104B2 +000104DB 000104DB 000104B3 +000104DC 000104DC 000104B4 +000104DD 000104DD 000104B5 +000104DE 000104DE 000104B6 +000104DF 000104DF 000104B7 +000104E0 000104E0 000104B8 +000104E1 000104E1 000104B9 +000104E2 000104E2 000104BA +000104E3 000104E3 000104BB +000104E4 000104E4 000104BC +000104E5 000104E5 000104BD +000104E6 000104E6 000104BE +000104E7 000104E7 000104BF +000104E8 000104E8 000104C0 +000104E9 000104E9 000104C1 +000104EA 000104EA 000104C2 +000104EB 000104EB 000104C3 +000104EC 000104EC 000104C4 +000104ED 000104ED 000104C5 +000104EE 000104EE 000104C6 +000104EF 000104EF 000104C7 +000104F0 000104F0 000104C8 +000104F1 000104F1 000104C9 +000104F2 000104F2 000104CA +000104F3 000104F3 000104CB +000104F4 000104F4 000104CC +000104F5 000104F5 000104CD +000104F6 000104F6 000104CE +000104F7 000104F7 000104CF +000104F8 000104F8 000104D0 +000104F9 000104F9 000104D1 +000104FA 000104FA 000104D2 +000104FB 000104FB 000104D3 +00010570 00010597 00010570 +00010571 00010598 00010571 +00010572 00010599 00010572 +00010573 0001059A 00010573 +00010574 0001059B 00010574 +00010575 0001059C 00010575 +00010576 0001059D 00010576 +00010577 0001059E 00010577 +00010578 0001059F 00010578 +00010579 000105A0 00010579 +0001057A 000105A1 0001057A +0001057C 000105A3 0001057C +0001057D 000105A4 0001057D +0001057E 000105A5 0001057E +0001057F 000105A6 0001057F +00010580 000105A7 00010580 +00010581 000105A8 00010581 +00010582 000105A9 00010582 +00010583 000105AA 00010583 +00010584 000105AB 00010584 +00010585 000105AC 00010585 +00010586 000105AD 00010586 +00010587 000105AE 00010587 +00010588 000105AF 00010588 +00010589 000105B0 00010589 +0001058A 000105B1 0001058A +0001058C 000105B3 0001058C +0001058D 000105B4 0001058D +0001058E 000105B5 0001058E +0001058F 000105B6 0001058F +00010590 000105B7 00010590 +00010591 000105B8 00010591 +00010592 000105B9 00010592 +00010594 000105BB 00010594 +00010595 000105BC 00010595 +00010597 00010597 00010570 +00010598 00010598 00010571 +00010599 00010599 00010572 +0001059A 0001059A 00010573 +0001059B 0001059B 00010574 +0001059C 0001059C 00010575 +0001059D 0001059D 00010576 +0001059E 0001059E 00010577 +0001059F 0001059F 00010578 +000105A0 000105A0 00010579 +000105A1 000105A1 0001057A +000105A3 000105A3 0001057C +000105A4 000105A4 0001057D +000105A5 000105A5 0001057E +000105A6 000105A6 0001057F +000105A7 000105A7 00010580 +000105A8 000105A8 00010581 +000105A9 000105A9 00010582 +000105AA 000105AA 00010583 +000105AB 000105AB 00010584 +000105AC 000105AC 00010585 +000105AD 000105AD 00010586 +000105AE 000105AE 00010587 +000105AF 000105AF 00010588 +000105B0 000105B0 00010589 +000105B1 000105B1 0001058A +000105B3 000105B3 0001058C +000105B4 000105B4 0001058D +000105B5 000105B5 0001058E +000105B6 000105B6 0001058F +000105B7 000105B7 00010590 +000105B8 000105B8 00010591 +000105B9 000105B9 00010592 +000105BB 000105BB 00010594 +000105BC 000105BC 00010595 +00010C80 00010CC0 00010C80 +00010C81 00010CC1 00010C81 +00010C82 00010CC2 00010C82 +00010C83 00010CC3 00010C83 +00010C84 00010CC4 00010C84 +00010C85 00010CC5 00010C85 +00010C86 00010CC6 00010C86 +00010C87 00010CC7 00010C87 +00010C88 00010CC8 00010C88 +00010C89 00010CC9 00010C89 +00010C8A 00010CCA 00010C8A +00010C8B 00010CCB 00010C8B +00010C8C 00010CCC 00010C8C +00010C8D 00010CCD 00010C8D +00010C8E 00010CCE 00010C8E +00010C8F 00010CCF 00010C8F +00010C90 00010CD0 00010C90 +00010C91 00010CD1 00010C91 +00010C92 00010CD2 00010C92 +00010C93 00010CD3 00010C93 +00010C94 00010CD4 00010C94 +00010C95 00010CD5 00010C95 +00010C96 00010CD6 00010C96 +00010C97 00010CD7 00010C97 +00010C98 00010CD8 00010C98 +00010C99 00010CD9 00010C99 +00010C9A 00010CDA 00010C9A +00010C9B 00010CDB 00010C9B +00010C9C 00010CDC 00010C9C +00010C9D 00010CDD 00010C9D +00010C9E 00010CDE 00010C9E +00010C9F 00010CDF 00010C9F +00010CA0 00010CE0 00010CA0 +00010CA1 00010CE1 00010CA1 +00010CA2 00010CE2 00010CA2 +00010CA3 00010CE3 00010CA3 +00010CA4 00010CE4 00010CA4 +00010CA5 00010CE5 00010CA5 +00010CA6 00010CE6 00010CA6 +00010CA7 00010CE7 00010CA7 +00010CA8 00010CE8 00010CA8 +00010CA9 00010CE9 00010CA9 +00010CAA 00010CEA 00010CAA +00010CAB 00010CEB 00010CAB +00010CAC 00010CEC 00010CAC +00010CAD 00010CED 00010CAD +00010CAE 00010CEE 00010CAE +00010CAF 00010CEF 00010CAF +00010CB0 00010CF0 00010CB0 +00010CB1 00010CF1 00010CB1 +00010CB2 00010CF2 00010CB2 +00010CC0 00010CC0 00010C80 +00010CC1 00010CC1 00010C81 +00010CC2 00010CC2 00010C82 +00010CC3 00010CC3 00010C83 +00010CC4 00010CC4 00010C84 +00010CC5 00010CC5 00010C85 +00010CC6 00010CC6 00010C86 +00010CC7 00010CC7 00010C87 +00010CC8 00010CC8 00010C88 +00010CC9 00010CC9 00010C89 +00010CCA 00010CCA 00010C8A +00010CCB 00010CCB 00010C8B +00010CCC 00010CCC 00010C8C +00010CCD 00010CCD 00010C8D +00010CCE 00010CCE 00010C8E +00010CCF 00010CCF 00010C8F +00010CD0 00010CD0 00010C90 +00010CD1 00010CD1 00010C91 +00010CD2 00010CD2 00010C92 +00010CD3 00010CD3 00010C93 +00010CD4 00010CD4 00010C94 +00010CD5 00010CD5 00010C95 +00010CD6 00010CD6 00010C96 +00010CD7 00010CD7 00010C97 +00010CD8 00010CD8 00010C98 +00010CD9 00010CD9 00010C99 +00010CDA 00010CDA 00010C9A +00010CDB 00010CDB 00010C9B +00010CDC 00010CDC 00010C9C +00010CDD 00010CDD 00010C9D +00010CDE 00010CDE 00010C9E +00010CDF 00010CDF 00010C9F +00010CE0 00010CE0 00010CA0 +00010CE1 00010CE1 00010CA1 +00010CE2 00010CE2 00010CA2 +00010CE3 00010CE3 00010CA3 +00010CE4 00010CE4 00010CA4 +00010CE5 00010CE5 00010CA5 +00010CE6 00010CE6 00010CA6 +00010CE7 00010CE7 00010CA7 +00010CE8 00010CE8 00010CA8 +00010CE9 00010CE9 00010CA9 +00010CEA 00010CEA 00010CAA +00010CEB 00010CEB 00010CAB +00010CEC 00010CEC 00010CAC +00010CED 00010CED 00010CAD +00010CEE 00010CEE 00010CAE +00010CEF 00010CEF 00010CAF +00010CF0 00010CF0 00010CB0 +00010CF1 00010CF1 00010CB1 +00010CF2 00010CF2 00010CB2 +000118A0 000118C0 000118A0 +000118A1 000118C1 000118A1 +000118A2 000118C2 000118A2 +000118A3 000118C3 000118A3 +000118A4 000118C4 000118A4 +000118A5 000118C5 000118A5 +000118A6 000118C6 000118A6 +000118A7 000118C7 000118A7 +000118A8 000118C8 000118A8 +000118A9 000118C9 000118A9 +000118AA 000118CA 000118AA +000118AB 000118CB 000118AB +000118AC 000118CC 000118AC +000118AD 000118CD 000118AD +000118AE 000118CE 000118AE +000118AF 000118CF 000118AF +000118B0 000118D0 000118B0 +000118B1 000118D1 000118B1 +000118B2 000118D2 000118B2 +000118B3 000118D3 000118B3 +000118B4 000118D4 000118B4 +000118B5 000118D5 000118B5 +000118B6 000118D6 000118B6 +000118B7 000118D7 000118B7 +000118B8 000118D8 000118B8 +000118B9 000118D9 000118B9 +000118BA 000118DA 000118BA +000118BB 000118DB 000118BB +000118BC 000118DC 000118BC +000118BD 000118DD 000118BD +000118BE 000118DE 000118BE +000118BF 000118DF 000118BF +000118C0 000118C0 000118A0 +000118C1 000118C1 000118A1 +000118C2 000118C2 000118A2 +000118C3 000118C3 000118A3 +000118C4 000118C4 000118A4 +000118C5 000118C5 000118A5 +000118C6 000118C6 000118A6 +000118C7 000118C7 000118A7 +000118C8 000118C8 000118A8 +000118C9 000118C9 000118A9 +000118CA 000118CA 000118AA +000118CB 000118CB 000118AB +000118CC 000118CC 000118AC +000118CD 000118CD 000118AD +000118CE 000118CE 000118AE +000118CF 000118CF 000118AF +000118D0 000118D0 000118B0 +000118D1 000118D1 000118B1 +000118D2 000118D2 000118B2 +000118D3 000118D3 000118B3 +000118D4 000118D4 000118B4 +000118D5 000118D5 000118B5 +000118D6 000118D6 000118B6 +000118D7 000118D7 000118B7 +000118D8 000118D8 000118B8 +000118D9 000118D9 000118B9 +000118DA 000118DA 000118BA +000118DB 000118DB 000118BB +000118DC 000118DC 000118BC +000118DD 000118DD 000118BD +000118DE 000118DE 000118BE +000118DF 000118DF 000118BF +00016E40 00016E60 00016E40 +00016E41 00016E61 00016E41 +00016E42 00016E62 00016E42 +00016E43 00016E63 00016E43 +00016E44 00016E64 00016E44 +00016E45 00016E65 00016E45 +00016E46 00016E66 00016E46 +00016E47 00016E67 00016E47 +00016E48 00016E68 00016E48 +00016E49 00016E69 00016E49 +00016E4A 00016E6A 00016E4A +00016E4B 00016E6B 00016E4B +00016E4C 00016E6C 00016E4C +00016E4D 00016E6D 00016E4D +00016E4E 00016E6E 00016E4E +00016E4F 00016E6F 00016E4F +00016E50 00016E70 00016E50 +00016E51 00016E71 00016E51 +00016E52 00016E72 00016E52 +00016E53 00016E73 00016E53 +00016E54 00016E74 00016E54 +00016E55 00016E75 00016E55 +00016E56 00016E76 00016E56 +00016E57 00016E77 00016E57 +00016E58 00016E78 00016E58 +00016E59 00016E79 00016E59 +00016E5A 00016E7A 00016E5A +00016E5B 00016E7B 00016E5B +00016E5C 00016E7C 00016E5C +00016E5D 00016E7D 00016E5D +00016E5E 00016E7E 00016E5E +00016E5F 00016E7F 00016E5F +00016E60 00016E60 00016E40 +00016E61 00016E61 00016E41 +00016E62 00016E62 00016E42 +00016E63 00016E63 00016E43 +00016E64 00016E64 00016E44 +00016E65 00016E65 00016E45 +00016E66 00016E66 00016E46 +00016E67 00016E67 00016E47 +00016E68 00016E68 00016E48 +00016E69 00016E69 00016E49 +00016E6A 00016E6A 00016E4A +00016E6B 00016E6B 00016E4B +00016E6C 00016E6C 00016E4C +00016E6D 00016E6D 00016E4D +00016E6E 00016E6E 00016E4E +00016E6F 00016E6F 00016E4F +00016E70 00016E70 00016E50 +00016E71 00016E71 00016E51 +00016E72 00016E72 00016E52 +00016E73 00016E73 00016E53 +00016E74 00016E74 00016E54 +00016E75 00016E75 00016E55 +00016E76 00016E76 00016E56 +00016E77 00016E77 00016E57 +00016E78 00016E78 00016E58 +00016E79 00016E79 00016E59 +00016E7A 00016E7A 00016E5A +00016E7B 00016E7B 00016E5B +00016E7C 00016E7C 00016E5C +00016E7D 00016E7D 00016E5D +00016E7E 00016E7E 00016E5E +00016E7F 00016E7F 00016E5F +0001E900 0001E922 0001E900 +0001E901 0001E923 0001E901 +0001E902 0001E924 0001E902 +0001E903 0001E925 0001E903 +0001E904 0001E926 0001E904 +0001E905 0001E927 0001E905 +0001E906 0001E928 0001E906 +0001E907 0001E929 0001E907 +0001E908 0001E92A 0001E908 +0001E909 0001E92B 0001E909 +0001E90A 0001E92C 0001E90A +0001E90B 0001E92D 0001E90B +0001E90C 0001E92E 0001E90C +0001E90D 0001E92F 0001E90D +0001E90E 0001E930 0001E90E +0001E90F 0001E931 0001E90F +0001E910 0001E932 0001E910 +0001E911 0001E933 0001E911 +0001E912 0001E934 0001E912 +0001E913 0001E935 0001E913 +0001E914 0001E936 0001E914 +0001E915 0001E937 0001E915 +0001E916 0001E938 0001E916 +0001E917 0001E939 0001E917 +0001E918 0001E93A 0001E918 +0001E919 0001E93B 0001E919 +0001E91A 0001E93C 0001E91A +0001E91B 0001E93D 0001E91B +0001E91C 0001E93E 0001E91C +0001E91D 0001E93F 0001E91D +0001E91E 0001E940 0001E91E +0001E91F 0001E941 0001E91F +0001E920 0001E942 0001E920 +0001E921 0001E943 0001E921 +0001E922 0001E922 0001E900 +0001E923 0001E923 0001E901 +0001E924 0001E924 0001E902 +0001E925 0001E925 0001E903 +0001E926 0001E926 0001E904 +0001E927 0001E927 0001E905 +0001E928 0001E928 0001E906 +0001E929 0001E929 0001E907 +0001E92A 0001E92A 0001E908 +0001E92B 0001E92B 0001E909 +0001E92C 0001E92C 0001E90A +0001E92D 0001E92D 0001E90B +0001E92E 0001E92E 0001E90C +0001E92F 0001E92F 0001E90D +0001E930 0001E930 0001E90E +0001E931 0001E931 0001E90F +0001E932 0001E932 0001E910 +0001E933 0001E933 0001E911 +0001E934 0001E934 0001E912 +0001E935 0001E935 0001E913 +0001E936 0001E936 0001E914 +0001E937 0001E937 0001E915 +0001E938 0001E938 0001E916 +0001E939 0001E939 0001E917 +0001E93A 0001E93A 0001E918 +0001E93B 0001E93B 0001E919 +0001E93C 0001E93C 0001E91A +0001E93D 0001E93D 0001E91B +0001E93E 0001E93E 0001E91C +0001E93F 0001E93F 0001E91D +0001E940 0001E940 0001E91E +0001E941 0001E941 0001E91F +0001E942 0001E942 0001E920 +0001E943 0001E943 0001E921 +DROP VIEW v_supplementary; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.test b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.test new file mode 100644 index 00000000000..3bc71609c48 --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_casefold.test @@ -0,0 +1,15 @@ +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +--echo # + +SET NAMES utf8mb4 COLLATE utf8mb4_general1400_as_ci; +--source include/ctype_unicode_casefold_bmp.inc +--source include/ctype_unicode_casefold_supplementary.inc + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.result b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.result new file mode 100644 index 00000000000..d96b36d1d4d --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.result @@ -0,0 +1,1482 @@ +# +# Start of 11.5 tests +# +# +# MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +# +SET NAMES utf8mb4 COLLATE utf8mb4_general1400_as_ci; +EXECUTE IMMEDIATE SFORMAT(' +CREATE VIEW v_bmp AS +SELECT + seq AS codepoint, + LPAD(HEX(seq),6,''0'') AS codepoint_hex6, + CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c +FROM + seq_0_to_1114111', @@character_set_connection, @@collation_connection); +SELECT COLLATION(c) FROM v_bmp LIMIT 1; +COLLATION(c) +utf8mb4_general1400_as_ci +SELECT +SUM(codepoint_hex6=HEX(LOWER(c))) AS count_bmp_weight_is_lower, +SUM(codepoint_hex6<>HEX(LOWER(c))) AS count_bmp_weight_is_not_lower +FROM v_bmp; +count_bmp_weight_is_lower count_bmp_weight_is_not_lower +0 1114112 +SELECT codepoint_hex6,HEX(WEIGHT_STRING(c)) +FROM v_bmp +WHERE codepoint_hex6<>HEX(WEIGHT_STRING(c)); +codepoint_hex6 HEX(WEIGHT_STRING(c)) +000061 000041 +000062 000042 +000063 000043 +000064 000044 +000065 000045 +000066 000046 +000067 000047 +000068 000048 +000069 000049 +00006A 00004A +00006B 00004B +00006C 00004C +00006D 00004D +00006E 00004E +00006F 00004F +000070 000050 +000071 000051 +000072 000052 +000073 000053 +000074 000054 +000075 000055 +000076 000056 +000077 000057 +000078 000058 +000079 000059 +00007A 00005A +0000B5 00039C +0000E0 0000C0 +0000E1 0000C1 +0000E2 0000C2 +0000E3 0000C3 +0000E4 0000C4 +0000E5 0000C5 +0000E6 0000C6 +0000E7 0000C7 +0000E8 0000C8 +0000E9 0000C9 +0000EA 0000CA +0000EB 0000CB +0000EC 0000CC +0000ED 0000CD +0000EE 0000CE +0000EF 0000CF +0000F0 0000D0 +0000F1 0000D1 +0000F2 0000D2 +0000F3 0000D3 +0000F4 0000D4 +0000F5 0000D5 +0000F6 0000D6 +0000F8 0000D8 +0000F9 0000D9 +0000FA 0000DA +0000FB 0000DB +0000FC 0000DC +0000FD 0000DD +0000FE 0000DE +0000FF 000178 +000101 000100 +000103 000102 +000105 000104 +000107 000106 +000109 000108 +00010B 00010A +00010D 00010C +00010F 00010E +000111 000110 +000113 000112 +000115 000114 +000117 000116 +000119 000118 +00011B 00011A +00011D 00011C +00011F 00011E +000121 000120 +000123 000122 +000125 000124 +000127 000126 +000129 000128 +00012B 00012A +00012D 00012C +00012F 00012E +000131 000049 +000133 000132 +000135 000134 +000137 000136 +00013A 000139 +00013C 00013B +00013E 00013D +000140 00013F +000142 000141 +000144 000143 +000146 000145 +000148 000147 +00014B 00014A +00014D 00014C +00014F 00014E +000151 000150 +000153 000152 +000155 000154 +000157 000156 +000159 000158 +00015B 00015A +00015D 00015C +00015F 00015E +000161 000160 +000163 000162 +000165 000164 +000167 000166 +000169 000168 +00016B 00016A +00016D 00016C +00016F 00016E +000171 000170 +000173 000172 +000175 000174 +000177 000176 +00017A 000179 +00017C 00017B +00017E 00017D +00017F 000053 +000180 000243 +000183 000182 +000185 000184 +000188 000187 +00018C 00018B +000192 000191 +000195 0001F6 +000199 000198 +00019A 00023D +00019E 000220 +0001A1 0001A0 +0001A3 0001A2 +0001A5 0001A4 +0001A8 0001A7 +0001AD 0001AC +0001B0 0001AF +0001B4 0001B3 +0001B6 0001B5 +0001B9 0001B8 +0001BD 0001BC +0001BF 0001F7 +0001C5 0001C4 +0001C6 0001C4 +0001C8 0001C7 +0001C9 0001C7 +0001CB 0001CA +0001CC 0001CA +0001CE 0001CD +0001D0 0001CF +0001D2 0001D1 +0001D4 0001D3 +0001D6 0001D5 +0001D8 0001D7 +0001DA 0001D9 +0001DC 0001DB +0001DD 00018E +0001DF 0001DE +0001E1 0001E0 +0001E3 0001E2 +0001E5 0001E4 +0001E7 0001E6 +0001E9 0001E8 +0001EB 0001EA +0001ED 0001EC +0001EF 0001EE +0001F2 0001F1 +0001F3 0001F1 +0001F5 0001F4 +0001F9 0001F8 +0001FB 0001FA +0001FD 0001FC +0001FF 0001FE +000201 000200 +000203 000202 +000205 000204 +000207 000206 +000209 000208 +00020B 00020A +00020D 00020C +00020F 00020E +000211 000210 +000213 000212 +000215 000214 +000217 000216 +000219 000218 +00021B 00021A +00021D 00021C +00021F 00021E +000223 000222 +000225 000224 +000227 000226 +000229 000228 +00022B 00022A +00022D 00022C +00022F 00022E +000231 000230 +000233 000232 +00023C 00023B +00023F 002C7E +000240 002C7F +000242 000241 +000247 000246 +000249 000248 +00024B 00024A +00024D 00024C +00024F 00024E +000250 002C6F +000251 002C6D +000252 002C70 +000253 000181 +000254 000186 +000256 000189 +000257 00018A +000259 00018F +00025B 000190 +00025C 00A7AB +000260 000193 +000261 00A7AC +000263 000194 +000265 00A78D +000266 00A7AA +000268 000197 +000269 000196 +00026A 00A7AE +00026B 002C62 +00026C 00A7AD +00026F 00019C +000271 002C6E +000272 00019D +000275 00019F +00027D 002C64 +000280 0001A6 +000282 00A7C5 +000283 0001A9 +000287 00A7B1 +000288 0001AE +000289 000244 +00028A 0001B1 +00028B 0001B2 +00028C 000245 +000292 0001B7 +00029D 00A7B2 +00029E 00A7B0 +000345 000399 +000371 000370 +000373 000372 +000377 000376 +00037B 0003FD +00037C 0003FE +00037D 0003FF +0003AC 000386 +0003AD 000388 +0003AE 000389 +0003AF 00038A +0003B1 000391 +0003B2 000392 +0003B3 000393 +0003B4 000394 +0003B5 000395 +0003B6 000396 +0003B7 000397 +0003B8 000398 +0003B9 000399 +0003BA 00039A +0003BB 00039B +0003BC 00039C +0003BD 00039D +0003BE 00039E +0003BF 00039F +0003C0 0003A0 +0003C1 0003A1 +0003C2 0003A3 +0003C3 0003A3 +0003C4 0003A4 +0003C5 0003A5 +0003C6 0003A6 +0003C7 0003A7 +0003C8 0003A8 +0003C9 0003A9 +0003CA 0003AA +0003CB 0003AB +0003CC 00038C +0003CD 00038E +0003CE 00038F +0003D0 000392 +0003D1 000398 +0003D5 0003A6 +0003D6 0003A0 +0003D7 0003CF +0003D9 0003D8 +0003DB 0003DA +0003DD 0003DC +0003DF 0003DE +0003E1 0003E0 +0003E3 0003E2 +0003E5 0003E4 +0003E7 0003E6 +0003E9 0003E8 +0003EB 0003EA +0003ED 0003EC +0003EF 0003EE +0003F0 00039A +0003F1 0003A1 +0003F2 0003F9 +0003F3 00037F +0003F5 000395 +0003F8 0003F7 +0003FB 0003FA +000430 000410 +000431 000411 +000432 000412 +000433 000413 +000434 000414 +000435 000415 +000436 000416 +000437 000417 +000438 000418 +000439 000419 +00043A 00041A +00043B 00041B +00043C 00041C +00043D 00041D +00043E 00041E +00043F 00041F +000440 000420 +000441 000421 +000442 000422 +000443 000423 +000444 000424 +000445 000425 +000446 000426 +000447 000427 +000448 000428 +000449 000429 +00044A 00042A +00044B 00042B +00044C 00042C +00044D 00042D +00044E 00042E +00044F 00042F +000450 000400 +000451 000401 +000452 000402 +000453 000403 +000454 000404 +000455 000405 +000456 000406 +000457 000407 +000458 000408 +000459 000409 +00045A 00040A +00045B 00040B +00045C 00040C +00045D 00040D +00045E 00040E +00045F 00040F +000461 000460 +000463 000462 +000465 000464 +000467 000466 +000469 000468 +00046B 00046A +00046D 00046C +00046F 00046E +000471 000470 +000473 000472 +000475 000474 +000477 000476 +000479 000478 +00047B 00047A +00047D 00047C +00047F 00047E +000481 000480 +00048B 00048A +00048D 00048C +00048F 00048E +000491 000490 +000493 000492 +000495 000494 +000497 000496 +000499 000498 +00049B 00049A +00049D 00049C +00049F 00049E +0004A1 0004A0 +0004A3 0004A2 +0004A5 0004A4 +0004A7 0004A6 +0004A9 0004A8 +0004AB 0004AA +0004AD 0004AC +0004AF 0004AE +0004B1 0004B0 +0004B3 0004B2 +0004B5 0004B4 +0004B7 0004B6 +0004B9 0004B8 +0004BB 0004BA +0004BD 0004BC +0004BF 0004BE +0004C2 0004C1 +0004C4 0004C3 +0004C6 0004C5 +0004C8 0004C7 +0004CA 0004C9 +0004CC 0004CB +0004CE 0004CD +0004CF 0004C0 +0004D1 0004D0 +0004D3 0004D2 +0004D5 0004D4 +0004D7 0004D6 +0004D9 0004D8 +0004DB 0004DA +0004DD 0004DC +0004DF 0004DE +0004E1 0004E0 +0004E3 0004E2 +0004E5 0004E4 +0004E7 0004E6 +0004E9 0004E8 +0004EB 0004EA +0004ED 0004EC +0004EF 0004EE +0004F1 0004F0 +0004F3 0004F2 +0004F5 0004F4 +0004F7 0004F6 +0004F9 0004F8 +0004FB 0004FA +0004FD 0004FC +0004FF 0004FE +000501 000500 +000503 000502 +000505 000504 +000507 000506 +000509 000508 +00050B 00050A +00050D 00050C +00050F 00050E +000511 000510 +000513 000512 +000515 000514 +000517 000516 +000519 000518 +00051B 00051A +00051D 00051C +00051F 00051E +000521 000520 +000523 000522 +000525 000524 +000527 000526 +000529 000528 +00052B 00052A +00052D 00052C +00052F 00052E +000561 000531 +000562 000532 +000563 000533 +000564 000534 +000565 000535 +000566 000536 +000567 000537 +000568 000538 +000569 000539 +00056A 00053A +00056B 00053B +00056C 00053C +00056D 00053D +00056E 00053E +00056F 00053F +000570 000540 +000571 000541 +000572 000542 +000573 000543 +000574 000544 +000575 000545 +000576 000546 +000577 000547 +000578 000548 +000579 000549 +00057A 00054A +00057B 00054B +00057C 00054C +00057D 00054D +00057E 00054E +00057F 00054F +000580 000550 +000581 000551 +000582 000552 +000583 000553 +000584 000554 +000585 000555 +000586 000556 +0010D0 001C90 +0010D1 001C91 +0010D2 001C92 +0010D3 001C93 +0010D4 001C94 +0010D5 001C95 +0010D6 001C96 +0010D7 001C97 +0010D8 001C98 +0010D9 001C99 +0010DA 001C9A +0010DB 001C9B +0010DC 001C9C +0010DD 001C9D +0010DE 001C9E +0010DF 001C9F +0010E0 001CA0 +0010E1 001CA1 +0010E2 001CA2 +0010E3 001CA3 +0010E4 001CA4 +0010E5 001CA5 +0010E6 001CA6 +0010E7 001CA7 +0010E8 001CA8 +0010E9 001CA9 +0010EA 001CAA +0010EB 001CAB +0010EC 001CAC +0010ED 001CAD +0010EE 001CAE +0010EF 001CAF +0010F0 001CB0 +0010F1 001CB1 +0010F2 001CB2 +0010F3 001CB3 +0010F4 001CB4 +0010F5 001CB5 +0010F6 001CB6 +0010F7 001CB7 +0010F8 001CB8 +0010F9 001CB9 +0010FA 001CBA +0010FD 001CBD +0010FE 001CBE +0010FF 001CBF +0013F8 0013F0 +0013F9 0013F1 +0013FA 0013F2 +0013FB 0013F3 +0013FC 0013F4 +0013FD 0013F5 +001C80 000412 +001C81 000414 +001C82 00041E +001C83 000421 +001C84 000422 +001C85 000422 +001C86 00042A +001C87 000462 +001C88 00A64A +001D79 00A77D +001D7D 002C63 +001D8E 00A7C6 +001E01 001E00 +001E03 001E02 +001E05 001E04 +001E07 001E06 +001E09 001E08 +001E0B 001E0A +001E0D 001E0C +001E0F 001E0E +001E11 001E10 +001E13 001E12 +001E15 001E14 +001E17 001E16 +001E19 001E18 +001E1B 001E1A +001E1D 001E1C +001E1F 001E1E +001E21 001E20 +001E23 001E22 +001E25 001E24 +001E27 001E26 +001E29 001E28 +001E2B 001E2A +001E2D 001E2C +001E2F 001E2E +001E31 001E30 +001E33 001E32 +001E35 001E34 +001E37 001E36 +001E39 001E38 +001E3B 001E3A +001E3D 001E3C +001E3F 001E3E +001E41 001E40 +001E43 001E42 +001E45 001E44 +001E47 001E46 +001E49 001E48 +001E4B 001E4A +001E4D 001E4C +001E4F 001E4E +001E51 001E50 +001E53 001E52 +001E55 001E54 +001E57 001E56 +001E59 001E58 +001E5B 001E5A +001E5D 001E5C +001E5F 001E5E +001E61 001E60 +001E63 001E62 +001E65 001E64 +001E67 001E66 +001E69 001E68 +001E6B 001E6A +001E6D 001E6C +001E6F 001E6E +001E71 001E70 +001E73 001E72 +001E75 001E74 +001E77 001E76 +001E79 001E78 +001E7B 001E7A +001E7D 001E7C +001E7F 001E7E +001E81 001E80 +001E83 001E82 +001E85 001E84 +001E87 001E86 +001E89 001E88 +001E8B 001E8A +001E8D 001E8C +001E8F 001E8E +001E91 001E90 +001E93 001E92 +001E95 001E94 +001E9B 001E60 +001EA1 001EA0 +001EA3 001EA2 +001EA5 001EA4 +001EA7 001EA6 +001EA9 001EA8 +001EAB 001EAA +001EAD 001EAC +001EAF 001EAE +001EB1 001EB0 +001EB3 001EB2 +001EB5 001EB4 +001EB7 001EB6 +001EB9 001EB8 +001EBB 001EBA +001EBD 001EBC +001EBF 001EBE +001EC1 001EC0 +001EC3 001EC2 +001EC5 001EC4 +001EC7 001EC6 +001EC9 001EC8 +001ECB 001ECA +001ECD 001ECC +001ECF 001ECE +001ED1 001ED0 +001ED3 001ED2 +001ED5 001ED4 +001ED7 001ED6 +001ED9 001ED8 +001EDB 001EDA +001EDD 001EDC +001EDF 001EDE +001EE1 001EE0 +001EE3 001EE2 +001EE5 001EE4 +001EE7 001EE6 +001EE9 001EE8 +001EEB 001EEA +001EED 001EEC +001EEF 001EEE +001EF1 001EF0 +001EF3 001EF2 +001EF5 001EF4 +001EF7 001EF6 +001EF9 001EF8 +001EFB 001EFA +001EFD 001EFC +001EFF 001EFE +001F00 001F08 +001F01 001F09 +001F02 001F0A +001F03 001F0B +001F04 001F0C +001F05 001F0D +001F06 001F0E +001F07 001F0F +001F10 001F18 +001F11 001F19 +001F12 001F1A +001F13 001F1B +001F14 001F1C +001F15 001F1D +001F20 001F28 +001F21 001F29 +001F22 001F2A +001F23 001F2B +001F24 001F2C +001F25 001F2D +001F26 001F2E +001F27 001F2F +001F30 001F38 +001F31 001F39 +001F32 001F3A +001F33 001F3B +001F34 001F3C +001F35 001F3D +001F36 001F3E +001F37 001F3F +001F40 001F48 +001F41 001F49 +001F42 001F4A +001F43 001F4B +001F44 001F4C +001F45 001F4D +001F51 001F59 +001F53 001F5B +001F55 001F5D +001F57 001F5F +001F60 001F68 +001F61 001F69 +001F62 001F6A +001F63 001F6B +001F64 001F6C +001F65 001F6D +001F66 001F6E +001F67 001F6F +001F70 001FBA +001F71 001FBB +001F72 001FC8 +001F73 001FC9 +001F74 001FCA +001F75 001FCB +001F76 001FDA +001F77 001FDB +001F78 001FF8 +001F79 001FF9 +001F7A 001FEA +001F7B 001FEB +001F7C 001FFA +001F7D 001FFB +001F80 001F88 +001F81 001F89 +001F82 001F8A +001F83 001F8B +001F84 001F8C +001F85 001F8D +001F86 001F8E +001F87 001F8F +001F90 001F98 +001F91 001F99 +001F92 001F9A +001F93 001F9B +001F94 001F9C +001F95 001F9D +001F96 001F9E +001F97 001F9F +001FA0 001FA8 +001FA1 001FA9 +001FA2 001FAA +001FA3 001FAB +001FA4 001FAC +001FA5 001FAD +001FA6 001FAE +001FA7 001FAF +001FB0 001FB8 +001FB1 001FB9 +001FB3 001FBC +001FBE 000399 +001FC3 001FCC +001FD0 001FD8 +001FD1 001FD9 +001FE0 001FE8 +001FE1 001FE9 +001FE5 001FEC +001FF3 001FFC +00214E 002132 +002170 002160 +002171 002161 +002172 002162 +002173 002163 +002174 002164 +002175 002165 +002176 002166 +002177 002167 +002178 002168 +002179 002169 +00217A 00216A +00217B 00216B +00217C 00216C +00217D 00216D +00217E 00216E +00217F 00216F +002184 002183 +0024D0 0024B6 +0024D1 0024B7 +0024D2 0024B8 +0024D3 0024B9 +0024D4 0024BA +0024D5 0024BB +0024D6 0024BC +0024D7 0024BD +0024D8 0024BE +0024D9 0024BF +0024DA 0024C0 +0024DB 0024C1 +0024DC 0024C2 +0024DD 0024C3 +0024DE 0024C4 +0024DF 0024C5 +0024E0 0024C6 +0024E1 0024C7 +0024E2 0024C8 +0024E3 0024C9 +0024E4 0024CA +0024E5 0024CB +0024E6 0024CC +0024E7 0024CD +0024E8 0024CE +0024E9 0024CF +002C30 002C00 +002C31 002C01 +002C32 002C02 +002C33 002C03 +002C34 002C04 +002C35 002C05 +002C36 002C06 +002C37 002C07 +002C38 002C08 +002C39 002C09 +002C3A 002C0A +002C3B 002C0B +002C3C 002C0C +002C3D 002C0D +002C3E 002C0E +002C3F 002C0F +002C40 002C10 +002C41 002C11 +002C42 002C12 +002C43 002C13 +002C44 002C14 +002C45 002C15 +002C46 002C16 +002C47 002C17 +002C48 002C18 +002C49 002C19 +002C4A 002C1A +002C4B 002C1B +002C4C 002C1C +002C4D 002C1D +002C4E 002C1E +002C4F 002C1F +002C50 002C20 +002C51 002C21 +002C52 002C22 +002C53 002C23 +002C54 002C24 +002C55 002C25 +002C56 002C26 +002C57 002C27 +002C58 002C28 +002C59 002C29 +002C5A 002C2A +002C5B 002C2B +002C5C 002C2C +002C5D 002C2D +002C5E 002C2E +002C5F 002C2F +002C61 002C60 +002C65 00023A +002C66 00023E +002C68 002C67 +002C6A 002C69 +002C6C 002C6B +002C73 002C72 +002C76 002C75 +002C81 002C80 +002C83 002C82 +002C85 002C84 +002C87 002C86 +002C89 002C88 +002C8B 002C8A +002C8D 002C8C +002C8F 002C8E +002C91 002C90 +002C93 002C92 +002C95 002C94 +002C97 002C96 +002C99 002C98 +002C9B 002C9A +002C9D 002C9C +002C9F 002C9E +002CA1 002CA0 +002CA3 002CA2 +002CA5 002CA4 +002CA7 002CA6 +002CA9 002CA8 +002CAB 002CAA +002CAD 002CAC +002CAF 002CAE +002CB1 002CB0 +002CB3 002CB2 +002CB5 002CB4 +002CB7 002CB6 +002CB9 002CB8 +002CBB 002CBA +002CBD 002CBC +002CBF 002CBE +002CC1 002CC0 +002CC3 002CC2 +002CC5 002CC4 +002CC7 002CC6 +002CC9 002CC8 +002CCB 002CCA +002CCD 002CCC +002CCF 002CCE +002CD1 002CD0 +002CD3 002CD2 +002CD5 002CD4 +002CD7 002CD6 +002CD9 002CD8 +002CDB 002CDA +002CDD 002CDC +002CDF 002CDE +002CE1 002CE0 +002CE3 002CE2 +002CEC 002CEB +002CEE 002CED +002CF3 002CF2 +002D00 0010A0 +002D01 0010A1 +002D02 0010A2 +002D03 0010A3 +002D04 0010A4 +002D05 0010A5 +002D06 0010A6 +002D07 0010A7 +002D08 0010A8 +002D09 0010A9 +002D0A 0010AA +002D0B 0010AB +002D0C 0010AC +002D0D 0010AD +002D0E 0010AE +002D0F 0010AF +002D10 0010B0 +002D11 0010B1 +002D12 0010B2 +002D13 0010B3 +002D14 0010B4 +002D15 0010B5 +002D16 0010B6 +002D17 0010B7 +002D18 0010B8 +002D19 0010B9 +002D1A 0010BA +002D1B 0010BB +002D1C 0010BC +002D1D 0010BD +002D1E 0010BE +002D1F 0010BF +002D20 0010C0 +002D21 0010C1 +002D22 0010C2 +002D23 0010C3 +002D24 0010C4 +002D25 0010C5 +002D27 0010C7 +002D2D 0010CD +00A641 00A640 +00A643 00A642 +00A645 00A644 +00A647 00A646 +00A649 00A648 +00A64B 00A64A +00A64D 00A64C +00A64F 00A64E +00A651 00A650 +00A653 00A652 +00A655 00A654 +00A657 00A656 +00A659 00A658 +00A65B 00A65A +00A65D 00A65C +00A65F 00A65E +00A661 00A660 +00A663 00A662 +00A665 00A664 +00A667 00A666 +00A669 00A668 +00A66B 00A66A +00A66D 00A66C +00A681 00A680 +00A683 00A682 +00A685 00A684 +00A687 00A686 +00A689 00A688 +00A68B 00A68A +00A68D 00A68C +00A68F 00A68E +00A691 00A690 +00A693 00A692 +00A695 00A694 +00A697 00A696 +00A699 00A698 +00A69B 00A69A +00A723 00A722 +00A725 00A724 +00A727 00A726 +00A729 00A728 +00A72B 00A72A +00A72D 00A72C +00A72F 00A72E +00A733 00A732 +00A735 00A734 +00A737 00A736 +00A739 00A738 +00A73B 00A73A +00A73D 00A73C +00A73F 00A73E +00A741 00A740 +00A743 00A742 +00A745 00A744 +00A747 00A746 +00A749 00A748 +00A74B 00A74A +00A74D 00A74C +00A74F 00A74E +00A751 00A750 +00A753 00A752 +00A755 00A754 +00A757 00A756 +00A759 00A758 +00A75B 00A75A +00A75D 00A75C +00A75F 00A75E +00A761 00A760 +00A763 00A762 +00A765 00A764 +00A767 00A766 +00A769 00A768 +00A76B 00A76A +00A76D 00A76C +00A76F 00A76E +00A77A 00A779 +00A77C 00A77B +00A77F 00A77E +00A781 00A780 +00A783 00A782 +00A785 00A784 +00A787 00A786 +00A78C 00A78B +00A791 00A790 +00A793 00A792 +00A794 00A7C4 +00A797 00A796 +00A799 00A798 +00A79B 00A79A +00A79D 00A79C +00A79F 00A79E +00A7A1 00A7A0 +00A7A3 00A7A2 +00A7A5 00A7A4 +00A7A7 00A7A6 +00A7A9 00A7A8 +00A7B5 00A7B4 +00A7B7 00A7B6 +00A7B9 00A7B8 +00A7BB 00A7BA +00A7BD 00A7BC +00A7BF 00A7BE +00A7C1 00A7C0 +00A7C3 00A7C2 +00A7C8 00A7C7 +00A7CA 00A7C9 +00A7D1 00A7D0 +00A7D7 00A7D6 +00A7D9 00A7D8 +00A7F6 00A7F5 +00AB53 00A7B3 +00AB70 0013A0 +00AB71 0013A1 +00AB72 0013A2 +00AB73 0013A3 +00AB74 0013A4 +00AB75 0013A5 +00AB76 0013A6 +00AB77 0013A7 +00AB78 0013A8 +00AB79 0013A9 +00AB7A 0013AA +00AB7B 0013AB +00AB7C 0013AC +00AB7D 0013AD +00AB7E 0013AE +00AB7F 0013AF +00AB80 0013B0 +00AB81 0013B1 +00AB82 0013B2 +00AB83 0013B3 +00AB84 0013B4 +00AB85 0013B5 +00AB86 0013B6 +00AB87 0013B7 +00AB88 0013B8 +00AB89 0013B9 +00AB8A 0013BA +00AB8B 0013BB +00AB8C 0013BC +00AB8D 0013BD +00AB8E 0013BE +00AB8F 0013BF +00AB90 0013C0 +00AB91 0013C1 +00AB92 0013C2 +00AB93 0013C3 +00AB94 0013C4 +00AB95 0013C5 +00AB96 0013C6 +00AB97 0013C7 +00AB98 0013C8 +00AB99 0013C9 +00AB9A 0013CA +00AB9B 0013CB +00AB9C 0013CC +00AB9D 0013CD +00AB9E 0013CE +00AB9F 0013CF +00ABA0 0013D0 +00ABA1 0013D1 +00ABA2 0013D2 +00ABA3 0013D3 +00ABA4 0013D4 +00ABA5 0013D5 +00ABA6 0013D6 +00ABA7 0013D7 +00ABA8 0013D8 +00ABA9 0013D9 +00ABAA 0013DA +00ABAB 0013DB +00ABAC 0013DC +00ABAD 0013DD +00ABAE 0013DE +00ABAF 0013DF +00ABB0 0013E0 +00ABB1 0013E1 +00ABB2 0013E2 +00ABB3 0013E3 +00ABB4 0013E4 +00ABB5 0013E5 +00ABB6 0013E6 +00ABB7 0013E7 +00ABB8 0013E8 +00ABB9 0013E9 +00ABBA 0013EA +00ABBB 0013EB +00ABBC 0013EC +00ABBD 0013ED +00ABBE 0013EE +00ABBF 0013EF +00FF41 00FF21 +00FF42 00FF22 +00FF43 00FF23 +00FF44 00FF24 +00FF45 00FF25 +00FF46 00FF26 +00FF47 00FF27 +00FF48 00FF28 +00FF49 00FF29 +00FF4A 00FF2A +00FF4B 00FF2B +00FF4C 00FF2C +00FF4D 00FF2D +00FF4E 00FF2E +00FF4F 00FF2F +00FF50 00FF30 +00FF51 00FF31 +00FF52 00FF32 +00FF53 00FF33 +00FF54 00FF34 +00FF55 00FF35 +00FF56 00FF36 +00FF57 00FF37 +00FF58 00FF38 +00FF59 00FF39 +00FF5A 00FF3A +010428 010400 +010429 010401 +01042A 010402 +01042B 010403 +01042C 010404 +01042D 010405 +01042E 010406 +01042F 010407 +010430 010408 +010431 010409 +010432 01040A +010433 01040B +010434 01040C +010435 01040D +010436 01040E +010437 01040F +010438 010410 +010439 010411 +01043A 010412 +01043B 010413 +01043C 010414 +01043D 010415 +01043E 010416 +01043F 010417 +010440 010418 +010441 010419 +010442 01041A +010443 01041B +010444 01041C +010445 01041D +010446 01041E +010447 01041F +010448 010420 +010449 010421 +01044A 010422 +01044B 010423 +01044C 010424 +01044D 010425 +01044E 010426 +01044F 010427 +0104D8 0104B0 +0104D9 0104B1 +0104DA 0104B2 +0104DB 0104B3 +0104DC 0104B4 +0104DD 0104B5 +0104DE 0104B6 +0104DF 0104B7 +0104E0 0104B8 +0104E1 0104B9 +0104E2 0104BA +0104E3 0104BB +0104E4 0104BC +0104E5 0104BD +0104E6 0104BE +0104E7 0104BF +0104E8 0104C0 +0104E9 0104C1 +0104EA 0104C2 +0104EB 0104C3 +0104EC 0104C4 +0104ED 0104C5 +0104EE 0104C6 +0104EF 0104C7 +0104F0 0104C8 +0104F1 0104C9 +0104F2 0104CA +0104F3 0104CB +0104F4 0104CC +0104F5 0104CD +0104F6 0104CE +0104F7 0104CF +0104F8 0104D0 +0104F9 0104D1 +0104FA 0104D2 +0104FB 0104D3 +010597 010570 +010598 010571 +010599 010572 +01059A 010573 +01059B 010574 +01059C 010575 +01059D 010576 +01059E 010577 +01059F 010578 +0105A0 010579 +0105A1 01057A +0105A3 01057C +0105A4 01057D +0105A5 01057E +0105A6 01057F +0105A7 010580 +0105A8 010581 +0105A9 010582 +0105AA 010583 +0105AB 010584 +0105AC 010585 +0105AD 010586 +0105AE 010587 +0105AF 010588 +0105B0 010589 +0105B1 01058A +0105B3 01058C +0105B4 01058D +0105B5 01058E +0105B6 01058F +0105B7 010590 +0105B8 010591 +0105B9 010592 +0105BB 010594 +0105BC 010595 +010CC0 010C80 +010CC1 010C81 +010CC2 010C82 +010CC3 010C83 +010CC4 010C84 +010CC5 010C85 +010CC6 010C86 +010CC7 010C87 +010CC8 010C88 +010CC9 010C89 +010CCA 010C8A +010CCB 010C8B +010CCC 010C8C +010CCD 010C8D +010CCE 010C8E +010CCF 010C8F +010CD0 010C90 +010CD1 010C91 +010CD2 010C92 +010CD3 010C93 +010CD4 010C94 +010CD5 010C95 +010CD6 010C96 +010CD7 010C97 +010CD8 010C98 +010CD9 010C99 +010CDA 010C9A +010CDB 010C9B +010CDC 010C9C +010CDD 010C9D +010CDE 010C9E +010CDF 010C9F +010CE0 010CA0 +010CE1 010CA1 +010CE2 010CA2 +010CE3 010CA3 +010CE4 010CA4 +010CE5 010CA5 +010CE6 010CA6 +010CE7 010CA7 +010CE8 010CA8 +010CE9 010CA9 +010CEA 010CAA +010CEB 010CAB +010CEC 010CAC +010CED 010CAD +010CEE 010CAE +010CEF 010CAF +010CF0 010CB0 +010CF1 010CB1 +010CF2 010CB2 +0118C0 0118A0 +0118C1 0118A1 +0118C2 0118A2 +0118C3 0118A3 +0118C4 0118A4 +0118C5 0118A5 +0118C6 0118A6 +0118C7 0118A7 +0118C8 0118A8 +0118C9 0118A9 +0118CA 0118AA +0118CB 0118AB +0118CC 0118AC +0118CD 0118AD +0118CE 0118AE +0118CF 0118AF +0118D0 0118B0 +0118D1 0118B1 +0118D2 0118B2 +0118D3 0118B3 +0118D4 0118B4 +0118D5 0118B5 +0118D6 0118B6 +0118D7 0118B7 +0118D8 0118B8 +0118D9 0118B9 +0118DA 0118BA +0118DB 0118BB +0118DC 0118BC +0118DD 0118BD +0118DE 0118BE +0118DF 0118BF +016E60 016E40 +016E61 016E41 +016E62 016E42 +016E63 016E43 +016E64 016E44 +016E65 016E45 +016E66 016E46 +016E67 016E47 +016E68 016E48 +016E69 016E49 +016E6A 016E4A +016E6B 016E4B +016E6C 016E4C +016E6D 016E4D +016E6E 016E4E +016E6F 016E4F +016E70 016E50 +016E71 016E51 +016E72 016E52 +016E73 016E53 +016E74 016E54 +016E75 016E55 +016E76 016E56 +016E77 016E57 +016E78 016E58 +016E79 016E59 +016E7A 016E5A +016E7B 016E5B +016E7C 016E5C +016E7D 016E5D +016E7E 016E5E +016E7F 016E5F +01E922 01E900 +01E923 01E901 +01E924 01E902 +01E925 01E903 +01E926 01E904 +01E927 01E905 +01E928 01E906 +01E929 01E907 +01E92A 01E908 +01E92B 01E909 +01E92C 01E90A +01E92D 01E90B +01E92E 01E90C +01E92F 01E90D +01E930 01E90E +01E931 01E90F +01E932 01E910 +01E933 01E911 +01E934 01E912 +01E935 01E913 +01E936 01E914 +01E937 01E915 +01E938 01E916 +01E939 01E917 +01E93A 01E918 +01E93B 01E919 +01E93C 01E91A +01E93D 01E91B +01E93E 01E91C +01E93F 01E91D +01E940 01E91E +01E941 01E91F +01E942 01E920 +01E943 01E921 +DROP VIEW v_bmp; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.test b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.test new file mode 100644 index 00000000000..d1db693e12e --- /dev/null +++ b/mysql-test/main/ctype_utf8mb4_general1400_as_ci_ws.test @@ -0,0 +1,39 @@ +--source include/have_utf32.inc +--source include/have_sequence.inc + +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +--echo # + +SET NAMES utf8mb4 COLLATE utf8mb4_general1400_as_ci; + +EXECUTE IMMEDIATE SFORMAT(' +CREATE VIEW v_bmp AS +SELECT + seq AS codepoint, + LPAD(HEX(seq),6,''0'') AS codepoint_hex6, + CONVERT(CHAR(seq USING utf32) USING {}) COLLATE {} AS c +FROM + seq_0_to_1114111', @@character_set_connection, @@collation_connection); + +SELECT COLLATION(c) FROM v_bmp LIMIT 1; + +SELECT + SUM(codepoint_hex6=HEX(LOWER(c))) AS count_bmp_weight_is_lower, + SUM(codepoint_hex6<>HEX(LOWER(c))) AS count_bmp_weight_is_not_lower +FROM v_bmp; + +SELECT codepoint_hex6,HEX(WEIGHT_STRING(c)) +FROM v_bmp +WHERE codepoint_hex6<>HEX(WEIGHT_STRING(c)); + +DROP VIEW v_bmp; + + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/identifier.result b/mysql-test/main/identifier.result new file mode 100644 index 00000000000..e8d8ae2f597 --- /dev/null +++ b/mysql-test/main/identifier.result @@ -0,0 +1,128 @@ +# +# Start of 11.5 tests +# +# +# MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +# +SET NAMES utf8; +CREATE TABLE t1 (I int, ı int); +ERROR 42S21: Duplicate column name 'ı' +CREATE TABLE t1 (a int, b int, KEY I(a), KEY ı(b)); +ERROR 42000: Duplicate key name 'ı' +SET @@lc_time_names=it_ıT; +SELECT @@lc_time_names; +@@lc_time_names +it_IT +SET @@lc_time_names=DEFAULT; +CREATE VIEW v1 AS SELECT 1; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1'; +COUNT(*) +1 +SELECT COUNT(*) FROM INFORMATION_SCHEMA.VıEWS WHERE TABLE_NAME='v1'; +COUNT(*) +1 +DROP VIEW v1; +CREATE OR REPLACE TABLE t1 (pk int, c int); +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (1,2); +INSERT INTO t1 VALUES (1,3); +INSERT INTO t1 VALUES (2,1); +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (2,3); +SELECT pk, COUNT(*) OVER I AS cnt +FROM t1 +WINDOW ı AS (PARTITION BY c ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +pk cnt +1 2 +2 2 +1 2 +2 2 +1 2 +2 2 +DROP TABLE t1; +SELECT CEIL(10.6); +CEIL(10.6) +11 +SELECT CEıL(10.6); +CEıL(10.6) +11 +CREATE FUNCTION I() RETURNS INT RETURN 1; +SELECT ı(); +ı() +1 +DROP FUNCTION ı; +WITH I AS (SELECT 'a1' AS a, 'b1' AS b) SELECT * FROM ı; +a b +a1 b1 +INSTALL PLUGIN arıa SONAME 'not important'; +ERROR HY000: Plugin 'arıa' already installed +CREATE TABLE t1 (a INT) ENGINE=MyıSAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +SELECT @@CHARACTER_SET_CLıENT; +@@CHARACTER_SET_CLıENT +utf8mb3 +SET @I='i'; +SELECT @ı; +@ı +i +CREATE TABLE t1( +x INT, +start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START, +end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END, +PERIOD FOR SYSTEM_TIME(start_tımestamp, end_tımestamp) +) WITH SYSTEM VERSIONING; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL, + `start_timestamp` timestamp(6) GENERATED ALWAYS AS ROW START, + `end_timestamp` timestamp(6) GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME (`start_timestamp`, `end_timestamp`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +DROP TABLE t1; +BEGIN NOT ATOMIC +label_ı: +LOOP +label_I: +LOOP +LEAVE label_I; +END LOOP; +LEAVE label_ı; +END LOOP; +END; +$$ +ERROR 42000: Redefining label label_I +BEGIN NOT ATOMIC +label_ı: +LOOP +SELECT 'looping' AS stage; +LEAVE label_I; +END LOOP; +SELECT 'out of loop' AS stage; +END; +$$ +stage +looping +stage +out of loop +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT 'a' AS I FROM t1 GROUP BY ı; +I +a +SELECT 'a' AS ı FROM t1 GROUP BY I; +ı +a +SELECT 'a' AS İ FROM t1 GROUP BY i; +ERROR 42S22: Unknown column 'i' in 'group statement' +SELECT 'a' AS i FROM t1 GROUP BY İ; +ERROR 42S22: Unknown column 'İ' in 'group statement' +DROP TABLE t1; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/identifier.test b/mysql-test/main/identifier.test new file mode 100644 index 00000000000..d8d90593927 --- /dev/null +++ b/mysql-test/main/identifier.test @@ -0,0 +1,154 @@ +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +--echo # + +# +# Identifiers are accent sensitive and case insensitive, +# and there are usually only two variants of a letter (capital and small) +# having equal octet length in utf8. +# +# There are a few exceptions (coming from Unicode casefolding rules) +# changing octet length during casefolding. +# +# Testing "U+0132 LATIN SMALL LETTER DOTLESS I" versus letters I and i. +# + + +# Column +SET NAMES utf8; +--error ER_DUP_FIELDNAME +CREATE TABLE t1 (I int, ı int); + + +# Index +--error ER_DUP_KEYNAME +CREATE TABLE t1 (a int, b int, KEY I(a), KEY ı(b)); + + +# Locale +SET @@lc_time_names=it_ıT; +SELECT @@lc_time_names; +SET @@lc_time_names=DEFAULT; + + +# Host +#CREATE user u1@ıT; +#SELECT user, host FROM mysql.user WHERE user='u1'; +#DROP USER u1@it; + + +# I_S table name +CREATE VIEW v1 AS SELECT 1; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1'; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.VıEWS WHERE TABLE_NAME='v1'; +DROP VIEW v1; + + +# Window name +CREATE OR REPLACE TABLE t1 (pk int, c int); +INSERT INTO t1 VALUES (1,1); +INSERT INTO t1 VALUES (1,2); +INSERT INTO t1 VALUES (1,3); +INSERT INTO t1 VALUES (2,1); +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (2,3); +SELECT pk, COUNT(*) OVER I AS cnt +FROM t1 +WINDOW ı AS (PARTITION BY c ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +DROP TABLE t1; + + +# Function +SELECT CEIL(10.6); +SELECT CEıL(10.6); + +CREATE FUNCTION I() RETURNS INT RETURN 1; +SELECT ı(); +DROP FUNCTION ı; + + +# CTE - WITH reference +WITH I AS (SELECT 'a1' AS a, 'b1' AS b) SELECT * FROM ı; + + +# Plugin +--error ER_PLUGIN_INSTALLED +INSTALL PLUGIN arıa SONAME 'not important'; + + +# Engine +CREATE TABLE t1 (a INT) ENGINE=MyıSAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; + + +# System variable +SELECT @@CHARACTER_SET_CLıENT; + + +# User variable +SET @I='i'; +SELECT @ı; + + +# System versioning: row start, row end + +CREATE TABLE t1( + x INT, + start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START, + end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END, + PERIOD FOR SYSTEM_TIME(start_tımestamp, end_tımestamp) +) WITH SYSTEM VERSIONING; +SHOW CREATE TABLE t1; +DROP TABLE t1; + + +# Label names + +DELIMITER $$; +--error ER_SP_LABEL_REDEFINE +BEGIN NOT ATOMIC +label_ı: + LOOP +label_I: + LOOP + LEAVE label_I; + END LOOP; + LEAVE label_ı; + END LOOP; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +BEGIN NOT ATOMIC + label_ı: + LOOP + SELECT 'looping' AS stage; + LEAVE label_I; + END LOOP; + SELECT 'out of loop' AS stage; +END; +$$ +DELIMITER ;$$ + + +# References in GROUP BY + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT 'a' AS I FROM t1 GROUP BY ı; +SELECT 'a' AS ı FROM t1 GROUP BY I; +--error ER_BAD_FIELD_ERROR +SELECT 'a' AS İ FROM t1 GROUP BY i; +--error ER_BAD_FIELD_ERROR +SELECT 'a' AS i FROM t1 GROUP BY İ; +DROP TABLE t1; + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/identifier_partition.result b/mysql-test/main/identifier_partition.result new file mode 100644 index 00000000000..61eab33e2d4 --- /dev/null +++ b/mysql-test/main/identifier_partition.result @@ -0,0 +1,50 @@ +# +# Start of 11.5 tests +# +# +# MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +# +SET NAMES utf8; +CREATE TABLE t1 +( +a INT +) +PARTITION BY LIST (a) +( +PARTITION I VALUES IN (0), +PARTITION ı DEFAULT +); +ERROR HY000: Duplicate partition name ı +CREATE TABLE t1 +( +a INT +) +PARTITION BY LIST (a) +( +PARTITION I0 VALUES IN (0), +PARTITION I1 VALUES IN (1), +PARTITION Id DEFAULT +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY LIST (`a`) +(PARTITION `I0` VALUES IN (0) ENGINE = MyISAM, + PARTITION `I1` VALUES IN (1) ENGINE = MyISAM, + PARTITION `Id` DEFAULT ENGINE = MyISAM) +INSERT INTO t1 VALUES (0),(1),(2); +SELECT * FROM t1 PARTITION (ı0); +a +0 +SELECT * FROM t1 PARTITION (ı1); +a +1 +SELECT * FROM t1 PARTITION (ıd); +a +2 +DROP TABLE t1; +# +# End of 11.5 tests +# diff --git a/mysql-test/main/identifier_partition.test b/mysql-test/main/identifier_partition.test new file mode 100644 index 00000000000..0208098aa51 --- /dev/null +++ b/mysql-test/main/identifier_partition.test @@ -0,0 +1,49 @@ +--source include/have_partition.inc + +--echo # +--echo # Start of 11.5 tests +--echo # + +--echo # +--echo # MDEV-31340 Remove MY_COLLATION_HANDLER::strcasecmp() +--echo # + +# +# Testing "U+0131 LATIN SMALL LETTER DOTLESS I" versus letters I and i. +# See comments on casefolding and octet length in identifier.test +# + +SET NAMES utf8; + +--error ER_SAME_NAME_PARTITION +CREATE TABLE t1 +( + a INT +) +PARTITION BY LIST (a) +( + PARTITION I VALUES IN (0), + PARTITION ı DEFAULT +); + + +CREATE TABLE t1 +( + a INT +) +PARTITION BY LIST (a) +( + PARTITION I0 VALUES IN (0), + PARTITION I1 VALUES IN (1), + PARTITION Id DEFAULT +); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (0),(1),(2); +SELECT * FROM t1 PARTITION (ı0); +SELECT * FROM t1 PARTITION (ı1); +SELECT * FROM t1 PARTITION (ıd); +DROP TABLE t1; + +--echo # +--echo # End of 11.5 tests +--echo # diff --git a/mysql-test/main/lowercase_table.result b/mysql-test/main/lowercase_table.result index ff0d0f81b24..02a972c1bfa 100644 --- a/mysql-test/main/lowercase_table.result +++ b/mysql-test/main/lowercase_table.result @@ -1,3 +1,6 @@ +show variables like "lower_case_table_names"; +Variable_name Value +lower_case_table_names 1 create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); create table t4 (id int primary key, Word varchar(40) not null); INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); @@ -191,3 +194,17 @@ ERROR 42000: Incorrect database name '#mysql50#■■■■■■■■■■■ # # End of 11.3 tests # +# +# Start of 11.4 tests +# +# +# MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +# +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE test.pkg AS +END TEST.PKG; +$$ +DROP PACKAGE test.pkg; +# +# End of 11.4 tests +# diff --git a/mysql-test/main/lowercase_table.test b/mysql-test/main/lowercase_table.test index 249989060e0..b5a8a7b7c0c 100644 --- a/mysql-test/main/lowercase_table.test +++ b/mysql-test/main/lowercase_table.test @@ -5,6 +5,8 @@ #remove this include after fix MDEV-27944 --source include/no_view_protocol.inc +show variables like "lower_case_table_names"; + create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); create table t4 (id int primary key, Word varchar(40) not null); INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); @@ -182,3 +184,24 @@ EXECUTE IMMEDIATE CONCAT('SHOW CREATE DATABASE `#mysql50#', REPEAT(@mb3char, 65) --echo # --echo # End of 11.3 tests --echo # + + +--echo # +--echo # Start of 11.4 tests +--echo # + +--echo # +--echo # MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +--echo # + +SET sql_mode=ORACLE; +DELIMITER $$; +CREATE OR REPLACE PACKAGE test.pkg AS +END TEST.PKG; +$$ +DELIMITER ;$$ +DROP PACKAGE test.pkg; + +--echo # +--echo # End of 11.4 tests +--echo # diff --git a/mysql-test/main/lowercase_table2.result b/mysql-test/main/lowercase_table2.result old mode 100755 new mode 100644 index 4180635e6af..0c69aa320dc --- a/mysql-test/main/lowercase_table2.result +++ b/mysql-test/main/lowercase_table2.result @@ -422,3 +422,11 @@ SHOW CREATE DATABASE db1; Database Create Database db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */ DROP DATABASE Db1; +# +# MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +# +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE test.pkg AS +END TEST.PKG; +$$ +DROP PACKAGE test.pkg; diff --git a/mysql-test/main/lowercase_table2.test b/mysql-test/main/lowercase_table2.test index 3addb13e2f9..1cbae5d7552 100644 --- a/mysql-test/main/lowercase_table2.test +++ b/mysql-test/main/lowercase_table2.test @@ -363,3 +363,16 @@ ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; SHOW CREATE DATABASE Db1; SHOW CREATE DATABASE db1; DROP DATABASE Db1; + + +--echo # +--echo # MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +--echo # + +SET sql_mode=ORACLE; +DELIMITER $$; +CREATE OR REPLACE PACKAGE test.pkg AS +END TEST.PKG; +$$ +DELIMITER ;$$ +DROP PACKAGE test.pkg; diff --git a/mysql-test/main/lowercase_table4.result b/mysql-test/main/lowercase_table4.result old mode 100755 new mode 100644 diff --git a/mysql-test/main/lowercase_table5.result b/mysql-test/main/lowercase_table5.result index 77318a8e2aa..2843559d4f5 100644 --- a/mysql-test/main/lowercase_table5.result +++ b/mysql-test/main/lowercase_table5.result @@ -47,3 +47,140 @@ DROP PROCEDURE SP; # # End of 10.4 tests # +# +# MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 +# +CREATE SEQUENCE t1; +CREATE SEQUENCE T1; +SELECT nextval(t1), lastval(t1); +nextval(t1) lastval(t1) +1 1 +SELECT nextval(T1), lastval(T1); +nextval(T1) lastval(T1) +1 1 +SELECT lastval(t1), lastval(T1) l2; +lastval(t1) l2 +1 1 +DROP SEQUENCE t1, T1; +# +# MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +SELECT * FROM db1.t1; +a +SHOW OPEN TABLES IN DB1; +Database Table In_use Name_locked +SHOW OPEN TABLES IN db1; +Database Table In_use Name_locked +db1 t1 0 0 +DROP DATABASE db1; +# +# MDEV-33088 Cannot create triggers in the database `MYSQL` +# +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.t1 (a INT); +CREATE TABLE MYSQL.t2 (a INT); +CREATE TRIGGER MYSQL.tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.a); +INSERT INTO MYSQL.t1 VALUES (10); +SELECT * FROM MYSQL.t1; +a +10 +SELECT * FROM MYSQL.t2; +a +10 +DROP DATABASE MYSQL; +# +# MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS t2; +a +1 +UNLOCK TABLES; +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS T2; +ERROR HY000: Table 'T2' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP TABLE t1; +# +# MDEV-33108 TABLE_STATISTICS and INDEX_STATISTICS are case insensitive with lower-case-table-names=0 +# +SET GLOBAL userstat=1; +CREATE TABLE t1 (a INT, KEY(a)); +INSERT INTO t1 VALUES (1),(2),(3),(4); +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +CREATE TABLE T1 (a INT, KEY(a)); +INSERT INTO T1 VALUES (1),(2),(3),(4); +SELECT * FROM T1 ORDER BY a; +a +1 +2 +3 +4 +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS ORDER BY BINARY TABLE_NAME; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test T1 4 4 4 +test t1 4 4 4 +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS ORDER BY BINARY TABLE_NAME; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test T1 a 4 +test t1 a 4 +DROP TABLE t1; +DROP TABLE T1; +SET GLOBAL userstat=DEFAULT; +# +# MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 +# +CREATE DATABASE MYSQL; +CREATE FUNCTION MYSQL.f1() RETURNS INT RETURN 1; +DROP DATABASE MYSQL; +SELECT db, name, body FROM mysql.proc WHERE db=BINARY 'MYSQL' AND name='f1'; +db name body +# +# MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a +1 +CREATE OR REPLACE TABLE T1 (a INT); +DROP TABLE T1; +HANDLER t1 READ NEXT; +a +2 +HANDLER t1 CLOSE; +DROP TABLE t1; +# +# MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 +# +CREATE TABLE mysql.GENERAL_log (a INT); +INSERT INTO mysql.GENERAL_log VALUES (1),(2); +DROP TABLE mysql.GENERAL_log; +CREATE TABLE mysql.SLOW_log (a INT); +INSERT INTO mysql.SLOW_log VALUES (1),(2); +DROP TABLE mysql.SLOW_log; +CREATE TABLE mysql.TRANSACTION_registry (a INT); +INSERT INTO mysql.TRANSACTION_registry VALUES (1),(2); +DROP TABLE mysql.TRANSACTION_registry; +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.general_log (a INT); +INSERT INTO MYSQL.general_log VALUES (1),(2); +DROP TABLE MYSQL.general_log; +CREATE TABLE MYSQL.slow_log (a INT); +INSERT INTO MYSQL.slow_log VALUES (1),(2); +DROP TABLE MYSQL.slow_log; +CREATE TABLE MYSQL.transaction_registry (a INT); +INSERT INTO MYSQL.transaction_registry VALUES (1),(2); +DROP TABLE MYSQL.transaction_registry; +DROP DATABASE MYSQL; +# End of 11.5 tests diff --git a/mysql-test/main/lowercase_table5.test b/mysql-test/main/lowercase_table5.test index 0103dbf5fd2..b79c8cf2504 100644 --- a/mysql-test/main/lowercase_table5.test +++ b/mysql-test/main/lowercase_table5.test @@ -49,3 +49,136 @@ DROP PROCEDURE SP; --echo # --echo # End of 10.4 tests --echo # + + +--echo # +--echo # MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 +--echo # + +CREATE SEQUENCE t1; +CREATE SEQUENCE T1; +--disable_ps2_protocol +SELECT nextval(t1), lastval(t1); +SELECT nextval(T1), lastval(T1); +SELECT lastval(t1), lastval(T1) l2; +--enable_ps2_protocol +DROP SEQUENCE t1, T1; + +--echo # +--echo # MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 +--echo # + +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +SELECT * FROM db1.t1; +SHOW OPEN TABLES IN DB1; +SHOW OPEN TABLES IN db1; +DROP DATABASE db1; + +--echo # +--echo # MDEV-33088 Cannot create triggers in the database `MYSQL` +--echo # + +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.t1 (a INT); +CREATE TABLE MYSQL.t2 (a INT); +CREATE TRIGGER MYSQL.tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.a); +INSERT INTO MYSQL.t1 VALUES (10); +SELECT * FROM MYSQL.t1; +SELECT * FROM MYSQL.t2; +DROP DATABASE MYSQL; + + +--echo # +--echo # MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 +--echo # + +--disable_view_protocol +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS t2; +UNLOCK TABLES; +LOCK TABLE t1 AS t2 READ; +--error ER_TABLE_NOT_LOCKED +SELECT * FROM t1 AS T2; +UNLOCK TABLES; +DROP TABLE t1; +--enable_view_protocol + + +--echo # +--echo # MDEV-33108 TABLE_STATISTICS and INDEX_STATISTICS are case insensitive with lower-case-table-names=0 +--echo # + +SET GLOBAL userstat=1; +CREATE TABLE t1 (a INT, KEY(a)); +INSERT INTO t1 VALUES (1),(2),(3),(4); +--disable_ps2_protocol +SELECT * FROM t1 ORDER BY a; +CREATE TABLE T1 (a INT, KEY(a)); +INSERT INTO T1 VALUES (1),(2),(3),(4); +SELECT * FROM T1 ORDER BY a; +--enable_ps2_protocol +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS ORDER BY BINARY TABLE_NAME; +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS ORDER BY BINARY TABLE_NAME; +DROP TABLE t1; +DROP TABLE T1; +SET GLOBAL userstat=DEFAULT; + + +--echo # +--echo # MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 +--echo # + +CREATE DATABASE MYSQL; +CREATE FUNCTION MYSQL.f1() RETURNS INT RETURN 1; +DROP DATABASE MYSQL; +SELECT db, name, body FROM mysql.proc WHERE db=BINARY 'MYSQL' AND name='f1'; + + +--echo # +--echo # MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +CREATE OR REPLACE TABLE T1 (a INT); +DROP TABLE T1; +HANDLER t1 READ NEXT; +HANDLER t1 CLOSE; +DROP TABLE t1; + +--echo # +--echo # MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 +--echo # + +CREATE TABLE mysql.GENERAL_log (a INT); +INSERT INTO mysql.GENERAL_log VALUES (1),(2); +DROP TABLE mysql.GENERAL_log; + +CREATE TABLE mysql.SLOW_log (a INT); +INSERT INTO mysql.SLOW_log VALUES (1),(2); +DROP TABLE mysql.SLOW_log; + +CREATE TABLE mysql.TRANSACTION_registry (a INT); +INSERT INTO mysql.TRANSACTION_registry VALUES (1),(2); +DROP TABLE mysql.TRANSACTION_registry; + +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.general_log (a INT); +INSERT INTO MYSQL.general_log VALUES (1),(2); +DROP TABLE MYSQL.general_log; + +CREATE TABLE MYSQL.slow_log (a INT); +INSERT INTO MYSQL.slow_log VALUES (1),(2); +DROP TABLE MYSQL.slow_log; + +CREATE TABLE MYSQL.transaction_registry (a INT); +INSERT INTO MYSQL.transaction_registry VALUES (1),(2); +DROP TABLE MYSQL.transaction_registry; +DROP DATABASE MYSQL; + +--echo # End of 11.5 tests diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test index 5ad1aabd001..4b49a34f49e 100644 --- a/mysql-test/main/subselect.test +++ b/mysql-test/main/subselect.test @@ -5946,6 +5946,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 ); --enable_ps2_protocol --echo # The following shows that t2 was indeed scanned with a full scan. +--sorted_result show table_statistics; show index_statistics; set global userstat=@tmp_mdev410; diff --git a/mysql-test/main/view_grant.result b/mysql-test/main/view_grant.result index cfb8f7df60e..9dd2233eb42 100644 --- a/mysql-test/main/view_grant.result +++ b/mysql-test/main/view_grant.result @@ -1964,3 +1964,34 @@ connection default; disconnect con1; drop user foo@localhost; drop schema foo; +# +# MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS +# +USE test; +CREATE USER foo; +CREATE USER FOO; +GRANT SELECT ON test.* TO foo; +GRANT SELECT ON test.* TO FOO; +CREATE DEFINER=foo SQL SECURITY INVOKER VIEW v1 AS SELECT 1 AS c1; +connect FOO, localhost, FOO, , test; +connection FOO; +SELECT CURRENT_USER; +CURRENT_USER +FOO@% +SELECT * FROM INFORMATION_SCHEMA.VIEWS; +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME v1 +VIEW_DEFINITION +CHECK_OPTION NONE +IS_UPDATABLE NO +DEFINER foo@% +SECURITY_TYPE INVOKER +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +ALGORITHM UNDEFINED +disconnect FOO; +connection default; +DROP VIEW v1; +DROP USER foo; +DROP USER FOO; diff --git a/mysql-test/main/view_grant.test b/mysql-test/main/view_grant.test index a7990b44636..2cfb86a7c95 100644 --- a/mysql-test/main/view_grant.test +++ b/mysql-test/main/view_grant.test @@ -2229,3 +2229,29 @@ drop schema foo; # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc +--echo # +--echo # MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS +--echo # + +USE test; +CREATE USER foo; +CREATE USER FOO; +GRANT SELECT ON test.* TO foo; +GRANT SELECT ON test.* TO FOO; + +CREATE DEFINER=foo SQL SECURITY INVOKER VIEW v1 AS SELECT 1 AS c1; + +--connect (FOO, localhost, FOO, , test) +--connection FOO + +SELECT CURRENT_USER; +--vertical_results +--query_vertical SELECT * FROM INFORMATION_SCHEMA.VIEWS +--horizontal_results + +--disconnect FOO +--connection default + +DROP VIEW v1; +DROP USER foo; +DROP USER FOO; diff --git a/mysql-test/suite/compat/oracle/r/lower_case_table_names.result b/mysql-test/suite/compat/oracle/r/lower_case_table_names.result new file mode 100644 index 00000000000..30275a3addc --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/lower_case_table_names.result @@ -0,0 +1,9 @@ +SELECT @@lower_case_table_names; +@@lower_case_table_names +1 +# +# MDEV-33050 Build-in schemas like oracle_schema are accent insensitive +# +SET NAMES utf8; +CREATE TABLE t1 (a öracle_schema.date); +ERROR HY000: Unknown data type: 'öracle_schema.date' diff --git a/mysql-test/suite/compat/oracle/t/lower_case_table_names.opt b/mysql-test/suite/compat/oracle/t/lower_case_table_names.opt new file mode 100644 index 00000000000..62ab6dad1e0 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/lower_case_table_names.opt @@ -0,0 +1 @@ +--lower_case_table_names=1 diff --git a/mysql-test/suite/compat/oracle/t/lower_case_table_names.test b/mysql-test/suite/compat/oracle/t/lower_case_table_names.test new file mode 100644 index 00000000000..c315367f37d --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/lower_case_table_names.test @@ -0,0 +1,9 @@ +SELECT @@lower_case_table_names; + +--echo # +--echo # MDEV-33050 Build-in schemas like oracle_schema are accent insensitive +--echo # + +SET NAMES utf8; +--error ER_UNKNOWN_DATA_TYPE +CREATE TABLE t1 (a öracle_schema.date); diff --git a/mysql-test/suite/csv/lowercase_table0.result b/mysql-test/suite/csv/lowercase_table0.result new file mode 100644 index 00000000000..fba6a509aea --- /dev/null +++ b/mysql-test/suite/csv/lowercase_table0.result @@ -0,0 +1,15 @@ +# +# MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 +# +CREATE OR REPLACE TABLE t1 (a INT NOT NULL) ENGINE=CSV; +CREATE OR REPLACE TABLE T1 (a INT NOT NULL) ENGINE=CSV; +INSERT INTO t1 VALUES (10); +INSERT INTO T1 VALUES (20); +SELECT * FROM t1; +a +10 +SELECT * FROM T1; +a +20 +DROP TABLE t1; +DROP TABLE T1; diff --git a/mysql-test/suite/csv/lowercase_table0.test b/mysql-test/suite/csv/lowercase_table0.test new file mode 100644 index 00000000000..2bb0e486cb6 --- /dev/null +++ b/mysql-test/suite/csv/lowercase_table0.test @@ -0,0 +1,16 @@ +--source include/have_csv.inc +--source include/have_lowercase0.inc +--source include/have_case_sensitive_file_system.inc + +--echo # +--echo # MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 +--echo # + +CREATE OR REPLACE TABLE t1 (a INT NOT NULL) ENGINE=CSV; +CREATE OR REPLACE TABLE T1 (a INT NOT NULL) ENGINE=CSV; +INSERT INTO t1 VALUES (10); +INSERT INTO T1 VALUES (20); +SELECT * FROM t1; +SELECT * FROM T1; +DROP TABLE t1; +DROP TABLE T1; diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result index ea092d1211f..acb4f1f0e75 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result @@ -127,6 +127,7 @@ utf8mb3_general_mysql500_ci utf8mb3 223 # # utf8mb3_croatian_ci utf8mb3 576 # # utf8mb3_myanmar_ci utf8mb3 577 # # utf8mb3_thai_520_w2 utf8mb3 578 # # +utf8mb3_general1400_as_ci utf8mb3 579 # # utf8mb3_general_nopad_ci utf8mb3 1057 # # utf8mb3_nopad_bin utf8mb3 1107 # # utf8mb3_unicode_nopad_ci utf8mb3 1216 # # @@ -220,6 +221,7 @@ utf8mb4_vietnamese_ci utf8mb4 247 # # utf8mb4_croatian_ci utf8mb4 608 # # utf8mb4_myanmar_ci utf8mb4 609 # # utf8mb4_thai_520_w2 utf8mb4 610 # # +utf8mb4_general1400_as_ci utf8mb4 611 # # utf8mb4_general_nopad_ci utf8mb4 1069 # # utf8mb4_nopad_bin utf8mb4 1070 # # utf8mb4_unicode_nopad_ci utf8mb4 1248 # # diff --git a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result index 0bc617071ca..dc7d62971be 100644 --- a/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result +++ b/mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result @@ -127,6 +127,7 @@ utf8mb3_general_mysql500_ci utf8mb3 223 # # utf8mb3_croatian_ci utf8mb3 576 # # utf8mb3_myanmar_ci utf8mb3 577 # # utf8mb3_thai_520_w2 utf8mb3 578 # # +utf8mb3_general1400_as_ci utf8mb3 579 # # utf8mb3_general_nopad_ci utf8mb3 1057 # # utf8mb3_nopad_bin utf8mb3 1107 # # utf8mb3_unicode_nopad_ci utf8mb3 1216 # # @@ -220,6 +221,7 @@ utf8mb4_vietnamese_ci utf8mb4 247 # # utf8mb4_croatian_ci utf8mb4 608 # # utf8mb4_myanmar_ci utf8mb4 609 # # utf8mb4_thai_520_w2 utf8mb4 610 # # +utf8mb4_general1400_as_ci utf8mb4 611 # # utf8mb4_general_nopad_ci utf8mb4 1069 # # utf8mb4_nopad_bin utf8mb4 1070 # # utf8mb4_unicode_nopad_ci utf8mb4 1248 # # diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result index 05b9fa4053b..d6542336d3f 100644 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result @@ -238,14 +238,17 @@ DROP TABLE t1; SET NAMES utf8; CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; -ALTER TABLE t1 DROP COLUMN FTS_DOC_ıD; +ERROR 42000: Incorrect column name 'FTS_DOC_ıD' ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +ERROR 42000: Incorrect column name 'FTS_DOC_ıD' DROP TABLE t1; CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; -ERROR 42000: Incorrect column name 'FTS_DOC_İD' +DROP TABLE t1; +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; -ERROR 42000: Incorrect column name 'FTS_DOC_İD' +DROP TABLE t1; +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=COPY; ERROR 42000: Incorrect column name 'fts_doc_id' ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=INPLACE; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test index bc0880c35c2..86d90de5a76 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test @@ -300,18 +300,21 @@ DROP TABLE t1; SET NAMES utf8; CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +--error ER_WRONG_COLUMN_NAME ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; -ALTER TABLE t1 DROP COLUMN FTS_DOC_ıD; +--error ER_WRONG_COLUMN_NAME ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; DROP TABLE t1; CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; - ---error ER_WRONG_COLUMN_NAME ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +DROP TABLE t1; ---error ER_WRONG_COLUMN_NAME +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; +DROP TABLE t1; + +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; --error ER_WRONG_COLUMN_NAME ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=COPY; diff --git a/mysql-test/suite/unit/disabled.def b/mysql-test/suite/unit/disabled.def new file mode 100644 index 00000000000..db59e171c10 --- /dev/null +++ b/mysql-test/suite/unit/disabled.def @@ -0,0 +1,12 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : BUG# +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +conc_charset : TODO: client side ID for utf8mb4_general_as_ci diff --git a/mysys/charset-def.c b/mysys/charset-def.c index b884fa5c78c..76168c1f4e3 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -377,6 +377,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_utf8mb3 add_compiled_collation(&my_charset_utf8mb3_general_ci); add_compiled_collation(&my_charset_utf8mb3_general_nopad_ci); + add_compiled_collation(&my_charset_utf8mb3_general1400_as_ci); add_compiled_collation(&my_charset_utf8mb3_bin); add_compiled_collation(&my_charset_utf8mb3_nopad_bin); add_compiled_collation(&my_charset_utf8mb3_general_mysql500_ci); @@ -422,6 +423,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) add_compiled_collation(&my_charset_utf8mb4_bin); add_compiled_collation(&my_charset_utf8mb4_general_nopad_ci); add_compiled_collation(&my_charset_utf8mb4_nopad_bin); + add_compiled_collation(&my_charset_utf8mb4_general1400_as_ci); #ifdef HAVE_UCA_COLLATIONS add_compiled_collation(&my_charset_utf8mb4_unicode_ci); add_compiled_collation(&my_charset_utf8mb4_german2_uca_ci); diff --git a/mysys/charset.c b/mysys/charset.c index 67abfe628a2..efbb52d9d6e 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -51,7 +51,7 @@ get_collation_number_internal(const char *name) cs++) { if (cs[0] && cs[0]->coll_name.str && - !my_strcasecmp(&my_charset_latin1, cs[0]->coll_name.str, name)) + !my_strcasecmp_latin1(cs[0]->coll_name.str, name)) return cs[0]->number; } return 0; @@ -780,7 +780,7 @@ get_charset_number_internal(const char *charset_name, uint cs_flags) cs++) { if ( cs[0] && cs[0]->cs_name.str && (cs[0]->state & cs_flags) && - !my_strcasecmp(&my_charset_latin1, cs[0]->cs_name.str, charset_name)) + !my_strcasecmp_latin1(cs[0]->cs_name.str, charset_name)) return cs[0]->number; } return 0; @@ -795,7 +795,7 @@ uint get_charset_number(const char *charset_name, uint cs_flags, myf flags) my_pthread_once(&charsets_initialized, init_available_charsets); if ((id= get_charset_number_internal(charset_name, cs_flags))) return id; - if ((charset_name= !my_strcasecmp(&my_charset_latin1, charset_name, "utf8") ? + if ((charset_name= !my_strcasecmp_latin1(charset_name, "utf8") ? new_charset_name : NULL)) return get_charset_number_internal(charset_name, cs_flags); return 0; diff --git a/mysys/hash.c b/mysys/hash.c index fccd4a24373..df49e0b17c8 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -378,9 +378,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key, size_t rec_keylength; uchar *rec_key; rec_key= (uchar*) my_hash_key(hash, pos->data, &rec_keylength, 1); - return (length != rec_keylength) || - my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength, - (uchar*) key, rec_keylength); + return my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength, + (uchar*) key, length); } diff --git a/mysys/my_access.c b/mysys/my_access.c index 81e635d9716..bd722da1e59 100644 --- a/mysys/my_access.c +++ b/mysys/my_access.c @@ -87,7 +87,7 @@ static int str_list_find(const char **list, const char *str) const char **name; for (name= list; *name; name++) { - if (!my_strcasecmp(&my_charset_latin1, *name, str)) + if (!my_strcasecmp_latin1(*name, str)) return 1; } return 0; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 0343e06a2f6..88b05f706d4 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -110,6 +110,13 @@ union ull_dbl double dbl; }; + +static inline int cmp_opt_name(const char *a, const char *b) +{ + return my_strcasecmp_latin1(a, b); +} + + /** Returns an ulonglong value containing a raw representation of the given double value. @@ -472,12 +479,12 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, */ (*argc)--; if (!optend || *optend == '1' || - !my_strcasecmp(&my_charset_latin1, optend, "true") || - !my_strcasecmp(&my_charset_latin1, optend, "on")) + !cmp_opt_name(optend, "true") || + !cmp_opt_name(optend, "on")) *((my_bool*) value)= (my_bool) 1; else if (*optend == '0' || - !my_strcasecmp(&my_charset_latin1, optend, "false") || - !my_strcasecmp(&my_charset_latin1, optend, "off")) + !cmp_opt_name(optend, "false") || + !cmp_opt_name(optend, "off")) *((my_bool*) value)= (my_bool) 0; else { @@ -728,13 +735,13 @@ static my_bool get_bool_argument(const struct my_option *opts, { DBUG_ENTER("get_bool_argument"); - if (!my_strcasecmp(&my_charset_latin1, argument, "true") || - !my_strcasecmp(&my_charset_latin1, argument, "on") || - !my_strcasecmp(&my_charset_latin1, argument, "1")) + if (!cmp_opt_name(argument, "true") || + !cmp_opt_name(argument, "on") || + !cmp_opt_name(argument, "1")) DBUG_RETURN(1); - else if (!my_strcasecmp(&my_charset_latin1, argument, "false") || - !my_strcasecmp(&my_charset_latin1, argument, "off") || - !my_strcasecmp(&my_charset_latin1, argument, "0")) + else if (!cmp_opt_name(argument, "false") || + !cmp_opt_name(argument, "off") || + !cmp_opt_name(argument, "0")) DBUG_RETURN(0); my_getopt_error_reporter(WARNING_LEVEL, "option '%s': boolean value '%s' wasn't recognized. Set to OFF.", @@ -838,7 +845,7 @@ static int setval(const struct my_option *opts, void *value, char *argument, if (err) { /* Check if option 'all' is used (to set all bits) */ - if (!my_strcasecmp(&my_charset_latin1, argument, "all")) + if (!cmp_opt_name(argument, "all")) *(ulonglong*) value= ((1ULL << opts->typelib->count) - 1); else { diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index cc29e57fcfe..fdb943c2d7a 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -110,7 +110,7 @@ static int prepare_for_fill(TABLE_LIST *tables) lex_start(thd); thd->lex->init_select(); - LEX_CSTRING tbl_name= {i_s_feedback->table_name, strlen(i_s_feedback->table_name) }; + const LEX_CSTRING tbl_name= i_s_feedback->table_name; tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ); tables->schema_table= i_s_feedback; diff --git a/plugin/func_test/plugin.cc b/plugin/func_test/plugin.cc index 5cbf05f4f24..69403eec933 100644 --- a/plugin/func_test/plugin.cc +++ b/plugin/func_test/plugin.cc @@ -40,8 +40,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("sysconst_test") }; return name; } - const char *fully_qualified_func_name() const override - { return "sysconst_test()"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("sysconst_test()"_LEX_CSTRING); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } }; diff --git a/plugin/locale_info/locale_info.cc b/plugin/locale_info/locale_info.cc index dd0ca303dc8..b7cc7fdf8a4 100644 --- a/plugin/locale_info/locale_info.cc +++ b/plugin/locale_info/locale_info.cc @@ -63,7 +63,7 @@ static int locale_info_fill_table_locale(THD* thd, TABLE_LIST* tables, COND* con /* ID */ table->field[0]->store((longlong) (*loc)->number, TRUE); /* NAME */ - table->field[1]->store((*loc)->name, strlen((*loc)->name), cs); + table->field[1]->store((*loc)->name, cs); /* DESCRIPTION */ table->field[2]->store((*loc)->description, strlen((*loc)->description), cs); /* MAX_MONTH_NAME_LENGTH */ diff --git a/plugin/qc_info/qc_info.cc b/plugin/qc_info/qc_info.cc index a73bc8ea9ec..52cfaa7a9ca 100644 --- a/plugin/qc_info/qc_info.cc +++ b/plugin/qc_info/qc_info.cc @@ -214,7 +214,7 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, sql_mode_string_representation(thd, flags.sql_mode, &sql_mode_str); table->field[COLUMN_SQL_MODE]->store(sql_mode_str.str, sql_mode_str.length, scs); - table->field[COLUMN_LC_TIME_NAMES]->store(flags.lc_time_names->name,strlen(flags.lc_time_names->name), scs); + table->field[COLUMN_LC_TIME_NAMES]->store(flags.lc_time_names->name, scs); table->field[COLUMN_CLIENT_LONG_FLAG]->store(flags.client_long_flag, 0); table->field[COLUMN_CLIENT_PROTOCOL_41]->store(flags.client_protocol_41, 0); diff --git a/plugin/versioning/versioning.cc b/plugin/versioning/versioning.cc index 38ebf76256b..51940ebbbe3 100644 --- a/plugin/versioning/versioning.cc +++ b/plugin/versioning/versioning.cc @@ -23,7 +23,6 @@ #include "sql_class.h" #include "item.h" #include "table.h" -#include "vers_string.h" /* System Versioning: TRT_TRX_ID(), TRT_COMMIT_ID(), TRT_BEGIN_TS(), TRT_COMMIT_TS(), TRT_ISO_LEVEL() */ template diff --git a/sql/create_options.cc b/sql/create_options.cc index cea5d7af950..e497db6ecdc 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -45,12 +45,11 @@ void engine_option_value::link(engine_option_value **start, /* check duplicates to avoid writing them to frm*/ for(opt= *start; opt && ((opt->parsed && !opt->value.str) || - system_charset_info->strnncoll(name.str, name.length, - opt->name.str, opt->name.length)); + !name.streq(opt->name)); opt= opt->next) /* no-op */; if (opt) { - opt->value.str= NULL; /* remove previous value */ + opt->value= Value(); /* remove previous value */ opt->parsed= TRUE; /* and don't issue warnings for it anymore */ } /* @@ -119,7 +118,8 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, #define value_ptr(STRUCT,OPT) ((char*)(STRUCT) + (OPT)->offset) static bool set_one_value(ha_create_table_option *opt, - THD *thd, const LEX_CSTRING *value, void *base, + THD *thd, const engine_option_value::Value *value, + void *base, bool suppress_warning, MEM_ROOT *root) { @@ -186,8 +186,7 @@ static bool set_one_value(ha_create_table_option *opt, for (end=start; *end && *end != ','; end++) /* no-op */; - if (!system_charset_info->strnncoll(start, end-start, - value->str, value->length)) + if (value->streq(Lex_cstring(start, end))) { *val= num; DBUG_RETURN(0); @@ -209,17 +208,17 @@ static bool set_one_value(ha_create_table_option *opt, if (!value->str) DBUG_RETURN(0); - if (!system_charset_info->strnncoll("NO", 2, value->str, value->length) || - !system_charset_info->strnncoll("OFF", 3, value->str, value->length) || - !system_charset_info->strnncoll("0", 1, value->str, value->length)) + if (value->streq("NO"_LEX_CSTRING) || + value->streq("OFF"_LEX_CSTRING) || + value->streq("0"_LEX_CSTRING)) { *val= FALSE; DBUG_RETURN(FALSE); } - if (!system_charset_info->strnncoll("YES", 3, value->str, value->length) || - !system_charset_info->strnncoll("ON", 2, value->str, value->length) || - !system_charset_info->strnncoll("1", 1, value->str, value->length)) + if (value->streq("YES"_LEX_CSTRING) || + value->streq("ON"_LEX_CSTRING) || + value->streq("1"_LEX_CSTRING)) { *val= TRUE; DBUG_RETURN(FALSE); @@ -281,8 +280,7 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, for (val= *option_list; val; val= val->next) { last= val; - if (system_charset_info->strnncoll(opt->name, opt->name_length, - val->name.str, val->name.length)) + if (!val->name.streq(Lex_cstring(opt->name, opt->name_length))) continue; /* skip duplicates (see engine_option_value constructor above) */ @@ -298,7 +296,7 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, } if (!seen || (opt->var && !last->value.str)) { - LEX_CSTRING default_val= null_clex_str; + engine_option_value::Value default_val; /* Okay, here's the logic for sysvar options: @@ -337,7 +335,7 @@ bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, String sbuf(buf, sizeof(buf), system_charset_info), *str; if ((str= sysvar->val_str(&sbuf, thd, OPT_SESSION, &null_clex_str))) { - LEX_CSTRING name= { opt->name, opt->name_length }; + engine_option_value::Name name(opt->name, opt->name_length); default_val.str= strmake_root(root, str->ptr(), str->length()); default_val.length= str->length(); val= new (root) engine_option_value( @@ -754,7 +752,9 @@ uchar *engine_option_value::frm_read(const uchar *buff, const uchar *buff_end, buff+= value.length; engine_option_value *ptr= - new (root) engine_option_value(name, value, len & FRM_QUOTED_VALUE); + new (root) engine_option_value(engine_option_value::Name(name), + engine_option_value::Value(value), + len & FRM_QUOTED_VALUE); if (!ptr) return NULL; ptr->link(start, end); @@ -870,8 +870,7 @@ bool is_engine_option_known(engine_option_value *opt, for (; rules->name; rules++) { - if (!system_charset_info->strnncoll(rules->name, rules->name_length, - opt->name.str, opt->name.length)) + if (opt->name.streq(Lex_cstring(rules->name, rules->name_length))) return true; } return false; diff --git a/sql/create_options.h b/sql/create_options.h index 4961231820f..e7d198bebe3 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -28,9 +28,24 @@ enum { ENGINE_OPTION_MAX_LENGTH=32767 }; class engine_option_value: public Sql_alloc { +public: + class Name: public Lex_ident_ci + { public: - LEX_CSTRING name; - LEX_CSTRING value; + using Lex_ident_ci::Lex_ident_ci; + }; + class Value: public Lex_cstring + { + public: + using Lex_cstring::Lex_cstring; + bool streq(const LEX_CSTRING &rhs) const + { + return my_charset_utf8mb3_general1400_as_ci.streq(*this, rhs); + } + }; + public: + Name name; + Value value; engine_option_value *next; ///< parser puts them in a FIFO linked list bool parsed; ///< to detect unrecognized options bool quoted_value; ///< option=VAL vs. option='VAL' @@ -40,18 +55,20 @@ class engine_option_value: public Sql_alloc next(NULL), parsed(src->parsed), quoted_value(src->quoted_value) { } - engine_option_value(LEX_CSTRING &name_arg, LEX_CSTRING &value_arg, + engine_option_value(const Name &name_arg, + const Value &value_arg, bool quoted) : name(name_arg), value(value_arg), next(NULL), parsed(false), quoted_value(quoted) { } - engine_option_value(LEX_CSTRING &name_arg): + engine_option_value(const Name &name_arg): name(name_arg), value(null_clex_str), next(NULL), parsed(false), quoted_value(false) { } - engine_option_value(LEX_CSTRING &name_arg, ulonglong value_arg, + engine_option_value(const Name &name_arg, + ulonglong value_arg, MEM_ROOT *root) : name(name_arg), next(NULL), parsed(false), quoted_value(false) { diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index 0a284011c41..af0b5c75324 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -1149,22 +1149,23 @@ static void execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file, static void rename_triggers(THD *thd, DDL_LOG_ENTRY *ddl_log_entry, bool swap_tables) { - LEX_CSTRING to_table, from_table, to_db, from_db, from_converted_name; + Lex_ident_table to_table, from_table, from_converted_name; + Lex_ident_db to_db, from_db; char to_path[FN_REFLEN+1], from_path[FN_REFLEN+1], conv_path[FN_REFLEN+1]; if (!swap_tables) { - from_db= ddl_log_entry->db; - from_table= ddl_log_entry->name; - to_db= ddl_log_entry->from_db; - to_table= ddl_log_entry->from_name; + from_db= Lex_ident_db(ddl_log_entry->db); + from_table= Lex_ident_table(ddl_log_entry->name); + to_db= Lex_ident_db(ddl_log_entry->from_db); + to_table= Lex_ident_table(ddl_log_entry->from_name); } else { - from_db= ddl_log_entry->from_db; - from_table= ddl_log_entry->from_name; - to_db= ddl_log_entry->db; - to_table= ddl_log_entry->extra_name; + from_db= Lex_ident_db(ddl_log_entry->from_db); + from_table= Lex_ident_table(ddl_log_entry->from_name); + to_db= Lex_ident_db(ddl_log_entry->db); + to_table= Lex_ident_table(ddl_log_entry->extra_name); } build_filename_and_delete_tmp_file(from_path, sizeof(from_path), @@ -1214,11 +1215,11 @@ static void rename_triggers(THD *thd, DDL_LOG_ENTRY *ddl_log_entry, (void) Table_triggers_list::prepare_for_rename(thd, &trigger_param, - &from_db, - &from_table, - &from_converted_name, - &to_db, - &to_table); + from_db, + from_table, + from_converted_name, + to_db, + to_table); (void) Table_triggers_list::change_table_name(thd, &trigger_param, &from_db, @@ -1710,9 +1711,7 @@ static int ddl_log_execute_action(THD *thd, MEM_ROOT *mem_root, switch (ddl_log_entry->phase) { case DDL_DROP_DB_PHASE_INIT: - drop_database_objects(thd, &path, &db, - !my_strcasecmp(system_charset_info, - MYSQL_SCHEMA_NAME.str, db.str)); + drop_database_objects(thd, &path, &db, MYSQL_SCHEMA_NAME.streq(db)); strxnmov(to_path, sizeof(to_path)-1, path.str, MY_DB_OPT_FILE, NullS); mysql_file_delete_with_symlink(key_file_misc, to_path, "", MYF(0)); diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 362463a7f22..b6f413e2459 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -858,6 +858,13 @@ static st_debug_sync_action *debug_sync_get_action(THD *thd, } +class Debug_token: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + /** Set a debug sync action. @@ -909,22 +916,23 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action) } else { - const char *dsp_name= action->sync_point.c_ptr(); + const Debug_token dsp_name(action->sync_point.to_lex_cstring()); #ifdef DBUG_TRACE DBUG_EXECUTE("debug_sync", { /* Functions as DBUG_PRINT args can change keyword and line nr. */ const char *sig_emit= action->signal.c_ptr(); const char *sig_wait= action->wait_for.c_ptr(); DBUG_PRINT("debug_sync", - ("sync_point: '%s' activation_count: %lu hit_limit: %lu " + ("sync_point: '%.*s' activation_count: %lu hit_limit: %lu " "execute: %lu timeout: %lu signal: '%s' wait_for: '%s'", - dsp_name, action->activation_count, + (int) dsp_name.length, dsp_name.str, + action->activation_count, action->hit_limit, action->execute, action->timeout, sig_emit, sig_wait));}); #endif /* Check this before sorting the array. action may move. */ - is_dsp_now= !my_strcasecmp(system_charset_info, dsp_name, "now"); + is_dsp_now= dsp_name.streq("now"_LEX_CSTRING); if (action->need_sort) { @@ -984,8 +992,7 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action) and that ASCII NUL ('\0') is used as the string terminator. This function needs to return tokens that are terminated with ASCII - NUL ('\0'). The tokens are used in my_strcasecmp(). Unfortunately - there is no my_strncasecmp(). + NUL ('\0'). The tokens are used in strtoul(). To return the last token without copying it, we require the input string to be nul terminated. @@ -1015,29 +1022,28 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action) to the string terminator ASCII NUL ('\0'). */ -static char *debug_sync_token(char **token_p, uint *token_length_p, +static char *debug_sync_token(Debug_token *to, char *ptr, char *ptrend) { - DBUG_ASSERT(token_p); - DBUG_ASSERT(token_length_p); + DBUG_ASSERT(to); DBUG_ASSERT(ptr); /* Skip leading space */ ptr+= system_charset_info->scan(ptr, ptrend, MY_SEQ_SPACES); if (!*ptr) { - ptr= NULL; - goto end; + // Keep "to" intact. + return NULL; } /* Get token start. */ - *token_p= ptr; + to->str= ptr; /* Find token end. */ ptr+= system_charset_info->scan(ptr, ptrend, MY_SEQ_NONSPACES); /* Get token length. */ - *token_length_p= (uint)(ptr - *token_p); + to->length= (uint)(ptr - to->str); /* If necessary, terminate token. */ if (*ptr) @@ -1056,7 +1062,6 @@ static char *debug_sync_token(char **token_p, uint *token_length_p, ptr+= system_charset_info->scan(ptr, ptrend, MY_SEQ_SPACES); } - end: return ptr; } @@ -1088,16 +1093,15 @@ static char *debug_sync_number(ulong *number_p, char *actstrptr, { char *ptr; char *ept; - char *token; - uint token_length; + Debug_token token; DBUG_ASSERT(number_p); DBUG_ASSERT(actstrptr); /* Get token from string. */ - if (!(ptr= debug_sync_token(&token, &token_length, actstrptr, actstrend))) + if (!(ptr= debug_sync_token(&token, actstrptr, actstrend))) goto end; - *number_p= strtoul(token, &ept, 10); + *number_p= strtoul(token.str, &ept, 10); if (*ept) ptr= NULL; @@ -1152,8 +1156,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) st_debug_sync_action *action= NULL; const char *errmsg; char *ptr; - char *token; - uint token_length= 0; + Debug_token token; DBUG_ENTER("debug_sync_eval_action"); DBUG_ASSERT(thd); DBUG_ASSERT(action_str); @@ -1162,7 +1165,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Get debug sync point name. Or a special command. */ - if (!(ptr= debug_sync_token(&token, &token_length, action_str, action_end))) + if (!(ptr= debug_sync_token(&token, action_str, action_end))) { errmsg= "Missing synchronization point name"; goto err; @@ -1174,7 +1177,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) if (*ptr) { /* Get an action object to collect the requested action parameters. */ - action= debug_sync_get_action(thd, token, token_length); + action= debug_sync_get_action(thd, token.str, (uint) token.length); if (!action) { /* Error message is sent. */ @@ -1185,14 +1188,14 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Get kind of action to be taken at sync point. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) { /* No action present. Try special commands. Token unchanged. */ /* Try RESET. */ - if (!my_strcasecmp(system_charset_info, token, "RESET")) + if (token.streq("RESET"_LEX_CSTRING)) { /* It is RESET. Reset all actions and global signal. */ debug_sync_reset(thd); @@ -1213,7 +1216,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Try TEST. */ - if (!my_strcasecmp(system_charset_info, token, "TEST")) + if (token.streq("TEST"_LEX_CSTRING)) { /* It is TEST. Nothing must follow it. */ if (*ptr) @@ -1243,7 +1246,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Try CLEAR. */ - if (!my_strcasecmp(system_charset_info, token, "CLEAR")) + if (token.streq("CLEAR"_LEX_CSTRING)) { /* It is CLEAR. Nothing must follow it. */ if (*ptr) @@ -1263,15 +1266,15 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Try SIGNAL. */ - if (!my_strcasecmp(system_charset_info, token, "SIGNAL")) + if (token.streq("SIGNAL"_LEX_CSTRING)) { /* It is SIGNAL. Signal name must follow. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) { errmsg= "Missing signal name after action SIGNAL"; goto err; } - if (action->signal.copy(token, token_length, system_charset_info)) + if (action->signal.copy(token.str, token.length, system_charset_info)) { /* Error is reported by my_malloc(). */ /* purecov: begin tested */ @@ -1284,22 +1287,22 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) action->execute= 1; /* Get next token. If none follows, set action. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) goto set_action; } /* Try WAIT_FOR. */ - if (!my_strcasecmp(system_charset_info, token, "WAIT_FOR")) + if (token.streq("WAIT_FOR"_LEX_CSTRING)) { /* It is WAIT_FOR. Wait_for signal name must follow. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) { errmsg= "Missing signal name after action WAIT_FOR"; goto err; } - if (action->wait_for.copy(token, token_length, system_charset_info)) + if (action->wait_for.copy(token.str, token.length, system_charset_info)) { /* Error is reported by my_malloc(). */ /* purecov: begin tested */ @@ -1314,13 +1317,13 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) action->clear_event= true; /* Get next token. If none follows, set action. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) goto set_action; /* Try TIMEOUT. */ - if (!my_strcasecmp(system_charset_info, token, "TIMEOUT")) + if (token.streq("TIMEOUT"_LEX_CSTRING)) { /* It is TIMEOUT. Number must follow. */ if (!(ptr= debug_sync_number(&action->timeout, ptr, action_end))) @@ -1330,7 +1333,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) } /* Get next token. If none follows, set action. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) goto set_action; } } @@ -1338,7 +1341,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) /* Try EXECUTE. */ - if (!my_strcasecmp(system_charset_info, token, "EXECUTE")) + if (token.streq("EXECUTE"_LEX_CSTRING)) { /* EXECUTE requires either SIGNAL and/or WAIT_FOR to be present. @@ -1358,24 +1361,24 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) } /* Get next token. If none follows, set action. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) goto set_action; } /* Try NO_CLEAR_EVENT. */ - if (!my_strcasecmp(system_charset_info, token, "NO_CLEAR_EVENT")) + if (token.streq("NO_CLEAR_EVENT"_LEX_CSTRING)) { action->clear_event= false; /* Get next token. If none follows, set action. */ - if (!(ptr = debug_sync_token(&token, &token_length, ptr, action_end))) goto set_action; + if (!(ptr = debug_sync_token(&token, ptr, action_end))) goto set_action; } /* Try HIT_LIMIT. */ - if (!my_strcasecmp(system_charset_info, token, "HIT_LIMIT")) + if (token.streq("HIT_LIMIT"_LEX_CSTRING)) { /* Number must follow. */ if (!(ptr= debug_sync_number(&action->hit_limit, ptr, action_end))) @@ -1385,7 +1388,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) } /* Get next token. If none follows, set action. */ - if (!(ptr= debug_sync_token(&token, &token_length, ptr, action_end))) + if (!(ptr= debug_sync_token(&token, ptr, action_end))) goto set_action; } @@ -1399,8 +1402,8 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) It can be NULL if an error message is already reported (e.g. by my_malloc()). */ - set_if_smaller(token_length, 64); /* Limit error message length. */ - my_printf_error(ER_PARSE_ERROR, errmsg, MYF(0), token_length, token); + set_if_smaller(token.length, 64); /* Limit error message length. */ + my_printf_error(ER_PARSE_ERROR, errmsg, MYF(0), token.length, token.str); } if (action) debug_sync_remove_action(thd->debug_sync_control, action); diff --git a/sql/field.cc b/sql/field.cc index c10e67c282d..5e116588921 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2202,8 +2202,8 @@ void Field::make_send_field(Send_field *field) field->db_name= orig_table->s->db; if (orig_table->pos_in_table_list && orig_table->pos_in_table_list->schema_table) - field->org_table_name= Lex_cstring_strlen(orig_table->pos_in_table_list-> - schema_table->table_name); + field->org_table_name= orig_table->pos_in_table_list-> + schema_table->table_name; else field->org_table_name= orig_table->s->table_name; } @@ -10585,7 +10585,7 @@ void Column_definition::create_length_to_internal_length_newdecimal() } -bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name, +bool check_expression(Virtual_column_info *vcol, const Lex_ident_column &name, enum_vcol_info_type type, Alter_info *alter_info) { bool ret; @@ -10593,7 +10593,7 @@ bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name, res.alter_info= alter_info; if (!vcol->name.length) - vcol->name= *name; + vcol->name= name; /* Walk through the Item tree checking if all items are valid @@ -10611,7 +10611,7 @@ bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name, if (unlikely(ret || (res.errors & filter))) { my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, - vcol_type_name(type), name->str); + vcol_type_name(type), name.str); return TRUE; } /* @@ -10718,7 +10718,7 @@ bool Column_definition::fix_attributes_temporal_with_time(uint int_part_length) bool Column_definition::validate_check_constraint(THD *thd) { return check_constraint && - check_expression(check_constraint, &field_name, VCOL_CHECK_FIELD); + check_expression(check_constraint, field_name, VCOL_CHECK_FIELD); } @@ -10731,7 +10731,7 @@ bool Column_definition::check(THD *thd) { DBUG_ASSERT(vcol_info->expr); vcol_info->set_handler(type_handler()); - if (check_expression(vcol_info, &field_name, vcol_info->is_stored() + if (check_expression(vcol_info, field_name, vcol_info->is_stored() ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL)) DBUG_RETURN(TRUE); } @@ -10742,7 +10742,7 @@ bool Column_definition::check(THD *thd) if (default_value) { Item *def_expr= default_value->expr; - if (check_expression(default_value, &field_name, VCOL_DEFAULT)) + if (check_expression(default_value, field_name, VCOL_DEFAULT)) DBUG_RETURN(TRUE); /* Constant's are stored in the 'empty_record', except for blobs */ @@ -11138,7 +11138,7 @@ bool Column_definition::check_vcol_for_key(THD *thd) const if (vcol_info && (vcol_info->flags & VCOL_NOT_STRICTLY_DETERMINISTIC)) { /* use check_expression() to report an error */ - check_expression(vcol_info, &field_name, VCOL_GENERATED_STORED); + check_expression(vcol_info, field_name, VCOL_GENERATED_STORED); DBUG_ASSERT(thd->is_error()); return true; } diff --git a/sql/field.h b/sql/field.h index 2e3c9b4a3d3..1147e1a7f66 100644 --- a/sql/field.h +++ b/sql/field.h @@ -590,7 +590,7 @@ public: bool automatic_name; bool if_not_exists; Item *expr; - Lex_ident name; /* Name of constraint */ + Lex_ident_column name; /* Name of constraint */ /* see VCOL_* (VCOL_FIELD_REF, ...) */ uint flags; @@ -803,7 +803,7 @@ public: TABLE *table; // Pointer for table TABLE *orig_table; // Pointer to original table const char * const *table_name; // Pointer to alias in TABLE - LEX_CSTRING field_name; + Lex_ident_column field_name; LEX_CSTRING comment; /** reference to the list of options or NULL */ engine_option_value *option_list; @@ -991,6 +991,14 @@ public: DBUG_ASSERT(ls.length < UINT_MAX32); return store(ls.str, (uint) ls.length, cs); } + int store_ident(const Lex_ident_ci &str) + { + return store(str, str.charset_info()); + } + int store_ident(const Lex_ident_fs &str) + { + return store(str, str.charset_info()); + } /* @brief @@ -1085,6 +1093,14 @@ public: @retval true (EOM) */ bool val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to); + /* + Return the field value as a LEX_CSTRING. + */ + Lex_cstring val_lex_cstring(String *buffer) + { + String *res= val_str(buffer); + return res ? res->to_lex_cstring() : Lex_cstring(); + } fast_field_copier get_fast_field_copier(const Field *from); /* str_needs_quotes() returns TRUE if the value returned by val_str() needs @@ -5285,7 +5301,7 @@ class Column_definition: public Sql_alloc, const Type_handler *field_type() const; // Prevent using this Compression_method *compression_method_ptr; public: - Lex_ident field_name; + Lex_ident_column field_name; LEX_CSTRING comment; // Comment for field enum enum_column_versioning { @@ -5709,15 +5725,15 @@ public: inline bool Row_definition_list::eq_name(const Spvar_definition *def, const LEX_CSTRING *name) const { - return def->field_name.length == name->length && my_strcasecmp(system_charset_info, def->field_name.str, name->str) == 0; + return def->field_name.streq(*name); } class Create_field :public Column_definition { public: - LEX_CSTRING change; // Old column name if column is renamed by ALTER - LEX_CSTRING after; // Put column after this one + Lex_ident_column change; // Old column name if column is renamed by ALTER + Lex_ident_column after; // Put column after this one Field *field; // For alter table const TYPELIB *save_interval; // Temporary copy for the above // Used only for UCS2 intervals @@ -5732,17 +5748,13 @@ public: Column_definition(), field(0), option_struct(NULL), create_if_not_exists(false) - { - change= after= null_clex_str; - } + { } Create_field(THD *thd, Field *old_field, Field *orig_field): Column_definition(thd, old_field, orig_field), change(old_field->field_name), field(old_field), option_struct(old_field->option_struct), create_if_not_exists(false) - { - after= null_clex_str; - } + { } /* Used to make a clone of this object for ALTER/CREATE TABLE */ Create_field *clone(MEM_ROOT *mem_root) const; static void upgrade_data_types(List &list) @@ -5902,7 +5914,7 @@ enum_field_types get_blob_type_from_length(ulong length); int set_field_to_null(Field *field); int set_field_to_null_with_conversions(Field *field, bool no_conversions); int convert_null_to_field_value_or_error(Field *field); -bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name, +bool check_expression(Virtual_column_info *vcol, const Lex_ident_column &name, enum_vcol_info_type type, Alter_info *alter_info= NULL); /* diff --git a/sql/grant.cc b/sql/grant.cc index 1ba197bc1d9..9fba1db811b 100644 --- a/sql/grant.cc +++ b/sql/grant.cc @@ -31,8 +31,8 @@ bool Grant_privilege::add_column_privilege(THD *thd, class LEX_COLUMN *point; while ((point=iter++)) { - if (!my_strcasecmp(system_charset_info, - point->column.c_ptr(), new_str->c_ptr())) + if (Lex_ident_column::charset_info()->streq(point->column.to_lex_cstring(), + name)) break; } m_column_privilege_total|= which_grant; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 1fbeb71b641..7d6cf4aaddb 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1562,7 +1562,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, sub_elem= subpart_it++; part= i * num_subparts + j; DBUG_PRINT("info", ("Optimize subpartition %u (%s)", - part, sub_elem->partition_name)); + part, sub_elem->partition_name.str)); if (unlikely((error= handle_opt_part(thd, check_opt, part, flag)))) { /* print a line which partition the error belongs to */ @@ -1575,7 +1575,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, table_share->db.str, table->alias, &opt_op_name[flag], "Subpartition %s returned error", - sub_elem->partition_name); + sub_elem->partition_name.str); } /* reset part_state for the remaining partitions */ do @@ -1590,7 +1590,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, else { DBUG_PRINT("info", ("Optimize partition %u (%s)", i, - part_elem->partition_name)); + part_elem->partition_name.str)); if (unlikely((error= handle_opt_part(thd, check_opt, i, flag)))) { /* print a line which partition the error belongs to */ @@ -1601,7 +1601,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, print_admin_msg(thd, MYSQL_ERRMSG_SIZE, &msg_error, table_share->db.str, table->alias, &opt_op_name[flag], "Partition %s returned error", - part_elem->partition_name); + part_elem->partition_name.str); } /* reset part_state for the remaining partitions */ do @@ -2697,7 +2697,7 @@ register_query_cache_dependant_tables(THD *thd, do { partition_element *part_elem= part_it++; - char *engine_pos= strmov(engine_key_end, part_elem->partition_name); + char *engine_pos= strmov(engine_key_end, part_elem->partition_name.str); if (m_is_sub_partitioned) { List_iterator subpart_it(part_elem->subpartitions); @@ -2714,7 +2714,7 @@ register_query_cache_dependant_tables(THD *thd, sub_elem= subpart_it++; part= i * num_subparts + j; /* we store the end \0 as part of the key */ - end= strmov(engine_pos, sub_elem->partition_name) + 1; + end= strmov(engine_pos, sub_elem->partition_name.str) + 1; length= (uint)(end - engine_key); /* Copy the suffix and end 0 to query cache key */ memcpy(query_cache_key_end, engine_key_end, (end - engine_key_end)); @@ -2879,7 +2879,7 @@ bool ha_partition::create_handler_file(const char *name) part_elem->part_state != PART_TO_BE_ADDED && part_elem->part_state != PART_CHANGED) continue; - tablename_to_filename(part_elem->partition_name, part_name, + tablename_to_filename(part_elem->partition_name.str, part_name, FN_REFLEN); part_name_len= strlen(part_name); if (!m_is_sub_partitioned) @@ -2893,7 +2893,7 @@ bool ha_partition::create_handler_file(const char *name) for (j= 0; j < m_part_info->num_subparts; j++) { subpart_elem= sub_it++; - tablename_to_filename(subpart_elem->partition_name, + tablename_to_filename(subpart_elem->partition_name.str, subpart_name, FN_REFLEN); subpart_name_len= strlen(subpart_name); @@ -2937,7 +2937,7 @@ bool ha_partition::create_handler_file(const char *name) continue; if (!m_is_sub_partitioned) { - tablename_to_filename(part_elem->partition_name, part_name, FN_REFLEN); + tablename_to_filename(part_elem->partition_name.str, part_name, FN_REFLEN); name_buffer_ptr= strmov(name_buffer_ptr, part_name)+1; *engine_array= (uchar) ha_legacy_type(part_elem->engine_type); DBUG_PRINT("info", ("engine: %u", *engine_array)); @@ -2949,9 +2949,9 @@ bool ha_partition::create_handler_file(const char *name) for (j= 0; j < m_part_info->num_subparts; j++) { subpart_elem= sub_it++; - tablename_to_filename(part_elem->partition_name, part_name, + tablename_to_filename(part_elem->partition_name.str, part_name, FN_REFLEN); - tablename_to_filename(subpart_elem->partition_name, subpart_name, + tablename_to_filename(subpart_elem->partition_name.str, subpart_name, FN_REFLEN); name_buffer_ptr+= name_add(name_buffer_ptr, part_name, @@ -3591,7 +3591,8 @@ bool ha_partition::populate_partition_name_hash() } tot_names= m_is_sub_partitioned ? m_tot_parts + num_parts : num_parts; if (my_hash_init(key_memory_Partition_share, - &part_share->partition_name_hash, system_charset_info, + &part_share->partition_name_hash, + Lex_ident_partition::charset_info(), tot_names, 0, 0, (my_hash_get_key) get_part_name, my_free, HASH_UNIQUE)) { @@ -3605,7 +3606,7 @@ bool ha_partition::populate_partition_name_hash() DBUG_ASSERT(part_elem->part_state == PART_NORMAL); if (part_elem->part_state == PART_NORMAL) { - if (insert_partition_name_in_hash(part_elem->partition_name, + if (insert_partition_name_in_hash(part_elem->partition_name.str, i * num_subparts, false)) goto err; if (m_is_sub_partitioned) @@ -3617,7 +3618,7 @@ bool ha_partition::populate_partition_name_hash() do { sub_elem= subpart_it++; - if (insert_partition_name_in_hash(sub_elem->partition_name, + if (insert_partition_name_in_hash(sub_elem->partition_name.str, i * num_subparts + j, true)) goto err; @@ -5022,7 +5023,7 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt) sub_elem= subpart_it++; part= i * num_subparts + j; DBUG_PRINT("info", ("truncate subpartition %u (%s)", - part, sub_elem->partition_name)); + part, sub_elem->partition_name.str)); if (unlikely((error= m_file[part]->ha_truncate()))) break; sub_elem->part_state= PART_NORMAL; @@ -5031,7 +5032,7 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt) else { DBUG_PRINT("info", ("truncate partition %u (%s)", i, - part_elem->partition_name)); + part_elem->partition_name.str)); error= m_file[i]->ha_truncate(); } part_elem->part_state= PART_NORMAL; diff --git a/sql/handler.cc b/sql/handler.cc index e4e290f3334..515c729ce16 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -129,13 +129,13 @@ ulong failed_ha_2pc= 0; /* size of savepoint storage area (see ha_init) */ ulong savepoint_alloc_size= 0; -static const LEX_CSTRING sys_table_aliases[]= +static const Lex_ident_engine sys_table_aliases[]= { - { STRING_WITH_LEN("INNOBASE") }, { STRING_WITH_LEN("INNODB") }, - { STRING_WITH_LEN("HEAP") }, { STRING_WITH_LEN("MEMORY") }, - { STRING_WITH_LEN("MERGE") }, { STRING_WITH_LEN("MRG_MYISAM") }, - { STRING_WITH_LEN("Maria") }, { STRING_WITH_LEN("Aria") }, - {NullS, 0} + "INNOBASE"_Lex_ident_engine, "INNODB"_Lex_ident_engine, + "HEAP"_Lex_ident_engine, "MEMORY"_Lex_ident_engine, + "MERGE"_Lex_ident_engine, "MRG_MYISAM"_Lex_ident_engine, + "Maria"_Lex_ident_engine, "Aria"_Lex_ident_engine, + Lex_ident_engine() }; const LEX_CSTRING ha_row_type[]= @@ -261,13 +261,10 @@ handlerton *ha_default_tmp_handlerton(THD *thd) plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name, bool tmp_table) { - const LEX_CSTRING *table_alias; plugin_ref plugin; redo: - if (thd && !my_charset_latin1.strnncoll( - (const uchar *)name->str, name->length, - (const uchar *)STRING_WITH_LEN("DEFAULT"), 0)) + if (thd && "DEFAULT"_Lex_ident_engine.streq(*name)) return tmp_table ? ha_default_tmp_plugin(thd) : ha_default_plugin(thd); if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN))) @@ -285,11 +282,11 @@ redo: /* We check for the historical aliases. */ - for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2) + for (const Lex_ident_engine *table_alias= sys_table_aliases; + table_alias->str; + table_alias+= 2) { - if (!my_charset_latin1.strnncoll( - (const uchar *)name->str, name->length, - (const uchar *)table_alias->str, table_alias->length)) + if (table_alias->streq(*name)) { name= table_alias + 1; goto redo; @@ -3236,8 +3233,8 @@ int ha_delete_table(THD *thd, handlerton *hton, const char *path, dummy_share.path.str= (char*) path; dummy_share.path.length= strlen(path); dummy_share.normalized_path= dummy_share.path; - dummy_share.db= *db; - dummy_share.table_name= *alias; + dummy_share.db= Lex_ident_db(*db); + dummy_share.table_name= Lex_ident_table(*alias); dummy_table.s= &dummy_share; dummy_table.alias.set(alias->str, alias->length, table_alias_charset); file->change_table_ptr(&dummy_table, &dummy_share); @@ -7557,7 +7554,8 @@ int handler::check_duplicate_long_entry_key(const uchar *new_rec, uint key_no) else { Item_func_left *fnc= static_cast(arguments[j]); - DBUG_ASSERT(!my_strcasecmp(system_charset_info, "left", fnc->func_name())); + DBUG_ASSERT(Lex_ident_routine(fnc->func_name_cstring()). + streq("left"_LEX_CSTRING)); DBUG_ASSERT(fnc->arguments()[0]->type() == Item::FIELD_ITEM); t_field= static_cast(fnc->arguments()[0])->field; uint length= (uint)fnc->arguments()[1]->val_int(); @@ -8360,14 +8358,14 @@ int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info) VERSIONING functions ******************************************************************************/ -bool Vers_parse_info::is_start(const char *name) const +bool Vers_parse_info::is_start(const LEX_CSTRING &name) const { - DBUG_ASSERT(name); + DBUG_ASSERT(name.str); return as_row.start && as_row.start.streq(name); } -bool Vers_parse_info::is_end(const char *name) const +bool Vers_parse_info::is_end(const LEX_CSTRING &name) const { - DBUG_ASSERT(name); + DBUG_ASSERT(name.str); return as_row.end && as_row.end.streq(name); } bool Vers_parse_info::is_start(const Create_field &f) const @@ -8379,14 +8377,15 @@ bool Vers_parse_info::is_end(const Create_field &f) const return f.flags & VERS_ROW_END; } -static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int flags, bool integer) +static Create_field *vers_init_sys_field(THD *thd, + const Lex_ident_column &field_name, + int flags, bool integer) { Create_field *f= new (thd->mem_root) Create_field(); if (!f) return NULL; - f->field_name.str= field_name; - f->field_name.length= strlen(field_name); + f->field_name= field_name; f->charset= system_charset_info; f->flags= flags | NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG; if (integer) @@ -8408,7 +8407,8 @@ static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int f return f; } -bool Vers_parse_info::create_sys_field(THD *thd, const char *field_name, +bool Vers_parse_info::create_sys_field(THD *thd, + const Lex_ident_column &field_name, Alter_info *alter_info, int flags) { DBUG_ASSERT(can_native >= 0); /* Requires vers_check_native() called */ @@ -8424,8 +8424,9 @@ bool Vers_parse_info::create_sys_field(THD *thd, const char *field_name, return false; } -const Lex_ident Vers_parse_info::default_start= "row_start"; -const Lex_ident Vers_parse_info::default_end= "row_end"; +const Lex_ident_column + Vers_parse_info::default_start= "row_start"_Lex_ident_column, + Vers_parse_info::default_end= "row_end"_Lex_ident_column; bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info) { @@ -8507,8 +8508,8 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields( bool Table_scope_and_contents_source_st::vers_check_system_fields( - THD *thd, Alter_info *alter_info, const Lex_table_name &table_name, - const Lex_table_name &db, int select_count) + THD *thd, Alter_info *alter_info, const Lex_ident_table &table_name, + const Lex_ident_db &db, int select_count) { if (!(options & HA_VERSIONED_TABLE)) return false; @@ -8533,7 +8534,7 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields( { List_iterator dup_it(alter_info->create_list); for (Create_field *dup= dup_it++; !is_dup && dup != f; dup= dup_it++) - is_dup= Lex_ident(dup->field_name).streq(f->field_name); + is_dup= dup->field_name.streq(f->field_name); } if (!(f->flags & VERS_UPDATE_UNVERSIONED_FLAG) && !is_dup) @@ -8558,7 +8559,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE *table) { TABLE_SHARE *share= table->s; - const char *table_name= share->table_name.str; + const Lex_ident_table &table_name= share->table_name; if (!need_check(alter_info) && !share->versioned) return false; @@ -8573,7 +8574,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, if (alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING && table->versioned()) { - my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name); + my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name.str); return true; } @@ -8581,14 +8582,14 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, { if (!share->versioned) { - my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name); + my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name.str); return true; } #ifdef WITH_PARTITION_STORAGE_ENGINE if (table->part_info && table->part_info->part_type == VERSIONING_PARTITION) { - my_error(ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION, MYF(0), table_name); + my_error(ER_DROP_VERSIONING_SYSTEM_TIME_PARTITION, MYF(0), table_name.str); return true; } #endif @@ -8618,7 +8619,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, if ((alter_info->flags & ALTER_DROP_PERIOD || versioned_fields || unversioned_fields) && !share->versioned) { - my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name); + my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name.str); return true; } @@ -8626,7 +8627,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, { if (alter_info->flags & ALTER_ADD_PERIOD) { - my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name); + my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name.str); return true; } @@ -8635,8 +8636,8 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, DBUG_ASSERT(share->vers_start_field()); DBUG_ASSERT(share->vers_end_field()); - Lex_ident start(share->vers_start_field()->field_name); - Lex_ident end(share->vers_end_field()->field_name); + Lex_ident_column start(share->vers_start_field()->field_name); + Lex_ident_column end(share->vers_end_field()->field_name); DBUG_ASSERT(start.str); DBUG_ASSERT(end.str); @@ -8701,8 +8702,7 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_ kp_it.init(key->columns); while (Key_part_spec *kp= kp_it++) { - if (0 == lex_string_cmp(system_charset_info, &kp->field_name, - &f->field_name)) + if (kp->field_name.streq(f->field_name)) { kp_it.remove(); } @@ -8760,8 +8760,8 @@ bool Vers_parse_info::need_check(const Alter_info *alter_info) const alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING || *this; } -bool Vers_parse_info::check_conditions(const Lex_table_name &table_name, - const Lex_table_name &db) const +bool Vers_parse_info::check_conditions(const Lex_ident_table &table_name, + const Lex_ident_db &db) const { if (!as_row.start || !as_row.end) { @@ -8876,8 +8876,8 @@ bool Vers_type_trx::check_sys_fields(const LEX_CSTRING &table_name, } -bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, - const Lex_table_name &db, +bool Vers_parse_info::check_sys_fields(const Lex_ident_table &table_name, + const Lex_ident_db &db, Alter_info *alter_info) const { if (check_conditions(table_name, db)) @@ -8904,7 +8904,7 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, if (!row_start_vers) { - require_timestamp_error(row_start->field_name.str, table_name); + require_timestamp_error(row_start->field_name.str, table_name.str); return true; } @@ -8912,7 +8912,7 @@ bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, } bool Table_period_info::check_field(const Create_field* f, - const Lex_ident& f_name) const + const Lex_ident_column& f_name) const { bool res= false; if (!f) @@ -8938,7 +8938,7 @@ bool Table_period_info::check_field(const Create_field* f, bool Table_scope_and_contents_source_st::check_fields( THD *thd, Alter_info *alter_info, - const Lex_table_name &table_name, const Lex_table_name &db, int select_count) + const Lex_ident_table &table_name, const Lex_ident_db &db, int select_count) { return vers_check_system_fields(thd, alter_info, table_name, db, select_count) || @@ -8973,8 +8973,8 @@ bool Table_scope_and_contents_source_st::check_period_fields( } } - bool res= period_info.check_field(row_start, period.start.str) - || period_info.check_field(row_end, period.end.str); + bool res= period_info.check_field(row_start, period.start) + || period_info.check_field(row_end, period.end); if (res) return true; diff --git a/sql/handler.h b/sql/handler.h index 01ec6468766..0224313924c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -35,7 +35,6 @@ #include "structs.h" /* SHOW_COMP_OPTION */ #include "sql_array.h" /* Dynamic_array<> */ #include "mdl.h" -#include "vers_string.h" #include "ha_handler_stats.h" #include "optimizer_costs.h" @@ -2104,7 +2103,7 @@ struct Table_period_info: Sql_alloc constr(NULL), unique_keys(0){} - Lex_ident name; + Lex_ident_column name; struct start_end_t { @@ -2112,8 +2111,8 @@ struct Table_period_info: Sql_alloc start_end_t(const LEX_CSTRING& _start, const LEX_CSTRING& _end) : start(_start), end(_end) {} - Lex_ident start; - Lex_ident end; + Lex_ident_column start; + Lex_ident_column end; }; start_end_t period; bool create_if_not_exists; @@ -2123,15 +2122,15 @@ struct Table_period_info: Sql_alloc bool is_set() const { DBUG_ASSERT(bool(period.start) == bool(period.end)); - return period.start; + return (bool) period.start; } - void set_period(const Lex_ident& start, const Lex_ident& end) + void set_period(const Lex_ident_column &start, const Lex_ident_column &end) { period.start= start; period.end= end; } - bool check_field(const Create_field* f, const Lex_ident& f_name) const; + bool check_field(const Create_field* f, const Lex_ident_column &f_name) const; }; struct Vers_parse_info: public Table_period_info @@ -2146,20 +2145,20 @@ struct Vers_parse_info: public Table_period_info Table_period_info::start_end_t as_row; friend struct Table_scope_and_contents_source_st; - void set_start(const LEX_CSTRING field_name) + void set_start(const Lex_ident_column field_name) { as_row.start= field_name; period.start= field_name; } - void set_end(const LEX_CSTRING field_name) + void set_end(const Lex_ident_column field_name) { as_row.end= field_name; period.end= field_name; } protected: - bool is_start(const char *name) const; - bool is_end(const char *name) const; + bool is_start(const LEX_CSTRING &name) const; + bool is_end(const LEX_CSTRING &name) const; bool is_start(const Create_field &f) const; bool is_end(const Create_field &f) const; bool fix_implicit(THD *thd, Alter_info *alter_info); @@ -2168,21 +2167,21 @@ protected: return as_row.start || as_row.end || period.start || period.end; } bool need_check(const Alter_info *alter_info) const; - bool check_conditions(const Lex_table_name &table_name, - const Lex_table_name &db) const; - bool create_sys_field(THD *thd, const char *field_name, + bool check_conditions(const Lex_ident_table &table_name, + const Lex_ident_db &db) const; + bool create_sys_field(THD *thd, const Lex_ident_column &field_name, Alter_info *alter_info, int flags); public: - static const Lex_ident default_start; - static const Lex_ident default_end; + static const Lex_ident_column default_start; + static const Lex_ident_column default_end; bool fix_alter_info(THD *thd, Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE *table); bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info, TABLE_LIST &src_table, TABLE_LIST &table); - bool check_sys_fields(const Lex_table_name &table_name, - const Lex_table_name &db, Alter_info *alter_info) const; + bool check_sys_fields(const Lex_ident_table &table_name, + const Lex_ident_db &db, Alter_info *alter_info) const; /** At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'. @@ -2304,8 +2303,8 @@ struct Table_scope_and_contents_source_st: const TABLE_LIST &create_table); bool fix_period_fields(THD *thd, Alter_info *alter_info); bool check_fields(THD *thd, Alter_info *alter_info, - const Lex_table_name &table_name, - const Lex_table_name &db, + const Lex_ident_table &table_name, + const Lex_ident_db &db, int select_count= 0); bool check_period_fields(THD *thd, Alter_info *alter_info); @@ -2314,8 +2313,8 @@ struct Table_scope_and_contents_source_st: const TABLE_LIST &create_table); bool vers_check_system_fields(THD *thd, Alter_info *alter_info, - const Lex_table_name &table_name, - const Lex_table_name &db, + const Lex_ident_table &table_name, + const Lex_ident_db &db, int select_count= 0); }; diff --git a/sql/item.cc b/sql/item.cc index 54ad511cb6b..8f16db87545 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -652,7 +652,7 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg, cached_field_index(NO_CACHED_FIELD_INDEX), can_be_depended(TRUE), alias_name_used(FALSE) { - name= field_name_arg; + name= Lex_ident_column(field_name_arg); } @@ -669,7 +669,7 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, cached_field_index(NO_CACHED_FIELD_INDEX), can_be_depended(TRUE), alias_name_used(FALSE) { - name= field_name_arg; + name= Lex_ident_column(field_name_arg); } @@ -823,10 +823,10 @@ bool Item_field::rename_fields_processor(void *arg) { if (def->change.str && (!db_name.str || !db_name.str[0] || - !my_strcasecmp(table_alias_charset, db_name.str, rename->db_name.str)) && + db_name.streq(rename->db_name)) && (!table_name.str || !table_name.str[0] || - !my_strcasecmp(table_alias_charset, table_name.str, rename->table_name.str)) && - !my_strcasecmp(system_charset_info, field_name.str, def->change.str)) + table_name.streq(rename->table_name)) && + field_name.streq(def->change)) { field_name= def->field_name; break; @@ -1176,7 +1176,7 @@ my_mb_wc_item_name(CHARSET_INFO *cs, my_wc_t *pwc, } -static LEX_CSTRING +static Lex_ident_column make_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs, size_t max_octet_length) @@ -1186,7 +1186,7 @@ make_name(THD *thd, set_if_smaller(dst_nbytes, max_octet_length); char *dst= (char*) thd->alloc(dst_nbytes + 1); if (!dst) - return null_clex_str; + return Lex_ident_column(); uint32 cnv_length= my_convert_using_func(dst, dst_nbytes, system_charset_info, my_wc_mb_item_name, str, length, @@ -1194,7 +1194,7 @@ make_name(THD *thd, system_charset_info : cs, my_mb_wc_item_name, &errors); dst[cnv_length]= '\0'; - return Lex_cstring(dst, cnv_length); + return Lex_ident_column(dst, cnv_length); } @@ -1274,7 +1274,7 @@ bool Item::eq(const Item *item, bool binary_cmp) const type() can be only among basic constant types. */ return type() == item->type() && name.str && item->name.str && - !lex_string_cmp(system_charset_info, &name, &item->name); + name.streq(item->name); } @@ -1366,7 +1366,7 @@ Item *Item_num::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) */ Item *Item::const_charset_converter(THD *thd, CHARSET_INFO *tocs, bool lossless, - const char *func_name) + const Lex_ident_routine &func_name) { DBUG_ASSERT(const_item()); DBUG_ASSERT(fixed()); @@ -1375,7 +1375,7 @@ Item *Item::const_charset_converter(THD *thd, CHARSET_INFO *tocs, MEM_ROOT *mem_root= thd->mem_root; if (!s) - return new (mem_root) Item_null(thd, (char *) func_name, tocs); + return new (mem_root) Item_null(thd, (char *) func_name.str, tocs); if (!needs_charset_converter(s->length(), tocs)) { @@ -1386,9 +1386,9 @@ Item *Item::const_charset_converter(THD *thd, CHARSET_INFO *tocs, } uint conv_errors; - Item_string *conv= (func_name ? + Item_string *conv= (func_name.str ? new (mem_root) - Item_static_string_func(thd, Lex_cstring_strlen(func_name), + Item_static_string_func(thd, func_name, s, tocs, &conv_errors, collation.derivation, collation.repertoire) : @@ -1475,7 +1475,7 @@ const MY_LOCALE *Item::locale_from_val_str() String *locale_name= val_str_ascii(&tmp); const MY_LOCALE *lc; if (!locale_name || - !(lc= my_locale_by_name(locale_name->c_ptr_safe()))) + !(lc= my_locale_by_name(locale_name->to_lex_cstring()))) { THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -2998,7 +2998,7 @@ Item_sp::init_result_field(THD *thd, uint max_length, uint maybe_null, dummy_table->in_use= thd; dummy_table->copy_blobs= TRUE; dummy_table->s->table_cache_key= empty_clex_str; - dummy_table->s->table_name= empty_clex_str; + dummy_table->s->table_name= Lex_ident_table(empty_clex_str); dummy_table->maybe_null= maybe_null; if (!(sp_result_field= m_sp->create_result_field(max_length, name, @@ -3100,11 +3100,11 @@ Item_field::Item_field(THD *thd, Name_resolution_context *context_arg, */ { if (db_name.str) - orig_db_name= thd->strmake_lex_cstring(db_name); + orig_db_name= thd->lex_ident_copy(db_name); if (table_name.str) - orig_table_name= thd->strmake_lex_cstring(table_name); + orig_table_name= thd->lex_ident_copy(table_name); if (field_name.str) - orig_field_name= thd->strmake_lex_cstring(field_name); + orig_field_name= thd->lex_ident_copy(field_name); /* We don't restore 'name' in cleanup because it's not changed during execution. Still we need it to point to persistent @@ -3491,14 +3491,11 @@ bool Item_field::eq(const Item *item, bool binary_cmp) const (In cases where we would choose wrong we would have to generate a ER_NON_UNIQ_ERROR). */ - return (!lex_string_cmp(system_charset_info, &item_field->name, - &field_name) && - (!item_field->table_name.str || !table_name.str || - (!my_strcasecmp(table_alias_charset, item_field->table_name.str, - table_name.str) && - (!item_field->db_name.str || !db_name.str || - (item_field->db_name.str && !strcmp(item_field->db_name.str, - db_name.str)))))); + return (item_field->name.streq(field_name) && + (!item_field->table_name.str || !table_name.str || + (item_field->table_name.streq(table_name) && + (!item_field->db_name.str || !db_name.str || + item_field->db_name.streq(db_name))))); } @@ -3746,7 +3743,7 @@ void Item_int::print(String *str, enum_query_type query_type) Item *Item_bool::neg_transformer(THD *thd) { value= !value; - name= null_clex_str; + name= Lex_ident_column(); return this; } @@ -4086,7 +4083,7 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, m_is_settable_routine_parameter(true), m_clones(thd->mem_root) { - name= *name_arg; + name= Lex_ident_column(*name_arg); /* Since we can't say whenever this item can be NULL or cannot be NULL before mysql_stmt_execute(), so we assuming that it can be NULL until @@ -5341,7 +5338,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) { LEX_CSTRING db_name; LEX_CSTRING table_name; - LEX_CSTRING field_name; + Lex_ident_column field_name; ORDER *found_group= NULL; int found_match_degree= 0; IdentBuffer db_name_buff; @@ -5371,8 +5368,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) /* SELECT list element with explicit alias */ if ((*(cur_group->item))->name.str && !table_name.str && (*(cur_group->item))->is_explicit_name() && - !lex_string_cmp(system_charset_info, - &(*(cur_group->item))->name, &field_name)) + field_name.streq((*(cur_group->item))->name)) { ++cur_match_degree; } @@ -5381,30 +5377,25 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) (*(cur_group->item))->type() == Item::REF_ITEM ) { Item_ident *cur_field= (Item_ident*) *cur_group->item; - const char *l_db_name= cur_field->db_name.str; - const char *l_table_name= cur_field->table_name.str; - LEX_CSTRING *l_field_name= &cur_field->field_name; + DBUG_ASSERT(cur_field->field_name.str != 0); - DBUG_ASSERT(l_field_name->str != 0); - - if (!lex_string_cmp(system_charset_info, - l_field_name, &field_name)) + if (field_name.streq(cur_field->field_name)) ++cur_match_degree; else continue; - if (l_table_name && table_name.str) + if (cur_field->table_name.str && table_name.str) { /* If field_name is qualified by a table name. */ - if (my_strcasecmp(table_alias_charset, l_table_name, table_name.str)) + if (!cur_field->table_name.streq(table_name)) /* Same field names, different tables. */ return NULL; ++cur_match_degree; - if (l_db_name && db_name.str) + if (cur_field->db_name.str && db_name.str) { /* If field_name is also qualified by a database name. */ - if (strcmp(l_db_name, db_name.str)) + if (strcmp(cur_field->db_name.str, db_name.str)) /* Same field names, different databases. */ return NULL; ++cur_match_degree; @@ -6204,7 +6195,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) db= field->table->s->db.str; tab= field->table->s->table_name.str; if (!(have_privileges= (get_column_grant(thd, &field->table->grant, - db, tab, field_name.str) & + db, tab, field_name) & VIEW_ANY_ACL))) { my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), @@ -7031,7 +7022,7 @@ Item *Item_int::neg(THD *thd) else if (value < 0 && max_length) max_length--; value= -value; - name= null_clex_str; + name= Lex_ident_column(); return this; } @@ -7039,7 +7030,7 @@ Item *Item_decimal::neg(THD *thd) { my_decimal_neg(&decimal_value); unsigned_flag= 0; - name= null_clex_str; + name= Lex_ident_column(); max_length= my_decimal_precision_to_length_no_truncation( decimal_value.intg + decimals, decimals, unsigned_flag); return this; @@ -7071,7 +7062,7 @@ Item *Item_float::neg(THD *thd) } } } - name= null_clex_str; + name= Lex_ident_column(); return this; } @@ -9972,8 +9963,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table, Try to find field by its name and if it will be found set field_idx properly. */ - (void)find_field_in_table(thd, table, field_name.str, field_name.length, - 0, &field_idx); + (void)find_field_in_table(thd, table, field_name, 0, &field_idx); thd->column_usage= saved_column_usage; triggers= table->triggers; table_grants= table_grant_info; @@ -9984,8 +9974,7 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const { return item->type() == TRIGGER_FIELD_ITEM && row_version == ((Item_trigger_field *)item)->row_version && - !lex_string_cmp(system_charset_info, &field_name, - &((Item_trigger_field *)item)->field_name); + field_name.streq(((Item_trigger_field *)item)->field_name); } @@ -10052,8 +10041,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items) if (check_grant_column(thd, table_grants, triggers->trigger_table->s->db.str, triggers->trigger_table->s->table_name.str, - field_name.str, field_name.length, - thd->security_ctx)) + field_name, thd->security_ctx)) return TRUE; } #endif // NO_EMBEDDED_ACCESS_CHECKS diff --git a/sql/item.h b/sql/item.h index 2d9cf135a80..109882ff920 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1050,9 +1050,9 @@ public: */ String str_value; - LEX_CSTRING name; /* Name of item */ + Lex_ident_column name; /* Name of item */ /* Original item name (if it was renamed)*/ - LEX_CSTRING orig_name; + Lex_ident_column orig_name; /* All common bool variables for an Item is stored here */ item_base_t base_flags; @@ -1146,7 +1146,7 @@ public: set_name(thd, str->ptr(), str->length(), str->charset()); } void set_name(THD *thd, const LEX_CSTRING &str, - CHARSET_INFO *cs= system_charset_info) + CHARSET_INFO *cs= Lex_ident_column::charset_info()) { set_name(thd, str.str, str.length, cs); } @@ -2562,9 +2562,9 @@ public: return needs_charset_converter(1, tocs); } Item *const_charset_converter(THD *thd, CHARSET_INFO *tocs, bool lossless, - const char *func_name); + const Lex_ident_routine &func_name); Item *const_charset_converter(THD *thd, CHARSET_INFO *tocs, bool lossless) - { return const_charset_converter(thd, tocs, lossless, NULL); } + { return const_charset_converter(thd, tocs, lossless, Lex_ident_routine()); } void delete_self() { cleanup(); @@ -3506,17 +3506,17 @@ protected: updated during fix_fields() to values from Field object and life-time of those is shorter than life-time of Item_field. */ - Lex_table_name orig_db_name; - Lex_table_name orig_table_name; - Lex_ident orig_field_name; + Lex_ident_db orig_db_name; + Lex_ident_table orig_table_name; + Lex_ident_column orig_field_name; void undeclared_spvar_error() const; public: Name_resolution_context *context; - Lex_table_name db_name; - Lex_table_name table_name; - Lex_ident field_name; + Lex_ident_db db_name; + Lex_ident_table table_name; + Lex_ident_column field_name; /* Cached pointer to table which contains this field, used for the same reason by prep. stmt. too in case then we have not-fully qualified field. @@ -4604,15 +4604,15 @@ public: class Item_static_float_func :public Item_float { - const char *func_name; + const Lex_ident_routine func_name; public: - Item_static_float_func(THD *thd, const char *str, double val_arg, + Item_static_float_func(THD *thd, const Lex_ident_routine &str, double val_arg, uint decimal_par, uint length): Item_float(thd, NullS, val_arg, decimal_par, length), func_name(str) {} void print(String *str, enum_query_type) override { - str->append(func_name, strlen(func_name)); + str->append(func_name); } Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override { @@ -4641,7 +4641,7 @@ protected: { collation.set(cs, dv); max_length= 0; - set_name(thd, NULL, 0, system_charset_info); + set_name(thd, NULL, 0, Lex_ident_column::charset_info()); decimals= NOT_FIXED_DEC; } public: @@ -4649,7 +4649,7 @@ public: :Item_literal(thd) { collation.set(csi, DERIVATION_COERCIBLE); - set_name(thd, NULL, 0, system_charset_info); + set_name(thd, NULL, 0, Lex_ident_column::charset_info()); decimals= NOT_FIXED_DEC; str_value.copy(str_arg, length_arg, csi); max_length= str_value.numchars() * csi->mbmaxlen; @@ -4785,10 +4785,10 @@ class Item_string_sys :public Item_string { public: Item_string_sys(THD *thd, const char *str, uint length): - Item_string(thd, str, length, system_charset_info) + Item_string(thd, str, length, system_charset_info_for_i_s) { } Item_string_sys(THD *thd, const char *str): - Item_string(thd, str, (uint) strlen(str), system_charset_info) + Item_string(thd, str, (uint) strlen(str), system_charset_info_for_i_s) { } }; @@ -4809,14 +4809,14 @@ public: class Item_static_string_func :public Item_string { - const LEX_CSTRING func_name; + const Lex_ident_routine func_name; public: - Item_static_string_func(THD *thd, const LEX_CSTRING &name_par, + Item_static_string_func(THD *thd, const Lex_ident_routine &name_par, const LEX_CSTRING &str, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE): Item_string(thd, LEX_CSTRING({NullS,0}), str, cs, dv), func_name(name_par) {} - Item_static_string_func(THD *thd, const LEX_CSTRING &name_par, + Item_static_string_func(THD *thd, const Lex_ident_routine &name_par, const String *str, CHARSET_INFO *tocs, uint *conv_errors, Derivation dv, my_repertoire_t repertoire): @@ -4825,7 +4825,7 @@ public: {} Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override { - return const_charset_converter(thd, tocs, true, func_name.str); + return const_charset_converter(thd, tocs, true, func_name); } void print(String *str, enum_query_type) override diff --git a/sql/item_create.cc b/sql/item_create.cc index bc4fa3816de..a2d109853f5 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -67,10 +67,11 @@ extern Native_func_registry_array native_func_registry_array_geom; class Create_sp_func : public Create_qfunc { public: - virtual Item *create_with_db(THD *thd, - const Lex_ident_db_normalized &db, - const LEX_CSTRING &name, - bool use_explicit_name, List *item_list); + Item *create_with_db(THD *thd, + const Lex_ident_db_normalized &db, + const Lex_ident_routine &name, + bool use_explicit_name, + List *item_list) override; static Create_sp_func s_singleton; @@ -2850,7 +2851,7 @@ Create_qfunc::create_func(THD *thd, const LEX_CSTRING *name, if (!db.str) return NULL; /*No db or EOM, error was already sent */ - return create_with_db(thd, db, *name, false, item_list); + return create_with_db(thd, db, Lex_ident_routine(*name), false, item_list); } @@ -2971,7 +2972,7 @@ Create_sp_func Create_sp_func::s_singleton; Item* Create_sp_func::create_with_db(THD *thd, const Lex_ident_db_normalized &db, - const LEX_CSTRING &name, + const Lex_ident_routine &name, bool use_explicit_name, List *item_list) { int arg_count= 0; @@ -2979,7 +2980,7 @@ Create_sp_func::create_with_db(THD *thd, LEX *lex= thd->lex; sp_name *qname; const Sp_handler *sph= &sp_handler_function; - Database_qualified_name pkgname(&null_clex_str, &null_clex_str); + Database_qualified_name pkgname; if (unlikely(has_named_parameters(item_list))) { @@ -5389,7 +5390,8 @@ Create_func_pi Create_func_pi::s_singleton; Item* Create_func_pi::create_builder(THD *thd) { - return new (thd->mem_root) Item_static_float_func(thd, "pi()", M_PI, 6, 8); + static const Lex_ident_routine name("pi()"_LEX_CSTRING); + return new (thd->mem_root) Item_static_float_func(thd, name, M_PI, 6, 8); } @@ -6044,10 +6046,10 @@ Item* Create_func_version::create_builder(THD *thd) { thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); - static Lex_cstring name(STRING_WITH_LEN("version()")); + static const Lex_ident_routine name("version()"_LEX_CSTRING); return new (thd->mem_root) Item_static_string_func(thd, name, Lex_cstring_strlen(server_version), - system_charset_info, + system_charset_info_for_i_s, DERIVATION_SYSCONST); } @@ -6495,7 +6497,8 @@ bool Native_functions_hash::init(size_t count) DBUG_ENTER("Native_functions_hash::init"); if (my_hash_init(key_memory_native_functions, this, - system_charset_info, (ulong) count, 0, 0, (my_hash_get_key) + Lex_ident_routine::charset_info(), + (ulong) count, 0, 0, (my_hash_get_key) get_native_fct_hash_key, NULL, MYF(0))) DBUG_RETURN(true); diff --git a/sql/item_create.h b/sql/item_create.h index 71ee0bc186d..68a287a0c8c 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -240,7 +240,7 @@ public: */ virtual Item *create_with_db(THD *thd, const Lex_ident_db_normalized &db, - const LEX_CSTRING &name, + const Lex_ident_routine &name, bool use_explicit_name, List *item_list) = 0; diff --git a/sql/item_func.cc b/sql/item_func.cc index 4e69ae54be4..38ca845393d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -131,16 +131,6 @@ Item_args::Item_args(THD *thd, const Item_args *other) } -void Item_func::wrong_param_count_error(const LEX_CSTRING &schema_name, - const LEX_CSTRING &func_name) -{ - DBUG_ASSERT(schema_name.length); - Database_qualified_name qname(schema_name, func_name); - my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), - ErrConvDQName(&qname).ptr()); -} - - void Item_func::sync_with_sum_func_and_with_field(List &list) { List_iterator_fast li(list); @@ -675,7 +665,8 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const (func_type != Item_func::FUNC_SP && func_name() != item_func->func_name()) || (func_type == Item_func::FUNC_SP && - my_strcasecmp(system_charset_info, func_name(), item_func->func_name()))) + !Lex_ident_routine(func_name_cstring()). + streq(item_func->func_name_cstring()))) return 0; return Item_args::eq(item_func, binary_cmp); } @@ -5831,7 +5822,8 @@ Item_func_get_system_var(THD *thd, sys_var *var_arg, enum_var_type var_type_arg, orig_var_type(var_type_arg), component(*component_arg), cache_present(0) { /* set_name() will allocate the name */ - set_name(thd, name_arg, (uint) name_len_arg, system_charset_info); + set_name(thd, name_arg, (uint) name_len_arg, + Lex_ident_column::charset_info()); } @@ -5886,6 +5878,8 @@ bool Item_func_get_system_var::fix_length_and_dec(THD *thd) break; case SHOW_CHAR: case SHOW_CHAR_PTR: + { + CHARSET_INFO *cs= system_charset_info_for_i_s; mysql_mutex_lock(&LOCK_global_system_variables); cptr= var->show_type() == SHOW_CHAR ? reinterpret_cast(var->value_ptr(thd, var_type, @@ -5893,26 +5887,26 @@ bool Item_func_get_system_var::fix_length_and_dec(THD *thd) *reinterpret_cast(var->value_ptr(thd, var_type, &component)); - if (cptr) - max_length= (uint32) system_charset_info->numchars(cptr, - cptr + strlen(cptr)); + uint char_length= cptr ? + (uint32) cs->numchars(cptr, cptr + strlen(cptr)) : 0; mysql_mutex_unlock(&LOCK_global_system_variables); - collation.set(system_charset_info, DERIVATION_SYSCONST); - max_length*= system_charset_info->mbmaxlen; + collation.set(cs, DERIVATION_SYSCONST); + fix_char_length(char_length); decimals=NOT_FIXED_DEC; break; + } case SHOW_LEX_STRING: { + CHARSET_INFO *cs= system_charset_info_for_i_s; mysql_mutex_lock(&LOCK_global_system_variables); const LEX_STRING *ls= reinterpret_cast(var->value_ptr(current_thd, var_type, &component)); - max_length= (uint32) system_charset_info->numchars(ls->str, - ls->str + ls->length); + uint char_length= (uint32) cs->numchars(ls->str, ls->str + ls->length); mysql_mutex_unlock(&LOCK_global_system_variables); - collation.set(system_charset_info, DERIVATION_SYSCONST); - max_length*= system_charset_info->mbmaxlen; + collation.set(cs, DERIVATION_SYSCONST); + fix_char_length(char_length); decimals=NOT_FIXED_DEC; } break; diff --git a/sql/item_func.h b/sql/item_func.h index e0cd5de64fc..6e69df3fd8b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -87,10 +87,6 @@ protected: Type_handler_hybrid_field_type *th); public: - // Print an error message for a builtin-schema qualified function call - static void wrong_param_count_error(const LEX_CSTRING &schema_name, - const LEX_CSTRING &func_name); - table_map not_null_tables_cache; enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2a1bfbf66b8..00fc4cbf647 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2821,7 +2821,7 @@ String *Item_func_database::val_str(String *str) return 0; } else - str->copy(thd->db.str, thd->db.length, system_charset_info); + str->copy(thd->db.str, thd->db.length, collation.collation); null_value= 0; return str; } @@ -2837,11 +2837,11 @@ String *Item_func_sqlerrm::val_str(String *str) if ((err= it++)) { str->copy(err->get_message_text(), err->get_message_octet_length(), - system_charset_info); + collation.collation); return str; } str->copy(STRING_WITH_LEN("normal, successful completion"), - system_charset_info); + collation.collation); return str; } @@ -2926,7 +2926,7 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref) if (ctx->priv_role[0]) { if (str_value.copy(ctx->priv_role, strlen(ctx->priv_role), - system_charset_info)) + collation.collation)) return 1; str_value.mark_as_const(); null_value= 0; @@ -3618,7 +3618,7 @@ err: bool Item_func_binlog_gtid_pos::fix_length_and_dec(THD *thd) { - collation.set(system_charset_info); + collation.set(system_charset_info_for_i_s); max_length= MAX_BLOB_WIDTH; set_maybe_null(); return FALSE; @@ -3630,7 +3630,7 @@ String *Item_func_binlog_gtid_pos::val_str(String *str) DBUG_ASSERT(fixed()); #ifndef HAVE_REPLICATION null_value= 0; - str->copy("", 0, system_charset_info); + str->copy("", 0, system_charset_info_for_i_s); return str; #else String name_str, *name; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 8fba6e6fd35..7b8cb3b6391 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -421,7 +421,7 @@ public: String *val_str(String *) override; bool fix_length_and_dec(THD *thd) override { - collation.set(system_charset_info); + collation.set(system_charset_info_for_i_s); max_length= MAX_BLOB_WIDTH; set_maybe_null(); return FALSE; @@ -1154,17 +1154,17 @@ class Item_func_sysconst :public Item_str_func { public: Item_func_sysconst(THD *thd): Item_str_func(thd) - { collation.set(system_charset_info,DERIVATION_SYSCONST); } + { collation.set(system_charset_info_for_i_s, DERIVATION_SYSCONST); } Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); /* Used to create correct Item name in new converted item in safe_charset_converter, return string representation of this function call */ - virtual const char *fully_qualified_func_name() const = 0; + virtual const Lex_ident_routine fully_qualified_func_name() const = 0; bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(fully_qualified_func_name(), arg, + return mark_unsupported_function(fully_qualified_func_name().str, arg, VCOL_SESSION_FUNC); } bool const_item() const; @@ -1178,7 +1178,7 @@ public: String *val_str(String *) override; bool fix_length_and_dec(THD *thd) override { - max_length= NAME_CHAR_LEN * system_charset_info->mbmaxlen; + fix_char_length(NAME_CHAR_LEN); set_maybe_null(); return FALSE; } @@ -1187,8 +1187,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("database") }; return name; } - const char *fully_qualified_func_name() const override - { return "database()"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("database()"_LEX_CSTRING); } Item *get_copy(THD *thd) override { return get_item_copy(thd, this); } }; @@ -1204,15 +1204,15 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("SQLERRM") }; return name; } - const char *fully_qualified_func_name() const override - { return "SQLERRM"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("SQLERRM"_LEX_CSTRING); } void print(String *str, enum_query_type query_type) override { str->append(func_name_cstring()); } bool fix_length_and_dec(THD *thd) override { - max_length= 512 * system_charset_info->mbmaxlen; + fix_char_length(512); null_value= false; base_flags&= ~item_base_t::MAYBE_NULL; return FALSE; @@ -1230,7 +1230,7 @@ protected: public: Item_func_user(THD *thd): Item_func_sysconst(thd) { - str_value.set("", 0, system_charset_info); + str_value.set("", 0, collation.collation); } String *val_str(String *) override { @@ -1249,8 +1249,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("user") }; return name; } - const char *fully_qualified_func_name() const override - { return "user()"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("user()"_LEX_CSTRING); } int save_in_field(Field *field, bool no_conversions) override { return save_str_value_in_field(field, &str_value); @@ -1273,12 +1273,12 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("current_user") }; return name; } - const char *fully_qualified_func_name() const override - { return "current_user()"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("current_user()"_LEX_CSTRING); } bool check_vcol_func_processor(void *arg) override { context= 0; - return mark_unsupported_function(fully_qualified_func_name(), arg, + return mark_unsupported_function(fully_qualified_func_name().str, arg, VCOL_SESSION_FUNC); } }; @@ -1304,8 +1304,8 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("current_role") }; return name; } - const char *fully_qualified_func_name() const override - { return "current_role()"; } + const Lex_ident_routine fully_qualified_func_name() const override + { return Lex_ident_routine("current_role()"_LEX_CSTRING); } String *val_str(String *) override { DBUG_ASSERT(fixed()); @@ -1314,7 +1314,7 @@ public: bool check_vcol_func_processor(void *arg) override { context= 0; - return mark_unsupported_function(fully_qualified_func_name(), arg, + return mark_unsupported_function(fully_qualified_func_name().str, arg, VCOL_SESSION_FUNC); } Item *get_copy(THD *thd) override @@ -2016,7 +2016,7 @@ public: Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { } bool fix_length_and_dec(THD *thd) override { - collation.set(system_charset_info); + collation.set(system_charset_info_for_i_s); max_length= 64 * collation.collation->mbmaxlen; // should be enough base_flags&= ~item_base_t::MAYBE_NULL; return FALSE; diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 5438cade27a..f0a5737bdf7 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -28,7 +28,7 @@ Item_window_func::resolve_window_name(THD *thd) return false; } DBUG_ASSERT(window_name != NULL && window_spec == NULL); - const char *ref_name= window_name->str; + const LEX_CSTRING &ref_name= *window_name; /* !TODO: Add the code to resolve ref_name in outer queries */ /* @@ -41,9 +41,8 @@ Item_window_func::resolve_window_name(THD *thd) Window_spec *win_spec; while((win_spec= it++)) { - const char *win_spec_name= win_spec->name(); - if (win_spec_name && - my_strcasecmp(system_charset_info, ref_name, win_spec_name) == 0) + const Lex_ident_window win_spec_name(win_spec->name()); + if (win_spec_name.str && win_spec_name.streq(ref_name)) { window_spec= win_spec; break; @@ -52,7 +51,7 @@ Item_window_func::resolve_window_name(THD *thd) if (!window_spec) { - my_error(ER_WRONG_WINDOW_SPEC_NAME, MYF(0), ref_name); + my_error(ER_WRONG_WINDOW_SPEC_NAME, MYF(0), ref_name.str); return true; } diff --git a/sql/json_table.cc b/sql/json_table.cc index 6713e796eb7..e7627738849 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -783,8 +783,7 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table, while ((jc2= it2++) != jc) { - if (lex_string_cmp(system_charset_info, - &sql_f->field_name, &jc2->m_field->field_name) == 0) + if (sql_f->field_name.streq(jc2->m_field->field_name)) { my_error(ER_DUP_FIELDNAME, MYF(0), sql_f->field_name.str); goto err_exit; diff --git a/sql/lex_ident.h b/sql/lex_ident.h index 4486cd63ec0..3044424c2e3 100644 --- a/sql/lex_ident.h +++ b/sql/lex_ident.h @@ -21,27 +21,130 @@ #include "char_buffer.h" #include "lex_string.h" +extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *table_alias_charset; + + +/* + LEX_CSTRING with comparison semantics. +*/ + +// db and table names: case sensitive (or insensitive) in table_alias_charset +struct Compare_table_names +{ + CHARSET_INFO *charset_info() const + { + return table_alias_charset; + } +}; + + +// case insensitive identifiers +struct Compare_ident_ci +{ + CHARSET_INFO *charset_info() const + { + return &my_charset_utf8mb3_general1400_as_ci; + } +}; + + +/* + Possible identifier values: + 1. {ptr==NULL,length==0} is valid and means "NULL identifier". + 2a. {ptr<>NULL,length==0} means "empty identifier". + 2b. {ptr<>NULL,length>0} means "not empty identifier. + In case of 2a and 2b, ptr must be a '\0'-terninated string. + + Comparison operands passed to streq() are not required to be 0-terminated. + + Debug validation is done during comparison time: + - inside methods of this class + - inside st_charset_info::streq() in include/m_ctype.h + The caller must make sure to maintain the object in the valid state, + as well as provide valid LEX_CSTRING instances for comparion. + + For better code stability, the Lex_cstring base should eventually be + encapsulated, so the object debug validation is done at constructor + time rather than at comparison time. +*/ + +template +class Lex_ident : public Lex_cstring +{ +protected: + // Make sure the object is valid + bool is_valid_ident() const + { + // NULL identifier, or 0-terminated identifier + return (str == NULL && length == 0) || str[length] == 0; + } +public: + + constexpr Lex_ident() = default; + explicit constexpr Lex_ident(const LEX_CSTRING &str) + :Lex_cstring(str) + { } + constexpr Lex_ident(const char *str, size_t len) + :Lex_cstring(str, len) + { } + Lex_ident(const char *start, const char *end) + :Lex_ident(start, end) + { } + Lex_ident(const Lex_cstring_strlen &str) + :Lex_cstring(str) + { } + explicit operator bool () const + { + return str != NULL; + } + static CHARSET_INFO *charset_info() + { + return Compare().charset_info(); + } + /* + Compare two not necessarily 0-terminated LEX_CSTRING instances. + Both sides can also be valid NULL identifiers. + */ + static bool streq(const LEX_CSTRING &a, const LEX_CSTRING &b) + { + return Compare().charset_info()->streq(a, b); + } + /* + Compare the object to a not necessarily 0-terminated LEX_CSTRING. + Both "this" and rhs can also be NULL identifiers. + */ + bool streq(const LEX_CSTRING &rhs) const + { + DBUG_ASSERT(is_valid_ident()); + return Compare().charset_info()->streq(*this, rhs); + } + /* + Compare two objects. + Both "this" and rhs can also be NULL identifiers. + */ + bool streq(const Lex_ident &b) const + { + DBUG_ASSERT(is_valid_ident()); + DBUG_ASSERT(b.is_valid_ident()); + return Compare().charset_info()->streq(*this, b); + } +}; + /* Identifiers for the database objects stored on disk, e.g. databases, tables, triggers. + Their sensitivity depends on table_alias_charset, i.e. on + - the datadir filesystem case sensitivity, and + - the value of --lower-case-table-names */ -class Lex_ident_fs: public LEX_CSTRING +class Lex_ident_fs: public Lex_ident { -public: - Lex_ident_fs() - :LEX_CSTRING({0,0}) - { } - Lex_ident_fs(const char *str, size_t length) - :LEX_CSTRING({str, length}) - { } - explicit Lex_ident_fs(const LEX_CSTRING &str) - :LEX_CSTRING(str) - { } +protected: static bool check_body(const char *name, size_t length, bool disallow_path_chars); - bool check_db_name() const; - bool check_db_name_with_error() const; +public: + using Lex_ident::Lex_ident; #ifndef DBUG_OFF bool is_in_lower_case() const; bool ok_for_lower_case_names() const; @@ -55,7 +158,7 @@ public: /** A valid database name identifier, - checked with check_db_name(). + checked with check_name(). It's not known if it was lower-cased or is in the user typed way. */ @@ -71,20 +174,28 @@ class Lex_ident_db: public Lex_ident_fs return length == 0 && str != NULL; } public: - Lex_ident_db() - :Lex_ident_fs(NULL, 0) + static bool check_name(const LEX_CSTRING &str); + static bool check_name_with_error(const LEX_CSTRING &str); +public: + constexpr Lex_ident_db() + :Lex_ident_fs() { } + explicit Lex_ident_db(const LEX_CSTRING &str) + :Lex_ident_fs(str) + { + DBUG_SLOW_ASSERT(is_null() || is_empty() || !check_name(*this)); + } Lex_ident_db(const char *str, size_t length) :Lex_ident_fs(str, length) { - DBUG_SLOW_ASSERT(is_null() || is_empty() || !check_db_name()); + DBUG_SLOW_ASSERT(is_null() || is_empty() || !check_name(*this)); } }; /** A normalized database name: - - checked with check_db_name() + - checked with Lex_ident_db::check_name() - lower-cased if lower_case_table_names>0 */ class Lex_ident_db_normalized: public Lex_ident_db @@ -105,6 +216,222 @@ public: }; +class Lex_ident_table: public Lex_ident_fs +{ +public: + static bool check_name(const LEX_CSTRING &str, bool check_for_path_chars); +public: + using Lex_ident_fs::Lex_ident_fs; +}; + + +class Lex_ident_trigger: public Lex_ident_fs +{ +public: + using Lex_ident_fs::Lex_ident_fs; +}; + + +/* + A case insensitive identifier. +*/ +class Lex_ident_ci: public Lex_ident +{ +public: + using Lex_ident::Lex_ident; +}; + + +class Lex_ident_column: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_sys_var: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_user_var: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_ps: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_i_s_db: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_i_s_table: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_window: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_routine: public Lex_ident_ci +{ +public: + static bool check_name_with_error(const LEX_CSTRING &name); +public: + Lex_ident_routine() + { } + explicit Lex_ident_routine(const LEX_CSTRING &name) + :Lex_ident_ci(name) + { + DBUG_ASSERT(!check_name_with_error(name)); + } +}; + + +class Lex_ident_partition: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_with_element: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_rpl_filter: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_master_info: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_host: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_locale: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_plugin: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_engine: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_server: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_savepoint: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + +class Lex_ident_charset: public Lex_ident_ci +{ +public: + using Lex_ident_ci::Lex_ident_ci; +}; + + + +static inline constexpr +Lex_ident_table operator"" _Lex_ident_table(const char *str, size_t length) +{ + return Lex_ident_table(str, length); +} + + +static inline constexpr +Lex_ident_column operator"" _Lex_ident_column(const char *str, size_t length) +{ + return Lex_ident_column(str, length); +} + +static inline constexpr +Lex_ident_i_s_table operator"" _Lex_ident_i_s_table(const char *str, + size_t length) +{ + return Lex_ident_i_s_table(str, length); +} + +static inline constexpr +Lex_ident_engine operator"" _Lex_ident_engine(const char *str, size_t length) +{ + return Lex_ident_engine(str, length); +} + + +static inline constexpr +Lex_ident_locale operator"" _Lex_ident_locale(const char *str, size_t length) +{ + return Lex_ident_locale(str, length); +} + + +static inline constexpr +Lex_ident_charset operator"" _Lex_ident_charset(const char *str, size_t length) +{ + return Lex_ident_charset(str, length); +} + + +static inline constexpr +Lex_ident_plugin operator"" _Lex_ident_plugin(const char *str, size_t length) +{ + return Lex_ident_plugin(str, length); +} + + template class IdentBuffer: public CharBuffer { @@ -137,13 +464,13 @@ public: /* A helper class to store temporary database names in a buffer. After constructing it's typically should be checked using - Lex_ident_fs::check_db_name(). + Lex_ident_db::check_name(). Note, the database name passed to the constructor can originally come from the parser and can be of an atribtrary long length. Let's reserve additional buffer space for one extra character - (SYSTEM_CHARSET_MBMAXLEN bytes), so check_db_name() can still - detect too long names even if the constructor cuts the data. + (SYSTEM_CHARSET_MBMAXLEN bytes), so Lex_ident_db::check_name() can + still detect too long names even if the constructor cuts the data. */ class DBNameBuffer: public CharBuffer { @@ -157,16 +484,16 @@ public: Lex_ident_db to_lex_ident_db() const { const LEX_CSTRING tmp= to_lex_cstring(); - if (Lex_ident_fs(tmp).check_db_name()) + if (Lex_ident_db::check_name(tmp)) return Lex_ident_db(); - return Lex_ident_db(tmp.str, tmp.length); + return Lex_ident_db(tmp); } Lex_ident_db to_lex_ident_db_with_error() const { const LEX_CSTRING tmp= to_lex_cstring(); - if (Lex_ident_fs(tmp).check_db_name_with_error()) + if (Lex_ident_db::check_name_with_error(tmp)) return Lex_ident_db(); - return Lex_ident_db(tmp.str, tmp.length); + return Lex_ident_db(tmp); } }; diff --git a/sql/lex_string.h b/sql/lex_string.h index c296d50eb32..97837e8a1bc 100644 --- a/sql/lex_string.h +++ b/sql/lex_string.h @@ -25,26 +25,27 @@ typedef struct st_mysql_const_lex_string LEX_CSTRING; class Lex_cstring : public LEX_CSTRING { public: - Lex_cstring() - { - str= NULL; - length= 0; - } - Lex_cstring(const LEX_CSTRING &str) - { - LEX_CSTRING::operator=(str); - } - Lex_cstring(const char *_str, size_t _len) - { - str= _str; - length= _len; - } + constexpr Lex_cstring() + :LEX_CSTRING({NULL, 0}) + { } + constexpr Lex_cstring(const LEX_CSTRING &str) + :LEX_CSTRING(str) + { } + constexpr Lex_cstring(const char *_str, size_t _len) + :LEX_CSTRING({_str, _len}) + { } Lex_cstring(const char *start, const char *end) { DBUG_ASSERT(start <= end); str= start; length= end - start; } + + bool bin_eq(const LEX_CSTRING &rhs) const + { + return length == rhs.length && !memcmp(str, rhs.str, length); + } + void set(const char *_str, size_t _len) { str= _str; @@ -143,12 +144,6 @@ public: /* Functions to compare if two lex strings are equal */ -static inline bool lex_string_cmp(CHARSET_INFO *charset, const LEX_CSTRING *a, - const LEX_CSTRING *b) -{ - return my_strcasecmp(charset, a->str, b->str); -} - /* Compare to LEX_CSTRING's and return 0 if equal */ diff --git a/sql/log.cc b/sql/log.cc index 460cefea47b..d89253ca981 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -594,20 +594,15 @@ int check_if_log_table(const TABLE_LIST *table, const char *error_msg) { int result= 0; - if (table->db.length == 5 && - !my_strcasecmp(table_alias_charset, table->db.str, "mysql")) + if (table->db.streq(MYSQL_SCHEMA_NAME)) { - const char *table_name= table->table_name.str; - - if (table->table_name.length == 11 && - !my_strcasecmp(table_alias_charset, table_name, "general_log")) + if (table->table_name.streq(GENERAL_LOG_NAME)) { result= QUERY_LOG_GENERAL; goto end; } - if (table->table_name.length == 8 && - !my_strcasecmp(table_alias_charset, table_name, "slow_log")) + if (table->table_name.streq(SLOW_LOG_NAME)) { result= QUERY_LOG_SLOW; goto end; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index dc4a955aa79..9d2be3c4019 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -623,10 +623,10 @@ my_bool encrypt_binlog; my_bool encrypt_tmp_disk_tables, encrypt_tmp_files; /** name of reference on left expression in rewritten IN subquery */ -const LEX_CSTRING in_left_expr_name= {STRING_WITH_LEN("") }; +const Lex_ident_column in_left_expr_name= ""_Lex_ident_column; /** name of additional condition */ -const LEX_CSTRING in_having_cond= {STRING_WITH_LEN("") }; -const LEX_CSTRING in_additional_cond= {STRING_WITH_LEN("") }; +const Lex_ident_column in_having_cond= ""_Lex_ident_column; +const Lex_ident_column in_additional_cond= ""_Lex_ident_column; /** Number of connection errors when selecting on the listening port */ ulong connection_errors_select= 0; @@ -686,6 +686,7 @@ uint temp_pool_set_next() } CHARSET_INFO *system_charset_info, *files_charset_info ; +CHARSET_INFO *system_charset_info_for_i_s; CHARSET_INFO *national_charset_info, *table_alias_charset; CHARSET_INFO *character_set_filesystem; CHARSET_INFO *error_message_charset_info; @@ -4128,7 +4129,7 @@ static int init_common_variables() unireg_init(opt_specialflag); /* Set up extern variabels */ if (!(my_default_lc_messages= - my_locale_by_name(lc_messages))) + my_locale_by_name(Lex_cstring_strlen(lc_messages)))) { sql_print_error("Unknown locale: '%s'", lc_messages); return 1; @@ -4243,7 +4244,7 @@ static int init_common_variables() global_system_variables.character_set_filesystem= character_set_filesystem; if (!(my_default_lc_time_names= - my_locale_by_name(lc_time_names_name))) + my_locale_by_name(Lex_cstring_strlen(lc_time_names_name)))) { sql_print_error("Unknown locale: '%s'", lc_time_names_name); return 1; @@ -5607,7 +5608,8 @@ int mysqld_main(int argc, char **argv) remaining_argv= argv; /* Must be initialized early for comparison of options name */ - system_charset_info= &my_charset_utf8mb3_general_ci; + system_charset_info= &my_charset_utf8mb3_general1400_as_ci; + system_charset_info_for_i_s= &my_charset_utf8mb3_general_ci; sys_var_init(); @@ -7804,8 +7806,9 @@ static int mysql_init_variables(void) key_map_full.set_all(); /* Character sets */ - system_charset_info= &my_charset_utf8mb3_general_ci; - files_charset_info= &my_charset_utf8mb3_general_ci; + system_charset_info= &my_charset_utf8mb3_general1400_as_ci; + system_charset_info_for_i_s= &my_charset_utf8mb3_general_ci; + files_charset_info= &my_charset_utf8mb3_general1400_as_ci; national_charset_info= &my_charset_utf8mb3_general_ci; table_alias_charset= &my_charset_bin; character_set_filesystem= &my_charset_bin; @@ -8365,7 +8368,8 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, val= strmake_root(&startup_root, val, (size_t) (ptr - val)); /* Add instrument name and value to array of configuration options */ - if (add_pfs_instr_to_array(name, val)) + if (add_pfs_instr_to_array(Lex_cstring_strlen(name), + Lex_cstring_strlen(val))) { my_getopt_error_reporter(WARNING_LEVEL, "Invalid value for performance_schema_instrument " diff --git a/sql/mysqld.h b/sql/mysqld.h index 385e56b0d93..f53d4ccf510 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -20,6 +20,7 @@ #include "sql_basic_types.h" /* query_id_t */ #include "sql_mode.h" /* Sql_mode_dependency */ #include "sql_plugin.h" +#include "lex_ident.h" #include "sql_bitmap.h" /* Bitmap */ #include "my_decimal.h" /* my_decimal */ #include "mysql_com.h" /* SERVER_VERSION_LENGTH */ @@ -89,6 +90,7 @@ extern void ssl_acceptor_stats_update(int sslaccept_ret); extern int reinit_ssl(); extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; +extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info_for_i_s; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *national_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *table_alias_charset; @@ -281,7 +283,7 @@ extern const char *first_keyword, *delayed_user; extern MYSQL_PLUGIN_IMPORT const char *my_localhost; extern MYSQL_PLUGIN_IMPORT const char **errmesg; /* Error messages */ extern const char *myisam_recover_options_str; -extern const LEX_CSTRING in_left_expr_name, in_additional_cond, in_having_cond; +extern const Lex_ident_column in_left_expr_name, in_additional_cond, in_having_cond; extern const LEX_CSTRING NULL_clex_str; extern const LEX_CSTRING error_clex_str; extern SHOW_VAR status_vars[]; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 6d9b40cc063..33ef4e2a2d2 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -439,7 +439,7 @@ tables. Note that this will disallow handling of cases like (CASE-FOR-SUBST). Currently, solution #2 is implemented. */ -LEX_CSTRING weedout_key= {STRING_WITH_LEN("weedout_key")}; +static const Lex_ident_column weedout_key= "weedout_key"_Lex_ident_column; static bool subquery_types_allow_materialization(THD *thd, Item_in_subselect *in_subs); @@ -1758,7 +1758,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) { TABLE_LIST *outer_tbl= subq_pred->emb_on_expr_nest; TABLE_LIST *wrap_nest; - LEX_CSTRING sj_wrap_name= { STRING_WITH_LEN("(sj-wrap)") }; + const Lex_ident_table sj_wrap_name= "(sj-wrap)"_Lex_ident_table; /* We're dealing with @@ -1823,7 +1823,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) TABLE_LIST *sj_nest; NESTED_JOIN *nested_join; - LEX_CSTRING sj_nest_name= { STRING_WITH_LEN("(sj-nest)") }; + const Lex_ident_table sj_nest_name= "(sj-nest)"_Lex_ident_table; if (!(sj_nest= alloc_join_nest(thd))) { DBUG_RETURN(TRUE); diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc index 93090acfb96..22714596e55 100644 --- a/sql/opt_trace.cc +++ b/sql/opt_trace.cc @@ -26,7 +26,7 @@ #include "rowid_filter.h" -const char I_S_table_name[]= "OPTIMIZER_TRACE"; +const Lex_ident_i_s_table I_S_table_name= "OPTIMIZER_TRACE"_Lex_ident_i_s_table; /** Whether a list of tables contains information_schema.OPTIMIZER_TRACE. @@ -43,7 +43,7 @@ bool list_has_optimizer_trace_table(const TABLE_LIST *tbl) for (; tbl; tbl= tbl->next_global) { if (tbl->schema_table && - 0 == strcmp(tbl->schema_table->table_name, I_S_table_name)) + I_S_table_name.streq(tbl->schema_table->table_name)) return true; } return false; @@ -191,9 +191,8 @@ void opt_trace_disable_if_no_security_context_access(THD *thd) if (!(thd->main_security_ctx.check_access(GLOBAL_ACLS & ~GRANT_ACL)) && (0 != strcmp(thd->main_security_ctx.priv_user, thd->security_context()->priv_user) || - 0 != my_strcasecmp(system_charset_info, - thd->main_security_ctx.priv_host, - thd->security_context()->priv_host))) + !Lex_ident_host(Lex_cstring_strlen(thd->main_security_ctx.priv_host)). + streq(Lex_cstring_strlen(thd->security_context()->priv_host)))) trace->missing_privilege(); } diff --git a/sql/partition_element.h b/sql/partition_element.h index 1abaa315218..ea1452027ff 100644 --- a/sql/partition_element.h +++ b/sql/partition_element.h @@ -111,7 +111,7 @@ public: ha_rows part_max_rows; ha_rows part_min_rows; longlong range_value; - const char *partition_name; + Lex_ident_partition partition_name; struct st_ddl_log_memory_entry *log_entry; const char* part_comment; const char* data_file_name; @@ -132,7 +132,6 @@ public: partition_element() : part_max_rows(0), part_min_rows(0), range_value(0), - partition_name(NULL), log_entry(NULL), part_comment(NULL), data_file_name(NULL), index_file_name(NULL), engine_type(NULL), connect_string(null_clex_str), part_state(PART_NORMAL), @@ -146,7 +145,7 @@ public: partition_element(partition_element *part_elem) : part_max_rows(part_elem->part_max_rows), part_min_rows(part_elem->part_min_rows), - range_value(0), partition_name(NULL), + range_value(0), log_entry(NULL), part_comment(part_elem->part_comment), data_file_name(part_elem->data_file_name), diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 1b65de6e3c0..577239c6c6c 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -34,7 +34,6 @@ #include "lock.h" #include "table.h" #include "sql_class.h" -#include "vers_string.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -319,7 +318,7 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no, { do { - if (make_partition_name(move_ptr, (start_no + i))) + if (!make_partition_name(move_ptr, (start_no + i)).str) DBUG_RETURN(NULL); move_ptr+= MAX_PART_NAME_SIZE; } while (++i < num_parts_arg); @@ -428,7 +427,7 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, (!partitions.push_back(part_elem)))) { part_elem->engine_type= default_engine_type; - part_elem->partition_name= default_name; + part_elem->partition_name= Lex_cstring_strlen(default_name); part_elem->id= i; default_name+=MAX_PART_NAME_SIZE; if (part_type == VERSIONING_PARTITION) @@ -437,7 +436,7 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, part_elem->type= partition_element::HISTORY; } else { part_elem->type= partition_element::CURRENT; - part_elem->partition_name= "pn"; + part_elem->partition_name= Lex_ident_partition("pn"_LEX_CSTRING); } } } @@ -501,11 +500,11 @@ bool partition_info::set_up_default_subpartitions(THD *thd, handler *file, (!part_elem->subpartitions.push_back(subpart_elem)))) { char *ptr= create_default_subpartition_name(thd, j, - part_elem->partition_name); + part_elem->partition_name.str); if (!ptr) goto end; subpart_elem->engine_type= default_engine_type; - subpart_elem->partition_name= ptr; + subpart_elem->partition_name= Lex_cstring_strlen(ptr); } else goto end; @@ -573,7 +572,6 @@ bool partition_info::set_up_defaults_for_partitioning(THD *thd, handler *file, const char* partition_info::find_duplicate_field() { - const char *field_name_outer, *field_name_inner; List_iterator it_outer(part_field_list); uint num_fields= part_field_list.elements; uint i,j; @@ -581,18 +579,16 @@ const char* partition_info::find_duplicate_field() for (i= 0; i < num_fields; i++) { - field_name_outer= it_outer++; + const Lex_ident_partition field_name_outer= Lex_cstring_strlen(it_outer++); List_iterator it_inner(part_field_list); for (j= 0; j < num_fields; j++) { - field_name_inner= it_inner++; + const char *field_name_inner= it_inner++; if (i >= j) continue; - if (!(my_strcasecmp(system_charset_info, - field_name_outer, - field_name_inner))) + if (field_name_outer.streq(Lex_cstring_strlen(field_name_inner))) { - DBUG_RETURN(field_name_outer); + DBUG_RETURN(field_name_outer.str); } } } @@ -615,10 +611,10 @@ const char* partition_info::find_duplicate_field() a partition is given for a subpartitioned table, part_elem will be the partition, but part_id will be NOT_A_PARTITION_ID and file_name not set. */ -partition_element *partition_info::get_part_elem(const char *partition_name, - char *file_name, - size_t file_name_size, - uint32 *part_id) +partition_element * +partition_info::get_part_elem(const Lex_ident_partition &partition_name, + char *file_name, size_t file_name_size, + uint32 *part_id) { List_iterator part_it(partitions); uint i= 0; @@ -635,8 +631,7 @@ partition_element *partition_info::get_part_elem(const char *partition_name, do { partition_element *sub_part_elem= sub_part_it++; - if (!my_strcasecmp(system_charset_info, - sub_part_elem->partition_name, partition_name)) + if (sub_part_elem->partition_name.streq(partition_name)) { if (file_name) if (create_subpartition_name(file_name, file_name_size, "", @@ -649,12 +644,10 @@ partition_element *partition_info::get_part_elem(const char *partition_name, } while (++j < num_subparts); /* Naming a partition (first level) on a subpartitioned table. */ - if (!my_strcasecmp(system_charset_info, - part_elem->partition_name, partition_name)) + if (part_elem->partition_name.streq(partition_name)) DBUG_RETURN(part_elem); } - else if (!my_strcasecmp(system_charset_info, - part_elem->partition_name, partition_name)) + else if (part_elem->partition_name.streq(partition_name)) { if (file_name) if (create_partition_name(file_name, file_name_size, "", @@ -714,7 +707,9 @@ char *partition_info::find_duplicate_name() max_names= num_parts; if (is_sub_partitioned()) max_names+= num_parts * num_subparts; - if (my_hash_init(PSI_INSTRUMENT_ME, &partition_names, system_charset_info, max_names, 0, 0, + if (my_hash_init(PSI_INSTRUMENT_ME, &partition_names, + Lex_ident_partition::charset_info(), + max_names, 0, 0, (my_hash_get_key) get_part_name_from_elem, 0, HASH_UNIQUE)) { DBUG_ASSERT(0); @@ -723,7 +718,7 @@ char *partition_info::find_duplicate_name() } while ((p_elem= (parts_it++))) { - curr_name= (const uchar*) p_elem->partition_name; + curr_name= (const uchar*) p_elem->partition_name.str; if (my_hash_insert(&partition_names, curr_name)) goto error; @@ -733,7 +728,7 @@ char *partition_info::find_duplicate_name() partition_element *subp_elem; while ((subp_elem= (subparts_it++))) { - curr_name= (const uchar*) subp_elem->partition_name; + curr_name= (const uchar*) subp_elem->partition_name.str; if (my_hash_insert(&partition_names, curr_name)) goto error; } @@ -763,15 +758,14 @@ bool partition_info::has_unique_name(partition_element *element) { DBUG_ENTER("partition_info::has_unique_name"); - const char *name_to_check= element->partition_name; List_iterator parts_it(partitions); partition_element *el; while ((el= (parts_it++))) { - if (!(my_strcasecmp(system_charset_info, el->partition_name, - name_to_check)) && el != element) - DBUG_RETURN(FALSE); + if (element->partition_name.streq(el->partition_name) && + el != element) + DBUG_RETURN(FALSE); if (!el->subpartitions.is_empty()) { @@ -779,9 +773,9 @@ bool partition_info::has_unique_name(partition_element *element) List_iterator subparts_it(el->subpartitions); while ((sub_el= (subparts_it++))) { - if (!(my_strcasecmp(system_charset_info, sub_el->partition_name, - name_to_check)) && sub_el != element) - DBUG_RETURN(FALSE); + if (element->partition_name.streq(sub_el->partition_name) && + sub_el != element) + DBUG_RETURN(FALSE); } } } @@ -880,7 +874,7 @@ bool partition_info::vers_set_hist_part(THD *thd, uint *create_count) { my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG), table->s->db.str, table->s->table_name.str, - vers_info->hist_part->partition_name, "INTERVAL"); + vers_info->hist_part->partition_name.str, "INTERVAL"); } } } @@ -1042,11 +1036,11 @@ void partition_info::vers_check_limit(THD *thd) WARN_VERS_PART_FULL, ER_THD(thd, WARN_VERS_PART_FULL), table->s->db.str, table->s->table_name.str, - vers_info->hist_part->partition_name, "LIMIT"); + vers_info->hist_part->partition_name.str, "LIMIT"); sql_print_warning(ER_THD(thd, WARN_VERS_PART_FULL), table->s->db.str, table->s->table_name.str, - vers_info->hist_part->partition_name, "LIMIT"); + vers_info->hist_part->partition_name.str, "LIMIT"); } } @@ -1403,8 +1397,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, num_parts_not_set++; part_elem->engine_type= default_engine_type; } - if (check_table_name(part_elem->partition_name, - strlen(part_elem->partition_name), FALSE)) + if (Lex_ident_table::check_name(part_elem->partition_name, false)) { my_error(ER_WRONG_PARTITION_NAME, MYF(0)); goto end; @@ -1422,8 +1415,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, { sub_elem= sub_it++; warn_if_dir_in_part_elem(thd, sub_elem); - if (check_table_name(sub_elem->partition_name, - strlen(sub_elem->partition_name), FALSE)) + if (Lex_ident_table::check_name(sub_elem->partition_name, false)) { my_error(ER_WRONG_PARTITION_NAME, MYF(0)); goto end; @@ -2164,7 +2156,7 @@ int partition_info::fix_partition_values(THD *thd, else if (item_expr->result_type() != INT_RESULT) { my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0), - part_elem->partition_name); + part_elem->partition_name.str); DBUG_RETURN(TRUE); } if (part_type == RANGE_PARTITION) @@ -2558,9 +2550,8 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info) while ((old_name= old_field_name_it++)) { new_name= new_field_name_it++; - if (!new_name || my_strcasecmp(system_charset_info, - new_name, - old_name)) + if (!new_name || !Lex_ident_partition(Lex_cstring_strlen(new_name)). + streq(Lex_cstring_strlen(old_name))) DBUG_RETURN(false); } @@ -2573,9 +2564,8 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info) while ((old_name= old_field_name_it++)) { new_name= new_field_name_it++; - if (!new_name || my_strcasecmp(system_charset_info, - new_name, - old_name)) + if (!new_name || !Lex_ident_partition(Lex_cstring_strlen(new_name)). + streq(Lex_cstring_strlen(old_name))) DBUG_RETURN(false); } } @@ -2604,8 +2594,8 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info) part_state must be PART_NORMAL! */ if (!part_elem || !new_part_elem || - strcmp(part_elem->partition_name, - new_part_elem->partition_name) || + strcmp(part_elem->partition_name.str, + new_part_elem->partition_name.str) || part_elem->part_state != PART_NORMAL || new_part_elem->part_state != PART_NORMAL || part_elem->max_value != new_part_elem->max_value || @@ -2666,8 +2656,8 @@ bool partition_info::has_same_partitioning(partition_info *new_part_info) sub_part_elem->engine_type != new_sub_part_elem->engine_type) DBUG_RETURN(false); - if (strcmp(sub_part_elem->partition_name, - new_sub_part_elem->partition_name) || + if (strcmp(sub_part_elem->partition_name.str, + new_sub_part_elem->partition_name.str) || sub_part_elem->part_state != PART_NORMAL || new_sub_part_elem->part_state != PART_NORMAL || sub_part_elem->part_min_rows != diff --git a/sql/partition_info.h b/sql/partition_info.h index 3a8c3a37524..50f39bcc7ac 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -393,7 +393,8 @@ public: bool check_partition_field_length(); bool init_column_part(THD *thd); bool add_column_list_value(THD *thd, Item *item); - partition_element *get_part_elem(const char *partition_name, char *file_name, + partition_element *get_part_elem(const Lex_ident_partition &partition_name, + char *file_name, size_t file_name_size, uint32 *part_id); void report_part_expr_error(bool use_subpart_expr); bool has_same_partitioning(partition_info *new_part_info); @@ -526,11 +527,13 @@ void partition_info::vers_update_el_ids() } -inline -bool make_partition_name(char *move_ptr, uint i) +static inline +Lex_ident_partition make_partition_name(char *move_ptr, uint i) { int res= snprintf(move_ptr, MAX_PART_NAME_SIZE + 1, "p%u", i); - return res < 0 || res > MAX_PART_NAME_SIZE; + return res < 0 || res > MAX_PART_NAME_SIZE ? + Lex_ident_partition() : + Lex_ident_partition(move_ptr, (size_t) res); } @@ -549,15 +552,16 @@ uint partition_info::next_part_no(uint new_parts) const for (uint cur_part= 0; cur_part < new_parts; ++cur_part, ++suffix) { uint32 cur_suffix= suffix; - if (make_partition_name(part_name, suffix)) + Lex_ident_partition part_name_ls(make_partition_name(part_name, suffix)); + if (!part_name_ls.str) return 0; partition_element *el; it.rewind(); while ((el= it++)) { - if (0 == my_strcasecmp(&my_charset_latin1, el->partition_name, part_name)) + if (el->partition_name.streq(part_name_ls)) { - if (make_partition_name(part_name, ++suffix)) + if (!(part_name_ls= make_partition_name(part_name, ++suffix)).str) return 0; it.rewind(); } diff --git a/sql/procedure.cc b/sql/procedure.cc index 21afef274bc..192e2877b54 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -29,16 +29,18 @@ #endif static struct st_procedure_def { - const char *name; + const Lex_ident_routine name; Procedure *(*init)(THD *thd,ORDER *param,select_result *result, List &field_list); } sql_procs[] = { #ifdef USE_PROC_RANGE - { "split_sum",proc_sum_range_init }, // Internal procedure at TCX - { "split_count",proc_count_range_init }, // Internal procedure at TCX - { "matris_ranges",proc_matris_range_init }, // Internal procedure at TCX + // A few internal procedures at TCX + { Lex_ident_routine("split_sum"_LEX_CSTRING), proc_sum_range_init }, + { Lex_ident_routine("split_count"_LEX_CSTRING), proc_count_range_init }, + { Lex_ident_routine("matris_ranges"_LEX_CSTRING), proc_matris_range_init }, #endif - { "analyse",proc_analyse_init } // Analyse a result + // Analyse a result + { Lex_ident_routine("analyse"_LEX_CSTRING), proc_analyse_init } }; @@ -88,8 +90,7 @@ setup_procedure(THD *thd,ORDER *param,select_result *result, DBUG_RETURN(0); for (i=0 ; i < array_elements(sql_procs) ; i++) { - if (!my_strcasecmp(system_charset_info, - (*param->item)->name.str, sql_procs[i].name)) + if (sql_procs[i].name.streq((*param->item)->name)) { Procedure *proc=(*sql_procs[i].init)(thd,param,result,field_list); *error= !proc; diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 982c0c9482d..0551fe5b76d 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -206,8 +206,8 @@ Rpl_filter::db_ok(const char* db) SYNOPSIS db_ok_with_wild_table() - db name of the db to check. - Is tested with check_db_name() before calling this function. + db name of the db to check. Is tested with + Lex_ident_db::check_name() before calling this function. NOTES Here is the reason for this function. @@ -670,7 +670,8 @@ void Rpl_filter::init_table_rule_hash(HASH* h, bool* h_inited) { my_hash_init(key_memory_TABLE_RULE_ENT, h, - system_charset_info,TABLE_RULE_HASH_SIZE,0,0, get_table_key, + Lex_ident_rpl_filter::charset_info(), + TABLE_RULE_HASH_SIZE,0,0, get_table_key, free_table_ent, 0); *h_inited = 1; } diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 66983c88a1c..45303365b1f 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1123,7 +1123,8 @@ bool Master_info_index::init_all_master_info() } /* Initialize Master_info Hash Table */ - if (my_hash_init(PSI_INSTRUMENT_ME, &master_info_hash, system_charset_info, + if (my_hash_init(PSI_INSTRUMENT_ME, &master_info_hash, + Lex_ident_master_info::charset_info(), MAX_REPLICATION_THREAD, 0, 0, (my_hash_get_key) get_key_master_info, (my_hash_free_key)free_key_master_info, HASH_UNIQUE)) diff --git a/sql/set_var.cc b/sql/set_var.cc index da638e1b5cb..d833efb0097 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -64,7 +64,8 @@ int sys_var_init() /* Must be already initialized. */ DBUG_ASSERT(system_charset_info != NULL); - if (my_hash_init(PSI_INSTRUMENT_ME, &system_variable_hash, system_charset_info, 700, 0, + if (my_hash_init(PSI_INSTRUMENT_ME, &system_variable_hash, + Lex_ident_sys_var::charset_info(), 700, 0, 0, (my_hash_get_key) get_sys_var_length, 0, HASH_UNIQUE)) goto error; @@ -499,31 +500,31 @@ bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v) typedef struct old_names_map_st { - const char *old_name; + const Lex_ident_charset old_name; const char *new_name; } my_old_conv; static my_old_conv old_conv[]= { - { "cp1251_koi8" , "cp1251" }, - { "cp1250_latin2" , "cp1250" }, - { "kam_latin2" , "keybcs2" }, - { "mac_latin2" , "MacRoman" }, - { "macce_latin2" , "MacCE" }, - { "pc2_latin2" , "pclatin2" }, - { "vga_latin2" , "pclatin1" }, - { "koi8_cp1251" , "koi8r" }, - { "win1251ukr_koi8_ukr" , "win1251ukr" }, - { "koi8_ukr_win1251ukr" , "koi8u" }, - { NULL , NULL } + { "cp1251_koi8"_Lex_ident_charset , "cp1251" }, + { "cp1250_latin2"_Lex_ident_charset , "cp1250" }, + { "kam_latin2"_Lex_ident_charset , "keybcs2" }, + { "mac_latin2"_Lex_ident_charset , "MacRoman" }, + { "macce_latin2"_Lex_ident_charset , "MacCE" }, + { "pc2_latin2"_Lex_ident_charset , "pclatin2" }, + { "vga_latin2"_Lex_ident_charset , "pclatin1" }, + { "koi8_cp1251"_Lex_ident_charset , "koi8r" }, + { "win1251ukr_koi8_ukr"_Lex_ident_charset , "win1251ukr" }, + { "koi8_ukr_win1251ukr"_Lex_ident_charset , "koi8u" }, + { Lex_ident_charset() , NULL } }; -CHARSET_INFO *get_old_charset_by_name(const char *name) +CHARSET_INFO *get_old_charset_by_name(const LEX_CSTRING &name) { my_old_conv *conv; - for (conv= old_conv; conv->old_name; conv++) + for (conv= old_conv; conv->old_name.str; conv++) { - if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name)) + if (conv->old_name.streq(name)) return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0)); } return NULL; @@ -959,7 +960,7 @@ int set_var_password::update(THD *thd) int set_var_role::check(THD *thd) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - int status= acl_check_setrole(thd, role.str, &access); + int status= acl_check_setrole(thd, role, &access); return status; #else return 0; @@ -969,7 +970,7 @@ int set_var_role::check(THD *thd) int set_var_role::update(THD *thd) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - int res= acl_setrole(thd, role.str, access); + int res= acl_setrole(thd, role, access); if (!res) thd->session_tracker.state_change.mark_as_changed(thd); return res; @@ -986,17 +987,17 @@ int set_var_default_role::check(THD *thd) { #ifndef NO_EMBEDDED_ACCESS_CHECKS real_user= get_current_user(thd, user); - real_role= role.str; + real_role= role; if (role.str == current_role.str) { if (!thd->security_ctx->priv_role[0]) - real_role= "NONE"; + real_role= "NONE"_LEX_CSTRING; else - real_role= thd->security_ctx->priv_role; + real_role= Lex_cstring_strlen(thd->security_ctx->priv_role); } - return acl_check_set_default_role(thd, real_user->host.str, - real_user->user.str, real_role); + return acl_check_set_default_role(thd, real_user->host, + real_user->user, real_role); #else return 0; #endif @@ -1007,7 +1008,7 @@ int set_var_default_role::update(THD *thd) #ifndef NO_EMBEDDED_ACCESS_CHECKS Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; thd->m_reprepare_observer= 0; - int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str, + int res= acl_set_default_role(thd, real_user->host, real_user->user, real_role); thd->m_reprepare_observer= save_reprepare_observer; return res; diff --git a/sql/set_var.h b/sql/set_var.h index aed4955ef62..8f7e3609f5f 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -131,7 +131,7 @@ public: int scope() const { return flags & SCOPE_MASK; } virtual CHARSET_INFO *charset(THD *thd) const { - return system_charset_info; + return system_charset_info_for_i_s; } bool is_readonly() const { return flags & READONLY; } void update_flags(int new_flags) { flags = new_flags; } @@ -383,7 +383,7 @@ class set_var_default_role: public set_var_base { LEX_USER *user, *real_user; LEX_CSTRING role; - const char *real_role; + LEX_CSTRING real_role; public: set_var_default_role(LEX_USER *user_arg, LEX_CSTRING role_arg) : user(user_arg), role(role_arg) {} @@ -477,7 +477,7 @@ extern sys_var *Sys_autocommit_ptr, *Sys_last_gtid_ptr, *Sys_character_set_client_ptr, *Sys_character_set_connection_ptr, *Sys_character_set_results_ptr; -CHARSET_INFO *get_old_charset_by_name(const char *old_name); +CHARSET_INFO *get_old_charset_by_name(const LEX_CSTRING &name); int sys_var_init(); uint sys_var_elements(); diff --git a/sql/slave.cc b/sql/slave.cc index a6858b428bd..57398496577 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3411,8 +3411,9 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, static int cmp_mi_by_name(const Master_info **arg1, const Master_info **arg2) { - return my_strcasecmp(system_charset_info, (*arg1)->connection_name.str, - (*arg2)->connection_name.str); + return Lex_ident_master_info::charset_info()->strnncoll( + (*arg1)->connection_name, + (*arg2)->connection_name); } diff --git a/sql/sp.cc b/sql/sp.cc index 95de3ef04cf..ebac672df4d 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2212,7 +2212,7 @@ Sp_handler::sp_find_package_routine(THD *thd, bool cache_only) const { DBUG_ENTER("sp_find_package_routine"); - Database_qualified_name pkgname(&name->m_db, &pkgname_str); + Database_qualified_name pkgname(name->m_db, pkgname_str); sp_head *ph= sp_cache_lookup(&thd->sp_package_body_cache, &pkgname); if (!ph && !cache_only) sp_handler_package_body.db_find_and_cache_routine(thd, &pkgname, &ph); @@ -2289,7 +2289,7 @@ Sp_handler::sp_exist_routines(THD *thd, TABLE_LIST *routines) const if (!lex_name.str) DBUG_RETURN(TRUE); // EOM, error was already sent /* - routine->db was earlier tested with check_db_name(). + routine->db was earlier tested with Lex_ident_db::check_name(). Now it's lower-cased according to lower_case_table_names. It's safe to make a Lex_ident_db_normalized. */ @@ -2355,7 +2355,8 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena, const Sp_handler *handler, TABLE_LIST *belong_to_view) { - my_hash_init_opt(PSI_INSTRUMENT_ME, &prelocking_ctx->sroutines, system_charset_info, + my_hash_init_opt(PSI_INSTRUMENT_ME, &prelocking_ctx->sroutines, + Lex_ident_routine::charset_info(), Query_tables_list::START_SROUTINES_HASH_SIZE, 0, 0, sp_sroutine_key, 0, 0); @@ -2432,7 +2433,7 @@ Sp_handler::sp_cache_routine_reentrant(THD *thd, static bool is_package_public_routine(THD *thd, - const LEX_CSTRING &db, + const Lex_ident_db &db, const LEX_CSTRING &package, const LEX_CSTRING &routine, enum_sp_type type) @@ -2466,7 +2467,7 @@ is_package_public_routine(THD *thd, static bool is_package_public_routine_quick(THD *thd, - const LEX_CSTRING &db, + const Lex_ident_db &db, const LEX_CSTRING &pkgname, const LEX_CSTRING &name, enum_sp_type type) @@ -2490,7 +2491,7 @@ is_package_body_routine(THD *thd, sp_package *pkg, const LEX_CSTRING &name2, enum_sp_type type) { - return Sp_handler::eq_routine_name(pkg->m_name, name1) && + return Lex_ident_routine(pkg->m_name).streq(name1) && (pkg->m_routine_declarations.find(name2, type) || pkg->m_routine_implementations.find(name2, type)); } @@ -2517,7 +2518,7 @@ bool Sp_handler:: Rewrite name if name->m_db (xxx) is a known package, and name->m_name (yyy) is a known routine in this package. */ - LEX_CSTRING tmpdb= thd->db; + const Lex_ident_db tmpdb= Lex_ident_db(thd->db); if (is_package_public_routine(thd, tmpdb, name->m_db, name->m_name, type()) || // Check if a package routine calls a private routine (caller && caller->m_parent && @@ -2528,7 +2529,7 @@ bool Sp_handler:: is_package_body_routine(thd, pkg, name->m_db, name->m_name, type()))) { pkgname->m_db= tmpdb; - pkgname->m_name= name->m_db; + pkgname->m_name= Lex_ident_routine(name->m_db); *pkg_routine_handler= package_routine_handler(); return name->make_package_routine_name(thd->mem_root, tmpdb, name->m_db, name->m_name); @@ -2584,7 +2585,7 @@ bool Sp_handler:: - yyy() has a forward declaration - yyy() is declared in the corresponding CREATE PACKAGE */ - if (eq_routine_name(tmpname, name->m_name) || + if (Lex_ident_routine(name->m_name).streq(tmpname) || caller->m_parent->m_routine_implementations.find(name->m_name, type()) || caller->m_parent->m_routine_declarations.find(name->m_name, type()) || is_package_public_routine_quick(thd, caller->m_db, @@ -2923,12 +2924,13 @@ Sp_handler::sp_cache_package_routine(THD *thd, { DBUG_ENTER("sp_cache_package_routine"); DBUG_ASSERT(type() == SP_TYPE_FUNCTION || type() == SP_TYPE_PROCEDURE); - LEX_CSTRING db= lower_case_table_names ? thd->make_ident_casedn(name->m_db) : - name->m_db; + const Lex_ident_db db= lower_case_table_names ? + thd->lex_ident_casedn(name->m_db) : + name->m_db; if (!db.str) DBUG_RETURN(true); // EOM, error was already sent /* - name->m_db was earlier tested with check_db_name(). + name->m_db was earlier tested with Lex_ident_db::check_name(). Now it's lower-cased according to lower_case_table_names. It's safe to make a Lex_ident_db_normalized. */ @@ -3100,13 +3102,13 @@ Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table, LEX_CSTRING dbn= lower_case_table_names ? thd->make_ident_casedn(db) : db; if (!dbn.str) return 0; // EOM, error was already sent - if (Lex_ident_fs(dbn).check_db_name()) + if (Lex_ident_db::check_name(dbn)) { my_error(ER_SP_WRONG_NAME, MYF(0), dbn.str); return 0; } /* - db was earlier tested with check_db_name(). + db was earlier tested with Lex_ident_db::check_name(). Now it's lower-cased according to lower_case_table_names. It's safe make a Lex_ident_db_normalized. */ diff --git a/sql/sp.h b/sql/sp.h index 792321c930d..5db5f888757 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -134,12 +134,6 @@ public: return sph ? sph->sp_handler_mysql_proc() : NULL; } - static bool eq_routine_name(const LEX_CSTRING &name1, - const LEX_CSTRING &name2) - { - return system_charset_info->strnncoll(name1.str, name1.length, - name2.str, name2.length) == 0; - } const char *type_str() const { return type_lex_cstring().str; } virtual const char *show_create_routine_col1_caption() const { diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8a6ff5718e3..705be54c925 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -462,8 +462,8 @@ bool THD::sp_eval_expr(Field *result_field, Item **expr_item_ptr) */ sp_name::sp_name(const MDL_key *key, char *qname_buff) - :Database_qualified_name(key->db_name(), key->db_name_length(), - key->name(), key->name_length()), + :Database_qualified_name(Lex_ident_db(key->db_name(), key->db_name_length()), + Lex_cstring(key->name(), key->name_length())), m_explicit_name(false) { if (m_db.length) @@ -487,17 +487,16 @@ sp_name::sp_name(const MDL_key *key, char *qname_buff) */ bool -check_routine_name(const LEX_CSTRING *ident) +Lex_ident_routine::check_name_with_error(const LEX_CSTRING &ident) { - DBUG_ASSERT(ident); - DBUG_ASSERT(ident->str); + DBUG_ASSERT(ident.str); - if (!ident->str[0] || ident->str[ident->length-1] == ' ') + if (!ident.str[0] || ident.str[ident.length-1] == ' ') { - my_error(ER_SP_WRONG_NAME, MYF(0), ident->str); + my_error(ER_SP_WRONG_NAME, MYF(0), ident.str); return TRUE; } - if (check_ident_length(ident)) + if (check_ident_length(&ident)) return TRUE; return FALSE; @@ -548,7 +547,6 @@ void sp_head::destroy(sp_head *sp) sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent, const Sp_handler *sph, enum_sp_aggregate_type agg_type) :Query_arena(NULL, STMT_INITIALIZED_FOR_SP), - Database_qualified_name(&null_clex_str, &null_clex_str), main_mem_root(*mem_root_arg), #ifdef PROTECT_STATEMENT_MEMROOT executed_counter(0), @@ -602,9 +600,11 @@ sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent, m_lex.empty(); my_init_dynamic_array(key_memory_sp_head_main_root, &m_instr, sizeof(sp_instr *), 16, 8, MYF(0)); - my_hash_init(key_memory_sp_head_main_root, &m_sptabs, system_charset_info, 0, - 0, 0, sp_table_key, 0, 0); - my_hash_init(key_memory_sp_head_main_root, &m_sroutines, system_charset_info, + my_hash_init(key_memory_sp_head_main_root, &m_sptabs, + Lex_ident_routine::charset_info(), + 0, 0, 0, sp_table_key, 0, 0); + my_hash_init(key_memory_sp_head_main_root, &m_sroutines, + Lex_ident_routine::charset_info(), 0, 0, 0, sp_sroutine_key, 0, 0); DBUG_VOID_RETURN; @@ -697,8 +697,7 @@ bool sp_package::validate_public_routines(THD *thd, sp_package *spec) for (LEX *lex2; (lex2= it2++); ) { DBUG_ASSERT(lex2->sphead); - if (Sp_handler::eq_routine_name(lex2->sphead->m_name, - lex->sphead->m_name) && + if (Lex_ident_routine(lex2->sphead->m_name).streq(lex->sphead->m_name) && lex2->sphead->eq_routine_spec(lex->sphead)) { found= true; @@ -732,8 +731,7 @@ bool sp_package::validate_private_routines(THD *thd) for (LEX *lex2; (lex2= it2++); ) { DBUG_ASSERT(lex2->sphead); - if (Sp_handler::eq_routine_name(lex2->sphead->m_name, - lex->sphead->m_name) && + if (Lex_ident_routine(lex2->sphead->m_name).streq(lex->sphead->m_name) && lex2->sphead->eq_routine_spec(lex->sphead)) { found= true; @@ -764,10 +762,10 @@ LEX *sp_package::LexList::find(const LEX_CSTRING &name, (dot= strrchr(lex->sphead->m_name.str, '.'))) { size_t ofs= dot + 1 - lex->sphead->m_name.str; - LEX_CSTRING non_qualified_sphead_name= lex->sphead->m_name; + Lex_ident_routine non_qualified_sphead_name(lex->sphead->m_name); non_qualified_sphead_name.str+= ofs; non_qualified_sphead_name.length-= ofs; - if (Sp_handler::eq_routine_name(non_qualified_sphead_name, name)) + if (non_qualified_sphead_name.streq(name)) return lex; } } @@ -783,7 +781,7 @@ LEX *sp_package::LexList::find_qualified(const LEX_CSTRING &name, { DBUG_ASSERT(lex->sphead); if (lex->sphead->m_handler->type() == type && - Sp_handler::eq_routine_name(lex->sphead->m_name, name)) + Lex_ident_routine(lex->sphead->m_name).streq(name)) return lex; } return NULL; @@ -2659,7 +2657,7 @@ sp_head::backpatch_goto(THD *thd, sp_label *lab,sp_label *lab_begin_block) */ continue; } - if (lex_string_cmp(system_charset_info, &bp->lab->name, &lab->name) == 0) + if (bp->lab->name.streq(lab->name)) { if (bp->instr_type == GOTO) { @@ -3997,7 +3995,7 @@ bool sp_head::check_group_aggregate_instructions_function() const bool sp_head::check_package_routine_end_name(const LEX_CSTRING &end_name) const { - LEX_CSTRING non_qualified_name= m_name; + Lex_ident_routine non_qualified_name(m_name); const char *errpos; size_t ofs; if (!end_name.length) @@ -4011,7 +4009,7 @@ bool sp_head::check_package_routine_end_name(const LEX_CSTRING &end_name) const ofs= errpos - m_name.str; non_qualified_name.str+= ofs; non_qualified_name.length-= ofs; - if (Sp_handler::eq_routine_name(end_name, non_qualified_name)) + if (non_qualified_name.streq(end_name)) return false; err: my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), end_name.str, errpos); @@ -4022,7 +4020,7 @@ err: bool sp_head::check_standalone_routine_end_name(const sp_name *end_name) const { - if (end_name && !end_name->eq(this)) + if (end_name && !end_name->eq_routine_name(this)) { my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), ErrConvDQName(end_name).ptr(), ErrConvDQName(this).ptr()); diff --git a/sql/sp_head.h b/sql/sp_head.h index 6a07e22401b..2b663f406d2 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -132,9 +132,6 @@ public: }; -bool -check_routine_name(const LEX_CSTRING *ident); - class sp_head :private Query_arena, public Database_qualified_name, public Sql_alloc @@ -769,7 +766,7 @@ public: return false; } bool fill_spvar_definition(THD *thd, Column_definition *def, - LEX_CSTRING *name) + const Lex_ident_column *name) { def->field_name= *name; return fill_spvar_definition(thd, def); diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 848d1f0c655..9f21d34eb88 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -139,8 +139,7 @@ sp_pcontext *sp_pcontext::push_context(THD *thd, sp_pcontext::enum_scope scope) bool cmp_labels(sp_label *a, sp_label *b) { - return (lex_string_cmp(system_charset_info, &a->name, &b->name) == 0 && - a->type == b->type); + return a->type == b->type && a->name.streq(b->name); } sp_pcontext *sp_pcontext::pop_context() @@ -215,8 +214,7 @@ sp_variable *sp_pcontext::find_variable(const LEX_CSTRING *name, { sp_variable *p= m_vars.at(i); - if (system_charset_info->strnncoll(name->str, name->length, - p->name.str, p->name.length) == 0) + if (p->name.streq(*name)) { return p; } @@ -310,7 +308,7 @@ sp_label *sp_pcontext::find_goto_label(const LEX_CSTRING *name, bool recusive) while ((lab= li++)) { - if (lex_string_cmp(system_charset_info, name, &lab->name) == 0) + if (lab->name.streq(*name)) return lab; } @@ -347,7 +345,7 @@ sp_label *sp_pcontext::find_label(const LEX_CSTRING *name) while ((lab= li++)) { - if (lex_string_cmp(system_charset_info, name, &lab->name) == 0) + if (lab->name.streq(*name)) return lab; } @@ -383,7 +381,7 @@ sp_label *sp_pcontext::find_label_current_loop_start() bool sp_pcontext::add_condition(THD *thd, - const LEX_CSTRING *name, + const Lex_ident_column &name, sp_condition_value *value) { sp_condition *p= new (thd->mem_root) sp_condition(name, value); @@ -442,12 +440,12 @@ static sp_condition_value static sp_condition sp_predefined_conditions[]= { // Warnings - sp_condition(STRING_WITH_LEN("NO_DATA_FOUND"), &cond_no_data_found), + sp_condition("NO_DATA_FOUND"_Lex_ident_column, &cond_no_data_found), // Errors - sp_condition(STRING_WITH_LEN("INVALID_CURSOR"), &cond_invalid_cursor), - sp_condition(STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index), - sp_condition(STRING_WITH_LEN("DUP_VAL_ON_INDEX"), &cond_dup_val_on_index2), - sp_condition(STRING_WITH_LEN("TOO_MANY_ROWS"), &cond_too_many_rows) + sp_condition("INVALID_CURSOR"_Lex_ident_column, &cond_invalid_cursor), + sp_condition("DUP_VAL_ON_INDEX"_Lex_ident_column, &cond_dup_val_on_index), + sp_condition("DUP_VAL_ON_INDEX"_Lex_ident_column, &cond_dup_val_on_index2), + sp_condition("TOO_MANY_ROWS"_Lex_ident_column, &cond_too_many_rows) }; @@ -628,10 +626,7 @@ const sp_pcursor *sp_pcontext::find_cursor(const LEX_CSTRING *name, while (i--) { - LEX_CSTRING n= m_cursors.at(i); - - if (system_charset_info->strnncoll(name->str, name->length, - n.str, n.length) == 0) + if (m_cursors.at(i).streq(*name)) { *poff= m_cursor_offset + i; return &m_cursors.at(i); diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 71846ad4620..972fc6aedc1 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -41,7 +41,7 @@ public: }; /// Name of the SP-variable. - LEX_CSTRING name; + Lex_ident_column name; /// Mode of the SP-variable. enum_mode mode; @@ -116,7 +116,7 @@ public: }; /// Name of the label. - LEX_CSTRING name; + Lex_ident_column name; /// Instruction pointer of the label. uint ip; @@ -242,28 +242,20 @@ class sp_condition : public Sql_alloc { public: /// Name of the condition. - LEX_CSTRING name; + Lex_ident_column name; /// Value of the condition. sp_condition_value *value; public: - sp_condition(const LEX_CSTRING *name_arg, sp_condition_value *value_arg) + sp_condition(const Lex_ident_column &name_arg, sp_condition_value *value_arg) :Sql_alloc(), - name(*name_arg), + name(name_arg), value(value_arg) { } - sp_condition(const char *name_arg, size_t name_length_arg, - sp_condition_value *value_arg) - :value(value_arg) - { - name.str= name_arg; - name.length= name_length_arg; - } bool eq_name(const LEX_CSTRING *str) const { - return system_charset_info->strnncoll(name.str, name.length, - str->str, str->length) == 0; + return name.streq(*str); } }; @@ -286,14 +278,14 @@ public: Note, m_param_context can be not NULL, but have no variables. This is also means a cursor with no parameters (similar to NULL). */ -class sp_pcursor: public LEX_CSTRING +class sp_pcursor: public Lex_ident_column { class sp_pcontext *m_param_context; // Formal parameters class sp_lex_cursor *m_lex; // The cursor statement LEX public: sp_pcursor(const LEX_CSTRING *name, class sp_pcontext *param_ctx, class sp_lex_cursor *lex) - :LEX_CSTRING(*name), m_param_context(param_ctx), m_lex(lex) + :Lex_ident_column(*name), m_param_context(param_ctx), m_lex(lex) { } class sp_pcontext *param_context() const { return m_param_context; } class sp_lex_cursor *lex() const { return m_lex; } @@ -605,7 +597,7 @@ public: // Conditions. ///////////////////////////////////////////////////////////////////////// - bool add_condition(THD *thd, const LEX_CSTRING *name, + bool add_condition(THD *thd, const Lex_ident_column &name, sp_condition_value *value); /// See comment for find_variable() above. @@ -615,12 +607,12 @@ public: sp_condition_value * find_declared_or_predefined_condition(THD *thd, const LEX_CSTRING *name) const; - bool declare_condition(THD *thd, const LEX_CSTRING *name, + bool declare_condition(THD *thd, const Lex_ident_column &name, sp_condition_value *val) { - if (find_condition(name, true)) + if (find_condition(&name, true)) { - my_error(ER_SP_DUP_COND, MYF(0), name->str); + my_error(ER_SP_DUP_COND, MYF(0), name.str); return true; } return add_condition(thd, name, val); diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index cff6c31d652..b00874bc9cb 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -211,12 +211,12 @@ bool sp_rcontext::init_var_table(THD *thd, */ static inline bool check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list, - const char *str, size_t length, + const Lex_ident_column &name, Field *fld) { #ifndef NO_EMBEDDED_ACCESS_CHECKS table_list->table->grant.want_privilege= SELECT_ACL; - return check_column_grant_in_table_ref(thd, table_list, str, length, fld); + return check_column_grant_in_table_ref(thd, table_list, name, fld); #else return false; #endif @@ -255,8 +255,7 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, if (likely((src= lex.query_tables->table->find_field_by_name(&m_column)))) { if (!(rc= check_column_grant_for_type_ref(thd, table_list, - m_column.str, - m_column.length, src))) + m_column, src))) { *def= Column_definition(thd, src, NULL/*No defaults,no constraints*/); def->flags&= (uint) ~NOT_NULL_FLAG; @@ -318,10 +317,9 @@ bool Table_ident::resolve_table_rowtype_ref(THD *thd, as the table will be closed and freed soon, in the end of this method. */ - LEX_CSTRING tmp= src[0]->field_name; + const Lex_ident_column tmp= src[0]->field_name; Spvar_definition *def; - if ((rc= check_column_grant_for_type_ref(thd, table_list, - tmp.str, tmp.length,src[0])) || + if ((rc= check_column_grant_for_type_ref(thd, table_list, tmp, src[0])) || (rc= !(src[0]->field_name.str= thd->strmake(tmp.str, tmp.length))) || (rc= !(def= new (thd->mem_root) Spvar_definition(thd, *src)))) break; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 14450a5a610..51885cc4c16 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -80,13 +80,13 @@ const char *safe_vio_type_name(Vio *vio) #include "sql_acl_getsort.ic" -static LEX_CSTRING native_password_plugin_name= { - STRING_WITH_LEN("mysql_native_password") -}; +static Lex_ident_plugin native_password_plugin_name= + "mysql_native_password"_Lex_ident_plugin; + + +static Lex_ident_plugin old_password_plugin_name= + "mysql_old_password"_Lex_ident_plugin; -static LEX_CSTRING old_password_plugin_name= { - STRING_WITH_LEN("mysql_old_password") -}; /// @todo make it configurable LEX_CSTRING *default_auth_plugin_name= &native_password_plugin_name; @@ -198,6 +198,11 @@ public: { return !(auth= (AUTH*) alloc_root(root, (nauth= n)*sizeof(AUTH))); } + Lex_ident_host hostname() const + { + DBUG_ASSERT(host.hostname[hostname_length] == '\0'); + return Lex_ident_host(host.hostname, hostname_length); + } }; @@ -239,18 +244,6 @@ public: return dst; } - int cmp(const char *user2, const char *host2) - { - CHARSET_INFO *cs= system_charset_info; - int res; - res= strcmp(user.str, user2); - if (!res) - res= my_strcasecmp(cs, host.hostname, host2); - return res; - } - - bool eq(const char *user2, const char *host2) { return !cmp(user2, host2); } - bool wild_eq(const char *user2, const char *host2, const char *ip2) { if (strcmp(user.str, user2)) @@ -563,14 +556,17 @@ static uchar* acl_role_get_key(ACL_ROLE *entry, size_t *length, struct ROLE_GRANT_PAIR : public Sql_alloc { - char *u_uname; - char *u_hname; - char *r_uname; + LEX_CSTRING u_uname; + LEX_CSTRING u_hname; + LEX_CSTRING r_uname; LEX_STRING hashkey; bool with_admin; - bool init(MEM_ROOT *mem, const char *username, const char *hostname, - const char *rolename, bool with_admin_option); + bool init(MEM_ROOT *mem, + const LEX_CSTRING &username, + const LEX_CSTRING &hostname, + const LEX_CSTRING &rolename, + bool with_admin_option); }; static uchar* acl_role_map_get_key(ROLE_GRANT_PAIR *entry, size_t *length, @@ -580,18 +576,18 @@ static uchar* acl_role_map_get_key(ROLE_GRANT_PAIR *entry, size_t *length, return (uchar*) entry->hashkey.str; } -bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, const char *username, - const char *hostname, const char *rolename, +bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, + const LEX_CSTRING &username, + const LEX_CSTRING &hostname, + const LEX_CSTRING &rolename, bool with_admin_option) { - size_t uname_l = safe_strlen(username); - size_t hname_l = safe_strlen(hostname); - size_t rname_l = safe_strlen(rolename); /* Create a buffer that holds all 3 NULL terminated strings in succession To save memory space, the same buffer is used as the hashkey + Add the '\0' aswell. */ - size_t bufflen = uname_l + hname_l + rname_l + 3; //add the '\0' aswell + size_t bufflen= username.length + hostname.length + rolename.length + 3; char *buff= (char *)alloc_root(mem, bufflen); if (!buff) return true; @@ -600,23 +596,23 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, const char *username, Offsets in the buffer for all 3 strings */ char *username_pos= buff; - char *hostname_pos= buff + uname_l + 1; - char *rolename_pos= buff + uname_l + hname_l + 2; + char *hostname_pos= buff + username.length + 1; + char *rolename_pos= buff + username.length + hostname.length + 2; - if (username) //prevent undefined behaviour - memcpy(username_pos, username, uname_l); - username_pos[uname_l]= '\0'; //#1 string terminator - u_uname= username_pos; + if (username.str) //prevent undefined behaviour + memcpy(username_pos, username.str, username.length); + username_pos[username.length]= '\0'; //#1 string terminator + u_uname= Lex_cstring(username_pos, username.length); - if (hostname) //prevent undefined behaviour - memcpy(hostname_pos, hostname, hname_l); - hostname_pos[hname_l]= '\0'; //#2 string terminator - u_hname= hostname_pos; + if (hostname.str) //prevent undefined behaviour + memcpy(hostname_pos, hostname.str, hostname.length); + hostname_pos[hostname.length]= '\0'; //#2 string terminator + u_hname= Lex_cstring(hostname_pos, hostname.length); - if (rolename) //prevent undefined behaviour - memcpy(rolename_pos, rolename, rname_l); - rolename_pos[rname_l]= '\0'; //#3 string terminator - r_uname= rolename_pos; + if (rolename.str) //prevent undefined behaviour + memcpy(rolename_pos, rolename.str, rolename.length); + rolename_pos[rolename.length]= '\0'; //#3 string terminator + r_uname= Lex_cstring(rolename_pos, rolename.length); hashkey.str = buff; hashkey.length = bufflen; @@ -690,15 +686,21 @@ static void rebuild_acl_dbs(); static void init_check_host(void); static void rebuild_check_host(void); static void rebuild_role_grants(void); -static ACL_USER *find_user_exact(const char *host, const char *user); -static ACL_USER *find_user_wild(const char *host, const char *user, const char *ip= 0); -static ACL_ROLE *find_acl_role(const char *user, bool allow_public); +static ACL_USER *find_user_exact(const LEX_CSTRING &host, + const LEX_CSTRING &user); +static ACL_USER *find_user_wild(const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &ip= null_clex_str); +static ACL_ROLE *find_acl_role(const LEX_CSTRING &user, bool allow_public); static ROLE_GRANT_PAIR *find_role_grant_pair(const LEX_CSTRING *u, const LEX_CSTRING *h, const LEX_CSTRING *r); -static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host); +static ACL_USER_BASE *find_acl_user_base(const LEX_CSTRING &user, + const LEX_CSTRING &host); static bool update_user_table_password(THD *, const User_table&, const ACL_USER&); static bool acl_load(THD *thd, const Grant_tables& grant_tables); static inline void get_grantor(THD *thd, char* grantor); -static bool add_role_user_mapping(const char *uname, const char *hname, const char *rname); +static bool add_role_user_mapping(const LEX_CSTRING &uname, + const LEX_CSTRING &hname, + const LEX_CSTRING &rname); static bool get_YN_as_bool(Field *field); #define ROLE_CYCLE_FOUND 2 @@ -2423,7 +2425,7 @@ static bool set_user_salt_if_needed(ACL_USER *user_copy, int curr_auth, return 1; } - ACL_USER *user= find_user_exact(user_copy->host.hostname, user_copy->user.str); + ACL_USER *user= find_user_exact(user_copy->hostname(), user_copy->user); // make sure the user wasn't altered or dropped meanwhile if (user) { @@ -2452,10 +2454,10 @@ static bool set_user_salt_if_needed(ACL_USER *user_copy, int curr_auth, */ static bool fix_user_plugin_ptr(ACL_USER::AUTH *auth) { - if (lex_string_eq(&auth->plugin, &native_password_plugin_name)) + if (native_password_plugin_name.streq(auth->plugin)) auth->plugin= native_password_plugin_name; else - if (lex_string_eq(&auth->plugin, &old_password_plugin_name)) + if (old_password_plugin_name.streq(auth->plugin)) auth->plugin= old_password_plugin_name; else return true; @@ -2760,7 +2762,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) ACL_DB db; db.user=safe_str(get_field(&acl_memroot, db_table.user())); const char *hostname= get_field(&acl_memroot, db_table.host()); - if (!hostname && find_acl_role(db.user, true)) + if (!hostname && find_acl_role(Lex_cstring_strlen(db.user), true)) hostname= ""; update_hostname(&db.host, hostname); @@ -2847,14 +2849,24 @@ static bool acl_load(THD *thd, const Grant_tables& tables) init_alloc_root(key_memory_acl_mem, &temp_root, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); while (!(read_record_info.read_record())) { - char *hostname= safe_str(get_field(&temp_root, roles_mapping_table.host())); - char *username= safe_str(get_field(&temp_root, roles_mapping_table.user())); - char *rolename= safe_str(get_field(&temp_root, roles_mapping_table.role())); + /* + acl_find_user_by_name() called later in this code block (through other + functions) needs a 0-terminated string. So does sql_print_error(). + Let's use Field::val_lex_string_strmake() to have 0-terminated copies + of field values. + */ + const Lex_cstring hostname(roles_mapping_table.host()-> + val_lex_string_strmake(&temp_root)); + const Lex_cstring username(roles_mapping_table.user()-> + val_lex_string_strmake(&temp_root)); + const Lex_cstring rolename(roles_mapping_table.role()-> + val_lex_string_strmake(&temp_root)); + bool with_grant_option= get_YN_as_bool(roles_mapping_table.admin_option()); if (add_role_user_mapping(username, hostname, rolename)) { sql_print_error("Invalid roles_mapping table entry user:'%s@%s', rolename:'%s'", - username, hostname, rolename); + username.str, hostname.str, rolename.str); continue; } @@ -3226,20 +3238,21 @@ static ACL_DB *acl_db_find(const char *db, const char *user, const char *host, c TRUE Error */ -bool acl_getroot(Security_context *sctx, const char *user, const char *host, - const char *ip, const char *db) +bool acl_getroot(Security_context *sctx, + const LEX_CSTRING &user, const LEX_CSTRING &host, + const LEX_CSTRING &ip, const LEX_CSTRING &db) { int res= 1; ACL_USER *acl_user= 0; DBUG_ENTER("acl_getroot"); DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'", - host, ip, user, db)); + host.str, ip.str, user.str, db.str)); sctx->init(); - sctx->user= *user ? user : NULL; - sctx->host= host; - sctx->ip= ip; - sctx->host_or_ip= host ? host : (safe_str(ip)); + sctx->user= *user.str ? user.str : NULL; + sctx->host= host.str; + sctx->ip= ip.str; + sctx->host_or_ip= host.str ? host.str : (safe_str(ip.str)); if (!initialized) { @@ -3254,19 +3267,19 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host, sctx->db_access= NO_ACL; - if (host[0]) // User, not Role + if (host.str[0]) // User, not Role { acl_user= find_user_wild(host, user, ip); if (acl_user) { res= 0; - if (ACL_DB *acl_db= acl_db_find(db, user, host, ip, FALSE)) + if (ACL_DB *acl_db= acl_db_find(db.str, user.str, host.str, ip.str, FALSE)) sctx->db_access= acl_db->access; sctx->master_access= acl_user->access; - strmake_buf(sctx->priv_user, user); + strmake_buf(sctx->priv_user, user.str); if (acl_user->host.hostname) strmake_buf(sctx->priv_host, acl_user->host.hostname); @@ -3278,18 +3291,18 @@ bool acl_getroot(Security_context *sctx, const char *user, const char *host, if (acl_role) { res= 0; - if (ACL_DB *acl_db= acl_db_find(db, user, "", "", FALSE)) + if (ACL_DB *acl_db= acl_db_find(db.str, user.str, "", "", FALSE)) sctx->db_access = acl_db->access; sctx->master_access= acl_role->access; - strmake_buf(sctx->priv_role, user); + strmake_buf(sctx->priv_role, user.str); } } if (acl_public) { - if (ACL_DB *acl_db= acl_db_find(db, public_name.str, "", "", FALSE)) + if (ACL_DB *acl_db= acl_db_find(db.str, public_name.str, "", "", FALSE)) sctx->db_access|= acl_db->access; sctx->master_access|= acl_public->access; @@ -3323,9 +3336,12 @@ static ACL_USER *find_user_or_anon(const char *host, const char *user, const cha } -static int check_user_can_set_role(THD *thd, const char *user, - const char *host, const char *ip, - const char *rolename, privilege_t *access) +static int check_user_can_set_role(THD *thd, + const LEX_CSTRING &user, + const LEX_CSTRING &host, + const LEX_CSTRING &ip, + const LEX_CSTRING &rolename, + privilege_t *access) { ACL_ROLE *role; ACL_USER_BASE *acl_user_base; @@ -3336,7 +3352,7 @@ static int check_user_can_set_role(THD *thd, const char *user, /* clear role privileges */ mysql_mutex_lock(&acl_cache->lock); - if (!strcasecmp(rolename, none.str)) + if (!strcasecmp(rolename.str, none.str)) { /* have to clear the privileges */ /* get the current user */ @@ -3365,7 +3381,7 @@ static int check_user_can_set_role(THD *thd, const char *user, continue; acl_user= (ACL_USER *)acl_user_base; - if (acl_user->wild_eq(user, host, ip)) + if (acl_user->wild_eq(user.str, host.str, ip.str)) { is_granted= TRUE; break; @@ -3393,19 +3409,18 @@ end: switch (result) { case ER_INVALID_CURRENT_USER: - my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename); + my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename.str); break; case ER_INVALID_ROLE: /* Role doesn't exist at all */ - my_error(ER_INVALID_ROLE, MYF(0), rolename); + my_error(ER_INVALID_ROLE, MYF(0), rolename.str); break; case 1: LEX_CSTRING role_lex; /* First, check if current user can see mysql database. */ bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); - role_lex.str= rolename; - role_lex.length= strlen(rolename); + role_lex= rolename; mysql_mutex_lock(&acl_cache->lock); ACL_USER *cur_user= find_user_or_anon(thd->security_ctx->priv_host, thd->security_ctx->priv_user, @@ -3423,19 +3438,19 @@ end: is used. In that situation host can be NULL and current user is always target user, so printing `priv_user@priv_host` is not incorrect. */ - if (!host) + if (!host.str) my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", MYF(0), thd->security_ctx->priv_user, - thd->security_ctx->priv_host, rolename); + thd->security_ctx->priv_host, rolename.str); else /* Role is not granted but current user can see the role */ my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s", - MYF(0), user, host, rolename); + MYF(0), user.str, host.str, rolename.str); } else { /* Role is not granted and current user cannot see the role */ - my_error(ER_INVALID_ROLE, MYF(0), rolename); + my_error(ER_INVALID_ROLE, MYF(0), rolename.str); } mysql_mutex_unlock(&acl_cache->lock); break; @@ -3445,7 +3460,9 @@ end: } -int acl_check_setrole(THD *thd, const char *rolename, privilege_t *access) +int acl_check_setrole(THD *thd, + const LEX_CSTRING &rolename, + privilege_t *access) { if (!initialized) { @@ -3453,24 +3470,27 @@ int acl_check_setrole(THD *thd, const char *rolename, privilege_t *access) return 1; } - return check_user_can_set_role(thd, thd->security_ctx->priv_user, - thd->security_ctx->host, thd->security_ctx->ip, rolename, access); + return check_user_can_set_role(thd, + Lex_cstring_strlen(thd->security_ctx->priv_user), + Lex_cstring_strlen(thd->security_ctx->host), + Lex_cstring_strlen(thd->security_ctx->ip), + rolename, access); } -int acl_setrole(THD *thd, const char *rolename, privilege_t access) +int acl_setrole(THD *thd, const LEX_CSTRING &rolename, privilege_t access) { /* merge the privileges */ Security_context *sctx= thd->security_ctx; sctx->master_access= access; - if (!strcasecmp(rolename, none.str)) + if (!strcasecmp(rolename.str, none.str)) { thd->security_ctx->priv_role[0]= 0; } else { /* mark the current role */ - strmake_buf(thd->security_ctx->priv_role, rolename); + strmake_buf(thd->security_ctx->priv_role, rolename.str); } if (thd->db.str) sctx->db_access= acl_get_all3(sctx, thd->db.str, FALSE); @@ -3486,13 +3506,15 @@ static uchar* check_get_key(ACL_USER *buff, size_t *length, } -static void acl_update_role(const char *rolename, const privilege_t privileges) +static void acl_update_role(const LEX_CSTRING &rolename, + const privilege_t privileges) { ACL_ROLE *role= find_acl_role(rolename, true); if (role) { role->initial_role_access= role->access= privileges; - DBUG_ASSERT(strcasecmp(rolename, public_name.str) || acl_public == role); + DBUG_ASSERT(strcasecmp(rolename.str, public_name.str) || + acl_public == role); } } @@ -3615,22 +3637,23 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth, } -static void acl_insert_role(const char *rolename, privilege_t privileges) +static void acl_insert_role(const LEX_CSTRING &rolename, privilege_t privileges) { ACL_ROLE *entry; DBUG_ENTER("acl_insert_role"); - DBUG_PRINT("enter", ("Role: '%s'", rolename)); + DBUG_PRINT("enter", ("Role: '%s'", rolename.str)); mysql_mutex_assert_owner(&acl_cache->lock); - entry= new (&acl_memroot) ACL_ROLE(rolename, privileges, &acl_memroot); + entry= new (&acl_memroot) ACL_ROLE(rolename.str, privileges, &acl_memroot); my_init_dynamic_array(key_memory_acl_mem, &entry->parent_grantee, sizeof(ACL_USER_BASE *), 0, 8, MYF(0)); my_init_dynamic_array(key_memory_acl_mem, &entry->role_grants, sizeof(ACL_ROLE *), 0, 8, MYF(0)); my_hash_insert(&acl_roles, (uchar *)entry); - DBUG_ASSERT(strcasecmp(rolename, public_name.str) || is_public(rolename)); - if (is_public(rolename)) + DBUG_ASSERT(strcasecmp(rolename.str, public_name.str) || + is_public(&rolename)); + if (is_public(&rolename)) acl_public= entry; DBUG_VOID_RETURN; @@ -3761,7 +3784,7 @@ privilege_t acl_get(const char *host, const char *ip, goto exit; // Fully specified. Take it /* the host table is not used for roles */ if ((!host || !host[0]) && !acl_db->host.hostname && - find_acl_role(user, false)) + find_acl_role(Lex_cstring_strlen(user), false)) goto exit; } @@ -3833,7 +3856,8 @@ static void init_check_host(void) (void) my_init_dynamic_array(key_memory_acl_mem, &acl_wild_hosts, sizeof(struct acl_host_and_ip), acl_users.elements, 1, MYF(0)); - (void) my_hash_init(key_memory_acl_mem, &acl_check_hosts,system_charset_info, + (void) my_hash_init(key_memory_acl_mem, &acl_check_hosts, + Lex_ident_host::charset_info(), acl_users.elements, 0, 0, (my_hash_get_key) check_get_key, 0, 0); if (!allow_all_hosts) @@ -3841,6 +3865,7 @@ static void init_check_host(void) for (size_t i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); + const Lex_ident_host acl_user_hostname(acl_user->hostname()); if (strchr(acl_user->host.hostname,wild_many) || strchr(acl_user->host.hostname,wild_one) || acl_user->host.ip_mask) @@ -3850,8 +3875,7 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(system_charset_info, - acl_user->host.hostname, acl->hostname)) + if (acl_user_hostname.streq(Lex_cstring_strlen(acl->hostname))) break; // already stored } if (j == acl_wild_hosts.elements) // If new @@ -3936,8 +3960,9 @@ static void undo_add_role_user_mapping(ACL_USER_BASE *grantee, ACL_ROLE *role) this happens either on initial loading of data from tables, in acl_load(). or in rebuild_role_grants after acl_role_reset_role_arrays(). */ -static bool add_role_user_mapping(const char *uname, const char *hname, - const char *rname) +static bool add_role_user_mapping(const LEX_CSTRING &uname, + const LEX_CSTRING &hname, + const LEX_CSTRING &rname) { ACL_USER_BASE *grantee= find_acl_user_base(uname, hname); ACL_ROLE *role= find_acl_role(rname, false); @@ -4071,7 +4096,9 @@ bool acl_check_host(const char *host, const char *ip) @retval 1 Error */ -static int check_alter_user(THD *thd, const char *host, const char *user) +static int check_alter_user(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user) { int error = 1; if (!initialized) @@ -4089,7 +4116,7 @@ static int check_alter_user(THD *thd, const char *host, const char *user) MYF(0)); goto end; } - if (!host) // Role + if (!host.str) // Role { my_error(ER_PASSWORD_NO_MATCH, MYF(0)); goto end; @@ -4129,7 +4156,7 @@ bool check_change_password(THD *thd, LEX_USER *user) LEX_USER *real_user= get_current_user(thd, user); user->user= real_user->user; user->host= real_user->host; - return check_alter_user(thd, user->host.str, user->user.str); + return check_alter_user(thd, user->host, user->user); } @@ -4178,7 +4205,7 @@ bool change_password(THD *thd, LEX_USER *user) acl_cache_is_locked= 1; mysql_mutex_lock(&acl_cache->lock); - if (!(acl_user= find_user_exact(user->host.str, user->user.str))) + if (!(acl_user= find_user_exact(user->host, user->user))) { my_error(ER_PASSWORD_NO_MATCH, MYF(0)); goto end; @@ -4221,7 +4248,7 @@ bool change_password(THD *thd, LEX_USER *user) /* If user is the connected user, reset the password expired field on sctx and allow the user to exit sandbox mode */ - if (thd->security_ctx->is_priv_user(user->user.str, user->host.str)) + if (thd->security_ctx->is_priv_user(user->user, user->host)) thd->security_ctx->password_expired= false; if (update_user_table_password(thd, tables.user_table(), *acl_user)) @@ -4257,8 +4284,10 @@ wsrep_error_label: DBUG_RETURN(result); } -int acl_check_set_default_role(THD *thd, const char *host, const char *user, - const char *role) +int acl_check_set_default_role(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &role) { DBUG_ENTER("acl_check_set_default_role"); #ifdef HAVE_REPLICATION @@ -4273,11 +4302,14 @@ int acl_check_set_default_role(THD *thd, const char *host, const char *user, DBUG_RETURN(0); #endif DBUG_RETURN(check_alter_user(thd, host, user) || - check_user_can_set_role(thd, user, host, NULL, role, NULL)); + check_user_can_set_role(thd, user, host, + null_clex_str, role, NULL)); } -int acl_set_default_role(THD *thd, const char *host, const char *user, - const char *rolename) +int acl_set_default_role(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &rolename) { Grant_tables tables; char user_key[MAX_KEY_LENGTH]; @@ -4291,9 +4323,9 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, DBUG_ENTER("acl_set_default_role"); DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'", - user, safe_str(host), safe_str(rolename))); + user.str, safe_str(host.str), safe_str(rolename.str))); - if (!strcasecmp(rolename, none.str)) + if (!strcasecmp(rolename.str, none.str)) clear_role= TRUE; if (mysql_bin_log.is_open() || @@ -4301,7 +4333,7 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, { query_length= sprintf(buff,"SET DEFAULT ROLE '%-.120s' FOR '%-.120s'@'%-.120s'", - safe_str(rolename), user, safe_str(host)); + safe_str(rolename.str), user.str, safe_str(host.str)); } /* @@ -4346,8 +4378,9 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, if (!clear_role) { /* set new default_rolename */ - acl_user->default_rolename.str= safe_strdup_root(&acl_memroot, rolename); - acl_user->default_rolename.length= strlen(rolename); + acl_user->default_rolename.str= safe_strdup_root(&acl_memroot, + rolename.str); + acl_user->default_rolename.length= rolename.length; } else { @@ -4358,8 +4391,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, /* update the mysql.user table with the new default role */ tables.user_table().table()->use_all_columns(); - user_table.set_host(host, strlen(host)); - user_table.set_user(user, strlen(user)); + user_table.set_host(host.str, host.length); + user_table.set_user(user.str, user.length); key_copy((uchar *) user_key, table->record[0], table->key_info, table->key_info->key_length); @@ -4425,7 +4458,7 @@ wsrep_error_label: TRUE there is such definer */ -bool is_acl_user(const char *host, const char *user) +bool is_acl_user(const LEX_CSTRING &host, const LEX_CSTRING &user) { bool res; @@ -4435,7 +4468,7 @@ bool is_acl_user(const char *host, const char *user) mysql_mutex_lock(&acl_cache->lock); - if (*host) // User + if (*host.str) // User res= find_user_exact(host, user) != NULL; else // Role res= find_acl_role(user, false) != NULL; @@ -4448,18 +4481,19 @@ bool is_acl_user(const char *host, const char *user) /* Find first entry that matches the specified user@host pair */ -static ACL_USER *find_user_exact(const char *host, const char *user) +static ACL_USER *find_user_exact(const LEX_CSTRING &host, + const LEX_CSTRING &user) { mysql_mutex_assert_owner(&acl_cache->lock); - size_t start= acl_find_user_by_name(user); + size_t start= acl_find_user_by_name(user.str); for (size_t i= start; i < acl_users.elements; i++) { ACL_USER *acl_user= dynamic_element(&acl_users, i, ACL_USER*); - if (i > start && strcmp(acl_user->user.str, user)) + if (i > start && strcmp(acl_user->user.str, user.str)) return 0; - if (!my_strcasecmp(system_charset_info, acl_user->host.hostname, host)) + if (Lex_ident_host(host).streq(acl_user->hostname())) return acl_user; } return 0; @@ -4468,18 +4502,20 @@ static ACL_USER *find_user_exact(const char *host, const char *user) /* Find first entry that matches the specified user@host pair */ -static ACL_USER * find_user_wild(const char *host, const char *user, const char *ip) +static ACL_USER * find_user_wild(const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &ip) { mysql_mutex_assert_owner(&acl_cache->lock); - size_t start = acl_find_user_by_name(user); + size_t start = acl_find_user_by_name(user.str); for (size_t i= start; i < acl_users.elements; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); - if (i > start && strcmp(acl_user->user.str, user)) + if (i > start && strcmp(acl_user->user.str, user.str)) break; - if (compare_hostname(&acl_user->host, host, ip ? ip : host)) + if (compare_hostname(&acl_user->host, host.str, ip.str ? ip.str : host.str)) return acl_user; } return 0; @@ -4488,28 +4524,31 @@ static ACL_USER * find_user_wild(const char *host, const char *user, const char /* Find a role with the specified name */ -static ACL_ROLE *find_acl_role(const char *role, bool allow_public) +static ACL_ROLE *find_acl_role(const LEX_CSTRING &role, bool allow_public) { - size_t length= strlen(role); DBUG_ENTER("find_acl_role"); - DBUG_PRINT("enter",("role: '%s'", role)); + DBUG_PRINT("enter",("role: '%s'", role.str)); DBUG_PRINT("info", ("Hash elements: %ld", acl_roles.records)); mysql_mutex_assert_owner(&acl_cache->lock); - if (!length || (!allow_public && strcasecmp(role, public_name.str) == 0)) + if (!role.length || + (!allow_public && + my_charset_utf8mb3_general1400_as_ci.streq(role, public_name))) DBUG_RETURN(NULL); - ACL_ROLE *r= (ACL_ROLE *)my_hash_search(&acl_roles, (uchar *)role, length); + ACL_ROLE *r= (ACL_ROLE *)my_hash_search(&acl_roles, (uchar *)role.str, + role.length); DBUG_RETURN(r); } /* Finds a grantee - something that privileges or roles can be granted to. */ -static ACL_USER_BASE *find_acl_user_base(const char *user, const char *host) +static ACL_USER_BASE *find_acl_user_base(const LEX_CSTRING &user, + const LEX_CSTRING &host) { - if (*host) + if (*host.str) return find_user_exact(host, user); return find_acl_role(user, true); @@ -4607,14 +4646,9 @@ bool hostname_requires_resolving(const char *hostname) /* Check if hostname is the localhost. */ - size_t hostname_len= strlen(hostname); - size_t localhost_len= strlen(my_localhost); - if (hostname == my_localhost || - (hostname_len == localhost_len && - !system_charset_info->strnncoll( - (const uchar *) hostname, hostname_len, - (const uchar *) my_localhost, strlen(my_localhost)))) + Lex_ident_host(Lex_cstring_strlen(hostname)). + streq(Lex_cstring_strlen(my_localhost))) { return FALSE; } @@ -4854,7 +4888,7 @@ static int replace_user_table(THD *thd, const User_table &user_table, } else { - old_acl_user= find_user_exact(combo->host.str, combo->user.str); + old_acl_user= find_user_exact(combo->host, combo->user); if ((old_acl_user != NULL) != old_row_exists) { my_error(ER_PASSWORD_NO_MATCH, MYF(0)); @@ -4971,9 +5005,9 @@ end: if (handle_as_role) { if (old_row_exists) - acl_update_role(combo->user.str, rights); + acl_update_role(combo->user, rights); else - acl_insert_role(combo->user.str, rights); + acl_insert_role(combo->user, rights); } else { @@ -5017,10 +5051,10 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_ENTER("replace_db_table"); /* Check if there is such a user in user table in memory? */ - if (!find_user_wild(combo.host.str,combo.user.str)) + if (!find_user_wild(combo.host, combo.user)) { /* The user could be a role, check if the user is registered as a role */ - if (!combo.host.length && !find_acl_role(combo.user.str, true)) + if (!combo.host.length && !find_acl_role(combo.user, true)) { my_message(ER_PASSWORD_NO_MATCH, ER_THD(table->in_use, ER_PASSWORD_NO_MATCH), MYF(0)); @@ -5240,8 +5274,7 @@ update_role_mapping(LEX_CSTRING *user, LEX_CSTRING *host, LEX_CSTRING *role, mysql_mutex_assert_owner(&acl_cache->lock); /* allocate a new entry that will go in the hash */ ROLE_GRANT_PAIR *hash_entry= new (&acl_memroot) ROLE_GRANT_PAIR; - if (hash_entry->init(&acl_memroot, user->str, host->str, - role->str, with_admin)) + if (hash_entry->init(&acl_memroot, *user, *host, *role, with_admin)) return 1; return my_hash_insert(&acl_roles_mappings, (uchar*) hash_entry); } @@ -5311,7 +5344,7 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, } /* Check if there is such a user in user table in memory? */ - if (!find_user_wild(user->host.str,user->user.str)) + if (!find_user_wild(user->host, user->user)) { my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH), MYF(0)); @@ -5478,7 +5511,8 @@ public: bool ok() { return privs != NO_ACL || cols != NO_ACL; } void init_hash() { - my_hash_init2(key_memory_acl_memex, &hash_columns, 4, system_charset_info, + my_hash_init2(key_memory_acl_memex, &hash_columns, 4, + Lex_ident_column::charset_info(), 0, 0, 0, (my_hash_get_key) get_key_column, 0, 0, 0); } }; @@ -5547,7 +5581,7 @@ GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine) const char *hostname= get_field(&grant_memroot, form->field[0]); mysql_mutex_lock(&acl_cache->lock); - if (!hostname && find_acl_role(user, true)) + if (!hostname && find_acl_role(Lex_cstring_strlen(user), true)) hostname= ""; mysql_mutex_unlock(&acl_cache->lock); update_hostname(&host, hostname); @@ -5718,8 +5752,8 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, { if (!grant_name->host.hostname || (host && - !my_strcasecmp(system_charset_info, host, - grant_name->host.hostname)) || + Lex_ident_host(Lex_cstring_strlen(host)). + streq(Lex_cstring_strlen(grant_name->host.hostname))) || (ip && !strcmp(ip, grant_name->host.hostname))) return grant_name; } @@ -5759,11 +5793,12 @@ static bool column_priv_insert(GRANT_TABLE *grant) } static GRANT_COLUMN * -column_hash_search(GRANT_TABLE *t, const char *cname, size_t length) +column_hash_search(GRANT_TABLE *t, const LEX_CSTRING &cname) { if (!my_hash_inited(&t->hash_columns)) return (GRANT_COLUMN*) 0; - return (GRANT_COLUMN*)my_hash_search(&t->hash_columns, (uchar*)cname, length); + return (GRANT_COLUMN*)my_hash_search(&t->hash_columns, + (uchar*)cname.str, cname.length); } @@ -5870,8 +5905,7 @@ static int replace_column_table(GRANT_TABLE *g_t, } else error= 0; - grant_column= column_hash_search(g_t, column->column.ptr(), - column->column.length()); + grant_column= column_hash_search(g_t, column->column.to_lex_cstring()); if (grant_column) // Should always be true { grant_column->rights= privileges; // Update hash @@ -5930,9 +5964,7 @@ static int replace_column_table(GRANT_TABLE *g_t, table->field[6]->store((longlong) get_rights_for_column(privileges), TRUE); table->field[4]->val_str(&column_name); - grant_column = column_hash_search(g_t, - column_name.ptr(), - column_name.length()); + grant_column = column_hash_search(g_t, column_name.to_lex_cstring()); if (privileges) { int tmp_error; @@ -6018,9 +6050,9 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, The following should always succeed as new users are created before this function is called! */ - if (!find_user_wild(combo.host.str,combo.user.str)) + if (!find_user_wild(combo.host, combo.user)) { - if (!combo.host.length && !find_acl_role(combo.user.str, true)) + if (!combo.host.length && !find_acl_role(combo.user, true)) { my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH), MYF(0)); /* purecov: deadcode */ @@ -7179,10 +7211,10 @@ static bool copy_and_check_auth(LEX_USER *to, LEX_USER *from, THD *thd) to->auth= from->auth; // if changing auth for an existing user - if (has_auth(to, thd->lex) && find_user_exact(to->host.str, to->user.str)) + if (has_auth(to, thd->lex) && find_user_exact(to->host, to->user)) { mysql_mutex_unlock(&acl_cache->lock); - bool res= check_alter_user(thd, to->host.str, to->user.str); + bool res= check_alter_user(thd, to->host, to->user); mysql_mutex_lock(&acl_cache->lock); return res; } @@ -7218,7 +7250,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, List_iterator str_list (user_list); LEX_USER *Str, *tmp_Str; bool create_new_users=0; - const char *db_name, *table_name; + Lex_ident_db db_name; + Lex_ident_table table_name; DBUG_ENTER("mysql_table_grant"); if (rights & ~TABLE_ACLS) @@ -7243,8 +7276,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { field_index_t unused_field_idx= NO_CACHED_FIELD_INDEX; TABLE_LIST *dummy; - Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(), - column->column.length(), + Field *f=find_field_in_table_ref(thd, table_list, + Lex_ident_column(column->column.to_lex_cstring()), column->column.ptr(), NULL, NULL, ignored_tables_list_t(NULL), NULL, TRUE, FALSE, &unused_field_idx, FALSE, @@ -7349,8 +7382,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, table_name= table_list->get_table_name(); /* Find/create cached table grant */ - grant_table= table_hash_search(Str->host.str, NullS, db_name, - Str->user.str, table_name, 1); + grant_table= table_hash_search(Str->host.str, NullS, db_name.str, + Str->user.str, table_name.str, 1); if (!grant_table) { if (revoke_grant) @@ -7360,8 +7393,10 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, result= TRUE; continue; } - grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, db_name, - Str->user.str, table_name, + grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, + db_name.str, + Str->user.str, + table_name.str, rights, column_priv); if (!grant_table || @@ -7383,8 +7418,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, while ((column = column_iter++)) { grant_column = column_hash_search(grant_table, - column->column.ptr(), - column->column.length()); + column->column.to_lex_cstring()); if (grant_column) { grant_column->init_rights&= ~(column->rights | rights); @@ -7418,13 +7452,14 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* TODO(cvicentiu) refactor replace_column_table to use Columns_priv_table instead of TABLE directly. */ if (replace_column_table(grant_table, tables.columns_priv_table().table(), - *Str, columns, db_name, table_name, rights, + *Str, columns, + db_name.str, table_name.str, rights, revoke_grant)) result= TRUE; } if ((res= replace_table_table(thd, grant_table, tables.tables_priv_table().table(), - *Str, db_name, table_name, + *Str, db_name.str, table_name.str, rights, column_priv, revoke_grant))) { if (res > 0) @@ -7434,8 +7469,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } } if (Str->is_role()) - propagate_role_grants(find_acl_role(Str->user.str, true), - PRIVS_TO_MERGE::TABLE_COLUMN, db_name, table_name); + propagate_role_grants(find_acl_role(Str->user, true), + PRIVS_TO_MERGE::TABLE_COLUMN, + db_name.str, table_name.str); } thd->mem_root= old_root; @@ -7561,7 +7597,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, continue; } if (Str->is_role()) - propagate_role_grants(find_acl_role(Str->user.str, true), + propagate_role_grants(find_acl_role(Str->user, true), sp_privs_to_merge(sph->type()), db_name, table_name); } @@ -7655,7 +7691,8 @@ static bool can_grant_role(THD *thd, ACL_ROLE *role) if (!sctx->user) // replication return true; - ACL_USER *grantee= find_user_exact(sctx->priv_host, sctx->priv_user); + ACL_USER *grantee= find_user_exact(Lex_cstring_strlen(sctx->priv_host), + Lex_cstring_strlen(sctx->priv_user)); if (!grantee) return false; @@ -7698,7 +7735,7 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); - if (!(role= find_acl_role(rolename.str, false))) + if (!(role= find_acl_role(rolename, false))) { mysql_mutex_unlock(&acl_cache->lock); mysql_rwlock_unlock(&LOCK_grant); @@ -7729,10 +7766,9 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) result= 1; continue; } - if (!(role_as_user= find_acl_role(thd->security_ctx->priv_role, true))) + const Lex_cstring_strlen ls(thd->security_ctx->priv_role); + if (!(role_as_user= find_acl_role(ls, true))) { - LEX_CSTRING ls= { thd->security_ctx->priv_role, - strlen(thd->security_ctx->priv_role) }; append_user(thd, &wrong_users, &ls, &empty_clex_str); result= 1; continue; @@ -7771,7 +7807,7 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) role_as_user= acl_public; break; case ROLE_NAME_OK: - if ((role_as_user= find_acl_role(user->user.str, false))) + if ((role_as_user= find_acl_role(user->user, false))) hostname= empty_clex_str; else hostname= host_not_specified; @@ -7787,7 +7823,7 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) if (has_auth(user, thd->lex)) DBUG_ASSERT(!grantee); else if (!grantee && !is_public(user)) - grantee= find_user_exact(hostname.str, username.str); + grantee= find_user_exact(hostname, username); if (!grantee && !revoke) { @@ -7805,7 +7841,7 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) continue; } if (!is_public(&user_combo)) - grantee= find_user_exact(hostname.str, username.str); + grantee= find_user_exact(hostname, username); else grantee= role_as_user= acl_public; @@ -8001,7 +8037,7 @@ bool mysql_grant(THD *thd, LEX_CSTRING db, List &list, result= true; } if (Str->is_role()) - propagate_role_grants(find_acl_role(Str->user.str, true), + propagate_role_grants(find_acl_role(Str->user, true), db.str ? PRIVS_TO_MERGE::DB : PRIVS_TO_MERGE::GLOBAL, db.str); @@ -8421,8 +8457,8 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, const ACL_internal_table_access *access= get_cached_table_access(&t_ref->grant.m_internal, - t_ref->get_db_name(), - t_ref->get_table_name()); + t_ref->get_db_name().str, + t_ref->get_table_name().str); if (access) { @@ -8487,7 +8523,8 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, mysql_rwlock_rdlock(&LOCK_grant); } - t_ref->grant.read(sctx, t_ref->get_db_name(), t_ref->get_table_name()); + t_ref->grant.read(sctx, t_ref->get_db_name().str, + t_ref->get_table_name().str); if (!t_ref->grant.grant_table_user && !t_ref->grant.grant_table_role && @@ -8532,21 +8569,22 @@ err: command, sctx->priv_user, sctx->host_or_ip, tl ? tl->db.str : "unknown", - tl ? tl->get_table_name() : "unknown"); + tl ? tl->get_table_name().str : "unknown"); } DBUG_RETURN(TRUE); } -static void check_grant_column_int(GRANT_TABLE *grant_table, const char *name, - uint length, privilege_t *want_access) +static void check_grant_column_int(GRANT_TABLE *grant_table, + const Lex_ident_column &name, + privilege_t *want_access) { if (grant_table) { *want_access&= ~grant_table->privs; if (*want_access & grant_table->cols) { - GRANT_COLUMN *grant_column= column_hash_search(grant_table, name, length); + GRANT_COLUMN *grant_column= column_hash_search(grant_table, name); if (grant_column) *want_access&= ~grant_column->rights; } @@ -8604,7 +8642,6 @@ void GRANT_INFO::read(const Security_context *sctx, db_name db name table_name table name name column name - length column name length sctx security context RETURN @@ -8613,8 +8650,9 @@ void GRANT_INFO::read(const Security_context *sctx, */ bool check_grant_column(THD *thd, GRANT_INFO *grant, - const char *db_name, const char *table_name, - const char *name, size_t length, Security_context *sctx) + const char *db_name, const char *table_name, + const Lex_ident_column &column_name, + Security_context *sctx) { privilege_t want_access(grant->want_privilege & ~grant->privilege); DBUG_ENTER("check_grant_column"); @@ -8629,12 +8667,9 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, /* reload table if someone has modified any grants */ grant->refresh(sctx, db_name, table_name); - check_grant_column_int(grant->grant_table_user, name, (uint)length, - &want_access); - check_grant_column_int(grant->grant_table_role, name, (uint)length, - &want_access); - check_grant_column_int(grant->grant_public, name, (uint)length, - &want_access); + check_grant_column_int(grant->grant_table_user, column_name, &want_access); + check_grant_column_int(grant->grant_table_role, column_name, &want_access); + check_grant_column_int(grant->grant_public, column_name, &want_access); mysql_rwlock_unlock(&LOCK_grant); if (!want_access) @@ -8644,7 +8679,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, get_privilege_desc(command, sizeof(command), want_access); /* TODO perhaps error should print current rolename aswell */ my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), command, sctx->priv_user, - sctx->host_or_ip, name, table_name); + sctx->host_or_ip, column_name.str, table_name); DBUG_RETURN(1); } @@ -8674,7 +8709,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, */ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, - const char *name, size_t length, + const Lex_ident_column &name, Field *fld) { GRANT_INFO *grant; @@ -8717,8 +8752,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, } if (grant->want_privilege) - return check_grant_column(thd, grant, db_name, table_name, name, - length, sctx); + return check_grant_column(thd, grant, db_name, table_name, name, sctx); else return FALSE; @@ -8764,12 +8798,11 @@ bool check_grant_all_columns(THD *thd, privilege_t want_access_arg, if (fields->field() && fields->field()->invisible >= INVISIBLE_SYSTEM) continue; - LEX_CSTRING *field_name= fields->name(); - if (table_name != fields->get_table_name()) + if (table_name != fields->get_table_name().str) { - table_name= fields->get_table_name(); - db_name= fields->get_db_name(); + table_name= fields->get_table_name().str; + db_name= fields->get_db_name().str; grant= fields->grant(); /* get a fresh one for each table */ want_access= want_access_arg & ~grant->privilege; @@ -8792,23 +8825,21 @@ bool check_grant_all_columns(THD *thd, privilege_t want_access_arg, if (grant_table) { GRANT_COLUMN *grant_column= - column_hash_search(grant_table, field_name->str, field_name->length); + column_hash_search(grant_table, fields->name()); if (grant_column) have_access= grant_column->rights; } if (grant_table_role) { GRANT_COLUMN *grant_column= - column_hash_search(grant_table_role, field_name->str, - field_name->length); + column_hash_search(grant_table_role, fields->name()); if (grant_column) have_access|= grant_column->rights; } if (grant_public) { GRANT_COLUMN *grant_column= - column_hash_search(grant_public, field_name->str, - field_name->length); + column_hash_search(grant_public, fields->name()); if (grant_column) have_access|= grant_column->rights; @@ -8841,7 +8872,7 @@ err: command, sctx->priv_user, sctx->host_or_ip, - fields->name()->str, + fields->name().str, table_name); return 1; } @@ -9104,7 +9135,7 @@ privilege_t get_table_grant(THD *thd, TABLE_LIST *table) privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, - const char *field_name) + const Lex_ident_column &field_name) { GRANT_TABLE *grant_table; GRANT_TABLE *grant_table_role; @@ -9126,8 +9157,7 @@ privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, { if (grant_table) { - grant_column= column_hash_search(grant_table, field_name, - (uint) strlen(field_name)); + grant_column= column_hash_search(grant_table, field_name); if (!grant_column) priv= (grant->privilege | grant_table->privs); else @@ -9136,8 +9166,7 @@ privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, if (grant_table_role) { - grant_column= column_hash_search(grant_table_role, field_name, - (uint) strlen(field_name)); + grant_column= column_hash_search(grant_table_role, field_name); if (!grant_column) priv|= (grant->privilege | grant_table_role->privs); else @@ -9146,8 +9175,7 @@ privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, } if (grant_public) { - grant_column= column_hash_search(grant_public, field_name, - (uint) strlen(field_name)); + grant_column= column_hash_search(grant_public, field_name); if (!grant_column) priv|= (grant->privilege | grant_public->privs); else @@ -9402,7 +9430,8 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user) mysql_rwlock_rdlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); - acl_user= find_user_exact(hostname, username); + acl_user= find_user_exact(Lex_cstring_strlen(hostname), + Lex_cstring_strlen(username)); // User not found in the internal data structures. if (!acl_user) @@ -9580,7 +9609,8 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) if (username) { - acl_user= find_user_exact(hostname, username); + acl_user= find_user_exact(Lex_cstring_strlen(hostname), + Lex_cstring_strlen(username)); if (!acl_user) { mysql_mutex_unlock(&acl_cache->lock); @@ -9629,7 +9659,7 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) if (rolename) { - acl_role= find_acl_role(rolename, true); + acl_role= find_acl_role(Lex_cstring_strlen(rolename), true); if (acl_role) { /* get a list of all inherited roles */ @@ -9864,7 +9894,8 @@ static bool show_database_privileges(THD *thd, const char *username, */ if (!strcmp(username, user) && - !my_strcasecmp(system_charset_info, hostname, host)) + Lex_ident_host(Lex_cstring_strlen(hostname)). + streq(Lex_cstring_strlen(host))) { /* do not print inherited access bits for roles, @@ -9943,7 +9974,8 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, */ if (!strcmp(username,user) && - !my_strcasecmp(system_charset_info, hostname, host)) + Lex_ident_host(Lex_cstring_strlen(hostname)). + streq(Lex_cstring_strlen(host))) { privilege_t table_access(NO_ACL); privilege_t cols_access(NO_ACL); @@ -10074,7 +10106,8 @@ static int show_routine_grants(THD* thd, const char *username, */ if (!strcmp(username, user) && - !my_strcasecmp(system_charset_info, hostname, host)) + Lex_ident_host(Lex_cstring_strlen(hostname)). + streq(Lex_cstring_strlen(host))) { privilege_t proc_access(NO_ACL); if (*hostname) // User @@ -10171,7 +10204,8 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc) mysql_mutex_lock(&acl_cache->lock); - if (initialized && (acl_user= find_user_wild(host,user))) + if (initialized && (acl_user= find_user_wild(Lex_cstring_strlen(host), + Lex_cstring_strlen(user)))) uc->user_resources= acl_user->user_resource; else bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); @@ -10246,8 +10280,6 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, int error; int result= 0; - THD *thd= table->in_use; - const char *host, *user, *role; Field *host_field= table->field[0]; Field *user_field= table->field[1]; Field *role_field= table->field[2]; @@ -10269,19 +10301,20 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, continue; } - host= safe_str(get_field(thd->mem_root, host_field)); - user= safe_str(get_field(thd->mem_root, user_field)); + StringBuffer host_buff; + StringBuffer user_buff; - if (!(strcmp(user_from->user.str, user) || - my_strcasecmp(system_charset_info, user_from->host.str, host))) + if (user_field->val_lex_cstring(&user_buff).bin_eq(user_from->user) && + Lex_ident_host::streq(host_field->val_lex_cstring(&host_buff), + user_from->host)) result= ((drop || user_to) && modify_grant_table(table, host_field, user_field, user_to)) ? -1 : result ? result : 1; /* Error or keep result or found. */ else { - role= safe_str(get_field(thd->mem_root, role_field)); - - if (!user_from->is_role() || strcmp(user_from->user.str, role)) + StringBuffer role_buff; + if (!user_from->is_role() || + !role_field->val_lex_cstring(&role_buff).bin_eq(user_from->user)) continue; error= 0; @@ -10350,10 +10383,6 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, Field *host_field= table->field[0]; Field *user_field= table->field[which_table == USER_TABLE || which_table == PROXIES_PRIV_TABLE ? 1 : 2]; - const char *host_str= user_from->host.str; - const char *user_str= user_from->user.str; - const char *host; - const char *user; uchar user_key[MAX_KEY_LENGTH]; uint key_prefix_length; DBUG_ENTER("handle_grant_table"); @@ -10377,9 +10406,10 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, by the searched record, if it exists. */ DBUG_PRINT("info",("read table: '%s' search: '%s'@'%s'", - table->s->table_name.str, user_str, host_str)); - host_field->store(host_str, user_from->host.length, system_charset_info); - user_field->store(user_str, user_from->user.length, system_charset_info); + table->s->table_name.str, + user_from->user.str, user_from->host.str)); + host_field->store(user_from->host, system_charset_info); + user_field->store(user_from->user, system_charset_info); key_prefix_length= (table->key_info->key_part[0].store_length + table->key_info->key_part[1].store_length); @@ -10388,7 +10418,7 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, error= table->file->ha_index_read_idx_map(table->record[0], 0, user_key, (key_part_map)3, HA_READ_KEY_EXACT); - if (!unlikely(error) && !*host_str) + if (!unlikely(error) && !*user_from->host.str) { // verify that we got a role or a user, as needed if (static_cast(grant_table).get_is_role() != @@ -10425,7 +10455,9 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, { #ifdef EXTRA_DEBUG DBUG_PRINT("info",("scan table: '%s' search: '%s'@'%s'", - table->s->table_name.str, user_str, host_str)); + table->s->table_name.str, + user_from->user.str, + user_from->host.str)); #endif while ((error= table->file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE) @@ -10436,8 +10468,6 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, DBUG_PRINT("info",("scan error: %d", error)); continue; } - host= safe_str(get_field(thd->mem_root, host_field)); - user= safe_str(get_field(thd->mem_root, user_field)); #ifdef EXTRA_DEBUG if (which_table != PROXIES_PRIV_TABLE) @@ -10450,8 +10480,10 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, table->field[4]) /*column*/)); } #endif - if (strcmp(user_str, user) || - my_strcasecmp(system_charset_info, host_str, host)) + StringBuffer user_buff, host_buff; + if (!user_field->val_lex_cstring(&user_buff).bin_eq(user_from->user) || + !Lex_ident_host::streq(host_field->val_lex_cstring(&host_buff), + user_from->host)) continue; /* If requested, delete or update the record. */ @@ -10522,7 +10554,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, if (struct_no == ROLE_ACL) //no need to scan the structures in this case { - acl_role= find_acl_role(user_from->user.str, true); + acl_role= find_acl_role(user_from->user, true); if (!acl_role) DBUG_RETURN(0); @@ -10656,8 +10688,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, case ROLES_MAPPINGS_HASH: role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx); - user= role_grant_pair->u_uname; - host= role_grant_pair->u_hname; + user= role_grant_pair->u_uname.str; + host= role_grant_pair->u_hname.str; break; default: @@ -10673,7 +10705,7 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, if (struct_no == ROLES_MAPPINGS_HASH) { - const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: ""; + const char* role= safe_str(role_grant_pair->r_uname.str); if (user_from->is_role()) { /* When searching for roles within the ROLES_MAPPINGS_HASH, we have @@ -10695,14 +10727,14 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, else { if (strcmp(user_from->user.str, user) || - my_strcasecmp(system_charset_info, user_from->host.str, host)) + !Lex_ident_host(user_from->host).streq(Lex_cstring_strlen(host))) continue; } } else { if (strcmp(user_from->user.str, user) || - my_strcasecmp(system_charset_info, user_from->host.str, host)) + !Lex_ident_host(user_from->host).streq(Lex_cstring_strlen(host))) continue; } @@ -10804,12 +10836,13 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, bool oom; if (user_to->is_role()) - oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname, + oom= role_grant_pair->init(&acl_memroot, + role_grant_pair->u_uname, role_grant_pair->u_hname, - user_to->user.str, false); + user_to->user, false); else - oom= role_grant_pair->init(&acl_memroot, user_to->user.str, - user_to->host.str, + oom= role_grant_pair->init(&acl_memroot, user_to->user, + user_to->host, role_grant_pair->r_uname, false); if (oom) DBUG_RETURN(-1); @@ -10880,10 +10913,10 @@ static int handle_grant_data(THD *thd, Grant_tables& tables, bool drop, if (search_only) { /* quickly search in-memory structures first */ - if (handle_as_role && find_acl_role(user_from->user.str, true)) + if (handle_as_role && find_acl_role(user_from->user, true)) DBUG_RETURN(1); // found - if (!handle_as_role && find_user_exact(user_from->host.str, user_from->user.str)) + if (!handle_as_role && find_user_exact(user_from->host, user_from->user)) DBUG_RETURN(1); // found } @@ -11178,9 +11211,9 @@ bool mysql_create_user(THD *thd, List &list, bool handle_as_role) // every created role is automatically granted to its creator-admin if (handle_as_role) { - ACL_USER_BASE *grantee= find_acl_user_base(thd->lex->definer->user.str, - thd->lex->definer->host.str); - ACL_ROLE *role= find_acl_role(user_name->user.str, false); + ACL_USER_BASE *grantee= find_acl_user_base(thd->lex->definer->user, + thd->lex->definer->host); + ACL_ROLE *role= find_acl_role(user_name->user, false); /* just like with routines, views, triggers, and events we allow @@ -11595,7 +11628,7 @@ bool mysql_revoke_all(THD *thd, List &list) /* This is not a role and the user could not be found */ if (!lex_user->is_role() && - !find_user_exact(lex_user->host.str, lex_user->user.str)) + !find_user_exact(lex_user->host, lex_user->user)) { result= -1; continue; @@ -11707,11 +11740,11 @@ bool mysql_revoke_all(THD *thd, List &list) if (lex_user->is_role()) { /* this can not fail due to get_current_user already having searched for it */ - user_or_role= find_acl_role(lex_user->user.str, true); + user_or_role= find_acl_role(lex_user->user, true); } else { - user_or_role= find_user_exact(lex_user->host.str, lex_user->user.str); + user_or_role= find_user_exact(lex_user->host, lex_user->user); } /* Find every role grant pair matching the role_grants array and remove it, @@ -11850,7 +11883,9 @@ Silence_routine_definer_errors::handle_condition( < 0 Error. Error message not yet sent. */ -bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_revoke_privileges(THD *thd, + const Lex_ident_db &sp_db, + const Lex_ident_routine &sp_name, const Sp_handler *sph) { uint counter, revoked; @@ -11880,8 +11915,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, for (counter= 0, revoked= 0 ; counter < hash->records ; ) { GRANT_NAME *grant_proc= (GRANT_NAME*) my_hash_element(hash, counter); - if (!my_strcasecmp(&my_charset_utf8mb3_bin, grant_proc->db, sp_db) && - !my_strcasecmp(system_charset_info, grant_proc->tname, sp_name)) + if (sp_db.streq(Lex_cstring_strlen(grant_proc->db)) && + sp_name.streq(Lex_cstring_strlen(grant_proc->tname))) { LEX_USER lex_user; lex_user.user.str= grant_proc->user; @@ -11923,7 +11958,9 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, @retval TRUE An error occurred. Error message not yet sent. */ -bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_grant_privileges(THD *thd, + const Lex_ident_db &sp_db, + const Lex_ident_routine &sp_name, const Sp_handler *sph) { Security_context *sctx= thd->security_ctx; @@ -11935,14 +11972,15 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, Dummy_error_handler error_handler; DBUG_ENTER("sp_grant_privileges"); + Lex_cstring_strlen sctx_user(sctx->priv_user); + Lex_cstring_strlen sctx_host(sctx->priv_host); + if (!(combo=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) DBUG_RETURN(TRUE); - combo->user.str= (char *) sctx->priv_user; - mysql_mutex_lock(&acl_cache->lock); - if ((au= find_user_exact(combo->host.str= (char *) sctx->priv_host, - combo->user.str))) + + if ((au= find_user_exact(sctx_host, sctx_user))) goto found_acl; mysql_mutex_unlock(&acl_cache->lock); @@ -11954,13 +11992,11 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, bzero((char*)tables, sizeof(TABLE_LIST)); user_list.empty(); - tables->db.str= sp_db; - tables->db.length= sp_db ? strlen(sp_db) : 0; - tables->table_name.str= tables->alias.str= sp_name; - tables->table_name.length= tables->alias.length= sp_name ? strlen(sp_name) : 0; + tables->db= sp_db; + tables->table_name= tables->alias= Lex_ident_table(sp_name); - thd->make_lex_string(&combo->user, combo->user.str, strlen(combo->user.str)); - thd->make_lex_string(&combo->host, combo->host.str, strlen(combo->host.str)); + thd->make_lex_string(&combo->user, sctx_user.str, sctx_user.length); + thd->make_lex_string(&combo->host, sctx_host.str, sctx_host.length); combo->auth= NULL; @@ -12023,11 +12059,13 @@ acl_find_proxy_user(const char *user, const char *host, const char *ip, bool -acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, +acl_check_proxy_grant_access(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, bool with_grant) { DBUG_ENTER("acl_check_proxy_grant_access"); - DBUG_PRINT("info", ("user=%s host=%s with_grant=%d", user, host, + DBUG_PRINT("info", ("user=%s host=%s with_grant=%d", user.str, host.str, (int) with_grant)); if (!initialized) { @@ -12057,8 +12095,8 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, if (thd->security_ctx->is_priv_user(user, host)) { DBUG_PRINT("info", ("strcmp (%s, %s) my_casestrcmp (%s, %s) equal", - thd->security_ctx->priv_user, user, - host, thd->security_ctx->priv_host)); + thd->security_ctx->priv_user, user.str, + host.str, thd->security_ctx->priv_host)); DBUG_RETURN(FALSE); } @@ -12072,7 +12110,7 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, if (proxy->matches(thd->security_ctx->host, thd->security_ctx->user, thd->security_ctx->ip, - user) && + user.str) && proxy->get_with_grant()) { DBUG_PRINT("info", ("found")); @@ -12229,8 +12267,8 @@ bool check_grant(THD *, privilege_t, TABLE_LIST *, bool, uint, bool) { return 0; } inline privilege_t public_access() { return NO_ACL; } -privilege_t get_column_grant(THD *, GRANT_INFO *, - const char *, const char *, const char *) +privilege_t get_column_grant(THD *, GRANT_INFO *, const char *, const char *, + const Lex_ident_column &) { return ALL_KNOWN_ACL; } #endif /*NO_EMBEDDED_ACCESS_CHECKS */ @@ -12305,7 +12343,7 @@ bool Sql_cmd_grant_proxy::check_access_proxy(THD *thd, List &users) // GRANT/REVOKE PROXY has the target user as a first entry in the list if (!(user= get_current_user(thd, user)) || !user->host.str) return true; - if (acl_check_proxy_grant_access(thd, user->host.str, user->user.str, + if (acl_check_proxy_grant_access(thd, user->host, user->user, m_grant_option & GRANT_ACL)) return true; } @@ -12486,9 +12524,10 @@ bool check_role_is_granted(const char *username, const char *hostname, ACL_USER_BASE *root; mysql_mutex_lock(&acl_cache->lock); if (hostname) - root= find_user_exact(hostname, username); + root= find_user_exact(Lex_cstring_strlen(hostname), + Lex_cstring_strlen(username)); else - root= find_acl_role(username, false); + root= find_acl_role(Lex_cstring_strlen(username), false); LEX_CSTRING role_lex; role_lex.str= rolename; @@ -12516,7 +12555,9 @@ int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond) { mysql_rwlock_rdlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); - ACL_ROLE *acl_role= find_acl_role(thd->security_ctx->priv_role, false); + ACL_ROLE *acl_role= find_acl_role(Lex_cstring_strlen( + thd->security_ctx->priv_role), + false); if (acl_role) traverse_role_graph_down(acl_role, table, enabled_roles_insert, NULL); mysql_mutex_unlock(&acl_cache->lock); @@ -12546,7 +12587,8 @@ int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond) Security_context *sctx= thd->security_ctx; mysql_rwlock_rdlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); - ACL_USER *user= find_user_exact(sctx->priv_host, sctx->priv_user); + ACL_USER *user= find_user_exact(Lex_cstring_strlen(sctx->priv_host), + Lex_cstring_strlen(sctx->priv_user)); if (user) { char buff[USER_HOST_BUFF_SIZE+10]; @@ -12643,10 +12685,12 @@ class Grantee_str { char m_buff[USER_HOST_BUFF_SIZE + 6 /* 4 quotes, @, '\0' */]; public: - Grantee_str(const char *user, const char *host) + Grantee_str(const LEX_CSTRING &user, const LEX_CSTRING &host) { - DBUG_ASSERT(strlen(user) + strlen(host) + 6 < sizeof(m_buff)); - strxmov(m_buff, "'", user, "'@'", host, "'", NullS); + DBUG_ASSERT(user.length + host.length + 6 < sizeof(m_buff)); + my_snprintf(m_buff, sizeof(m_buff), "'%.*s'@'%.*s'", + (int) user.length, user.str, + (int) host.length, host.str); } operator const char *() const { return m_buff; } }; @@ -12658,7 +12702,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS int error= 0; uint counter; - ACL_USER *acl_user; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -12670,10 +12713,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (counter=0 ; counter < acl_users.elements ; counter++) { - const char *user,*host, *is_grantable="YES"; - acl_user=dynamic_element(&acl_users,counter,ACL_USER*); - user= acl_user->user.str; - host= safe_str(acl_user->host.hostname); + const char *is_grantable="YES"; + const ACL_USER *acl_user= dynamic_element(&acl_users,counter,ACL_USER*); + const LEX_CSTRING user= acl_user->user; + const LEX_CSTRING host= acl_user->hostname(); if (no_global_access && !thd->security_ctx->is_priv_user(user, host)) @@ -12740,11 +12783,12 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (counter=0 ; counter < acl_dbs.elements() ; counter++) { - const char *user, *host, *is_grantable="YES"; + const char *is_grantable="YES"; acl_db=&acl_dbs.at(counter); - user= acl_db->user; - host= safe_str(acl_db->host.hostname); + const LEX_CSTRING user= Lex_cstring_strlen(acl_db->user); + const LEX_CSTRING host= Lex_cstring_strlen( + safe_str(acl_db->host.hostname)); if (no_global_access && !thd->security_ctx->is_priv_user(user, host)) @@ -12811,11 +12855,12 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (index=0 ; index < column_priv_hash.records ; index++) { - const char *user, *host, *is_grantable= "YES"; + const char *is_grantable= "YES"; GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash, index); - user= grant_table->user; - host= safe_str(grant_table->host.hostname); + const LEX_CSTRING user= Lex_cstring_strlen(grant_table->user); + const LEX_CSTRING host= Lex_cstring_strlen( + safe_str(grant_table->host.hostname)); if (no_global_access && !thd->security_ctx->is_priv_user(user, host)) @@ -12892,11 +12937,12 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (index=0 ; index < column_priv_hash.records ; index++) { - const char *user, *host, *is_grantable= "YES"; + const char *is_grantable= "YES"; GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash, index); - user= grant_table->user; - host= safe_str(grant_table->host.hostname); + const LEX_CSTRING user= Lex_cstring_strlen(grant_table->user); + const LEX_CSTRING host= Lex_cstring_strlen( + safe_str(grant_table->host.hostname)); if (no_global_access && !thd->security_ctx->is_priv_user(user, host)) @@ -13080,7 +13126,7 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock) if (lock) mysql_mutex_lock(&acl_cache->lock); - if (find_acl_role(dup->user.str, false)) + if (find_acl_role(dup->user, false)) dup->host= empty_clex_str; else dup->host= host_not_specified; @@ -13096,7 +13142,7 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool lock) struct ACL_internal_schema_registry_entry { - const LEX_CSTRING *m_name; + Lex_ident_i_s_table m_name; const ACL_internal_schema_access *m_access; }; @@ -13122,7 +13168,7 @@ void ACL_internal_schema_registry::register_schema DBUG_ASSERT(m_registry_array_size < array_elements(registry_array)); /* Not thread safe, and does not need to be. */ - registry_array[m_registry_array_size].m_name= name; + registry_array[m_registry_array_size].m_name= Lex_ident_i_s_table(*name); registry_array[m_registry_array_size].m_access= access; m_registry_array_size++; } @@ -13139,10 +13185,10 @@ ACL_internal_schema_registry::lookup(const char *name) uint i; + const Lex_cstring_strlen name_ls(name); for (i= 0; istr, - name) == 0) + if (registry_array[i].m_name.streq(name_ls)) return registry_array[i].m_access; } return NULL; @@ -13227,7 +13273,7 @@ struct MPVIO_EXT :public MYSQL_PLUGIN_VIO LEX_CSTRING db; ///< db name from the handshake packet /** when restarting a plugin this caches the last client reply */ struct { - const char *plugin; + LEX_CSTRING plugin; char *pkt; ///< pointer into NET::buff uint pkt_len; } cached_client_reply; @@ -13471,8 +13517,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, */ bool switch_from_long_to_short_scramble= client_auth_plugin == old_password_plugin_name.str && - my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin, - native_password_plugin_name.str) == 0; + Lex_ident_plugin(mpvio->cached_client_reply.plugin). + streq(native_password_plugin_name); if (switch_from_long_to_short_scramble) DBUG_RETURN (secure_auth(mpvio->auth_info.thd) || @@ -13486,8 +13532,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, */ bool switch_from_short_to_long_scramble= client_auth_plugin == native_password_plugin_name.str && - my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin, - old_password_plugin_name.str) == 0; + Lex_ident_plugin(mpvio->cached_client_reply.plugin). + streq(old_password_plugin_name); if (switch_from_short_to_long_scramble) { @@ -13592,10 +13638,10 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio) mpvio->acl_user->auth->plugin.str != old_password_plugin_name.str && !(mpvio->auth_info.thd->client_capabilities & CLIENT_PLUGIN_AUTH)) { - DBUG_ASSERT(my_strcasecmp(system_charset_info, - mpvio->acl_user->auth->plugin.str, native_password_plugin_name.str)); - DBUG_ASSERT(my_strcasecmp(system_charset_info, - mpvio->acl_user->auth->plugin.str, old_password_plugin_name.str)); + DBUG_ASSERT(!Lex_ident_plugin(mpvio->acl_user->auth->plugin). + streq(native_password_plugin_name)); + DBUG_ASSERT(!Lex_ident_plugin(mpvio->acl_user->auth->plugin). + streq(old_password_plugin_name)); my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); general_log_print(mpvio->auth_info.thd, COM_CONNECT, ER_THD(mpvio->auth_info.thd, ER_NOT_SUPPORTED_AUTH_MODE)); @@ -13769,7 +13815,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) if (find_mpvio_user(mpvio)) DBUG_RETURN(1); - const char *client_plugin; + LEX_CSTRING client_plugin; if (thd->client_capabilities & CLIENT_PLUGIN_AUTH) { if (next_field >= end) @@ -13778,13 +13824,13 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) MYF(0)); DBUG_RETURN(1); } - client_plugin= next_field; - next_field+= strlen(next_field) + 1; + client_plugin= Lex_cstring_strlen(next_field); + next_field+= client_plugin.length + 1; } else { if (thd->client_capabilities & CLIENT_SECURE_CONNECTION) - client_plugin= native_password_plugin_name.str; + client_plugin= native_password_plugin_name; else { /* @@ -13792,8 +13838,8 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) a passwordless accounts we use native_password_plugin. See guess_auth_plugin(). */ - client_plugin= passwd_len ? old_password_plugin_name.str - : native_password_plugin_name.str; + client_plugin= passwd_len ? old_password_plugin_name + : native_password_plugin_name; } } @@ -13805,7 +13851,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) DBUG_RETURN(1); } - DBUG_PRINT("info", ("client_plugin=%s, restart", client_plugin)); + DBUG_PRINT("info", ("client_plugin=%s, restart", client_plugin.str)); /* Remember the data part of the packet, to present it to plugin in read_packet() @@ -14008,8 +14054,8 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, /* strlen() can't be easily deleted without changing protocol */ db_len= safe_strlen(db); - char *next_field; - const char *client_plugin= next_field= passwd + passwd_len + (db ? db_len + 1 : 0); + char *next_field= passwd + passwd_len + (db ? db_len + 1 : 0); + Lex_ident_plugin client_plugin= Lex_cstring_strlen(next_field); /* Since 4.1 all database names are stored in utf8 @@ -14067,7 +14113,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, return packet_error; if ((thd->client_capabilities & CLIENT_PLUGIN_AUTH) && - (client_plugin < (char *)net->read_pos + pkt_len)) + (client_plugin.str < (char *)net->read_pos + pkt_len)) { next_field+= strlen(next_field) + 1; } @@ -14077,7 +14123,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, thd->client_capabilities &= ~CLIENT_PLUGIN_AUTH; if (thd->client_capabilities & CLIENT_SECURE_CONNECTION) - client_plugin= native_password_plugin_name.str; + client_plugin= native_password_plugin_name; else { /* @@ -14085,8 +14131,8 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, a passwordless accounts we use native_password_plugin. See guess_auth_plugin(). */ - client_plugin= passwd_len ? old_password_plugin_name.str - : native_password_plugin_name.str; + client_plugin= passwd_len ? old_password_plugin_name + : native_password_plugin_name; } } @@ -14123,7 +14169,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin; if (client_auth_plugin && - my_strcasecmp(system_charset_info, client_plugin, client_auth_plugin)) + !client_plugin.streq(Lex_cstring_strlen(client_auth_plugin))) { mpvio->cached_client_reply.plugin= client_plugin; if (send_plugin_request_packet(mpvio, @@ -14226,8 +14272,8 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) and a client has used the correct plugin, then we can return the cached data straight away and avoid one round trip. */ - if (my_strcasecmp(system_charset_info, mpvio->cached_client_reply.plugin, - client_auth_plugin) == 0) + if (Lex_ident_plugin(Lex_cstring_strlen(client_auth_plugin)). + streq(mpvio->cached_client_reply.plugin)) { mpvio->status= MPVIO_EXT::FAILURE; pkt_len= mpvio->cached_client_reply.pkt_len; @@ -14488,7 +14534,9 @@ enum PASSWD_ERROR_ACTION }; /* Increment, or clear password errors for a user. */ -static void handle_password_errors(const char *user, const char *hostname, PASSWD_ERROR_ACTION action) +static void handle_password_errors(const LEX_CSTRING &user, + const LEX_CSTRING &hostname, + PASSWD_ERROR_ACTION action) { #ifndef NO_EMBEDDED_ACCESS_CHECKS mysql_mutex_assert_not_owner(&acl_cache->lock); @@ -14561,7 +14609,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) bzero(&mpvio, sizeof(mpvio)); mpvio.read_packet= server_mpvio_read_packet; mpvio.write_packet= server_mpvio_write_packet; - mpvio.cached_client_reply.plugin= ""; + mpvio.cached_client_reply.plugin= ""_LEX_CSTRING; mpvio.info= server_mpvio_info; mpvio.status= MPVIO_EXT::RESTART; mpvio.auth_info.thd= thd; @@ -14657,7 +14705,8 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) case CR_AUTH_USER_CREDENTIALS: errors.m_authentication= 1; if (thd->password && !mpvio.make_it_fail) - handle_password_errors(acl_user->user.str, acl_user->host.hostname, PASSWD_ERROR_INCREMENT); + handle_password_errors(acl_user->user, acl_user->hostname(), + PASSWD_ERROR_INCREMENT); break; case CR_ERROR: default: @@ -14675,7 +14724,8 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) if (thd->password && acl_user->password_errors) { /* Login succeeded, clear password errors.*/ - handle_password_errors(acl_user->user.str, acl_user->host.hostname, PASSWD_ERROR_CLEAR); + handle_password_errors(acl_user->user, acl_user->hostname(), + PASSWD_ERROR_CLEAR); } if (initialized) // if not --skip-grant-tables @@ -14747,8 +14797,11 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) /* we're proxying : find the proxy user definition */ mysql_mutex_lock(&acl_cache->lock); - acl_proxy_user= find_user_exact(safe_str(proxy_user->get_proxied_host()), - mpvio.auth_info.authenticated_as); + acl_proxy_user= + find_user_exact( + Lex_cstring_strlen(safe_str(proxy_user->get_proxied_host())), + Lex_cstring_strlen(mpvio.auth_info.authenticated_as)); + if (!acl_proxy_user) { mysql_mutex_unlock(&acl_cache->lock); @@ -14849,9 +14902,9 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) if (initialized && acl_user->default_rolename.length) { privilege_t access(NO_ACL); int result; - result= acl_check_setrole(thd, acl_user->default_rolename.str, &access); + result= acl_check_setrole(thd, acl_user->default_rolename, &access); if (!result) - result= acl_setrole(thd, acl_user->default_rolename.str, access); + result= acl_setrole(thd, acl_user->default_rolename, access); if (result) thd->clear_error(); // even if the default role was not granted, do not // close the connection diff --git a/sql/sql_acl.h b/sql/sql_acl.h index f99190a61b6..b23fcb45f5d 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -81,8 +81,9 @@ void acl_free(bool end=0); privilege_t acl_get_all3(Security_context *sctx, const char *db, bool db_is_patern); bool acl_authenticate(THD *thd, uint com_change_user_pkt_len); -bool acl_getroot(Security_context *sctx, const char *user, const char *host, - const char *ip, const char *db); +bool acl_getroot(Security_context *sctx, + const LEX_CSTRING &user, const LEX_CSTRING &host, + const LEX_CSTRING &ip, const LEX_CSTRING &db); bool acl_check_host(const char *host, const char *ip); bool check_change_password(THD *thd, LEX_USER *user); bool change_password(THD *thd, LEX_USER *user); @@ -101,9 +102,10 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, bool any_combination_will_do, uint number, bool no_errors); bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, - const char *name, size_t length, Security_context *sctx); + const Lex_ident_column &name, + Security_context *sctx); bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, - const char *name, size_t length, Field *fld); + const Lex_ident_column &name, Field *fld); bool check_grant_all_columns(THD *thd, privilege_t want_access, Field_iterator_table_ref *fields); bool check_grant_routine(THD *thd, privilege_t want_access, @@ -118,7 +120,7 @@ bool check_access(THD *thd, privilege_t want_access, privilege_t get_table_grant(THD *thd, TABLE_LIST *table); privilege_t get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, - const char *field_name); + const Lex_ident_column &field_name); bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username, const char **hostname, const char **rolename); void mysql_show_grants_get_fields(THD *thd, List *fields, @@ -136,14 +138,18 @@ int mysql_alter_user(THD *thd, List &list); bool mysql_revoke_all(THD *thd, List &list); void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); -bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_revoke_privileges(THD *thd, + const Lex_ident_db &sp_db, + const Lex_ident_routine &sp_name, const Sp_handler *sph); -bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, +bool sp_grant_privileges(THD *thd, + const Lex_ident_db &sp_db, + const Lex_ident_routine &sp_name, const Sp_handler *sph); bool check_routine_level_acl(THD *thd, privilege_t acl, const char *db, const char *name, const Sp_handler *sph); -bool is_acl_user(const char *host, const char *user); +bool is_acl_user(const LEX_CSTRING &host, const LEX_CSTRING &user); int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond); @@ -273,14 +279,22 @@ get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info, const char *schema_name, const char *table_name); -bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user, +bool acl_check_proxy_grant_access (THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, bool with_grant); -int acl_setrole(THD *thd, const char *rolename, privilege_t access); -int acl_check_setrole(THD *thd, const char *rolename, privilege_t *access); -int acl_check_set_default_role(THD *thd, const char *host, const char *user, - const char *role); -int acl_set_default_role(THD *thd, const char *host, const char *user, - const char *rolename); +int acl_setrole(THD *thd, const LEX_CSTRING &rolename, privilege_t access); +int acl_check_setrole(THD *thd, + const LEX_CSTRING &rolename, + privilege_t *access); +int acl_check_set_default_role(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &role); +int acl_set_default_role(THD *thd, + const LEX_CSTRING &host, + const LEX_CSTRING &user, + const LEX_CSTRING &rolename); extern SHOW_VAR acl_statistics[]; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 86af7919d99..815763662b4 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -356,9 +356,7 @@ bool Alter_info::add_stat_drop_index(THD *thd, const LEX_CSTRING *key_name) KEY *key_info= original_table->key_info; for (uint i= 0; i < original_table->s->keys; i++, key_info++) { - if (key_info->name.length && - !lex_string_cmp(system_charset_info, &key_info->name, - key_name)) + if (key_info->name.length && key_info->name.streq(*key_name)) return add_stat_drop_index(key_info, false, thd->mem_root); } } @@ -415,7 +413,7 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list, table_name= table_list->table_name; alias= (lower_case_table_names == 2) ? table_list->alias : table_name; - if (!new_db.str || !my_strcasecmp(table_alias_charset, new_db.str, db.str)) + if (!new_db.str || new_db.streq(db)) new_db= db; if (new_name.str) @@ -424,21 +422,23 @@ Alter_table_ctx::Alter_table_ctx(THD *thd, TABLE_LIST *table_list, if (lower_case_table_names == 1) // Convert new_name/new_alias to lower { - new_name= new_name_buff.copy_casedn(files_charset_info, new_name). - to_lex_cstring(); + new_name= Lex_ident_table(new_name_buff.copy_casedn(files_charset_info, + new_name). + to_lex_cstring()); new_alias= new_name; } else if (lower_case_table_names == 2) // Convert new_name to lower case { new_alias= new_name; - new_name= new_name_buff.copy_casedn(files_charset_info, new_name). - to_lex_cstring(); + new_name= Lex_ident_table(new_name_buff.copy_casedn(files_charset_info, + new_name). + to_lex_cstring()); } else new_alias= new_name; // LCTN=0 => case sensitive + case preserving if (!is_database_changed() && - !my_strcasecmp(table_alias_charset, new_name.str, table_name.str)) + new_name.streq(table_name)) { /* Source and destination table names are equal: diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 8ffac83b7c0..425e6067991 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -85,7 +85,8 @@ public: ALTER_TABLE_LOCK_EXCLUSIVE }; - Lex_table_name db, table_name; + Lex_ident_db db; + Lex_ident_table table_name; // Columns and keys to be dropped. List drop_list; @@ -405,12 +406,12 @@ public: Create_field *implicit_default_value_error_field= nullptr; bool error_if_not_empty= false; uint tables_opened= 0; - LEX_CSTRING db; - LEX_CSTRING table_name; + Lex_ident_db db; + Lex_ident_table table_name; LEX_CSTRING storage_engine_name; LEX_CSTRING alias; - LEX_CSTRING new_db; - LEX_CSTRING new_name; + Lex_ident_db new_db; + Lex_ident_table new_name; LEX_CSTRING new_alias; LEX_CSTRING tmp_name; LEX_CSTRING tmp_storage_engine_name; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e33b4728829..b527b02d633 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -202,9 +202,9 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) is properly initialized, so table definition cache can be produced from key used by MDL subsystem. */ - DBUG_ASSERT(!strcmp(table_list->get_db_name(), + DBUG_ASSERT(!strcmp(table_list->get_db_name().str, table_list->mdl_request.key.db_name())); - DBUG_ASSERT(!strcmp(table_list->get_table_name(), + DBUG_ASSERT(!strcmp(table_list->get_table_name().str, table_list->mdl_request.key.name())); *key= (const char*)table_list->mdl_request.key.ptr() + 1; @@ -235,33 +235,40 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) # Pointer to list of names of open tables. */ -struct list_open_tables_arg +class list_open_tables_arg { +public: THD *thd; - const char *db; + const Lex_ident_db db; const char *wild; TABLE_LIST table_list; OPEN_TABLE_LIST **start_list, *open_list; + + list_open_tables_arg(THD *thd_arg, const LEX_CSTRING &db_arg, + const char *wild_arg) + :thd(thd_arg), db(db_arg), wild(wild_arg), + start_list(&open_list), open_list(0) + { + bzero((char*) &table_list, sizeof(table_list)); + } }; static my_bool list_open_tables_callback(TDC_element *element, list_open_tables_arg *arg) { - const char *db= (char*) element->m_key; - size_t db_length= strlen(db); - const char *table_name= db + db_length + 1; + const Lex_ident_db + db= Lex_ident_db(Lex_cstring_strlen((const char*) element->m_key)); + const char *table_name= db.str + db.length + 1; - if (arg->db && my_strcasecmp(system_charset_info, arg->db, db)) + if (arg->db.str && !arg->db.streq(db)) return FALSE; if (arg->wild && wild_compare(table_name, arg->wild, 0)) return FALSE; /* Check if user has SELECT privilege for any column in the table */ - arg->table_list.db.str= db; - arg->table_list.db.length= db_length; - arg->table_list.table_name.str= table_name; - arg->table_list.table_name.length= strlen(table_name); + arg->table_list.db= db; + arg->table_list.table_name= Lex_cstring_strlen(table_name); arg->table_list.grant.privilege= NO_ACL; if (check_table_access(arg->thd, SELECT_ACL, &arg->table_list, TRUE, 1, TRUE)) @@ -273,7 +280,7 @@ static my_bool list_open_tables_callback(TDC_element *element, strmov((*arg->start_list)->table= strmov(((*arg->start_list)->db= (char*) ((*arg->start_list) + 1)), - db) + 1, table_name); + db.str) + 1, table_name); (*arg->start_list)->in_use= 0; mysql_mutex_lock(&element->LOCK_table_share); @@ -290,17 +297,12 @@ static my_bool list_open_tables_callback(TDC_element *element, } -OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) +OPEN_TABLE_LIST *list_open_tables(THD *thd, + const LEX_CSTRING &db, + const char *wild) { - list_open_tables_arg argument; DBUG_ENTER("list_open_tables"); - - argument.thd= thd; - argument.db= db; - argument.wild= wild; - bzero((char*) &argument.table_list, sizeof(argument.table_list)); - argument.start_list= &argument.open_list; - argument.open_list= 0; + list_open_tables_arg argument(thd, db, wild); if (tdc_iterate(thd, (my_hash_walk_action) list_open_tables_callback, &argument, true)) @@ -1117,7 +1119,6 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, uint check_flag) { TABLE_LIST *res= 0; - LEX_CSTRING *d_name, *t_name, *t_alias; DBUG_ENTER("find_dup_table"); DBUG_PRINT("enter", ("table alias: %s", table->alias.str)); @@ -1147,12 +1148,12 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, */ DBUG_ASSERT(table); } - d_name= &table->db; - t_name= &table->table_name; - t_alias= &table->alias; + const Lex_ident_db d_name= table->db; + const Lex_ident_table t_name= table->table_name; + const Lex_ident_table t_alias= table->alias; retry: - DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str)); + DBUG_PRINT("info", ("real table: %s.%s", d_name.str, t_name.str)); for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0) { if (tl->select_lex && tl->select_lex->master_unit() && @@ -1168,7 +1169,7 @@ retry: Table is unique if it is present only once in the global list of tables and once in the list of table locks. */ - if (! (res= find_table_in_global_list(tl, d_name, t_name))) + if (! (res= find_table_in_global_list(tl, &d_name, &t_name))) break; tl= res; // We can continue search after this table @@ -1188,7 +1189,7 @@ retry: /* Skip if table alias does not match. */ if (check_flag & CHECK_DUP_ALLOW_DIFFERENT_ALIAS) { - if (my_strcasecmp(table_alias_charset, t_alias->str, res->alias.str)) + if (!t_alias.streq(res->alias)) continue; } @@ -1342,12 +1343,8 @@ void update_non_unique_table_error(TABLE_LIST *update, duplicate= duplicate->top_table(); if (!update->view || !duplicate->view || update->view == duplicate->view || - update->view_name.length != duplicate->view_name.length || - update->view_db.length != duplicate->view_db.length || - lex_string_cmp(table_alias_charset, - &update->view_name, &duplicate->view_name) != 0 || - lex_string_cmp(table_alias_charset, - &update->view_db, &duplicate->view_db) != 0) + !update->view_name.streq(duplicate->view_name) || + !update->view_db.streq(duplicate->view_db)) { /* it is not the same view repeated (but it can be parts of the same copy @@ -1892,7 +1889,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) TABLE *table; const char *key; uint key_length; - const char *alias= table_list->alias.str; + const LEX_CSTRING &alias= table_list->alias; uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; TABLE_SHARE *share; @@ -1960,7 +1957,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length)) { - if (!my_strcasecmp(system_charset_info, table->alias.c_ptr(), alias) && + if (table_alias_charset->streq(table->alias.to_lex_cstring(), alias) && table->query_id != thd->query_id && /* skip tables already used */ (thd->locked_tables_mode == LTM_LOCK_TABLES || table->query_id == 0)) @@ -2034,7 +2031,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) if (thd->locked_tables_mode == LTM_PRELOCKED) my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db.str, table_list->alias.str); else - my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); + my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias.str); DBUG_RETURN(TRUE); } @@ -6161,21 +6158,21 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table) static Field * find_field_in_view(THD *thd, TABLE_LIST *table_list, - const char *name, size_t length, + const Lex_ident_column &name, const char *item_name, Item **ref, bool register_tree_change) { DBUG_ENTER("find_field_in_view"); DBUG_PRINT("enter", ("view: '%s', field name: '%s', item name: '%s', ref %p", - table_list->alias.str, name, item_name, ref)); + table_list->alias.str, name.str, item_name, ref)); Field_iterator_view field_it; field_it.set(table_list); Query_arena *arena= 0, backup; for (; !field_it.end_of_fields(); field_it.next()) { - if (!my_strcasecmp(system_charset_info, field_it.name()->str, name)) + if (name.streq(field_it.name())) { // in PS use own arena or data will be freed after prepare if (register_tree_change && @@ -6241,7 +6238,9 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, */ static Field * -find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, size_t length, Item **ref, bool register_tree_change, +find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, + const Lex_ident_column &name, + Item **ref, bool register_tree_change, TABLE_LIST **actual_table) { List_iterator_fast @@ -6250,19 +6249,18 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si Field *UNINIT_VAR(found_field); Query_arena *UNINIT_VAR(arena), backup; DBUG_ENTER("find_field_in_natural_join"); - DBUG_PRINT("enter", ("field name: '%s', ref %p", - name, ref)); + DBUG_PRINT("enter", ("field name: '%s', ref %p", name.str, ref)); DBUG_ASSERT(table_ref->is_natural_join && table_ref->join_columns); DBUG_ASSERT(*actual_table == NULL); for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col; curr_nj_col= field_it++) { - if (!my_strcasecmp(system_charset_info, curr_nj_col->name()->str, name)) + if (name.streq(curr_nj_col->name())) { if (nj_col) { - my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), name.str, thd->where); DBUG_RETURN(NULL); } nj_col= curr_nj_col; @@ -6362,27 +6360,25 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si */ Field * -find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length, +find_field_in_table(THD *thd, TABLE *table, const Lex_ident_column &name, bool allow_rowid, field_index_t *cached_field_index_ptr) { Field *field; field_index_t cached_field_index= *cached_field_index_ptr; DBUG_ENTER("find_field_in_table"); DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias.c_ptr(), - name)); + name.str)); /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */ if (cached_field_index < table->s->fields && - !my_strcasecmp(system_charset_info, - table->field[cached_field_index]->field_name.str, name)) + table->field[cached_field_index]->field_name.streq(name)) { field= table->field[cached_field_index]; DEBUG_SYNC(thd, "table_field_cached"); } else { - LEX_CSTRING fname= {name, length}; - field= table->find_field_by_name(&fname); + field= table->find_field_by_name(&name); } if (field) @@ -6403,7 +6399,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length, else { if (!allow_rowid || - my_strcasecmp(system_charset_info, name, "_rowid") || + !name.streq("_rowid"_LEX_CSTRING) || table->s->rowid_field_offset == 0) DBUG_RETURN((Field*) 0); field= table->field[table->s->rowid_field_offset-1]; @@ -6462,8 +6458,9 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length, */ Field * -find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, - size_t length, const char *item_name, +find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, + const Lex_ident_column &name, + const char *item_name, const char *db_name, const char *table_name, ignored_tables_list_t ignored_tables, Item **ref, bool check_privileges, bool allow_rowid, @@ -6473,11 +6470,11 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, Field *fld; DBUG_ENTER("find_field_in_table_ref"); DBUG_ASSERT(table_list->alias.str); - DBUG_ASSERT(name); + DBUG_ASSERT(name.str); DBUG_ASSERT(item_name); DBUG_PRINT("enter", ("table: '%s' field name: '%s' item name: '%s' ref %p", - table_list->alias.str, name, item_name, ref)); + table_list->alias.str, name.str, item_name, ref)); /* Check that the table and database that qualify the current field name @@ -6509,11 +6506,12 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, to search. */ table_name && table_name[0] && - (my_strcasecmp(table_alias_charset, table_list->alias.str, table_name) || + (!table_list->alias.streq(Lex_cstring_strlen(table_name)) || (db_name && (!table_list->db.str || !table_list->db.str[0])) || (db_name && table_list->db.str && table_list->db.str[0] && (table_list->schema_table ? - my_strcasecmp(system_charset_info, db_name, table_list->db.str) : + !Lex_ident_i_s_table(Lex_cstring_strlen(db_name)). + streq(table_list->db) : strcmp(db_name, table_list->db.str))))) DBUG_RETURN(0); @@ -6529,7 +6527,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, if (table_list->field_translation) { /* 'table_list' is a view or an information schema table. */ - if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref, + if ((fld= find_field_in_view(thd, table_list, name, item_name, ref, register_tree_change))) *actual_table= table_list; } @@ -6537,7 +6535,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, { /* 'table_list' is a stored table. */ DBUG_ASSERT(table_list->table); - if ((fld= find_field_in_table(thd, table_list->table, name, length, + if ((fld= find_field_in_table(thd, table_list->table, name, allow_rowid, cached_field_index_ptr))) *actual_table= table_list; } @@ -6563,7 +6561,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, if (table->table && ignored_list_includes_table(ignored_tables, table)) continue; - if ((fld= find_field_in_table_ref(thd, table, name, length, item_name, + if ((fld= find_field_in_table_ref(thd, table, name, item_name, db_name, table_name, ignored_tables, ref, check_privileges, allow_rowid, cached_field_index_ptr, @@ -6578,7 +6576,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, natural join, thus if the field is not qualified, we will search directly the top-most NATURAL/USING join. */ - fld= find_field_in_natural_join(thd, table_list, name, length, ref, + fld= find_field_in_natural_join(thd, table_list, name, ref, register_tree_change, actual_table); } @@ -6588,7 +6586,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, /* Check if there are sufficient access rights to the found field. */ if (check_privileges && !table_list->is_derived() && - check_column_grant_in_table_ref(thd, *actual_table, name, length, fld)) + check_column_grant_in_table_ref(thd, *actual_table, name, fld)) fld= WRONG_GRANT; else #endif @@ -6647,13 +6645,13 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, const char *name, # pointer to field */ -Field *find_field_in_table_sef(TABLE *table, const char *name) +Field *find_field_in_table_sef(TABLE *table, const Lex_ident_column &name) { Field **field_ptr; if (table->s->name_hash.records) { - field_ptr= (Field**)my_hash_search(&table->s->name_hash,(uchar*) name, - strlen(name)); + field_ptr= (Field**)my_hash_search(&table->s->name_hash,(uchar*) name.str, + name.length); if (field_ptr) { /* @@ -6668,8 +6666,7 @@ Field *find_field_in_table_sef(TABLE *table, const char *name) if (!(field_ptr= table->field)) return (Field *)0; for (; *field_ptr; ++field_ptr) - if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name.str, - name)) + if ((*field_ptr)->field_name.streq(name)) break; } if (field_ptr) @@ -6725,8 +6722,7 @@ find_field_in_tables(THD *thd, Item_ident *item, Field *found=0; LEX_CSTRING db= item->db_name; const char *table_name= item->table_name.str; - const char *name= item->field_name.str; - size_t length= item->field_name.length; + const Lex_ident_column &name= item->field_name; IdentBuffer db_name_buff; TABLE_LIST *cur_table= first_table; TABLE_LIST *actual_table; @@ -6763,17 +6759,17 @@ find_field_in_tables(THD *thd, Item_ident *item, (!table_ref->is_multitable() && table_ref->merged_for_insert))) { - found= find_field_in_table(thd, table_ref->table, name, length, + found= find_field_in_table(thd, table_ref->table, name, TRUE, &(item->cached_field_index)); #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (found && check_privileges && !is_temporary_table(table_ref) && - check_column_grant_in_table_ref(thd, table_ref, name, length, found)) + check_column_grant_in_table_ref(thd, table_ref, name, found)) found= WRONG_GRANT; #endif } else - found= find_field_in_table_ref(thd, table_ref, name, length, + found= find_field_in_table_ref(thd, table_ref, name, item->name.str, NULL, NULL, ignored_tables, ref, check_privileges, TRUE, &(item->cached_field_index), @@ -6852,7 +6848,7 @@ find_field_in_tables(THD *thd, Item_ident *item, ignored_list_includes_table(ignored_tables, cur_table)) continue; - Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length, + Field *cur_field= find_field_in_table_ref(thd, cur_table, name, item->name.str, db.str, table_name, ignored_tables, ref, @@ -6871,7 +6867,7 @@ find_field_in_tables(THD *thd, Item_ident *item, return (Field*) 0; thd->clear_error(); - cur_field= find_field_in_table_ref(thd, cur_table, name, length, + cur_field= find_field_in_table_ref(thd, cur_table, name, item->name.str, db.str, table_name, ignored_tables, ref, false, allow_rowid, @@ -6919,7 +6915,7 @@ find_field_in_tables(THD *thd, Item_ident *item, if (report_error == REPORT_ALL_ERRORS || report_error == IGNORE_EXCEPT_NON_UNIQUE) my_error(ER_NON_UNIQ_ERROR, MYF(0), - table_name ? item->full_name() : name, thd->where); + table_name ? item->full_name() : name.str, thd->where); return (Field*) 0; } found= cur_field; @@ -7008,9 +7004,9 @@ find_item_in_list(Item *find, List &items, uint *counter, List_iterator li(items); uint n_items= limit == 0 ? items.elements : limit; Item **found=0, **found_unaliased= 0, *item; - const char *db_name=0; - const LEX_CSTRING *field_name= 0; - const char *table_name=0; + Lex_ident_db db_name; + Lex_ident_column field_name; + Lex_ident_table table_name; bool found_unaliased_non_uniq= 0; /* true if the item that we search for is a valid name reference @@ -7025,15 +7021,15 @@ find_item_in_list(Item *find, List &items, uint *counter, find->type() == Item::REF_ITEM); if (is_ref_by_name) { - field_name= &((Item_ident*) find)->field_name; - table_name= ((Item_ident*) find)->table_name.str; - db_name= ((Item_ident*) find)->db_name.str; + field_name= ((Item_ident*) find)->field_name; + table_name= ((Item_ident*) find)->table_name; + db_name= ((Item_ident*) find)->db_name; } for (uint i= 0; i < n_items; i++) { item= li++; - if (field_name && field_name->str && + if (field_name.str && (item->real_item()->type() == Item::FIELD_ITEM || ((item->type() == Item::REF_ITEM) && (((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)))) @@ -7049,7 +7045,7 @@ find_item_in_list(Item *find, List &items, uint *counter, if (unlikely(!item_field->name.str)) continue; - if (table_name) + if (table_name.str) { /* If table name is specified we should find field 'field_name' in @@ -7068,12 +7064,11 @@ find_item_in_list(Item *find, List &items, uint *counter, item is not fix_field()'ed yet. */ if (item_field->field_name.str && item_field->table_name.str && - !lex_string_cmp(system_charset_info, &item_field->field_name, - field_name) && - !my_strcasecmp(table_alias_charset, item_field->table_name.str, - table_name) && - (!db_name || (item_field->db_name.str && - !strcmp(item_field->db_name.str, db_name)))) + item_field->field_name.streq(field_name) && + item_field->table_name.streq(table_name) && + (!db_name.str || + (item_field->db_name.str && + item_field->db_name.streq(db_name)))) { if (found_unaliased) { @@ -7092,17 +7087,14 @@ find_item_in_list(Item *find, List &items, uint *counter, found_unaliased= li.ref(); unaliased_counter= i; *resolution= RESOLVED_IGNORING_ALIAS; - if (db_name) + if (db_name.str) break; // Perfect match } } else { - bool fname_cmp= lex_string_cmp(system_charset_info, - &item_field->field_name, - field_name); - if (!lex_string_cmp(system_charset_info, - &item_field->name, field_name)) + bool fname_cmp= !item_field->field_name.streq(field_name); + if (item_field->name.streq(field_name)) { /* If table name was not given we should scan through aliases @@ -7144,11 +7136,10 @@ find_item_in_list(Item *find, List &items, uint *counter, } } } - else if (!table_name) + else if (!table_name.str) { if (is_ref_by_name && find->name.str && item->name.str && - find->name.length == item->name.length && - !lex_string_cmp(system_charset_info, &item->name, &find->name)) + item->name.streq(find->name)) { found= li.ref(); *counter= i; @@ -7215,16 +7206,13 @@ find_item_in_list(Item *find, List &items, uint *counter, */ static bool -test_if_string_in_list(const char *find, List *str_list) +test_if_string_in_list(const Lex_ident_column &find, List *str_list) { List_iterator str_list_it(*str_list); String *curr_str; - size_t find_length= strlen(find); while ((curr_str= str_list_it++)) { - if (find_length != curr_str->length()) - continue; - if (!my_strcasecmp(system_charset_info, find, curr_str->ptr())) + if (find.streq(curr_str->to_lex_cstring())) return TRUE; } return FALSE; @@ -7328,7 +7316,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) { bool found= FALSE; - const LEX_CSTRING *field_name_1; + Lex_ident_column field_name_1; Field *field_2= 0; /* true if field_name_1 is a member of using_fields */ @@ -7344,10 +7332,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, field_name_1= nj_col_1->name(); is_using_column_1= using_fields && - test_if_string_in_list(field_name_1->str, using_fields); + test_if_string_in_list(field_name_1, using_fields); DBUG_PRINT ("info", ("field_name_1=%s.%s", nj_col_1->safe_table_name(), - field_name_1->str)); + field_name_1.str)); if (field_1_invisible && !is_using_column_1) continue; @@ -7363,7 +7351,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) { Natural_join_column *cur_nj_col_2; - const LEX_CSTRING *cur_field_name_2; + Lex_ident_column cur_field_name_2; if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, leaf_2))) goto err; @@ -7376,7 +7364,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, cur_field_name_2= cur_nj_col_2->name(); DBUG_PRINT ("info", ("cur_field_name_2=%s.%s", cur_nj_col_2->safe_table_name(), - cur_field_name_2->str)); + cur_field_name_2.str)); /* Compare the two columns and check for duplicate common fields. @@ -7389,13 +7377,12 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, here. These columns must be checked only on unqualified reference by name (e.g. in SELECT list). */ - if (!lex_string_cmp(system_charset_info, field_name_1, - cur_field_name_2)) + if (field_name_1.streq(cur_field_name_2)) { DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common)); if (cur_nj_col_2->is_common || found) { - my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1->str, thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1.str, thd->where); goto err; } if ((!using_fields && !field_2_invisible) || is_using_column_1) @@ -7482,9 +7469,9 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, nj_col_1->is_common= nj_col_2->is_common= TRUE; DBUG_PRINT ("info", ("%s.%s and %s.%s are common", nj_col_1->safe_table_name(), - nj_col_1->name()->str, + nj_col_1->name().str, nj_col_2->safe_table_name(), - nj_col_2->name()->str)); + nj_col_2->name().str)); if (field_1) update_field_dependencies(thd, field_1, field_1->table); @@ -7598,7 +7585,6 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, List_iterator_fast using_fields_it(*using_fields); while ((using_field_name= using_fields_it++)) { - const char *using_field_name_ptr= using_field_name->c_ptr(); List_iterator_fast it(*join_columns); Natural_join_column *common_field; @@ -7608,12 +7594,12 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, /* If reached the end of fields, and none was found, report error. */ if (!(common_field= it++)) { - my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr, + my_error(ER_BAD_FIELD_ERROR, MYF(0), + ErrConvString(using_field_name).ptr(), current_thd->where); goto err; } - if (!my_strcasecmp(system_charset_info, - common_field->name()->str, using_field_name_ptr)) + if (common_field->name().streq(using_field_name->to_lex_cstring())) break; // Found match } } @@ -8531,14 +8517,15 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, Name_resolution_context *context, - const LEX_CSTRING &db_name_arg, const LEX_CSTRING &table_name, + const Lex_ident_db &db_name_arg, + const Lex_ident_table &table_name, List_iterator *it, bool any_privileges, uint *hidden_bit_fields, bool returning_field) { Field_iterator_table_ref field_iterator; bool found; - LEX_CSTRING db_name= db_name_arg; + Lex_ident_db db_name= db_name_arg; IdentBuffer db_name_buff; DBUG_ENTER("insert_fields"); DBUG_PRINT("arena", ("stmt arena: %p",thd->stmt_arena)); @@ -8550,7 +8537,7 @@ insert_fields(THD *thd, Name_resolution_context *context, We can't do this in Item_field as this would change the 'name' of the item which may be used in the select list */ - db_name= db_name_buff.copy_casedn(db_name).to_lex_cstring(); + db_name= Lex_ident_db(db_name_buff.copy_casedn(db_name).to_lex_cstring()); } found= FALSE; @@ -8574,8 +8561,7 @@ insert_fields(THD *thd, Name_resolution_context *context, DBUG_ASSERT(tables->is_leaf_for_name_resolution()); - if ((table_name.str && my_strcasecmp(table_alias_charset, table_name.str, - tables->alias.str)) || + if ((table_name.str && !table_name.streq(tables->alias)) || (db_name.str && strcmp(tables->db.str, db_name.str))) continue; @@ -8668,14 +8654,14 @@ insert_fields(THD *thd, Name_resolution_context *context, tables->is_natural_join); DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *fld= (Item_field*) item; - const char *field_db_name= field_iterator.get_db_name(); - const char *field_table_name= field_iterator.get_table_name(); + const char *field_db_name= field_iterator.get_db_name().str; + const char *field_table_name= field_iterator.get_table_name().str; if (!tables->schema_table && !(fld->have_privileges= (get_column_grant(thd, field_iterator.grant(), field_db_name, - field_table_name, fld->field_name.str) & + field_table_name, fld->field_name) & VIEW_ANY_ACL))) { my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "ANY", diff --git a/sql/sql_base.h b/sql/sql_base.h index 04e487db65d..eb35b708451 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -179,7 +179,8 @@ bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, bool ignore_errors, enum trg_event_type event); bool insert_fields(THD *thd, Name_resolution_context *context, - const LEX_CSTRING &db_name, const LEX_CSTRING &table_name, + const Lex_ident_db &db_name, + const Lex_ident_table &table_name, List_iterator *it, bool any_privileges, uint *hidden_bit_fields, bool returning_field); void make_leaves_list(THD *thd, List &list, TABLE_LIST *tables, @@ -205,7 +206,7 @@ find_field_in_tables(THD *thd, Item_ident *item, bool check_privileges, bool register_tree_change); Field * find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, - const char *name, size_t length, + const Lex_ident_column &name, const char *item_name, const char *db_name, const char *table_name, ignored_tables_list_t ignored_tables, @@ -213,10 +214,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, field_index_t *cached_field_index_ptr, bool register_tree_change, TABLE_LIST **actual_table); Field * -find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length, +find_field_in_table(THD *thd, TABLE *table, const Lex_ident_column &name, bool allow_rowid, field_index_t *cached_field_index_ptr); Field * -find_field_in_table_sef(TABLE *table, const char *name); +find_field_in_table_sef(TABLE *table, const Lex_ident_column &name); Item ** find_item_in_list(Item *item, List &items, uint *counter, find_item_error_report_type report_error, enum_resolution_type *resolution, uint limit= 0); @@ -318,7 +319,8 @@ bool flush_tables(THD *thd, flush_tables_type flag); void close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ha_extra_function extra, TABLE *skip_table); -OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild); +OPEN_TABLE_LIST *list_open_tables(THD *thd, const LEX_CSTRING &db, + const char *wild); bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags); TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, @@ -370,8 +372,8 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr) } inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, - LEX_CSTRING *db_name, - LEX_CSTRING *table_name) + const LEX_CSTRING *db_name, + const LEX_CSTRING *table_name) { return find_table_in_list(table, &TABLE_LIST::next_global, db_name, table_name); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 40569c67d72..0dee58184dd 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -124,8 +124,7 @@ extern "C" void free_sequence_last(SEQUENCE_LAST_VALUE *entry) bool Key_part_spec::operator==(const Key_part_spec& other) const { return length == other.length && - !lex_string_cmp(system_charset_info, &field_name, - &other.field_name); + field_name.streq(other.field_name); } @@ -289,9 +288,8 @@ bool Foreign_key::validate(List &table_fields) { it.rewind(); while ((sql_field= it++) && - lex_string_cmp(system_charset_info, - &column->field_name, - &sql_field->field_name)) {} + !sql_field->field_name.streq(column->field_name)) + { } if (!sql_field) { my_error(ER_KEY_COLUMN_DOES_NOT_EXIST, MYF(0), column->field_name.str); @@ -855,10 +853,11 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) profiling.set_thd(this); #endif user_connect=(USER_CONN *)0; - my_hash_init(key_memory_user_var_entry, &user_vars, system_charset_info, + my_hash_init(key_memory_user_var_entry, &user_vars, + Lex_ident_user_var::charset_info(), USER_VARS_HASH_SIZE, 0, 0, (my_hash_get_key) get_var_key, (my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC); - my_hash_init(PSI_INSTRUMENT_ME, &sequences, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &sequences, Lex_ident_fs::charset_info(), SEQUENCES_HASH_SIZE, 0, 0, (my_hash_get_key) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); @@ -1491,10 +1490,12 @@ void THD::change_user(void) init(); stmt_map.reset(); - my_hash_init(key_memory_user_var_entry, &user_vars, system_charset_info, + my_hash_init(key_memory_user_var_entry, &user_vars, + Lex_ident_user_var::charset_info(), USER_VARS_HASH_SIZE, 0, 0, (my_hash_get_key) get_var_key, (my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC); - my_hash_init(key_memory_user_var_entry, &sequences, system_charset_info, + my_hash_init(key_memory_user_var_entry, &sequences, + Lex_ident_fs::charset_info(), SEQUENCES_HASH_SIZE, 0, 0, (my_hash_get_key) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); @@ -4039,9 +4040,9 @@ Query_arena::Type Statement::type() const /* - Return a valid database name: - - validated with Lex_ident_db::check_db_name() - - optionally converted to lower-case + Return an internal database name: + - validated with Lex_ident_db::check_name() + - optionally converted to lower-case when lower_case_table_names==1 The lower-cased copy is made on mem_root when needed. An error is raised in case of EOM or a bad database name. @@ -4062,7 +4063,7 @@ Query_arena::to_ident_db_opt_casedn_with_error(const LEX_CSTRING &src, const LEX_CSTRING tmp= casedn ? make_ident_casedn(src) : src; if (!tmp.str /*EOM*/ || - Lex_ident_fs(tmp).check_db_name_with_error()) + Lex_ident_db::check_name_with_error(tmp)) return Lex_ident_db(); return Lex_ident_db(tmp.str, tmp.length); @@ -4202,7 +4203,9 @@ Statement_map::Statement_map() : my_hash_init(key_memory_prepared_statement_map, &st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0, get_statement_id_as_hash_key, delete_statement_as_hash_key, MYF(0)); - my_hash_init(key_memory_prepared_statement_map, &names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0, + my_hash_init(key_memory_prepared_statement_map, &names_hash, + Lex_ident_ps::charset_info(), + START_NAME_HASH_SIZE, 0, 0, (my_hash_get_key) get_stmt_name_hash_key, NULL, MYF(0)); } @@ -4689,12 +4692,11 @@ change_security_context(THD *thd, *backup= NULL; needs_change= (strcmp(definer_user->str, thd->security_ctx->priv_user) || - my_strcasecmp(system_charset_info, definer_host->str, - thd->security_ctx->priv_host)); + !Lex_ident_host(*definer_host). + streq(Lex_cstring_strlen(thd->security_ctx->priv_host))); if (needs_change) { - if (acl_getroot(this, definer_user->str, definer_host->str, - definer_host->str, db->str)) + if (acl_getroot(this, *definer_user, *definer_host, *definer_host, *db)) { my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str, definer_host->str); @@ -4724,11 +4726,12 @@ bool Security_context::user_matches(Security_context *them) !strcmp(user, them->user)); } -bool Security_context::is_priv_user(const char *user, const char *host) +bool Security_context::is_priv_user(const LEX_CSTRING &user, + const LEX_CSTRING &host) { - return ((user != NULL) && (host != NULL) && - !strcmp(user, priv_user) && - !my_strcasecmp(system_charset_info, host,priv_host)); + return ((user.str != NULL) && (host.str != NULL) && + !strcmp(user.str, priv_user) && + Lex_ident_host(host).streq(Lex_cstring_strlen(priv_host))); } @@ -8365,16 +8368,18 @@ void AUTHID::parse(const char *str, size_t length) bool Database_qualified_name::copy_sp_name_internal(MEM_ROOT *mem_root, - const LEX_CSTRING &db, + const Lex_ident_db &db, const LEX_CSTRING &name) { DBUG_ASSERT(db.str); DBUG_ASSERT(name.str); - m_db= lower_case_table_names == 1 ? - lex_string_casedn_root(mem_root, &my_charset_utf8mb3_general_ci, - db.str, db.length) : - lex_string_strmake_root(mem_root, db.str, db.length); - m_name= lex_string_strmake_root(mem_root, name.str, name.length); + m_db= Lex_ident_db(lower_case_table_names == 1 ? + lex_string_casedn_root(mem_root, + &my_charset_utf8mb3_general_ci, + db.str, db.length) : + lex_string_strmake_root(mem_root, + db.str, db.length)); + m_name= Lex_cstring(lex_string_strmake_root(mem_root, name.str, name.length)); return m_db.str == NULL || m_name.str == NULL; // check if EOM } diff --git a/sql/sql_class.h b/sql/sql_class.h index c1efb49f6da..cc72cf44e95 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -330,7 +330,7 @@ typedef struct st_copy_info { class Key_part_spec :public Sql_alloc { public: - Lex_ident field_name; + Lex_ident_column field_name; uint length; bool generated, asc; Key_part_spec(const LEX_CSTRING *name, uint len, bool gen= false) @@ -365,13 +365,15 @@ public: class Alter_drop :public Sql_alloc { public: enum drop_type { KEY, COLUMN, FOREIGN_KEY, CHECK_CONSTRAINT, PERIOD }; - const char *name; + Lex_ident_column name; enum drop_type type; bool drop_if_exists; - Alter_drop(enum drop_type par_type,const char *par_name, bool par_exists) + Alter_drop(enum drop_type par_type, + const LEX_CSTRING &par_name, + bool par_exists) :name(par_name), type(par_type), drop_if_exists(par_exists) { - DBUG_ASSERT(par_name != NULL); + DBUG_ASSERT(par_name.str != NULL); } /** Used to make a clone of this object for ALTER/CREATE TABLE @@ -416,8 +418,8 @@ public: class Alter_rename_key : public Sql_alloc { public: - LEX_CSTRING old_name; - LEX_CSTRING new_name; + const Lex_ident_column old_name; + const Lex_ident_column new_name; bool alter_if_exists; Alter_rename_key(LEX_CSTRING old_name_arg, LEX_CSTRING new_name_arg, bool exists) @@ -433,13 +435,14 @@ public: class Alter_index_ignorability: public Sql_alloc { public: - Alter_index_ignorability(const char *name, bool is_ignored, bool if_exists) : + Alter_index_ignorability(const LEX_CSTRING &name, + bool is_ignored, bool if_exists) : m_name(name), m_is_ignored(is_ignored), m_if_exists(if_exists) { - assert(name != NULL); + DBUG_ASSERT(name.str != NULL); } - const char *name() const { return m_name; } + const Lex_ident_column &name() const { return m_name; } bool if_exists() const { return m_if_exists; } /* The ignorability after the operation is performed. */ @@ -448,7 +451,7 @@ public: { return new (mem_root) Alter_index_ignorability(*this); } private: - const char *m_name; + const Lex_ident_column m_name; bool m_is_ignored; bool m_if_exists; }; @@ -461,13 +464,13 @@ public: enum Keytype type; KEY_CREATE_INFO key_create_info; List columns; - LEX_CSTRING name; + Lex_ident_column name; engine_option_value *option_list; bool generated; bool invisible; bool without_overlaps; bool old; - Lex_ident period; + Lex_ident_column period; Key(enum Keytype type_par, const LEX_CSTRING *name_arg, ha_key_alg algorithm_arg, bool generated_arg, DDL_options_st ddl_options) @@ -1419,6 +1422,18 @@ public: lex_string_strmake_root(mem_root, src.str, src.length); } + template + Lex_ident_XXX lex_ident_copy(const Lex_ident_XXX &src) + { + return Lex_ident_XXX(strmake_lex_cstring(src)); + } + + template + Lex_ident_XXX lex_ident_casedn(const Lex_ident_XXX &src) + { + return Lex_ident_XXX(make_ident_casedn(src)); + } + /* Convert a LEX_CSTRING to a valid database name: - validated with Lex_ident_fs::check_db_name() @@ -1436,7 +1451,7 @@ public: /* Convert a LEX_CSTRING to a valid internal database name: - - validated with Lex_ident_fs::check_db_name() + - validated with Lex_ident_db::check_name() - optionally lower-cased when lower_case_table_names==1 The lower-cased copy is created on Query_arena::mem_root, when needed. @@ -1786,7 +1801,7 @@ public: @return True if the security context fulfills the access requirements. */ bool check_access(const privilege_t want_access, bool match_any = false); - bool is_priv_user(const char *user, const char *host); + bool is_priv_user(const LEX_CSTRING &user, const LEX_CSTRING &host); }; @@ -5511,19 +5526,20 @@ public: TABLE *create_and_open_tmp_table(LEX_CUSTRING *frm, const char *path, - const char *db, - const char *table_name, + const Lex_ident_db &db, + const Lex_ident_table &table_name, bool open_internal_tables); - TABLE *find_temporary_table(const char *db, const char *table_name, + TABLE *find_temporary_table(const Lex_ident_db &db, + const Lex_ident_table &table_name, Temporary_table_state state= TMP_TABLE_IN_USE); TABLE *find_temporary_table(const TABLE_LIST *tl, Temporary_table_state state= TMP_TABLE_IN_USE); TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key, uint key_length); - TMP_TABLE_SHARE *find_tmp_table_share(const char *db, - const char *table_name); + TMP_TABLE_SHARE *find_tmp_table_share(const Lex_ident_db &db, + const Lex_ident_table &table_name); TMP_TABLE_SHARE *find_tmp_table_share(const TABLE_LIST *tl); TMP_TABLE_SHARE *find_tmp_table_share(const char *key, size_t key_length); @@ -5546,14 +5562,16 @@ private: /* Whether a lock has been acquired? */ bool m_tmp_tables_locked; - uint create_tmp_table_def_key(char *key, const char *db, - const char *table_name); + uint create_tmp_table_def_key(char *key, const Lex_ident_db &db, + const Lex_ident_table &table_name); TMP_TABLE_SHARE *create_temporary_table(LEX_CUSTRING *frm, - const char *path, const char *db, - const char *table_name); + const char *path, + const Lex_ident_db &db, + const Lex_ident_table &table_name); TABLE *find_temporary_table(const char *key, uint key_length, Temporary_table_state state); - TABLE *open_temporary_table(TMP_TABLE_SHARE *share, const char *alias); + TABLE *open_temporary_table(TMP_TABLE_SHARE *share, + const Lex_ident_table &alias); bool find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table); bool use_temporary_table(TABLE *table, TABLE **out_table); void close_temporary_table(TABLE *table); @@ -7316,7 +7334,7 @@ public: bool append_to(THD *thd, String *to) const; /* Convert Table_ident::m_db to a valid internal database name: - - validated with Lex_ident_fs::check_db_name() + - validated with Lex_ident_db::check_name() - optionally lower-cased when lower_case_table_names==1 @param arena - the arena to allocate the lower-cased copy on, when needed. @@ -7330,7 +7348,7 @@ public: class Qualified_column_ident: public Table_ident { public: - LEX_CSTRING m_column; + const Lex_ident_column m_column; public: Qualified_column_ident(const LEX_CSTRING *column) :Table_ident(&null_clex_str), @@ -8097,47 +8115,32 @@ public: class Database_qualified_name { public: - LEX_CSTRING m_db; - LEX_CSTRING m_name; - Database_qualified_name(const LEX_CSTRING *db, const LEX_CSTRING *name) - :m_db(*db), m_name(*name) + Lex_ident_db m_db; + Lex_cstring m_name; // no comparison semantics + Database_qualified_name() { } - Database_qualified_name(const LEX_CSTRING &db, const LEX_CSTRING &name) + Database_qualified_name(const Lex_ident_db &db, const LEX_CSTRING &name) :m_db(db), m_name(name) { } - Database_qualified_name(const char *db, size_t db_length, - const char *name, size_t name_length) - { - m_db.str= db; - m_db.length= db_length; - m_name.str= name; - m_name.length= name_length; - } Identifier_chain2 to_identifier_chain2() const { return Identifier_chain2(m_db, m_name); } - bool eq(const Database_qualified_name *other) const + + bool eq_routine_name(const Database_qualified_name *other) const { - CHARSET_INFO *cs= lower_case_table_names ? - &my_charset_utf8mb3_general_ci : - &my_charset_utf8mb3_bin; - return - m_db.length == other->m_db.length && - m_name.length == other->m_name.length && - !cs->strnncoll(m_db.str, m_db.length, - other->m_db.str, other->m_db.length) && - !cs->strnncoll(m_name.str, m_name.length, - other->m_name.str, other->m_name.length); + + return m_db.streq(other->m_db) && + Lex_ident_routine(m_name).streq(other->m_name); } /* Make copies of "db" and "name" on the memory root in internal format: - Lower-case "db" if lower-case-table-names==1. - Preserve "name" as is. */ - bool copy_sp_name_internal(MEM_ROOT *mem_root, const LEX_CSTRING &db, + bool copy_sp_name_internal(MEM_ROOT *mem_root, const Lex_ident_db &db, const LEX_CSTRING &name); bool make_package_routine_name(MEM_ROOT *mem_root, diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index a802fb2736e..ba012c9f543 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -323,7 +323,8 @@ void init_max_user_conn(void) { #ifndef NO_EMBEDDED_ACCESS_CHECKS my_hash_init(key_memory_user_conn, &hash_user_connections, - system_charset_info, max_connections, 0, 0, (my_hash_get_key) + USER_CONN::user_host_key_charset_info_for_hash(), + max_connections, 0, 0, (my_hash_get_key) get_key_conn, (my_hash_free_key) free_user, 0); #endif } @@ -483,14 +484,18 @@ void init_user_stats(USER_STATS *user_stats, void init_global_user_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_user_stats, system_charset_info, max_connections, + my_hash_init(PSI_INSTRUMENT_ME, &global_user_stats, + USER_STATS::user_key_charset_info_for_hash(), + max_connections, 0, 0, (my_hash_get_key) get_key_user_stats, (my_hash_free_key) free_user_stats, 0); } void init_global_client_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_client_stats, system_charset_info, max_connections, + my_hash_init(PSI_INSTRUMENT_ME, &global_client_stats, + USER_STATS::user_key_charset_info_for_hash(), + max_connections, 0, 0, (my_hash_get_key) get_key_user_stats, (my_hash_free_key) free_user_stats, 0); } @@ -509,7 +514,8 @@ extern "C" void free_table_stats(TABLE_STATS* table_stats) void init_global_table_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_table_stats, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &global_table_stats, + Lex_ident_fs::charset_info(), max_connections, 0, 0, (my_hash_get_key) get_key_table_stats, (my_hash_free_key) free_table_stats, 0); } @@ -528,7 +534,8 @@ extern "C" void free_index_stats(INDEX_STATS* index_stats) void init_global_index_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_index_stats, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &global_index_stats, + Lex_ident_fs::charset_info(), max_connections, 0, 0, (my_hash_get_key) get_key_index_stats, (my_hash_free_key) free_index_stats, 0); } diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 5b3db9bca1d..b7664799c2c 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -291,8 +291,7 @@ bool With_clause::check_dependencies() elem != with_elem; elem= elem->next) { - if (lex_string_cmp(system_charset_info, with_elem->get_name(), - elem->get_name()) == 0) + if (with_elem->get_name().streq(elem->get_name())) { my_error(ER_DUP_QUERY_NAME, MYF(0), with_elem->get_name_str()); @@ -414,8 +413,7 @@ With_element *With_clause::find_table_def(TABLE_LIST *table, { if (excl_spec && with_elem->spec == excl_spec) continue; - if (my_strcasecmp(system_charset_info, with_elem->get_name_str(), - table->table_name.str) == 0 && + if (with_elem->get_name().streq(table->table_name) && !table->is_fqtn) { table->set_derived(); diff --git a/sql/sql_cte.h b/sql/sql_cte.h index 1da7c6c323a..490678ddb25 100644 --- a/sql/sql_cte.h +++ b/sql/sql_cte.h @@ -36,7 +36,7 @@ struct st_unit_ctxt_elem; class With_element_head : public Sql_alloc { /* The name of the defined CTE */ - LEX_CSTRING *query_name; + const Lex_ident_with_element query_name; public: /* @@ -47,7 +47,7 @@ public: */ TABLE_CHAIN tables_pos; - With_element_head(LEX_CSTRING *name) + With_element_head(const Lex_ident_with_element &name) : query_name(name) { tables_pos.set_start_pos(0); @@ -224,8 +224,8 @@ public: level(0), rec_result(NULL) { unit->with_element= this; } - LEX_CSTRING *get_name() { return head->query_name; } - const char *get_name_str() { return get_name()->str; } + const Lex_ident_with_element get_name() const { return head->query_name; } + const char *get_name_str() const { return get_name().str; } void set_tables_start_pos(TABLE_LIST **pos) { head->tables_pos.set_start_pos(pos); } diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index cef8ac161df..999c6961cc7 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -273,8 +273,9 @@ int Materialized_cursor::send_result_set_metadata( Item_ident *ident= static_cast(item_dst); Send_field send_field(thd, item_org); - ident->db_name= thd->strmake_lex_cstring(send_field.db_name); - ident->table_name= thd->strmake_lex_cstring(send_field.table_name); + ident->db_name= Lex_ident_db(thd->strmake_lex_cstring(send_field.db_name)); + ident->table_name= Lex_ident_table(thd->strmake_lex_cstring( + send_field.table_name)); } /* diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 484861512e4..0eeec41342e 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -98,12 +98,10 @@ typedef struct my_dbopt_st */ static inline bool -cmp_db_names(LEX_CSTRING *db1_name, const LEX_CSTRING *db2_name) +cmp_db_names(const Lex_ident_db &db1_name, const Lex_ident_db &db2_name) { - return (db1_name->length == db2_name->length && - (db1_name->length == 0 || - my_strcasecmp(table_alias_charset, - db1_name->str, db2_name->str) == 0)); + return (db1_name.length == 0 && db2_name.length == 0) || + db1_name.streq(db2_name); } #ifdef HAVE_PSI_INTERFACE @@ -1087,8 +1085,7 @@ mysql_rm_db_internal(THD *thd, const Lex_ident_db &db, bool if_exists, Disable drop of enabled log tables, must be done before name locking. This check is only needed if we are dropping the "mysql" database. */ - if ((rm_mysql_schema= - (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db.str) == 0))) + if ((rm_mysql_schema= MYSQL_SCHEMA_NAME.streq(db))) { for (table= tables; table; table= table->next_local) if (check_if_log_table(table, TRUE, "DROP")) @@ -1291,7 +1288,8 @@ exit: SELECT DATABASE() in the future). For this we free() thd->db and set it to 0. */ - if (unlikely(thd->db.str && cmp_db_names(&thd->db, &db) && !error)) + if (unlikely(thd->db.str && + cmp_db_names(Lex_ident_db(thd->db), db) && !error)) { mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); thd->session_tracker.current_schema.mark_as_changed(thd); @@ -1332,7 +1330,7 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, for (size_t idx=0; idx < files.elements(); idx++) { - LEX_CSTRING *table= files.at(idx); + const LEX_CSTRING *table= files.at(idx); /* Drop the table nicely */ TABLE_LIST *table_list=(TABLE_LIST*)thd->calloc(sizeof(*table_list)); @@ -1346,8 +1344,8 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, as well to look up the cache properly. */ table_list->table_name= lower_case_file_system ? - thd->make_ident_casedn(*table) : - *table; + Lex_ident_table(thd->make_ident_casedn(*table)) : + Lex_ident_table(*table); table_list->open_type= OT_BASE_ONLY; @@ -1641,7 +1639,7 @@ static void backup_current_db_name(THD *thd, - new_db_name is NULL or empty; - OR new database name is invalid - (check_db_name() failed); + (Lex_ident_db::check_name() failed); - OR user has no privilege on the new database; @@ -1655,8 +1653,9 @@ static void backup_current_db_name(THD *thd, succeed. - if new database name is invalid - (check_db_name() failed), the current database - will be NULL, @@collation_database will be set to + (Lex_ident_db::check_name() failed), + the current database will be NULL, + @@collation_database will be set to @@collation_server, but the operation will fail; - user privileges will not be checked @@ -1745,7 +1744,8 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, *new_db_name; /* - NOTE: if check_db_name() fails, we should throw an error in any case, + NOTE: if Lex_ident_db::check_name() fails, + we should throw an error in any case, even if we are called from sp_head::execute(). It's next to impossible however to get this error when we are called @@ -1754,7 +1754,7 @@ uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name, The cast below ok here as new_db_file_name was just allocated */ - if (Lex_ident_fs(new_db_file_name).check_db_name_with_error()) + if (Lex_ident_db::check_name_with_error(new_db_file_name)) { if (force_switch) mysql_change_db_impl(thd, NULL, NO_ACL, thd->variables.collation_server); @@ -1871,7 +1871,8 @@ bool mysql_opt_change_db(THD *thd, bool force_switch, bool *cur_db_changed) { - *cur_db_changed= !cmp_db_names(&thd->db, new_db_name); + *cur_db_changed= !cmp_db_names(Lex_ident_db(thd->db), + Lex_ident_db(*new_db_name)); if (!*cur_db_changed) return FALSE; @@ -2059,7 +2060,8 @@ bool mysql_upgrade_db(THD *thd, const Lex_ident_db &old_db) DBUG_PRINT("info",("Examining: %s", file->name)); /* skiping MY_DB_OPT_FILE */ - if (!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE)) + if (!files_charset_info->strnncoll(Lex_cstring_strlen(file->name), + Lex_cstring_strlen(MY_DB_OPT_FILE))) continue; /* pass empty file name, and file->name as extension to avoid encoding */ diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 406f67ff955..a066417b28e 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -646,9 +646,8 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, { /* Check if same as last keyname. If not, do a full lookup */ if (handler->keyno < 0 || - my_strcasecmp(&my_charset_latin1, - keyname, - table->s->key_info[handler->keyno].name.str)) + !Lex_ident_column(Lex_cstring_strlen(keyname)). + streq(table->s->key_info[handler->keyno].name)) { if ((handler->keyno= find_type(keyname, &table->s->keynames, FIND_TYPE_NO_PREFIX) - 1) < 0) @@ -1081,10 +1080,8 @@ static SQL_HANDLER *mysql_ha_find_match(THD *thd, TABLE_LIST *tables) if (tables->is_anonymous_derived_table()) continue; if ((! tables->db.str[0] || - ! my_strcasecmp(&my_charset_latin1, hash_tables->db.str, - tables->get_db_name())) && - ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name.str, - tables->get_table_name())) + tables->get_db_name().streq(hash_tables->db)) && + tables->get_table_name().streq(hash_tables->table_name)) { /* Link into hash_tables list */ hash_tables->next= head; diff --git a/sql/sql_i_s.h b/sql/sql_i_s.h index 263031ae2c9..12cec39ad71 100644 --- a/sql/sql_i_s.h +++ b/sql/sql_i_s.h @@ -88,14 +88,14 @@ public: class ST_FIELD_INFO: public Show::Type { protected: - LEX_CSTRING m_name; // I_S column name + Lex_ident_column m_name; // I_S column name enum_nullability m_nullability; // NULLABLE or NOT NULL - LEX_CSTRING m_old_name; // SHOW column name + Lex_ident_column m_old_name; // SHOW column name enum_show_open_table m_open_method; public: - ST_FIELD_INFO(const LEX_CSTRING &name, const Type &type, + ST_FIELD_INFO(const Lex_ident_column &name, const Type &type, enum_nullability nullability, - LEX_CSTRING &old_name, + const Lex_ident_column &old_name, enum_show_open_table open_method) :Type(type), m_name(name), m_nullability(nullability), @@ -106,18 +106,14 @@ public: enum_nullability nullability, const char *old_name, enum_show_open_table open_method) - :Type(type), + :Type(type), m_name(Lex_cstring_strlen(name)), m_nullability(nullability), + m_old_name(Lex_cstring_strlen(old_name)), m_open_method(open_method) - { - m_name.str= name; - m_name.length= safe_strlen(name); - m_old_name.str= old_name; - m_old_name.length= safe_strlen(old_name); - } - const LEX_CSTRING &name() const { return m_name; } + { } + const Lex_ident_column &name() const { return m_name; } bool nullable() const { return m_nullability == NULLABLE; } - const LEX_CSTRING &old_name() const { return m_old_name; } + const Lex_ident_column &old_name() const { return m_old_name; } enum_show_open_table open_method() const { return m_open_method; } bool end_marker() const { return m_name.str == NULL; } }; @@ -329,7 +325,7 @@ typedef class Item COND; typedef struct st_schema_table { - const char *table_name; + Lex_ident_i_s_table table_name; ST_FIELD_INFO *fields_info; /* for FLUSH table_name */ int (*reset_table) (); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ccb5a7de1eb..d904732036f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2612,7 +2612,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, /* Replace volatile strings with local copies */ di->table_list.alias.str= di->table_list.table_name.str= di->thd.query(); di->table_list.alias.length= di->table_list.table_name.length= di->thd.query_length(); - di->table_list.db= di->thd.db; + di->table_list.db= Lex_ident_db(di->thd.db); /* Nulify select_lex because, if the thread that spawned the current one disconnects, the select_lex will point to freed memory. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ac2fe5f4537..d8c5306ca78 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -578,7 +578,7 @@ void LEX::init_last_field(Column_definition *field, const LEX_CSTRING *field_name) { last_field= field; - field->field_name= *field_name; + field->field_name= Lex_ident_column(*field_name); } @@ -7431,9 +7431,7 @@ bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock, sp_label *splabel; if (unlikely(sp_block_finalize(thd, spblock, &splabel))) return true; - if (unlikely(end_label->str && - lex_string_cmp(system_charset_info, - end_label, &splabel->name) != 0)) + if (unlikely(end_label->str && !splabel->name.streq(*end_label))) { my_error(ER_SP_LABEL_MISMATCH, MYF(0), end_label->str); return true; @@ -7446,7 +7444,7 @@ sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name) { sp_name *res; Lex_ident_db_normalized db; - if (unlikely(check_routine_name(&name)) || + if (unlikely(Lex_ident_routine::check_name_with_error(name)) || unlikely(!(db= copy_db_normalized()).str) || unlikely((!(res= new (thd->mem_root) sp_name(db, name, false))))) return NULL; @@ -7488,7 +7486,7 @@ sp_name *LEX::make_sp_name(THD *thd, const Lex_ident_sys_st &name1, const Lex_ident_db_normalized norm_name1= thd->to_ident_db_normalized_with_error(name1); if (unlikely(!norm_name1.str) || - unlikely(check_routine_name(&name2)) || + unlikely(Lex_ident_routine::check_name_with_error(name2)) || unlikely(!(res= new (thd->mem_root) sp_name(norm_name1, name2, true)))) return NULL; return res; @@ -8012,9 +8010,7 @@ bool LEX::sp_pop_loop_label(THD *thd, const LEX_CSTRING *label_name) { sp_label *lab= spcont->pop_label(); sphead->backpatch(lab); - if (label_name->str && - lex_string_cmp(system_charset_info, label_name, - &lab->name) != 0) + if (label_name->str && !lab->name.streq(*label_name)) { my_error(ER_SP_LABEL_MISMATCH, MYF(0), label_name->str); return true; @@ -8447,13 +8443,9 @@ Item *LEX::create_item_ident(THD *thd, if ((thd->variables.sql_mode & MODE_ORACLE) && b.length == 7) { - if (!system_charset_info->strnncoll( - (const uchar *) b.str, 7, - (const uchar *) "NEXTVAL", 7)) + if (Lex_ident_column(b).streq("NEXTVAL"_Lex_ident_column)) return create_item_func_nextval(thd, &null_clex_str, &a); - else if (!system_charset_info->strnncoll( - (const uchar *) b.str, 7, - (const uchar *) "CURRVAL", 7)) + else if (Lex_ident_column(b).streq("CURRVAL"_Lex_ident_column)) return create_item_func_lastval(thd, &null_clex_str, &a); } @@ -8470,13 +8462,9 @@ Item *LEX::create_item_ident(THD *thd, Lex_ident_sys() : *a; if ((thd->variables.sql_mode & MODE_ORACLE) && c->length == 7) { - if (!system_charset_info->strnncoll( - (const uchar *) c->str, 7, - (const uchar *) "NEXTVAL", 7)) + if (Lex_ident_column(*c).streq("NEXTVAL"_Lex_ident_column)) return create_item_func_nextval(thd, a, b); - else if (!system_charset_info->strnncoll( - (const uchar *) c->str, 7, - (const uchar *) "CURRVAL", 7)) + else if (Lex_ident_column(*c).streq("CURRVAL"_Lex_ident_column)) return create_item_func_lastval(thd, a, b); } @@ -9406,7 +9394,7 @@ bool LEX::add_create_view(THD *thd, DDL_options_st ddl, bool LEX::call_statement_start(THD *thd, sp_name *name) { - Database_qualified_name pkgname(&null_clex_str, &null_clex_str); + Database_qualified_name pkgname; const Sp_handler *sph= &sp_handler_procedure; sql_command= SQLCOM_CALL; value_list.empty(); @@ -9443,7 +9431,6 @@ bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *proc) { DBUG_ASSERT(db->str); - Database_qualified_name q_db_pkg(db, pkg); Identifier_chain2 q_pkg_proc(*pkg, *proc); sp_name *spname; @@ -9451,10 +9438,12 @@ bool LEX::call_statement_start(THD *thd, const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(*db); if (!dbn.str || - check_routine_name(pkg) || - check_routine_name(proc)) + Lex_ident_routine::check_name_with_error(*pkg) || + Lex_ident_routine::check_name_with_error(*proc)) return true; + Database_qualified_name q_db_pkg(dbn, *pkg); + // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_proc; if (!(pkg_dot_proc= q_pkg_proc.make_qname(thd->mem_root)).str || @@ -9540,8 +9529,7 @@ bool LEX::create_package_finalize(THD *thd, { if (name2 && (name2->m_explicit_name != name->m_explicit_name || - strcmp(name2->m_db.str, name->m_db.str) || - !Sp_handler::eq_routine_name(name2->m_name, name->m_name))) + !name2->eq_routine_name(name))) { bool exp= name2->m_explicit_name || name->m_explicit_name; my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), @@ -9597,8 +9585,9 @@ LEX::find_func_schema_by_name_or_error(const Lex_ident_sys &schema, Schema *res= Schema::find_by_name(schema); if (res) return res; - Database_qualified_name qname(schema, func); - my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), ErrConvDQName(&qname).ptr()); + char err_buffer[MYSQL_ERRMSG_SIZE]; + Identifier_chain2(schema, func).make_qname(err_buffer, sizeof(err_buffer)); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), err_buffer); return NULL; } @@ -9827,6 +9816,19 @@ Item *LEX::make_item_func_call_generic(THD *thd, const Lex_ident_sys &db, const Lex_ident_sys &name, List *args) +{ + const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db); + if (!db_int.str || Lex_ident_routine::check_name_with_error(name)) + return NULL; + return make_item_func_call_generic(thd, db_int, + Lex_ident_routine(name), args); +} + + +Item *LEX::make_item_func_call_generic(THD *thd, + const Lex_ident_db &db, + const Lex_ident_routine &name, + List *args) { const Schema *schema= Schema::find_by_name(db); if (schema) @@ -9836,7 +9838,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, DBUG_ASSERT(builder); const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(db); - if (!dbn.str || check_routine_name(&name)) + if (!dbn.str || Lex_ident_routine::check_name_with_error(name)) return NULL; return builder->create_with_db(thd, dbn, name, true, args); @@ -9854,9 +9856,7 @@ Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cfunc, List *args) { - static Lex_cstring dot(".", 1); Lex_ident_sys db(thd, cdb), pkg(thd, cpkg), func(thd, cfunc); - Database_qualified_name q_db_pkg(db, pkg); Identifier_chain2 q_pkg_func(pkg, func); sp_name *qname; @@ -9865,10 +9865,12 @@ Item *LEX::make_item_func_call_generic(THD *thd, const Lex_ident_db_normalized dbn= thd->to_ident_db_normalized_with_error(db); if (!dbn.str || - check_routine_name(&pkg) || - check_routine_name(&func)) + Lex_ident_routine::check_name_with_error(pkg) || + Lex_ident_routine::check_name_with_error(func)) return NULL; + Database_qualified_name q_db_pkg(dbn, pkg); + // Concat `pkg` and `name` to `pkg.name` LEX_CSTRING pkg_dot_func; if (!(pkg_dot_func= q_pkg_func.make_qname(thd->mem_root)).str || @@ -10081,7 +10083,7 @@ bool LEX::part_values_history(THD *thd) #endif /* WITH_PARTITION_STORAGE_ENGINE */ -bool LEX::last_field_generated_always_as_row_start_or_end(Lex_ident *p, +bool LEX::last_field_generated_always_as_row_start_or_end(Lex_ident_column *p, const char *type, uint flag) { @@ -10102,7 +10104,7 @@ bool LEX::last_field_generated_always_as_row_start_or_end(Lex_ident *p, bool LEX::last_field_generated_always_as_row_start() { Vers_parse_info &info= vers_get_info(); - Lex_ident *p= &info.as_row.start; + Lex_ident_column *p= &info.as_row.start; return last_field_generated_always_as_row_start_or_end(p, "START", VERS_ROW_START); } @@ -10111,7 +10113,7 @@ bool LEX::last_field_generated_always_as_row_start() bool LEX::last_field_generated_always_as_row_end() { Vers_parse_info &info= vers_get_info(); - Lex_ident *p= &info.as_row.end; + Lex_ident_column *p= &info.as_row.end; return last_field_generated_always_as_row_start_or_end(p, "END", VERS_ROW_END); } @@ -11763,8 +11765,7 @@ bool LEX::stmt_alter_table(Table_ident *table) } else if (copy_db_to(&first_select_lex()->db)) return true; - if (unlikely(check_table_name(table->table.str, table->table.length, - false))) + if (unlikely(Lex_ident_table::check_name(table->table, false))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); return true; @@ -11853,7 +11854,7 @@ bool LEX::stmt_drop_routine(const Sp_handler *sph, my_error(ER_SP_NO_DROP_SP, MYF(0), sph->type_lex_cstring().str); return true; } - if (check_routine_name(&name)) + if (Lex_ident_routine::check_name_with_error(name)) return true; enum_sql_command sqlcom= sph->sqlcom_drop(); Lex_ident_db_normalized dbn; @@ -11869,7 +11870,6 @@ bool LEX::stmt_drop_routine(const Sp_handler *sph, There is no an explicit database name in the DROP statement. Two cases are possible: a. The current database is not NULL. - copy_db_to() copies the current database to db_int. b. The current database is NULL and the command is either of these: - DROP PACKAGE - DROP PACKAGE BODY diff --git a/sql/sql_lex.h b/sql/sql_lex.h index eda162dba7f..c22d93fee7a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -588,15 +588,13 @@ public: The index name. Empty (str=NULL) name represents an empty list USE INDEX () clause */ - LEX_CSTRING key_name; + const Lex_ident_column key_name; Index_hint (enum index_hint_type type_arg, index_clause_map clause_arg, const char *str, size_t length) : - type(type_arg), clause(clause_arg) - { - key_name.str= str; - key_name.length= length; - } + type(type_arg), clause(clause_arg), + key_name(str, length) + { } void print(THD *thd, String *str); }; @@ -3889,7 +3887,7 @@ public: bool restore_set_statement_var(); void init_last_field(Column_definition *field, const LEX_CSTRING *name); - bool last_field_generated_always_as_row_start_or_end(Lex_ident *p, + bool last_field_generated_always_as_row_start_or_end(Lex_ident_column *p, const char *type, uint flags); bool last_field_generated_always_as_row_start(); @@ -4251,6 +4249,10 @@ public: const Lex_ident_sys &db, const Lex_ident_sys &name, List *args); + Item *make_item_func_call_generic(THD *thd, + const Lex_ident_db &db, + const Lex_ident_routine &name, + List *args); Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db, Lex_ident_cli_st *pkg, @@ -4529,7 +4531,7 @@ public: bool add_constraint(const LEX_CSTRING &name, Virtual_column_info *constr, bool if_not_exists) { - constr->name= name; + constr->name= Lex_ident_column(name); constr->if_not_exists= if_not_exists; alter_info.check_constraint_list.push_back(constr); return false; @@ -4720,14 +4722,15 @@ public: } } - int add_period(Lex_ident name, Lex_ident_sys_st start, Lex_ident_sys_st end) + int add_period(Lex_ident_column name, + Lex_ident_sys_st start, Lex_ident_sys_st end) { if (check_period_name(name.str)) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), name.str); return 1; } - if (lex_string_cmp(system_charset_info, &start, &end) == 0) + if (Lex_ident_column(start).streq(end)) { my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), start.str); return 1; @@ -4743,7 +4746,7 @@ public: my_error(ER_MORE_THAN_ONE_PERIOD, MYF(0)); return 1; } - info.set_period(start, end); + info.set_period(Lex_ident_column(start), Lex_ident_column(end)); info.name= name; info.constr= new Virtual_column_info(); diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index bf32e99841b..a390af951fb 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -88,7 +88,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ar_AE = MY_LOCALE my_locale_ar_AE ( 6, - "ar_AE", + "ar_AE"_Lex_ident_locale, "Arabic - United Arab Emirates", FALSE, &my_locale_typelib_month_names_ar_AE, @@ -124,7 +124,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ar_BH = MY_LOCALE my_locale_ar_BH ( 7, - "ar_BH", + "ar_BH"_Lex_ident_locale, "Arabic - Bahrain", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -160,7 +160,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ar_JO = MY_LOCALE my_locale_ar_JO ( 8, - "ar_JO", + "ar_JO"_Lex_ident_locale, "Arabic - Jordan", FALSE, &my_locale_typelib_month_names_ar_JO, @@ -196,7 +196,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ar_SA = MY_LOCALE my_locale_ar_SA ( 9, - "ar_SA", + "ar_SA"_Lex_ident_locale, "Arabic - Saudi Arabia", FALSE, &my_locale_typelib_month_names_ar_SA, @@ -232,7 +232,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ar_SY = MY_LOCALE my_locale_ar_SY ( 10, - "ar_SY", + "ar_SY"_Lex_ident_locale, "Arabic - Syria", FALSE, &my_locale_typelib_month_names_ar_SY, @@ -268,7 +268,7 @@ static TYPELIB my_locale_typelib_ab_day_names_be_BY = MY_LOCALE my_locale_be_BY ( 11, - "be_BY", + "be_BY"_Lex_ident_locale, "Belarusian - Belarus", FALSE, &my_locale_typelib_month_names_be_BY, @@ -304,7 +304,7 @@ static TYPELIB my_locale_typelib_ab_day_names_bg_BG = MY_LOCALE my_locale_bg_BG ( 12, - "bg_BG", + "bg_BG"_Lex_ident_locale, "Bulgarian - Bulgaria", FALSE, &my_locale_typelib_month_names_bg_BG, @@ -340,7 +340,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ca_ES = MY_LOCALE my_locale_ca_ES ( 13, - "ca_ES", + "ca_ES"_Lex_ident_locale, "Catalan - Catalan", FALSE, &my_locale_typelib_month_names_ca_ES, @@ -376,7 +376,7 @@ static TYPELIB my_locale_typelib_ab_day_names_cs_CZ = MY_LOCALE my_locale_cs_CZ ( 14, - "cs_CZ", + "cs_CZ"_Lex_ident_locale, "Czech - Czech Republic", FALSE, &my_locale_typelib_month_names_cs_CZ, @@ -412,7 +412,7 @@ static TYPELIB my_locale_typelib_ab_day_names_da_DK = MY_LOCALE my_locale_da_DK ( 15, - "da_DK", + "da_DK"_Lex_ident_locale, "Danish - Denmark", FALSE, &my_locale_typelib_month_names_da_DK, @@ -448,7 +448,7 @@ static TYPELIB my_locale_typelib_ab_day_names_de_AT = MY_LOCALE my_locale_de_AT ( 16, - "de_AT", + "de_AT"_Lex_ident_locale, "German - Austria", FALSE, &my_locale_typelib_month_names_de_AT, @@ -484,7 +484,7 @@ static TYPELIB my_locale_typelib_ab_day_names_de_DE = MY_LOCALE my_locale_de_DE ( 4, - "de_DE", + "de_DE"_Lex_ident_locale, "German - Germany", FALSE, &my_locale_typelib_month_names_de_DE, @@ -520,7 +520,7 @@ static TYPELIB my_locale_typelib_ab_day_names_en_US = MY_LOCALE my_locale_en_US ( 0, - "en_US", + "en_US"_Lex_ident_locale, "English - United States", TRUE, &my_locale_typelib_month_names_en_US, @@ -556,7 +556,7 @@ static TYPELIB my_locale_typelib_ab_day_names_es_ES = MY_LOCALE my_locale_es_ES ( 17, - "es_ES", + "es_ES"_Lex_ident_locale, "Spanish - Spain", FALSE, &my_locale_typelib_month_names_es_ES, @@ -592,7 +592,7 @@ static TYPELIB my_locale_typelib_ab_day_names_et_EE = MY_LOCALE my_locale_et_EE ( 18, - "et_EE", + "et_EE"_Lex_ident_locale, "Estonian - Estonia", FALSE, &my_locale_typelib_month_names_et_EE, @@ -628,7 +628,7 @@ static TYPELIB my_locale_typelib_ab_day_names_eu_ES = MY_LOCALE my_locale_eu_ES ( 19, - "eu_ES", + "eu_ES"_Lex_ident_locale, "Basque - Basque", TRUE, &my_locale_typelib_month_names_eu_ES, @@ -664,7 +664,7 @@ static TYPELIB my_locale_typelib_ab_day_names_fi_FI = MY_LOCALE my_locale_fi_FI ( 20, - "fi_FI", + "fi_FI"_Lex_ident_locale, "Finnish - Finland", FALSE, &my_locale_typelib_month_names_fi_FI, @@ -700,7 +700,7 @@ static TYPELIB my_locale_typelib_ab_day_names_fo_FO = MY_LOCALE my_locale_fo_FO ( 21, - "fo_FO", + "fo_FO"_Lex_ident_locale, "Faroese - Faroe Islands", FALSE, &my_locale_typelib_month_names_fo_FO, @@ -736,7 +736,7 @@ static TYPELIB my_locale_typelib_ab_day_names_fr_FR = MY_LOCALE my_locale_fr_FR ( 5, - "fr_FR", + "fr_FR"_Lex_ident_locale, "French - France", FALSE, &my_locale_typelib_month_names_fr_FR, @@ -772,7 +772,7 @@ static TYPELIB my_locale_typelib_ab_day_names_gl_ES = MY_LOCALE my_locale_gl_ES ( 22, - "gl_ES", + "gl_ES"_Lex_ident_locale, "Galician - Galician", FALSE, &my_locale_typelib_month_names_gl_ES, @@ -808,7 +808,7 @@ static TYPELIB my_locale_typelib_ab_day_names_gu_IN = MY_LOCALE my_locale_gu_IN ( 23, - "gu_IN", + "gu_IN"_Lex_ident_locale, "Gujarati - India", FALSE, &my_locale_typelib_month_names_gu_IN, @@ -844,7 +844,7 @@ static TYPELIB my_locale_typelib_ab_day_names_he_IL = MY_LOCALE my_locale_he_IL ( 24, - "he_IL", + "he_IL"_Lex_ident_locale, "Hebrew - Israel", FALSE, &my_locale_typelib_month_names_he_IL, @@ -880,7 +880,7 @@ static TYPELIB my_locale_typelib_ab_day_names_hi_IN = MY_LOCALE my_locale_hi_IN ( 25, - "hi_IN", + "hi_IN"_Lex_ident_locale, "Hindi - India", FALSE, &my_locale_typelib_month_names_hi_IN, @@ -916,7 +916,7 @@ static TYPELIB my_locale_typelib_ab_day_names_hr_HR = MY_LOCALE my_locale_hr_HR ( 26, - "hr_HR", + "hr_HR"_Lex_ident_locale, "Croatian - Croatia", FALSE, &my_locale_typelib_month_names_hr_HR, @@ -952,7 +952,7 @@ static TYPELIB my_locale_typelib_ab_day_names_hu_HU = MY_LOCALE my_locale_hu_HU ( 27, - "hu_HU", + "hu_HU"_Lex_ident_locale, "Hungarian - Hungary", FALSE, &my_locale_typelib_month_names_hu_HU, @@ -988,7 +988,7 @@ static TYPELIB my_locale_typelib_ab_day_names_id_ID = MY_LOCALE my_locale_id_ID ( 28, - "id_ID", + "id_ID"_Lex_ident_locale, "Indonesian - Indonesia", TRUE, &my_locale_typelib_month_names_id_ID, @@ -1024,7 +1024,7 @@ static TYPELIB my_locale_typelib_ab_day_names_is_IS = MY_LOCALE my_locale_is_IS ( 29, - "is_IS", + "is_IS"_Lex_ident_locale, "Icelandic - Iceland", FALSE, &my_locale_typelib_month_names_is_IS, @@ -1060,7 +1060,7 @@ static TYPELIB my_locale_typelib_ab_day_names_it_CH = MY_LOCALE my_locale_it_CH ( 30, - "it_CH", + "it_CH"_Lex_ident_locale, "Italian - Switzerland", FALSE, &my_locale_typelib_month_names_it_CH, @@ -1096,7 +1096,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ja_JP = MY_LOCALE my_locale_ja_JP ( 2, - "ja_JP", + "ja_JP"_Lex_ident_locale, "Japanese - Japan", FALSE, &my_locale_typelib_month_names_ja_JP, @@ -1132,7 +1132,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ko_KR = MY_LOCALE my_locale_ko_KR ( 31, - "ko_KR", + "ko_KR"_Lex_ident_locale, "Korean - Korea", FALSE, &my_locale_typelib_month_names_ko_KR, @@ -1168,7 +1168,7 @@ static TYPELIB my_locale_typelib_ab_day_names_lt_LT = MY_LOCALE my_locale_lt_LT ( 32, - "lt_LT", + "lt_LT"_Lex_ident_locale, "Lithuanian - Lithuania", FALSE, &my_locale_typelib_month_names_lt_LT, @@ -1204,7 +1204,7 @@ static TYPELIB my_locale_typelib_ab_day_names_lv_LV = MY_LOCALE my_locale_lv_LV ( 33, - "lv_LV", + "lv_LV"_Lex_ident_locale, "Latvian - Latvia", FALSE, &my_locale_typelib_month_names_lv_LV, @@ -1240,7 +1240,7 @@ static TYPELIB my_locale_typelib_ab_day_names_mk_MK = MY_LOCALE my_locale_mk_MK ( 34, - "mk_MK", + "mk_MK"_Lex_ident_locale, "Macedonian - FYROM", FALSE, &my_locale_typelib_month_names_mk_MK, @@ -1276,7 +1276,7 @@ static TYPELIB my_locale_typelib_ab_day_names_mn_MN = MY_LOCALE my_locale_mn_MN ( 35, - "mn_MN", + "mn_MN"_Lex_ident_locale, "Mongolia - Mongolian", FALSE, &my_locale_typelib_month_names_mn_MN, @@ -1312,7 +1312,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ms_MY = MY_LOCALE my_locale_ms_MY ( 36, - "ms_MY", + "ms_MY"_Lex_ident_locale, "Malay - Malaysia", TRUE, &my_locale_typelib_month_names_ms_MY, @@ -1348,7 +1348,7 @@ static TYPELIB my_locale_typelib_ab_day_names_nb_NO = MY_LOCALE my_locale_nb_NO ( 37, - "nb_NO", + "nb_NO"_Lex_ident_locale, "Norwegian(Bokml) - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, @@ -1384,7 +1384,7 @@ static TYPELIB my_locale_typelib_ab_day_names_nl_NL = MY_LOCALE my_locale_nl_NL ( 38, - "nl_NL", + "nl_NL"_Lex_ident_locale, "Dutch - The Netherlands", TRUE, &my_locale_typelib_month_names_nl_NL, @@ -1420,7 +1420,7 @@ static TYPELIB my_locale_typelib_ab_day_names_pl_PL = MY_LOCALE my_locale_pl_PL ( 39, - "pl_PL", + "pl_PL"_Lex_ident_locale, "Polish - Poland", FALSE, &my_locale_typelib_month_names_pl_PL, @@ -1456,7 +1456,7 @@ static TYPELIB my_locale_typelib_ab_day_names_pt_BR = MY_LOCALE my_locale_pt_BR ( 40, - "pt_BR", + "pt_BR"_Lex_ident_locale, "Portuguese - Brazil", FALSE, &my_locale_typelib_month_names_pt_BR, @@ -1492,7 +1492,7 @@ static TYPELIB my_locale_typelib_ab_day_names_pt_PT = MY_LOCALE my_locale_pt_PT ( 41, - "pt_PT", + "pt_PT"_Lex_ident_locale, "Portuguese - Portugal", FALSE, &my_locale_typelib_month_names_pt_PT, @@ -1528,7 +1528,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ro_RO = MY_LOCALE my_locale_ro_RO ( 42, - "ro_RO", + "ro_RO"_Lex_ident_locale, "Romanian - Romania", FALSE, &my_locale_typelib_month_names_ro_RO, @@ -1564,7 +1564,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ru_RU = MY_LOCALE my_locale_ru_RU ( 43, - "ru_RU", + "ru_RU"_Lex_ident_locale, "Russian - Russia", FALSE, &my_locale_typelib_month_names_ru_RU, @@ -1600,7 +1600,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ru_UA = MY_LOCALE my_locale_ru_UA ( 44, - "ru_UA", + "ru_UA"_Lex_ident_locale, "Russian - Ukraine", FALSE, &my_locale_typelib_month_names_ru_UA, @@ -1636,7 +1636,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sk_SK = MY_LOCALE my_locale_sk_SK ( 45, - "sk_SK", + "sk_SK"_Lex_ident_locale, "Slovak - Slovakia", FALSE, &my_locale_typelib_month_names_sk_SK, @@ -1672,7 +1672,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sl_SI = MY_LOCALE my_locale_sl_SI ( 46, - "sl_SI", + "sl_SI"_Lex_ident_locale, "Slovenian - Slovenia", FALSE, &my_locale_typelib_month_names_sl_SI, @@ -1708,7 +1708,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sq_AL = MY_LOCALE my_locale_sq_AL ( 47, - "sq_AL", + "sq_AL"_Lex_ident_locale, "Albanian - Albania", FALSE, &my_locale_typelib_month_names_sq_AL, @@ -1745,7 +1745,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sr_RS = MY_LOCALE my_locale_sr_RS ( 48, - "sr_RS", + "sr_RS"_Lex_ident_locale, "Serbian - Serbia", FALSE, &my_locale_typelib_month_names_sr_RS, @@ -1781,7 +1781,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sv_SE = MY_LOCALE my_locale_sv_SE ( 3, - "sv_SE", + "sv_SE"_Lex_ident_locale, "Swedish - Sweden", FALSE, &my_locale_typelib_month_names_sv_SE, @@ -1817,7 +1817,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ta_IN = MY_LOCALE my_locale_ta_IN ( 49, - "ta_IN", + "ta_IN"_Lex_ident_locale, "Tamil - India", FALSE, &my_locale_typelib_month_names_ta_IN, @@ -1853,7 +1853,7 @@ static TYPELIB my_locale_typelib_ab_day_names_te_IN = MY_LOCALE my_locale_te_IN ( 50, - "te_IN", + "te_IN"_Lex_ident_locale, "Telugu - India", FALSE, &my_locale_typelib_month_names_te_IN, @@ -1889,7 +1889,7 @@ static TYPELIB my_locale_typelib_ab_day_names_th_TH = MY_LOCALE my_locale_th_TH ( 51, - "th_TH", + "th_TH"_Lex_ident_locale, "Thai - Thailand", FALSE, &my_locale_typelib_month_names_th_TH, @@ -1925,7 +1925,7 @@ static TYPELIB my_locale_typelib_ab_day_names_tr_TR = MY_LOCALE my_locale_tr_TR ( 52, - "tr_TR", + "tr_TR"_Lex_ident_locale, "Turkish - Türkiye", FALSE, &my_locale_typelib_month_names_tr_TR, @@ -1961,7 +1961,7 @@ static TYPELIB my_locale_typelib_ab_day_names_uk_UA = MY_LOCALE my_locale_uk_UA ( 53, - "uk_UA", + "uk_UA"_Lex_ident_locale, "Ukrainian - Ukraine", FALSE, &my_locale_typelib_month_names_uk_UA, @@ -1997,7 +1997,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ur_PK = MY_LOCALE my_locale_ur_PK ( 54, - "ur_PK", + "ur_PK"_Lex_ident_locale, "Urdu - Pakistan", FALSE, &my_locale_typelib_month_names_ur_PK, @@ -2033,7 +2033,7 @@ static TYPELIB my_locale_typelib_ab_day_names_vi_VN = MY_LOCALE my_locale_vi_VN ( 55, - "vi_VN", + "vi_VN"_Lex_ident_locale, "Vietnamese - Vietnam", FALSE, &my_locale_typelib_month_names_vi_VN, @@ -2069,7 +2069,7 @@ static TYPELIB my_locale_typelib_ab_day_names_zh_CN = MY_LOCALE my_locale_zh_CN ( 56, - "zh_CN", + "zh_CN"_Lex_ident_locale, "Chinese - Peoples Republic of China", FALSE, &my_locale_typelib_month_names_zh_CN, @@ -2105,7 +2105,7 @@ static TYPELIB my_locale_typelib_ab_day_names_zh_TW = MY_LOCALE my_locale_zh_TW ( 57, - "zh_TW", + "zh_TW"_Lex_ident_locale, "Chinese - Taiwan", FALSE, &my_locale_typelib_month_names_zh_TW, @@ -2125,7 +2125,7 @@ MY_LOCALE my_locale_zh_TW MY_LOCALE my_locale_ar_DZ ( 58, - "ar_DZ", + "ar_DZ"_Lex_ident_locale, "Arabic - Algeria", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2145,7 +2145,7 @@ MY_LOCALE my_locale_ar_DZ MY_LOCALE my_locale_ar_EG ( 59, - "ar_EG", + "ar_EG"_Lex_ident_locale, "Arabic - Egypt", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2165,7 +2165,7 @@ MY_LOCALE my_locale_ar_EG MY_LOCALE my_locale_ar_IN ( 60, - "ar_IN", + "ar_IN"_Lex_ident_locale, "Arabic - Iran", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2185,7 +2185,7 @@ MY_LOCALE my_locale_ar_IN MY_LOCALE my_locale_ar_IQ ( 61, - "ar_IQ", + "ar_IQ"_Lex_ident_locale, "Arabic - Iraq", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2205,7 +2205,7 @@ MY_LOCALE my_locale_ar_IQ MY_LOCALE my_locale_ar_KW ( 62, - "ar_KW", + "ar_KW"_Lex_ident_locale, "Arabic - Kuwait", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2225,7 +2225,7 @@ MY_LOCALE my_locale_ar_KW MY_LOCALE my_locale_ar_LB ( 63, - "ar_LB", + "ar_LB"_Lex_ident_locale, "Arabic - Lebanon", FALSE, &my_locale_typelib_month_names_ar_JO, @@ -2245,7 +2245,7 @@ MY_LOCALE my_locale_ar_LB MY_LOCALE my_locale_ar_LY ( 64, - "ar_LY", + "ar_LY"_Lex_ident_locale, "Arabic - Libya", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2265,7 +2265,7 @@ MY_LOCALE my_locale_ar_LY MY_LOCALE my_locale_ar_MA ( 65, - "ar_MA", + "ar_MA"_Lex_ident_locale, "Arabic - Morocco", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2285,7 +2285,7 @@ MY_LOCALE my_locale_ar_MA MY_LOCALE my_locale_ar_OM ( 66, - "ar_OM", + "ar_OM"_Lex_ident_locale, "Arabic - Oman", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2305,7 +2305,7 @@ MY_LOCALE my_locale_ar_OM MY_LOCALE my_locale_ar_QA ( 67, - "ar_QA", + "ar_QA"_Lex_ident_locale, "Arabic - Qatar", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2325,7 +2325,7 @@ MY_LOCALE my_locale_ar_QA MY_LOCALE my_locale_ar_SD ( 68, - "ar_SD", + "ar_SD"_Lex_ident_locale, "Arabic - Sudan", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2345,7 +2345,7 @@ MY_LOCALE my_locale_ar_SD MY_LOCALE my_locale_ar_TN ( 69, - "ar_TN", + "ar_TN"_Lex_ident_locale, "Arabic - Tunisia", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2365,7 +2365,7 @@ MY_LOCALE my_locale_ar_TN MY_LOCALE my_locale_ar_YE ( 70, - "ar_YE", + "ar_YE"_Lex_ident_locale, "Arabic - Yemen", FALSE, &my_locale_typelib_month_names_ar_BH, @@ -2385,7 +2385,7 @@ MY_LOCALE my_locale_ar_YE MY_LOCALE my_locale_de_BE ( 71, - "de_BE", + "de_BE"_Lex_ident_locale, "German - Belgium", FALSE, &my_locale_typelib_month_names_de_DE, @@ -2405,7 +2405,7 @@ MY_LOCALE my_locale_de_BE MY_LOCALE my_locale_de_CH ( 72, - "de_CH", + "de_CH"_Lex_ident_locale, "German - Switzerland", FALSE, &my_locale_typelib_month_names_de_DE, @@ -2425,7 +2425,7 @@ MY_LOCALE my_locale_de_CH MY_LOCALE my_locale_de_LU ( 73, - "de_LU", + "de_LU"_Lex_ident_locale, "German - Luxembourg", FALSE, &my_locale_typelib_month_names_de_DE, @@ -2445,7 +2445,7 @@ MY_LOCALE my_locale_de_LU MY_LOCALE my_locale_en_AU ( 74, - "en_AU", + "en_AU"_Lex_ident_locale, "English - Australia", TRUE, &my_locale_typelib_month_names_en_US, @@ -2465,7 +2465,7 @@ MY_LOCALE my_locale_en_AU MY_LOCALE my_locale_en_CA ( 75, - "en_CA", + "en_CA"_Lex_ident_locale, "English - Canada", TRUE, &my_locale_typelib_month_names_en_US, @@ -2485,7 +2485,7 @@ MY_LOCALE my_locale_en_CA MY_LOCALE my_locale_en_GB ( 1, - "en_GB", + "en_GB"_Lex_ident_locale, "English - United Kingdom", TRUE, &my_locale_typelib_month_names_en_US, @@ -2505,7 +2505,7 @@ MY_LOCALE my_locale_en_GB MY_LOCALE my_locale_en_IN ( 76, - "en_IN", + "en_IN"_Lex_ident_locale, "English - India", TRUE, &my_locale_typelib_month_names_en_US, @@ -2525,7 +2525,7 @@ MY_LOCALE my_locale_en_IN MY_LOCALE my_locale_en_NZ ( 77, - "en_NZ", + "en_NZ"_Lex_ident_locale, "English - New Zealand", TRUE, &my_locale_typelib_month_names_en_US, @@ -2545,7 +2545,7 @@ MY_LOCALE my_locale_en_NZ MY_LOCALE my_locale_en_PH ( 78, - "en_PH", + "en_PH"_Lex_ident_locale, "English - Philippines", TRUE, &my_locale_typelib_month_names_en_US, @@ -2565,7 +2565,7 @@ MY_LOCALE my_locale_en_PH MY_LOCALE my_locale_en_ZA ( 79, - "en_ZA", + "en_ZA"_Lex_ident_locale, "English - South Africa", TRUE, &my_locale_typelib_month_names_en_US, @@ -2585,7 +2585,7 @@ MY_LOCALE my_locale_en_ZA MY_LOCALE my_locale_en_ZW ( 80, - "en_ZW", + "en_ZW"_Lex_ident_locale, "English - Zimbabwe", TRUE, &my_locale_typelib_month_names_en_US, @@ -2605,7 +2605,7 @@ MY_LOCALE my_locale_en_ZW MY_LOCALE my_locale_es_AR ( 81, - "es_AR", + "es_AR"_Lex_ident_locale, "Spanish - Argentina", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2625,7 +2625,7 @@ MY_LOCALE my_locale_es_AR MY_LOCALE my_locale_es_BO ( 82, - "es_BO", + "es_BO"_Lex_ident_locale, "Spanish - Bolivia", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2645,7 +2645,7 @@ MY_LOCALE my_locale_es_BO MY_LOCALE my_locale_es_CL ( 83, - "es_CL", + "es_CL"_Lex_ident_locale, "Spanish - Chile", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2665,7 +2665,7 @@ MY_LOCALE my_locale_es_CL MY_LOCALE my_locale_es_CO ( 84, - "es_CO", + "es_CO"_Lex_ident_locale, "Spanish - Columbia", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2685,7 +2685,7 @@ MY_LOCALE my_locale_es_CO MY_LOCALE my_locale_es_CR ( 85, - "es_CR", + "es_CR"_Lex_ident_locale, "Spanish - Costa Rica", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2705,7 +2705,7 @@ MY_LOCALE my_locale_es_CR MY_LOCALE my_locale_es_DO ( 86, - "es_DO", + "es_DO"_Lex_ident_locale, "Spanish - Dominican Republic", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2725,7 +2725,7 @@ MY_LOCALE my_locale_es_DO MY_LOCALE my_locale_es_EC ( 87, - "es_EC", + "es_EC"_Lex_ident_locale, "Spanish - Ecuador", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2745,7 +2745,7 @@ MY_LOCALE my_locale_es_EC MY_LOCALE my_locale_es_GT ( 88, - "es_GT", + "es_GT"_Lex_ident_locale, "Spanish - Guatemala", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2765,7 +2765,7 @@ MY_LOCALE my_locale_es_GT MY_LOCALE my_locale_es_HN ( 89, - "es_HN", + "es_HN"_Lex_ident_locale, "Spanish - Honduras", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2785,7 +2785,7 @@ MY_LOCALE my_locale_es_HN MY_LOCALE my_locale_es_MX ( 90, - "es_MX", + "es_MX"_Lex_ident_locale, "Spanish - Mexico", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2805,7 +2805,7 @@ MY_LOCALE my_locale_es_MX MY_LOCALE my_locale_es_NI ( 91, - "es_NI", + "es_NI"_Lex_ident_locale, "Spanish - Nicaragua", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2825,7 +2825,7 @@ MY_LOCALE my_locale_es_NI MY_LOCALE my_locale_es_PA ( 92, - "es_PA", + "es_PA"_Lex_ident_locale, "Spanish - Panama", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2845,7 +2845,7 @@ MY_LOCALE my_locale_es_PA MY_LOCALE my_locale_es_PE ( 93, - "es_PE", + "es_PE"_Lex_ident_locale, "Spanish - Peru", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2865,7 +2865,7 @@ MY_LOCALE my_locale_es_PE MY_LOCALE my_locale_es_PR ( 94, - "es_PR", + "es_PR"_Lex_ident_locale, "Spanish - Puerto Rico", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2885,7 +2885,7 @@ MY_LOCALE my_locale_es_PR MY_LOCALE my_locale_es_PY ( 95, - "es_PY", + "es_PY"_Lex_ident_locale, "Spanish - Paraguay", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2905,7 +2905,7 @@ MY_LOCALE my_locale_es_PY MY_LOCALE my_locale_es_SV ( 96, - "es_SV", + "es_SV"_Lex_ident_locale, "Spanish - El Salvador", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2925,7 +2925,7 @@ MY_LOCALE my_locale_es_SV MY_LOCALE my_locale_es_US ( 97, - "es_US", + "es_US"_Lex_ident_locale, "Spanish - United States", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2945,7 +2945,7 @@ MY_LOCALE my_locale_es_US MY_LOCALE my_locale_es_UY ( 98, - "es_UY", + "es_UY"_Lex_ident_locale, "Spanish - Uruguay", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2965,7 +2965,7 @@ MY_LOCALE my_locale_es_UY MY_LOCALE my_locale_es_VE ( 99, - "es_VE", + "es_VE"_Lex_ident_locale, "Spanish - Venezuela", FALSE, &my_locale_typelib_month_names_es_ES, @@ -2985,7 +2985,7 @@ MY_LOCALE my_locale_es_VE MY_LOCALE my_locale_fr_BE ( 100, - "fr_BE", + "fr_BE"_Lex_ident_locale, "French - Belgium", FALSE, &my_locale_typelib_month_names_fr_FR, @@ -3005,7 +3005,7 @@ MY_LOCALE my_locale_fr_BE MY_LOCALE my_locale_fr_CA ( 101, - "fr_CA", + "fr_CA"_Lex_ident_locale, "French - Canada", FALSE, &my_locale_typelib_month_names_fr_FR, @@ -3025,7 +3025,7 @@ MY_LOCALE my_locale_fr_CA MY_LOCALE my_locale_fr_CH ( 102, - "fr_CH", + "fr_CH"_Lex_ident_locale, "French - Switzerland", FALSE, &my_locale_typelib_month_names_fr_FR, @@ -3045,7 +3045,7 @@ MY_LOCALE my_locale_fr_CH MY_LOCALE my_locale_fr_LU ( 103, - "fr_LU", + "fr_LU"_Lex_ident_locale, "French - Luxembourg", FALSE, &my_locale_typelib_month_names_fr_FR, @@ -3065,7 +3065,7 @@ MY_LOCALE my_locale_fr_LU MY_LOCALE my_locale_it_IT ( 104, - "it_IT", + "it_IT"_Lex_ident_locale, "Italian - Italy", FALSE, &my_locale_typelib_month_names_it_CH, @@ -3085,7 +3085,7 @@ MY_LOCALE my_locale_it_IT MY_LOCALE my_locale_nl_BE ( 105, - "nl_BE", + "nl_BE"_Lex_ident_locale, "Dutch - Belgium", TRUE, &my_locale_typelib_month_names_nl_NL, @@ -3105,7 +3105,7 @@ MY_LOCALE my_locale_nl_BE MY_LOCALE my_locale_no_NO ( 106, - "no_NO", + "no_NO"_Lex_ident_locale, "Norwegian - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, @@ -3125,7 +3125,7 @@ MY_LOCALE my_locale_no_NO MY_LOCALE my_locale_sv_FI ( 107, - "sv_FI", + "sv_FI"_Lex_ident_locale, "Swedish - Finland", FALSE, &my_locale_typelib_month_names_sv_SE, @@ -3145,7 +3145,7 @@ MY_LOCALE my_locale_sv_FI MY_LOCALE my_locale_zh_HK ( 108, - "zh_HK", + "zh_HK"_Lex_ident_locale, "Chinese - Hong Kong SAR", FALSE, &my_locale_typelib_month_names_zh_CN, @@ -3218,7 +3218,7 @@ static TYPELIB my_locale_typelib_ab_day_names_el_GR= MY_LOCALE my_locale_el_GR ( 109, - "el_GR", + "el_GR"_Lex_ident_locale, "Greek - Greece", FALSE, &my_locale_typelib_month_names_el_GR, @@ -3286,7 +3286,7 @@ static TYPELIB my_locale_typelib_ab_day_names_rm_CH= MY_LOCALE my_locale_rm_CH ( 110, - "rm_CH", + "rm_CH"_Lex_ident_locale, "Romansh - Switzerland", FALSE, &my_locale_typelib_month_names_rm_CH, @@ -3345,7 +3345,7 @@ static TYPELIB my_locale_typelib_ab_day_names_ka_GE = MY_LOCALE my_locale_ka_GE ( 111, - "ka_GE", + "ka_GE"_Lex_ident_locale, "Georgian - Georgia", FALSE, &my_locale_typelib_month_names_ka_GE, @@ -3381,7 +3381,7 @@ static TYPELIB my_locale_typelib_ab_day_names_sw_KE = MY_LOCALE my_locale_sw_KE ( 112, - "sw_KE", + "sw_KE"_Lex_ident_locale, "Swahili - Kenya", TRUE, &my_locale_typelib_month_names_sw_KE, @@ -3536,19 +3536,19 @@ MY_LOCALE *my_locale_by_number(uint number) static MY_LOCALE* -my_locale_by_name(MY_LOCALE** locales, const char *name) +my_locale_by_name(MY_LOCALE** locales, const LEX_CSTRING &name) { MY_LOCALE **locale; for (locale= locales; *locale != NULL; locale++) { - if (!my_strcasecmp(&my_charset_latin1, (*locale)->name, name)) + if ((*locale)->name.streq(name)) return *locale; } return NULL; } -MY_LOCALE *my_locale_by_name(const char *name) +MY_LOCALE *my_locale_by_name(const LEX_CSTRING &name) { MY_LOCALE *locale; diff --git a/sql/sql_locale.h b/sql/sql_locale.h index b7ce9f7ba1d..1c8f2443d32 100644 --- a/sql/sql_locale.h +++ b/sql/sql_locale.h @@ -29,7 +29,7 @@ class MY_LOCALE { public: uint number; - const char *name; + const Lex_ident_locale name; const char *description; const bool is_ascii; TYPELIB *month_names; @@ -43,7 +43,8 @@ public: const char *grouping; MY_LOCALE_ERRMSGS *errmsgs; MY_LOCALE(uint number_par, - const char *name_par, const char *descr_par, bool is_ascii_par, + const Lex_ident_locale &name_par, + const char *descr_par, bool is_ascii_par, TYPELIB *month_names_par, TYPELIB *ab_month_names_par, TYPELIB *day_names_par, TYPELIB *ab_day_names_par, uint max_month_name_length_par, uint max_day_name_length_par, @@ -72,7 +73,7 @@ extern MY_LOCALE *my_default_lc_time_names; /* Exported functions */ -MY_LOCALE *my_locale_by_name(const char *name); +MY_LOCALE *my_locale_by_name(const LEX_CSTRING &name); MY_LOCALE *my_locale_by_number(uint number); void cleanup_errmsgs(void); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 819c5df8291..37b544a7752 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1129,10 +1129,9 @@ void cleanup_items(Item *item) #ifdef WITH_WSREP static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables) { - for (const TABLE_LIST *table= tables; table; table= table->next_global) + for (const TABLE_LIST *t= tables; t; t= t->next_global) { - LEX_CSTRING db= table->db, tn= table->table_name; - if (get_table_category(&db, &tn) < TABLE_CATEGORY_INFORMATION) + if (get_table_category(t->db, t->table_name) < TABLE_CATEGORY_INFORMATION) return false; } return tables != NULL; @@ -2033,7 +2032,7 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * } thd->convert_string(&table_name, system_charset_info, packet, arg_length, thd->charset()); - if (check_table_name(table_name.str, table_name.length, FALSE)) + if (Lex_ident_table::check_name(table_name, false)) { /* this is OK due to convert_string() null-terminating the string */ my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str); @@ -2648,7 +2647,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, lex->first_select_lex()->db= thd->make_ident_casedn(lex->first_select_lex()->db); schema_select_lex->db= lex->first_select_lex()->db; - if (Lex_ident_fs(lex->first_select_lex()->db).check_db_name_with_error()) + if (Lex_ident_db::check_name_with_error(lex->first_select_lex()->db)) DBUG_RETURN(1); break; } @@ -2831,8 +2830,8 @@ bool sp_process_definer(THD *thd) bool curuser= !strcmp(d->user.str, thd->security_ctx->priv_user); bool currole= !curuser && !strcmp(d->user.str, thd->security_ctx->priv_role); bool curuserhost= curuser && d->host.str && - !my_strcasecmp(system_charset_info, d->host.str, - thd->security_ctx->priv_host); + Lex_ident_host(d->host). + streq(Lex_cstring_strlen(thd->security_ctx->priv_host)); if (!curuserhost && !currole && check_global_access(thd, PRIV_DEFINER_CLAUSE, false)) DBUG_RETURN(TRUE); @@ -2841,7 +2840,7 @@ bool sp_process_definer(THD *thd) /* Check that the specified definer exists. Emit a warning if not. */ #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!is_acl_user(lex->definer->host.str, lex->definer->user.str)) + if (!is_acl_user(lex->definer->host, lex->definer->user)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_NO_SUCH_USER, ER_THD(thd, ER_NO_SUCH_USER), @@ -3073,7 +3072,7 @@ mysql_create_routine(THD *thd, LEX *lex) DBUG_ASSERT(lower_case_table_names != 1 || Lex_ident_fs(lex->sphead->m_db).is_in_lower_case()); - if (Lex_ident_fs(lex->sphead->m_db).check_db_name_with_error()) + if (Lex_ident_db::check_name_with_error(lex->sphead->m_db)) return true; if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, @@ -3089,15 +3088,15 @@ mysql_create_routine(THD *thd, LEX *lex) return true; } - const LEX_CSTRING *name= lex->sphead->name(); + const Lex_ident_routine name= Lex_ident_routine(*lex->sphead->name()); #ifdef HAVE_DLOPEN if (lex->sphead->m_handler->type() == SP_TYPE_FUNCTION) { - udf_func *udf = find_udf(name->str, name->length); + udf_func *udf= find_udf(name.str, name.length); if (udf) { - my_error(ER_UDF_EXISTS, MYF(0), name->str); + my_error(ER_UDF_EXISTS, MYF(0), name.str); return true; } } @@ -3141,7 +3140,7 @@ mysql_create_routine(THD *thd, LEX *lex) which doesn't any check routine privileges, so no routine privilege record will insert into mysql.procs_priv. */ - if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str)) + if (thd->slave_thread && is_acl_user(definer->host, definer->user)) { security_context.change_security_context(thd, &thd->lex->definer->user, &thd->lex->definer->host, @@ -3152,10 +3151,10 @@ mysql_create_routine(THD *thd, LEX *lex) if (sp_automatic_privileges && !opt_noacl && check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS, - &lex->sphead->m_db, name, + &lex->sphead->m_db, &name, Sp_handler::handler(lex->sql_command), 1)) { - if (sp_grant_privileges(thd, lex->sphead->m_db.str, name->str, + if (sp_grant_privileges(thd, lex->sphead->m_db, name, Sp_handler::handler(lex->sql_command))) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_PROC_AUTO_GRANT_FAIL, ER_THD(thd, ER_PROC_AUTO_GRANT_FAIL)); @@ -5568,7 +5567,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) case SQLCOM_SHOW_PACKAGE_BODY_CODE: { #ifndef DBUG_OFF - Database_qualified_name pkgname(&null_clex_str, &null_clex_str); + Database_qualified_name pkgname; sp_head *sp; const Sp_handler *sph= Sp_handler::handler(lex->sql_command); WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); @@ -6192,15 +6191,15 @@ static TABLE *find_temporary_table_for_rename(THD *thd, { TABLE_LIST *next= table->next_local; - if (!strcmp(table->get_db_name(), cur_table->get_db_name()) && - !strcmp(table->get_table_name(), cur_table->get_table_name())) + if (!strcmp(table->get_db_name().str, cur_table->get_db_name().str) && + !strcmp(table->get_table_name().str, cur_table->get_table_name().str)) { /* Table was moved away, can't be same as 'table' */ found= 1; res= 0; // Table can't be a temporary table } - if (!strcmp(next->get_db_name(), cur_table->get_db_name()) && - !strcmp(next->get_table_name(), cur_table->get_table_name())) + if (!strcmp(next->get_db_name().str, cur_table->get_db_name().str) && + !strcmp(next->get_table_name().str, cur_table->get_table_name().str)) { /* Table has matching name with new name of this table. cur_table should @@ -6305,7 +6304,7 @@ show_create_db(THD *thd, LEX *lex) my_error(ER_UNKNOWN_ERROR, MYF(0)); return 1;); const DBNameBuffer dbbuf(lex->name, lower_case_table_names == 1); - if (Lex_ident_fs(dbbuf.to_lex_cstring()).check_db_name_with_error()) + if (Lex_ident_db::check_name_with_error(dbbuf.to_lex_cstring())) return 1; LEX_CSTRING db= dbbuf.to_lex_cstring(); return mysqld_show_create_db(thd, &db, &lex->name, lex->create_info); @@ -6423,7 +6422,8 @@ absent: if (sp_result != SP_KEY_NOT_FOUND && sp_automatic_privileges && !opt_noacl && - sp_revoke_privileges(thd, lex->spname->m_db.str, lex->spname->m_name.str, + sp_revoke_privileges(thd, lex->spname->m_db, + Lex_ident_routine(lex->spname->m_name), Sp_handler::handler(lex->sql_command))) { push_warning(thd, Sql_condition::WARN_LEVEL_WARN, @@ -6953,7 +6953,7 @@ check_table_access(THD *thd, privilege_t requirements, TABLE_LIST *tables, } if (check_access(thd, want_access, - table_ref->get_db_name(), + table_ref->get_db_name().str, &table_ref->grant.privilege, &table_ref->grant.m_internal, 0, no_errors)) @@ -6973,8 +6973,8 @@ check_routine_access(THD *thd, privilege_t want_access, const LEX_CSTRING *db, TABLE_LIST tables[1]; bzero((char *)tables, sizeof(TABLE_LIST)); - tables->db= *db; - tables->table_name= tables->alias= *name; + tables->db= Lex_ident_db(*db); + tables->table_name= tables->alias= Lex_ident_table(*name); /* The following test is just a shortcut for check_access() (to avoid @@ -7145,7 +7145,7 @@ bool check_fk_parent_table_access(THD *thd, // Check if tablename is valid or not. DBUG_ASSERT(table_name.str != NULL); - if (check_table_name(table_name.str, table_name.length, false)) + if (Lex_ident_table::check_name(table_name, false)) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str); return true; @@ -7157,7 +7157,7 @@ bool check_fk_parent_table_access(THD *thd, if (fk_key->ref_db.str) { - if (Lex_ident_fs(fk_key->ref_db).check_db_name_with_error() || + if (Lex_ident_db::check_name_with_error(fk_key->ref_db) || !(db_name= thd->make_ident_opt_casedn(fk_key->ref_db, lower_case_table_names)).str) return true; @@ -7167,7 +7167,7 @@ bool check_fk_parent_table_access(THD *thd, if (!thd->db.str) { DBUG_ASSERT(create_db.str); - if (Lex_ident_fs(create_db).check_db_name_with_error() || + if (Lex_ident_db::check_name_with_error(create_db) || !(db_name= thd->make_ident_opt_casedn(create_db, lower_case_table_names)).str) return true; @@ -7980,7 +7980,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { TABLE_LIST *ptr; TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */ - LEX_CSTRING alias_str; LEX *lex= thd->lex; DBUG_ENTER("add_table_to_list"); DBUG_PRINT("enter", ("Table '%s' (%p) Select %p (%u)", @@ -7991,10 +7990,11 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (unlikely(!table)) DBUG_RETURN(0); // End of memory - alias_str= alias ? *alias : table->table; + Lex_ident_table alias_str= alias ? Lex_ident_table(*alias) : + Lex_ident_table(table->table); DBUG_ASSERT(alias_str.str); if (!MY_TEST(table_options & TL_OPTION_ALIAS) && - unlikely(check_table_name(table->table.str, table->table.length, FALSE))) + unlikely(Lex_ident_table::check_name(table->table, false))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); @@ -8002,7 +8002,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (unlikely(table->is_derived_table() == FALSE && table->db.str && !(table_options & TL_OPTION_TABLE_FUNCTION) && - Lex_ident_fs(table->db).check_db_name_with_error())) + Lex_ident_db::check_name_with_error(table->db))) DBUG_RETURN(0); if (!alias) /* Alias is case sensitive */ @@ -8022,7 +8022,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (table->db.str) { ptr->is_fqtn= TRUE; - ptr->db= table->db; + ptr->db= Lex_ident_db(table->db); } else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db)) DBUG_RETURN(0); @@ -8031,14 +8031,14 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->alias= alias_str; ptr->is_alias= alias ? TRUE : FALSE; - ptr->table_name= table->table; + ptr->table_name= Lex_ident_table(table->table); if (lower_case_table_names) { - if (!(ptr->table_name= thd->make_ident_casedn(ptr->table_name)).str) + if (!(ptr->table_name= thd->lex_ident_casedn(ptr->table_name)).str) DBUG_RETURN(0); if (ptr->db.length && ptr->db.str != any_db.str && - !(ptr->db= thd->make_ident_casedn(ptr->db)).str) + !(ptr->db= thd->lex_ident_casedn(ptr->db)).str) DBUG_RETURN(0); } @@ -8064,7 +8064,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, } ST_SCHEMA_TABLE *schema_table; schema_table= find_schema_table(thd, &ptr->table_name); - ptr->schema_table_name= ptr->table_name; + ptr->schema_table_name= Lex_ident_i_s_table(ptr->table_name); ptr->schema_table= schema_table; } ptr->select_lex= this; @@ -8085,8 +8085,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, tables ; tables=tables->next_local) { - if (unlikely(!my_strcasecmp(table_alias_charset, alias_str.str, - tables->alias.str) && + if (unlikely(alias_str.streq(tables->alias) && (tables->db.str == any_db.str || ptr->db.str == any_db.str || !cmp(&ptr->db, &tables->db)) && !tables->sequence)) @@ -9451,12 +9450,12 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl, if (tbl->is_fqtn && elem->is_alias) continue; /* no match */ if (tbl->is_fqtn && elem->is_fqtn) - res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) || + res= (!tbl->table_name.streq(elem->table_name) || cmp(&tbl->db, &elem->db)); else if (elem->is_alias) - res= my_strcasecmp(table_alias_charset, tbl->alias.str, elem->alias.str); + res= !tbl->alias.streq(elem->alias); else - res= (my_strcasecmp(table_alias_charset, tbl->table_name.str, elem->table_name.str) || + res= (!tbl->table_name.streq(elem->table_name) || cmp(&tbl->db, &elem->db)); if (res) @@ -9974,7 +9973,8 @@ bool check_string_char_length(const LEX_CSTRING *str, uint err_msg, bool check_ident_length(const LEX_CSTRING *ident) { - if (check_string_char_length(ident, 0, NAME_CHAR_LEN, system_charset_info, 1)) + if (check_string_char_length(ident, 0, NAME_CHAR_LEN, + Lex_ident_ci::charset_info(), 1)) { my_error(ER_TOO_LONG_IDENT, MYF(0), ident->str); return 1; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 130e70d73e6..72b27609bb4 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -161,7 +161,8 @@ Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs) @retval false String not found */ -static bool is_name_in_list(const char *name, List list_names) +static bool is_name_in_list(const Lex_ident_partition &name, + List list_names) { List_iterator names_it(list_names); uint num_names= list_names.elements; @@ -170,7 +171,7 @@ static bool is_name_in_list(const char *name, List list_names) do { const char *list_name= names_it++; - if (!(my_strcasecmp(system_charset_info, name, list_name))) + if (name.streq(Lex_cstring_strlen(list_name))) return TRUE; } while (++i < num_names); return FALSE; @@ -389,9 +390,7 @@ static bool set_up_field_array(THD *thd, TABLE *table, do { field_name= it++; - if (!my_strcasecmp(system_charset_info, - field_name, - field->field_name.str)) + if (field->field_name.streq(Lex_cstring_strlen(field_name))) break; } while (++inx < num_fields); if (inx == num_fields) @@ -689,7 +688,7 @@ static bool handle_list_of_fields(THD *thd, List_iterator it, while ((field_name= it++)) { is_list_empty= FALSE; - field= find_field_in_table_sef(table, field_name); + field= find_field_in_table_sef(table, Lex_cstring_strlen(field_name)); if (likely(field != 0)) field->flags|= GET_FIXED_FIELDS_FLAG; else @@ -2261,7 +2260,7 @@ static int add_engine_part_options(String *str, partition_element *p_elem) NULL No field found */ -static Create_field* get_sql_field(const char *field_name, +static Create_field* get_sql_field(const LEX_CSTRING &field_name, Alter_info *alter_info) { List_iterator it(alter_info->create_list); @@ -2270,9 +2269,7 @@ static Create_field* get_sql_field(const char *field_name, while ((sql_field= it++)) { - if (!(my_strcasecmp(system_charset_info, - sql_field->field_name.str, - field_name))) + if (sql_field->field_name.streq(field_name)) { DBUG_RETURN(sql_field); } @@ -2325,7 +2322,7 @@ static int add_column_list_values(String *str, partition_info *part_info, derived_attr(create_info->default_table_charset); Create_field *sql_field; - if (!(sql_field= get_sql_field(field_name, + if (!(sql_field= get_sql_field(Lex_cstring_strlen(field_name), alter_info))) { my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0)); @@ -2716,8 +2713,7 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info, err+= str.append(STRING_WITH_LEN(",\n ")); first= FALSE; err+= str.append(STRING_WITH_LEN("PARTITION ")); - err+= append_identifier(thd, &str, part_elem->partition_name, - strlen(part_elem->partition_name)); + err+= append_identifier(thd, &str, &part_elem->partition_name); err+= add_partition_values(&str, part_info, part_elem, create_info, alter_info); if (!part_info->is_sub_partitioned() || @@ -2738,8 +2734,7 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info, { part_elem= sub_it++; err+= str.append(STRING_WITH_LEN("SUBPARTITION ")); - err+= append_identifier(thd, &str, part_elem->partition_name, - strlen(part_elem->partition_name)); + err+= append_identifier(thd, &str, &part_elem->partition_name); if (show_partition_options) err+= add_server_part_options(&str, part_elem); if (j != (num_subparts-1)) @@ -4742,7 +4737,7 @@ bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info, num_parts_found++; part_elem->part_state= part_state; DBUG_PRINT("info", ("Setting part_state to %u for partition %s", - part_state, part_elem->partition_name)); + part_state, part_elem->partition_name.str)); } else part_elem->part_state= PART_NORMAL; @@ -6022,13 +6017,12 @@ the generated partition syntax in a correct manner. { KEY *primary_key= table->key_info + table->s->primary_key; List_iterator_fast drop_it(alter_info->drop_list); - const char *primary_name= primary_key->name.str; const Alter_drop *drop; drop_it.rewind(); while ((drop= drop_it++)) { if (drop->type == Alter_drop::KEY && - 0 == my_strcasecmp(system_charset_info, primary_name, drop->name)) + drop->name.streq(primary_key->name)) break; } if (drop) @@ -7388,7 +7382,8 @@ static bool check_table_data(ALTER_PARTITION_PARAM_TYPE *lpt) uint32 new_part_id; partition_element *part_elem; - const char* partition_name= thd->lex->part_info->curr_part_elem->partition_name; + const Lex_ident_partition &partition_name= + thd->lex->part_info->curr_part_elem->partition_name; part_elem= table_to->part_info->get_part_elem(partition_name, nullptr, 0, &new_part_id); if (unlikely(!part_elem)) @@ -8067,12 +8062,10 @@ void make_used_partitions_str(MEM_ROOT *alloc, parts_str->append(','); uint index= parts_str->length(); parts_str->append(head_pe->partition_name, - strlen(head_pe->partition_name), - system_charset_info); + head_pe->partition_name.charset_info()); parts_str->append('_'); parts_str->append(pe->partition_name, - strlen(pe->partition_name), - system_charset_info); + pe->partition_name.charset_info()); used_partitions_list.append_str(alloc, parts_str->ptr() + index); } partition_id++; @@ -8087,9 +8080,9 @@ void make_used_partitions_str(MEM_ROOT *alloc, { if (parts_str->length()) parts_str->append(','); - used_partitions_list.append_str(alloc, pe->partition_name); - parts_str->append(pe->partition_name, strlen(pe->partition_name), - system_charset_info); + used_partitions_list.append_str(alloc, pe->partition_name.str); + parts_str->append(pe->partition_name, + pe->partition_name.charset_info()); } partition_id++; } @@ -9114,7 +9107,8 @@ static const char *longest_str(const char *s1, const char *s2, */ int create_partition_name(char *out, size_t outlen, const char *in1, - const char *in2, uint name_variant, bool translate) + const char *in2, + uint name_variant, bool translate) { char transl_part_name[FN_REFLEN]; const char *transl_part, *end; @@ -9160,15 +9154,15 @@ int create_partition_name(char *out, size_t outlen, const char *in1, @retval false Success. */ -int create_subpartition_name(char *out, size_t outlen, - const char *in1, const char *in2, - const char *in3, uint name_variant) +int create_subpartition_name(char *out, size_t outlen, const char *in1, + const Lex_ident_partition &in2, + const Lex_ident_partition &in3, uint name_variant) { char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN], *end; DBUG_ASSERT(outlen >= FN_REFLEN + 1); // consistency! same limit everywhere - tablename_to_filename(in2, transl_part_name, FN_REFLEN); - tablename_to_filename(in3, transl_subpart_name, FN_REFLEN); + tablename_to_filename(in2.str, transl_part_name, FN_REFLEN); + tablename_to_filename(in3.str, transl_subpart_name, FN_REFLEN); if (name_variant == NORMAL_PART_NAME) end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name, diff --git a/sql/sql_partition.h b/sql/sql_partition.h index cff3214f477..47afcb09807 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -292,11 +292,25 @@ bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt, #endif int __attribute__((warn_unused_result)) - create_partition_name(char *out, size_t outlen, const char *in1, const char - *in2, uint name_variant, bool translate); + create_partition_name(char *out, size_t outlen, const char *in1, + const char *in2, + uint name_variant, bool translate); + +static inline int __attribute__((warn_unused_result)) - create_subpartition_name(char *out, size_t outlen, const char *in1, const - char *in2, const char *in3, uint name_variant); + create_partition_name(char *out, size_t outlen, const char *in1, + const Lex_ident_partition &in2, + uint name_variant, bool translate) +{ + return create_partition_name(out, outlen, in1, in2.str, + name_variant, translate); +} + + +int __attribute__((warn_unused_result)) + create_subpartition_name(char *out, size_t outlen, const char *in1, + const Lex_ident_partition &in2, + const Lex_ident_partition &in3, uint name_variant); void set_key_field_ptr(KEY *key_info, const uchar *new_buf, const uchar *old_buf); diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 2f2eb3f7a1e..0238406b737 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -507,7 +507,6 @@ bool Sql_cmd_alter_table_exchange_partition:: TABLE_LIST *swap_table_list; handlerton *table_hton; partition_element *part_elem; - const char *partition_name; char temp_name[FN_REFLEN+1]; char part_file_name[2*FN_REFLEN+1]; char swap_file_name[FN_REFLEN+1]; @@ -629,10 +628,10 @@ bool Sql_cmd_alter_table_exchange_partition:: ddl_log.new_table_id.length= MY_UUID_SIZE; /* set lock pruning on first table */ - partition_name= alter_info->partition_names.head(); + const Lex_cstring_strlen partition_name= alter_info->partition_names.head(); if (unlikely(table_list->table->part_info-> - set_named_partition_bitmap(partition_name, - strlen(partition_name)))) + set_named_partition_bitmap(partition_name.str, + partition_name.length))) DBUG_RETURN(true); if (unlikely(lock_tables(thd, table_list, table_counter, 0))) @@ -1023,7 +1022,7 @@ bool alter_partition_convert_in(ALTER_PARTITION_PARAM_TYPE *lpt) const char *path= lpt->table_list->table->s->path.str; TABLE_LIST *table_from= lpt->table_list->next_local; - const char *partition_name= + const Lex_ident_partition &partition_name= thd->lex->part_info->curr_part_elem->partition_name; if (create_partition_name(part_file_name, sizeof(part_file_name), path, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index fce94459603..d873949614f 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -207,7 +207,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]= static struct { - const char *plugin_name; + Lex_ident_plugin plugin_name; enum enum_plugin_load_option override; } override_plugin_load_policy[]={ /* @@ -226,10 +226,10 @@ static struct - yet disable explicitly a component needed for the functionality to work, by using '--skip-performance-schema' (the plugin) */ - { "performance_schema", PLUGIN_FORCE } + { "performance_schema"_Lex_ident_plugin, PLUGIN_FORCE } /* we disable few other plugins by default */ - ,{ "feedback", PLUGIN_OFF } + ,{ "feedback"_Lex_ident_plugin, PLUGIN_OFF } }; /* support for Services */ @@ -374,16 +374,16 @@ bool check_valid_path(const char *path, size_t len) static void fix_dl_name(MEM_ROOT *root, LEX_CSTRING *dl) { - const size_t so_ext_len= sizeof(SO_EXT) - 1; - if (dl->length < so_ext_len || - my_strcasecmp(&my_charset_latin1, dl->str + dl->length - so_ext_len, - SO_EXT)) + const Lex_ident_plugin so_ext(STRING_WITH_LEN(SO_EXT)); + if (dl->length < so_ext.length || + !so_ext.streq(Lex_cstring(dl->str + dl->length - so_ext.length, + so_ext.length))) { - char *s= (char*)alloc_root(root, dl->length + so_ext_len + 1); + char *s= (char*)alloc_root(root, dl->length + so_ext.length + 1); memcpy(s, dl->str, dl->length); strcpy(s + dl->length, SO_EXT); dl->str= s; - dl->length+= so_ext_len; + dl->length+= so_ext.length; } } @@ -1144,8 +1144,7 @@ static enum install_status plugin_add(MEM_ROOT *tmp_root, bool if_not_exists, tmp.plugin_dl->mariaversion == 0)) continue; // unsupported plugin type - if (name->str && system_charset_info->strnncoll(name->str, name->length, - tmp.name.str, tmp.name.length)) + if (name->str && !Lex_ident_plugin(*name).streq(tmp.name)) continue; // plugin name doesn't match if (!name->str && @@ -1634,7 +1633,9 @@ int plugin_init(int *argc, char **argv, int flags) for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) { - if (my_hash_init(key_memory_plugin_mem_root, &plugin_hash[i], system_charset_info, 32, 0, 0, + if (my_hash_init(key_memory_plugin_mem_root, &plugin_hash[i], + Lex_ident_plugin::charset_info(), + 32, 0, 0, get_plugin_hash_key, NULL, HASH_UNIQUE)) goto err; } @@ -1667,21 +1668,20 @@ int plugin_init(int *argc, char **argv, int flags) } for (plugin= *builtins; plugin->info; plugin++) { + Lex_ident_plugin tmp_plugin_name(Lex_cstring_strlen(plugin->name)); if (opt_ignore_builtin_innodb && - !my_charset_latin1.strnncoll(plugin->name, 6, "InnoDB", 6)) + tmp_plugin_name.streq("InnoDB"_Lex_ident_plugin)) continue; bzero(&tmp, sizeof(tmp)); tmp.plugin= plugin; - tmp.name.str= (char *)plugin->name; - tmp.name.length= strlen(plugin->name); + tmp.name= tmp_plugin_name; tmp.state= 0; tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON; for (i=0; i < array_elements(override_plugin_load_policy); i++) { - if (!my_strcasecmp(&my_charset_latin1, plugin->name, - override_plugin_load_policy[i].plugin_name)) + if (tmp_plugin_name.streq(override_plugin_load_policy[i].plugin_name)) { tmp.load_option= override_plugin_load_policy[i].override; break; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 1137e0e1b09..98246545bed 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -234,7 +234,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table) struct rename_param { - LEX_CSTRING old_alias, new_alias; + Lex_ident_table old_alias, new_alias; LEX_CUSTRING old_version; handlerton *from_table_hton; }; @@ -260,10 +260,10 @@ struct rename_param static int check_rename(THD *thd, rename_param *param, - TABLE_LIST *ren_table, - const LEX_CSTRING *new_db, - const LEX_CSTRING *new_table_name, - const LEX_CSTRING *new_table_alias, + const TABLE_LIST *ren_table, + const Lex_ident_db &new_db, + const Lex_ident_table &new_table_name, + const Lex_ident_table &new_table_alias, bool if_exists) { DBUG_ENTER("check_rename"); @@ -273,12 +273,12 @@ check_rename(THD *thd, rename_param *param, if (lower_case_table_names == 2) { param->old_alias= ren_table->alias; - param->new_alias= *new_table_alias; + param->new_alias= new_table_alias; } else { param->old_alias= ren_table->table_name; - param->new_alias= *new_table_name; + param->new_alias= new_table_name; } DBUG_ASSERT(param->new_alias.str); @@ -304,7 +304,7 @@ check_rename(THD *thd, rename_param *param, DBUG_RETURN(-1); } - if (ha_table_exists(thd, new_db, ¶m->new_alias, NULL, NULL, 0)) + if (ha_table_exists(thd, &new_db, ¶m->new_alias, NULL, NULL, 0)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), param->new_alias.str); DBUG_RETURN(1); // This can't be skipped @@ -335,19 +335,18 @@ check_rename(THD *thd, rename_param *param, */ static bool -do_rename(THD *thd, rename_param *param, DDL_LOG_STATE *ddl_log_state, - TABLE_LIST *ren_table, const LEX_CSTRING *new_db, +do_rename(THD *thd, const rename_param *param, DDL_LOG_STATE *ddl_log_state, + TABLE_LIST *ren_table, const Lex_ident_db *new_db, bool skip_error, bool *force_if_exists) { int rc= 1; handlerton *hton; - LEX_CSTRING *old_alias, *new_alias; TRIGGER_RENAME_PARAM rename_param; DBUG_ENTER("do_rename"); DBUG_PRINT("enter", ("skip_error: %d", (int) skip_error)); - old_alias= ¶m->old_alias; - new_alias= ¶m->new_alias; + const Lex_ident_table * const old_alias= ¶m->old_alias; + const Lex_ident_table * const new_alias= ¶m->new_alias; hton= param->from_table_hton; DBUG_ASSERT(!thd->locked_tables_mode); @@ -367,11 +366,11 @@ do_rename(THD *thd, rename_param *param, DDL_LOG_STATE *ddl_log_state, /* Check if we can rename triggers */ if (Table_triggers_list::prepare_for_rename(thd, &rename_param, - &ren_table->db, - old_alias, - &ren_table->table_name, - new_db, - new_alias)) + ren_table->db, + *old_alias, + ren_table->table_name, + *new_db, + *new_alias)) DBUG_RETURN(!skip_error); thd->replication_flags= 0; @@ -523,9 +522,9 @@ rename_tables(THD *thd, TABLE_LIST *table_list, DDL_LOG_STATE *ddl_log_state, { int error; rename_param param; - error= check_rename(thd, ¶m, ren_table, &new_table->db, - &new_table->table_name, - &new_table->alias, (skip_error || if_exists)); + error= check_rename(thd, ¶m, ren_table, new_table->db, + new_table->table_name, + new_table->alias, (skip_error || if_exists)); if (error < 0) continue; // Ignore rename (if exists) if (error > 0) diff --git a/sql/sql_schema.cc b/sql/sql_schema.cc index 7a6c0c99398..a267ad83ef7 100644 --- a/sql/sql_schema.cc +++ b/sql/sql_schema.cc @@ -103,7 +103,7 @@ Schema::find_native_function_builder(THD *thd, const LEX_CSTRING &name) const Item *Schema::make_item_func_call_native(THD *thd, - const Lex_ident_sys &name, + const Lex_ident_routine &name, List *args) const { Create_func *builder= find_native_function_builder(thd, name); diff --git a/sql/sql_schema.h b/sql/sql_schema.h index af83c5e9599..2406dd5ff08 100644 --- a/sql/sql_schema.h +++ b/sql/sql_schema.h @@ -24,13 +24,13 @@ class Create_func; class Schema { - LEX_CSTRING m_name; + const Lex_ident_db m_name; public: Schema(const LEX_CSTRING &name) :m_name(name) { } virtual ~Schema() = default; - const LEX_CSTRING &name() const { return m_name; } + const Lex_ident_db &name() const { return m_name; } virtual const Type_handler *map_data_type(THD *thd, const Type_handler *src) const { @@ -42,7 +42,7 @@ public: build an Item otherwise. */ Item *make_item_func_call_native(THD *thd, - const Lex_ident_sys &name, + const Lex_ident_routine &name, List *args) const; /** @@ -79,8 +79,7 @@ public: */ bool eq_name(const LEX_CSTRING &name) const { - return !table_alias_charset->strnncoll(m_name.str, m_name.length, - name.str, name.length); + return m_name.streq(name); } static Schema *find_by_name(const LEX_CSTRING &name); static Schema *find_implied(THD *thd); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6f2797b6b39..15fc2b7a158 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -125,8 +125,8 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "index_merge", "hash_ALL", "hash_range", "hash_index", "hash_index_merge" }; -LEX_CSTRING group_key= {STRING_WITH_LEN("group_key")}; -LEX_CSTRING distinct_key= {STRING_WITH_LEN("distinct_key")}; +static const Lex_ident_column group_key= "group_key"_Lex_ident_column; +static const Lex_ident_column distinct_key= "distinct_key"_Lex_ident_column; struct st_sargable_param; @@ -20742,9 +20742,9 @@ Item_field::create_tmp_field_from_item_field(MEM_ROOT *root, TABLE *new_table, { DBUG_ASSERT(!is_result_field()); Field *result; - LEX_CSTRING *new_name= (orig_item ? &orig_item->name : - !param->modify_item() ? &name : - &field->field_name); + const Lex_ident_column *new_name= (orig_item ? &orig_item->name : + !param->modify_item() ? &name : + &field->field_name); /* If item have to be able to store NULLs but underlaid field can't do it, @@ -21267,7 +21267,7 @@ TABLE *Create_tmp_table::start(THD *thd, share->table_charset= param->table_charset; share->primary_key= MAX_KEY; // Indicate no primary key if (param->schema_table) - share->db= INFORMATION_SCHEMA_NAME; + share->db= Lex_ident_db(INFORMATION_SCHEMA_NAME); param->using_outer_summary_function= 0; thd->mem_root= mem_root_save; @@ -22216,8 +22216,7 @@ bool Virtual_tmp_table::sp_find_field_by_name(uint *idx, for (uint i= 0; (f= field[i]); i++) { // Use the same comparison style with sp_context::find_variable() - if (!system_charset_info->strnncoll(f->field_name.str, f->field_name.length, - name.str, name.length)) + if (f->field_name.streq(name)) { *idx= i; return false; @@ -28583,7 +28582,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, real_pos->type() == Item::COND_ITEM) && !real_pos->with_sum_func()) { // Save for send fields - LEX_CSTRING real_name= pos->name; + const Lex_ident_column real_name= pos->name; pos= real_pos; pos->name= real_name; /* TODO: @@ -30846,10 +30845,7 @@ Index_hint::print(THD *thd, String *str) str->append(STRING_WITH_LEN(" (")); if (key_name.length) { - if (thd && !system_charset_info->strnncoll( - (const uchar *)key_name.str, key_name.length, - (const uchar *)primary_key_name.str, - primary_key_name.length)) + if (thd && key_name.streq(primary_key_name)) str->append(primary_key_name); else append_identifier(thd, str, &key_name); @@ -30901,7 +30897,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, } else { - const char *cmp_name; // Name to compare with alias + Lex_ident_table cmp_name(empty_clex_str); // Name to compare with alias if (view_name.str) { // A view @@ -30914,7 +30910,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, str->append('.'); } append_identifier(thd, str, &view_name); - cmp_name= view_name.str; + cmp_name= view_name; } else if (derived) { @@ -30924,12 +30920,12 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, str->append('('); derived->print(str, query_type); str->append(')'); - cmp_name= ""; // Force printing of alias + cmp_name= Lex_ident_table(empty_clex_str); // Force printing of alias } else { append_identifier(thd, str, &table_name); - cmp_name= table_name.str; + cmp_name= table_name; } } else if (table_function) @@ -30938,7 +30934,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, (void) table_function->print(thd, this, str, query_type); str->append(' '); append_identifier(thd, str, &alias); - cmp_name= alias.str; + cmp_name= alias; } else { @@ -30954,12 +30950,12 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, if (schema_table) { append_identifier(thd, str, &schema_table_name); - cmp_name= schema_table_name.str; + cmp_name= Lex_ident_table(schema_table_name); } else { append_identifier(thd, str, &table_name); - cmp_name= table_name.str; + cmp_name= table_name; } #ifdef WITH_PARTITION_STORAGE_ENGINE if (partition_names && partition_names->elements) @@ -30981,7 +30977,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, if (table && table->versioned()) vers_conditions.print(str, query_type); - if (my_strcasecmp(table_alias_charset, cmp_name, alias.str)) + if (!cmp_name.streq(alias)) { str->append(' '); append_identifier_opt_casedn(thd, str, alias, diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 19715ad97fd..4903bdd20de 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -380,8 +380,7 @@ bool check_sequence_fields(LEX *lex, List *fields, for (field_no= 0; (field= it++); field_no++) { const Sequence_field_definition *field_def= &row_structure.fields[field_no]; - if (my_strcasecmp(system_charset_info, field_def->field_name, - field->field_name.str) || + if (!field->field_name.streq(Lex_cstring_strlen(field_def->field_name)) || field->flags != field_def->flags || field->type_handler() != field_def->type_handler || field->check_constraint || field->vcol_info) @@ -418,8 +417,8 @@ bool sequence_definition::prepare_sequence_fields(List *fields, field_info->field_name; field_info++) { Create_field *new_field; - LEX_CSTRING field_name= {field_info->field_name, - strlen(field_info->field_name)}; + const Lex_ident_column field_name= Lex_cstring_strlen(field_info-> + field_name); if (unlikely(!(new_field= new Create_field()))) DBUG_RETURN(TRUE); /* purify inspected */ diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 10a32abe716..29d106dfd81 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -233,7 +233,9 @@ bool servers_init(bool dont_read_servers_table) DBUG_RETURN(TRUE); /* initialise our servers cache */ - if (my_hash_init(key_memory_servers, &servers_cache, system_charset_info, 32, 0, 0, + if (my_hash_init(key_memory_servers, &servers_cache, + Lex_ident_server::charset_info(), + 32, 0, 0, (my_hash_get_key) servers_cache_get_key, 0, 0)) { return_val= TRUE; /* we failed, out of memory? */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3c2e4e1adb2..dfce9b64804 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1086,7 +1086,8 @@ public: ER_THD(thd, ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW", m_sctx->priv_user, m_sctx->host_or_ip, - m_top_view->get_db_name(), m_top_view->get_table_name()); + m_top_view->get_db_name().str, + m_top_view->get_table_name().str); } return m_view_access_denied_message_ptr; } @@ -1131,8 +1132,8 @@ public: push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_VIEW_INVALID, ER_THD(thd, ER_VIEW_INVALID), - m_top_view->get_db_name(), - m_top_view->get_table_name()); + m_top_view->get_db_name().str, + m_top_view->get_table_name().str); is_handled= TRUE; break; @@ -1350,8 +1351,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) else { if (table_list->schema_table) - protocol->store(table_list->schema_table->table_name, - strlen(table_list->schema_table->table_name), + protocol->store(&table_list->schema_table->table_name, system_charset_info); else protocol->store(table_list->table->alias.ptr(), @@ -1434,7 +1434,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname, if (is_infoschema_db(dbname)) { *dbname= INFORMATION_SCHEMA_NAME; - create.default_table_charset= system_charset_info; + create.default_table_charset= system_charset_info_for_i_s; create.schema_comment= NULL; } else @@ -2157,8 +2157,7 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list, { if (table_list->schema_table) { - alias.str= table_list->schema_table->table_name; - alias.length= strlen(alias.str); + alias= table_list->schema_table->table_name; } else { @@ -2180,8 +2179,9 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list, */ if (with_db_name == WITH_DB_NAME) { - const LEX_CSTRING *const db= - table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db; + const LEX_CSTRING *const db= table_list->schema_table ? + static_cast(&INFORMATION_SCHEMA_NAME) : + static_cast(&table->s->db); if (!thd->db.str || cmp(db, &thd->db)) { append_identifier(thd, packet, db); @@ -3861,7 +3861,7 @@ static bool show_status_array(THD *thd, const char *wild, for status variables defined under wsrep plugin. TODO: remove once lp:1306875 has been addressed. */ - if (prefix.length && !my_strcasecmp(system_charset_info, prefix.str, "wsrep")) + if (prefix.length && Lex_ident_sys_var(prefix).streq("wsrep"_LEX_CSTRING)) { is_wsrep_var= TRUE; } @@ -4090,10 +4090,10 @@ bool get_lookup_value(THD *thd, Item_func *item_func, { ST_SCHEMA_TABLE *schema_table= table->schema_table; ST_FIELD_INFO *field_info= schema_table->fields_info; - const char *field_name1= schema_table->idx_field1 >= 0 ? - field_info[schema_table->idx_field1].name().str : ""; - const char *field_name2= schema_table->idx_field2 >= 0 ? - field_info[schema_table->idx_field2].name().str : ""; + const Lex_ident_column field_name1= schema_table->idx_field1 >= 0 ? + field_info[schema_table->idx_field1].name() : ""_Lex_ident_column; + const Lex_ident_column field_name2= schema_table->idx_field2 >= 0 ? + field_info[schema_table->idx_field2].name() : ""_Lex_ident_column; if (item_func->functype() == Item_func::EQ_FUNC || item_func->functype() == Item_func::EQUAL_FUNC) @@ -4102,7 +4102,6 @@ bool get_lookup_value(THD *thd, Item_func *item_func, char tmp[MAX_FIELD_WIDTH]; String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info); Item_field *item_field; - CHARSET_INFO *cs= system_charset_info; if (item_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && item_func->arguments()[1]->const_item()) @@ -4129,18 +4128,13 @@ bool get_lookup_value(THD *thd, Item_func *item_func, return 1; /* Lookup value is database name */ - if (!cs->strnncollsp(field_name1, strlen(field_name1), - item_field->field_name.str, - item_field->field_name.length)) + if (item_field->field_name.streq(field_name1)) { thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(), tmp_str->length()); } /* Lookup value is table name */ - else if (!cs->strnncollsp(field_name2, - strlen(field_name2), - item_field->field_name.str, - item_field->field_name.length)) + else if (item_field->field_name.streq(field_name2)) { thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(), tmp_str->length()); @@ -4225,20 +4219,15 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) else if (item->type() == Item::FIELD_ITEM) { Item_field *item_field= (Item_field*)item; - CHARSET_INFO *cs= system_charset_info; ST_SCHEMA_TABLE *schema_table= table->schema_table; ST_FIELD_INFO *field_info= schema_table->fields_info; - const char *field_name1= schema_table->idx_field1 >= 0 ? - field_info[schema_table->idx_field1].name().str : ""; - const char *field_name2= schema_table->idx_field2 >= 0 ? - field_info[schema_table->idx_field2].name().str : ""; + const Lex_ident_column field_name1= schema_table->idx_field1 >= 0 ? + field_info[schema_table->idx_field1].name() : ""_Lex_ident_column; + const Lex_ident_column field_name2= schema_table->idx_field2 >= 0 ? + field_info[schema_table->idx_field2].name() : ""_Lex_ident_column; if (table->table != item_field->field->table || - (cs->strnncollsp(field_name1, strlen(field_name1), - item_field->field_name.str, - item_field->field_name.length) && - cs->strnncollsp(field_name2, strlen(field_name2), - item_field->field_name.str, - item_field->field_name.length))) + (!field_name1.streq(item_field->field_name) && + !field_name2.streq(item_field->field_name))) return 0; } else if (item->type() == Item::EXPR_CACHE_ITEM) @@ -4504,16 +4493,15 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, if (lower_case_table_names) { if (wild_case_compare(files_charset_info, - schema_table->table_name, + schema_table->table_name.str, wild)) DBUG_RETURN(0); } - else if (wild_compare(schema_table->table_name, wild, 0)) + else if (wild_compare(schema_table->table_name.str, wild, 0)) DBUG_RETURN(0); } - if ((file_name= thd->make_clex_string(schema_table->table_name, - strlen(schema_table->table_name))) && + if ((file_name= thd->make_clex_string(schema_table->table_name)) && !file_list->append(file_name)) DBUG_RETURN(0); DBUG_RETURN(1); @@ -4528,7 +4516,7 @@ int schema_tables_add(THD *thd, Dynamic_array *files, st_add_schema_table add_data; DBUG_ENTER("schema_tables_add"); - for (; tmp_schema_table->table_name; tmp_schema_table++) + for (; tmp_schema_table->table_name.str; tmp_schema_table++) { if (tmp_schema_table->hidden) continue; @@ -4537,16 +4525,14 @@ int schema_tables_add(THD *thd, Dynamic_array *files, if (lower_case_table_names) { if (wild_case_compare(files_charset_info, - tmp_schema_table->table_name, + tmp_schema_table->table_name.str, wild)) continue; } - else if (wild_compare(tmp_schema_table->table_name, wild, 0)) + else if (wild_compare(tmp_schema_table->table_name.str, wild, 0)) continue; } - if ((file_name= - thd->make_clex_string(tmp_schema_table->table_name, - strlen(tmp_schema_table->table_name))) && + if ((file_name= thd->make_clex_string(tmp_schema_table->table_name)) && !files->append(file_name)) continue; DBUG_RETURN(1); @@ -4590,9 +4576,7 @@ make_table_name_list(THD *thd, Dynamic_array *table_names, if (!lookup_field_vals->wild_table_value && lookup_field_vals->table_value.str) { - if (check_table_name(lookup_field_vals->table_value.str, - lookup_field_vals->table_value.length, - false)) + if (Lex_ident_table::check_name(lookup_field_vals->table_value, false)) { /* Impossible value for a table name, @@ -4607,8 +4591,7 @@ make_table_name_list(THD *thd, Dynamic_array *table_names, find_schema_table(thd, &lookup_field_vals->table_value); if (schema_table && !schema_table->hidden) { - if (!(name= thd->make_clex_string(schema_table->table_name, - strlen(schema_table->table_name))) || + if (!(name= thd->make_clex_string(schema_table->table_name)) || table_names->append(name)) return 1; } @@ -5088,14 +5071,16 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, cache subsystems require normalized (lowercased) database and table names as input. */ - table_list.db= db_name_buff.copy_casedn(*db_name).to_lex_cstring(); - table_list.table_name= table_name_buff.copy_casedn(*table_name). - to_lex_cstring(); + table_list.db= Lex_ident_db(db_name_buff. + copy_casedn(*db_name).to_lex_cstring()); + table_list.table_name= Lex_ident_table(table_name_buff. + copy_casedn(*table_name). + to_lex_cstring()); } else { - table_list.table_name= *table_name; - table_list.db= *db_name; + table_list.table_name= Lex_ident_table(*table_name); + table_list.db= Lex_ident_db(*db_name); } /* @@ -5428,15 +5413,16 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { All_tmp_tables_list::Iterator it(*open_tables_state_backup.temporary_tables); TMP_TABLE_SHARE *share_temp; - const char *lookup_db= plan->lookup_field_vals.db_value.str; - int (*cmp)(CHARSET_INFO *, const char *, const char *)= - plan->lookup_field_vals.wild_db_value - ? wild_case_compare : system_charset_info->coll->strcasecmp; + const LEX_CSTRING &lookup_db= plan->lookup_field_vals.db_value; while ((share_temp= it++)) { - if (lookup_db) + if (lookup_db.str) { - if (cmp(system_charset_info, share_temp->db.str, lookup_db)) + if (lookup_db.str && + (plan->lookup_field_vals.wild_db_value ? + wild_case_compare(system_charset_info, + share_temp->db.str, lookup_db.str) : + !share_temp->db.streq(lookup_db))) continue; } @@ -5496,8 +5482,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(thd->col_access & TABLE_ACLS)) { - table_acl_check.db= *db_name; - table_acl_check.table_name= *table_name; + table_acl_check.db= Lex_ident_db(*db_name); + table_acl_check.table_name= Lex_ident_table(*table_name); table_acl_check.grant.privilege= thd->col_access; if (check_grant(thd, TABLE_ACLS, &table_acl_check, TRUE, 1, TRUE)) continue; @@ -5672,7 +5658,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) if (db_name == &INFORMATION_SCHEMA_NAME) { if (store_schema_schemata(thd, table, db_name, - system_charset_info)) + system_charset_info_for_i_s)) DBUG_RETURN(1); continue; } @@ -6329,7 +6315,7 @@ static int store_schema_period_record(THD *thd, TABLE_LIST *tl, /* Reveal the value only if the user has any privilege on this column */ bool col_granted= get_column_grant(thd, &tl->grant, db_name->str, table_name->str, - field->field_name.str) & COL_DML_ACLS; + field->field_name) & COL_DML_ACLS; if (col_granted) { schema_table->field[period_field]->set_notnull(); @@ -6424,7 +6410,7 @@ int get_schema_column_record(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS ulonglong col_access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, - field->field_name.str) & COL_ACLS; + field->field_name) & COL_ACLS; if (!col_access && !tables->schema_table) continue; @@ -7236,7 +7222,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, { auto access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, - key_part->field->field_name.str); + key_part->field->field_name); if (!access) break; @@ -7352,10 +7338,10 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, Security_context *sctx= thd->security_ctx; if (!tables->allowed_show) { - if (!my_strcasecmp(system_charset_info, tables->definer.user.str, - sctx->priv_user) && - !my_strcasecmp(system_charset_info, tables->definer.host.str, - sctx->priv_host)) + if (my_charset_bin.streq(tables->definer.user, + Lex_cstring_strlen(sctx->priv_user)) && + Lex_ident_host(tables->definer.host). + streq(Lex_cstring_strlen(sctx->priv_host))) tables->allowed_show= TRUE; #ifndef NO_EMBEDDED_ACCESS_CHECKS else @@ -7504,8 +7490,8 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables, if (!(thd->col_access & TABLE_ACLS)) { - table_acl_check.db= *db_name; - table_acl_check.table_name= *table_name; + table_acl_check.db= Lex_ident_db(*db_name); + table_acl_check.table_name= Lex_ident_table(*table_name); table_acl_check.grant.privilege= thd->col_access; if (check_grant(thd, TABLE_ACLS, &table_acl_check, FALSE, 1, TRUE)) DBUG_RETURN(res); @@ -7746,7 +7732,7 @@ get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables, { auto access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, - key_part->field->field_name.str); + key_part->field->field_name); if (!access) break; @@ -7787,7 +7773,8 @@ get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables, while ((r_info= it1++)) { auto access= get_column_grant(thd, &tables->grant, db_name->str, - table_name->str, r_info->str); + table_name->str, + Lex_ident_column(*r_info)); if (!access) break; @@ -7839,7 +7826,7 @@ int get_schema_key_period_usage_record(THD *thd, TABLE_LIST *tables, { const uint keys_total= tables->table->s->keys; const KEY *keys= tables->table->s->key_info; - const Lex_ident &period_name= tables->table->s->period.name; + const Lex_ident_column &period_name= tables->table->s->period.name; if (!period_name) return 0; @@ -8089,8 +8076,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, while ((part_elem= part_it++)) { - table->field[3]->store(part_elem->partition_name, - strlen(part_elem->partition_name), cs); + table->field[3]->store_ident(part_elem->partition_name); table->field[3]->set_notnull(); /* PARTITION_ORDINAL_POSITION */ table->field[5]->store((longlong) ++part_pos, TRUE); @@ -8180,8 +8166,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, while ((subpart_elem= sub_it++)) { - table->field[4]->store(subpart_elem->partition_name, - strlen(subpart_elem->partition_name), cs); + table->field[4]->store_ident(subpart_elem->partition_name); table->field[4]->set_notnull(); /* SUBPARTITION_ORDINAL_POSITION */ table->field[6]->store((longlong) ++subpart_pos, TRUE); @@ -8396,7 +8381,7 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; OPEN_TABLE_LIST *open_list; - if (!(open_list= list_open_tables(thd, thd->lex->first_select_lex()->db.str, + if (!(open_list= list_open_tables(thd, thd->lex->first_select_lex()->db, wild)) && thd->is_fatal_error) DBUG_RETURN(1); @@ -8614,8 +8599,8 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, { TABLE_LIST table_acl_check; bzero((char*) &table_acl_check, sizeof(table_acl_check)); - table_acl_check.db= *f_key_info->referenced_db; - table_acl_check.table_name= *f_key_info->referenced_table; + table_acl_check.db= Lex_ident_db(*f_key_info->referenced_db); + table_acl_check.table_name= Lex_ident_table(*f_key_info->referenced_table); table_acl_check.grant.privilege= thd->col_access; check_grant(thd, SELECT_ACL, &table_acl_check, 0, 1, 1); @@ -8651,8 +8636,11 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, struct schema_table_ref { - const char *table_name; + const Lex_ident_i_s_table table_name; ST_SCHEMA_TABLE *schema_table; + schema_table_ref(const LEX_CSTRING &name, ST_SCHEMA_TABLE *table) + :table_name(name), schema_table(table) + { } }; /* @@ -8672,13 +8660,10 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin, void* p_table) { schema_table_ref *p_schema_table= (schema_table_ref *)p_table; - const char* table_name= p_schema_table->table_name; ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("find_schema_table_in_plugin"); - if (!my_strcasecmp(system_charset_info, - schema_table->table_name, - table_name)) + if (p_schema_table->table_name.streq(schema_table->table_name)) { my_plugin_lock(thd, plugin); p_schema_table->schema_table= schema_table; @@ -8705,21 +8690,18 @@ static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin, ST_SCHEMA_TABLE *find_schema_table(THD *thd, const LEX_CSTRING *table_name, bool *in_plugin) { - schema_table_ref schema_table_a; ST_SCHEMA_TABLE *schema_table= schema_tables; DBUG_ENTER("find_schema_table"); *in_plugin= false; - for (; schema_table->table_name; schema_table++) + for (; schema_table->table_name.str; schema_table++) { - if (!my_strcasecmp(system_charset_info, - schema_table->table_name, - table_name->str)) + if (schema_table->table_name.streq(*table_name)) DBUG_RETURN(schema_table); } *in_plugin= true; - schema_table_a.table_name= table_name->str; + schema_table_ref schema_table_a(*table_name, NULL); if (plugin_foreach(thd, find_schema_table_in_plugin, MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a)) DBUG_RETURN(schema_table_a.schema_table); @@ -8772,7 +8754,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) tmp_table_param = new (thd->mem_root) TMP_TABLE_PARAM; tmp_table_param->init(); - tmp_table_param->table_charset= system_charset_info; + tmp_table_param->table_charset= system_charset_info_for_i_s; tmp_table_param->field_count= field_count; tmp_table_param->schema_table= 1; select_lex= table_list->select_lex; @@ -8999,9 +8981,8 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) working correctly */ if (table_list->schema_table_name.str) - table->alias_name_used= my_strcasecmp(table_alias_charset, - table_list->schema_table_name.str, - table_list->alias.str); + table->alias_name_used= !table_list->schema_table_name. + streq(table_list->alias); table_list->table= table; table->next= thd->derived_tables; thd->derived_tables= table; @@ -9066,7 +9047,7 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, { LEX_CSTRING db, table; DBUG_ENTER("make_schema_select"); - DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name)); + DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name.str)); /* We have to make non const db_name & table_name because of lower_case_table_names @@ -9075,8 +9056,8 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, INFORMATION_SCHEMA_NAME.length)) DBUG_RETURN(1); - if (!thd->make_lex_string(&table, schema_table->table_name, - strlen(schema_table->table_name))) + if (!thd->make_lex_string(&table, schema_table->table_name.str, + schema_table->table_name.length)) DBUG_RETURN(1); if (schema_table->old_format(thd, schema_table)) @@ -10391,127 +10372,137 @@ extern ST_FIELD_INFO optimizer_trace_info[]; ST_SCHEMA_TABLE schema_tables[]= { - {"ALL_PLUGINS", Show::plugin_fields_info, 0, + {"ALL_PLUGINS"_Lex_ident_i_s_table, Show::plugin_fields_info, 0, fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, - {"APPLICABLE_ROLES", Show::applicable_roles_fields_info, 0, + {"APPLICABLE_ROLES"_Lex_ident_i_s_table, + Show::applicable_roles_fields_info, 0, fill_schema_applicable_roles, 0, 0, -1, -1, 0, 0}, - {"CHARACTER_SETS", Show::charsets_fields_info, 0, + {"CHARACTER_SETS"_Lex_ident_i_s_table, Show::charsets_fields_info, 0, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, - {"CHECK_CONSTRAINTS", Show::check_constraints_fields_info, 0, + {"CHECK_CONSTRAINTS"_Lex_ident_i_s_table, + Show::check_constraints_fields_info, 0, get_all_tables, 0, get_check_constraints_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, - {"COLLATIONS", Show::collation_fields_info, 0, + {"COLLATIONS"_Lex_ident_i_s_table, Show::collation_fields_info, 0, fill_schema_collation, make_old_format, 0, -1, -1, 0, 0}, - {"COLLATION_CHARACTER_SET_APPLICABILITY", Show::coll_charset_app_fields_info, + {"COLLATION_CHARACTER_SET_APPLICABILITY"_Lex_ident_i_s_table, + Show::coll_charset_app_fields_info, 0, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0}, - {"COLUMNS", Show::columns_fields_info, 0, + {"COLUMNS"_Lex_ident_i_s_table, Show::columns_fields_info, 0, get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL}, - {"COLUMN_PRIVILEGES", Show::column_privileges_fields_info, 0, + {"COLUMN_PRIVILEGES"_Lex_ident_i_s_table, + Show::column_privileges_fields_info, 0, fill_schema_column_privileges, 0, 0, -1, -1, 0, 0}, - {"ENABLED_ROLES", Show::enabled_roles_fields_info, 0, + {"ENABLED_ROLES"_Lex_ident_i_s_table, Show::enabled_roles_fields_info, 0, fill_schema_enabled_roles, 0, 0, -1, -1, 0, 0}, - {"ENGINES", Show::engines_fields_info, 0, + {"ENGINES"_Lex_ident_i_s_table, Show::engines_fields_info, 0, fill_schema_engines, make_old_format, 0, -1, -1, 0, 0}, #ifdef HAVE_EVENT_SCHEDULER - {"EVENTS", Show::events_fields_info, 0, + {"EVENTS"_Lex_ident_i_s_table, Show::events_fields_info, 0, Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0}, #else - {"EVENTS", Show::events_fields_info, 0, + {"EVENTS"_Lex_ident_i_s_table, Show::events_fields_info, 0, 0, make_old_format, 0, -1, -1, 0, 0}, #endif - {"EXPLAIN", Show::show_explain_tabular_fields_info, 0, + {"EXPLAIN"_Lex_ident_i_s_table, Show::show_explain_tabular_fields_info, 0, fill_show_explain_tabular, make_old_format, 0, -1, -1, TRUE /*hidden*/ , 0}, - {"EXPLAIN_JSON", Show::show_explain_json_fields_info, 0, + {"EXPLAIN_JSON"_Lex_ident_i_s_table, Show::show_explain_json_fields_info, 0, fill_show_explain_json, make_old_format, 0, -1, -1, TRUE /*hidden*/ , 0}, - {"ANALYZE", Show::show_analyze_tabular_fields_info, 0, + {"ANALYZE"_Lex_ident_i_s_table, Show::show_analyze_tabular_fields_info, 0, fill_show_analyze_tabular, make_old_format, 0, -1, -1, TRUE /*hidden*/, 0}, - {"ANALYZE_JSON", Show::show_analyze_json_fields_info, 0, + {"ANALYZE_JSON"_Lex_ident_i_s_table, Show::show_analyze_json_fields_info, 0, fill_show_analyze_json, make_old_format, 0, -1, -1, TRUE /*hidden*/, 0}, - {"FILES", Show::files_fields_info, 0, + {"FILES"_Lex_ident_i_s_table, Show::files_fields_info, 0, hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, - {"GLOBAL_STATUS", Show::variables_fields_info, 0, + {"GLOBAL_STATUS"_Lex_ident_i_s_table, Show::variables_fields_info, 0, fill_status, make_old_format, 0, 0, -1, 0, 0}, - {"GLOBAL_VARIABLES", Show::variables_fields_info, 0, + {"GLOBAL_VARIABLES"_Lex_ident_i_s_table, Show::variables_fields_info, 0, fill_variables, make_old_format, 0, 0, -1, 0, 0}, - {"KEYWORDS", Show::keywords_field_info, 0, + {"KEYWORDS"_Lex_ident_i_s_table, Show::keywords_field_info, 0, fill_i_s_keywords, 0, 0, -1, -1, 0, 0}, - {"KEY_CACHES", Show::keycache_fields_info, 0, + {"KEY_CACHES"_Lex_ident_i_s_table, Show::keycache_fields_info, 0, fill_key_cache_tables, 0, 0, -1,-1, 0, 0}, - {"KEY_COLUMN_USAGE", Show::key_column_usage_fields_info, 0, + {"KEY_COLUMN_USAGE"_Lex_ident_i_s_table, + Show::key_column_usage_fields_info, 0, get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, - {"KEY_PERIOD_USAGE", Show::key_period_usage_fields_info, 0, + {"KEY_PERIOD_USAGE"_Lex_ident_i_s_table, Show::key_period_usage_fields_info, 0, get_all_tables, 0, get_schema_key_period_usage_record, 4, 5, 0, OPTIMIZE_I_S_TABLE | OPEN_FRM_FILE_ONLY}, - {"OPEN_TABLES", Show::open_tables_fields_info, 0, + {"OPEN_TABLES"_Lex_ident_i_s_table, Show::open_tables_fields_info, 0, fill_open_tables, make_old_format, 0, -1, -1, 1, 0}, - {"OPTIMIZER_COSTS", Show::optimizer_costs_fields_info, 0, + {"OPTIMIZER_COSTS"_Lex_ident_i_s_table, Show::optimizer_costs_fields_info, 0, fill_optimizer_costs_tables, 0, 0, -1,-1, 0, 0}, - {"OPTIMIZER_TRACE", Show::optimizer_trace_info, 0, + {"OPTIMIZER_TRACE"_Lex_ident_i_s_table, Show::optimizer_trace_info, 0, fill_optimizer_trace_info, NULL, NULL, -1, -1, false, 0}, - {"PARAMETERS", Show::parameters_fields_info, 0, + {"PARAMETERS"_Lex_ident_i_s_table, Show::parameters_fields_info, 0, fill_schema_proc, 0, 0, 1, 2, 0, 0}, - {"PARTITIONS", Show::partitions_fields_info, 0, + {"PARTITIONS"_Lex_ident_i_s_table, Show::partitions_fields_info, 0, get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, - {"PERIODS", Show::periods_fields_info, 0, + {"PERIODS"_Lex_ident_i_s_table, Show::periods_fields_info, 0, get_all_tables, 0, get_schema_period_records, 1, 2, 0, OPTIMIZE_I_S_TABLE | OPEN_TABLE_ONLY}, - {"PLUGINS", Show::plugin_fields_info, 0, + {"PLUGINS"_Lex_ident_i_s_table, Show::plugin_fields_info, 0, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, - {"PROCESSLIST", Show::processlist_fields_info, 0, + {"PROCESSLIST"_Lex_ident_i_s_table, Show::processlist_fields_info, 0, fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, - {"PROFILING", Show::query_profile_statistics_info, 0, + {"PROFILING"_Lex_ident_i_s_table, Show::query_profile_statistics_info, 0, fill_query_profile_statistics_info, make_profile_table_for_show, NULL, -1, -1, false, 0}, - {"REFERENTIAL_CONSTRAINTS", Show::referential_constraints_fields_info, + {"REFERENTIAL_CONSTRAINTS"_Lex_ident_i_s_table, + Show::referential_constraints_fields_info, 0, get_all_tables, 0, get_referential_constraints_record, 1, 9, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, - {"ROUTINES", Show::proc_fields_info, 0, + {"ROUTINES"_Lex_ident_i_s_table, Show::proc_fields_info, 0, fill_schema_proc, make_proc_old_format, 0, 2, 3, 0, 0}, - {"SCHEMATA", Show::schema_fields_info, 0, + {"SCHEMATA"_Lex_ident_i_s_table, Show::schema_fields_info, 0, fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0}, - {"SCHEMA_PRIVILEGES", Show::schema_privileges_fields_info, 0, + {"SCHEMA_PRIVILEGES"_Lex_ident_i_s_table, + Show::schema_privileges_fields_info, 0, fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0}, - {"SEQUENCES", Show::sequence_fields_info, 0, + {"SEQUENCES"_Lex_ident_i_s_table, Show::sequence_fields_info, 0, get_all_tables, make_old_format, get_schema_sequence_record, 1, 2, 0, 0}, - {"SESSION_STATUS", Show::variables_fields_info, 0, + {"SESSION_STATUS"_Lex_ident_i_s_table, Show::variables_fields_info, 0, fill_status, make_old_format, 0, 0, -1, 0, 0}, - {"SESSION_VARIABLES", Show::variables_fields_info, 0, + {"SESSION_VARIABLES"_Lex_ident_i_s_table, Show::variables_fields_info, 0, fill_variables, make_old_format, 0, 0, -1, 0, 0}, - {"STATISTICS", Show::stat_fields_info, 0, + {"STATISTICS"_Lex_ident_i_s_table, Show::stat_fields_info, 0, get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0, OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE}, - {"SQL_FUNCTIONS", Show::sql_functions_field_info, 0, + {"SQL_FUNCTIONS"_Lex_ident_i_s_table, Show::sql_functions_field_info, 0, fill_i_s_sql_functions, 0, 0, -1, -1, 0, 0}, - {"SYSTEM_VARIABLES", Show::sysvars_fields_info, 0, + {"SYSTEM_VARIABLES"_Lex_ident_i_s_table, Show::sysvars_fields_info, 0, fill_sysvars, make_old_format, 0, 0, -1, 0, 0}, - {"TABLES", Show::tables_fields_info, 0, + {"TABLES"_Lex_ident_i_s_table, Show::tables_fields_info, 0, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|I_S_EXTENDED_ERROR_HANDLING}, - {"TABLESPACES", Show::tablespaces_fields_info, 0, + {"TABLESPACES"_Lex_ident_i_s_table, Show::tablespaces_fields_info, 0, hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, - {"TABLE_CONSTRAINTS", Show::table_constraints_fields_info, 0, + {"TABLE_CONSTRAINTS"_Lex_ident_i_s_table, + Show::table_constraints_fields_info, 0, get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, - {"TABLE_NAMES", Show::table_names_fields_info, 0, + {"TABLE_NAMES"_Lex_ident_i_s_table, Show::table_names_fields_info, 0, get_all_tables, make_table_names_old_format, 0, 1, 2, 1, OPTIMIZE_I_S_TABLE}, - {"TABLE_PRIVILEGES", Show::table_privileges_fields_info, 0, + {"TABLE_PRIVILEGES"_Lex_ident_i_s_table, + Show::table_privileges_fields_info, 0, fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, - {"TRIGGERS", Show::triggers_fields_info, 0, + {"TRIGGERS"_Lex_ident_i_s_table, Show::triggers_fields_info, 0, get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0, OPEN_TRIGGER_ONLY|OPTIMIZE_I_S_TABLE}, - {"USER_PRIVILEGES", Show::user_privileges_fields_info, 0, + {"USER_PRIVILEGES"_Lex_ident_i_s_table, + Show::user_privileges_fields_info, 0, fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, - {"VIEWS", Show::view_fields_info, 0, + {"VIEWS"_Lex_ident_i_s_table, Show::view_fields_info, 0, get_all_tables, 0, get_schema_views_record, 1, 2, 0, OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE|I_S_EXTENDED_ERROR_HANDLING}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + {Lex_ident_i_s_table(), 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static_assert(array_elements(schema_tables) == SCH_ENUM_SIZE + 1, @@ -10534,7 +10525,7 @@ int initialize_schema_table(st_plugin_int *plugin) schema_table->idx_field2= -1; /* Make the name available to the init() function. */ - schema_table->table_name= plugin->name.str; + schema_table->table_name= Lex_ident_i_s_table(plugin->name); if (plugin->plugin->init(schema_table)) { @@ -10554,7 +10545,7 @@ int initialize_schema_table(st_plugin_int *plugin) } /* Make sure the plugin name is not set inside the init() function. */ - schema_table->table_name= plugin->name.str; + schema_table->table_name= Lex_ident_i_s_table(plugin->name); } DBUG_RETURN(0); } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 408a5cfe1f6..df77facb3a7 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -73,11 +73,11 @@ static const uint STATISTICS_TABLES= 3; The names of the statistical tables in this array must correspond the definitions of the tables in the file ../scripts/mysql_system_tables.sql */ -static const LEX_CSTRING stat_table_name[STATISTICS_TABLES]= +static const Lex_ident_table stat_table_name[STATISTICS_TABLES]= { - { STRING_WITH_LEN("table_stats") }, - { STRING_WITH_LEN("column_stats") }, - { STRING_WITH_LEN("index_stats") } + "table_stats"_Lex_ident_table, + "column_stats"_Lex_ident_table, + "index_stats"_Lex_ident_table, }; @@ -3296,7 +3296,7 @@ read_statistics_for_tables(THD *thd, TABLE_LIST *tables, bool force_reload) statistics_for_tables_is_needed= true; } } - else if (is_stat_table(&tl->db, &tl->alias)) + else if (is_stat_table(tl->db, tl->alias)) found_stat_table= true; } @@ -4449,15 +4449,15 @@ double Histogram_binary::range_selectivity(Field *field, /* Check whether the table is one of the persistent statistical tables. */ -bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table) +bool is_stat_table(const Lex_ident_db &db, const Lex_ident_table &table) { - DBUG_ASSERT(db->str && table->str); + DBUG_ASSERT(db.str && table.str); - if (!my_strcasecmp(table_alias_charset, db->str, MYSQL_SCHEMA_NAME.str)) + if (db.streq(MYSQL_SCHEMA_NAME)) { for (uint i= 0; i < STATISTICS_TABLES; i ++) { - if (!my_strcasecmp(table_alias_charset, table->str, stat_table_name[i].str)) + if (table.streq(stat_table_name[i])) return true; } } diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 12802bc98e2..bd997588153 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -148,7 +148,7 @@ double get_column_range_cardinality(Field *field, key_range *min_endp, key_range *max_endp, uint range_flag); -bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table); +bool is_stat_table(const Lex_ident_db &db, const Lex_ident_table &table); bool is_eits_usable(Field* field); class Histogram_builder; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6803c335615..9d48a895214 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -101,18 +101,22 @@ class Enable_wsrep_ctas_guard #include #endif -const LEX_CSTRING primary_key_name= { STRING_WITH_LEN("PRIMARY") }; +const Lex_ident_column primary_key_name= "PRIMARY"_Lex_ident_column; static const LEX_CSTRING generated_by_server= { STRING_WITH_LEN(" /* generated by server */") }; static const LEX_CSTRING SEQUENCE_clex_str= { STRING_WITH_LEN("SEQUENCE") }; static const LEX_CSTRING TABLE_clex_str= { STRING_WITH_LEN("TABLE") }; -static int check_if_keyname_exists(const char *name,KEY *start, KEY *end); -static char *make_unique_key_name(THD *, const char *, KEY *, KEY *); +static int check_if_keyname_exists(const Lex_ident_column &name, + const KEY *start, const KEY *end); +static Lex_ident_column make_unique_key_name(THD *, + const Lex_ident_column &name, + const KEY *, const KEY *); static bool make_unique_constraint_name(THD *, LEX_CSTRING *, const char *, List *, uint *); -static const char *make_unique_invisible_field_name(THD *, const char *, - List *); +static Lex_ident_column make_unique_invisible_field_name(THD *, + const Lex_ident_column &name, + List *); static int copy_data_between_tables(THD *, TABLE *,TABLE *, bool, uint, ORDER *, ha_rows *, ha_rows *, @@ -526,7 +530,7 @@ uint tablename_to_filename(const char *from, char *to, size_t to_length) a lot of places don't check the return value and expect a zero terminated string. */ - if (check_table_name(to, length, TRUE)) + if (Lex_ident_table::check_name({to, length}, true)) { to[0]= 0; length= 0; @@ -2366,7 +2370,7 @@ void promote_first_timestamp_column(List *column_definitions) static bool key_cmp(const Key_part_spec &a, const Key_part_spec &b) { return a.length == b.length && a.asc == b.asc && - !lex_string_cmp(system_charset_info, &a.field_name, &b.field_name); + a.field_name.streq(b.field_name); } /** @@ -2566,27 +2570,23 @@ bool Column_definition::prepare_stage1_check_typelib_default() Create_field pointer */ int mysql_add_invisible_field(THD *thd, List * field_list, - const char *field_name, Type_handler *type_handler, + const Lex_ident_column &field_name, Type_handler *type_handler, field_visibility_t invisible, Item* default_value) { Create_field *fld= new(thd->mem_root)Create_field(); - const char *new_name= NULL; /* Get unique field name if invisible == INVISIBLE_FULL */ if (invisible == INVISIBLE_FULL) { + Lex_ident_column new_name; if ((new_name= make_unique_invisible_field_name(thd, field_name, - field_list))) - { - fld->field_name.str= new_name; - fld->field_name.length= strlen(new_name); - } + field_list)).str) + fld->field_name= new_name; else return 1; //Should not happen } else { - fld->field_name.str= thd->strmake(field_name, strlen(field_name)); - fld->field_name.length= strlen(field_name); + fld->field_name= thd->lex_ident_copy(field_name); } fld->set_handler(type_handler); fld->invisible= invisible; @@ -2636,14 +2636,14 @@ static Create_field * add_hash_field(THD * thd, List *create_list, */ while ((dup_field= it++)) { - if (!my_strcasecmp(system_charset_info, field_name.str, dup_field->field_name.str)) + if (dup_field->field_name.streq(field_name)) { num++; make_long_hash_field_name(&field_name, num); it.rewind(); } } - cf->field_name= field_name; + cf->field_name= Lex_ident_column(field_name); cf->set_handler(&type_handler_slonglong); key_info->algorithm= HA_KEY_ALG_LONG_HASH; create_list->push_back(cf,thd->mem_root); @@ -2735,18 +2735,18 @@ static bool mysql_prepare_create_table_stage1(THD *thd, DBUG_EXECUTE_IF("test_pseudo_invisible",{ mysql_add_invisible_field(thd, &alter_info->create_list, - "invisible", &type_handler_slong, INVISIBLE_SYSTEM, + "invisible"_Lex_ident_column, + &type_handler_slong, INVISIBLE_SYSTEM, new (thd->mem_root)Item_int(thd, 9)); }); DBUG_EXECUTE_IF("test_completely_invisible",{ mysql_add_invisible_field(thd, &alter_info->create_list, - "invisible", &type_handler_slong, INVISIBLE_FULL, + "invisible"_Lex_ident_column, + &type_handler_slong, INVISIBLE_FULL, new (thd->mem_root)Item_int(thd, 9)); }); DBUG_EXECUTE_IF("test_invisible_index",{ - LEX_CSTRING temp; - temp.str= "invisible"; - temp.length= strlen("invisible"); + LEX_CSTRING temp= "invisible"_Lex_ident_column; mysql_add_invisible_index(thd, &alter_info->key_list , &temp, Key::MULTIPLE); }); @@ -2817,7 +2817,7 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, handler *file, KEY **key_info_buffer, uint *key_count, int create_table_mode) { - const char *key_name; + Lex_ident_column key_name; Create_field *sql_field,*dup_field; uint field,null_fields,max_key_length; ulong record_offset= 0; @@ -2878,7 +2878,7 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, /* Check if we have used the same field name before */ for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) { - if (lex_string_cmp(scs, &sql_field->field_name, &dup_field->field_name) == 0) + if (sql_field->field_name.streq(dup_field->field_name)) { /* If this was a CREATE ... SELECT statement, accept a field @@ -3073,13 +3073,13 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, else (*key_count)--; if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) && - !my_strcasecmp(scs, key->name.str, primary_key_name.str)) + key->name.streq(primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); DBUG_RETURN(TRUE); } if (key->type == Key::PRIMARY && key->name.str && - my_strcasecmp(scs, key->name.str, primary_key_name.str) != 0) + !key->name.streq(primary_key_name)) { bool sav_abort_on_warning= thd->abort_on_warning; thd->abort_on_warning= FALSE; /* Don't make an error out of this. */ @@ -3117,28 +3117,28 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, MYF(0)); DBUG_RETURN(true); } - key_name= primary_key_name.str; + key_name= primary_key_name; primary_key=1; } - else if (!(key_name= key->name.str)) + else if (!(key_name= key->name).str) { - auto field_name= key->columns.elem(0)->field_name; + Lex_ident_column field_name(key->columns.elem(0)->field_name); it.rewind(); while ((sql_field=it++) && - lex_string_cmp(scs, &field_name, &sql_field->field_name)); + !field_name.streq(sql_field->field_name)) + { } if (sql_field) field_name= sql_field->field_name; - key_name=make_unique_key_name(thd, field_name.str, - *key_info_buffer, key_info); + key_name= make_unique_key_name(thd, field_name, + *key_info_buffer, key_info); } if (check_if_keyname_exists(key_name, *key_info_buffer, key_info)) { - my_error(ER_DUP_KEYNAME, MYF(0), key_name); + my_error(ER_DUP_KEYNAME, MYF(0), key_name.str); DBUG_RETURN(true); } - key_info->name.str= (char*) key_name; - key_info->name.length= strlen(key_name); + key_info->name= key_name; key->name= key_info->name; int parts_added= append_system_key_parts(thd, create_info, key); @@ -3301,8 +3301,8 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, it.rewind(); field=0; while ((sql_field=it++) && - lex_string_cmp(scs, &column->field_name, &sql_field->field_name)) - field++; + !column->field_name.streq(sql_field->field_name)) + field++; /* Either field is not present or field visibility is > INVISIBLE_USER */ @@ -3321,7 +3321,7 @@ mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info, } while ((dup_column= cols2++) != column) { - if (!lex_string_cmp(scs, &column->field_name, &dup_column->field_name)) + if (column->field_name.streq(dup_column->field_name)) { my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str); DBUG_RETURN(TRUE); @@ -3627,7 +3627,7 @@ without_overlaps_err: { for (Key_part_spec& kp2: fk->columns) { - if (!lex_string_cmp(scs, &kp.field_name, &kp2.field_name)) + if (kp.field_name.streq(kp2.field_name)) { goto without_overlaps_err; } @@ -3738,19 +3738,19 @@ without_overlaps_err: if (create_simple) { if (sql_field->vcol_info && sql_field->vcol_info->expr && - check_expression(sql_field->vcol_info, &sql_field->field_name, + check_expression(sql_field->vcol_info, sql_field->field_name, sql_field->vcol_info->is_stored() ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL, alter_info)) DBUG_RETURN(TRUE); if (sql_field->default_value && - check_expression(sql_field->default_value, &sql_field->field_name, + check_expression(sql_field->default_value, sql_field->field_name, VCOL_DEFAULT, alter_info)) DBUG_RETURN(TRUE); if (sql_field->check_constraint && - check_expression(sql_field->check_constraint, &sql_field->field_name, + check_expression(sql_field->check_constraint, sql_field->field_name, VCOL_CHECK_FIELD, alter_info)) DBUG_RETURN(TRUE); } @@ -3785,8 +3785,7 @@ without_overlaps_err: key->type != Key::FOREIGN_KEY) continue; - if (check->name.length == key->name.length && - my_strcasecmp(scs, check->name.str, key->name.str) == 0) + if (check->name.streq(key->name)) { my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); DBUG_RETURN(TRUE); @@ -3799,7 +3798,7 @@ without_overlaps_err: DBUG_RETURN(TRUE); } } - if (check_expression(check, &check->name, VCOL_CHECK_TABLE, alter_info)) + if (check_expression(check, check->name, VCOL_CHECK_TABLE, alter_info)) DBUG_RETURN(TRUE); } } @@ -4010,8 +4009,8 @@ bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root) static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info, Key *key) { - const Lex_ident &row_start_field= create_info->vers_info.as_row.start; - const Lex_ident &row_end_field= create_info->vers_info.as_row.end; + const Lex_ident_column &row_start_field= create_info->vers_info.as_row.start; + const Lex_ident_column &row_end_field= create_info->vers_info.as_row.end; DBUG_ASSERT(!create_info->versioned() || (row_start_field && row_end_field)); int result = 0; @@ -4141,7 +4140,7 @@ handler *mysql_create_frm_image(THD *thd, HA_CREATE_INFO *create_info, if (validate_comment_length(thd, &comment, TABLE_PARTITION_COMMENT_MAXLEN, ER_TOO_LONG_TABLE_PARTITION_COMMENT, - part_elem->partition_name)) + part_elem->partition_name.str)) DBUG_RETURN(NULL); /* cut comment length. Safe to do in all cases */ ((char*)part_elem->part_comment)[comment.length]= '\0'; @@ -4160,7 +4159,7 @@ handler *mysql_create_frm_image(THD *thd, HA_CREATE_INFO *create_info, if (validate_comment_length(thd, &comment, TABLE_PARTITION_COMMENT_MAXLEN, ER_TOO_LONG_TABLE_PARTITION_COMMENT, - subpart_elem->partition_name)) + subpart_elem->partition_name.str)) DBUG_RETURN(NULL); /* cut comment length. Safe to do in all cases */ ((char*)subpart_elem->part_comment)[comment.length]= '\0'; @@ -4366,8 +4365,8 @@ static int create_table_impl(THD *thd, DDL_LOG_STATE *ddl_log_state_create, DDL_LOG_STATE *ddl_log_state_rm, - const LEX_CSTRING &orig_db, - const LEX_CSTRING &orig_table_name, + const Lex_ident_db &orig_db, + const Lex_ident_table &orig_table_name, const LEX_CSTRING &db, const LEX_CSTRING &table_name, const LEX_CSTRING &path, const DDL_options_st options, HA_CREATE_INFO *create_info, Alter_info *alter_info, @@ -4430,7 +4429,8 @@ int create_table_impl(THD *thd, in-use in THD::all_temp_tables list of TABLE_SHAREs. */ TABLE *tmp_table= internal_tmp_table ? NULL : - thd->find_temporary_table(db.str, table_name.str, THD::TMP_TABLE_ANY); + thd->find_temporary_table(Lex_ident_db(db), Lex_ident_table(table_name), + THD::TMP_TABLE_ANY); if (tmp_table) { @@ -4663,8 +4663,9 @@ int create_table_impl(THD *thd, create_info->table= 0; if (!frm_only && create_info->tmp_table()) { - TABLE *table= thd->create_and_open_tmp_table(frm, path.str, db.str, - table_name.str, + TABLE *table= thd->create_and_open_tmp_table(frm, path.str, + Lex_ident_db(db), + Lex_ident_table(table_name), false); if (!table) @@ -4726,8 +4727,8 @@ int mysql_create_table_no_lock(THD *thd, uint path_length; char path[FN_REFLEN + 1]; LEX_CSTRING cpath; - const LEX_CSTRING *db= &table_list->db; - const LEX_CSTRING *table_name= &table_list->table_name; + const Lex_ident_db *db= &table_list->db; + const Lex_ident_table *table_name= &table_list->table_name; LEX_CUSTRING frm= {0,0}; DBUG_ASSERT(create_info->default_table_charset); @@ -5039,12 +5040,15 @@ err: **/ static int -check_if_keyname_exists(const char *name, KEY *start, KEY *end) +check_if_keyname_exists(const Lex_ident_column &name, + const KEY *start, const KEY *end) { uint i= 1; - for (KEY *key=start; key != end ; key++, i++) - if (!my_strcasecmp(system_charset_info, name, key->name.str)) + for (const KEY *key= start; key != end ; key++, i++) + { + if (key->name.streq(name)) return i; + } return 0; } @@ -5052,27 +5056,29 @@ check_if_keyname_exists(const char *name, KEY *start, KEY *end) Returns 1 if field name exists otherwise 0 */ static bool -check_if_field_name_exists(const char *name, List * fields) +check_if_field_name_exists(const Lex_ident_column &name, + List * fields) { Create_field *fld; List_iteratorit(*fields); while ((fld = it++)) { - if (!my_strcasecmp(system_charset_info, fld->field_name.str, name)) + if (fld->field_name.streq(name)) return 1; } return 0; } -static char * -make_unique_key_name(THD *thd, const char *field_name,KEY *start,KEY *end) +static Lex_ident_column +make_unique_key_name(THD *thd, const Lex_ident_column &field_name, + const KEY *start, const KEY *end) { char buff[MAX_FIELD_NAME],*buff_end; if (!check_if_keyname_exists(field_name,start,end) && - my_strcasecmp(system_charset_info,field_name,primary_key_name.str)) - return (char*) field_name; // Use fieldname - buff_end=strmake(buff,field_name, sizeof(buff)-4); + !field_name.streq(primary_key_name)) + return field_name; // Use fieldname + buff_end= strmake(buff, field_name.str, sizeof(buff)-4); /* Only 3 chars + '\0' left, so need to limit to 2 digit @@ -5081,11 +5087,12 @@ make_unique_key_name(THD *thd, const char *field_name,KEY *start,KEY *end) for (uint i=2 ; i< 100; i++) { *buff_end= '_'; - int10_to_str(i, buff_end+1, 10); - if (!check_if_keyname_exists(buff,start,end)) - return thd->strdup(buff); + const char *buff_end2= int10_to_str(i, buff_end + 1, 10); + const Lex_ident_column ident(buff, (size_t) (buff_end2 - buff)); + if (!check_if_keyname_exists(ident, start, end)) + return thd->lex_ident_copy(ident); } - return (char*) "not_specified"; // Should never happen + return "not_specified"_Lex_ident_column; // Should never happen } /** @@ -5109,16 +5116,16 @@ static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, // if own_base_name provided, try it first if (round != 0 || !own_name_base) real_end= int10_to_str((*nr)++, end, 10); + const Lex_ident_column ident(buff, (size_t) (real_end - buff)); it.rewind(); while ((check= it++)) { - if (check->name.str && - !my_strcasecmp(system_charset_info, buff, check->name.str)) + if (check->name.str && check->name.streq(ident)) break; } if (!check) // Found unique name { - name->length= (size_t) (real_end - buff); + name->length= ident.length; name->str= strmake_root(thd->stmt_arena->mem_root, buff, name->length); return (name->str == NULL); } @@ -5133,25 +5140,27 @@ static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, user added a same column name as of INVISIBLE_FULL , we change INVISIBLE_FULL column name. */ -static const -char * make_unique_invisible_field_name(THD *thd, const char *field_name, - List *fields) +static Lex_ident_column +make_unique_invisible_field_name(THD *thd, + const Lex_ident_column &field_name, + List *fields) { if (!check_if_field_name_exists(field_name, fields)) return field_name; char buff[MAX_FIELD_NAME], *buff_end; - buff_end= strmake_buf(buff, field_name); + buff_end= strmake_buf(buff, field_name.str); if (buff_end - buff < 5) - return NULL; // Should not happen + return Lex_ident_column(); // Should not happen for (uint i=1 ; i < 10000; i++) { char *real_end= int10_to_str(i, buff_end, 10); - if (check_if_field_name_exists(buff, fields)) + const Lex_ident_column ident(buff, (size_t) (real_end - buff)); + if (check_if_field_name_exists(ident, fields)) continue; - return (const char *)thd->strmake(buff, real_end - buff); + return thd->lex_ident_copy(ident); } - return NULL; //Should not happen + return Lex_ident_column(); // Should not happen } /**************************************************************************** @@ -5189,7 +5198,7 @@ bool operator!=(const MYSQL_TIME &lhs, const MYSQL_TIME &rhs) bool mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, const LEX_CSTRING *old_name, const LEX_CSTRING *new_db, - const LEX_CSTRING *new_name, LEX_CUSTRING *id, uint flags) + const LEX_CSTRING *new_name, const LEX_CUSTRING *id, uint flags) { THD *thd= current_thd; char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN]; @@ -5849,9 +5858,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info, */ for (f_ptr=table->field; *f_ptr; f_ptr++) { - if (lex_string_cmp(system_charset_info, - &sql_field->field_name, - &(*f_ptr)->field_name) == 0) + if (sql_field->field_name.streq((*f_ptr)->field_name)) goto drop_create_field; } { @@ -5863,9 +5870,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info, Create_field *chk_field; while ((chk_field= chk_it++) && chk_field != sql_field) { - if (lex_string_cmp(system_charset_info, - &sql_field->field_name, - &chk_field->field_name) == 0) + if (sql_field->field_name.streq(chk_field->field_name)) goto drop_create_field; } } @@ -5899,9 +5904,7 @@ drop_create_field: */ for (f_ptr=table->field; *f_ptr; f_ptr++) { - if (lex_string_cmp(system_charset_info, - &sql_field->change, - &(*f_ptr)->field_name) == 0) + if (sql_field->change.streq((*f_ptr)->field_name)) { break; } @@ -5938,8 +5941,7 @@ drop_create_field: */ for (f_ptr=table->field; *f_ptr; f_ptr++) { - if (my_strcasecmp(system_charset_info, - acol->name.str, (*f_ptr)->field_name.str) == 0) + if ((*f_ptr)->field_name.streq(acol->name)) break; } if (unlikely(*f_ptr == NULL)) @@ -5993,8 +5995,7 @@ drop_create_field: */ for (f_ptr=table->field; *f_ptr; f_ptr++) { - if (my_strcasecmp(system_charset_info, - drop->name, (*f_ptr)->field_name.str) == 0) + if ((*f_ptr)->field_name.streq(drop->name)) { remove_drop= FALSE; break; @@ -6007,8 +6008,7 @@ drop_create_field: i < table->s->table_check_constraints; i++) { - if (my_strcasecmp(system_charset_info, drop->name, - table->check_constraints[i]->name.str) == 0) + if (table->check_constraints[i]->name.streq(drop->name)) { remove_drop= FALSE; break; @@ -6027,9 +6027,7 @@ drop_create_field: { for (n_key=0; n_key < table->s->keys; n_key++) { - if (my_strcasecmp(system_charset_info, - drop->name, - table->key_info[n_key].name.str) == 0) + if (table->key_info[n_key].name.streq(drop->name)) { remove_drop= FALSE; break; @@ -6044,8 +6042,7 @@ drop_create_field: List_iterator fk_key_it(fk_child_key_list); while ((f_key= fk_key_it++)) { - if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - drop->name) == 0) + if (Lex_ident_column(*f_key->foreign_id).streq(drop->name)) { remove_drop= FALSE; break; @@ -6064,8 +6061,7 @@ drop_create_field: while ((chk_drop= chk_it++) && chk_drop != drop) { if (drop->type == chk_drop->type && - my_strcasecmp(system_charset_info, - drop->name, chk_drop->name) == 0) + chk_drop->name.streq(drop->name)) { remove_drop= TRUE; break; @@ -6078,7 +6074,7 @@ drop_create_field: push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_CANT_DROP_FIELD_OR_KEY, ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY), - drop->type_name(), drop->name); + drop->type_name(), drop->name.str); drop_it.remove(); } else @@ -6102,9 +6098,7 @@ drop_create_field: bool exists= false; for (uint n_key= 0; n_key < table->s->keys; n_key++) { - if (my_strcasecmp(system_charset_info, - rename_key->old_name.str, - table->key_info[n_key].name.str) == 0) + if (table->key_info[n_key].name.streq(rename_key->old_name)) { exists= true; break; @@ -6130,8 +6124,7 @@ drop_create_field: bool exists= false; for (uint n_key= 0; n_key < table->s->keys; n_key++) { - if (my_strcasecmp(system_charset_info, aii->name(), - table->key_info[n_key].name.str) == 0) + if (table->key_info[n_key].name.streq(aii->name())) { exists= true; break; @@ -6142,7 +6135,7 @@ drop_create_field: push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_KEY_DOES_NOT_EXISTS, ER_THD(thd, ER_KEY_DOES_NOT_EXISTS), - aii->name(), table->s->table_name.str); + aii->name().str, table->s->table_name.str); ignor_it.remove(); } } @@ -6152,7 +6145,7 @@ drop_create_field: Key *key; List_iterator key_it(alter_info->key_list); uint n_key; - const char *keyname= NULL; + Lex_ident_column keyname; while ((key=key_it++)) { if (!key->if_not_exists() && !key->or_replace()) @@ -6162,24 +6155,25 @@ drop_create_field: bool dup_primary_key= key->type == Key::PRIMARY && table->s->primary_key != MAX_KEY && - (keyname= table->s->key_info[table->s->primary_key].name.str) && - my_strcasecmp(system_charset_info, keyname, primary_key_name.str) == 0; + (keyname= table->s->key_info[table->s->primary_key].name).str && + table->s->key_info[table->s->primary_key].name. + streq(primary_key_name); if (dup_primary_key) goto remove_key; /* If the name of the key is not specified, */ /* let us check the name of the first key part. */ - if ((keyname= key->name.str) == NULL) + if ((keyname= key->name).str == NULL) { if (key->type == Key::PRIMARY) - keyname= primary_key_name.str; + keyname= primary_key_name; else { List_iterator part_it(key->columns); Key_part_spec *kp; if ((kp= part_it++)) - keyname= kp->field_name.str; - if (keyname == NULL) + keyname= kp->field_name; + if (keyname.str == NULL) continue; } } @@ -6187,8 +6181,7 @@ drop_create_field: { for (n_key=0; n_key < table->s->keys; n_key++) { - if (my_strcasecmp(system_charset_info, - keyname, table->key_info[n_key].name.str) == 0) + if (table->key_info[n_key].name.streq(keyname)) { goto remove_key; } @@ -6202,8 +6195,7 @@ drop_create_field: List_iterator fk_key_it(fk_child_key_list); while ((f_key= fk_key_it++)) { - if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - keyname) == 0) + if (Lex_ident_column(*f_key->foreign_id).streq(keyname)) goto remove_key; } } @@ -6211,20 +6203,20 @@ drop_create_field: { Key *chk_key; List_iterator chk_it(alter_info->key_list); - const char *chkname; + Lex_ident_column chkname; while ((chk_key=chk_it++) && chk_key != key) { - if ((chkname= chk_key->name.str) == NULL) + if ((chkname= chk_key->name).str == NULL) { List_iterator part_it(chk_key->columns); Key_part_spec *kp; if ((kp= part_it++)) - chkname= kp->field_name.str; - if (chkname == NULL) + chkname= kp->field_name; + if (chkname.str == NULL) continue; } if (key->type == chk_key->type && - my_strcasecmp(system_charset_info, keyname, chkname) == 0) + chkname.streq(keyname)) goto remove_key; } } @@ -6235,7 +6227,8 @@ remove_key: { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_DUP_KEYNAME, ER_THD(thd, dup_primary_key - ? ER_MULTIPLE_PRI_KEY : ER_DUP_KEYNAME), keyname); + ? ER_MULTIPLE_PRI_KEY : ER_DUP_KEYNAME), + keyname.str); key_it.remove(); if (key->type == Key::FOREIGN_KEY) { @@ -6250,7 +6243,7 @@ remove_key: DBUG_ASSERT(key->or_replace()); Alter_drop::drop_type type= (key->type == Key::FOREIGN_KEY) ? Alter_drop::FOREIGN_KEY : Alter_drop::KEY; - Alter_drop *ad= new (thd->mem_root) Alter_drop(type, key->name.str, FALSE); + Alter_drop *ad= new (thd->mem_root) Alter_drop(type, key->name, FALSE); if (ad != NULL) { // Adding the index into the drop list for replacing @@ -6282,7 +6275,7 @@ remove_key: push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SAME_NAME_PARTITION, ER_THD(thd, ER_SAME_NAME_PARTITION), - pe->partition_name); + pe->partition_name.str); alter_info->partition_flags&= ~ALTER_PARTITION_ADD; thd->work_part_info= NULL; break; @@ -6303,8 +6296,7 @@ remove_key: partition_element *part_elem; while ((part_elem= part_it++)) { - if (my_strcasecmp(system_charset_info, - part_elem->partition_name, name) == 0) + if (part_elem->partition_name.streq(Lex_cstring_strlen(name))) break; } if (!part_elem) @@ -6336,9 +6328,7 @@ remove_key: c < share->table_check_constraints ; c++) { Virtual_column_info *dup= table->check_constraints[c]; - if (dup->name.length == check->name.length && - lex_string_cmp(system_charset_info, - &check->name, &dup->name) == 0) + if (check->name.streq(dup->name)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_DUP_CONSTRAINT_NAME, ER_THD(thd, ER_DUP_CONSTRAINT_NAME), @@ -6537,11 +6527,12 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key, as renamed). */ -static KEY *find_key_ci(const char *key_name, KEY *key_start, KEY *key_end) +static KEY *find_key_ci(const Lex_ident_column &key_name, + KEY *key_start, KEY *key_end) { for (KEY *key = key_start; key < key_end; key++) { - if (!my_strcasecmp(system_charset_info, key_name, key->name.str)) + if (key_name.streq(key->name)) return key; } return NULL; @@ -6897,9 +6888,8 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, Primary key index for the new table */ const KEY* const new_pk= (ha_alter_info->key_count > 0 && - (!my_strcasecmp(system_charset_info, - ha_alter_info->key_info_buffer->name.str, - primary_key_name.str) || + (ha_alter_info->key_info_buffer->name. + streq(primary_key_name) || is_candidate_key(ha_alter_info->key_info_buffer))) ? ha_alter_info->key_info_buffer : NULL; const KEY *const old_pk= table->s->primary_key == MAX_KEY ? NULL : @@ -6920,8 +6910,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, new_key < new_key_end; new_key++) { - if (!lex_string_cmp(system_charset_info, &table_key->name, - &new_key->name)) + if (table_key->name.streq(new_key->name)) break; } if (new_key >= new_key_end) @@ -6971,8 +6960,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, /* Search an old key with the same name. */ for (table_key= table->key_info; table_key < table_key_end; table_key++) { - if (!lex_string_cmp(system_charset_info, &table_key->name, - &new_key->name)) + if (table_key->name.streq(new_key->name)) break; } if (table_key >= table_key_end) @@ -7004,8 +6992,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, continue; } - DBUG_ASSERT( - lex_string_cmp(system_charset_info, &old_key->name, &new_key->name)); + DBUG_ASSERT(!old_key->name.streq(new_key->name)); ha_alter_info->handler_flags|= ALTER_RENAME_INDEX; ha_alter_info->rename_keys.push_back( @@ -7027,7 +7014,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, Alter_index_ignorability *alter_index_ignorability; while((alter_index_ignorability= ignorability_index_it++)) { - const char *name= alter_index_ignorability->name(); + const Lex_ident_column &name= alter_index_ignorability->name(); KEY *old_key, *new_key; old_key= find_key_ci(name, table->key_info, table_key_end); @@ -7037,7 +7024,8 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, if (new_key == NULL) { - my_error(ER_KEY_DOES_NOT_EXISTS, MYF(0), name, table->s->table_name.str); + my_error(ER_KEY_DOES_NOT_EXISTS, MYF(0), + name.str, table->s->table_name.str); DBUG_RETURN(true); } new_key->is_ignored= alter_index_ignorability->is_ignored(); @@ -7229,9 +7217,7 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, create_info->table_options|= HA_OPTION_PACK_RECORD; /* Check if field was renamed */ - if (lex_string_cmp(system_charset_info, - &field->field_name, - &tmp_new_field->field_name)) + if (!field->field_name.streq(tmp_new_field->field_name)) DBUG_RETURN(false); /* Evaluate changes bitmap and send to check_if_incompatible_data() */ @@ -7258,8 +7244,7 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, /* Search a key with the same name. */ for (new_key= key_info_buffer; new_key < new_key_end; new_key++) { - if (!lex_string_cmp(system_charset_info, &table_key->name, - &new_key->name)) + if (table_key->name.streq(new_key->name)) break; } if (new_key >= new_key_end) @@ -7299,8 +7284,7 @@ bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, /* Search a key with the same name. */ for (table_key= table->key_info; table_key < table_key_end; table_key++) { - if (!lex_string_cmp(system_charset_info, &table_key->name, - &new_key->name)) + if (table_key->name.streq(new_key->name)) break; } if (table_key >= table_key_end) @@ -8034,7 +8018,7 @@ void rename_field_in_list(Create_field *field, List *field_list) List_iterator it(*field_list); while (const char *name= it++) { - if (my_strcasecmp(system_charset_info, name, field->change.str)) + if (!field->change.streq(Lex_cstring_strlen(name))) continue; it.replace(field->field_name.str); } @@ -8129,8 +8113,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Field **f_ptr,*field; MY_BITMAP *dropped_fields= NULL; // if it's NULL - no dropped fields bool drop_period= false; - LEX_CSTRING period_start_name= {nullptr, 0}; - LEX_CSTRING period_end_name= {nullptr, 0}; + Lex_ident_column period_start_name; + Lex_ident_column period_end_name; DBUG_ENTER("mysql_prepare_alter_table"); if (table->s->period.name) @@ -8220,7 +8204,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(system_charset_info,field->field_name.str, drop->name)) + field->field_name.streq(drop->name)) break; } /* @@ -8276,9 +8260,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, def_it.rewind(); while ((def=def_it++)) { - if (def->change.str && - !lex_string_cmp(system_charset_info, &field->field_name, - &def->change)) + if (def->change.str && field->field_name.streq(def->change)) break; } if (def && field->invisible < INVISIBLE_SYSTEM) @@ -8349,33 +8331,32 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_column *alter; while ((alter=alter_it++)) { - if (!my_strcasecmp(system_charset_info,field->field_name.str, - alter->name.str)) + if (field->field_name.streq(alter->name)) break; } if (alter && field->invisible < INVISIBLE_SYSTEM) { if (alter->is_rename()) { - def->change= alter->name; - def->field_name= alter->new_name; + def->change= Lex_ident_column(alter->name); + def->field_name= Lex_ident_column(alter->new_name); column_rename_param.fields.push_back(def); if (field->flags & VERS_ROW_START) { - create_info->vers_info.as_row.start= alter->new_name; - create_info->vers_info.period.start= alter->new_name; + create_info->vers_info.as_row.start= Lex_ident_column(alter->new_name); + create_info->vers_info.period.start= Lex_ident_column(alter->new_name); } else if (field->flags & VERS_ROW_END) { - create_info->vers_info.as_row.end= alter->new_name; - create_info->vers_info.period.end= alter->new_name; + create_info->vers_info.as_row.end= Lex_ident_column(alter->new_name); + create_info->vers_info.period.end= Lex_ident_column(alter->new_name); } if (table->s->period.name) { if (field == table->period_start_field()) - period_start_name= alter->new_name; + period_start_name= Lex_ident_column(alter->new_name); else if (field == table->period_end_field()) - period_end_name= alter->new_name; + period_end_name= Lex_ident_column(alter->new_name); } } else @@ -8491,8 +8472,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, find_it.rewind(); while((find=find_it++)) { - if (!my_strcasecmp(system_charset_info,find->field_name.str, - def->field_name.str)) + if (find->field_name.streq(def->field_name)) break; } @@ -8553,8 +8533,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, find_it.rewind(); while ((find=find_it++)) { - if (!lex_string_cmp(system_charset_info, &def->after, - &find->field_name)) + if (def->after.streq(find->field_name)) break; } if (unlikely(!find)) @@ -8573,8 +8552,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_column *alter; while ((alter=alter_it++)) { - if (!my_strcasecmp(system_charset_info,def->field_name.str, - alter->name.str)) + if (def->field_name.streq(alter->name)) break; } if (alter) @@ -8612,11 +8590,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, bool long_hash_key= false; if (key_info->flags & HA_INVISIBLE_KEY) continue; - const char *key_name= key_info->name.str; + Lex_ident_column key_name(key_info->name); const bool primary_key= table->s->primary_key == i; const bool explicit_pk= primary_key && - !my_strcasecmp(system_charset_info, key_name, - primary_key_name.str); + key_name.streq(primary_key_name); const bool implicit_pk= primary_key && !explicit_pk; Alter_drop *drop; @@ -8624,7 +8601,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((drop=drop_it++)) { if (drop->type == Alter_drop::KEY && - !my_strcasecmp(system_charset_info,key_name, drop->name)) + key_name.streq(drop->name)) break; } if (drop) @@ -8659,8 +8636,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_index_ignorability *index_ignorability; while((index_ignorability= ignorability_index_it++)) { - const char* name= index_ignorability->name(); - if (!my_strcasecmp(system_charset_info, key_name, name)) + if (key_name.streq(index_ignorability->name())) ignorability_index_it.remove(); } @@ -8671,21 +8647,20 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((rename_key= rename_key_it++)) { - if (!my_strcasecmp(system_charset_info, key_name, rename_key->old_name.str)) + if (key_name.streq(rename_key->old_name)) { - if (!my_strcasecmp(system_charset_info, key_name, primary_key_name.str)) + if (key_name.streq(primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->old_name.str); goto err; } - else if (!my_strcasecmp(system_charset_info, rename_key->new_name.str, - primary_key_name.str)) + else if (rename_key->new_name.streq(primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->new_name.str); goto err; } - key_name= rename_key->new_name.str; // New name of current key_info + key_name= rename_key->new_name; // New name of current key_info if (cmp(&rename_key->old_name, &rename_key->new_name)) { /* Key was renamed */ @@ -8724,7 +8699,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Field *kfield= key_part->field; if (!kfield) continue; // Wrong field (from UNIREG) - const char *key_part_name=kfield->field_name.str; + const Lex_ident_column key_part_name(kfield->field_name); Create_field *cfield; uint key_part_length; @@ -8733,12 +8708,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, { if (cfield->change.str) { - if (!my_strcasecmp(system_charset_info, key_part_name, - cfield->change.str)) + if (cfield->change.streq(key_part_name)) break; } - else if (!my_strcasecmp(system_charset_info, - key_part_name, cfield->field_name.str)) + else if (cfield->field_name.streq(key_part_name)) break; } if (!cfield) @@ -8747,7 +8720,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter_ctx->modified_primary_key= true; delete_index_stat= TRUE; if (!(kfield->flags & VERS_SYSTEM_FIELD)) - dropped_key_part= key_part_name; + dropped_key_part= key_part_name.str; continue; // Field is removed } @@ -8876,8 +8849,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_index_ignorability *index_ignorability; while((index_ignorability= ignorability_index_it++)) { - const char *name= index_ignorability->name(); - if (!my_strcasecmp(system_charset_info, key_name, name)) + if (key_name.streq(index_ignorability->name())) { if (table->s->primary_key <= MAX_KEY && table->key_info + table->s->primary_key == key_info) @@ -8889,8 +8861,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } - tmp_name.str= key_name; - tmp_name.length= strlen(key_name); + tmp_name= key_name; /* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */ key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info, key_info->flags & HA_GENERATED_KEY, @@ -8913,7 +8884,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_drop *drop; for(drop_it.rewind(); (drop=drop_it++); ) if (drop->type == Alter_drop::FOREIGN_KEY && - !my_strcasecmp(system_charset_info, fk.foreign_id->str, drop->name)) + drop->name.streq(*fk.foreign_id)) break; if (drop) continue; @@ -8939,8 +8910,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, goto err; new_key_list.push_back(key, thd->mem_root); if (key->name.str && - !my_strcasecmp(system_charset_info, key->name.str, - primary_key_name.str)) + key->name.streq(primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); goto err; @@ -8990,7 +8960,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((drop=drop_it++)) { if (drop->type == Alter_drop::CHECK_CONSTRAINT && - !my_strcasecmp(system_charset_info, check->name.str, drop->name)) + check->name.streq(drop->name)) { drop_it.remove(); keep= false; @@ -8998,7 +8968,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } - if (share->period.constr_name.streq(check->name.str)) + if (share->period.constr_name.streq(check->name)) { if (!drop_period && !keep) { @@ -9066,9 +9036,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (!check->name.length || check->automatic_name) continue; - if (check->name.length == f_key->foreign_id->length && - my_strcasecmp(system_charset_info, f_key->foreign_id->str, - check->name.str) == 0) + if (check->name.streq(*f_key->foreign_id)) { my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); goto err; @@ -9091,7 +9059,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, case Alter_drop::CHECK_CONSTRAINT: case Alter_drop::PERIOD: my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop->type_name(), - alter_info->drop_list.head()->name); + alter_info->drop_list.head()->name.str); goto err; case Alter_drop::FOREIGN_KEY: // Leave the DROP FOREIGN KEY names in the alter_info->drop_list. @@ -9105,14 +9073,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, { fk_not_found: my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop->type_name(), - drop->name); + drop->name.str); goto err; } List_iterator fk_key_it(fk_child_key_list); while (FOREIGN_KEY_INFO *f_key= fk_key_it++) { - if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - drop->name) == 0) + if (Lex_ident_column(*f_key->foreign_id).streq(drop->name)) goto fk_found; } goto fk_not_found; @@ -9134,7 +9101,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (alter_index_ignorability_list.elements) { my_error(ER_KEY_DOES_NOT_EXISTS, MYF(0), - alter_index_ignorability_list.head()->name(), + alter_index_ignorability_list.head()->name().str, table->s->table_name.str); goto err; } @@ -9188,7 +9155,7 @@ err: */ static Create_field *get_field_by_old_name(Alter_info *alter_info, - const char *old_name) + const LEX_CSTRING &old_name) { List_iterator_fast new_field_it(alter_info->create_list); Create_field *new_field; @@ -9196,9 +9163,7 @@ static Create_field *get_field_by_old_name(Alter_info *alter_info, while ((new_field= new_field_it++)) { if (new_field->field && - (my_strcasecmp(system_charset_info, - new_field->field->field_name.str, - old_name) == 0)) + new_field->field->field_name.streq(old_name)) break; } return new_field; @@ -9246,14 +9211,13 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info, while ((column= column_it++)) { - Create_field *new_field= get_field_by_old_name(alter_info, column->str); + Create_field *new_field= get_field_by_old_name(alter_info, *column); if (new_field) { Field *old_field= new_field->field; - if (lex_string_cmp(system_charset_info, &old_field->field_name, - &new_field->field_name)) + if (!old_field->field_name.streq(new_field->field_name)) { /* Copy algorithm doesn't support proper renaming of columns in @@ -9370,12 +9334,9 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table, l_c_t_n > 0 modes case-insensitive comparison is used. */ if ((drop->type == Alter_drop::FOREIGN_KEY) && - (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - drop->name) == 0) && - (lex_string_cmp(table_alias_charset, f_key->foreign_db, - &table->s->db) == 0) && - (lex_string_cmp(table_alias_charset, f_key->foreign_table, - &table->s->table_name) == 0)) + drop->name.streq(*f_key->foreign_id) && + table->s->db.streq(*f_key->foreign_db) && + table->s->table_name.streq(*f_key->foreign_table)) fk_parent_key_it.remove(); } } @@ -9458,8 +9419,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table, { /* Names of foreign keys in InnoDB are case-insensitive. */ if ((drop->type == Alter_drop::FOREIGN_KEY) && - (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - drop->name) == 0)) + (Lex_ident_column(*f_key->foreign_id).streq(drop->name))) fk_key_it.remove(); } } @@ -10465,8 +10425,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, If such table exists, there must be a corresponding TABLE_SHARE in THD::all_temp_tables list. */ - if (thd->find_tmp_table_share(alter_ctx.new_db.str, - alter_ctx.new_name.str)) + if (thd->find_tmp_table_share(alter_ctx.new_db, alter_ctx.new_name)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str); DBUG_RETURN(true); @@ -10651,8 +10610,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, while ((f_key= fk_key_it++)) { - if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - drop->name) == 0) + if (Lex_ident_column(*f_key->foreign_id).streq(drop->name)) { drop->type= Alter_drop::FOREIGN_KEY; alter_info->flags|= ALTER_DROP_FOREIGN_KEY; @@ -10668,8 +10626,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, for (n_key=0; n_key < table->s->keys; n_key++) { if ((table->key_info[n_key].flags & HA_NOSAME) && - my_strcasecmp(system_charset_info, - drop->name, table->key_info[n_key].name.str) == 0) + table->key_info[n_key].name.streq(drop->name)) { drop->type= Alter_drop::KEY; alter_info->flags|= ALTER_DROP_INDEX; @@ -10692,11 +10649,11 @@ do_continue:; /* Check if rename of triggers are supported */ if (alter_ctx.is_table_renamed() && Table_triggers_list::prepare_for_rename(thd, &trigger_param, - &alter_ctx.db, - &alter_ctx.alias, - &alter_ctx.table_name, - &alter_ctx.new_db, - &alter_ctx.new_alias)) + alter_ctx.db, + Lex_ident_table(alter_ctx.alias), + alter_ctx.table_name, + alter_ctx.new_db, + Lex_ident_table(alter_ctx.new_alias))) DBUG_RETURN(true); /* @@ -11254,8 +11211,8 @@ do_continue:; /* Open the table since we need to copy the data. */ new_table= thd->create_and_open_tmp_table(&frm, alter_ctx.get_tmp_path(), - alter_ctx.new_db.str, - alter_ctx.new_name.str, true); + alter_ctx.new_db, + alter_ctx.new_name, true); if (!new_table) goto err_new_table_cleanup; diff --git a/sql/sql_table.h b/sql/sql_table.h index fded83531f5..36ad7e6ef89 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -20,6 +20,7 @@ #include // pthread_mutex_t #include "m_string.h" // LEX_CUSTRING #include "lex_charset.h" +#include "lex_ident.h" #define ERROR_INJECT(code) \ ((DBUG_IF("crash_" code) && (DBUG_SUICIDE(), 0)) || \ @@ -167,7 +168,7 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, class Recreate_info *recreate_info, bool table_copy); bool mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, const LEX_CSTRING *old_name, const LEX_CSTRING *new_db, - const LEX_CSTRING *new_name, LEX_CUSTRING *id, + const LEX_CSTRING *new_name, const LEX_CUSTRING *id, uint flags); bool mysql_backup_table(THD* thd, TABLE_LIST* table_list); bool mysql_restore_table(THD* thd, TABLE_LIST* table_list); @@ -212,7 +213,7 @@ uint explain_filename(THD* thd, const char *from, char *to, uint to_length, enum_explain_filename_mode explain_mode); -extern MYSQL_PLUGIN_IMPORT const LEX_CSTRING primary_key_name; +extern MYSQL_PLUGIN_IMPORT const Lex_ident_column primary_key_name; bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c9864e57fff..2cc0801c485 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -470,7 +470,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) /* We don't allow creating triggers on tables in the 'mysql' schema */ - if (create && lex_string_eq(&tables->db, STRING_WITH_LEN("mysql"))) + if (create && tables->db.streq(MYSQL_SCHEMA_NAME)) { my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0)); DBUG_RETURN(TRUE); @@ -948,7 +948,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, DBUG_RETURN(true); /* Trigger must be in the same schema as target table. */ - if (lex_string_cmp(table_alias_charset, &table->s->db, &lex->spname->m_db)) + if (!table->s->db.streq(lex->spname->m_db)) { my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); DBUG_RETURN(true); @@ -1126,13 +1126,13 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigger->client_cs_name= thd->charset()->cs_name; trigger->connection_cl_name= thd->variables.collation_connection->coll_name; trigger->db_cl_name= get_default_db_collation(thd, tables->db.str)->coll_name; - trigger->name= lex->spname->m_name; + trigger->name= Lex_ident_trigger(lex->spname->m_name); /* Add trigger in it's correct place */ add_trigger(lex->trg_chistics.event, lex->trg_chistics.action_time, lex->trg_chistics.ordering_clause, - &lex->trg_chistics.anchor_trigger_name, + Lex_ident_trigger(lex->trg_chistics.anchor_trigger_name), trigger); /* Create trigger definition file .TRG */ @@ -1318,8 +1318,7 @@ Trigger *Table_triggers_list::find_trigger(const LEX_CSTRING *name, (trigger= *parent); parent= &trigger->next) { - if (lex_string_cmp(table_alias_charset, - &trigger->name, name) == 0) + if (trigger->name.streq(*name)) { if (remove_from_list) { @@ -1723,7 +1722,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, */ if (trigger->hr_create_time.val < 429496729400ULL) trigger->hr_create_time.val*= 10000; - trigger->name= sp ? sp->m_name : empty_clex_str; + trigger->name= sp ? Lex_ident_trigger(sp->m_name) : + Lex_ident_trigger(empty_clex_str); trigger->on_table_name.str= (char*) lex.raw_trg_on_table_name_begin; trigger->on_table_name.length= (lex.raw_trg_on_table_name_end - lex.raw_trg_on_table_name_begin); @@ -1738,7 +1738,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, trigger_list->add_trigger(lex.trg_chistics.event, lex.trg_chistics.action_time, TRG_ORDER_NONE, - &lex.trg_chistics.anchor_trigger_name, + Lex_ident_trigger(lex.trg_chistics.anchor_trigger_name), trigger); if (unlikely(parse_error)) @@ -1757,7 +1757,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, if (likely((name= error_handler.get_trigger_name()))) { - trigger->name= safe_lexcstrdup_root(&table->mem_root, *name); + trigger->name= Lex_ident_trigger(safe_lexcstrdup_root( + &table->mem_root, *name)); if (unlikely(!trigger->name.str)) goto err_with_lex_cleanup; } @@ -1820,12 +1821,13 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, */ char fname[SAFE_NAME_LEN + 1]; - DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db.str, db->str) || + DBUG_ASSERT((lex.query_tables->db.streq(*db) || (check_n_cut_mysql50_prefix(db->str, fname, sizeof(fname)) && - !my_strcasecmp(table_alias_charset, lex.query_tables->db.str, fname)))); - DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, table_name->str) || + lex.query_tables->db.streq(Lex_cstring_strlen(fname))))); + DBUG_ASSERT((lex.query_tables->table_name.streq(*table_name) || (check_n_cut_mysql50_prefix(table_name->str, fname, sizeof(fname)) && - !my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, fname)))); + lex.query_tables->table_name. + streq(Lex_cstring_strlen(fname))))); #endif if (names_only) { @@ -1901,7 +1903,8 @@ error: void Table_triggers_list::add_trigger(trg_event_type event, trg_action_time_type action_time, trigger_order_type ordering_clause, - LEX_CSTRING *anchor_trigger_name, + const Lex_ident_trigger & + anchor_trigger_name, Trigger *trigger) { Trigger **parent= &triggers[event][action_time]; @@ -1910,8 +1913,7 @@ void Table_triggers_list::add_trigger(trg_event_type event, for ( ; *parent ; parent= &(*parent)->next, position++) { if (ordering_clause != TRG_ORDER_NONE && - !lex_string_cmp(table_alias_charset, anchor_trigger_name, - &(*parent)->name)) + anchor_trigger_name.streq((*parent)->name)) { if (ordering_clause == TRG_ORDER_FOLLOWS) { @@ -2318,11 +2320,11 @@ bool Trigger::change_on_table_name(void* param_arg) bool Table_triggers_list::prepare_for_rename(THD *thd, TRIGGER_RENAME_PARAM *param, - const LEX_CSTRING *db, - const LEX_CSTRING *old_alias, - const LEX_CSTRING *old_table, - const LEX_CSTRING *new_db, - const LEX_CSTRING *new_table) + const Lex_ident_db &db, + const Lex_ident_table &old_alias, + const Lex_ident_table &old_table, + const Lex_ident_db &new_db, + const Lex_ident_table &new_table) { TABLE *table= ¶m->table; bool result= 0; @@ -2331,11 +2333,10 @@ Table_triggers_list::prepare_for_rename(THD *thd, init_sql_alloc(key_memory_Table_trigger_dispatcher, &table->mem_root, 8192, 0, MYF(0)); - DBUG_ASSERT(my_strcasecmp(table_alias_charset, db->str, new_db->str) || - my_strcasecmp(table_alias_charset, old_alias->str, - new_table->str)); + DBUG_ASSERT(!db.streq(new_db) || + !old_alias.streq(new_table)); - if (Table_triggers_list::check_n_load(thd, db, old_table, table, TRUE)) + if (Table_triggers_list::check_n_load(thd, &db, &old_table, table, TRUE)) { result= 1; goto end; @@ -2357,11 +2358,11 @@ Table_triggers_list::prepare_for_rename(THD *thd, we will be given table name with "#mysql50#" prefix To remove this prefix we use check_n_cut_mysql50_prefix(). */ - if (my_strcasecmp(table_alias_charset, db->str, new_db->str)) + if (!db.streq(new_db)) { char dbname[SAFE_NAME_LEN + 1]; - if (check_n_cut_mysql50_prefix(db->str, dbname, sizeof(dbname)) && - !my_strcasecmp(table_alias_charset, dbname, new_db->str)) + if (check_n_cut_mysql50_prefix(db.str, dbname, sizeof(dbname)) && + new_db.streq(Lex_cstring_strlen(dbname))) { param->upgrading50to51= TRUE; } diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 493349afb9d..5648f8f15ff 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -74,8 +74,10 @@ struct st_trg_execution_order /** Trigger name referenced in the FOLLOWS/PRECEDES clause of the CREATE TRIGGER statement. + Cannot be Lex_ident_trigger, + as this structure is used in %union in sql_yacc.yy */ - LEX_CSTRING anchor_trigger_name; + LEX_CSTRING anchor_trigger_name; // Used in sql_yacc %union }; @@ -122,7 +124,7 @@ public: sp_head *body; Trigger *next; /* Next trigger of same type */ - LEX_CSTRING name; + Lex_ident_trigger name; LEX_CSTRING on_table_name; /* Raw table name */ LEX_CSTRING definition; LEX_CSTRING definer; @@ -256,11 +258,11 @@ public: static bool drop_all_triggers(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name, myf MyFlags); static bool prepare_for_rename(THD *thd, TRIGGER_RENAME_PARAM *param, - const LEX_CSTRING *db, - const LEX_CSTRING *old_alias, - const LEX_CSTRING *old_table, - const LEX_CSTRING *new_db, - const LEX_CSTRING *new_table); + const Lex_ident_db &db, + const Lex_ident_table &old_alias, + const Lex_ident_table &old_table, + const Lex_ident_db &new_db, + const Lex_ident_table &new_table); static bool change_table_name(THD *thd, TRIGGER_RENAME_PARAM *param, const LEX_CSTRING *db, const LEX_CSTRING *old_alias, @@ -270,7 +272,7 @@ public: void add_trigger(trg_event_type event_type, trg_action_time_type action_time, trigger_order_type ordering_clause, - LEX_CSTRING *anchor_trigger_name, + const Lex_ident_trigger &anchor_trigger_name, Trigger *trigger); Trigger *get_trigger(trg_event_type event_type, trg_action_time_type action_time) diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index beeee9da72f..e6b46548567 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -147,14 +147,10 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table) /* Loop over the set of foreign keys for which this table is a parent. */ while ((fk_info= it++)) { - if (lex_string_cmp(system_charset_info, fk_info->referenced_db, - &table->s->db) || - lex_string_cmp(system_charset_info, fk_info->referenced_table, - &table->s->table_name) || - lex_string_cmp(system_charset_info, fk_info->foreign_db, - &table->s->db) || - lex_string_cmp(system_charset_info, fk_info->foreign_table, - &table->s->table_name)) + if (!table->s->db.streq(*fk_info->referenced_db) || + !table->s->table_name.streq(*fk_info->referenced_table) || + !table->s->db.streq(*fk_info->foreign_db) || + !table->s->table_name.streq(*fk_info->foreign_table)) break; } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index f4eb8d4f29f..76fb908cdac 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2702,7 +2702,7 @@ Field *Type_handler_enum::make_schema_field(MEM_ROOT *root, TABLE *table, addr.null_ptr(), addr.null_bit(), Field::NONE, &name, get_enum_pack_length(typelib->count), - typelib, system_charset_info); + typelib, system_charset_info_for_i_s); } @@ -4031,7 +4031,7 @@ Field *Type_handler_varchar::make_schema_field(MEM_ROOT *root, TABLE *table, { Field *field= new (root) Field_blob(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field::NONE, - &name, table->s, 4, system_charset_info); + &name, table->s, 4, system_charset_info_for_i_s); if (field) field->field_length= octet_length; return field; @@ -4043,7 +4043,7 @@ Field *Type_handler_varchar::make_schema_field(MEM_ROOT *root, TABLE *table, HA_VARCHAR_PACKLENGTH(octet_length), addr.null_ptr(), addr.null_bit(), Field::NONE, &name, - table->s, system_charset_info); + table->s, system_charset_info_for_i_s); } } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index db7f6483309..e936876c32d 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -169,8 +169,9 @@ void udf_init() init_sql_alloc(key_memory_udf_mem, &mem, UDF_ALLOC_BLOCK_SIZE, 0, MYF(0)); THD *new_thd = new THD(0); if (!new_thd || - my_hash_init(key_memory_udf_mem, - &udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0)) + my_hash_init(key_memory_udf_mem, &udf_hash, + Lex_ident_routine::charset_info(), + 32,0,0,get_hash_key, NULL, 0)) { sql_print_error("Can't allocate memory for udf structures"); my_hash_free(&udf_hash); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index cb39ef001fc..8393ba49c7d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -89,7 +89,7 @@ static void make_unique_view_field_name(THD *thd, Item *target, { check= itc++; if (check != target && - my_strcasecmp(system_charset_info, buff, check->name.str) == 0) + check->name.streq(Lex_cstring(buff, name_len))) { ok= FALSE; break; @@ -145,7 +145,7 @@ bool check_duplicate_names(THD *thd, List &item_list, bool gen_unique_view itc.rewind(); while ((check= itc++) && check != item) { - if (lex_string_cmp(system_charset_info, &item->name, &check->name) == 0) + if (item->name.streq(check->name)) { if (!gen_unique_view_name) goto err; @@ -628,13 +628,13 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, Item_field *fld= item->field_for_view_update(); privilege_t priv(get_column_grant(thd, &view->grant, view->db.str, view->table_name.str, - item->name.str) & + item->name) & VIEW_ANY_ACL); if (!fld) continue; TABLE_SHARE *s= fld->field->table->s; - const Lex_ident field_name= fld->field->field_name; + const Lex_ident_column field_name= fld->field->field_name; if (s->tmp_table || (s->versioned && (field_name.streq(s->vers_start_field()->field_name) || @@ -1349,12 +1349,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, precedent; precedent= precedent->referencing_view) { - if (precedent->view_name.length == table->table_name.length && - precedent->view_db.length == table->db.length && - my_strcasecmp(system_charset_info, - precedent->view_name.str, table->table_name.str) == 0 && - my_strcasecmp(system_charset_info, - precedent->view_db.str, table->db.str) == 0) + if (precedent->view_name.streq(table->table_name) && + precedent->view_db.streq(table->db)) { my_error(ER_VIEW_RECURSIVE, MYF(0), top_view->view_db.str, top_view->view_name.str); @@ -2188,10 +2184,9 @@ bool insert_view_fields(THD *thd, List *list, TABLE_LIST *view) if ((fld= entry->item->field_for_view_update())) { TABLE_SHARE *s= fld->context->table_list->table->s; - Lex_ident field_name= fld->field_name; if (s->versioned && - (field_name.streq(s->vers_start_field()->field_name) || - field_name.streq(s->vers_end_field()->field_name))) + (fld->field_name.streq(s->vers_start_field()->field_name) || + fld->field_name.streq(s->vers_end_field()->field_name))) continue; list->push_back(fld, thd->mem_root); } diff --git a/sql/sql_window.cc b/sql/sql_window.cc index e0c7cef1a9e..884673e3605 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -29,37 +29,38 @@ Window_spec::check_window_names(List_iterator_fast &it) { if (window_names_are_checked) return false; - const char *name= this->name(); - const char *ref_name= window_reference(); + const Lex_ident_window name= this->name(); + const Lex_ident_window ref_name= window_reference(); it.rewind(); Window_spec *win_spec; while((win_spec= it++) && win_spec != this) { - const char *win_spec_name= win_spec->name(); - if (!win_spec_name) + const Lex_ident_window win_spec_name= win_spec->name(); + if (!win_spec_name.str) break; - if (name && my_strcasecmp(system_charset_info, name, win_spec_name) == 0) + if (name.str && name.streq(win_spec_name)) { - my_error(ER_DUP_WINDOW_NAME, MYF(0), name); + my_error(ER_DUP_WINDOW_NAME, MYF(0), name.str); return true; } - if (ref_name && - my_strcasecmp(system_charset_info, ref_name, win_spec_name) == 0) + if (ref_name.str && win_spec_name.streq(ref_name)) { if (partition_list->elements) { my_error(ER_PARTITION_LIST_IN_REFERENCING_WINDOW_SPEC, MYF(0), - ref_name); + ref_name.str); return true; } if (win_spec->order_list->elements && order_list->elements) { - my_error(ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC, MYF(0), ref_name); + my_error(ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC, MYF(0), + ref_name.str); return true; } if (win_spec->window_frame) { - my_error(ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC, MYF(0), ref_name); + my_error(ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC, MYF(0), + ref_name.str); return true; } referenced_win_spec= win_spec; @@ -69,9 +70,9 @@ Window_spec::check_window_names(List_iterator_fast &it) order_list= win_spec->order_list; } } - if (ref_name && !referenced_win_spec) + if (ref_name.str && !referenced_win_spec) { - my_error(ER_WRONG_WINDOW_SPEC_NAME, MYF(0), ref_name); + my_error(ER_WRONG_WINDOW_SPEC_NAME, MYF(0), ref_name.str); return true; } window_names_are_checked= true; @@ -221,7 +222,7 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, uint elems= win_specs.elements; while ((win_spec= it++) && i++ < elems) { - if (win_spec->name() == NULL) + if (win_spec->name().str == NULL) { it.remove(); win_specs.push_back(win_spec); @@ -647,7 +648,7 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1, Partition lists contain the same elements. Let's use only one of the lists. */ - if (!win_spec1->name() && win_spec2->name()) + if (!win_spec1->name().str && win_spec2->name().str) { win_spec1->save_partition_list= win_spec1->partition_list; win_spec1->partition_list= win_spec2->partition_list; @@ -670,7 +671,7 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1, Order lists contain the same elements. Let's use only one of the lists. */ - if (!win_spec1->name() && win_spec2->name()) + if (!win_spec1->name().str && win_spec2->name().str) { win_spec1->save_order_list= win_spec2->order_list; win_spec1->order_list= win_spec2->order_list; @@ -688,7 +689,7 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1, return cmp; /* Window frames are equal. Let's use only one of them. */ - if (!win_spec1->name() && win_spec2->name()) + if (!win_spec1->name().str && win_spec2->name().str) win_spec1->window_frame= win_spec2->window_frame; else win_spec2->window_frame= win_spec1->window_frame; diff --git a/sql/sql_window.h b/sql/sql_window.h index 1c02740e769..79a185edb6d 100644 --- a/sql/sql_window.h +++ b/sql/sql_window.h @@ -134,13 +134,13 @@ class Window_spec : public Sql_alloc order_list(ord_list), save_order_list(NULL), window_frame(win_frame), referenced_win_spec(NULL) {} - virtual const char *name() { return NULL; } + virtual const Lex_ident_window name() { return Lex_ident_window(); } bool check_window_names(List_iterator_fast &it); - const char *window_reference() + const Lex_ident_window window_reference() { - return window_ref ? window_ref->str : NULL; + return window_ref ? Lex_ident_window(*window_ref) : Lex_ident_window(); } void join_partition_and_order_lists() @@ -173,7 +173,7 @@ class Window_def : public Window_spec : Window_spec(win_ref, part_list, ord_list, win_frame), window_name(win_name) {} - const char *name() { return window_name->str; } + const Lex_ident_window name() override { return Lex_ident_window(*window_name); } }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 16835192d3e..9b8c1a1f268 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4988,7 +4988,7 @@ part_name: partition_element *p_elem= part_info->curr_part_elem; if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; - p_elem->partition_name= $1.str; + p_elem->partition_name= Lex_ident_partition($1); } ; @@ -5292,7 +5292,8 @@ sub_name: { if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; - Lex->part_info->curr_part_elem->partition_name= $1.str; + Lex->part_info->curr_part_elem->partition_name= + Lex_ident_partition($1); } ; @@ -5712,24 +5713,31 @@ engine_defined_option: { if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - $$= new (thd->mem_root) engine_option_value($1, $3, true); + $$= new (thd->mem_root) engine_option_value( + engine_option_value::Name($1), + engine_option_value::Value($3), true); MYSQL_YYABORT_UNLESS($$); } | ident_options equal ident { if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - $$= new (thd->mem_root) engine_option_value($1, $3, false); + $$= new (thd->mem_root) engine_option_value( + engine_option_value::Name($1), + engine_option_value::Value($3), false); MYSQL_YYABORT_UNLESS($$); } | ident_options equal real_ulonglong_num { - $$= new (thd->mem_root) engine_option_value($1, $3, thd->mem_root); + $$= new (thd->mem_root) engine_option_value( + engine_option_value::Name($1), + $3, thd->mem_root); MYSQL_YYABORT_UNLESS($$); } | ident_options equal DEFAULT { - $$= new (thd->mem_root) engine_option_value($1); + $$= new (thd->mem_root) engine_option_value( + engine_option_value::Name($1)); MYSQL_YYABORT_UNLESS($$); } ; @@ -5954,14 +5962,14 @@ period_for_system_time: PERIOD_SYM FOR_SYSTEM_TIME_SYM '(' ident ',' ident ')' { Vers_parse_info &info= Lex->vers_get_info(); - info.set_period($4, $6); + info.set_period(Lex_ident_column($4), Lex_ident_column($6)); } ; period_for_application_time: FOR_SYM ident '(' ident ',' ident ')' { - if (Lex->add_period($2, $4, $6)) + if (Lex->add_period(Lex_ident_column($2), $4, $6)) MYSQL_YYABORT; } ; @@ -6697,7 +6705,7 @@ old_or_new_charset_name: if (unlikely(!($$=get_charset_by_csname($1.str, MY_CS_PRIMARY, MYF(utf8_flag))) && - !($$=get_old_charset_by_name($1.str)))) + !($$=get_old_charset_by_name($1)))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str)); } | BINARY { $$= &my_charset_bin; } @@ -7112,7 +7120,7 @@ opt_without_overlaps: | ',' ident WITHOUT OVERLAPS_SYM { Lex->last_key->without_overlaps= true; - Lex->last_key->period= $2; + Lex->last_key->period= Lex_ident_column($2); } ; @@ -7698,7 +7706,7 @@ alter_list_item: LEX *lex=Lex; lex->create_last_non_select_table= lex->last_table(); lex->alter_info.flags|= ALTER_PARSER_ADD_COLUMN; - $2->after= $3; + $2->after= Lex_ident_column($3); } | ADD key_def { @@ -7737,8 +7745,8 @@ alter_list_item: { Lex->alter_info.flags|= ALTER_CHANGE_COLUMN | ALTER_RENAME_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - $5->change= $4; - $5->after= $6; + $5->change= Lex_ident_column($4); + $5->after= Lex_ident_column($6); } | MODIFY_SYM opt_column opt_if_exists_table_element field_spec opt_place @@ -7746,13 +7754,13 @@ alter_list_item: Lex->alter_info.flags|= ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); $4->change= $4->field_name; - $4->after= $5; + $4->after= Lex_ident_column($5); } | DROP opt_column opt_if_exists_table_element field_ident opt_restrict { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::COLUMN, $4.str, $3)); + Alter_drop(Alter_drop::COLUMN, $4, $3)); if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); @@ -7763,7 +7771,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::CHECK_CONSTRAINT, - $4.str, $3)); + $4, $3)); if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); @@ -7773,7 +7781,7 @@ alter_list_item: { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::FOREIGN_KEY, $5.str, $4)); + Alter_drop(Alter_drop::FOREIGN_KEY, $5, $4)); if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); @@ -7783,7 +7791,7 @@ alter_list_item: { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::KEY, primary_key_name.str, + Alter_drop(Alter_drop::KEY, primary_key_name, FALSE)); if (unlikely(ad == NULL)) MYSQL_YYABORT; @@ -7794,7 +7802,7 @@ alter_list_item: { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::KEY, $4.str, $3)); + Alter_drop(Alter_drop::KEY, $4, $3)); if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); @@ -7814,7 +7822,7 @@ alter_list_item: } | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr { - if (check_expression($7, &$4, VCOL_DEFAULT)) + if (check_expression($7, Lex_ident_column($4), VCOL_DEFAULT)) MYSQL_YYABORT; if (unlikely(Lex->add_alter_list($4, $7, $3))) MYSQL_YYABORT; @@ -7823,7 +7831,7 @@ alter_list_item: { LEX *lex= Lex; Alter_index_ignorability *ac= new (thd->mem_root) - Alter_index_ignorability($4.str, $5, $3); + Alter_index_ignorability($4, $5, $3); if (ac == NULL) MYSQL_YYABORT; lex->alter_info.alter_index_ignorability_list.push_back(ac); @@ -7900,7 +7908,7 @@ alter_list_item: } | DROP PERIOD_SYM opt_if_exists_table_element FOR_SYM ident { - Alter_drop *ad= new Alter_drop(Alter_drop::PERIOD, $5.str, $3); + Alter_drop *ad= new Alter_drop(Alter_drop::PERIOD, $5, $3); if (unlikely(ad == NULL)) MYSQL_YYABORT; Lex->alter_info.drop_list.push_back(ad, thd->mem_root); @@ -9070,7 +9078,7 @@ for_portion_of_time_clause: Lex->period_conditions.init(SYSTEM_TIME_FROM_TO, Vers_history_point(VERS_TIMESTAMP, $7), Vers_history_point(VERS_TIMESTAMP, $9), - $5); + Lex_ident_column($5)); } ; @@ -10657,7 +10665,7 @@ function_call_generic: Create_func *builder; Item *item= NULL; - if (unlikely(check_routine_name(&$1))) + if (unlikely(Lex_ident_routine::check_name_with_error($1))) MYSQL_YYABORT; /* @@ -13136,7 +13144,7 @@ drop: { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::KEY, $5.str, $4)); + Alter_drop(Alter_drop::KEY, $5, $4)); if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->sql_command= SQLCOM_DROP_INDEX; @@ -15473,10 +15481,9 @@ comma_separated_ident_list: with_element_head: ident { - LEX_CSTRING *name= - (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - $$= new (thd->mem_root) With_element_head(name); - if (unlikely(name == NULL || $$ == NULL)) + $$= new (thd->mem_root) With_element_head( + Lex_ident_with_element($1)); + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->tables_pos.set_start_pos(Lex->query_tables_last); } @@ -15587,19 +15594,16 @@ field_ident: | ident '.' ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (unlikely(my_strcasecmp(table_alias_charset, $1.str, - table->db.str))) + if (unlikely(!table->db.streq($1))) my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (unlikely(my_strcasecmp(table_alias_charset, $3.str, - table->table_name.str))) + if (unlikely(!table->table_name.streq($3))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str)); $$=$5; } | ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (unlikely(my_strcasecmp(table_alias_charset, $1.str, - table->alias.str))) + if (unlikely(!table->alias.streq($1))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str)); $$=$3; } @@ -18164,8 +18168,7 @@ trigger_follows_precedes_clause: /* empty */ { $$.ordering_clause= TRG_ORDER_NONE; - $$.anchor_trigger_name.str= NULL; - $$.anchor_trigger_name.length= 0; + $$.anchor_trigger_name= null_clex_str; } | trigger_action_order ident_or_text @@ -18750,7 +18753,9 @@ sp_decl_body: sp_decl_variable_list | sp_decl_ident CONDITION_SYM FOR_SYM sp_cond { - if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4))) + if (unlikely(Lex->spcont->declare_condition(thd, + Lex_ident_column($1), + $4))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -19692,7 +19697,9 @@ sp_decl_non_handler: sp_decl_variable_list | ident_directly_assignable CONDITION_SYM FOR_SYM sp_cond { - if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4))) + if (unlikely(Lex->spcont->declare_condition(thd, + Lex_ident_column($1), + $4))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -19702,7 +19709,9 @@ sp_decl_non_handler: sp_condition_value *spcond= new (thd->mem_root) sp_condition_value_user_defined(); if (unlikely(!spcond) || - unlikely(Lex->spcont->declare_condition(thd, &$1, spcond))) + unlikely(Lex->spcont->declare_condition(thd, + Lex_ident_column($1), + spcond))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; diff --git a/sql/structs.h b/sql/structs.h index 029543ceb01..4f196de6254 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -29,6 +29,7 @@ #include /* USERNAME_LENGTH */ #include "sql_bitmap.h" #include "lex_charset.h" +#include "lex_ident.h" struct TABLE; class Type_handler; @@ -133,7 +134,7 @@ typedef struct st_key { key_map overlapped; /* Set of keys constraint correlated with this key */ key_map constraint_correlated; - LEX_CSTRING name; + Lex_ident_column name; enum ha_key_alg algorithm; /* Note that parser is used when the table is opened for use, and @@ -322,11 +323,26 @@ typedef struct user_conn { uint conn_per_hour, updates, questions; /* Maximum amount of resources which account is allowed to consume. */ USER_RESOURCES user_resources; + + /* + The CHARSET_INFO used for hashes to compare the entire 'user\0hash' key. + Eventually we should fix it as follows: + - the user part should be hashed and compared case sensitively, + - the host part should be hashed and compared case insensitively. + */ + static CHARSET_INFO *user_host_key_charset_info_for_hash() + { + return &my_charset_utf8mb3_general1400_as_ci; + } } USER_CONN; typedef struct st_user_stats { char user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; + static CHARSET_INFO *user_key_charset_info_for_hash() + { + return &my_charset_utf8mb3_general1400_as_ci; + } // Account name the user is mapped to when this is a user from mapped_user. // Otherwise, the same value as user. char priv_user[MY_MAX(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1]; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 47e31291e6b..57dd29104e8 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -794,10 +794,11 @@ static bool check_charset(sys_var *self, THD *thd, set_var *var) { ErrConvString err(res); /* Get utf8 '\0' terminated string */ myf utf8_flag= thd->get_utf8_flag(); - if (!(var->save_result.ptr= get_charset_by_csname(err.ptr(), + Lex_cstring csname= err.lex_cstring(); + if (!(var->save_result.ptr= get_charset_by_csname(csname.str, MY_CS_PRIMARY, MYF(utf8_flag))) && - !(var->save_result.ptr= get_old_charset_by_name(err.ptr()))) + !(var->save_result.ptr= get_old_charset_by_name(csname))) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr()); return true; @@ -838,7 +839,7 @@ static bool check_charset_not_null(sys_var *self, THD *thd, set_var *var) static Sys_var_struct Sys_character_set_system( "character_set_system", "The character set used by the server " "for storing identifiers", - READ_ONLY GLOBAL_VAR(system_charset_info), NO_CMD_LINE, + READ_ONLY GLOBAL_VAR(system_charset_info_for_i_s), NO_CMD_LINE, offsetof(CHARSET_INFO, cs_name.str), DEFAULT(0)); static Sys_var_struct Sys_character_set_server( @@ -5961,7 +5962,7 @@ static bool check_locale(sys_var *self, THD *thd, set_var *var) String str(buff, sizeof(buff), system_charset_info), *res; if (!(res=var->value->val_str(&str))) return true; - else if (!(locale= my_locale_by_name(res->c_ptr_safe()))) + else if (!(locale= my_locale_by_name(res->to_lex_cstring()))) { ErrConvString err(res); my_error(ER_UNKNOWN_LOCALE, MYF(0), err.ptr()); diff --git a/sql/table.cc b/sql/table.cc index ca4b4e40014..36621ee0b38 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -74,7 +74,7 @@ struct extra2_fields { LEX_CUSTRING version; LEX_CUSTRING options; - Lex_ident engine; + Lex_ident_engine engine; LEX_CUSTRING gis; LEX_CUSTRING field_flags; LEX_CUSTRING system_period; @@ -89,23 +89,31 @@ struct extra2_fields static Virtual_column_info * unpack_vcol_info_from_frm(THD *, TABLE *, String *, Virtual_column_info **, bool *); +/* + Lex_ident_db does not have operator""_Lex_ident_db, + because its constructor contains DBUG_SLOW_ASSERT + and therefore it's not a constexpr constructor. + So let's initialize a number of Lex_ident_db constants + using operator""_LEX_CSTRING. +*/ + /* INFORMATION_SCHEMA name */ -LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")}; +Lex_ident_i_s_db INFORMATION_SCHEMA_NAME("information_schema"_LEX_CSTRING); /* PERFORMANCE_SCHEMA name */ -LEX_CSTRING PERFORMANCE_SCHEMA_DB_NAME= {STRING_WITH_LEN("performance_schema")}; +Lex_ident_i_s_db PERFORMANCE_SCHEMA_DB_NAME("performance_schema"_LEX_CSTRING); /* MYSQL_SCHEMA name */ -LEX_CSTRING MYSQL_SCHEMA_NAME= {STRING_WITH_LEN("mysql")}; +Lex_ident_db MYSQL_SCHEMA_NAME("mysql"_LEX_CSTRING); /* GENERAL_LOG name */ -LEX_CSTRING GENERAL_LOG_NAME= {STRING_WITH_LEN("general_log")}; +Lex_ident_table GENERAL_LOG_NAME= "general_log"_Lex_ident_table; /* SLOW_LOG name */ -LEX_CSTRING SLOW_LOG_NAME= {STRING_WITH_LEN("slow_log")}; +Lex_ident_table SLOW_LOG_NAME= "slow_log"_Lex_ident_table; -LEX_CSTRING TRANSACTION_REG_NAME= {STRING_WITH_LEN("transaction_registry")}; -LEX_CSTRING MYSQL_PROC_NAME= {STRING_WITH_LEN("proc")}; +Lex_ident_table TRANSACTION_REG_NAME= "transaction_registry"_Lex_ident_table; +Lex_ident_table MYSQL_PROC_NAME= "proc"_Lex_ident_table; /* Keyword added as a prefix when parsing the defining expression for a @@ -281,42 +289,38 @@ const char *fn_frm_ext(const char *name) } -TABLE_CATEGORY get_table_category(const LEX_CSTRING *db, - const LEX_CSTRING *name) +TABLE_CATEGORY get_table_category(const Lex_ident_db &db, + const Lex_ident_table &name) { - DBUG_ASSERT(db != NULL); - DBUG_ASSERT(name != NULL); - #ifdef WITH_WSREP - if (db->str && - my_strcasecmp(system_charset_info, db->str, WSREP_SCHEMA) == 0) + if (db.str && db.streq(MYSQL_SCHEMA_NAME)) { - if ((my_strcasecmp(system_charset_info, name->str, WSREP_STREAMING_TABLE) == 0 || - my_strcasecmp(system_charset_info, name->str, WSREP_CLUSTER_TABLE) == 0 || - my_strcasecmp(system_charset_info, name->str, WSREP_MEMBERS_TABLE) == 0)) + if (name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_STREAMING_TABLE)}) || + name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_CLUSTER_TABLE)}) || + name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_MEMBERS_TABLE)})) { return TABLE_CATEGORY_INFORMATION; } } #endif /* WITH_WSREP */ - if (is_infoschema_db(db)) + if (is_infoschema_db(&db)) return TABLE_CATEGORY_INFORMATION; - if (is_perfschema_db(db)) + if (is_perfschema_db(&db)) return TABLE_CATEGORY_PERFORMANCE; - if (lex_string_eq(&MYSQL_SCHEMA_NAME, db)) + if (db.streq(MYSQL_SCHEMA_NAME)) { - if (is_system_table_name(name->str, name->length)) + if (is_system_table_name(name.str, name.length)) return TABLE_CATEGORY_SYSTEM; - if (lex_string_eq(&GENERAL_LOG_NAME, name)) + if (name.streq(GENERAL_LOG_NAME)) return TABLE_CATEGORY_LOG; - if (lex_string_eq(&SLOW_LOG_NAME, name)) + if (name.streq(SLOW_LOG_NAME)) return TABLE_CATEGORY_LOG; - if (lex_string_eq(&TRANSACTION_REG_NAME, name)) + if (name.streq(TRANSACTION_REG_NAME)) return TABLE_CATEGORY_LOG; } @@ -369,7 +373,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, strmov(path_buff, path); share->normalized_path.str= share->path.str; share->normalized_path.length= path_length; - share->table_category= get_table_category(&share->db, &share->table_name); + share->table_category= get_table_category(share->db, share->table_name); share->open_errno= ENOENT; /* The following will be updated in open_table_from_share */ share->can_do_row_logging= 1; @@ -1870,7 +1874,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, options= extra2.options; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (extra2.engine) + if (extra2.engine.str) { share->default_part_plugin= ha_resolve_by_name(NULL, &extra2.engine, false); if (!share->default_part_plugin) @@ -2353,7 +2357,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH; if (use_hash) use_hash= !my_hash_init(PSI_INSTRUMENT_ME, &share->name_hash, - system_charset_info, share->fields, 0, 0, + Lex_ident_column::charset_info(), + share->fields, 0, 0, (my_hash_get_key) get_field_name, 0, 0); if (share->mysql_version >= 50700 && share->mysql_version < 100000 && @@ -2373,7 +2378,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } /* Set system versioning information. */ - vers.name= Lex_ident(STRING_WITH_LEN("SYSTEM_TIME")); + vers.name= "SYSTEM_TIME"_Lex_ident_column; if (extra2.system_period.str == NULL) { versioned= VERS_UNDEFINED; @@ -2859,9 +2864,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } longlong ha_option= handler_file->ha_table_flags(); keyinfo= share->key_info; - uint primary_key= my_strcasecmp(system_charset_info, - share->keynames.type_names[0], - primary_key_name.str) ? MAX_KEY : 0; + uint primary_key= Lex_ident_column(share->keynames.type_names[0], + share->keynames.type_lengths[0]). + streq(primary_key_name) ? 0 : MAX_KEY; KEY* key_first_info= NULL; if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME && @@ -5258,16 +5263,18 @@ bool Lex_ident_fs::is_in_lower_case() const returns 1 on error */ -bool check_table_name(const char *name, size_t length, bool disallow_path_chars) +bool Lex_ident_table::check_name(const LEX_CSTRING &str, + bool disallow_path_chars) { if (!disallow_path_chars && - (disallow_path_chars= check_mysql50_prefix(name))) + (disallow_path_chars= check_mysql50_prefix(str.str))) { - name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH; - length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH; + return check_body(str.str + MYSQL50_TABLE_NAME_PREFIX_LENGTH, + str.length - MYSQL50_TABLE_NAME_PREFIX_LENGTH, + disallow_path_chars); } - return Lex_ident_fs::check_body(name, length, disallow_path_chars); + return check_body(str.str, str.length, disallow_path_chars); } @@ -5321,18 +5328,18 @@ bool Lex_ident_fs::check_body(const char *name, size_t length, @returns false - on success (valid) @returns true - on error (invalid) */ -bool Lex_ident_fs::check_db_name() const +bool Lex_ident_db::check_name(const LEX_CSTRING &str) { - DBUG_ASSERT(str); - if (check_mysql50_prefix(str)) + DBUG_ASSERT(str.str); + if (check_mysql50_prefix(str.str)) { - Lex_ident_fs name(Lex_cstring(str + MYSQL50_TABLE_NAME_PREFIX_LENGTH, - length - MYSQL50_TABLE_NAME_PREFIX_LENGTH)); + Lex_ident_fs name(Lex_cstring(str.str + MYSQL50_TABLE_NAME_PREFIX_LENGTH, + str.length - MYSQL50_TABLE_NAME_PREFIX_LENGTH)); return db_name_is_in_ignore_db_dirs_list(name.str) || check_body(name.str, name.length, true); } - return db_name_is_in_ignore_db_dirs_list(str) || - check_body(str, length, false); + return db_name_is_in_ignore_db_dirs_list(str.str) || + check_body(str.str, str.length, false); } @@ -5343,11 +5350,11 @@ bool Lex_ident_fs::check_db_name() const @returns false - on success (valid) @returns true - on error (invalid) */ -bool Lex_ident_fs::check_db_name_with_error() const +bool Lex_ident_db::check_name_with_error(const LEX_CSTRING &str) { - if (!check_db_name()) + if (!check_name(str)) return false; - my_error(ER_WRONG_DB_NAME ,MYF(0), safe_str(str)); + my_error(ER_WRONG_DB_NAME ,MYF(0), safe_str(str.str)); return true; } @@ -5809,9 +5816,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) DBUG_ASSERT(s->tmp_table != NO_TMP_TABLE || s->tdc->ref_count > 0); if (thd->lex->need_correct_ident()) - alias_name_used= my_strcasecmp(table_alias_charset, - s->table_name.str, - tl->alias.str); + alias_name_used= !s->table_name.streq(tl->alias); /* Fix alias if table name changes. */ if (!alias.alloced_length() || strcmp(alias.c_ptr(), tl->alias.str)) alias.copy(tl->alias.str, tl->alias.length, alias.charset()); @@ -6803,8 +6808,8 @@ bool TABLE_LIST::prepare_view_security_context(THD *thd, bool upgrade_check) { DBUG_PRINT("info", ("This table is suid view => load contest")); DBUG_ASSERT(view && view_sctx); - if (acl_getroot(view_sctx, definer.user.str, definer.host.str, - definer.host.str, thd->db.str)) + if (acl_getroot(view_sctx, definer.user, definer.host, + definer.host, thd->db)) { if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) || (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) @@ -7062,15 +7067,15 @@ Natural_join_column::Natural_join_column(Item_field *field_param, } -LEX_CSTRING *Natural_join_column::name() +const Lex_ident_column Natural_join_column::name() { if (view_field) { DBUG_ASSERT(table_field == NULL); - return &view_field->name; + return view_field->name; } - return &table_field->field_name; + return table_field->field_name; } @@ -7097,17 +7102,19 @@ Field *Natural_join_column::field() } -const char *Natural_join_column::safe_table_name() +const Lex_ident_table Natural_join_column::safe_table_name() const { DBUG_ASSERT(table_ref); - return table_ref->alias.str ? table_ref->alias.str : ""; + return table_ref->alias.str ? table_ref->alias : + Lex_ident_table(empty_clex_str); } -const char *Natural_join_column::safe_db_name() +const Lex_ident_db Natural_join_column::safe_db_name() const { if (view_field) - return table_ref->view_db.str ? table_ref->view_db.str : ""; + return table_ref->view_db.str ? table_ref->view_db : + Lex_ident_db(empty_clex_str); /* Test that TABLE_LIST::db is the same as TABLE_SHARE::db to @@ -7119,7 +7126,7 @@ const char *Natural_join_column::safe_db_name() (table_ref->schema_table && is_infoschema_db(&table_ref->table->s->db)) || table_ref->is_materialized_derived()); - return table_ref->db.str ? table_ref->db.str : ""; + return table_ref->db.str ? table_ref->db : Lex_ident_db(empty_clex_str); } @@ -7148,9 +7155,9 @@ void Field_iterator_view::set(TABLE_LIST *table) } -LEX_CSTRING *Field_iterator_table::name() +const Lex_ident_column Field_iterator_table::name() { - return &(*ptr)->field_name; + return (*ptr)->field_name; } @@ -7172,9 +7179,9 @@ Item *Field_iterator_table::create_item(THD *thd) } -LEX_CSTRING *Field_iterator_view::name() +const Lex_ident_column Field_iterator_view::name() { - return &ptr->name; + return ptr->name; } @@ -7338,26 +7345,26 @@ void Field_iterator_table_ref::next() } -const char *Field_iterator_table_ref::get_table_name() +const Lex_ident_table Field_iterator_table_ref::get_table_name() const { if (table_ref->view) - return table_ref->view_name.str; + return table_ref->view_name; if (table_ref->is_derived()) - return table_ref->table->s->table_name.str; + return table_ref->table->s->table_name; else if (table_ref->is_natural_join) return natural_join_it.column_ref()->safe_table_name(); DBUG_ASSERT(!strcmp(table_ref->table_name.str, table_ref->table->s->table_name.str) || table_ref->schema_table || table_ref->table_function); - return table_ref->table_name.str; + return table_ref->table_name; } -const char *Field_iterator_table_ref::get_db_name() +const Lex_ident_db Field_iterator_table_ref::get_db_name() const { if (table_ref->view) - return table_ref->view_db.str; + return table_ref->view_db; else if (table_ref->is_natural_join) return natural_join_it.column_ref()->safe_db_name(); @@ -7371,7 +7378,7 @@ const char *Field_iterator_table_ref::get_db_name() is_infoschema_db(&table_ref->table->s->db)) || table_ref->table_function); - return table_ref->db.str; + return table_ref->db; } @@ -10677,18 +10684,17 @@ void Vers_history_point::print(String *str, enum_query_type query_type, Field *TABLE::find_field_by_name(const LEX_CSTRING *str) const { Field **tmp; - size_t length= str->length; if (s->name_hash.records) { - tmp= (Field**) my_hash_search(&s->name_hash, (uchar*) str->str, length); + tmp= (Field**) my_hash_search(&s->name_hash, + (uchar*) str->str, str->length); return tmp ? field[tmp - s->field] : NULL; } else { for (tmp= field; *tmp; tmp++) { - if ((*tmp)->field_name.length == length && - !lex_string_cmp(system_charset_info, &(*tmp)->field_name, str)) + if ((*tmp)->field_name.streq(*str)) return *tmp; } } diff --git a/sql/table.h b/sql/table.h index 7d6eba07831..fa4d0e8bfe8 100644 --- a/sql/table.h +++ b/sql/table.h @@ -536,8 +536,8 @@ enum enum_table_category typedef enum enum_table_category TABLE_CATEGORY; -TABLE_CATEGORY get_table_category(const LEX_CSTRING *db, - const LEX_CSTRING *name); +TABLE_CATEGORY get_table_category(const Lex_ident_db &db, + const Lex_ident_table &name); typedef struct st_table_field_type @@ -757,8 +757,8 @@ struct TABLE_SHARE To ensure this one can use set_table_cache() methods. */ LEX_CSTRING table_cache_key; - LEX_CSTRING db; /* Pointer to db */ - LEX_CSTRING table_name; /* Table name (for open) */ + Lex_ident_db db; /* Pointer to db */ + Lex_ident_table table_name; /* Table name (for open) */ LEX_CSTRING path; /* Path to .frm file (from datadir) */ LEX_CSTRING normalized_path; /* unpack_filename(path) */ LEX_CSTRING connect_string; @@ -915,8 +915,8 @@ struct TABLE_SHARE { field_index_t start_fieldno; field_index_t end_fieldno; - Lex_ident name; - Lex_ident constr_name; + Lex_ident_column name; + Lex_ident_column constr_name; uint unique_keys; Field *start_field(TABLE_SHARE *s) const { @@ -2087,7 +2087,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, struct Field_translator { Item *item; - LEX_CSTRING name; + Lex_ident_column name; }; @@ -2114,11 +2114,11 @@ public: public: Natural_join_column(Field_translator *field_param, TABLE_LIST *tab); Natural_join_column(Item_field *field_param, TABLE_LIST *tab); - LEX_CSTRING *name(); + const Lex_ident_column name(); Item *create_item(THD *thd); Field *field(); - const char *safe_table_name(); - const char *safe_db_name(); + const Lex_ident_table safe_table_name() const; + const Lex_ident_db safe_db_name() const; GRANT_INFO *grant(); }; @@ -2176,7 +2176,7 @@ struct vers_select_conds_t bool delete_history:1; Vers_history_point start; Vers_history_point end; - Lex_ident name; + Lex_ident_column name; Item_field *field_start; Item_field *field_end; @@ -2196,7 +2196,7 @@ struct vers_select_conds_t void init(vers_system_time_t _type, Vers_history_point _start= Vers_history_point(), Vers_history_point _end= Vers_history_point(), - Lex_ident _name= "SYSTEM_TIME") + Lex_ident_column _name= "SYSTEM_TIME"_Lex_ident_column) { type= _type; orig_type= _type; @@ -2211,7 +2211,7 @@ struct vers_select_conds_t void set_all() { type= SYSTEM_TIME_ALL; - name= "SYSTEM_TIME"; + name= "SYSTEM_TIME"_Lex_ident_column; } void print(String *str, enum_query_type query_type) const; @@ -2327,9 +2327,10 @@ struct TABLE_LIST DBUG_ASSERT(!db_arg->str || strlen(db_arg->str) == db_arg->length); DBUG_ASSERT(!table_name_arg->str || strlen(table_name_arg->str) == table_name_arg->length); DBUG_ASSERT(!alias_arg || strlen(alias_arg->str) == alias_arg->length); - db= *db_arg; - table_name= *table_name_arg; - alias= (alias_arg ? *alias_arg : *table_name_arg); + db= Lex_ident_db(*db_arg); + table_name= Lex_ident_table(*table_name_arg); + alias= alias_arg ? Lex_ident_table(*alias_arg) : + Lex_ident_table(*table_name_arg); lock_type= lock_type_arg; updating= lock_type >= TL_FIRST_WRITE; MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE, db.str, table_name.str, @@ -2390,10 +2391,10 @@ struct TABLE_LIST TABLE_LIST *next_local; /* link in a global list of all queries tables */ TABLE_LIST *next_global, **prev_global; - LEX_CSTRING db; - LEX_CSTRING table_name; - LEX_CSTRING schema_table_name; - LEX_CSTRING alias; + Lex_ident_db db; + Lex_ident_table table_name; + Lex_ident_i_s_table schema_table_name; + Lex_ident_table alias; const char *option; /* Used by cache index */ Item *on_expr; /* Used with outer join */ Name_resolution_context *on_context; /* For ON expressions */ @@ -2605,8 +2606,8 @@ struct TABLE_LIST LEX_STRING select_stmt; /* text of (CREATE/SELECT) statement */ LEX_CSTRING md5; /* md5 of query text */ LEX_CSTRING source; /* source of CREATE VIEW */ - LEX_CSTRING view_db; /* saved view database */ - LEX_CSTRING view_name; /* saved view name */ + Lex_ident_db view_db; /* saved view database */ + Lex_ident_table view_name; /* saved view name */ LEX_STRING hr_timestamp; /* time stamp of last operation */ LEX_USER definer; /* definer of view */ ulonglong file_version; /* version of file's field set */ @@ -3000,7 +3001,10 @@ struct TABLE_LIST @brief Returns the name of the database that the referenced table belongs to. */ - const char *get_db_name() const { return view != NULL ? view_db.str : db.str; } + const Lex_ident_db get_db_name() const + { + return view != NULL ? view_db : db; + } /** @brief Returns the name of the table that this TABLE_LIST represents. @@ -3008,7 +3012,10 @@ struct TABLE_LIST @details The unqualified table name or view name for a table or view, respectively. */ - const char *get_table_name() const { return view != NULL ? view_name.str : table_name.str; } + const Lex_ident_table get_table_name() const + { + return view != NULL ? view_name : table_name; + } bool is_active_sjm(); bool is_sjm_scan_table(); bool is_jtbm() { return MY_TEST(jtbm_subselect != NULL); } @@ -3080,7 +3087,7 @@ public: virtual void set(TABLE_LIST *)= 0; virtual void next()= 0; virtual bool end_of_fields()= 0; /* Return 1 at end of list */ - virtual LEX_CSTRING *name()= 0; + virtual const Lex_ident_column name()= 0; virtual Item *create_item(THD *)= 0; virtual Field *field()= 0; }; @@ -3100,7 +3107,7 @@ public: void set_table(TABLE *table) { ptr= table->field; } void next() { ptr++; } bool end_of_fields() { return *ptr == 0; } - LEX_CSTRING *name(); + const Lex_ident_column name(); Item *create_item(THD *thd); Field *field() { return *ptr; } }; @@ -3117,7 +3124,7 @@ public: void set(TABLE_LIST *table); void next() { ptr++; } bool end_of_fields() { return ptr == array_end; } - LEX_CSTRING *name(); + const Lex_ident_column name(); Item *create_item(THD *thd); Item **item_ptr() {return &ptr->item; } Field *field() { return 0; } @@ -3141,10 +3148,10 @@ public: void set(TABLE_LIST *table); void next(); bool end_of_fields() { return !cur_column_ref; } - LEX_CSTRING *name() { return cur_column_ref->name(); } + const Lex_ident_column name() { return cur_column_ref->name(); } Item *create_item(THD *thd) { return cur_column_ref->create_item(thd); } Field *field() { return cur_column_ref->field(); } - Natural_join_column *column_ref() { return cur_column_ref; } + Natural_join_column *column_ref() const { return cur_column_ref; } }; @@ -3178,9 +3185,9 @@ public: void next(); bool end_of_fields() { return (table_ref == last_leaf && field_it->end_of_fields()); } - LEX_CSTRING *name() { return field_it->name(); } - const char *get_table_name(); - const char *get_db_name(); + const Lex_ident_column name() { return field_it->name(); } + const Lex_ident_table get_table_name() const; + const Lex_ident_db get_db_name() const; GRANT_INFO *grant(); Item *create_item(THD *thd) { return field_it->create_item(thd); } Field *field() { return field_it->field(); } @@ -3377,7 +3384,6 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); bool check_column_name(const char *name); bool check_period_name(const char *name); -bool check_table_name(const char *name, size_t length, bool check_for_path_chars); int rename_file_ext(const char * from,const char * to,const char * ext); char *get_field(MEM_ROOT *mem, Field *field); @@ -3404,27 +3410,27 @@ static inline int set_zone(int nr,int min_zone,int max_zone) } /* performance schema */ -extern LEX_CSTRING PERFORMANCE_SCHEMA_DB_NAME; +extern Lex_ident_i_s_db PERFORMANCE_SCHEMA_DB_NAME; -extern LEX_CSTRING GENERAL_LOG_NAME; -extern LEX_CSTRING SLOW_LOG_NAME; -extern LEX_CSTRING TRANSACTION_REG_NAME; +extern Lex_ident_table GENERAL_LOG_NAME; +extern Lex_ident_table SLOW_LOG_NAME; +extern Lex_ident_table TRANSACTION_REG_NAME; /* information schema */ -extern LEX_CSTRING INFORMATION_SCHEMA_NAME; -extern LEX_CSTRING MYSQL_SCHEMA_NAME; +extern Lex_ident_i_s_db INFORMATION_SCHEMA_NAME; +extern Lex_ident_db MYSQL_SCHEMA_NAME; /* table names */ -extern LEX_CSTRING MYSQL_PROC_NAME; +extern Lex_ident_table MYSQL_PROC_NAME; inline bool is_infoschema_db(const LEX_CSTRING *name) { - return lex_string_eq(&INFORMATION_SCHEMA_NAME, name); + return INFORMATION_SCHEMA_NAME.streq(*name); } inline bool is_perfschema_db(const LEX_CSTRING *name) { - return lex_string_eq(&PERFORMANCE_SCHEMA_DB_NAME, name); + return PERFORMANCE_SCHEMA_DB_NAME.streq(*name); } inline void mark_as_null_row(TABLE *table) diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 4a226df0e0b..8d3d41025b4 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -59,8 +59,8 @@ bool THD::has_thd_temporary_tables() */ TABLE *THD::create_and_open_tmp_table(LEX_CUSTRING *frm, const char *path, - const char *db, - const char *table_name, + const Lex_ident_db &db, + const Lex_ident_table &table_name, bool open_internal_tables) { DBUG_ENTER("THD::create_and_open_tmp_table"); @@ -112,8 +112,8 @@ TABLE *THD::create_and_open_tmp_table(LEX_CUSTRING *frm, @return Success Pointer to first used table instance. Failure NULL */ -TABLE *THD::find_temporary_table(const char *db, - const char *table_name, +TABLE *THD::find_temporary_table(const Lex_ident_db &db, + const Lex_ident_table &table_name, Temporary_table_state state) { DBUG_ENTER("THD::find_temporary_table"); @@ -215,8 +215,8 @@ TMP_TABLE_SHARE *THD::find_tmp_table_share_w_base_key(const char *key, @return Success A pointer to table share object Failure NULL */ -TMP_TABLE_SHARE *THD::find_tmp_table_share(const char *db, - const char *table_name) +TMP_TABLE_SHARE *THD::find_tmp_table_share(const Lex_ident_db &db, + const Lex_ident_table &table_name) { DBUG_ENTER("THD::find_tmp_table_share"); @@ -581,7 +581,8 @@ bool THD::rename_temporary_table(TABLE *table, /* Temporary tables are renamed by simply changing their table definition key. */ - key_length= create_tmp_table_def_key(key, db->str, table_name->str); + key_length= create_tmp_table_def_key(key, Lex_ident_db(*db), + Lex_ident_table(*table_name)); share->set_table_cache_key(key, key_length); DBUG_RETURN(false); @@ -917,13 +918,14 @@ bool THD::has_temporary_tables() 4 bytes of master thread id 4 bytes of pseudo thread id */ -uint THD::create_tmp_table_def_key(char *key, const char *db, - const char *table_name) +uint THD::create_tmp_table_def_key(char *key, + const Lex_ident_db &db, + const Lex_ident_table &table_name) { uint key_length; DBUG_ENTER("THD::create_tmp_table_def_key"); - key_length= tdc_create_key(key, db, table_name); + key_length= tdc_create_key(key, db.str, table_name.str); int4store(key + key_length, variables.server_id); int4store(key + key_length + 4, variables.pseudo_thread_id); key_length += TMP_TABLE_KEY_EXTRA; @@ -945,8 +947,8 @@ uint THD::create_tmp_table_def_key(char *key, const char *db, */ TMP_TABLE_SHARE *THD::create_temporary_table(LEX_CUSTRING *frm, const char *path, - const char *db, - const char *table_name) + const Lex_ident_db &db, + const Lex_ident_table &table_name) { DBUG_ENTER("THD::create_temporary_table"); @@ -1086,7 +1088,7 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length, share->all_tmp_tables.remove(table); free_temporary_table(table); if (share->all_tmp_tables.is_empty()) - table= open_temporary_table(share, share->table_name.str); + table= open_temporary_table(share, share->table_name); else { it.rewind(); @@ -1119,10 +1121,9 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length, Failure NULL */ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share, - const char *alias_arg) + const Lex_ident_table &alias) { TABLE *table; - LEX_CSTRING alias= {alias_arg, strlen(alias_arg) }; DBUG_ENTER("THD::open_temporary_table"); diff --git a/sql/transaction.cc b/sql/transaction.cc index 053466c0c14..2f70086a8da 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -551,16 +551,15 @@ bool trans_rollback_stmt(THD *thd) } /** Find a savepoint by name in a savepoint list */ -SAVEPOINT** find_savepoint_in_list(THD *thd, LEX_CSTRING name, +SAVEPOINT** find_savepoint_in_list(THD *thd, + const Lex_ident_savepoint name, SAVEPOINT ** const list) { SAVEPOINT **sv= list; while (*sv) { - if (system_charset_info->strnncoll( - (uchar *) name.str, name.length, - (uchar *) (*sv)->name, (*sv)->length) == 0) + if (name.streq(Lex_cstring((*sv)->name, (*sv)->length))) break; sv= &(*sv)->prev; } @@ -570,12 +569,12 @@ SAVEPOINT** find_savepoint_in_list(THD *thd, LEX_CSTRING name, /* Find a named savepoint in the current transaction. */ static SAVEPOINT ** -find_savepoint(THD *thd, LEX_CSTRING name) +find_savepoint(THD *thd, Lex_ident_savepoint name) { return find_savepoint_in_list(thd, name, &thd->transaction->savepoints); } -SAVEPOINT* savepoint_add(THD *thd, LEX_CSTRING name, SAVEPOINT **list, +SAVEPOINT* savepoint_add(THD *thd, Lex_ident_savepoint name, SAVEPOINT **list, int (*release_old)(THD*, SAVEPOINT*)) { DBUG_ENTER("savepoint_add"); @@ -627,7 +626,8 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name) if (thd->transaction->xid_state.check_has_uncommitted_xa()) DBUG_RETURN(TRUE); - SAVEPOINT *newsv= savepoint_add(thd, name, &thd->transaction->savepoints, + SAVEPOINT *newsv= savepoint_add(thd, Lex_ident_savepoint(name), + &thd->transaction->savepoints, ha_release_savepoint); if (newsv == NULL) @@ -679,7 +679,7 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name) bool trans_rollback_to_savepoint(THD *thd, LEX_CSTRING name) { int res= FALSE; - SAVEPOINT *sv= *find_savepoint(thd, name); + SAVEPOINT *sv= *find_savepoint(thd, Lex_ident_savepoint(name)); DBUG_ENTER("trans_rollback_to_savepoint"); if (sv == NULL) @@ -734,7 +734,7 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_CSTRING name) bool trans_release_savepoint(THD *thd, LEX_CSTRING name) { int res= FALSE; - SAVEPOINT *sv= *find_savepoint(thd, name); + SAVEPOINT *sv= *find_savepoint(thd, Lex_ident_savepoint(name)); DBUG_ENTER("trans_release_savepoint"); if (sv == NULL) diff --git a/sql/tztime.cc b/sql/tztime.cc index 1e919140660..85a13123960 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1626,7 +1626,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) THD *thd; TABLE_LIST tz_tables[1+MY_TZ_TABLES_COUNT]; TABLE *table; - const LEX_CSTRING tmp_table_name= { STRING_WITH_LEN("time_zone_leap_second") }; + const Lex_ident_table tmp_table_name= "time_zone_leap_second"_Lex_ident_table; Tz_names_entry *tmp_tzname; my_bool return_val= 1; int res; diff --git a/sql/unireg.cc b/sql/unireg.cc index 6cc4bc8495c..eab107b3f21 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -137,7 +137,7 @@ static uchar *extra2_write_index_properties(uchar *pos, const KEY *keyinfo, static field_index_t get_fieldno_by_name(HA_CREATE_INFO *create_info, List &create_fields, - const Lex_ident &field_name) + const Lex_ident_column &field_name) { List_iterator it(create_fields); Create_field *sql_field = NULL; diff --git a/sql/vers_string.h b/sql/vers_string.h deleted file mode 100644 index 93740ea8523..00000000000 --- a/sql/vers_string.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2018, 2020, 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-1301 USA */ - -#ifndef VERS_STRING_INCLUDED -#define VERS_STRING_INCLUDED - -#include "lex_string.h" - -/* - LEX_CSTRING with comparison semantics. -*/ - -// db and table names: case sensitive (or insensitive) in table_alias_charset -struct Compare_table_names -{ - int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const - { - DBUG_ASSERT(a.str[a.length] == 0); - DBUG_ASSERT(b.str[b.length] == 0); - return table_alias_charset->strnncoll(a.str, a.length, - b.str, b.length); - } -}; - -// column names and other identifiers: case insensitive in system_charset_info -struct Compare_identifiers -{ - int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const - { - DBUG_ASSERT(a.str != NULL); - DBUG_ASSERT(b.str != NULL); - DBUG_ASSERT(a.str[a.length] == 0); - DBUG_ASSERT(b.str[b.length] == 0); - return my_strcasecmp(system_charset_info, a.str, b.str); - } -}; - - -template -struct Lex_cstring_with_compare : public Lex_cstring -{ -public: - Lex_cstring_with_compare() = default; - Lex_cstring_with_compare(const char *_str, size_t _len) : - Lex_cstring(_str, _len) - { } - Lex_cstring_with_compare(const LEX_CSTRING src) : Lex_cstring(src.str, src.length) - { } - Lex_cstring_with_compare(const char *_str) : Lex_cstring(_str, strlen(_str)) - { } - bool streq(const Lex_cstring_with_compare& b) const - { - return Lex_cstring::length == b.length && 0 == Compare()(*this, b); - } - operator const char* () const - { - return str; - } - operator bool () const - { - return str != NULL; - } -}; - -typedef Lex_cstring_with_compare Lex_ident; -typedef Lex_cstring_with_compare Lex_table_name; - -#endif // VERS_STRING_INCLUDED diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index e9ce787d140..3dcfdc4af40 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1464,7 +1464,7 @@ bool wsrep_check_mode_after_open_table (THD *thd, per statement. Note: kick-start will take-care of creating isolation key for all tables involved in the list (provided all of them are MYISAM or Aria tables). */ - if (!is_stat_table(&tables->db, &tables->alias)) + if (!is_stat_table(tables->db, tables->alias)) { if (tbl->s->primary_key == MAX_KEY && wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY)) @@ -2405,7 +2405,7 @@ static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len) bool found_temp_table= false; for (TABLE_LIST* table= first_table; table; table= table->next_global) { - if (thd->find_temporary_table(table->db.str, table->table_name.str)) + if (thd->find_temporary_table(table->db, table->table_name)) { found_temp_table= true; break; @@ -2420,7 +2420,7 @@ static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len) for (TABLE_LIST* table= first_table; table; table= table->next_global) { - if (!thd->find_temporary_table(table->db.str, table->table_name.str)) + if (!thd->find_temporary_table(table->db, table->table_name)) { append_identifier(thd, &buff, table->db.str, table->db.length); buff.append('.'); @@ -2617,7 +2617,8 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, } /* fallthrough */ default: - if (table && !thd->find_temporary_table(db, table)) + if (table && !thd->find_temporary_table(Lex_ident_db(Lex_cstring_strlen(db)), + Lex_cstring_strlen(table))) { return true; } @@ -2626,7 +2627,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, { for (const TABLE_LIST* table= first_table; table; table= table->next_global) { - if (!thd->find_temporary_table(table->db.str, table->table_name.str)) + if (!thd->find_temporary_table(table->db, table->table_name)) { return true; } diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 343f3c70286..525912bcd05 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -416,7 +416,8 @@ static int blackhole_init(void *p) mysql_mutex_init(bh_key_mutex_blackhole, &blackhole_mutex, MY_MUTEX_INIT_FAST); (void) my_hash_init(PSI_INSTRUMENT_ME, &blackhole_open_tables, - system_charset_info, 32, 0, 0, + Lex_ident_table::charset_info(), + 32, 0, 0, (my_hash_get_key) blackhole_get_key, (my_hash_free_key) blackhole_free_key, 0); diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index 093eaeb9a5e..27ab744cbde 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -45,7 +45,6 @@ #include "catalog.h" #include "ha_connect.h" -#define my_stricmp(a, b) my_strcasecmp(default_charset_info, (a), (b)) /***********************************************************************/ /* Routines called internally by semantic routines. */ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index fc5011c63b1..f4b6323e28f 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -156,8 +156,6 @@ #include "tabpivot.h" #include "tabfix.h" -#define my_stricmp(a,b) my_strcasecmp(default_charset_info, (a), (b)) - /***********************************************************************/ /* Initialize the ha_connect static members. */ diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index e705ff0e7c0..e9b7d84a703 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -184,7 +184,8 @@ static int tina_init_func(void *p) tina_hton= (handlerton *)p; mysql_mutex_init(csv_key_mutex_tina, &tina_mutex, MY_MUTEX_INIT_FAST); (void) my_hash_init(csv_key_memory_tina_share, &tina_open_tables, - system_charset_info, 32, 0, 0, (my_hash_get_key) + Lex_ident_table::charset_info(), + 32, 0, 0, (my_hash_get_key) tina_get_key, 0, 0); tina_hton->db_type= DB_TYPE_CSV_DB; tina_hton->create= tina_create_handler; diff --git a/storage/federatedx/federatedx_pushdown.cc b/storage/federatedx/federatedx_pushdown.cc index c4d77a73984..6253fca75a0 100644 --- a/storage/federatedx/federatedx_pushdown.cc +++ b/storage/federatedx/federatedx_pushdown.cc @@ -73,22 +73,8 @@ bool local_and_remote_names_mismatch(const TABLE_SHARE *tbl_share, const FEDERATEDX_SHARE *fshare) { - - if (lower_case_table_names) - { - if (strcasecmp(fshare->database, tbl_share->db.str) != 0) - return true; - } - else - { - if (strncmp(fshare->database, tbl_share->db.str, tbl_share->db.length) != 0) - return true; - } - - return my_strnncoll(system_charset_info, (uchar *) fshare->table_name, - strlen(fshare->table_name), - (uchar *) tbl_share->table_name.str, - tbl_share->table_name.length) != 0; + return !tbl_share->db.streq(Lex_cstring_strlen(fshare->database)) || + !tbl_share->table_name.streq(Lex_cstring_strlen(fshare->table_name)); } diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index dd858287f46..0f6c2f7ea10 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -173,7 +173,6 @@ dict_create_sys_columns_tuple( const dict_col_t* column; dfield_t* dfield; byte* ptr; - const char* col_name; ulint num_base = 0; ulint v_col_no = ULINT_UNDEFINED; @@ -225,13 +224,11 @@ dict_create_sys_columns_tuple( /* 4: NAME ---------------------------*/ dfield = dtuple_get_nth_field(entry, DICT_COL__SYS_COLUMNS__NAME); - if (i >= table->n_def) { - col_name = dict_table_get_v_col_name(table, i - table->n_def); - } else { - col_name = dict_table_get_col_name(table, i); - } + Lex_ident_column col_name= i >= table->n_def ? + dict_table_get_v_col_name(table, i - table->n_def) : + dict_table_get_col_name(table, i); - dfield_set_data(dfield, col_name, strlen(col_name)); + dfield_set_data(dfield, col_name.str, col_name.length); /* 5: MTYPE --------------------------*/ dfield = dtuple_get_nth_field(entry, DICT_COL__SYS_COLUMNS__MTYPE); @@ -1814,7 +1811,7 @@ dict_foreign_base_for_stored( for (ulint j = 0; j < s_col.num_base; j++) { if (strcmp(col_name, dict_table_get_col_name( table, - s_col.base_col[j]->ind)) == 0) { + s_col.base_col[j]->ind).str) == 0) { return(true); } } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index b49c76093c9..a6a2e006c69 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -284,27 +284,24 @@ otherwise table->n_def */ ulint dict_table_has_column( const dict_table_t* table, - const char* col_name, + const LEX_CSTRING &col_name, ulint col_nr) { ulint col_max = table->n_def; ut_ad(table); - ut_ad(col_name); + ut_ad(col_name.str); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); if (col_nr < col_max - && innobase_strcasecmp( - col_name, dict_table_get_col_name(table, col_nr)) == 0) { + && dict_table_get_col_name(table, col_nr).streq(col_name)) { return(col_nr); } /** The order of column may changed, check it with other columns */ for (ulint i = 0; i < col_max; i++) { if (i != col_nr - && innobase_strcasecmp( - col_name, dict_table_get_col_name(table, i)) == 0) { - + && dict_table_get_col_name(table, i).streq(col_name)) { return(i); } } @@ -312,63 +309,60 @@ dict_table_has_column( return(col_max); } -/** Retrieve the column name. -@param[in] table the table of this column */ -const char* dict_col_t::name(const dict_table_t& table) const + +/** Retrieve a column name from a 0-separated list +@param str the list in the format "name1\0name2\0...nameN\0" +@param col_nr the position +*/ +Lex_ident_column +dict_table_t::get_name_from_z_list(const char *str, size_t col_nr) { - ut_ad(table.magic_n == DICT_TABLE_MAGIC_N); + if (!str) + return Lex_ident_column(); + Lex_ident_column res(str, strlen(str)); + for (size_t i= 0; i < col_nr; i++) + { + res.str+= res.length + 1; + res.length= strlen(res.str); + } + return res; +} - size_t col_nr; - const char *s; - if (is_virtual()) { - col_nr = size_t(reinterpret_cast(this) - - table.v_cols); - ut_ad(col_nr < table.n_v_def); - s = table.v_col_names; - } else { - col_nr = size_t(this - table.cols); - ut_ad(col_nr < table.n_def); - s = table.col_names; - } +/** Retrieve the column name. +@param[in] table the table of this column */ +Lex_ident_column +dict_col_t::name(const dict_table_t& table) const +{ + ut_ad(table.magic_n == DICT_TABLE_MAGIC_N); - if (s) { - for (size_t i = 0; i < col_nr; i++) { - s += strlen(s) + 1; - } - } + size_t col_nr; - return(s); + if (is_virtual()) + { + col_nr= size_t(reinterpret_cast(this) - table.v_cols); + ut_ad(col_nr < table.n_v_def); + return dict_table_t::get_name_from_z_list(table.v_col_names, col_nr); + } + col_nr= size_t(this - table.cols); + ut_ad(col_nr < table.n_def); + return dict_table_t::get_name_from_z_list(table.col_names, col_nr); } /** Returns a virtual column's name. -@param[in] table target table -@param[in] col_nr virtual column number (nth virtual column) +@param[in] table target table +@param[in] col_nr virtual column number (nth virtual column) @return column name or NULL if column number out of range. */ -const char* -dict_table_get_v_col_name( - const dict_table_t* table, - ulint col_nr) +Lex_ident_column +dict_table_get_v_col_name(const dict_table_t* table, ulint col_nr) { - const char* s; + ut_ad(table); + ut_ad(col_nr < table->n_v_def); + ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table); - ut_ad(col_nr < table->n_v_def); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - if (col_nr >= table->n_v_def) { - return(NULL); - } - - s = table->v_col_names; - - if (s != NULL) { - for (ulint i = 0; i < col_nr; i++) { - s += strlen(s) + 1; - } - } - - return(s); + return col_nr >= table->n_v_def ? + Lex_ident_column() : + dict_table_t::get_name_from_z_list(table->v_col_names, col_nr); } /** Search virtual column's position in InnoDB according to its position @@ -408,7 +402,7 @@ MySQL table position. @param[in] col_nr column number (nth column in the table) @return column name. */ static -const char* +Lex_ident_column dict_table_get_v_col_name_mysql( const dict_table_t* table, ulint col_nr) @@ -416,7 +410,7 @@ dict_table_get_v_col_name_mysql( ulint i = dict_table_get_v_col_pos_for_mysql(table, col_nr); if (i == ULINT_UNDEFINED) { - return(NULL); + return Lex_ident_column(); } return(dict_table_get_v_col_name(table, i)); @@ -1904,16 +1898,18 @@ TRUE. ibool dict_col_name_is_reserved( /*======================*/ - const char* name) /*!< in: column name */ + const LEX_CSTRING &name) /*!< in: column name */ { - static const char* reserved_names[] = { - "DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR" + static Lex_ident_column reserved_names[] = { + "DB_ROW_ID"_Lex_ident_column, + "DB_TRX_ID"_Lex_ident_column, + "DB_ROLL_PTR"_Lex_ident_column }; compile_time_assert(UT_ARR_SIZE(reserved_names) == DATA_N_SYS_COLS); for (ulint i = 0; i < UT_ARR_SIZE(reserved_names); i++) { - if (innobase_strcasecmp(name, reserved_names[i]) == 0) { + if (reserved_names[i].streq(name)) { return(TRUE); } @@ -2147,10 +2143,11 @@ dict_index_find_cols( for (ulint i = 0; i < index->n_fields; i++) { ulint j; dict_field_t* field = dict_index_get_nth_field(index, i); + const Lex_ident_column field_name = Lex_cstring_strlen(field->name); for (j = 0; j < table->n_cols; j++) { - if (!innobase_strcasecmp(dict_table_get_col_name(table, j), - field->name)) { + if (field_name. + streq(dict_table_get_col_name(table, j))) { /* Check if same column is being assigned again which suggest that column has duplicate name. */ @@ -2174,7 +2171,7 @@ dict_index_find_cols( /* Let's check if it is a virtual column */ for (j = 0; j < table->n_v_cols; j++) { - if (!strcmp(dict_table_get_v_col_name(table, j), + if (!strcmp(dict_table_get_v_col_name(table, j).str, field->name)) { /* Check if same column is being assigned again @@ -2242,9 +2239,9 @@ void dict_index_add_col(dict_index_t *index, const dict_table_t *table, /* Register the index with the virtual column index list */ v_col->v_indexes.push_front(dict_v_idx_t(index, index->n_def)); col_name = dict_table_get_v_col_name_mysql( - table, dict_col_get_no(col)); + table, dict_col_get_no(col)).str; } else { - col_name = dict_table_get_col_name(table, dict_col_get_no(col)); + col_name = dict_table_get_col_name(table, dict_col_get_no(col)).str; } dict_mem_index_add_field(index, col_name, prefix_len); @@ -4572,12 +4569,10 @@ dict_foreign_qualify_index( } for (ulint i = 0; i < n_cols; i++) { - dict_field_t* field; - const char* col_name; - ulint col_no; - - field = dict_index_get_nth_field(index, i); - col_no = dict_col_get_no(field->col); + const dict_field_t * const field(dict_index_get_nth_field(index, i)); + const Lex_ident_column field_name= Lex_cstring_strlen(field->name); + const ulint col_no = dict_col_get_no(field->col); + Lex_ident_column col_name; if (field->prefix_len != 0) { /* We do not accept column prefix @@ -4601,20 +4596,20 @@ dict_foreign_qualify_index( } if (field->col->is_virtual()) { - col_name = ""; + col_name = ""_Lex_ident_column; for (ulint j = 0; j < table->n_v_def; j++) { col_name = dict_table_get_v_col_name(table, j); - if (innobase_strcasecmp(field->name,col_name) == 0) { + if (field_name.streq(col_name)) { break; } } } else { col_name = col_names - ? col_names[col_no] + ? Lex_ident_column(Lex_cstring_strlen(col_names[col_no])) : dict_table_get_col_name(table, col_no); } - if (0 != innobase_strcasecmp(columns[i], col_name)) { + if (!col_name.streq(Lex_cstring_strlen(columns[i]))) { return(false); } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 8bf496f5e6a..1b1730f567e 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -168,7 +168,7 @@ name_of_col_is( dict_index_get_nth_field( index, i))); - return(strcmp(name, dict_table_get_col_name(table, tmp)) == 0); + return(strcmp(name, dict_table_get_col_name(table, tmp).str) == 0); } #endif /* UNIV_DEBUG */ @@ -1383,8 +1383,8 @@ static dberr_t dict_load_columns(dict_table_t *table, unsigned use_uncommitted, /* Note: Currently we have one DOC_ID column that is shared by all FTS indexes on a table. And only non-virtual column can be used for FULLTEXT index */ - if (innobase_strcasecmp(name, - FTS_DOC_ID_COL_NAME) == 0 + if (Lex_ident_column(Lex_cstring_strlen(name)). + streq(FTS_DOC_ID) && nth_v_col == ULINT_UNDEFINED) { dict_col_t* col; /* As part of normal loading of tables the @@ -2155,7 +2155,7 @@ next_rec: if (table->fts != NULL) { dict_index_t *idx = dict_table_get_index_on_name( - table, FTS_DOC_ID_INDEX_NAME); + table, FTS_DOC_ID_INDEX.str); if (idx && dict_index_is_unique(idx)) { table->fts_doc_id_index = idx; } diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 3e419765868..2e227c0c4fe 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -694,8 +694,8 @@ dict_mem_table_col_rename( /*======================*/ dict_table_t* table, /*!< in/out: table */ ulint nth_col,/*!< in: column index */ - const char* from, /*!< in: old column name */ - const char* to, /*!< in: new column name */ + const LEX_CSTRING &from,/*!< in: old column name */ + const LEX_CSTRING &to, /*!< in: new column name */ bool is_virtual) /*!< in: if this is a virtual column */ { @@ -710,10 +710,10 @@ dict_mem_table_col_rename( s += len + 1; } - ut_ad(!my_strcasecmp(system_charset_info, from, s)); + ut_ad(Lex_ident_column(from).streq(Lex_cstring_strlen(s))); dict_mem_table_col_rename_low(table, static_cast(nth_col), - to, s, is_virtual); + to.str, s, is_virtual); } /**********************************************************************//** @@ -939,7 +939,7 @@ dict_mem_fill_vcol_set_for_base_col( for (ulint j = 0; j < unsigned{v_col->num_base}; j++) { if (strcmp(col_name, dict_table_get_col_name( table, - v_col->base_col[j]->ind)) == 0) { + v_col->base_col[j]->ind).str) == 0) { if (*v_cols == NULL) { *v_cols = UT_NEW_NOKEY(dict_vcol_set()); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 97f8ba319d3..9d68e99500d 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -178,7 +178,7 @@ dict_stats_should_ignore_index( struct dict_col_meta_t { /** column name */ - const char *name; + const LEX_CSTRING name; /** main type */ unsigned mtype; /** prtype mask; all these bits have to be set in prtype */ @@ -204,8 +204,8 @@ static const dict_table_schema_t table_stats_schema = { {C_STRING_WITH_LEN(TABLE_STATS_NAME)}, TABLE_STATS_NAME_PRINT, 6, { - {"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192}, - {"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597}, + {"database_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 192}, + {"table_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 597}, /* Don't check the DATA_UNSIGNED flag in last_update. It presents if the server is running in a pure MariaDB installation, @@ -216,10 +216,12 @@ static const dict_table_schema_t table_stats_schema = This is fine not to check DATA_UNSIGNED, because Field_timestampf in both MariaDB and MySQL support only non-negative time_t values. */ - {"last_update", DATA_INT, DATA_NOT_NULL, 4}, - {"n_rows", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, - {"clustered_index_size", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, - {"sum_of_other_index_sizes", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, + {"last_update"_LEX_CSTRING, DATA_INT, DATA_NOT_NULL, 4}, + {"n_rows"_LEX_CSTRING, DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, + {"clustered_index_size"_LEX_CSTRING, DATA_INT, + DATA_NOT_NULL | DATA_UNSIGNED, 8}, + {"sum_of_other_index_sizes"_LEX_CSTRING, DATA_INT, + DATA_NOT_NULL | DATA_UNSIGNED, 8}, } }; @@ -227,18 +229,18 @@ static const dict_table_schema_t index_stats_schema = { {C_STRING_WITH_LEN(INDEX_STATS_NAME)}, INDEX_STATS_NAME_PRINT, 8, { - {"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192}, - {"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597}, - {"index_name", DATA_VARMYSQL, DATA_NOT_NULL, 192}, + {"database_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 192}, + {"table_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 597}, + {"index_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 192}, /* Don't check the DATA_UNSIGNED flag in last_update. See comments about last_update in table_stats_schema above. */ - {"last_update", DATA_INT, DATA_NOT_NULL, 4}, - {"stat_name", DATA_VARMYSQL, DATA_NOT_NULL, 64*3}, - {"stat_value", DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, - {"sample_size", DATA_INT, DATA_UNSIGNED, 8}, - {"stat_description", DATA_VARMYSQL, DATA_NOT_NULL, 1024*3} + {"last_update"_LEX_CSTRING, DATA_INT, DATA_NOT_NULL, 4}, + {"stat_name"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 64*3}, + {"stat_value"_LEX_CSTRING, DATA_INT, DATA_NOT_NULL | DATA_UNSIGNED, 8}, + {"sample_size"_LEX_CSTRING, DATA_INT, DATA_UNSIGNED, 8}, + {"stat_description"_LEX_CSTRING, DATA_VARMYSQL, DATA_NOT_NULL, 1024*3} } }; @@ -408,7 +410,7 @@ dict_table_schema_check( snprintf(errstr, errstr_sz, "required column %s" " not found in table %s.", - req_schema->columns[i].name, + req_schema->columns[i].name.str, req_schema->table_name_sql); return(DB_ERROR); @@ -424,7 +426,7 @@ dict_table_schema_check( " column name %s." " Please run mariadb-upgrade", req_schema->table_name_sql, - req_schema->columns[i].name); + req_schema->columns[i].name.str); } /* @@ -445,7 +447,7 @@ dict_table_schema_check( int s = snprintf(errstr, errstr_sz, "Column %s in table %s is ", - req_schema->columns[i].name, + req_schema->columns[i].name.str, req_schema->table_name_sql); if (s < 0 || static_cast(s) >= errstr_sz) { return DB_ERROR; diff --git a/storage/innobase/fsp/fsp0space.cc b/storage/innobase/fsp/fsp0space.cc index c2152b08590..75fc7ee09ec 100644 --- a/storage/innobase/fsp/fsp0space.cc +++ b/storage/innobase/fsp/fsp0space.cc @@ -28,6 +28,7 @@ Created 2012-11-16 by Sunny Bains as srv/srv0space.cc #include "fsp0fsp.h" #include "os0file.h" #include "my_sys.h" +#include "lex_ident.h" /** Check if two tablespaces have common data file names. @param other_space Tablespace to check against this. @@ -156,9 +157,10 @@ Tablespace::open_or_create(bool is_temp) bool Tablespace::find(const char* filename) const { + const Lex_ident_column filename_ident = Lex_cstring_strlen(filename); for (const_iterator it = begin(); it != end(); ++it) { - if (innobase_strcasecmp(filename, it->m_filename) == 0) { + if (filename_ident.streq(Lex_cstring_strlen(it->m_filename))) { return(true); } } diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 0c033ef0354..78af6c88e34 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1955,14 +1955,16 @@ fts_create_common_tables( } if (table->versioned()) { - index = dict_mem_index_create(table, FTS_DOC_ID_INDEX_NAME, + index = dict_mem_index_create(table, + FTS_DOC_ID_INDEX.str, DICT_UNIQUE, 2); - dict_mem_index_add_field(index, FTS_DOC_ID_COL_NAME, 0); - dict_mem_index_add_field(index, table->cols[table->vers_end].name(*table), 0); + dict_mem_index_add_field(index, FTS_DOC_ID.str, 0); + dict_mem_index_add_field(index, table->cols[table->vers_end].name(*table).str, 0); } else { - index = dict_mem_index_create(table, FTS_DOC_ID_INDEX_NAME, + index = dict_mem_index_create(table, + FTS_DOC_ID_INDEX.str, DICT_UNIQUE, 1); - dict_mem_index_add_field(index, FTS_DOC_ID_COL_NAME, 0); + dict_mem_index_add_field(index, FTS_DOC_ID.str, 0); } error = row_create_index_for_mysql(index, trx, NULL, @@ -3614,8 +3616,9 @@ fts_get_max_doc_id( dfield = dict_index_get_nth_field(index, 0); -#if 0 /* This can fail when renaming a column to FTS_DOC_ID_COL_NAME. */ - ut_ad(innobase_strcasecmp(FTS_DOC_ID_COL_NAME, dfield->name) == 0); +#if 0 /* This can fail when renaming a column to FTS_DOC_ID. */ + ut_ad(Lex_ident_column(Lex_cstring_strlen(dfield->name)). + streq(FTS_DOC_ID)); #endif mtr.start(); @@ -3731,7 +3734,8 @@ fts_doc_fetch_by_doc_id( " END IF;\n" "END LOOP;\n" "CLOSE c;", - select_str, FTS_DOC_ID_COL_NAME)); + select_str, + FTS_DOC_ID.str)); } else { ut_ad(option == FTS_FETCH_DOC_BY_ID_LARGE); @@ -3767,8 +3771,9 @@ fts_doc_fetch_by_doc_id( " END IF;\n" "END LOOP;\n" "CLOSE c;", - FTS_DOC_ID_COL_NAME, - select_str, FTS_DOC_ID_COL_NAME)); + FTS_DOC_ID.str, + select_str, + FTS_DOC_ID.str)); } if (get_doc) { get_doc->get_document_graph = graph; @@ -5208,7 +5213,7 @@ fts_add_doc_id_column( { dict_mem_table_add_col( table, heap, - FTS_DOC_ID_COL_NAME, + FTS_DOC_ID.str, DATA_INT, dtype_form_prtype( DATA_NOT_NULL | DATA_UNSIGNED @@ -5763,7 +5768,7 @@ fts_valid_stopword_table( return(NULL); } else { - if (strcmp(dict_table_get_col_name(table, 0), "value")) { + if (strcmp(dict_table_get_col_name(table, 0).str, "value")) { ib::error() << "Invalid column name for stopword" " table " << stopword_table_name << ". Its" " first column must be named as 'value'."; @@ -5788,7 +5793,7 @@ fts_valid_stopword_table( if (row_end) { *row_end = table->versioned() - ? dict_table_get_col_name(table, table->vers_end) + ? dict_table_get_col_name(table, table->vers_end).str : "value"; /* for fts_load_user_stopword() */ } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4461e279530..9156bfd2ba8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2425,27 +2425,6 @@ innobase_convert_from_id( strconvert(cs, from, FN_REFLEN, system_charset_info, to, (uint) len, &errors); } -/******************************************************************//** -Compares NUL-terminated UTF-8 strings case insensitively. -@return 0 if a=b, <0 if a1 if a>b */ -int -innobase_strcasecmp( -/*================*/ - const char* a, /*!< in: first string to compare */ - const char* b) /*!< in: second string to compare */ -{ - if (!a) { - if (!b) { - return(0); - } else { - return(-1); - } - } else if (!b) { - return(1); - } - - return(my_strcasecmp(system_charset_info, a, b)); -} /******************************************************************//** Compares NUL-terminated UTF-8 strings case insensitively. The @@ -5638,11 +5617,10 @@ innobase_build_v_templ( if (z >= ib_table->n_v_def) { name = add_v->v_col_name[z - ib_table->n_v_def]; } else { - name = dict_table_get_v_col_name(ib_table, z); + name = dict_table_get_v_col_name(ib_table, z).str; } - ut_ad(!my_strcasecmp(system_charset_info, name, - field->field_name.str)); + ut_ad(field->field_name.streq(Lex_cstring_strlen(name))); #endif const dict_v_col_t* vcol; @@ -5673,10 +5651,8 @@ innobase_build_v_templ( dict_col_t* col = dict_table_get_nth_col( ib_table, j); - ut_ad(!my_strcasecmp(system_charset_info, - dict_table_get_col_name( - ib_table, j), - field->field_name.str)); + ut_ad(field->field_name.streq( + dict_table_get_col_name(ib_table, j))); s_templ->vtempl[j] = static_cast< mysql_row_templ_t*>( @@ -7110,7 +7086,7 @@ build_template_field( /* If clustered index record field is not found, lets print out field names and all the rest to understand why field is not found. */ if (templ->clust_rec_field_no == ULINT_UNDEFINED) { - const char* tb_col_name = dict_table_get_col_name(clust_index->table, i); + const char* tb_col_name = dict_table_get_col_name(clust_index->table, i).str; dict_field_t* field=NULL; size_t size = 0; @@ -8118,8 +8094,7 @@ calc_row_difference( if (field_mysql_type == MYSQL_TYPE_LONGLONG && prebuilt->table->fts - && innobase_strcasecmp( - field->field_name.str, FTS_DOC_ID_COL_NAME) == 0) { + && field->field_name.streq(FTS_DOC_ID)) { doc_id = mach_read_uint64_little_endian(n_ptr); if (doc_id == 0) { return(DB_FTS_INVALID_DOCID); @@ -9178,7 +9153,7 @@ ha_innobase::change_active_index( if (m_prebuilt->read_just_key && bitmap_is_set(table->read_set, i) && !strcmp(table->s->field[i]->field_name.str, - FTS_DOC_ID_COL_NAME)) { + FTS_DOC_ID.str)) { m_prebuilt->fts_doc_id_in_read_set = true; break; } @@ -9667,7 +9642,7 @@ innobase_fts_create_doc_id_key( dict_field_t* field = dict_index_get_nth_field(index, 0); ut_a(field->col->mtype == DATA_INT); ut_ad(sizeof(*doc_id) == field->fixed_len); - ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME)); + ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX.str)); #endif /* UNIV_DEBUG */ /* Convert to storage byte order */ @@ -9965,7 +9940,8 @@ wsrep_append_foreign_key( int i = 0; while (idx != NULL && idx != idx_target) { - if (innobase_strcasecmp (idx->name, innobase_index_reserve_name) != 0) { + if (!Lex_ident_column(Lex_cstring_strlen(idx->name)). + streq(GEN_CLUST_INDEX)) { i++; } idx = UT_LIST_GET_NEXT(indexes, idx); @@ -10384,8 +10360,7 @@ create_table_check_doc_id_col( auto col_len = field->pack_length(); - if (innobase_strcasecmp(field->field_name.str, - FTS_DOC_ID_COL_NAME) == 0) { + if (field->field_name.streq(FTS_DOC_ID)) { /* Note the name is case sensitive due to our internal query parser */ @@ -10393,7 +10368,7 @@ create_table_check_doc_id_col( && !field->real_maybe_null() && col_len == sizeof(doc_id_t) && (strcmp(field->field_name.str, - FTS_DOC_ID_COL_NAME) == 0)) { + FTS_DOC_ID.str) == 0)) { *doc_id_col = i; } else { push_warning_printf( @@ -10472,9 +10447,9 @@ innodb_base_col_setup( ulint z; for (z = 0; z < table->n_cols; z++) { - const char* name = dict_table_get_col_name(table, z); - if (!innobase_strcasecmp(name, - base_field->field_name.str)) { + const Lex_cstring name = + dict_table_get_col_name(table, z); + if (base_field->field_name.streq(name)) { break; } } @@ -10510,10 +10485,9 @@ innodb_base_col_setup_for_stored( && bitmap_is_set(&field->table->tmp_set, i)) { ulint z; for (z = 0; z < table->n_cols; z++) { - const char* name = dict_table_get_col_name( - table, z); - if (!innobase_strcasecmp( - name, base_field->field_name.str)) { + const Lex_cstring name = + dict_table_get_col_name(table, z); + if (base_field->field_name.streq(name)) { break; } } @@ -10714,7 +10688,7 @@ err_col: /* First check whether the column to be added has a system reserved name. */ - if (dict_col_name_is_reserved(field->field_name.str)){ + if (dict_col_name_is_reserved(field->field_name)){ my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name.str); goto err_col; @@ -10879,7 +10853,7 @@ create_index( key = form->key_info + key_num; /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */ - ut_a(innobase_strcasecmp(key->name.str, innobase_index_reserve_name) != 0); + ut_a(!key->name.streq(GEN_CLUST_INDEX)); const ha_table_option_struct& o = *form->s->option_struct; if (key->flags & (HA_SPATIAL | HA_FULLTEXT)) { @@ -11563,7 +11537,7 @@ bool create_table_info_t::innobase_table_flags() } } - if (innobase_strcasecmp(key->name.str, FTS_DOC_ID_INDEX_NAME)) { + if (!key->name.streq(FTS_DOC_ID_INDEX)) { continue; } @@ -11571,9 +11545,9 @@ bool create_table_info_t::innobase_table_flags() if (!(key->flags & HA_NOSAME) || key->user_defined_key_parts != fts_n_uniq || (key->key_part[0].key_part_flag & HA_REVERSE_SORT) - || strcmp(key->name.str, FTS_DOC_ID_INDEX_NAME) + || strcmp(key->name.str, FTS_DOC_ID_INDEX.str) || strcmp(key->key_part[0].field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + FTS_DOC_ID.str)) { fts_doc_id_index_bad = key->name.str; } @@ -11868,6 +11842,7 @@ innobase_parse_hint_from_comment( continue; } + const Lex_cstring_strlen index_name(index->name); for (uint i = 0; i < table_share->keys; i++) { if (is_found[i]) { continue; @@ -11875,8 +11850,7 @@ innobase_parse_hint_from_comment( KEY* key_info = &table_share->key_info[i]; - if (innobase_strcasecmp( - index->name, key_info->name.str) == 0) { + if (key_info->name.streq(index_name)) { dict_index_set_merge_threshold( index, @@ -11911,6 +11885,7 @@ innobase_parse_hint_from_comment( continue; } + const Lex_cstring_strlen index_name(index->name); for (uint i = 0; i < table_share->keys; i++) { if (is_found[i]) { continue; @@ -11918,9 +11893,7 @@ innobase_parse_hint_from_comment( KEY* key_info = &table_share->key_info[i]; - if (innobase_strcasecmp( - index->name, key_info->name.str) == 0) { - + if (key_info->name.streq(index_name)) { /* x-lock index is needed to exclude concurrent pessimistic tree operations */ index->lock.x_lock(SRW_LOCK_CALL); @@ -12126,7 +12099,7 @@ foreign_push_index_error(trx_t* trx, const char* operation, col_name = field->col->is_virtual() ? "(null)" : dict_table_get_col_name( - table, dict_col_get_no(field->col)); + table, dict_col_get_no(field->col)).str; ib_foreign_warn( trx, DB_CANNOT_ADD_CONSTRAINT, create_name, "%s table %s with foreign key %s constraint" @@ -12148,24 +12121,27 @@ static bool find_col(dict_table_t* table, const char** name) { ulint i; + const Lex_ident_column outer_name = Lex_cstring_strlen(*name); for (i = 0; i < dict_table_get_n_cols(table); i++) { - const char* col_name = dict_table_get_col_name(table, i); + const Lex_ident_column inner_name = + dict_table_get_col_name(table, i); - if (0 == innobase_strcasecmp(col_name, *name)) { + if (outer_name.streq(inner_name)) { /* Found */ - strcpy((char*)*name, col_name); + strcpy((char*)*name, inner_name.str); return true; } } for (i = 0; i < dict_table_get_n_v_cols(table); i++) { - const char* col_name = dict_table_get_v_col_name(table, i); + const Lex_ident_column inner_name = + dict_table_get_v_col_name(table, i); - if (0 == innobase_strcasecmp(col_name, *name)) { + if (outer_name.streq(inner_name)) { /* Found */ - strcpy((char*)*name, col_name); + strcpy((char*)*name, inner_name.str); return true; } } @@ -12561,7 +12537,7 @@ create_table_info_t::create_foreign_keys() = dict_table_get_col_name( foreign->foreign_index ->table, - dict_col_get_no(col)); + dict_col_get_no(col)).str; /* It is not sensible to define SET NULL @@ -12689,7 +12665,7 @@ int create_table_info_t::create_table(bool create_fk) by InnoDB */ ulint flags = m_table->flags; dict_index_t* index = dict_mem_index_create( - m_table, innobase_index_reserve_name, + m_table, GEN_CLUST_INDEX.str, DICT_CLUSTERED, 0); const ha_table_option_struct& o = *m_form->s->option_struct; error = convert_error_code_to_mysql( @@ -12734,7 +12710,7 @@ int create_table_info_t::create_table(bool create_fk) " the index definition to" " make sure it is of correct" " type\n", - FTS_DOC_ID_INDEX_NAME, + FTS_DOC_ID_INDEX.str, m_table->name.m_name); if (m_table->fts) { @@ -12743,7 +12719,7 @@ int create_table_info_t::create_table(bool create_fk) } my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), - FTS_DOC_ID_INDEX_NAME); + FTS_DOC_ID_INDEX.str); DBUG_RETURN(-1); case FTS_EXIST_DOC_ID_INDEX: case FTS_NOT_EXIST_DOC_ID_INDEX: @@ -13087,10 +13063,10 @@ void create_table_info_t::create_table_update_dict(dict_table_t *table, { if (!table->fts_doc_id_index) table->fts_doc_id_index= - dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX_NAME); + dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX.str); else DBUG_ASSERT(table->fts_doc_id_index == - dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX_NAME)); + dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX.str)); } DBUG_ASSERT(!table->fts == !table->fts_doc_id_index); @@ -17622,6 +17598,7 @@ innodb_monitor_id_by_name_get( const char* name) /*!< in: monitor counter namer */ { ut_a(name); + const Lex_ident_column ident = Lex_cstring_strlen(name); /* Search for wild character '%' in the name, if found, we treat it as a wildcard match. We do not search for @@ -17634,8 +17611,8 @@ innodb_monitor_id_by_name_get( /* Not wildcard match, check for an exact match */ for (ulint i = 0; i < NUM_MONITOR; i++) { - if (!innobase_strcasecmp( - name, srv_mon_get_name(static_cast(i)))) { + if (ident.streq(Lex_cstring_strlen( + srv_mon_get_name(static_cast(i))))) { return(i); } } @@ -18059,8 +18036,7 @@ innobase_index_name_is_reserved( for (key_num = 0; key_num < num_of_keys; key_num++) { key = &key_info[key_num]; - if (innobase_strcasecmp(key->name.str, - innobase_index_reserve_name) == 0) { + if (key->name.streq(GEN_CLUST_INDEX)) { /* Push warning to mysql */ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -18069,10 +18045,10 @@ innobase_index_name_is_reserved( " '%s'. The name is reserved" " for the system default primary" " index.", - innobase_index_reserve_name); + GEN_CLUST_INDEX.str); my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), - innobase_index_reserve_name); + GEN_CLUST_INDEX.str); return(true); } diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index eb6960fac8e..245d501fbaf 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -25,10 +25,6 @@ this program; if not, write to the Free Software Foundation, Inc., /* The InnoDB handler: the interface between MySQL and InnoDB. */ -/** "GEN_CLUST_INDEX" is the name reserved for InnoDB default -system clustered index when there is no primary key. */ -extern const char innobase_index_reserve_name[]; - /** Prebuilt structures in an InnoDB table handle used within MySQL */ struct row_prebuilt_t; @@ -791,7 +787,7 @@ enum fts_doc_id_index_enum { }; /** -Check whether the table has a unique index with FTS_DOC_ID_INDEX_NAME +Check whether the table has a unique index with name FTS_DOC_ID_INDEX on the Doc ID column. @return the status of the FTS_DOC_ID index */ fts_doc_id_index_enum @@ -804,7 +800,7 @@ innobase_fts_check_doc_id_index( MY_ATTRIBUTE((warn_unused_result)); /** -Check whether the table has a unique index with FTS_DOC_ID_INDEX_NAME +Check whether the table has a unique index with name FTS_DOC_ID_INDEX on the Doc ID column in MySQL create index definition. @return FTS_EXIST_DOC_ID_INDEX if there exists the FTS_DOC_ID index, FTS_INCORRECT_DOC_ID_INDEX if the FTS_DOC_ID index is of wrong format */ diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index ba974a7a2f8..072e6d61af9 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -354,7 +354,7 @@ found_j: fields[i] = index.fields[j++]; DBUG_ASSERT(!fields[i].col->is_dropped()); DBUG_ASSERT(fields[i].name - == fields[i].col->name(*this)); + == fields[i].col->name(*this).str); if (fields[i].col->is_nullable()) { goto found_nullable; } @@ -397,7 +397,7 @@ found_j: n_nullable += fields[i].col->is_nullable(); DBUG_ASSERT(!fields[i].col->is_dropped()); DBUG_ASSERT(fields[i].name - == fields[i].col->name(*this)); + == fields[i].col->name(*this).str); } DBUG_ASSERT(j == index.n_fields); index.n_fields = index.n_def = n_fields @@ -471,7 +471,7 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant) f.name = NULL; } else { f.col = &table->cols[icol - instant.table->cols]; - f.name = f.col->name(*table); + f.name = f.col->name(*table).str; } } @@ -688,7 +688,7 @@ dup_dropped: f.col = &cols[col_map[f.col - old_cols]]; DBUG_ASSERT(!f.col->is_virtual()); } - f.name = f.col->name(*this); + f.name = f.col->name(*this).str; if (f.col->is_virtual()) { dict_v_col_t* v_col = reinterpret_cast (f.col); @@ -840,7 +840,7 @@ inline void dict_table_t::rollback_instant( f.col = &cols[old_col_no]; DBUG_ASSERT(!f.col->is_virtual()); } - f.name = f.col->name(*this); + f.name = f.col->name(*this).str; } } } @@ -948,7 +948,7 @@ get_error_key_name( const dict_table_t* table) { if (error_key_num == ULINT_UNDEFINED) { - return(FTS_DOC_ID_INDEX_NAME); + return(FTS_DOC_ID_INDEX.str); } else if (ha_alter_info->key_count == 0) { return(dict_table_get_first_index(table)->name); } else { @@ -1394,8 +1394,7 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx { const Field *altered_field= altered_table.field[j]; - if (my_strcasecmp(system_charset_info, field_name, - altered_field->field_name.str)) + if (!altered_field->field_name.streq(Lex_cstring_strlen(field_name))) continue; unsigned prtype; @@ -1647,9 +1646,7 @@ check_v_col_in_order( continue; } - if (my_strcasecmp(system_charset_info, - field->field_name.str, - new_field->field_name.str) != 0) { + if (!field->field_name.streq(new_field->field_name)) { /* different column */ return(false); } else { @@ -2055,12 +2052,11 @@ innobase_fts_check_doc_id_col( (*num_v)++; } - if (my_strcasecmp(system_charset_info, - field->field_name.str, FTS_DOC_ID_COL_NAME)) { + if (!field->field_name.streq(FTS_DOC_ID)) { continue; } - if (strcmp(field->field_name.str, FTS_DOC_ID_COL_NAME)) { + if (strcmp(field->field_name.str, FTS_DOC_ID.str)) { err = ER_WRONG_COLUMN_NAME; } else if (field->type() != MYSQL_TYPE_LONGLONG || field->pack_length() != 8 @@ -2087,9 +2083,9 @@ innobase_fts_check_doc_id_col( i -= *num_v; for (; i + DATA_N_SYS_COLS < (uint) table->n_cols; i++) { - const char* name = dict_table_get_col_name(table, i); + const char* name = dict_table_get_col_name(table, i).str; - if (strcmp(name, FTS_DOC_ID_COL_NAME) == 0) { + if (strcmp(name, FTS_DOC_ID.str) == 0) { #ifdef UNIV_DEBUG const dict_col_t* col; @@ -2492,10 +2488,8 @@ innodb_instant_alter_column_allowed_reason: /* We cannot replace a hidden FTS_DOC_ID with a user-visible FTS_DOC_ID. */ if (fulltext_indexes && m_prebuilt->table->fts - && !my_strcasecmp( - system_charset_info, - key_part->field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + && key_part->field->field_name. + streq(FTS_DOC_ID)) { ha_alter_info->unsupported_reason = my_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); @@ -2561,10 +2555,8 @@ innodb_instant_alter_column_allowed_reason: /* Disallow DROP INDEX FTS_DOC_ID_INDEX */ for (uint i = 0; i < ha_alter_info->index_drop_count; i++) { - if (!my_strcasecmp( - system_charset_info, - ha_alter_info->index_drop_buffer[i]->name.str, - FTS_DOC_ID_INDEX_NAME)) { + if (ha_alter_info->index_drop_buffer[i]->name.streq( + FTS_DOC_ID_INDEX)) { ha_alter_info->unsupported_reason = my_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); @@ -2581,10 +2573,7 @@ innodb_instant_alter_column_allowed_reason: continue; } - if (!my_strcasecmp( - system_charset_info, - (*fp)->field_name.str, - FTS_DOC_ID_COL_NAME)) { + if ((*fp)->field_name.streq(FTS_DOC_ID)) { ha_alter_info->unsupported_reason = my_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); @@ -2650,9 +2639,7 @@ innodb_instant_alter_column_allowed_reason: } else if (!is_non_const_value(*af) && set_default_value(*af)) { if (fulltext_indexes > 1 - && !my_strcasecmp(system_charset_info, - (*af)->field_name.str, - FTS_DOC_ID_COL_NAME)) { + && (*af)->field_name.streq(FTS_DOC_ID)) { /* If a hidden FTS_DOC_ID column exists (because of FULLTEXT INDEX), it cannot be replaced with a user-created one @@ -3063,8 +3050,8 @@ no_match: goto no_match; } - if (innobase_strcasecmp(col_names[j], - key_part.field->field_name.str)) { + if (!key_part.field->field_name. + streq(Lex_cstring_strlen(col_names[j]))) { /* Name mismatch */ goto no_match; } @@ -3129,7 +3116,7 @@ innobase_col_check_fk( for (it = s_cols->begin(); it != s_cols->end(); ++it) { for (ulint j = it->num_base; j--; ) { if (!strcmp(col_name, dict_table_get_col_name( - table, it->base_col[j]->ind))) { + table, it->base_col[j]->ind).str)) { return(true); } } @@ -3974,8 +3961,7 @@ innobase_fts_check_doc_id_index( for (uint i = 0; i < altered_table->s->keys; i++) { const KEY& key = altered_table->key_info[i]; - if (innobase_strcasecmp( - key.name.str, FTS_DOC_ID_INDEX_NAME)) { + if (!key.name.streq(FTS_DOC_ID_INDEX)) { continue; } @@ -3983,9 +3969,9 @@ innobase_fts_check_doc_id_index( && key.user_defined_key_parts == fts_n_uniq && !(key.key_part[0].key_part_flag & HA_REVERSE_SORT) - && !strcmp(key.name.str, FTS_DOC_ID_INDEX_NAME) + && !strcmp(key.name.str, FTS_DOC_ID_INDEX.str) && !strcmp(key.key_part[0].field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + FTS_DOC_ID.str)) { if (fts_doc_col_no) { *fts_doc_col_no = ULINT_UNDEFINED; } @@ -4006,14 +3992,15 @@ innobase_fts_check_doc_id_index( /* Check if there exists a unique index with the name of FTS_DOC_ID_INDEX_NAME and ignore the corrupted index */ + const Lex_ident_column index_name = Lex_cstring_strlen(index->name); if (index->type & DICT_CORRUPT - || innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) { + || !index_name.streq(FTS_DOC_ID_INDEX)) { continue; } if (!dict_index_is_unique(index) || dict_index_get_n_unique(index) != table->fts_n_uniq() - || strcmp(index->name, FTS_DOC_ID_INDEX_NAME)) { + || strcmp(index->name, FTS_DOC_ID_INDEX.str)) { return(FTS_INCORRECT_DOC_ID_INDEX); } @@ -4022,7 +4009,7 @@ innobase_fts_check_doc_id_index( field = dict_index_get_nth_field(index, 0); /* The column would be of a BIGINT data type */ - if (strcmp(field->name, FTS_DOC_ID_COL_NAME) == 0 + if (strcmp(field->name, FTS_DOC_ID.str) == 0 && !field->descending && field->col->mtype == DATA_INT && field->col->len == 8 @@ -4058,7 +4045,7 @@ innobase_fts_check_doc_id_index_in_def( for (ulint j = 0; j < n_key; j++) { const KEY* key = &key_info[j]; - if (innobase_strcasecmp(key->name.str, FTS_DOC_ID_INDEX_NAME)) { + if (!key->name.streq(FTS_DOC_ID_INDEX)) { continue; } @@ -4067,9 +4054,9 @@ innobase_fts_check_doc_id_index_in_def( if (!(key->flags & HA_NOSAME) || key->user_defined_key_parts != fts_n_uniq || (key->key_part[0].key_part_flag & HA_REVERSE_SORT) - || strcmp(key->name.str, FTS_DOC_ID_INDEX_NAME) + || strcmp(key->name.str, FTS_DOC_ID_INDEX.str) || strcmp(key->key_part[0].field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + FTS_DOC_ID.str)) { return(FTS_INCORRECT_DOC_ID_INDEX); } @@ -4132,8 +4119,8 @@ ha_innobase_inplace_ctx::create_key_defs( defined for the innodb_table. */ new_primary = n_add > 0 - && !my_strcasecmp(system_charset_info, - key_info[*add].name.str, "PRIMARY"); + && Lex_ident_column(key_info[*add].name). + streq("PRIMARY"_LEX_CSTRING); n_fts_add = 0; /* If there is a UNIQUE INDEX consisting entirely of NOT NULL @@ -4174,7 +4161,7 @@ ha_innobase_inplace_ctx::create_key_defs( index->fields = NULL; index->n_fields = 0; index->ind_type = DICT_CLUSTERED; - index->name = innobase_index_reserve_name; + index->name = GEN_CLUST_INDEX.str; index->rebuild = true; index->key_number = ~0U; primary_key_number = ULINT_UNDEFINED; @@ -4281,7 +4268,7 @@ created_clustered: || !add_fts_doc_id || fts_doc_id_col <= altered_table->s->fields); - index->name = FTS_DOC_ID_INDEX_NAME; + index->name = FTS_DOC_ID_INDEX.str; index->rebuild = rebuild; /* TODO: assign a real MySQL key number for this */ @@ -4726,8 +4713,8 @@ found_col: DICT_TF2_FTS_HAS_DOC_ID)); DBUG_ASSERT(i + DATA_N_SYS_COLS + 1 == old_table->n_cols); DBUG_ASSERT(!strcmp(dict_table_get_col_name( - old_table, i), - FTS_DOC_ID_COL_NAME)); + old_table, i).str, + FTS_DOC_ID.str)); if (altered_table->s->fields + DATA_N_SYS_COLS - new_table->n_v_cols < new_table->n_cols) { @@ -4813,7 +4800,7 @@ innobase_get_col_names( /* Copy the internal column names. */ i = table->s->fields - user_table->n_v_def; - cols[i] = dict_table_get_col_name(user_table, i); + cols[i] = dict_table_get_col_name(user_table, i).str; while (++i < user_table->n_def) { cols[i] = cols[i - 1] + strlen(cols[i - 1]) + 1; @@ -5101,7 +5088,7 @@ innobase_check_gis_columns( ulint col_nr = dict_table_has_column( table, - key_part.field->field_name.str, + key_part.field->field_name, key_part.fieldnr); ut_ad(col_nr != table->n_def); dict_col_t* col = &table->cols[col_nr]; @@ -5112,7 +5099,7 @@ innobase_check_gis_columns( } const char* col_name = dict_table_get_col_name( - table, col_nr); + table, col_nr).str; if (innobase_update_gis_column_type( table->id, col_name, trx)) { @@ -5941,7 +5928,7 @@ static bool innobase_instant_try( DBUG_ASSERT(!col->is_dropped()); DBUG_ASSERT(col->mtype != DATA_SYS); DBUG_ASSERT(!strcmp((*af)->field_name.str, - dict_table_get_col_name(user_table, i))); + dict_table_get_col_name(user_table, i).str)); DBUG_ASSERT(old || col->is_added()); ut_d(const Create_field* new_field = cf_it++); @@ -6025,7 +6012,7 @@ add_all_virtual: for (uint i = 0; i < user_table->n_v_cols; i++) { if (innobase_add_one_virtual( user_table, - dict_table_get_v_col_name(user_table, i), + dict_table_get_v_col_name(user_table, i).str, &user_table->v_cols[i], trx)) { return true; } @@ -6054,8 +6041,8 @@ add_all_virtual: DBUG_ASSERT(i <= altered_table->s->stored_fields + 1); if (i > altered_table->s->fields) { const dict_col_t& fts_doc_id = user_table->cols[i - 1]; - DBUG_ASSERT(!strcmp(fts_doc_id.name(*user_table), - FTS_DOC_ID_COL_NAME)); + DBUG_ASSERT(!strcmp(fts_doc_id.name(*user_table).str, + FTS_DOC_ID.str)); DBUG_ASSERT(!fts_doc_id.is_nullable()); DBUG_ASSERT(fts_doc_id.len == 8); dfield_set_data(dtuple_get_nth_field(row, i - 1), @@ -6744,7 +6731,7 @@ new_clustered_failed: } - if (dict_col_name_is_reserved(field->field_name.str)) { + if (dict_col_name_is_reserved(field->field_name)) { wrong_column_name: dict_mem_table_free(ctx->new_table); ctx->new_table = ctx->old_table; @@ -6757,13 +6744,12 @@ wrong_column_name: to internal query parser. FTS_DOC_ID column must be of BIGINT NOT NULL type and it should be in all capitalized characters */ - if (!innobase_strcasecmp(field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + if (field->field_name.streq(FTS_DOC_ID)) { if (col_type != DATA_INT || field->real_maybe_null() || col_len != sizeof(doc_id_t) || strcmp(field->field_name.str, - FTS_DOC_ID_COL_NAME)) { + FTS_DOC_ID.str)) { goto wrong_column_name; } } @@ -6947,7 +6933,7 @@ wrong_column_name: ctx->new_table, i); DBUG_ASSERT(!strcmp((*af)->field_name.str, dict_table_get_col_name(ctx->new_table, - i))); + i).str)); DBUG_ASSERT(!col->is_added()); if (new_field.field) { @@ -7017,8 +7003,8 @@ wrong_column_name: || (1 + DATA_N_SYS_COLS + i == ctx->new_table->n_cols && !strcmp(dict_table_get_col_name( - ctx->new_table, i), - FTS_DOC_ID_COL_NAME))); + ctx->new_table, i).str, + FTS_DOC_ID.str))); if (altered_table->found_next_number_field) { ctx->new_table->persistent_autoinc @@ -7313,7 +7299,7 @@ error_handling_drop_uncached: commit_cache_norebuild(). */ ctx->new_table->fts_doc_id_index = dict_table_get_index_on_name( - ctx->new_table, FTS_DOC_ID_INDEX_NAME); + ctx->new_table, FTS_DOC_ID_INDEX.str); DBUG_ASSERT(ctx->new_table->fts_doc_id_index != NULL); } @@ -8005,9 +7991,7 @@ err_exit_no_heap: check_if_ok_to_rename: /* Prohibit renaming a column from FTS_DOC_ID if full-text indexes exist. */ - if (!my_strcasecmp(system_charset_info, - (*fp)->field_name.str, - FTS_DOC_ID_COL_NAME) + if ((*fp)->field_name.streq(FTS_DOC_ID) && innobase_fulltext_exist(altered_table)) { my_error(ER_INNODB_FT_WRONG_DOCID_COLUMN, MYF(0), name); @@ -8027,8 +8011,8 @@ check_if_ok_to_rename: } for (; j < m_prebuilt->table->n_def; j++) { - if (!my_strcasecmp( - system_charset_info, name, s)) { + if (Lex_ident_column(Lex_cstring_strlen(name)). + streq(Lex_cstring_strlen(s))) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), s); goto err_exit_no_heap; @@ -8184,14 +8168,14 @@ check_if_ok_to_rename: to the full constraint name. */ fid = fid ? fid + 1 : foreign->id; - if (!my_strcasecmp(system_charset_info, - fid, drop.name)) { + if (Lex_ident_column(Lex_cstring_strlen(fid)). + streq(drop.name)) { goto found_fk; } } my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), - drop.type_name(), drop.name); + drop.type_name(), drop.name.str); goto err_exit; found_fk: for (ulint i = n_drop_fk; i--; ) { @@ -8269,10 +8253,8 @@ dup_fk: DBUG_ASSERT(!fts_doc_index->to_be_dropped); for (uint i = 0; i < table->s->keys; i++) { - if (!my_strcasecmp( - system_charset_info, - FTS_DOC_ID_INDEX_NAME, - table->key_info[i].name.str)) { + if (table->key_info[i].name. + streq(FTS_DOC_ID_INDEX)) { /* The index exists in the MySQL data dictionary. Do not drop it, even though it is no longer needed @@ -8566,7 +8548,7 @@ success: break; case FTS_INCORRECT_DOC_ID_INDEX: my_error(ER_INNODB_FT_WRONG_DOCID_INDEX, MYF(0), - FTS_DOC_ID_INDEX_NAME); + FTS_DOC_ID_INDEX.str); goto err_exit; case FTS_EXIST_DOC_ID_INDEX: DBUG_ASSERT( @@ -9334,8 +9316,9 @@ innobase_rename_column_try( const dict_field_t& f = index->fields[i]; DBUG_ASSERT(!f.name == f.col->is_dropped()); - if (!f.name || my_strcasecmp(system_charset_info, - f.name, from)) { + if (!f.name || + !Lex_ident_column(Lex_cstring_strlen(f.name)). + streq(Lex_cstring_strlen(from))) { continue; } @@ -9420,9 +9403,9 @@ rename_foreign: foreign_modified = false; for (unsigned i = 0; i < foreign->n_fields; i++) { - if (my_strcasecmp(system_charset_info, - foreign->foreign_col_names[i], - from)) { + if (!Lex_ident_column( + Lex_cstring_strlen(foreign->foreign_col_names[i])). + streq(Lex_cstring_strlen(from))) { continue; } @@ -9469,9 +9452,9 @@ rename_foreign: dict_foreign_t* foreign = *it; for (unsigned i = 0; i < foreign->n_fields; i++) { - if (my_strcasecmp(system_charset_info, - foreign->referenced_col_names[i], - from)) { + if (!Lex_ident_column( + Lex_cstring_strlen(foreign->referenced_col_names[i])). + streq(Lex_cstring_strlen(from))) { continue; } @@ -9640,7 +9623,7 @@ innobase_rename_or_enlarge_column_try( } #endif /* UNIV_DEBUG */ - const char* col_name = col->name(*user_table); + const char* col_name = col->name(*user_table).str; const bool same_name = !strcmp(col_name, f.field_name.str); if (!same_name @@ -9773,8 +9756,8 @@ innobase_rename_or_enlarge_columns_cache( if ((*fp)->flags & FIELD_IS_RENAMED) { dict_mem_table_col_rename( user_table, col_n, - cf.field->field_name.str, - (*af)->field_name.str, is_virtual); + cf.field->field_name, + (*af)->field_name, is_virtual); } break; @@ -9832,7 +9815,7 @@ commit_set_autoinc( It must be persisted to the data file. */ const Field* ai = old_table->found_next_number_field; ut_ad(!strcmp(dict_table_get_col_name(ctx->old_table, - innodb_col_no(ai)), + innodb_col_no(ai)).str, ai->field_name.str)); ib_uint64_t autoinc @@ -10972,7 +10955,7 @@ commit_cache_norebuild( ctx->new_table->fts_doc_id_index = ctx->new_table->fts ? dict_table_get_index_on_name( - ctx->new_table, FTS_DOC_ID_INDEX_NAME) + ctx->new_table, FTS_DOC_ID_INDEX.str) : NULL; DBUG_ASSERT((ctx->new_table->fts == NULL) == (ctx->new_table->fts_doc_id_index == NULL)); diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 3513f21b5ec..7832d6ea995 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -309,7 +309,7 @@ TRUE. ibool dict_col_name_is_reserved( /*======================*/ - const char* name) /*!< in: column name */ + const LEX_CSTRING &name) /*!< in: column name */ MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Unconditionally set the AUTO_INCREMENT counter. @param[in,out] table table or partition @@ -521,7 +521,7 @@ dict_foreign_find_index( @param[in] table table object @param[in] col_nr virtual column number(nth virtual column) @return column name. */ -const char* +Lex_ident_column dict_table_get_v_col_name( const dict_table_t* table, ulint col_nr); @@ -535,7 +535,7 @@ otherwise table->n_def */ ulint dict_table_has_column( const dict_table_t* table, - const char* col_name, + const LEX_CSTRING &col_name, ulint col_nr = 0); /**********************************************************************//** @@ -764,7 +764,7 @@ dict_table_get_sys_col( @param[in] col_nr column number in table @return column name */ inline -const char* +Lex_ident_column dict_table_get_col_name(const dict_table_t* table, ulint col_nr) { return(dict_table_get_nth_col(table, col_nr)->name(*table)); diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 37d6fb3c8a5..5e8aeeda3b2 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -48,6 +48,7 @@ Created 1/8/1996 Heikki Tuuri #include "fil0fil.h" #include "fil0crypt.h" #include "mysql_com.h" +#include "lex_ident.h" #include #include #include @@ -357,8 +358,8 @@ dict_mem_table_col_rename( /*======================*/ dict_table_t* table, /*!< in/out: table */ ulint nth_col,/*!< in: column index */ - const char* from, /*!< in: old column name */ - const char* to, /*!< in: new column name */ + const LEX_CSTRING &from,/*!< in: old column name */ + const LEX_CSTRING &to, /*!< in: new column name */ bool is_virtual); /*!< in: if this is a virtual column */ /**********************************************************************//** @@ -549,7 +550,7 @@ public: /** Retrieve the column name. @param table the table of this column */ - const char *name(const dict_table_t &table) const; + Lex_ident_column name(const dict_table_t &table) const; /** @return whether this is a virtual column */ bool is_virtual() const { return prtype & DATA_VIRTUAL; } @@ -927,7 +928,8 @@ struct zip_pad_info_t { /** "GEN_CLUST_INDEX" is the name reserved for InnoDB default system clustered index when there is no primary key. */ -const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX"; +static constexpr +Lex_cstring GEN_CLUST_INDEX = "GEN_CLUST_INDEX"_LEX_CSTRING; /** Data structure for an index. Most fields will be initialized to 0, NULL or FALSE in dict_mem_index_create(). */ @@ -1585,11 +1587,12 @@ struct dict_foreign_matches_id { bool operator()(const dict_foreign_t* foreign) const { - if (0 == innobase_strcasecmp(foreign->id, m_id)) { + const Lex_ident_column ident = Lex_cstring_strlen(m_id); + if (ident.streq(Lex_cstring_strlen(foreign->id))) { return(true); } if (const char* pos = strchr(foreign->id, '/')) { - if (0 == innobase_strcasecmp(m_id, pos + 1)) { + if (ident.streq(Lex_cstring_strlen(pos + 1))) { return(true); } } @@ -2150,6 +2153,13 @@ public: /** Instantly dropped or reordered columns, or NULL if none */ dict_instant_t* instant; + /** Retrieve a column name from a 0-separated list + @param str the list in the format "name1\0name2\0...nameN\0" + @param col_nr the position + */ + static Lex_ident_column get_name_from_z_list(const char *str, + size_t col_nr); + /** Column names packed in a character string "name1\0name2\0...nameN\0". Until the string contains n_cols, it will be allocated from a temporary heap. The final string will be allocated diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 9dbc3235255..e873d703313 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -38,17 +38,16 @@ Created 2011/09/02 Sunny Bains #include "que0types.h" #include "ft_global.h" #include "mysql/plugin_ftparser.h" +#include "lex_string.h" /** "NULL" value of a document id. */ #define FTS_NULL_DOC_ID 0 /** FTS hidden column that is used to map to and from the row */ -#define FTS_DOC_ID_COL_NAME "FTS_DOC_ID" +static constexpr Lex_cstring FTS_DOC_ID= "FTS_DOC_ID"_LEX_CSTRING; /** The name of the index created by FTS */ -#define FTS_DOC_ID_INDEX_NAME "FTS_DOC_ID_INDEX" - -#define FTS_DOC_ID_INDEX_NAME_LEN 16 +static constexpr Lex_cstring FTS_DOC_ID_INDEX= "FTS_DOC_ID_INDEX"_LEX_CSTRING; /** Doc ID is a 8 byte value */ #define FTS_DOC_ID_LEN 8 diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 3c693a1cac5..7f9c209ca6a 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -139,15 +139,6 @@ at least ENUM and SET, and unsigned integer types are 'unsigned types' uint8_t get_innobase_type_from_mysql_type(unsigned *unsigned_flag, const Field *field); -/******************************************************************//** -Compares NUL-terminated UTF-8 strings case insensitively. -@return 0 if a=b, <0 if a1 if a>b */ -int -innobase_strcasecmp( -/*================*/ - const char* a, /*!< in: first string to compare */ - const char* b); /*!< in: second string to compare */ - /** Strip dir name from a full path name and return only the file name @param[in] path_name full path name @return file name or "null" if no file name */ diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 51bcc9540fc..a800f072b0e 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -703,11 +703,11 @@ pars_resolve_exp_columns( for (i = 0; i < n_cols; i++) { const dict_col_t* col = dict_table_get_nth_col(table, i); - const char* col_name + const Lex_ident_column col_name = dict_table_get_col_name(table, i); - if (sym_node->name_len == strlen(col_name) - && !memcmp(sym_node->name, col_name, + if (sym_node->name_len == col_name.length + && !memcmp(sym_node->name, col_name.str, sym_node->name_len)) { /* Found */ sym_node->resolved = TRUE; @@ -822,12 +822,12 @@ pars_select_all_columns( table = table_node->table; for (i = 0; i < dict_table_get_n_user_cols(table); i++) { - const char* col_name = dict_table_get_col_name( + const Lex_ident_column col_name = dict_table_get_col_name( table, i); col_node = sym_tab_add_id(pars_sym_tab_global, - (byte*) col_name, - strlen(col_name)); + (byte*) col_name.str, + col_name.length); select_node->select_list = que_node_list_add_last( select_node->select_list, col_node); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index d3c8839e500..c1bc4a008d1 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1210,7 +1210,7 @@ row_import::match_table_columns( ulint cfg_col_index; col_name = dict_table_get_col_name( - m_table, dict_col_get_no(col)); + m_table, dict_col_get_no(col)).str; cfg_col_index = find_col(col_name); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 770675c5e43..4fc2c3f8603 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1865,8 +1865,9 @@ bool row_ins_foreign_index_entry(dict_foreign_t *foreign, if (col->is_dropped()) continue; - const char *col_name= dict_table_get_col_name(index->table, col->ind); - if (0 == innobase_strcasecmp(col_name, foreign->foreign_col_names[i])) + const Lex_ident_column col_name= + dict_table_get_col_name(index->table, col->ind); + if (col_name.streq(Lex_cstring_strlen(foreign->foreign_col_names[i]))) { dfield_copy(&ref_entry->fields[i], &entry->fields[j]); goto got_match; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index f95e97fb6b5..8f43de5f88d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4544,10 +4544,10 @@ row_merge_create_index( n_add_vcol++; } else { name = dict_table_get_v_col_name( - table, ifield->col_no); + table, ifield->col_no).str; } } else { - name = dict_table_get_col_name(table, ifield->col_no); + name = dict_table_get_col_name(table, ifield->col_no).str; } dict_mem_index_add_field(index, name, ifield->prefix_len, diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index f28953f5bb6..120864f166e 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -278,12 +278,10 @@ row_quiesce_write_table( /* Write out the column name as [len, byte array]. The len includes the NUL byte. */ ib_uint32_t len; - const char* col_name; - - col_name = dict_table_get_col_name(table, dict_col_get_no(col)); + const Lex_ident_column col_name = dict_table_get_col_name(table, dict_col_get_no(col)); /* Include the NUL byte in the length. */ - len = static_cast(strlen(col_name) + 1); + len = static_cast(col_name.length + 1); ut_a(len > 1); mach_write_to_4(row, len); @@ -292,7 +290,7 @@ row_quiesce_write_table( close(fileno(file));); if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(col_name, 1, len, file) != len) { + || fwrite(col_name.str, 1, len, file) != len) { ib_senderrf( thd, IB_LOG_LEVEL_WARN, ER_IO_WRITE_ERROR, diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 44fd09e74ed..10b99f9ccf0 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -1936,7 +1936,9 @@ static int mrn_init(void *p) MY_MUTEX_INIT_FAST) != 0)) { goto err_allocated_thds_mutex_init; } - if (mrn_my_hash_init(&mrn_allocated_thds, system_charset_info, 32, 0, 0, + if (mrn_my_hash_init(&mrn_allocated_thds, + &my_charset_bin, + 32, 0, 0, mrn_allocated_thds_get_key, 0, 0)) { goto error_allocated_thds_hash_init; } @@ -1945,7 +1947,9 @@ static int mrn_init(void *p) MY_MUTEX_INIT_FAST) != 0)) { goto err_allocated_open_tables_mutex_init; } - if (mrn_my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0, + if (mrn_my_hash_init(&mrn_open_tables, + Lex_ident_table::charset_info(), + 32, 0, 0, mrn_open_tables_get_key, 0, 0)) { goto error_allocated_open_tables_hash_init; } @@ -1954,7 +1958,9 @@ static int mrn_init(void *p) MY_MUTEX_INIT_FAST) != 0)) { goto error_allocated_long_term_share_mutex_init; } - if (mrn_my_hash_init(&mrn_long_term_share, system_charset_info, 32, 0, 0, + if (mrn_my_hash_init(&mrn_long_term_share, + Lex_ident_table::charset_info(), + 32, 0, 0, mrn_long_term_share_get_key, 0, 0)) { goto error_allocated_long_term_share_hash_init; } diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index c6d2f23d653..b1e3b65fb3e 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -50,23 +50,16 @@ static handler* pfs_create_handler(handlerton *hton, return new (mem_root) ha_perfschema(hton, table); } -static int compare_database_names(const char *name1, const char *name2) -{ - if (lower_case_table_names) - return strcasecmp(name1, name2); - return strcmp(name1, name2); -} - static const PFS_engine_table_share* -find_table_share(const char *db, const char *name) +find_table_share(const PFS_ident_db &db, const PFS_ident_table &name) { DBUG_ENTER("find_table_share"); - if (compare_database_names(db, PERFORMANCE_SCHEMA_str.str) != 0) + if (!db.streq(PERFORMANCE_SCHEMA_str)) DBUG_RETURN(NULL); const PFS_engine_table_share* result; - result= PFS_engine_table::find_engine_table_share(name); + result= PFS_engine_table::find_engine_table_share(name.str); DBUG_RETURN(result); } @@ -74,7 +67,8 @@ static int pfs_discover_table(handlerton *hton, THD *thd, TABLE_SHARE *share) { const PFS_engine_table_share *pfs_share; - if ((pfs_share= find_table_share(share->db.str, share->table_name.str))) + if ((pfs_share= find_table_share(PFS_ident_db(share->db), + PFS_ident_table(share->table_name)))) return share->init_from_sql_statement_string(thd, false, pfs_share->sql.str, pfs_share->sql.length); @@ -84,7 +78,9 @@ static int pfs_discover_table(handlerton *hton, THD *thd, TABLE_SHARE *share) static int pfs_discover_table_existence(handlerton *hton, const char *db, const char *table_name) { - return MY_TEST(find_table_share(db, table_name)); + return MY_TEST(find_table_share( + PFS_ident_db(Lex_cstring_strlen(db)), + PFS_ident_table(Lex_cstring_strlen(table_name)))); } static int pfs_init_func(void *p) @@ -244,8 +240,8 @@ int ha_perfschema::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_perfschema::open"); - m_table_share= find_table_share(table_share->db.str, - table_share->table_name.str); + m_table_share= find_table_share(PFS_ident_db(table_share->db), + PFS_ident_table(table_share->table_name)); if (! m_table_share) DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); @@ -479,7 +475,8 @@ int ha_perfschema::delete_table(const char *name) db_name = ptr + 1; - share = find_table_share(db_name, table_name); + share = find_table_share(PFS_ident_db(Lex_cstring_strlen(db_name)), + PFS_ident_table(Lex_cstring_strlen(table_name))); if (share != NULL) { if (share->m_optional) { /* diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index e1356f837ba..6a73f75f582 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -394,27 +394,6 @@ int PFS_engine_table_share::write_row(TABLE *table, const unsigned char *buf, return result; } -static int compare_table_names(const char *name1, const char *name2) -{ - /* - The performance schema is implemented as a storage engine, in memory. - The current storage engine interface exposed by the server, - and in particular handlerton::discover, uses 'FRM' files to describe a - table structure, which are later stored on disk, by the server, - in ha_create_table_from_engine(). - Because the table metadata is stored on disk, the table naming rules - used by the performance schema then have to comply with the constraints - imposed by the disk storage, and in particular with lower_case_table_names. - Once the server is changed to be able to discover a table in a storage engine - and then open the table without storing a FRM file on disk, this constraint - on the performance schema will be lifted, and the naming logic can be relaxed - to be simply my_strcasecmp(system_charset_info, name1, name2). - */ - if (lower_case_table_names) - return strcasecmp(name1, name2); - return strcmp(name1, name2); -} - /** Find a table share by name. @param name The table name @@ -427,9 +406,10 @@ PFS_engine_table::find_engine_table_share(const char *name) PFS_engine_table_share **current; + PFS_ident_table table_name= Lex_cstring_strlen(name); for (current= &all_shares[0]; (*current) != NULL; current++) { - if (compare_table_names(name, (*current)->m_name.str) == 0) + if (table_name.streq((*current)->m_name)) DBUG_RETURN(*current); } @@ -1964,7 +1944,7 @@ int pfs_discover_table_names(handlerton *hton __attribute__((unused)), MY_DIR *dir __attribute__((unused)), handlerton::discovered_list *result) { - if (compare_table_names(db->str, PERFORMANCE_SCHEMA_str.str)) + if (!PFS_ident_db(*db).streq(PERFORMANCE_SCHEMA_str)) return 0; for (size_t i= 0; i < array_elements(all_shares) - 1; i++) result->add_table(all_shares[i]->m_name.str, diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h index 1ef1e0282de..389d9a56480 100644 --- a/storage/perfschema/pfs_engine_table.h +++ b/storage/perfschema/pfs_engine_table.h @@ -25,6 +25,22 @@ #include "table.h" #include "sql_acl.h" + +/* + The performance schema is implemented as a storage engine, in memory. + The current storage engine interface exposed by the server, + and in particular handlerton::discover, uses 'FRM' files to describe a + table structure, which are later stored on disk, by the server, + in ha_create_table_from_engine(). + Because the table metadata is stored on disk, the table naming rules + used by the performance schema then have to comply with the constraints + imposed by the disk storage, and in particular with lower_case_table_names. +*/ + +using PFS_ident_db= Lex_ident_i_s_db; +using PFS_ident_table = Lex_ident_i_s_table; + + /** @file storage/perfschema/pfs_engine_table.h Performance schema tables (declarations). @@ -304,7 +320,7 @@ struct PFS_engine_table_share int write_row(TABLE *table, const unsigned char *buf, Field **fields) const; /** Table name. */ - LEX_STRING m_name; + Lex_ident_table m_name; /** Table ACL. */ const ACL_internal_table_access *m_acl; /** Open table function. */ diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc index 258c2153d24..d5402547148 100644 --- a/storage/perfschema/pfs_server.cc +++ b/storage/perfschema/pfs_server.cc @@ -390,43 +390,43 @@ void cleanup_instrument_config() @return 0 for success, non zero for errors */ -int add_pfs_instr_to_array(const char* name, const char* value) +int add_pfs_instr_to_array(const LEX_CSTRING &name, + const LEX_CSTRING &value_arg) { - size_t name_length= strlen(name); - size_t value_length= strlen(value); + Lex_ident_ci value(value_arg); /* Allocate structure plus string buffers plus null terminators */ PFS_instr_config* e = (PFS_instr_config*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(PFS_instr_config) - + name_length + 1 + value_length + 1, MYF(MY_WME)); + + name.length + 1 + value.length + 1, MYF(MY_WME)); if (!e) return 1; /* Copy the instrument name */ e->m_name= (char*)e + sizeof(PFS_instr_config); - memcpy(e->m_name, name, name_length); - e->m_name_length= (uint)name_length; - e->m_name[name_length]= '\0'; + memcpy(e->m_name, name.str, name.length); + e->m_name_length= (uint) name.length; + e->m_name[name.length]= '\0'; /* Set flags accordingly */ - if (!my_strcasecmp(&my_charset_latin1, value, "counted")) + if (value.streq("counted"_LEX_CSTRING)) { e->m_enabled= true; e->m_timed= false; } else - if (!my_strcasecmp(&my_charset_latin1, value, "true") || - !my_strcasecmp(&my_charset_latin1, value, "on") || - !my_strcasecmp(&my_charset_latin1, value, "1") || - !my_strcasecmp(&my_charset_latin1, value, "yes")) + if (value.streq("true"_LEX_CSTRING) || + value.streq("on"_LEX_CSTRING) || + value.streq("1"_LEX_CSTRING) || + value.streq("yes"_LEX_CSTRING)) { e->m_enabled= true; e->m_timed= true; } else - if (!my_strcasecmp(&my_charset_latin1, value, "false") || - !my_strcasecmp(&my_charset_latin1, value, "off") || - !my_strcasecmp(&my_charset_latin1, value, "0") || - !my_strcasecmp(&my_charset_latin1, value, "no")) + if (value.streq("false"_LEX_CSTRING) || + value.streq("off"_LEX_CSTRING) || + value.streq("0"_LEX_CSTRING) || + value.streq("no"_LEX_CSTRING)) { e->m_enabled= false; e->m_timed= false; diff --git a/storage/perfschema/pfs_server.h b/storage/perfschema/pfs_server.h index 7c22812fca8..af3b6e87b66 100644 --- a/storage/perfschema/pfs_server.h +++ b/storage/perfschema/pfs_server.h @@ -23,6 +23,8 @@ #ifndef PFS_SERVER_H #define PFS_SERVER_H +#include "m_string.h" /* LEX_CSTRING */ + /** @file storage/perfschema/pfs_server.h Private interface for the server (declarations). @@ -299,7 +301,7 @@ void init_pfs_instrument_array(); /** Process one PFS_INSTRUMENT configuration string. */ -int add_pfs_instr_to_array(const char* name, const char* value); +int add_pfs_instr_to_array(const LEX_CSTRING &name, const LEX_CSTRING &value); /** Shutdown the performance schema. diff --git a/storage/perfschema/pfs_variable.cc b/storage/perfschema/pfs_variable.cc index a33fe2edd06..8f81990be64 100644 --- a/storage/perfschema/pfs_variable.cc +++ b/storage/perfschema/pfs_variable.cc @@ -170,12 +170,12 @@ int PFS_system_variable_cache::do_materialize_global(void) for (SHOW_VAR *show_var= m_show_var_array.front(); show_var->value && (show_var != m_show_var_array.end()); show_var++) { - const char* name= show_var->name; + const Lex_ident_sys_var name= Lex_cstring_strlen(show_var->name); sys_var *value= (sys_var *)show_var->value; assert(value); if ((m_query_scope == OPT_GLOBAL) && - (!my_strcasecmp(system_charset_info, name, "sql_log_bin"))) + name.streq("sql_log_bin"_LEX_CSTRING)) { /* PLEASE READ: @@ -665,9 +665,9 @@ bool PFS_status_variable_cache::filter_by_name(const SHOW_VAR *show_var) if (show_var->type == SHOW_ARRAY) { /* The SHOW_ARRAY name is the prefix for the variables in the subarray. */ - const char *prefix= show_var->name; + const Lex_ident_sys_var prefix= Lex_cstring_strlen(show_var->name); /* Exclude COM counters if not a SHOW STATUS command. */ - if (!my_strcasecmp(system_charset_info, prefix, "Com") && !m_show_command) + if (prefix.streq("Com"_LEX_CSTRING) && !m_show_command) return true; } else @@ -679,12 +679,12 @@ bool PFS_status_variable_cache::filter_by_name(const SHOW_VAR *show_var) Assume null prefix to ensure that only server-defined slave status variables are filtered. */ - const char *name= show_var->name; - if (!my_strcasecmp(system_charset_info, name, "Slave_running") || - !my_strcasecmp(system_charset_info, name, "Slave_retried_transactions") || - !my_strcasecmp(system_charset_info, name, "Slave_last_heartbeat") || - !my_strcasecmp(system_charset_info, name, "Slave_received_heartbeats") || - !my_strcasecmp(system_charset_info, name, "Slave_heartbeat_period")) + const Lex_ident_sys_var name= Lex_cstring_strlen(show_var->name); + if (name.streq("Slave_running"_LEX_CSTRING) || + name.streq("Slave_retried_transactions"_LEX_CSTRING) || + name.streq("Slave_last_heartbeat"_LEX_CSTRING) || + name.streq("Slave_received_heartbeats"_LEX_CSTRING) || + name.streq("Slave_heartbeat_period"_LEX_CSTRING)) { return true; } diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 4ab0252033c..72112da9660 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -14256,11 +14256,11 @@ int mysql_value_to_bool(struct st_mysql_value *value, my_bool *return_value) { char buf[16]; int len = sizeof(buf); const char *str = value->val_str(value, buf, &len); - if (str && (my_strcasecmp(system_charset_info, "true", str) == 0 || - my_strcasecmp(system_charset_info, "on", str) == 0)) { + if (str && (strcasecmp("true", str) == 0 || + strcasecmp("on", str) == 0)) { *return_value = TRUE; - } else if (str && (my_strcasecmp(system_charset_info, "false", str) == 0 || - my_strcasecmp(system_charset_info, "off", str) == 0)) { + } else if (str && (strcasecmp("false", str) == 0 || + strcasecmp("off", str) == 0)) { *return_value = FALSE; } else { return 1; diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 9afc2100069..888a3adb8fd 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -62,11 +62,10 @@ void get_mem_comparable_space(const CHARSET_INFO *cs, /* MariaDB's replacement for FB/MySQL Field::check_field_name_match : */ -inline bool field_check_field_name_match(Field *field, const char *name) +inline bool field_check_field_name_match(Field *field, std::string *str) { - return (0 == my_strcasecmp(system_charset_info, - field->field_name.str, - name)); + // Lex_ident_column::streq() expects str[length]=='\0', hence c_str(). + return field->field_name.streq(Lex_cstring(str->c_str(), str->length())); } @@ -548,7 +547,7 @@ uint Rdb_key_def::setup(const TABLE *const tbl, the offset of the TTL key part here. */ if (!m_ttl_column.empty() && - field_check_field_name_match(field, m_ttl_column.c_str())) { + field_check_field_name_match(field, &m_ttl_column)) { DBUG_ASSERT(field->real_type() == MYSQL_TYPE_LONGLONG); DBUG_ASSERT(field->key_type() == HA_KEYTYPE_ULONGLONG); DBUG_ASSERT(!field->real_maybe_null()); @@ -669,7 +668,7 @@ uint Rdb_key_def::extract_ttl_col(const TABLE *const table_arg, if (skip_checks) { for (uint i = 0; i < table_arg->s->fields; i++) { Field *const field = table_arg->field[i]; - if (field_check_field_name_match(field, ttl_col_str.c_str())) { + if (field_check_field_name_match(field, &ttl_col_str)) { *ttl_column = ttl_col_str; *ttl_field_index = i; } @@ -682,7 +681,7 @@ uint Rdb_key_def::extract_ttl_col(const TABLE *const table_arg, bool found = false; for (uint i = 0; i < table_arg->s->fields; i++) { Field *const field = table_arg->field[i]; - if (field_check_field_name_match(field, ttl_col_str.c_str()) && + if (field_check_field_name_match(field, &ttl_col_str) && field->real_type() == MYSQL_TYPE_LONGLONG && field->key_type() == HA_KEYTYPE_ULONGLONG && !field->real_maybe_null()) { diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc index 6f66e122ed9..85de9e17b9b 100644 --- a/storage/sequence/sequence.cc +++ b/storage/sequence/sequence.cc @@ -34,13 +34,14 @@ static handlerton *sequence_hton; class Sequence_share : public Handler_share { public: - const char *name; + Lex_ident_table name; THR_LOCK lock; ulonglong from, to, step; bool reverse; - Sequence_share(const char *name_arg, ulonglong from_arg, ulonglong to_arg, + Sequence_share(const Lex_ident_table &name_arg, + ulonglong from_arg, ulonglong to_arg, ulonglong step_arg, bool reverse_arg): name(name_arg), from(from_arg), to(to_arg), step(step_arg), reverse(reverse_arg) @@ -263,7 +264,7 @@ int ha_seq::open(const char *name, int mode, uint test_if_locked) { if (!(seqs= get_share())) return HA_ERR_OUT_OF_MEM; - DBUG_ASSERT(my_strcasecmp(table_alias_charset, name, seqs->name) == 0); + DBUG_ASSERT(seqs->name.streq(Lex_cstring_strlen(name))); ref_length= sizeof(cur); thr_lock_data_init(&seqs->lock,&lock,NULL); @@ -328,7 +329,8 @@ Sequence_share *ha_seq::get_share() to= (to - from) / step * step + step + from; - tmp_share= new Sequence_share(table_share->normalized_path.str, from, to, step, reverse); + tmp_share= new Sequence_share(Lex_ident_table(table_share->normalized_path), + from, to, step, reverse); if (!tmp_share) goto err; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 45ff1e1d480..788849f9c04 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1202,7 +1202,8 @@ int spider_db_mbase_result::fetch_table_cardinality( if ( mysql_row[4] && mysql_row[6] && - (field = find_field_in_table_sef(table, mysql_row[4])) + (field = find_field_in_table_sef(table, + Lex_cstring_strlen(mysql_row[4]))) ) { if ((cardinality[field->field_index] = (longlong) my_strtoll10(mysql_row[6], (char**) NULL, &error_num)) @@ -1229,7 +1230,8 @@ int spider_db_mbase_result::fetch_table_cardinality( if ( mysql_row[0] && mysql_row[1] && - (field = find_field_in_table_sef(table, mysql_row[0])) + (field = find_field_in_table_sef(table, + Lex_cstring_strlen(mysql_row[0]))) ) { if ((cardinality[field->field_index] = (longlong) my_strtoll10(mysql_row[1], (char**) NULL, &error_num)) diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index f2682e8b39d..444365ed333 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -4193,8 +4193,8 @@ int spider_set_connect_info_default( if ( !(share->tgt_table_names[roop_count] = spider_create_table_name_string( table_share->table_name.str, - (part_elem ? part_elem->partition_name : NULL), - (sub_elem ? sub_elem->partition_name : NULL) + (part_elem ? part_elem->partition_name.str : NULL), + (sub_elem ? sub_elem->partition_name.str : NULL) )) ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index c74e88c3b73..c5a560e4026 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6723,7 +6723,6 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_chinese_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -6744,7 +6743,6 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -6765,7 +6763,6 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_chinese_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -6786,7 +6783,6 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 2c6dddff78c..296139ef088 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -246,13 +246,6 @@ static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)), } -static int my_strcasecmp_bin(CHARSET_INFO * cs __attribute__((unused)), - const char *s, const char *t) -{ - return strcmp(s,t); -} - - static int my_mb_wc_bin(CHARSET_INFO *cs __attribute__((unused)), my_wc_t *wc, const uchar *str, @@ -511,7 +504,6 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_bin, - my_strcasecmp_bin, my_instr_bin, my_hash_sort_8bit_bin, my_propagate_simple, @@ -532,7 +524,6 @@ MY_COLLATION_HANDLER my_collation_8bit_nopad_bin_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_bin, - my_strcasecmp_bin, my_instr_bin, my_hash_sort_bin, my_propagate_simple, @@ -553,7 +544,6 @@ static MY_COLLATION_HANDLER my_collation_binary_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_bin, - my_strcasecmp_bin, my_instr_bin, my_hash_sort_bin, my_propagate_simple, diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 0767f7db91f..9602d3a1de6 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -34680,7 +34680,6 @@ static MY_COLLATION_HANDLER my_collation_handler_cp932_japanese_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_8bit, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -34701,7 +34700,6 @@ static MY_COLLATION_HANDLER my_collation_handler_cp932_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -34722,7 +34720,6 @@ static MY_COLLATION_HANDLER my_collation_handler_cp932_japanese_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_8bit, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -34743,7 +34740,6 @@ static MY_COLLATION_HANDLER my_collation_handler_cp932_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 64aff2e7be0..92cd4721853 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -591,7 +591,6 @@ static MY_COLLATION_HANDLER my_collation_latin2_czech_cs_handler = my_strnxfrmlen_czech, my_like_range_czech, my_wildcmp_bin, - my_strcasecmp_8bit, my_instr_simple, my_hash_sort_simple, my_propagate_simple, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 51bbb589dad..488cbee1be5 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -9970,7 +9970,6 @@ static MY_COLLATION_HANDLER my_collation_handler_euckr_korean_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -9991,7 +9990,6 @@ static MY_COLLATION_HANDLER my_collation_handler_euckr_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -10012,7 +10010,6 @@ static MY_COLLATION_HANDLER my_collation_handler_euckr_korean_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -10033,7 +10030,6 @@ static MY_COLLATION_HANDLER my_collation_handler_euckr_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 6e0045366da..95484e72812 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -67508,7 +67508,6 @@ static MY_COLLATION_HANDLER my_collation_eucjpms_japanese_ci_handler = my_strnxfrmlen_simple, my_like_range_mb, /* like_range */ my_wildcmp_mb, /* wildcmp */ - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -67529,7 +67528,6 @@ static MY_COLLATION_HANDLER my_collation_eucjpms_bin_handler = my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -67550,7 +67548,6 @@ static MY_COLLATION_HANDLER my_collation_eucjpms_japanese_nopad_ci_handler = my_strnxfrmlen_simple, my_like_range_mb, /* like_range */ my_wildcmp_mb, /* wildcmp */ - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -67571,7 +67568,6 @@ static MY_COLLATION_HANDLER my_collation_eucjpms_nopad_bin_handler = my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index c474ec390ea..88e524c1989 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -6374,7 +6374,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gb2312_chinese_ci= my_strnxfrmlen_simple, my_like_range_mb, /* like_range */ my_wildcmp_mb, /* wildcmp */ - my_strcasecmp_mb, /* instr */ my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -6395,7 +6394,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gb2312_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -6416,7 +6414,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gb2312_chinese_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -6437,7 +6434,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gb2312_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index b1f53999402..cdd2391f382 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -10656,7 +10656,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_chinese_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -10677,7 +10676,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -10698,7 +10696,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_chinese_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -10719,7 +10716,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 0488aaebe67..69b3831867d 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -732,7 +732,6 @@ static MY_COLLATION_HANDLER my_collation_german2_ci_handler= my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_8bit, - my_strcasecmp_8bit, my_instr_simple, my_hash_sort_latin1_de, my_propagate_complex, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 2711b089582..e375ece2c64 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -99,34 +99,6 @@ my_caseup_mb(CHARSET_INFO * cs, const char *src, size_t srclen, } -/* - my_strcasecmp_mb() returns 0 if strings are equal, non-zero otherwise. - */ - -int my_strcasecmp_mb(CHARSET_INFO * cs,const char *s, const char *t) -{ - register uint32 l; - register const uchar *map=cs->to_upper; - - while (*s && *t) - { - /* Pointing after the '\0' is safe here. */ - if ((l=my_ismbchar(cs, s, s + cs->mbmaxlen))) - { - while (l--) - if (*s++ != *t++) - return 1; - } - else if (my_ci_charlen(cs, (const uchar *) t, (const uchar *) t + cs->mbmaxlen) > 1) - return 1; - else if (map[(uchar) *s++] != map[(uchar) *t++]) - return 1; - } - /* At least one of '*s' and '*t' is zero here. */ - return (*t != *s); -} - - /* ** Compare string against string with wildcard ** 0 if matched @@ -562,15 +534,6 @@ my_strnxfrm_mb_nopad(CHARSET_INFO *cs, } -int -my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), - const char *s, const char *t) -{ - return strcmp(s,t); -} - - - void my_hash_sort_mb_nopad_bin(CHARSET_INFO *cs __attribute__((unused)), const uchar *key, size_t len,ulong *nr1, ulong *nr2) diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index a77139139e5..17f3bdab14f 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -2176,7 +2176,6 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_8bit, - my_strcasecmp_8bit, my_instr_simple, my_hash_sort_simple, my_propagate_simple, @@ -2197,7 +2196,6 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_nopad_ci_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_8bit, - my_strcasecmp_8bit, my_instr_simple, my_hash_sort_simple_nopad, my_propagate_simple, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 807c2fa7bcd..c39dd945b6f 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -34068,7 +34068,6 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_japanese_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_8bit, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -34089,7 +34088,6 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -34110,7 +34108,6 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_japanese_nopad_ci= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_8bit, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -34131,7 +34128,6 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_nopad_bin= my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index f6a2dd30819..3d588963493 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -874,7 +874,6 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_8bit, /* wildcmp */ - my_strcasecmp_8bit, my_instr_simple, /* QQ: To be fixed */ my_hash_sort_simple, my_propagate_simple, @@ -894,7 +893,6 @@ static MY_COLLATION_HANDLER my_collation_nopad_ci_handler = my_strnxfrmlen_simple, my_like_range_simple, my_wildcmp_8bit, /* wildcmp */ - my_strcasecmp_8bit, my_instr_simple, /* QQ: To be fixed */ my_hash_sort_simple_nopad, my_propagate_simple, diff --git a/strings/ctype-uca.inl b/strings/ctype-uca.inl index 62abbb9b0d0..d05b47da09b 100644 --- a/strings/ctype-uca.inl +++ b/strings/ctype-uca.inl @@ -954,7 +954,6 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler)= my_strnxfrmlen_any_uca, MY_LIKE_RANGE, my_wildcmp_uca, - NULL, /* strcasecmp() */ my_instr_mb, MY_FUNCTION_NAME(hash_sort), my_propagate_complex, @@ -980,7 +979,6 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_nopad)= my_strnxfrmlen_any_uca, MY_LIKE_RANGE, /* my_like_range_mb or my_like_range_generic */ my_wildcmp_uca, - NULL, /* strcasecmp() */ my_instr_mb, MY_FUNCTION_NAME(hash_sort_nopad), my_propagate_complex, @@ -1004,7 +1002,6 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_multilevel)= my_strnxfrmlen_any_uca_multilevel, MY_LIKE_RANGE, my_wildcmp_uca, - NULL, /* strcasecmp() */ my_instr_mb, MY_FUNCTION_NAME(hash_sort), my_propagate_complex, @@ -1028,7 +1025,6 @@ MY_COLLATION_HANDLER MY_FUNCTION_NAME(collation_handler_nopad_multilevel)= my_strnxfrmlen_any_uca_multilevel, MY_LIKE_RANGE, my_wildcmp_uca, - NULL, /* strcasecmp() */ my_instr_mb, MY_FUNCTION_NAME(hash_sort), my_propagate_complex, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index c4c4444188b..6759b8eeca2 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -56,16 +56,6 @@ static unsigned long lfactor[9]= #ifdef HAVE_CHARSET_mb2_or_mb4 -static int -my_strcasecmp_mb2_or_mb4(CHARSET_INFO *cs __attribute__((unused)), - const char *s __attribute__((unused)), - const char *t __attribute__((unused))) -{ - DBUG_ASSERT(0); - return 0; -} - - typedef enum { MY_CHAR_COPY_OK= 0, /* The character was Okey */ @@ -1502,7 +1492,6 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16, my_propagate_simple, @@ -1523,7 +1512,6 @@ static MY_COLLATION_HANDLER my_collation_utf16_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_bin, my_propagate_simple, @@ -1544,7 +1532,6 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_nopad_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_nopad, my_propagate_simple, @@ -1565,7 +1552,6 @@ static MY_COLLATION_HANDLER my_collation_utf16_nopad_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_nopad_bin, my_propagate_simple, @@ -1853,7 +1839,6 @@ static MY_COLLATION_HANDLER my_collation_utf16le_general_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16, my_propagate_simple, @@ -1874,7 +1859,6 @@ static MY_COLLATION_HANDLER my_collation_utf16le_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_bin, my_propagate_simple, @@ -1895,7 +1879,6 @@ static MY_COLLATION_HANDLER my_collation_utf16le_general_nopad_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_nopad, my_propagate_simple, @@ -1916,7 +1899,6 @@ static MY_COLLATION_HANDLER my_collation_utf16le_nopad_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf16_nopad_bin, my_propagate_simple, @@ -2627,7 +2609,6 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf32, my_propagate_simple, @@ -2648,7 +2629,6 @@ static MY_COLLATION_HANDLER my_collation_utf32_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf32, my_propagate_simple, @@ -2669,7 +2649,6 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_nopad_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf32_nopad, my_propagate_simple, @@ -2690,7 +2669,6 @@ static MY_COLLATION_HANDLER my_collation_utf32_nopad_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_utf32_nopad, my_propagate_simple, @@ -3196,7 +3174,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_ucs2, my_propagate_simple, @@ -3217,7 +3194,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_mysql500_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_ucs2, my_propagate_simple, @@ -3238,7 +3214,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_ucs2_bin, my_propagate_simple, @@ -3259,7 +3234,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_nopad_ci_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_general_ci, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_ucs2_nopad, my_propagate_simple, @@ -3280,7 +3254,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_nopad_bin_handler = my_strnxfrmlen_unicode, my_like_range_generic, my_wildcmp_mb2_or_mb4_bin, - my_strcasecmp_mb2_or_mb4, my_instr_mb, my_hash_sort_ucs2_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 06b3d307530..7793a25b408 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67252,7 +67252,6 @@ static MY_COLLATION_HANDLER my_collation_ujis_japanese_ci_handler = my_strnxfrmlen_simple, my_like_range_mb, /* like_range */ my_wildcmp_mb, /* wildcmp */ - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple, my_propagate_simple, @@ -67273,7 +67272,6 @@ static MY_COLLATION_HANDLER my_collation_ujis_bin_handler = my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -67294,7 +67292,6 @@ static MY_COLLATION_HANDLER my_collation_ujis_japanese_nopad_ci_handler = my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, - my_strcasecmp_mb, my_instr_mb, my_hash_sort_simple_nopad, my_propagate_simple, @@ -67315,7 +67312,6 @@ static MY_COLLATION_HANDLER my_collation_ujis_nopad_bin_handler = my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, diff --git a/strings/ctype-unidata.h b/strings/ctype-unidata.h index bb741dc3eb5..89d3e00ff66 100644 --- a/strings/ctype-unidata.h +++ b/strings/ctype-unidata.h @@ -150,6 +150,22 @@ my_casefold_char_eq_general_ci(MY_CASEFOLD_INFO *casefold, } +/* + Compare two characters for equality, according to the collation. + For simple Uncode AS CI collations, e.g. utf8mb4_general1400_as_ci. + @return TRUE if the two characters are equal + @return FALSE otherwise +*/ +static inline my_bool +my_casefold_char_eq_general_as_ci(MY_CASEFOLD_INFO *casefold, + my_wc_t wc1, my_wc_t wc2) +{ + my_toupper_unicode(casefold, &wc1); + my_toupper_unicode(casefold, &wc2); + return wc1 == wc2; +} + + extern MY_CASEFOLD_INFO my_casefold_default; extern MY_CASEFOLD_INFO my_casefold_turkish; extern MY_CASEFOLD_INFO my_casefold_mysql500; @@ -158,11 +174,22 @@ extern MY_CASEFOLD_INFO my_casefold_unicode1400; extern MY_CASEFOLD_INFO my_casefold_unicode1400tr; -size_t my_strxfrm_pad_nweights_unicode(uchar *str, uchar *strend, size_t nweights); -size_t my_strxfrm_pad_unicode(uchar *str, uchar *strend); +size_t my_strxfrm_pad_nweights_unicode_be2(uchar *str, uchar *strend, + size_t nweights); +size_t my_strxfrm_pad_unicode_be2(uchar *str, uchar *strend); + +size_t my_strxfrm_pad_nweights_unicode_be3(uchar *str, uchar *strend, + size_t nweights); +size_t my_strxfrm_pad_unicode_be3(uchar *str, uchar *strend); #define PUT_WC_BE2_HAVE_1BYTE(dst, de, wc) \ do { *dst++= (uchar) (wc >> 8); if (dst < de) *dst++= (uchar) (wc & 0xFF); } while(0) +#define PUT_WC_BE3_HAVE_1BYTE(dst, de, wc) \ + do { *dst++= (uchar) (wc >> 16); \ + if (dst < de) *dst++= (uchar) ((wc >> 8) & 0xFF);\ + if (dst < de) *dst++= (uchar) (wc & 0xFF);\ + } while(0) + #endif /* CTYPE_UNIDATA_H_INCLUDED */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 2dc120a2d0d..18bdf42b2fb 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -141,6 +141,14 @@ my_char_eq_utf8mbx_general_ci(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) } +static inline my_bool +my_char_eq_utf8mbx_general_as_ci(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) +{ + DBUG_ASSERT((cs->state & MY_CS_BINSORT) == 0); + return my_casefold_char_eq_general_as_ci(cs->casefold, wc1, wc2); +} + + /** Pad buffer with weights for space characters. @@ -161,7 +169,7 @@ my_char_eq_utf8mbx_general_ci(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2) */ size_t -my_strxfrm_pad_nweights_unicode(uchar *str, uchar *strend, size_t nweights) +my_strxfrm_pad_nweights_unicode_be2(uchar *str, uchar *strend, size_t nweights) { uchar *str0; DBUG_ASSERT(str && str <= strend); @@ -175,6 +183,23 @@ my_strxfrm_pad_nweights_unicode(uchar *str, uchar *strend, size_t nweights) } +size_t +my_strxfrm_pad_nweights_unicode_be3(uchar *str, uchar *strend, size_t nweights) +{ + uchar *str0; + DBUG_ASSERT(str && str <= strend); + for (str0= str; str < strend && nweights; nweights--) + { + *str++= 0x00; + if (str < strend) + *str++= 0x00; + if (str < strend) + *str++= 0x20; + } + return str - str0; +} + + /** Pad buffer with weights for space characters. @@ -190,7 +215,7 @@ my_strxfrm_pad_nweights_unicode(uchar *str, uchar *strend, size_t nweights) */ size_t -my_strxfrm_pad_unicode(uchar *str, uchar *strend) +my_strxfrm_pad_unicode_be2(uchar *str, uchar *strend) { uchar *str0= str; DBUG_ASSERT(str && str <= strend); @@ -204,6 +229,23 @@ my_strxfrm_pad_unicode(uchar *str, uchar *strend) } +size_t +my_strxfrm_pad_unicode_be3(uchar *str, uchar *strend) +{ + uchar *str0= str; + DBUG_ASSERT(str && str <= strend); + for ( ; str < strend ; ) + { + *str++= 0x00; + if (str < strend) + *str++= 0x00; + if (str < strend) + *str++= 0x20; + } + return str - str0; +} + + /* For BMP-only collations that use 2 bytes per weight. */ @@ -495,6 +537,38 @@ static void my_hash_sort_utf8mb3(CHARSET_INFO *cs, const uchar *s, size_t slen, } +static void +my_hash_sort_utf8mb3_general1400_nopad_as_ci(CHARSET_INFO *cs, + const uchar *s, size_t slen, + ulong *nr1, ulong *nr2) +{ + my_wc_t wc; + int res; + const uchar *e= s + slen; + MY_CASEFOLD_INFO *uni_plane= cs->casefold; + register ulong m1= *nr1, m2= *nr2; + + while ((res= my_utf8mb3_uni(cs, &wc, (uchar*) s, (uchar*) e)) > 0) + { + my_toupper_unicode(uni_plane, &wc); + MY_HASH_ADD_16(m1, m2, (uint) (wc & 0xFFFF)); + s+= res; + } + *nr1= m1; + *nr2= m2; +} + + +static void +my_hash_sort_utf8mb3_general1400_as_ci(CHARSET_INFO *cs, + const uchar *s, size_t slen, + ulong *nr1, ulong *nr2) +{ + const uchar *e= skip_trailing_space(s, slen); + my_hash_sort_utf8mb3_general1400_nopad_as_ci(cs, s, e - s, nr1, nr2); +} + + static size_t my_casedn_utf8mb3(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) @@ -519,101 +593,6 @@ static size_t my_casedn_utf8mb3(CHARSET_INFO *cs, } -/* - Compare 0-terminated UTF8 strings. - - SYNOPSIS - my_strcasecmp_utf8mb3() - cs character set handler - s First 0-terminated string to compare - t Second 0-terminated string to compare - - IMPLEMENTATION - - RETURN - - negative number if s < t - - positive number if s > t - - 0 is the strings are equal -*/ - -static -int my_strcasecmp_utf8mb3(CHARSET_INFO *cs, const char *s, const char *t) -{ - MY_CASEFOLD_INFO *uni_plane= cs->casefold; - while (s[0] && t[0]) - { - my_wc_t s_wc,t_wc; - - if ((uchar) s[0] < 128) - { - /* - s[0] is between 0 and 127. - It represents a single byte character. - Convert it into weight according to collation. - */ - s_wc= my_u300_tolower_7bit((uchar) s[0]); - s++; - } - else - { - int res; - - /* - Scan a multibyte character. - - In the future it is worth to write a special version of my_utf8mb3_uni() - for 0-terminated strings which will not take in account length. Now - we call the regular version of my_utf8mb3_uni() with s+3 in the - last argument. s+3 is enough to scan any multibyte sequence. - - Calling the regular version of my_utf8mb3_uni is safe for 0-terminated - strings: we will never lose the end of the string: - If we have 0 character in the middle of a multibyte sequence, - then my_utf8mb3_uni will always return a negative number, so the - loop with finish. - */ - - res= my_utf8mb3_uni(cs,&s_wc, (const uchar*)s, (const uchar*) s + 3); - - /* - In the case of wrong multibyte sequence we will - call strcmp() for byte-to-byte comparison. - */ - if (res <= 0) - return strcmp(s, t); - s+= res; - - /* Convert Unicode code into weight according to collation */ - my_tolower_unicode_bmp(uni_plane, &s_wc); - } - - - /* Do the same for the second string */ - - if ((uchar) t[0] < 128) - { - /* Convert single byte character into weight */ - t_wc= my_u300_tolower_7bit((uchar) t[0]); - t++; - } - else - { - int res=my_utf8mb3_uni(cs,&t_wc, (const uchar*)t, (const uchar*) t + 3); - if (res <= 0) - return strcmp(s, t); - t+= res; - - /* Convert code into weight */ - my_tolower_unicode_bmp(uni_plane, &t_wc); - } - - /* Now we have two weights, let's compare them */ - if ( s_wc != t_wc ) - return ((int) s_wc) - ((int) t_wc); - } - return ((int)(uchar)s[0]) - ((int) (uchar) t[0]); -} - /* my_wildcmp_utf8mb3_general_ci_impl() @@ -626,6 +605,12 @@ int my_strcasecmp_utf8mb3(CHARSET_INFO *cs, const char *s, const char *t) #include "ctype-wildcmp.inl" +#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb3_general_as_ci_impl +#define MY_MB_WC(cs, pwc, s, e) my_mb_wc_utf8mb3_quick(pwc, s, e) +#define MY_CHAR_EQ(cs, wc1, wc2) my_char_eq_utf8mbx_general_as_ci(cs, wc1, wc2) +#include "ctype-wildcmp.inl" + + static int my_wildcmp_utf8mb3(CHARSET_INFO *cs, const char *str,const char *str_end, @@ -637,6 +622,17 @@ int my_wildcmp_utf8mb3(CHARSET_INFO *cs, } +static +int my_wildcmp_utf8mb3_general_as_ci(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + return my_wildcmp_utf8mb3_general_as_ci_impl(cs, str, str_end, wildstr, wildend, + escape, w_one, w_many, 1); +} + + static int my_charlen_utf8mb3(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, const uchar *e) @@ -788,6 +784,72 @@ my_wc_weight_utf8mb3_general_mysql500_ci(my_wc_t wc) #define STRCOLL_MB7_BIN #include "strcoll.inl" + +static inline my_wc_t my_general1400_as_ci_char_to_weight(my_wc_t wc) +{ + my_toupper_unicode(&my_casefold_unicode1400, &wc); + return wc; +} + + +static inline int my_weight_mb1_utf8mb3_general1400_as_ci(uchar b) +{ + my_wc_t wc= b; + my_toupper_unicode(&my_casefold_unicode1400, &wc); + return wc; +} + + +static inline int my_weight_mb2_utf8mb3_general1400_as_ci(uchar b0, uchar b1) +{ + my_wc_t wc= UTF8MB2_CODE(b0, b1); + my_toupper_unicode(&my_casefold_unicode1400, &wc); + return wc; +} + + +static inline int my_weight_mb3_utf8mb3_general1400_as_ci(uchar b0, uchar b1, uchar b2) +{ + my_wc_t wc= UTF8MB3_CODE(b0, b1, b2); + my_toupper_unicode(&my_casefold_unicode1400, &wc); + return wc; +} + + +#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb3_general1400_as_ci +#define DEFINE_STRNXFRM_UNICODE +#define MY_MB_WC(cs, pwc, s, e) my_mb_wc_utf8mb3_quick(pwc, s, e) +#define OPTIMIZE_ASCII 1 +#define MY_WC_WEIGHT(x) my_general1400_as_ci_char_to_weight(x) +#define WEIGHT_ILSEQ(x) (0xFF0000 + (uchar) (x)) +#define WEIGHT_MB1(x) my_weight_mb1_utf8mb3_general1400_as_ci(x) +#define WEIGHT_MB2(x,y) my_weight_mb2_utf8mb3_general1400_as_ci(x,y) +#define WEIGHT_MB3(x,y,z) my_weight_mb3_utf8mb3_general1400_as_ci(x,y,z) +#define STRCOLL_MB7_TOUPPER +#undef IS_MB4_CHAR +#include "strcoll.inl" + + +static MY_COLLATION_HANDLER my_collation_utf8mb3_general1400_as_ci_handler= +{ + NULL, /* init */ + my_strnncoll_utf8mb3_general1400_as_ci, + my_strnncollsp_utf8mb3_general1400_as_ci, + my_strnncollsp_nchars_utf8mb3_general1400_as_ci, + my_strnxfrm_utf8mb3_general1400_as_ci, + my_strnxfrmlen_unicode, + my_like_range_mb, + my_wildcmp_utf8mb3_general_as_ci, + my_instr_mb, + my_hash_sort_utf8mb3_general1400_as_ci, + my_propagate_complex, + my_min_str_mb_simple, + my_max_str_mb_simple, + my_ci_get_id_generic, + my_ci_get_collation_name_generic +}; + + /* TODO-10.2: join this with pad_max_char() in ctype-mb.c */ @@ -830,7 +892,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_ci_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb3, - my_strcasecmp_utf8mb3, my_instr_mb, my_hash_sort_utf8mb3, my_propagate_complex, @@ -851,7 +912,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_mysql500_ci_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb3, - my_strcasecmp_utf8mb3, my_instr_mb, my_hash_sort_utf8mb3, my_propagate_complex, @@ -872,7 +932,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_bin_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -893,7 +952,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_general_nopad_ci_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb3, - my_strcasecmp_utf8mb3, my_instr_mb, my_hash_sort_utf8mb3_nopad, my_propagate_complex, @@ -914,7 +972,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb3_nopad_bin_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, @@ -1023,6 +1080,37 @@ struct charset_info_st my_charset_utf8mb3_general_mysql500_ci= }; +struct charset_info_st my_charset_utf8mb3_general1400_as_ci= +{ + 579,0,0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_UNICODE_SUPPLEMENT, /* state */ + { charset_name_utf8mb3, charset_name_utf8mb3_length}, /* cs name */ + { STRING_WITH_LEN(MY_UTF8MB3 "_general1400_as_ci") }, /* name */ + "UTF-8 Unicode", /* comment */ + NULL, /* tailoring */ + ctype_utf8mb3, /* ctype */ + to_lower_utf8mb3, /* to_lower */ + to_upper_utf8mb3, /* to_upper */ + to_upper_utf8mb3, /* sort_order */ + NULL, /* uca */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + &my_casefold_unicode1400,/* casefold */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* mbminlen */ + 3, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + MY_CS_COLL_LEVELS_S1, + &my_charset_utf8mb3_handler, + &my_collation_utf8mb3_general1400_as_ci_handler +}; + + struct charset_info_st my_charset_utf8mb3_bin= { 83,0,0, /* number */ @@ -1240,7 +1328,6 @@ static MY_COLLATION_HANDLER my_collation_cs_handler = my_strnxfrmlen_unicode, my_like_range_simple, my_wildcmp_mb, - my_strcasecmp_utf8mb3, my_instr_mb, my_hash_sort_utf8mb3, my_propagate_simple, @@ -2557,7 +2644,6 @@ static MY_COLLATION_HANDLER my_collation_filename_handler = my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb3, - my_strcasecmp_utf8mb3, my_instr_mb, my_hash_sort_utf8mb3, my_propagate_complex, @@ -2717,53 +2803,6 @@ my_mb_wc_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), } -/* - The same as above, but without range check - for example, for a null-terminated string -*/ -static int -my_mb_wc_utf8mb4_no_range(CHARSET_INFO *cs __attribute__((unused)), - my_wc_t *pwc, const uchar *s) -{ - uchar c; - - c= s[0]; - if (c < 0x80) - { - *pwc = c; - return 1; - } - - if (c < 0xc2) - return MY_CS_ILSEQ; - - if (c < 0xe0) - { - if (!IS_CONTINUATION_BYTE(s[1])) - return MY_CS_ILSEQ; - - *pwc= UTF8MB2_CODE(c, s[1]); - return 2; - } - - if (c < 0xf0) - { - if (!IS_UTF8MB3_STEP2(c, s[1], s[2])) - return MY_CS_ILSEQ; - *pwc= UTF8MB3_CODE(c, s[1], s[2]); - return 3; - } - else if (c < 0xf5) - { - if (!IS_UTF8MB4_STEP2(c, s[1], s[2], s[3])) - return MY_CS_ILSEQ; - *pwc= UTF8MB4_CODE(c, s[1], s[2], s[3]); - return 4; - } - return MY_CS_ILSEQ; -} - - static int my_wc_mb_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), my_wc_t wc, uchar *r, uchar *e) @@ -2895,77 +2934,6 @@ my_casedn_utf8mb4(CHARSET_INFO *cs, } -/** - Compare 0-terminated UTF8 strings. - - @param cs character set handler - @param s First 0-terminated string to compare - @param t Second 0-terminated string to compare - - @return Comparison result. - @retval negative number if s < t - @retval positive number if s > t - @retval 0 is the strings are equal -*/ - -static int -my_strcasecmp_utf8mb4(CHARSET_INFO *cs, const char *s, const char *t) -{ - MY_CASEFOLD_INFO *uni_plane= cs->casefold; - while (s[0] && t[0]) - { - my_wc_t s_wc,t_wc; - - if ((uchar) s[0] < 128) - { - /* - s[0] is between 0 and 127. - It represents a single byte character. - Convert it into weight according to collation. - */ - s_wc= my_u300_tolower_7bit((uchar) s[0]); - s++; - } - else - { - int res= my_mb_wc_utf8mb4_no_range(cs, &s_wc, (const uchar*) s); - - /* - In the case of wrong multibyte sequence we will - call strcmp() for byte-to-byte comparison. - */ - if (res <= 0) - return strcmp(s, t); - s+= res; - - my_tolower_unicode(uni_plane, &s_wc); - } - - - /* Do the same for the second string */ - - if ((uchar) t[0] < 128) - { - /* Convert single byte character into weight */ - t_wc= my_u300_tolower_7bit((uchar) t[0]); - t++; - } - else - { - int res= my_mb_wc_utf8mb4_no_range(cs, &t_wc, (const uchar*) t); - if (res <= 0) - return strcmp(s, t); - t+= res; - - my_tolower_unicode(uni_plane, &t_wc); - } - - /* Now we have two weights, let's compare them */ - if ( s_wc != t_wc ) - return ((int) s_wc) - ((int) t_wc); - } - return ((int) (uchar) s[0]) - ((int) (uchar) t[0]); -} /* @@ -2979,6 +2947,12 @@ my_strcasecmp_utf8mb4(CHARSET_INFO *cs, const char *s, const char *t) #include "ctype-wildcmp.inl" +#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb4_general_as_ci_impl +#define MY_MB_WC(cs, pwc, s, e) my_mb_wc_utf8mb4_quick(pwc, s, e) +#define MY_CHAR_EQ(cs, wc1, wc2) my_char_eq_utf8mbx_general_as_ci(cs, wc1, wc2) +#include "ctype-wildcmp.inl" + + static int my_wildcmp_utf8mb4(CHARSET_INFO *cs, const char *str, const char *strend, @@ -2990,6 +2964,17 @@ my_wildcmp_utf8mb4(CHARSET_INFO *cs, } +static int +my_wildcmp_utf8mb4_general_as_ci(CHARSET_INFO *cs, + const char *str, const char *strend, + const char *wildstr, const char *wildend, + int escape, int w_one, int w_many) +{ + return my_wildcmp_utf8mb4_general_as_ci_impl(cs, str, strend, wildstr, wildend, + escape, w_one, w_many, 1); +} + + static int my_charlen_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, const uchar *e) @@ -3093,7 +3078,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_general_ci_handler= my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb4, - my_strcasecmp_utf8mb4, my_instr_mb, my_hash_sort_utf8mb4, my_propagate_complex, @@ -3114,7 +3098,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_bin, my_propagate_simple, @@ -3135,7 +3118,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_general_nopad_ci_handler= my_strnxfrmlen_unicode, my_like_range_mb, my_wildcmp_utf8mb4, - my_strcasecmp_utf8mb4, my_instr_mb, my_hash_sort_utf8mb4_nopad, my_propagate_complex, @@ -3156,7 +3138,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_nopad_bin_handler = my_strnxfrmlen_unicode_full_bin, my_like_range_mb, my_wildcmp_mb_bin, - my_strcasecmp_mb_bin, my_instr_mb, my_hash_sort_mb_nopad_bin, my_propagate_simple, @@ -3167,6 +3148,105 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_nopad_bin_handler = }; + +static inline int my_weight_mb4_utf8mb4_general1400_as_ci(uchar b0, uchar b1, uchar b2, uchar b3) +{ + my_wc_t wc= UTF8MB4_CODE(b0, b1, b2, b3); + my_toupper_unicode(&my_casefold_unicode1400, &wc); + return wc; +} + + +size_t +my_strnxfrmlen_utf8mb4_general1400_as_ci(CHARSET_INFO *cs, size_t len) +{ + return ((len + cs->mbmaxlen - 1) / cs->mbmaxlen) * 4; +} + + +#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb4_general1400_as_ci +#define DEFINE_STRNXFRM_UNICODE +#define MY_MB_WC(cs, pwc, s, e) my_mb_wc_utf8mb4_quick(pwc, s, e) +#define OPTIMIZE_ASCII 1 +#define MY_WC_WEIGHT(x) my_general1400_as_ci_char_to_weight(x) +#define IS_MB4_CHAR(b0,b1,b2,b3) IS_UTF8MB4_STEP3(b0,b1,b2,b3) +#define WEIGHT_ILSEQ(x) (0xFF0000 + (uchar) (x)) +#define WEIGHT_MB1(b0) my_weight_mb1_utf8mb3_general1400_as_ci(b0) +#define WEIGHT_MB2(b0,b1) my_weight_mb2_utf8mb3_general1400_as_ci(b0,b1) +#define WEIGHT_MB3(b0,b1,b2) my_weight_mb3_utf8mb3_general1400_as_ci(b0,b1,b2) +#define WEIGHT_MB4(b0,b1,b2,b3) my_weight_mb4_utf8mb4_general1400_as_ci(b0,b1,b2,b3) +#define STRCOLL_MB7_TOUPPER +#define WEIGHT_SIZE 3 +#include "strcoll.inl" + + +static void +my_hash_sort_utf8mb4_general1400_nopad_as_ci(CHARSET_INFO *cs, + const uchar *s, size_t slen, + ulong *nr1, ulong *nr2) +{ + my_wc_t wc; + int res; + const uchar *e= s + slen; + MY_CASEFOLD_INFO *uni_plane= cs->casefold; + register ulong m1= *nr1, m2= *nr2; + + while ((res= my_mb_wc_utf8mb4(cs, &wc, (uchar*) s, (uchar*) e)) > 0) + { + my_toupper_unicode(uni_plane, &wc); + MY_HASH_ADD_16(m1, m2, (uint) (wc & 0xFFFF)); + if (wc > 0xFFFF) + { + /* + Put the highest byte only if it is non-zero, + to make hash functions for utf8mb3 and utf8mb4 + compatible for BMP characters. + This is useful to keep order of records in + test results, e.g. for "SHOW GRANTS". + */ + MY_HASH_ADD(m1, m2, (uint) ((wc >> 16) & 0xFF)); + } + s+= res; + } + *nr1= m1; + *nr2= m2; +} + + +static void +my_hash_sort_utf8mb4_general1400_as_ci(CHARSET_INFO *cs, + const uchar *s, size_t slen, + ulong *nr1, ulong *nr2) +{ + /* + Remove end space. We do this to be able to compare + 'A ' and 'A' as identical + */ + const uchar *e= skip_trailing_space(s, slen); + my_hash_sort_utf8mb4_general1400_nopad_as_ci(cs, s, e - s, nr1, nr2); +} + + +static MY_COLLATION_HANDLER my_collation_utf8mb4_general1400_as_ci_handler= +{ + NULL, /* init */ + my_strnncoll_utf8mb4_general1400_as_ci, + my_strnncollsp_utf8mb4_general1400_as_ci, + my_strnncollsp_nchars_utf8mb4_general1400_as_ci, + my_strnxfrm_utf8mb4_general1400_as_ci, + my_strnxfrmlen_utf8mb4_general1400_as_ci, + my_like_range_mb, + my_wildcmp_utf8mb4_general_as_ci, + my_instr_mb, + my_hash_sort_utf8mb4_general1400_as_ci, + my_propagate_complex, + my_min_str_mb_simple, + my_max_str_mb_simple, + my_ci_get_id_generic, + my_ci_get_collation_name_generic +}; + + MY_CHARSET_HANDLER my_charset_utf8mb4_handler= { NULL, /* init */ @@ -3341,4 +3421,36 @@ int my_wc_mb_utf8mb4_bmp_only(CHARSET_INFO *cs, my_wc_t wc, uchar *r, uchar *e) return my_wc_mb_utf8mb4(cs, wc, r, e); } + +struct charset_info_st my_charset_utf8mb4_general1400_as_ci= +{ + 611,0,0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_UNICODE_SUPPLEMENT, /* state */ + { charset_name_utf8mb4, charset_name_utf8mb4_length}, /* cs name */ + { STRING_WITH_LEN(MY_UTF8MB4 "_general1400_as_ci") }, /* name */ + "UTF-8 Unicode", /* comment */ + NULL, /* tailoring */ + ctype_utf8mb4, /* ctype */ + to_lower_utf8mb4, /* to_lower */ + to_upper_utf8mb4, /* to_upper */ + to_upper_utf8mb4, /* sort_order */ + NULL, /* uca */ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + &my_casefold_unicode1400,/* casefold */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* mbminlen */ + 4, /* mbmaxlen */ + 0, /* min_sort_char */ + 0x10FFFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + MY_CS_COLL_LEVELS_S1, + &my_charset_utf8mb4_handler, + &my_collation_utf8mb4_general1400_as_ci_handler +}; + + #endif /* HAVE_CHARSET_utf8mb4 */ diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index a908bdd2b95..a9245630d98 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -683,7 +683,6 @@ static MY_COLLATION_HANDLER my_collation_czech_cs_handler = my_strnxfrmlen_simple, my_like_range_win1250ch, my_wildcmp_8bit, - my_strcasecmp_8bit, my_instr_simple, my_hash_sort_simple, my_propagate_simple, diff --git a/strings/strcoll.inl b/strings/strcoll.inl index a70009991df..7e6d3c8c6c2 100644 --- a/strings/strcoll.inl +++ b/strings/strcoll.inl @@ -100,6 +100,17 @@ #endif +#if defined(WEIGHT_SIZE) && WEIGHT_SIZE == 3 +#define PUT_WC_BE_HAVE_1BYTE(dst, de, wc) PUT_WC_BE3_HAVE_1BYTE((dst), (de), (wc)) +#define PAD_NWEIGHTS_UNICODE_BE(str, end, n) my_strxfrm_pad_nweights_unicode_be3(str, end, n) +#define PAD_UNICODE_BE(str, end) my_strxfrm_pad_unicode_be3(str, end) +#else +#define PUT_WC_BE_HAVE_1BYTE(dst, de, wc) PUT_WC_BE2_HAVE_1BYTE((dst), (de), (wc)) +#define PAD_NWEIGHTS_UNICODE_BE(str, end, n) my_strxfrm_pad_nweights_unicode_be2(str, end, n) +#define PAD_UNICODE_BE(str, end) my_strxfrm_pad_unicode_be2(str, end) +#endif + + #if DEFINE_STRNNCOLL /** @@ -254,10 +265,10 @@ MY_FUNCTION_NAME(strnncoll)(CHARSET_INFO *cs __attribute__((unused)), >0 >0 Two weights were scanned, check weight difference. */ if (!a_wlen) - return b_wlen ? -b_weight : 0; + return b_wlen ? -1 : 0; if (!b_wlen) - return b_is_prefix ? 0 : a_weight; + return b_is_prefix ? 0 : +1; if ((res= (a_weight - b_weight))) return res; @@ -498,7 +509,6 @@ MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, #error MY_WC_WEIGHT must be defined for DEFINE_STRNXFRM_UNICODE #endif - static size_t MY_FUNCTION_NAME(strnxfrm_internal)(CHARSET_INFO *cs __attribute__((unused)), uchar *dst, uchar *de, @@ -520,7 +530,7 @@ MY_FUNCTION_NAME(strnxfrm_internal)(CHARSET_INFO *cs __attribute__((unused)), if (src[0] <= 0x7F) { wc= WEIGHT_MB1(*src++); - PUT_WC_BE2_HAVE_1BYTE(dst, de, wc); + PUT_WC_BE_HAVE_1BYTE(dst, de, wc); continue; } #endif @@ -528,7 +538,7 @@ MY_FUNCTION_NAME(strnxfrm_internal)(CHARSET_INFO *cs __attribute__((unused)), break; src+= res; wc= MY_WC_WEIGHT(wc); - PUT_WC_BE2_HAVE_1BYTE(dst, de, wc); + PUT_WC_BE_HAVE_1BYTE(dst, de, wc); } return dst - dst0; } @@ -546,12 +556,12 @@ MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, DBUG_ASSERT(dst <= de); /* Safety */ if (dst < de && nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) - dst+= my_strxfrm_pad_nweights_unicode(dst, de, nweights); + dst+= PAD_NWEIGHTS_UNICODE_BE(dst, de, nweights); my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) - dst+= my_strxfrm_pad_unicode(dst, de); + dst+= PAD_UNICODE_BE(dst, de); return dst - dst0; } @@ -661,12 +671,12 @@ MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, DBUG_ASSERT(dst <= de); /* Safety */ if (dst < de && nweights && (flags & MY_STRXFRM_PAD_WITH_SPACE)) - dst+= my_strxfrm_pad_nweights_unicode(dst, de, nweights); + dst+= PAD_NWEIGHTS_UNICODE_BE(dst, de, nweights); my_strxfrm_desc_and_reverse(dst0, dst, flags, 0); if ((flags & MY_STRXFRM_PAD_TO_MAXLEN) && dst < de) - dst+= my_strxfrm_pad_unicode(dst, de); + dst+= PAD_UNICODE_BE(dst, de); return dst - dst0; } @@ -718,6 +728,7 @@ MY_FUNCTION_NAME(strnxfrm_nopad)(CHARSET_INFO *cs, #undef WEIGHT_MB4 #undef WEIGHT_PAD_SPACE #undef WEIGHT_MB2_FRM +#undef WEIGHT_SIZE #undef DEFINE_STRNXFRM #undef DEFINE_STRNXFRM_UNICODE #undef DEFINE_STRNXFRM_UNICODE_NOPAD @@ -729,3 +740,6 @@ MY_FUNCTION_NAME(strnxfrm_nopad)(CHARSET_INFO *cs, #undef STRCOLL_MB7_BIN #undef MY_STRCOLL_MB7_4BYTES #undef MY_STRCOLL_MB7_8BYTES +#undef PUT_WC_BE_HAVE_1BYTE +#undef PAD_NWEIGHTS_UNICODE_BE +#undef PAD_UNICODE_BE diff --git a/strings/string.doc b/strings/string.doc index fc5153eb693..09572c968d4 100644 --- a/strings/string.doc +++ b/strings/string.doc @@ -141,8 +141,3 @@ I mysys: string strcfind(str,search) find string in another with no case_sensivity - - my_strcasecmp(s,t) - Compare strings without regarding to case - - For many strings it quicker to forst use case_sort on all strings and - then compare them with strcmp().