Bug #109002 filename_to_tablename() handles temp table's name "p0#tmp" incorrectly
Description:
When running a REBUILD PARTITION p0 command on a paritioned table tr, the server will generate a temporary table named "p0#tmp" to store records from old partition.
Look at the codes of function filename_to_tablename():
```
size_t filename_to_tablename(const char *from, char *to, size_t to_length,
bool stay_quiet, bool *has_errors) {
uint errors;
size_t res;
DBUG_TRACE;
DBUG_PRINT("enter", ("from '%s'", from));
if (has_errors != nullptr) *has_errors = false;
if (strlen(from) >= tmp_file_prefix_length &&
!memcmp(from, tmp_file_prefix, tmp_file_prefix_length)) {
/* Temporary table name. */
res = (my_stpnmov(to, from, to_length) - to);
} else {
res = strconvert(&my_charset_filename, from, system_charset_info, to,
to_length, &errors);
if (errors) // Old 5.0 name
{
if (has_errors != nullptr) *has_errors = true;
if (!stay_quiet) {
LogErr(ERROR_LEVEL, ER_INVALID_OR_OLD_TABLE_OR_DB_NAME, from);
}
/*
TODO: add a stored procedure for fix table and database names,
and mention its name in error log.
*/
}
}
DBUG_PRINT("exit", ("to '%s'", to));
return res;
}
```
When the function filename_to_tablename() is called on the temporary table, it cannot recognize it as temporary table since the tmp_file_prefix is "#sql". What it does is trying converting the name using strconvert() with my_charset_filename, but it cannot deal with the character '#', so strconvert() returns with result "p0?tmp" and causes the caller wrongly printing an error ER_INVALID_OR_OLD_TABLE_OR_DB_NAME to the log.
How to repeat:
As above
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.038 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: When running a REBUILD PARTITION p0 command on a paritioned table tr, the server will generate a temporary table named "p0#tmp" to store records from old partition. Look at the codes of function filename_to_tablename(): ``` size_t filename_to_tablename(const char *from, char *to, size_t to_length, bool stay_quiet, bool *has_errors) { uint errors; size_t res; DBUG_TRACE; DBUG_PRINT("enter", ("from '%s'", from)); if (has_errors != nullptr) *has_errors = false; if (strlen(from) >= tmp_file_prefix_length && !memcmp(from, tmp_file_prefix, tmp_file_prefix_length)) { /* Temporary table name. */ res = (my_stpnmov(to, from, to_length) - to); } else { res = strconvert(&my_charset_filename, from, system_charset_info, to, to_length, &errors); if (errors) // Old 5.0 name { if (has_errors != nullptr) *has_errors = true; if (!stay_quiet) { LogErr(ERROR_LEVEL, ER_INVALID_OR_OLD_TABLE_OR_DB_NAME, from); } /* TODO: add a stored procedure for fix table and database names, and mention its name in error log. */ } } DBUG_PRINT("exit", ("to '%s'", to)); return res; } ``` When the function filename_to_tablename() is called on the temporary table, it cannot recognize it as temporary table since the tmp_file_prefix is "#sql". What it does is trying converting the name using strconvert() with my_charset_filename, but it cannot deal with the character '#', so strconvert() returns with result "p0?tmp" and causes the caller wrongly printing an error ER_INVALID_OR_OLD_TABLE_OR_DB_NAME to the log. How to repeat: As above