Bug #3891 drop table with lots of arguments gives wrong error
Submitted: 26 May 2004 1:00 Modified: 2 Apr 2005 18:55
Reporter: mattias guns Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:4.0.18-log OS:Linux (debian GNU/Linux)
Assigned to: Sergei Golubchik CPU Architecture:Any

[26 May 2004 1:00] mattias guns
Description:
When you do a 'DROP TABLE' with a lot of unexisting tables, the error message will change its output.

How to repeat:
When u drop multiple tables that do not exist, u get a nice error:

DROP TABLE `table1`, `table2`, `table3`, `table4`, `table5`, `table6`, `table7`, `table8`;
ERROR 1051: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8'

now if u increase the number of unexisting tables:
mysql> DROP TABLE `table1`, `table2`, `table3`, `table4`, `table5`, `table6`, `table7`, `table8`, `table9`, `table10`, `table11`, `table12`, `table13`, `table14`, `table15`, `table16`, `table17`, `table18`, `table19`, `table20`, `table21`, `table22`, `table23`, `table24`, `table25`, `table26`, `table27`, `table28`;
ERROR 1051: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table24,t

[it stops after 'table24,t']

and eventually, if u wanna drop a LOT of unexisting tables (always fun):
mysql> DROP TABLE `table1`, `table2`, `table3`, `table4`, `table5`, `table6`, `table7`, `table8`, `table9`, `table10`, `table11`, `table12`, `table13`, `table14`, `table15`, `table16`, `table17`, `table18`, `table19`, `table20`, `table21`, `table22`, `table23`, `table24`, `table25`, `table26`, `table27`, `table28`, `table29`, `table30`;
ERROR 1051: Unknown table '%s'

It's not much of a bug, but i think its related to a replication error i have (see other bugreport)
[26 May 2004 16:29] Dean Ellis
Verified against 4.0.20.  Thank you for reporting this.
[7 Jun 2004 2:09] Antony Curtis
As of rev 1.1880 on 4.0 tree, error is being emitted on line 254 of 
sql/sql_table.cc... 
 
  if (wrong_tables.length()) 
  { 
    if (!foreign_key_error) 
      my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); 
    else 
 
The current error strings only permit up to 64 chars. Originally meant for one 
table per error message.  Suggest sending the user a warning for each 
nonexistant table finishing which an error message for 'incomplete action'.
[12 Aug 2004 18:26] Antony Curtis
Limitation in the client C library - only 200 characters for error messages. 
(MYSQL_ERRMSG_SIZE) 
Changing this may introduce incompatibilities with binaries compiled with older 
headers due to lack of opaqueness. 
 
The bad error result from the server can be fixed by the following patch (however, 
message will still be truncated by client C lib): 
 
===== sql/sql_table.cc 1.180 vs edited ===== 
--- 1.180/sql/sql_table.cc      2004-07-17 15:58:13 +01:00 
+++ edited/sql/sql_table.cc     2004-08-12 17:10:15 +01:00 
@@ -235,7 +235,15 @@ 
   if (wrong_tables.length()) 
   { 
     if (!foreign_key_error) 
-      my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); 
+    { 
+      char msg[128]; 
+      String message; 
+      message.alloc(snprintf(msg, 128, ER(ER_BAD_TABLE_ERROR), "%s") 
+                  +wrong_tables.length()); 
+      message.length(snprintf((char *)message.ptr(), message.alloced_length(), 
msg, wrong_tables.c_ptr())); 
+      send_error(&thd->net, ER_BAD_TABLE_ERROR, message.c_ptr()); 
+      /*my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());*/ 
+    } 
     else 
       my_error(ER_ROW_IS_REFERENCED,MYF(0)); 
     error= 1;
[5 Sep 2004 18:43] Peter Zaitsev
Bug reopened on Sergei  advice.

It is correct observation   error message is designed to report only one table, so why not to report 
first table which does not exist ? 

It will also be more consistent with other queries -  SELECT returns only first table from ones which do not exist:

mysql> select * from abc,def;
ERROR 1146: Table 'test.abc' doesn't exist

It even would be more efficient for this command to ball out on the first non-existing table instead of creating a full list.
[12 Sep 2004 15:41] Antony Curtis
The following patch alters the behaviour of DROP TABLE ... 
 
===== mysql-test/r/drop.result 1.11 vs edited ===== 
--- 1.11/mysql-test/r/drop.result 2003-07-03 09:55:34 +01:00 
+++ edited/mysql-test/r/drop.result 2004-09-12 16:16:02 +01:00 
@@ -1,6 +1,6 @@ 
 drop table if exists t1; 
 drop table t1; 
-Unknown table 't1' 
+Table 'test.t1' doesn't exist 
 create table t1(n int); 
 insert into t1 values(1); 
 create temporary table t1( n int); 
===== mysql-test/r/rpl_drop.result 1.1 vs edited ===== 
--- 1.1/mysql-test/r/rpl_drop.result 2004-07-17 15:58:13 +01:00 
+++ edited/mysql-test/r/rpl_drop.result 2004-09-12 16:27:58 +01:00 
@@ -7,4 +7,4 @@ 
 drop table if exists t1, t2; 
 create table t1 (a int); 
 drop table t1, t2; 
-Unknown table 't2' 
+Table 'test.t2' doesn't exist 
===== mysql-test/t/drop.test 1.11 vs edited ===== 
--- 1.11/mysql-test/t/drop.test 2003-07-03 09:55:34 +01:00 
+++ edited/mysql-test/t/drop.test 2004-09-12 16:08:48 +01:00 
@@ -1,5 +1,5 @@ 
 drop table if exists t1; 
---error 1051; 
+--error 1146; 
 drop table t1; 
 create table t1(n int); 
 insert into t1 values(1); 
===== mysql-test/t/rpl_drop.test 1.1 vs edited ===== 
--- 1.1/mysql-test/t/rpl_drop.test 2004-07-17 15:58:13 +01:00 
+++ edited/mysql-test/t/rpl_drop.test 2004-09-12 16:32:56 +01:00 
@@ -3,7 +3,7 @@ 
 source include/master-slave.inc; 
 drop table if exists t1, t2; 
 create table t1 (a int); 
---error 1051; 
+--error 1146; 
 drop table t1, t2; 
 save_master_pos; 
 connection slave; 
===== sql/sql_table.cc 1.185 vs edited ===== 
--- 1.185/sql/sql_table.cc 2004-09-06 22:20:30 +01:00 
+++ edited/sql/sql_table.cc 2004-09-12 16:38:36 +01:00 
@@ -174,15 +174,38 @@ 
 { 
   TABLE_LIST *table; 
   char path[FN_REFLEN], *alias; 
-  String wrong_tables; 
   db_type table_type; 
-  int error; 
+  int error= 0; 
   bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; 
   DBUG_ENTER("mysql_rm_table_part2"); 
  
   if (lock_table_names(thd, tables)) 
     DBUG_RETURN(1); 
  
+  if (!if_exists)  
+  { 
+    /* we check that all the tables exist  
+     * If a table does not exist, we don't drop any tables. 
+     * This preserves the concept of atomicity 
+     */ 
+    for (table=tables ; table; table=table->next) 
+    { 
+      char *db=table->db; 
+       
+      if (find_temporary_table(thd, db, table->real_name)) 
+        continue; 
+  
+      strxmov(path, mysql_data_home, "/", db, "/",  
+              table->real_name, reg_ext, NullS); 
+      if (get_table_type(path) == DB_TYPE_UNKNOWN) 
+      { 
+        my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->real_name); 
+        unlock_table_names(thd, tables); 
+        DBUG_RETURN(1); 
+      } 
+    } 
+  } 
+ 
   for (table=tables ; table ; table=table->next) 
   { 
     char *db=table->db; 
@@ -235,20 +258,13 @@ 
     } 
     if (error) 
     { 
-      if (wrong_tables.length()) 
- wrong_tables.append(','); 
-      wrong_tables.append(String(table->real_name)); 
+      if (!foreign_key_error) 
+        my_error(ER_BAD_TABLE_ERROR,MYF(0),table->real_name); 
+      else 
+        my_error(ER_ROW_IS_REFERENCED,MYF(0)); 
+      error= 1; 
+      break; 
     } 
-  } 
- 
-  error= 0; 
-  if (wrong_tables.length()) 
-  { 
-    if (!foreign_key_error) 
-      my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); 
-    else 
-      my_error(ER_ROW_IS_REFERENCED,MYF(0)); 
-    error= 1; 
   } 
  
   if (some_tables_deleted || tmp_table_deleted)
[14 Sep 2004 3:09] Antony Curtis
New simpler patch commited to local repo.
[14 Sep 2004 22:00] Antony Curtis
Latest patch: 
1.2018 04/09/14 22:22:36 antony@ltantony.rdg.cyberkinetica.homeunix.net +1 -0
[22 Dec 2004 17:02] Ingo Strüwing
I take one review with permission from Sergei.
Mail sent to dev-bugs.
[2 Apr 2005 18:05] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/internals/23584
[2 Apr 2005 18:55] Sergei Golubchik
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

fixed in 4.0.25, 4.1.12, 5.0.4
[3 Apr 2005 7:30] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/internals/23595