MDEV-32019 Replace my_casedn_str(local_buffer) to CharBuffer::copy_casedn()

Replacing my_casedn_str() called on local char[] buffer variables
to CharBuffer::copy_casedn() calls.

This is a sub-task for MDEV-31531 Remove my_casedn_str()

Details:
- Adding a helper template class IdentBuffer (a CharBuffer descendant),
  which assumes utf8 data. Like CharBuffer, it's initialized to an empty
  string in the constructor, but can be populated with lower-cased data
  later.

- Adding a helper template class IdentBufferCasedn, which initializes
  to lower case right in the constructor.

- Removing char[] buffers, replacing them to IdentBuffer and IdentBufferCasedn.

- Changing the data type of "db" and "table" parameters from
  "const char*" to LEX_CSTRING in the following functions:

    find_field_in_table_ref()
    insert_fields()
    set_thd_db()
    mysql_grant()

  to reuse IdentBuffer easeir.
This commit is contained in:
Alexander Barkov 2023-08-26 14:39:18 +04:00
parent e0949cd6f0
commit cb37c99dd8
14 changed files with 113 additions and 117 deletions

View File

@ -67,6 +67,10 @@ public:
{
return LEX_CSTRING{m_buff, m_length};
}
const char *ptr() const { return m_buff; }
size_t length() const { return m_length; }
};
#endif // CHAR_BUFFER_INCLUDED

View File

@ -837,7 +837,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
*/
if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
LEX_CSTRING *lexdb= &thd->lex->first_select_lex()->db;
const LEX_CSTRING *lexdb= &thd->lex->first_select_lex()->db;
DBUG_ASSERT(lexdb);
if (!is_infoschema_db(lexdb) && !is_perfschema_db(lexdb) &&
check_access(thd, EVENT_ACL, lexdb->str, NULL, NULL, 0, 0))

View File

@ -5324,7 +5324,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
LEX_CSTRING field_name;
ORDER *found_group= NULL;
int found_match_degree= 0;
char name_buff[SAFE_NAME_LEN+1];
IdentBuffer<SAFE_NAME_LEN> db_name_buff;
if (find_item->type() == Item::FIELD_ITEM ||
find_item->type() == Item::REF_ITEM)
@ -5339,9 +5339,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
if (db_name.str && lower_case_table_names)
{
/* Convert database to lower case for comparison */
strmake_buf(name_buff, db_name.str);
my_casedn_str(files_charset_info, name_buff);
db_name= Lex_cstring_strlen(name_buff);
db_name= db_name_buff.copy_casedn(db_name).to_lex_cstring();
}
DBUG_ASSERT(field_name.str != 0);

View File

@ -3561,8 +3561,9 @@ public:
*/
bool collect_outer_ref_processor(void *arg) override;
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
const char *table_name, List_iterator<Item> *it,
const LEX_CSTRING &db_name,
const LEX_CSTRING &table_name,
List_iterator<Item> *it,
bool any_privileges, bool returning_field);
};

View File

@ -67,6 +67,35 @@ public:
};
template<size_t buff_sz>
class IdentBuffer: public CharBuffer<buff_sz>
{
constexpr static CHARSET_INFO *charset()
{
return &my_charset_utf8mb3_general_ci;
}
public:
IdentBuffer()
{ }
IdentBuffer<buff_sz> & copy_casedn(const LEX_CSTRING &str)
{
CharBuffer<buff_sz>::copy_casedn(charset(), str);
return *this;
}
};
template<size_t buff_sz>
class IdentBufferCasedn: public IdentBuffer<buff_sz>
{
public:
IdentBufferCasedn(const LEX_CSTRING &str)
{
IdentBuffer<buff_sz>::copy_casedn(str);
}
};
/*
A helper class to store temporary database names in a buffer.
After constructing it's typically should be checked using

View File

@ -233,19 +233,12 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
#if defined(HAVE_REPLICATION)
static void set_thd_db(THD *thd, Rpl_filter *rpl_filter,
const char *db, uint32 db_len)
const LEX_CSTRING &db)
{
char lcase_db_buf[NAME_LEN +1];
LEX_CSTRING new_db;
new_db.length= db_len;
if (lower_case_table_names == 1)
{
strmov(lcase_db_buf, db);
my_casedn_str(system_charset_info, lcase_db_buf);
new_db.str= lcase_db_buf;
}
else
new_db.str= db;
IdentBuffer<NAME_LEN> lcase_db_buf;
LEX_CSTRING new_db= lower_case_table_names == 1 ?
lcase_db_buf.copy_casedn(db).to_lex_cstring() :
db;
/* TODO WARNING this makes rewrite_db respect lower_case_table_names values
* for more info look MDEV-17446 */
new_db.str= rpl_filter->get_rewrite_db(new_db.str, &new_db.length);
@ -1890,7 +1883,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
goto end;
}
set_thd_db(thd, rpl_filter, db, db_len);
set_thd_db(thd, rpl_filter, LEX_CSTRING{db, db_len});
/*
Setting the character set and collation of the current database thd->db.

View File

@ -1369,20 +1369,15 @@ Master_info_index::get_master_info(const LEX_CSTRING *connection_name,
Sql_condition::enum_warning_level warning)
{
Master_info *mi;
char buff[MAX_CONNECTION_NAME+1], *res;
size_t buff_length;
DBUG_ENTER("get_master_info");
DBUG_PRINT("enter",
("connection_name: '%.*s'", (int) connection_name->length,
connection_name->str));
/* Make name lower case for comparison */
res= strmake(buff, connection_name->str, connection_name->length);
my_casedn_str(system_charset_info, buff);
buff_length= (size_t) (res-buff);
IdentBufferCasedn<MAX_CONNECTION_NAME> buff(*connection_name);
mi= (Master_info*) my_hash_search(&master_info_hash,
(uchar*) buff, buff_length);
(const uchar*) buff.ptr(), buff.length());
if (!mi && warning != Sql_condition::WARN_LEVEL_NOTE)
{
my_error(WARN_NO_MASTER_INFO,

View File

@ -7849,31 +7849,30 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
}
bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
static
bool mysql_grant(THD *thd, LEX_CSTRING db, List <LEX_USER> &list,
privilege_t rights, bool revoke_grant, bool is_proxy)
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str, *proxied_user= NULL;
char tmp_db[SAFE_NAME_LEN+1];
IdentBuffer<SAFE_NAME_LEN + MY_CS_MBMAXLEN> tmp_db;
bool create_new_users=0;
int result;
DBUG_ENTER("mysql_grant");
if (lower_case_table_names && db)
if (lower_case_table_names && db.str)
{
char *end= strnmov(tmp_db,db, sizeof(tmp_db));
if (end >= tmp_db + sizeof(tmp_db))
if (tmp_db.copy_casedn(db).length() > SAFE_NAME_LEN)
{
my_error(ER_WRONG_DB_NAME ,MYF(0), db);
my_error(ER_WRONG_DB_NAME ,MYF(0), db.str);
DBUG_RETURN(TRUE);
}
my_casedn_str(files_charset_info, tmp_db);
db=tmp_db;
db= tmp_db.to_lex_cstring();
}
if (is_proxy)
{
DBUG_ASSERT(!db);
DBUG_ASSERT(!db.str);
proxied_user= str_list++;
}
@ -7909,20 +7908,20 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
if (copy_and_check_auth(Str, tmp_Str, thd) ||
replace_user_table(thd, tables.user_table(), Str,
(!db ? rights : NO_ACL),
(!db.str ? rights : NO_ACL),
revoke_grant, create_new_users,
MY_TEST(!is_public(Str) &&
(thd->variables.sql_mode &
MODE_NO_AUTO_CREATE_USER))))
result= true;
else if (db)
else if (db.str)
{
privilege_t db_rights(rights & DB_ACLS);
if (db_rights == rights)
{
if (replace_db_table(tables.db_table().table(), db, *Str, db_rights,
revoke_grant))
result= true;
if (replace_db_table(tables.db_table().table(), db.str,
*Str, db_rights, revoke_grant))
result= true;
}
else
{
@ -7938,8 +7937,9 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
}
if (Str->is_role())
propagate_role_grants(find_acl_role(Str->user.str, true),
db ? PRIVS_TO_MERGE::DB : PRIVS_TO_MERGE::GLOBAL,
db);
db.str ? PRIVS_TO_MERGE::DB :
PRIVS_TO_MERGE::GLOBAL,
db.str);
}
mysql_mutex_unlock(&acl_cache->lock);
@ -12269,7 +12269,7 @@ bool Sql_cmd_grant_proxy::execute(THD *thd)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* Conditionally writes to binlog */
if (mysql_grant(thd, NULL/*db*/, lex->users_list, m_grant_option,
if (mysql_grant(thd, null_clex_str/*db*/, lex->users_list, m_grant_option,
is_revoke(), true/*proxy*/))
return true;
@ -12370,7 +12370,7 @@ bool Sql_cmd_grant_table::execute_table_mask(THD *thd)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* Conditionally writes to binlog */
if (mysql_grant(thd, m_db.str, lex->users_list, m_object_privilege,
if (mysql_grant(thd, m_db, lex->users_list, m_object_privilege,
is_revoke(), false/*not proxy*/))
return true;

View File

@ -88,8 +88,6 @@ bool check_change_password(THD *thd, LEX_USER *user);
bool change_password(THD *thd, LEX_USER *user);
bool mysql_grant_role(THD *thd, List<LEX_USER> &user_list, bool revoke);
bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
privilege_t rights, bool revoke, bool is_proxy);
int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
List <LEX_COLUMN> &column_list, privilege_t rights,
bool revoke);

View File

@ -6701,11 +6701,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
bool check_privileges, bool register_tree_change)
{
Field *found=0;
const char *db= item->db_name.str;
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;
char name_buff[SAFE_NAME_LEN+1];
IdentBuffer<SAFE_NAME_LEN> db_name_buff;
TABLE_LIST *cur_table= first_table;
TABLE_LIST *actual_table;
bool allow_rowid;
@ -6713,7 +6713,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
if (!table_name || !table_name[0])
{
table_name= 0; // For easier test
db= 0;
db= Lex_cstring();
}
allow_rowid= table_name || (cur_table && !cur_table->next_local);
@ -6803,16 +6803,14 @@ find_field_in_tables(THD *thd, Item_ident *item,
else
item->can_be_depended= TRUE;
if (db && lower_case_table_names)
if (db.str && lower_case_table_names)
{
/*
convert database to lower case for comparison.
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
*/
strmake_buf(name_buff, db);
my_casedn_str(files_charset_info, name_buff);
db= name_buff;
db= db_name_buff.copy_casedn(db).to_lex_cstring();
}
if (last_table)
@ -6833,7 +6831,8 @@ find_field_in_tables(THD *thd, Item_ident *item,
continue;
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
item->name.str, db, table_name,
item->name.str,
db.str, table_name,
ignored_tables, ref,
(thd->lex->sql_command ==
SQLCOM_SHOW_FIELDS)
@ -6851,7 +6850,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
thd->clear_error();
cur_field= find_field_in_table_ref(thd, cur_table, name, length,
item->name.str, db, table_name,
item->name.str, db.str, table_name,
ignored_tables, ref, false,
allow_rowid,
current_cache,
@ -6890,7 +6889,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
If we found a fully qualified field we return it directly as it can't
have duplicates.
*/
if (db)
if (db.str)
return cur_field;
if (unlikely(found))
@ -6921,9 +6920,9 @@ find_field_in_tables(THD *thd, Item_ident *item,
report_error == REPORT_EXCEPT_NON_UNIQUE))
{
char buff[SAFE_NAME_LEN*2 + 2];
if (db && db[0])
if (db.str && db.str[0])
{
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
strxnmov(buff, sizeof(buff) - 1, db.str, ".", table_name, NullS);
table_name=buff;
}
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
@ -7953,8 +7952,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
MY_INT64_NUM_DECIMAL_DIGITS));
}
else if (insert_fields(thd, ((Item_field*) item)->context,
((Item_field*) item)->db_name.str,
((Item_field*) item)->table_name.str, &it,
((Item_field*) item)->db_name,
((Item_field*) item)->table_name, &it,
any_privileges, &select_lex->hidden_bit_fields, returning_field))
{
if (arena)
@ -8508,26 +8507,27 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
*/
bool
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
const char *table_name, List_iterator<Item> *it,
bool any_privileges, uint *hidden_bit_fields, bool returning_field)
insert_fields(THD *thd, Name_resolution_context *context,
const LEX_CSTRING &db_name_arg, const LEX_CSTRING &table_name,
List_iterator<Item> *it,
bool any_privileges, uint *hidden_bit_fields,
bool returning_field)
{
Field_iterator_table_ref field_iterator;
bool found;
char name_buff[SAFE_NAME_LEN+1];
LEX_CSTRING 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));
if (db_name && lower_case_table_names)
if (db_name.str && lower_case_table_names)
{
/*
convert database to lower case for comparison
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
*/
strmake_buf(name_buff, db_name);
my_casedn_str(files_charset_info, name_buff);
db_name= name_buff;
db_name= db_name_buff.copy_casedn(db_name).to_lex_cstring();
}
found= FALSE;
@ -8539,7 +8539,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
*/
TABLE_LIST *first= context->first_name_resolution_table;
TABLE_LIST *TABLE_LIST::* next= &TABLE_LIST::next_name_resolution_table;
if (table_name && !returning_field)
if (table_name.str && !returning_field)
{
first= context->table_list;
next= &TABLE_LIST::next_local;
@ -8551,9 +8551,9 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
DBUG_ASSERT(tables->is_leaf_for_name_resolution());
if ((table_name && my_strcasecmp(table_alias_charset, table_name,
tables->alias.str)) ||
(db_name && strcmp(tables->db.str, db_name)))
if ((table_name.str && my_strcasecmp(table_alias_charset, table_name.str,
tables->alias.str)) ||
(db_name.str && strcmp(tables->db.str, db_name.str)))
continue;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -8712,15 +8712,15 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
qualified '*', and all columns were coalesced, we have to give a more
meaningful message than ER_BAD_TABLE_ERROR.
*/
if (!table_name)
if (!table_name.str)
my_error(ER_NO_TABLES_USED, MYF(0));
else if (!db_name && !thd->db.str)
else if (!db_name.str && !thd->db.str)
my_error(ER_NO_DB_ERROR, MYF(0));
else
{
char name[FN_REFLEN];
my_snprintf(name, sizeof(name), "%s.%s",
db_name ? db_name : thd->get_db(), table_name);
db_name.str ? db_name.str : thd->get_db(), table_name.str);
my_error(ER_BAD_TABLE_ERROR, MYF(0), name);
}

View File

@ -176,7 +176,7 @@ 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 char *db_name, const char *table_name,
const LEX_CSTRING &db_name, const LEX_CSTRING &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,

View File

@ -5024,7 +5024,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
TABLE tbl;
TABLE_LIST table_list;
uint res= 0;
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
IdentBuffer<NAME_LEN> db_name_buff, table_name_buff;
bzero((char*) &table_list, sizeof(TABLE_LIST));
bzero((char*) &tbl, sizeof(TABLE));
@ -5039,12 +5039,9 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
cache subsystems require normalized (lowercased) database and table
names as input.
*/
strmov(db_name_buff, db_name->str);
strmov(table_name_buff, table_name->str);
table_list.db.length= my_casedn_str(files_charset_info, db_name_buff);
table_list.table_name.length= my_casedn_str(files_charset_info, table_name_buff);
table_list.db.str= db_name_buff;
table_list.table_name.str= table_name_buff;
table_list.db= db_name_buff.copy_casedn(*db_name).to_lex_cstring();
table_list.table_name= table_name_buff.copy_casedn(*table_name).
to_lex_cstring();
}
else
{

View File

@ -647,20 +647,11 @@ void build_lower_case_table_filename(char *buff, size_t bufflen,
const LEX_CSTRING *table,
uint flags)
{
char table_name[SAFE_NAME_LEN+1], db_name[SAFE_NAME_LEN+1];
DBUG_ASSERT(db->length <= SAFE_NAME_LEN && table->length <= SAFE_NAME_LEN);
memcpy(db_name, db->str, db->length);
db_name[db->length]= 0;
my_casedn_str(files_charset_info, db_name);
memcpy(table_name, table->str, table->length);
table_name[table->length]= 0;
my_casedn_str(files_charset_info, table_name);
build_table_filename(buff, bufflen, db_name, table_name, "",
flags & FN_IS_TMP);
build_table_filename(buff, bufflen,
IdentBufferCasedn<SAFE_NAME_LEN>(*db).to_lex_cstring().str,
IdentBufferCasedn<SAFE_NAME_LEN>(*table).to_lex_cstring().str, "",
flags & FN_IS_TMP);
}
@ -9382,25 +9373,19 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
continue;
Foreign_key *fk= static_cast<Foreign_key*>(key);
char dbuf[NAME_LEN];
char tbuf[NAME_LEN];
const char *ref_db= (fk->ref_db.str ?
fk->ref_db.str :
alter_ctx->new_db.str);
const char *ref_table= fk->ref_table.str;
IdentBuffer<NAME_LEN> dbuf, tbuf;
LEX_CSTRING ref_db= fk->ref_db.str ? fk->ref_db : alter_ctx->new_db;
LEX_CSTRING ref_table= fk->ref_table;
MDL_request mdl_request;
if (lower_case_table_names)
{
strmake_buf(dbuf, ref_db);
my_casedn_str(system_charset_info, dbuf);
strmake_buf(tbuf, ref_table);
my_casedn_str(system_charset_info, tbuf);
ref_db= dbuf;
ref_table= tbuf;
ref_db= dbuf.copy_casedn(ref_db).to_lex_cstring();
ref_table= tbuf.copy_casedn(ref_table).to_lex_cstring();
}
MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE, ref_db, ref_table,
MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE,
ref_db.str, ref_table.str,
MDL_SHARED_NO_WRITE, MDL_TRANSACTION);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))

View File

@ -3638,7 +3638,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
Alter_info *alter_info = &lex->alter_info;
List_iterator<Key> key_iterator(alter_info->key_list);
Key *key;
char ref_db_buff[NAME_LEN + 1], ref_table_buff[NAME_LEN + 1];
IdentBuffer<NAME_LEN> ref_db_buff, ref_table_buff;
while ((key = key_iterator++))
{
if (key->type != MRN_KEYTYPE_FOREIGN)
@ -3673,9 +3673,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
#endif
DBUG_PRINT("info", ("mroonga: ref_db_name=%s", ref_db_name.str));
if (ref_db_name.str && lower_case_table_names) {
strmake(ref_db_buff, ref_db_name.str, sizeof(ref_db_buff) - 1);
my_casedn_str(system_charset_info, ref_db_buff);
ref_db_name.str = ref_db_buff;
ref_db_name= ref_db_buff.copy_casedn(ref_db_name).to_lex_cstring();
DBUG_PRINT("info", ("mroonga: casedn ref_db_name=%s", ref_db_name.str));
}
#ifdef MRN_FOREIGN_KEY_USE_CONST_STRING
@ -3685,9 +3683,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
#endif
DBUG_PRINT("info", ("mroonga: ref_table_name=%s", ref_table_name.str));
if (ref_table_name.str && lower_case_table_names) {
strmake(ref_table_buff, ref_table_name.str, sizeof(ref_table_buff) - 1);
my_casedn_str(system_charset_info, ref_table_buff);
ref_table_name.str = ref_table_buff;
ref_table_name= ref_table_buff.copy_casedn(ref_table_name).to_lex_cstring();
DBUG_PRINT("info", ("mroonga: casedn ref_table_name=%s", ref_table_name.str));
}
if (ref_db_name.str && strcmp(table->s->db.str, ref_db_name.str))