Skip to content

Commit 030d1a1

Browse files
author
ramil/ram@ramil.myoffice.izhnet.ru
committed
Merge mysql.com:/home/ram/work/mysql-5.1-maint
into mysql.com:/home/ram/work/b30654/b30654.5.1
2 parents 9d57de1 + 0a11bc2 commit 030d1a1

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

client/mysqlcheck.c

+38-14
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ static void dbDisconnect(char *host);
206206
static void DBerror(MYSQL *mysql, const char *when);
207207
static void safe_exit(int error);
208208
static void print_result();
209+
static uint fixed_name_length(const char *name);
209210
static char *fix_table_name(char *dest, char *src);
210211
int what_to_do = 0;
211212

@@ -438,14 +439,14 @@ static int process_selected_tables(char *db, char **table_names, int tables)
438439
{
439440
/*
440441
We need table list in form `a`, `b`, `c`
441-
that's why we need 4 more chars added to to each table name
442+
that's why we need 2 more chars added to to each table name
442443
space is for more readable output in logs and in case of error
443444
*/
444445
char *table_names_comma_sep, *end;
445446
int i, tot_length = 0;
446447

447448
for (i = 0; i < tables; i++)
448-
tot_length += strlen(*(table_names + i)) + 4;
449+
tot_length+= fixed_name_length(*(table_names + i)) + 2;
449450

450451
if (!(table_names_comma_sep = (char *)
451452
my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
@@ -463,23 +464,46 @@ static int process_selected_tables(char *db, char **table_names, int tables)
463464
}
464465
else
465466
for (; tables > 0; tables--, table_names++)
466-
handle_request_for_tables(*table_names, strlen(*table_names));
467+
handle_request_for_tables(*table_names, fixed_name_length(*table_names));
467468
return 0;
468469
} /* process_selected_tables */
469470

470471

471-
static char *fix_table_name(char *dest, char *src)
472+
static uint fixed_name_length(const char *name)
472473
{
473-
char *db_sep;
474+
const char *p;
475+
uint extra_length= 2; /* count the first/last backticks */
476+
477+
for (p= name; *p; p++)
478+
{
479+
if (*p == '`')
480+
extra_length++;
481+
else if (*p == '.')
482+
extra_length+= 2;
483+
}
484+
return (p - name) + extra_length;
485+
}
486+
474487

488+
static char *fix_table_name(char *dest, char *src)
489+
{
475490
*dest++= '`';
476-
if ((db_sep= strchr(src, '.')))
491+
for (; *src; src++)
477492
{
478-
dest= strmake(dest, src, (uint) (db_sep - src));
479-
dest= strmov(dest, "`.`");
480-
src= db_sep + 1;
493+
switch (*src) {
494+
case '.': /* add backticks around '.' */
495+
*dest++= '`';
496+
*dest++= '.';
497+
*dest++= '`';
498+
break;
499+
case '`': /* escape backtick character */
500+
*dest++= '`';
501+
/* fall through */
502+
default:
503+
*dest++= *src;
504+
}
481505
}
482-
dest= strxmov(dest, src, "`", NullS);
506+
*dest++= '`';
483507
return dest;
484508
}
485509

@@ -500,15 +524,15 @@ static int process_all_tables_in_db(char *database)
500524
{
501525
/*
502526
We need table list in form `a`, `b`, `c`
503-
that's why we need 4 more chars added to to each table name
527+
that's why we need 2 more chars added to to each table name
504528
space is for more readable output in logs and in case of error
505529
*/
506530

507531
char *tables, *end;
508532
uint tot_length = 0;
509533

510534
while ((row = mysql_fetch_row(res)))
511-
tot_length += strlen(row[0]) + 4;
535+
tot_length+= fixed_name_length(row[0]) + 2;
512536
mysql_data_seek(res, 0);
513537

514538
if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
@@ -536,7 +560,7 @@ static int process_all_tables_in_db(char *database)
536560
/* Skip tables with an engine of NULL (probably a view). */
537561
if (row[1])
538562
{
539-
handle_request_for_tables(row[0], strlen(row[0]));
563+
handle_request_for_tables(row[0], fixed_name_length(row[0]));
540564
}
541565
}
542566
mysql_free_result(res);
@@ -826,7 +850,7 @@ int main(int argc, char **argv)
826850
for (i = 0; i < tables4repair.elements ; i++)
827851
{
828852
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
829-
handle_request_for_tables(name, strlen(name));
853+
handle_request_for_tables(name, fixed_name_length(name));
830854
}
831855
}
832856
end:

mysql-test/r/mysqlcheck.result

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
DROP TABLE IF EXISTS t1;
1+
DROP TABLE IF EXISTS t1, `t``1`, `t 1`;
22
drop view if exists v1;
33
drop database if exists client_test_db;
44
mysql.columns_priv OK
@@ -57,4 +57,9 @@ test.t1 OK
5757
test.t1 OK
5858
drop view v1;
5959
drop table t1;
60+
create table `t``1`(a int);
61+
create table `t 1`(a int);
62+
test.t 1 OK
63+
test.t`1 OK
64+
drop table `t``1`, `t 1`;
6065
End of 5.0 tests

mysql-test/t/mysqlcheck.test

+10-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212

1313
--disable_warnings
14-
DROP TABLE IF EXISTS t1;
14+
DROP TABLE IF EXISTS t1, `t``1`, `t 1`;
1515
drop view if exists v1;
1616
drop database if exists client_test_db;
1717
--enable_warnings
@@ -37,4 +37,13 @@ create view v1 as select * from t1;
3737
drop view v1;
3838
drop table t1;
3939

40+
#
41+
# Bug #30654: mysqlcheck fails during upgrade of tables whose names include backticks
42+
#
43+
create table `t``1`(a int);
44+
create table `t 1`(a int);
45+
--replace_result 'Table is already up to date' OK
46+
--exec $MYSQL_CHECK --databases test
47+
drop table `t``1`, `t 1`;
48+
4049
--echo End of 5.0 tests

0 commit comments

Comments
 (0)