Fix for bug #30654: mysqlcheck fails during upgrade of tables whose

names include backticks or blank

Problem: mysqlcheck doesn't escape backtick characters in the table names.

Fix: escape them.
parent 4d44d8b3
......@@ -186,6 +186,7 @@ static void dbDisconnect(char *host);
static void DBerror(MYSQL *mysql, const char *when);
static void safe_exit(int error);
static void print_result();
static uint fixed_name_length(const char *name);
static char *fix_table_name(char *dest, char *src);
int what_to_do = 0;
......@@ -409,14 +410,14 @@ static int process_selected_tables(char *db, char **table_names, int tables)
{
/*
We need table list in form `a`, `b`, `c`
that's why we need 4 more chars added to to each table name
that's why we need 2 more chars added to to each table name
space is for more readable output in logs and in case of error
*/
char *table_names_comma_sep, *end;
int i, tot_length = 0;
for (i = 0; i < tables; i++)
tot_length += strlen(*(table_names + i)) + 4;
tot_length+= fixed_name_length(*(table_names + i)) + 2;
if (!(table_names_comma_sep = (char *)
my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
......@@ -434,23 +435,46 @@ static int process_selected_tables(char *db, char **table_names, int tables)
}
else
for (; tables > 0; tables--, table_names++)
handle_request_for_tables(*table_names, strlen(*table_names));
handle_request_for_tables(*table_names, fixed_name_length(*table_names));
return 0;
} /* process_selected_tables */
static char *fix_table_name(char *dest, char *src)
static uint fixed_name_length(const char *name)
{
char *db_sep;
const char *p;
uint extra_length= 2; /* count the first/last backticks */
for (p= name; *p; p++)
{
if (*p == '`')
extra_length++;
else if (*p == '.')
extra_length+= 2;
}
return (p - name) + extra_length;
}
static char *fix_table_name(char *dest, char *src)
{
*dest++= '`';
if ((db_sep= strchr(src, '.')))
for (; *src; src++)
{
dest= strmake(dest, src, (uint) (db_sep - src));
dest= strmov(dest, "`.`");
src= db_sep + 1;
switch (*src) {
case '.': /* add backticks around '.' */
*dest++= '`';
*dest++= '.';
*dest++= '`';
break;
case '`': /* escape backtick character */
*dest++= '`';
/* fall through */
default:
*dest++= *src;
}
}
dest= strxmov(dest, src, "`", NullS);
*dest++= '`';
return dest;
}
......@@ -471,7 +495,7 @@ static int process_all_tables_in_db(char *database)
{
/*
We need table list in form `a`, `b`, `c`
that's why we need 4 more chars added to to each table name
that's why we need 2 more chars added to to each table name
space is for more readable output in logs and in case of error
*/
......@@ -479,7 +503,7 @@ static int process_all_tables_in_db(char *database)
uint tot_length = 0;
while ((row = mysql_fetch_row(res)))
tot_length += strlen(row[0]) + 4;
tot_length+= fixed_name_length(row[0]) + 2;
mysql_data_seek(res, 0);
if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
......@@ -507,7 +531,7 @@ static int process_all_tables_in_db(char *database)
/* Skip tables with an engine of NULL (probably a view). */
if (row[1])
{
handle_request_for_tables(row[0], strlen(row[0]));
handle_request_for_tables(row[0], fixed_name_length(row[0]));
}
}
mysql_free_result(res);
......@@ -741,7 +765,7 @@ int main(int argc, char **argv)
for (i = 0; i < tables4repair.elements ; i++)
{
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
handle_request_for_tables(name, strlen(name));
handle_request_for_tables(name, fixed_name_length(name));
}
}
end:
......
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1, `t``1`, `t 1`;
drop view if exists v1;
drop database if exists client_test_db;
mysql.columns_priv OK
......@@ -41,4 +41,9 @@ test.t1 OK
test.t1 OK
drop view v1;
drop table t1;
create table `t``1`(a int);
create table `t 1`(a int);
test.t 1 OK
test.t`1 OK
drop table `t``1`, `t 1`;
End of 5.0 tests
......@@ -2,7 +2,7 @@
#
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1, `t``1`, `t 1`;
drop view if exists v1;
drop database if exists client_test_db;
--enable_warnings
......@@ -31,4 +31,13 @@ create view v1 as select * from t1;
drop view v1;
drop table t1;
#
# Bug #30654: mysqlcheck fails during upgrade of tables whose names include backticks
#
create table `t``1`(a int);
create table `t 1`(a int);
--replace_result 'Table is already up to date' OK
--exec $MYSQL_CHECK --databases test
drop table `t``1`, `t 1`;
--echo End of 5.0 tests
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment