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")});
This commit is contained in:
Alexander Barkov 2023-04-26 15:27:01 +04:00
parent 159b7ca3f2
commit fd247cc21f
204 changed files with 8971 additions and 3202 deletions

View file

@ -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)
{

View file

@ -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))
{

View file

@ -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))

View file

@ -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)

View file

@ -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
{

View file

@ -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.

View file

@ -220,6 +220,15 @@ template<typename T> 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
{

View file

@ -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
#

View file

@ -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 #

View file

@ -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
#

View file

@ -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 #

File diff suppressed because it is too large Load diff

View file

@ -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 #

File diff suppressed because it is too large Load diff

View file

@ -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 #

View file

@ -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
#

View file

@ -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 #

View file

@ -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
#

View file

@ -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 #

View file

@ -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
#

View file

@ -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 #

8
mysql-test/main/lowercase_table2.result Executable file → Normal file
View file

@ -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;

View file

@ -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;

0
mysql-test/main/lowercase_table4.result Executable file → Normal file
View file

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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'

View file

@ -0,0 +1 @@
--lower_case_table_names=1

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 # #

View file

@ -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 # #

View file

@ -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;

View file

@ -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;

View file

@ -0,0 +1,12 @@
##############################################################################
#
# List the test cases that are to be disabled temporarily.
#
# Separate the test case name and the comment with ':'.
#
# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
#
# Do not use any TAB characters for whitespace.
#
##############################################################################
conc_charset : TODO: client side ID for utf8mb4_general_as_ci

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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
{

View file

@ -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;

View file

@ -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<Item_func_sysconst_test>(thd, this); }
};

View file

@ -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 */

View file

@ -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);

View file

@ -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 <TR_table::field_id_t TRT_FIELD>

View file

@ -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;

View file

@ -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)
{

View file

@ -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));

View file

@ -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);

View file

@ -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;
}

View file

@ -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<Create_field> &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);
/*

View file

@ -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;

View file

@ -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<partition_element> 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;

View file

@ -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<Item_func_left *>(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<Item_field *>(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<Create_field> 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;

View file

@ -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);
};

View file

@ -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<SAFE_NAME_LEN> 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

View file

@ -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

View file

@ -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> *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> *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> *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);

View file

@ -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> *item_list) = 0;

View file

@ -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<Item> &list)
{
List_iterator_fast<Item> 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<const char*>(var->value_ptr(thd, var_type,
@ -5893,26 +5887,26 @@ bool Item_func_get_system_var::fix_length_and_dec(THD *thd)
*reinterpret_cast<const char* const*>(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<const LEX_STRING*>(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;

View file

@ -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,

View file

@ -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;

View file

@ -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<Item_func_database>(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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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 Compare>
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<Compare_table_names>
{
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<Compare_ident_ci>
{
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<size_t buff_sz>
class IdentBuffer: public CharBuffer<buff_sz>
{
@ -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<SAFE_NAME_LEN + MY_CS_MBMAXLEN>
{
@ -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);
}
};

View file

@ -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
*/

View file

@ -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;

View file

@ -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("<left expr>") };
const Lex_ident_column in_left_expr_name= "<left expr>"_Lex_ident_column;
/** name of additional condition */
const LEX_CSTRING in_having_cond= {STRING_WITH_LEN("<IN HAVING>") };
const LEX_CSTRING in_additional_cond= {STRING_WITH_LEN("<IN COND>") };
const Lex_ident_column in_having_cond= "<IN HAVING>"_Lex_ident_column;
const Lex_ident_column in_additional_cond= "<IN 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 "

View file

@ -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[];

View file

@ -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);

View file

@ -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();
}

View file

@ -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),

View file

@ -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<const char> 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<const char> 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<partition_element> 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<partition_element> 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<partition_element> 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 !=

View file

@ -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();
}

View file

@ -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<Item> &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;

View file

@ -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;
}

View file

@ -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))

View file

@ -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;

View file

@ -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();

View file

@ -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);
}

View file

@ -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.
*/

View file

@ -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
{

View file

@ -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());

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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<Item> *fields,
@ -136,14 +138,18 @@ int mysql_alter_user(THD *thd, List <LEX_USER> &list);
bool mysql_revoke_all(THD *thd, List <LEX_USER> &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[];

View file

@ -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:

View file

@ -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<Alter_drop> 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;

View file

@ -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<Natural_join_column>
@ -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<SAFE_NAME_LEN> 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<Item> &items, uint *counter,
List_iterator<Item> 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<Item> &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<Item> &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<Item> &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<Item> &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<Item> &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<Item> &items, uint *counter,
*/
static bool
test_if_string_in_list(const char *find, List<String> *str_list)
test_if_string_in_list(const Lex_ident_column &find, List<String> *str_list)
{
List_iterator<String> 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<String> 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<Natural_join_column>
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<Item> *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<SAFE_NAME_LEN> 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",

View file

@ -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<Item> *it, bool any_privileges,
uint *hidden_bit_fields, bool returning_field);
void make_leaves_list(THD *thd, List<TABLE_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<Item> &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);

View file

@ -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<Create_field> &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
}

View file

@ -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<Key_part_spec> 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 <typename Lex_ident_XXX>
Lex_ident_XXX lex_ident_copy(const Lex_ident_XXX &src)
{
return Lex_ident_XXX(strmake_lex_cstring(src));
}
template <typename Lex_ident_XXX>
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,

Some files were not shown because too many files have changed in this diff Show more