mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names
a correct fix: * store properly quoted table names in tables4repair/etc lists * tell handle_request_for_tables whether the name is aalready properly quoted * test cases for all uses of fix_table_name()
This commit is contained in:
@ -232,7 +232,7 @@ static int process_selected_tables(char *db, char **table_names, int tables);
|
|||||||
static int process_all_tables_in_db(char *database);
|
static int process_all_tables_in_db(char *database);
|
||||||
static int process_one_db(char *database);
|
static int process_one_db(char *database);
|
||||||
static int use_db(char *database);
|
static int use_db(char *database);
|
||||||
static int handle_request_for_tables(char *tables, size_t length, my_bool view);
|
static int handle_request_for_tables(char *, size_t, my_bool, my_bool);
|
||||||
static int dbConnect(char *host, char *user,char *passwd);
|
static int dbConnect(char *host, char *user,char *passwd);
|
||||||
static void dbDisconnect(char *host);
|
static void dbDisconnect(char *host);
|
||||||
static void DBerror(MYSQL *mysql, const char *when);
|
static void DBerror(MYSQL *mysql, const char *when);
|
||||||
@ -566,7 +566,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
|
|||||||
}
|
}
|
||||||
*--end = 0;
|
*--end = 0;
|
||||||
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1,
|
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1,
|
||||||
opt_do_views != 0);
|
opt_do_views != 0, opt_all_in_1);
|
||||||
my_free(table_names_comma_sep);
|
my_free(table_names_comma_sep);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -577,7 +577,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
|
|||||||
view= is_view(table);
|
view= is_view(table);
|
||||||
if (view < 0)
|
if (view < 0)
|
||||||
continue;
|
continue;
|
||||||
handle_request_for_tables(table, table_len, (view == 1));
|
handle_request_for_tables(table, table_len, view == 1, opt_all_in_1);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
} /* process_selected_tables */
|
} /* process_selected_tables */
|
||||||
@ -605,13 +605,9 @@ static char *fix_table_name(char *dest, char *src)
|
|||||||
*dest++= '`';
|
*dest++= '`';
|
||||||
for (; *src; src++)
|
for (; *src; src++)
|
||||||
{
|
{
|
||||||
switch (*src) {
|
if (*src == '`')
|
||||||
case '`': /* escape backtick character */
|
|
||||||
*dest++= '`';
|
*dest++= '`';
|
||||||
/* fall through */
|
*dest++= *src;
|
||||||
default:
|
|
||||||
*dest++= *src;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*dest++= '`';
|
*dest++= '`';
|
||||||
|
|
||||||
@ -700,9 +696,9 @@ static int process_all_tables_in_db(char *database)
|
|||||||
*--end = 0;
|
*--end = 0;
|
||||||
*--views_end = 0;
|
*--views_end = 0;
|
||||||
if (tot_length)
|
if (tot_length)
|
||||||
handle_request_for_tables(tables + 1, tot_length - 1, FALSE);
|
handle_request_for_tables(tables + 1, tot_length - 1, FALSE, opt_all_in_1);
|
||||||
if (tot_views_length)
|
if (tot_views_length)
|
||||||
handle_request_for_tables(views + 1, tot_views_length - 1, TRUE);
|
handle_request_for_tables(views + 1, tot_views_length - 1, TRUE, opt_all_in_1);
|
||||||
my_free(tables);
|
my_free(tables);
|
||||||
my_free(views);
|
my_free(views);
|
||||||
}
|
}
|
||||||
@ -728,7 +724,7 @@ static int process_all_tables_in_db(char *database)
|
|||||||
!strcmp(row[0], "slow_log")))
|
!strcmp(row[0], "slow_log")))
|
||||||
continue; /* Skip logging tables */
|
continue; /* Skip logging tables */
|
||||||
|
|
||||||
handle_request_for_tables(row[0], fixed_name_length(row[0]), view);
|
handle_request_for_tables(row[0], fixed_name_length(row[0]), view, opt_all_in_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
@ -787,13 +783,11 @@ static int rebuild_table(char *name)
|
|||||||
int rc= 0;
|
int rc= 0;
|
||||||
DBUG_ENTER("rebuild_table");
|
DBUG_ENTER("rebuild_table");
|
||||||
|
|
||||||
query= (char*)my_malloc(sizeof(char) * (12 + fixed_name_length(name) + 6 + 1),
|
query= (char*)my_malloc(sizeof(char) * (12 + strlen(name) + 6 + 1),
|
||||||
MYF(MY_WME));
|
MYF(MY_WME));
|
||||||
if (!query)
|
if (!query)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
ptr= strmov(query, "ALTER TABLE ");
|
ptr= strxmov(query, "ALTER TABLE ", name, " FORCE", NullS);
|
||||||
ptr= fix_table_name(ptr, name);
|
|
||||||
ptr= strxmov(ptr, " FORCE", NullS);
|
|
||||||
if (mysql_real_query(sock, query, (ulong)(ptr - query)))
|
if (mysql_real_query(sock, query, (ulong)(ptr - query)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to %s\n", query);
|
fprintf(stderr, "Failed to %s\n", query);
|
||||||
@ -849,7 +843,8 @@ static int disable_binlog()
|
|||||||
return run_query(stmt);
|
return run_query(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_request_for_tables(char *tables, size_t length, my_bool view)
|
static int handle_request_for_tables(char *tables, size_t length,
|
||||||
|
my_bool view, my_bool dont_quote)
|
||||||
{
|
{
|
||||||
char *query, *end, options[100], message[100];
|
char *query, *end, options[100], message[100];
|
||||||
char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name;
|
char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name;
|
||||||
@ -907,7 +902,7 @@ static int handle_request_for_tables(char *tables, size_t length, my_bool view)
|
|||||||
|
|
||||||
if (!(query =(char *) my_malloc(query_size, MYF(MY_WME))))
|
if (!(query =(char *) my_malloc(query_size, MYF(MY_WME))))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (opt_all_in_1)
|
if (dont_quote)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size);
|
DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size);
|
||||||
|
|
||||||
@ -950,6 +945,13 @@ static int handle_request_for_tables(char *tables, size_t length, my_bool view)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void insert_table_name(DYNAMIC_ARRAY *arr, char *in, size_t dblen)
|
||||||
|
{
|
||||||
|
char buf[NAME_LEN*2+2];
|
||||||
|
in[dblen]= 0;
|
||||||
|
my_snprintf(buf, sizeof(buf), "%`s.%`s", in, in + dblen + 1);
|
||||||
|
insert_dynamic(arr, (uchar*) buf);
|
||||||
|
}
|
||||||
|
|
||||||
static void print_result()
|
static void print_result()
|
||||||
{
|
{
|
||||||
@ -957,16 +959,13 @@ static void print_result()
|
|||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
char prev[(NAME_LEN+9)*3+2];
|
char prev[(NAME_LEN+9)*3+2];
|
||||||
char prev_alter[MAX_ALTER_STR_SIZE];
|
char prev_alter[MAX_ALTER_STR_SIZE];
|
||||||
char *db_name;
|
size_t length_of_db= strlen(sock->db);
|
||||||
uint length_of_db;
|
|
||||||
uint i;
|
uint i;
|
||||||
my_bool found_error=0, table_rebuild=0;
|
my_bool found_error=0, table_rebuild=0;
|
||||||
DYNAMIC_ARRAY *array4repair= &tables4repair;
|
DYNAMIC_ARRAY *array4repair= &tables4repair;
|
||||||
DBUG_ENTER("print_result");
|
DBUG_ENTER("print_result");
|
||||||
|
|
||||||
res = mysql_use_result(sock);
|
res = mysql_use_result(sock);
|
||||||
db_name= sock->db;
|
|
||||||
length_of_db= strlen(db_name);
|
|
||||||
|
|
||||||
prev[0] = '\0';
|
prev[0] = '\0';
|
||||||
prev_alter[0]= 0;
|
prev_alter[0]= 0;
|
||||||
@ -990,16 +989,10 @@ static void print_result()
|
|||||||
if (prev_alter[0])
|
if (prev_alter[0])
|
||||||
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
|
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
|
||||||
else
|
else
|
||||||
{
|
insert_table_name(&tables4rebuild, prev, length_of_db);
|
||||||
char *table_name= prev + (length_of_db+1);
|
|
||||||
insert_dynamic(&tables4rebuild, (uchar*) table_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
insert_table_name(array4repair, prev, length_of_db);
|
||||||
char *table_name= prev + (length_of_db+1);
|
|
||||||
insert_dynamic(array4repair, (uchar*) table_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
array4repair= &tables4repair;
|
array4repair= &tables4repair;
|
||||||
found_error=0;
|
found_error=0;
|
||||||
@ -1066,16 +1059,10 @@ static void print_result()
|
|||||||
if (prev_alter[0])
|
if (prev_alter[0])
|
||||||
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
|
insert_dynamic(&alter_table_cmds, (uchar*) prev_alter);
|
||||||
else
|
else
|
||||||
{
|
insert_table_name(&tables4rebuild, prev, length_of_db);
|
||||||
char *table_name= prev + (length_of_db+1);
|
|
||||||
insert_dynamic(&tables4rebuild, (uchar*) table_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
insert_table_name(array4repair, prev, length_of_db);
|
||||||
char *table_name= prev + (length_of_db+1);
|
|
||||||
insert_dynamic(array4repair, (uchar*) table_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -1209,7 +1196,7 @@ int main(int argc, char **argv)
|
|||||||
for (i = 0; i < tables4repair.elements ; i++)
|
for (i = 0; i < tables4repair.elements ; i++)
|
||||||
{
|
{
|
||||||
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
|
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
|
||||||
handle_request_for_tables(name, fixed_name_length(name), FALSE);
|
handle_request_for_tables(name, fixed_name_length(name), FALSE, TRUE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < tables4rebuild.elements ; i++)
|
for (i = 0; i < tables4rebuild.elements ; i++)
|
||||||
rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i));
|
rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i));
|
||||||
@ -1220,7 +1207,7 @@ int main(int argc, char **argv)
|
|||||||
for (i = 0; i < views4repair.elements ; i++)
|
for (i = 0; i < views4repair.elements ; i++)
|
||||||
{
|
{
|
||||||
char *name= (char*) dynamic_array_ptr(&views4repair, i);
|
char *name= (char*) dynamic_array_ptr(&views4repair, i);
|
||||||
handle_request_for_tables(name, fixed_name_length(name), TRUE);
|
handle_request_for_tables(name, fixed_name_length(name), TRUE, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret= test(first_error);
|
ret= test(first_error);
|
||||||
|
@ -312,10 +312,37 @@ DROP TABLE bug47205;
|
|||||||
#
|
#
|
||||||
#MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names
|
#MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names
|
||||||
#
|
#
|
||||||
CREATE TABLE test.`t.1` (id int);
|
create table `t.1` (id int);
|
||||||
|
create view `v.1` as select 1;
|
||||||
mysqlcheck test t.1
|
mysqlcheck test t.1
|
||||||
test.t.1 OK
|
test.t.1 OK
|
||||||
drop table test.`t.1`;
|
mysqlcheck --all-in-1 test t.1
|
||||||
|
test.t.1 OK
|
||||||
|
mysqlcheck --all-in-1 --databases --process-views test
|
||||||
|
test.t.1 OK
|
||||||
|
test.v.1 OK
|
||||||
|
create table `t.2`(a varchar(20) primary key) default character set utf8 collate utf8_general_ci engine=innodb;
|
||||||
|
flush table `t.2`;
|
||||||
|
mysqlcheck --check-upgrade --auto-repair test
|
||||||
|
test.t.1 OK
|
||||||
|
test.t.2
|
||||||
|
error : Table rebuild required. Please do "ALTER TABLE `t.2` FORCE" or dump/reload to fix it!
|
||||||
|
test.t.3 Needs upgrade
|
||||||
|
|
||||||
|
Repairing tables
|
||||||
|
test.t.3 OK
|
||||||
|
check table `t.1`, `t.2`, `t.3`;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t.1 check status OK
|
||||||
|
test.t.2 check status OK
|
||||||
|
test.t.3 check status OK
|
||||||
|
check table `t.1`, `t.2`, `t.3` for upgrade;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t.1 check status OK
|
||||||
|
test.t.2 check status OK
|
||||||
|
test.t.3 check status OK
|
||||||
|
drop view `v.1`;
|
||||||
|
drop table test.`t.1`, `t.2`, `t.3`;
|
||||||
create view v1 as select 1;
|
create view v1 as select 1;
|
||||||
mysqlcheck --process-views test
|
mysqlcheck --process-views test
|
||||||
test.v1 OK
|
test.v1 OK
|
||||||
@ -344,3 +371,48 @@ show tables;
|
|||||||
Tables_in_test
|
Tables_in_test
|
||||||
t1`1
|
t1`1
|
||||||
drop table `t1``1`;
|
drop table `t1``1`;
|
||||||
|
call mtr.add_suppression("ha_myisam");
|
||||||
|
call mtr.add_suppression("Checking table");
|
||||||
|
create database mysqltest1;
|
||||||
|
create table mysqltest1.t1 (a int) engine=myisam;
|
||||||
|
create table t2 (a int);
|
||||||
|
check table mysqltest1.t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysqltest1.t1 check warning Size of datafile is: 4 Should be: 0
|
||||||
|
mysqltest1.t1 check error got error: 0 when reading datafile at record: 0
|
||||||
|
mysqltest1.t1 check error Corrupt
|
||||||
|
mtr.global_suppressions Table is already up to date
|
||||||
|
mtr.test_suppressions Table is already up to date
|
||||||
|
mysql.columns_priv Table is already up to date
|
||||||
|
mysql.db Table is already up to date
|
||||||
|
mysql.event Table is already up to date
|
||||||
|
mysql.func Table is already up to date
|
||||||
|
mysql.help_category Table is already up to date
|
||||||
|
mysql.help_keyword Table is already up to date
|
||||||
|
mysql.help_relation Table is already up to date
|
||||||
|
mysql.help_topic Table is already up to date
|
||||||
|
mysql.host Table is already up to date
|
||||||
|
mysql.ndb_binlog_index Table is already up to date
|
||||||
|
mysql.plugin Table is already up to date
|
||||||
|
mysql.proc Table is already up to date
|
||||||
|
mysql.procs_priv Table is already up to date
|
||||||
|
mysql.proxies_priv Table is already up to date
|
||||||
|
mysql.servers Table is already up to date
|
||||||
|
mysql.tables_priv Table is already up to date
|
||||||
|
mysql.time_zone Table is already up to date
|
||||||
|
mysql.time_zone_leap_second Table is already up to date
|
||||||
|
mysql.time_zone_name Table is already up to date
|
||||||
|
mysql.time_zone_transition Table is already up to date
|
||||||
|
mysql.time_zone_transition_type Table is already up to date
|
||||||
|
mysql.user Table is already up to date
|
||||||
|
mysqltest1.t1
|
||||||
|
warning : Table is marked as crashed
|
||||||
|
warning : Size of datafile is: 4 Should be: 0
|
||||||
|
error : got error: 0 when reading datafile at record: 0
|
||||||
|
error : Corrupt
|
||||||
|
test.t2 Table is already up to date
|
||||||
|
|
||||||
|
Repairing tables
|
||||||
|
mysqltest1.t1 OK
|
||||||
|
drop table t2;
|
||||||
|
drop database mysqltest1;
|
||||||
|
@ -310,15 +310,36 @@ CHECK TABLE bug47205 FOR UPGRADE;
|
|||||||
|
|
||||||
DROP TABLE bug47205;
|
DROP TABLE bug47205;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo #MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names
|
--echo #MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names
|
||||||
--echo #
|
--echo #
|
||||||
CREATE TABLE test.`t.1` (id int);
|
create table `t.1` (id int);
|
||||||
|
create view `v.1` as select 1;
|
||||||
|
|
||||||
--echo mysqlcheck test t.1
|
--echo mysqlcheck test t.1
|
||||||
--exec $MYSQL_CHECK test t.1
|
--exec $MYSQL_CHECK test t.1
|
||||||
|
--echo mysqlcheck --all-in-1 test t.1
|
||||||
|
--exec $MYSQL_CHECK --all-in-1 test t.1
|
||||||
|
--echo mysqlcheck --all-in-1 --databases --process-views test
|
||||||
|
--exec $MYSQL_CHECK --all-in-1 --databases --process-views test
|
||||||
|
|
||||||
drop table test.`t.1`;
|
create table `t.2`(a varchar(20) primary key) default character set utf8 collate utf8_general_ci engine=innodb;
|
||||||
|
flush table `t.2`;
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t@002e2.frm
|
||||||
|
--copy_file std_data/bug47205.frm $MYSQLD_DATADIR/test/t@002e2.frm
|
||||||
|
|
||||||
|
--copy_file std_data/bug36055.frm $MYSQLD_DATADIR/test/t@002e3.frm
|
||||||
|
--copy_file std_data/bug36055.MYD $MYSQLD_DATADIR/test/t@002e3.MYD
|
||||||
|
--copy_file std_data/bug36055.MYI $MYSQLD_DATADIR/test/t@002e3.MYI
|
||||||
|
|
||||||
|
--echo mysqlcheck --check-upgrade --auto-repair test
|
||||||
|
--exec $MYSQL_CHECK --check-upgrade --auto-repair test
|
||||||
|
|
||||||
|
check table `t.1`, `t.2`, `t.3`;
|
||||||
|
check table `t.1`, `t.2`, `t.3` for upgrade;
|
||||||
|
drop view `v.1`;
|
||||||
|
drop table test.`t.1`, `t.2`, `t.3`;
|
||||||
|
|
||||||
#
|
#
|
||||||
# MDEV-8123 mysqlcheck: new --process-views option conflicts with --quick, --extended and such
|
# MDEV-8123 mysqlcheck: new --process-views option conflicts with --quick, --extended and such
|
||||||
@ -355,3 +376,25 @@ create table `#mysql50#t1``1` (a int) engine=myisam;
|
|||||||
--exec $MYSQL_CHECK --fix-table-names --databases test
|
--exec $MYSQL_CHECK --fix-table-names --databases test
|
||||||
show tables;
|
show tables;
|
||||||
drop table `t1``1`;
|
drop table `t1``1`;
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-9440 mysqlcheck -A --auto-repair selects wrong database when trying to repair broken table
|
||||||
|
#
|
||||||
|
call mtr.add_suppression("ha_myisam");
|
||||||
|
call mtr.add_suppression("Checking table");
|
||||||
|
create database mysqltest1;
|
||||||
|
create table mysqltest1.t1 (a int) engine=myisam;
|
||||||
|
create table t2 (a int);
|
||||||
|
|
||||||
|
let $datadir= `select @@datadir`;
|
||||||
|
remove_file $datadir/mysqltest1/t1.MYD;
|
||||||
|
write_file $datadir/mysqltest1/t1.MYD;
|
||||||
|
foo
|
||||||
|
EOF
|
||||||
|
|
||||||
|
check table mysqltest1.t1;
|
||||||
|
|
||||||
|
--exec $MYSQL_CHECK -A --auto-repair --fast
|
||||||
|
|
||||||
|
drop table t2;
|
||||||
|
drop database mysqltest1;
|
||||||
|
Reference in New Issue
Block a user