1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-31606 Refactor check_db_name() to get a const argument

Problem:
Under terms of MDEV-27490, we'll update Unicode version used
to compare identifiers to 14.0.0. Unlike in the old Unicode version,
in the new version a string can grow during lower-case. We cannot
perform check_db_name() inplace any more.

Change summary:

- Allocate memory to store lower-cased identifiers in memory root

- Removing check_db_name() performing both in-place lower-casing and validation
  at the same time. Splitting it into two separate stages:
  * creating a memory-root lower-cased copy of an identifier
    (using new MEM_ROOT functions and Query_arena wrapper methods)
  * performing validation on a constant string
    (using Lex_ident_fs methods)

Implementation details:

- Adding a mysys helper function to allocate lower-cased strings on MEM_ROOT:

    lex_string_casedn_root()

  and a Query_arena wrappers for it:

    make_ident_casedn()
    make_ident_opt_casedn()

- Adding a Query_arena method to perform both MEM_ROOT lower-casing and
  database name validation at the same time:

    to_ident_db_internal_with_error()

  This method is very close to the old (pre-11.3) check_db_name(),
  but performs lower-casing to a newly allocated MEM_ROOT
  memory (instead of performing lower-casing the original string in-place).

- Adding a Table_ident method which additionally handles derived table names:

    to_ident_db_internal_with_error()

- Removing the old check_db_name()
This commit is contained in:
Alexander Barkov
2023-07-04 14:09:43 +04:00
parent e987b9350c
commit f5aae71661
15 changed files with 245 additions and 173 deletions

View File

@@ -1355,6 +1355,45 @@ public:
return false;
}
/*
Make a lower-cased copy of an identifier on mem_root.
@param src - The original identifier (usually coming from the parser)
@return - {NULL,0} in case of EOM, or a non-NULL LEX_STRING
with the lower-cased identifier copy.
*/
LEX_STRING make_ident_casedn(const LEX_CSTRING &src)
{
return lex_string_casedn_root(mem_root, &my_charset_utf8mb3_general_ci,
src.str, src.length);
}
/*
Make an exact copy or a lower-cased copy of an identifier on mem_root.
@param src - The original identifier (usually coming from the parser)
@param casedn - If the name should be converted to lower case
@return - {NULL,0} in case of EOM,
or a non-NULL LEX_STRING with the identifier copy.
*/
LEX_STRING make_ident_opt_casedn(const LEX_CSTRING &src, bool casedn)
{
return casedn ? make_ident_casedn(src) :
lex_string_strmake_root(mem_root, src.str, src.length);
}
/*
Convert a LEX_CSTRING to a valid internal database name:
- validated with Lex_ident_fs::check_db_name()
- optionally lower-cased when lower_case_table_names==1
The lower-cased copy is created on Query_arena::mem_root, when needed.
@param name - The name to normalize. Must not be {NULL,0}.
@return - {NULL,0} on EOM or a bad database name
(with an errror is raised,
or a good database name otherwise.
*/
Lex_ident_db to_ident_db_internal_with_error(const LEX_CSTRING &name);
void set_query_arena(Query_arena *set);
@@ -7051,6 +7090,16 @@ public:
}
bool resolve_table_rowtype_ref(THD *thd, Row_definition_list &defs);
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()
- optionally lower-cased when lower_case_table_names==1
@param arena - the arena to allocate the lower-cased copy on, when needed.
@return {NULL,0} in case of EOM or invalid database name,
or a good identifier otherwise.
*/
Lex_ident_db to_ident_db_internal_with_error(Query_arena *arena) const;
};
@@ -7865,8 +7914,13 @@ public:
!cs->strnncoll(m_name.str, m_name.length,
other->m_name.str, other->m_name.length);
}
void copy(MEM_ROOT *mem_root, const LEX_CSTRING &db,
const LEX_CSTRING &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,
const LEX_CSTRING &name);
// Export db and name as a qualified name string: 'db.name'
size_t make_qname(char *dst, size_t dstlen) const