List:Internals« Previous MessageNext Message »
From:msvensson Date:June 8 2005 1:32pm
Subject:bk commit into 4.1 tree (msvensson:1.2299) BUG#10365
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of msvensson. When msvensson does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2299 05/06/08 13:31:59 msvensson@neptunus.(none) +9 -0
  BUG#10365 Cluster handler uses non-standard error codes
   - Added better error messages when trying to open a table that can't be discovered or
unpacked. The most likely cause of this is that it does not have any frm data, probably
since it has been created from NdbApi or is a NDB system table.
   - Separated functionality that was in ha_create_table_from_engine into two functions.
One that checks if the table exists and another one that tries to create the table from
the engine.

  sql/sql_table.cc
    1.282 05/06/08 13:31:56 msvensson@neptunus.(none) +10 -8
    Add comments, remove parameter create_if_found to ha_create_table_from_engine.
    When dropping a table, try to discover it from engine. If discover fails, use same
error message as if the table didn't exists. 
    Maybe another message should be displayed here, ex: "Table could not be dropped,
unpack failed"
    
    When creating a new table, use ha_table_exists_in_engine to check if a table with the
given name already exists.

  sql/sql_base.cc
    1.249 05/06/08 13:31:56 msvensson@neptunus.(none) +14 -3
    Use the function ha_table_exists_in_engine to detect if table exists in enegine. 
    If it exists, call function ha_create_table_from_engine to try and create it.
    If create of table fails, set correct error message. 

  sql/handler.h
    1.141 05/06/08 13:31:56 msvensson@neptunus.(none) +2 -3
    Remove paramter create_if_cound from  ha_create_table_from_engine
    Rename ha_table_exists to ha_table_exists_in_engine 

  sql/handler.cc
    1.165 05/06/08 13:31:56 msvensson@neptunus.(none) +45 -50
    Update comment of ha_create_table_from_engine
    Remove parameter create_if_found from ha_create_table_from_engine, the function
ha_table_exists_in_engine is now used toi check if table is found in engine.
    Cleanup return codes from ha_create_table_from_engine.
    Change name of ha_table_exists to ha_table_exists_in_engine, update comment and
returne codes.

  sql/ha_ndbcluster.h
    1.54 05/06/08 13:31:56 msvensson@neptunus.(none) +2 -1
    Rename function ndbcluster_table_exists to ndb ndbcluster_table_exists_in_engine

  sql/ha_ndbcluster.cc
    1.154 05/06/08 13:31:56 msvensson@neptunus.(none) +11 -12
    Rename and use the function ndbcluster_table_exists_in_engine.
    Correct return valu from ndbcluster_discover
    Remove old code "ndb_discover_tables"

  ndb/test/ndbapi/create_tab.cpp
    1.7 05/06/08 13:31:56 msvensson@neptunus.(none) +1 -1
    Set connectstring before creating Ndb object.

  mysql-test/t/ndb_autodiscover.test
    1.16 05/06/08 13:31:56 msvensson@neptunus.(none) +21 -0
    Add tests for reading from a table that can't be discovered(SYSTAB_0)
    Discovery is not performed during create table anymore.

  mysql-test/r/ndb_autodiscover.result
    1.12 05/06/08 13:31:56 msvensson@neptunus.(none) +17 -3
    Add tests for reading from a table that can't be discovered(SYSTAB_0)
    Discovery is not performed during create table anymore.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	msvensson
# Host:	neptunus.(none)
# Root:	/home/msvensson/mysql/bug10365

--- 1.164/sql/handler.cc	2005-05-26 12:09:09 +02:00
+++ 1.165/sql/handler.cc	2005-06-08 13:31:56 +02:00
@@ -1336,21 +1336,18 @@
 }
 
 /*
-  Try to discover table from engine and 
+  Try to discover table from engine and
   if found, write the frm file to disk.
-  
+
   RETURN VALUES:
-   0 : Table existed in engine and created 
-       on disk if so requested
-   1 : Table does not exist
-  >1 : error
+   0 : Table created ok
+   1 : Table could not be created
 
 */
 
-int ha_create_table_from_engine(THD* thd, 
-				const char *db, 
-				const char *name,
-				bool create_if_found)
+int ha_create_table_from_engine(THD* thd,
+				const char *db,
+				const char *name)
 {
   int error;
   const void *frmblob;
@@ -1359,45 +1356,47 @@
   HA_CREATE_INFO create_info;
   TABLE table;
   DBUG_ENTER("ha_create_table_from_engine");
-  DBUG_PRINT("enter", ("name '%s'.'%s'  create_if_found: %d",
-                       db, name, create_if_found));
+  DBUG_PRINT("enter", ("name '%s'.'%s'",
+                       db, name));
 
   bzero((char*) &create_info,sizeof(create_info));
 
-  if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
-    DBUG_RETURN(error); 
+  if(ha_discover(thd, db, name, &frmblob, &frmlen))
+  {
+    // Table could not be discovered and thus not created
+    DBUG_RETURN(1);
+  }
+
   /*
-    Table exists in handler
-    frmblob and frmlen are set
+    Table exists in handler and could be discovered
+    frmblob and frmlen are set, write the frm to disk
   */
 
-  if (create_if_found)
+  (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS);
+  // Save the frm file
+  if (writefrm(path, frmblob, frmlen))
   {
-    (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS);
-    // Save the frm file    
-    if ((error = writefrm(path, frmblob, frmlen)))
-      goto err_end;
-
-    if (openfrm(path,"",0,(uint) READ_ALL, 0, &table))
-      DBUG_RETURN(1);
-
-    update_create_info_from_table(&create_info, &table);
-    create_info.table_options|= HA_CREATE_FROM_ENGINE;
-
-    if (lower_case_table_names == 2 &&
-	!(table.file->table_flags() & HA_FILE_BASED))
-    {
-      /* Ensure that handler gets name in lower case */
-      my_casedn_str(files_charset_info, path);
-    }
-    
-    error=table.file->create(path,&table,&create_info);
-    VOID(closefrm(&table));
+    my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR));
+    DBUG_RETURN(1);
   }
 
-err_end:
+  if (openfrm(path,"",0,(uint) READ_ALL, 0, &table))
+    DBUG_RETURN(1);
+
+  update_create_info_from_table(&create_info, &table);
+  create_info.table_options|= HA_CREATE_FROM_ENGINE;
+
+  if (lower_case_table_names == 2 &&
+      !(table.file->table_flags() & HA_FILE_BASED))
+  {
+    /* Ensure that handler gets name in lower case */
+    my_casedn_str(files_charset_info, path);
+  }
+  error=table.file->create(path,&table,&create_info);
+  VOID(closefrm(&table));
   my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR));
-  DBUG_RETURN(error);  
+
+  DBUG_RETURN(error != 0);
 }
 
 static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
@@ -1507,8 +1506,8 @@
   Try to discover one table from handler(s)
 
   RETURN
-    0  ok. In this case *frmblob and *frmlen are set
-    1  error.  frmblob and frmlen may not be set
+    0    ok. In this case *frmblob and *frmlen are set
+    >=1  error.  frmblob and frmlen may not be set
 */
 
 int ha_discover(THD *thd, const char *db, const char *name,
@@ -1546,11 +1545,8 @@
     error= ndbcluster_find_files(thd, db, path, wild, dir, files);
 #endif
   DBUG_RETURN(error);
-  
-  
 }
 
-#ifdef NOT_YET_USED
 
 /*
   Ask handler if the table exists in engine
@@ -1561,19 +1557,18 @@
     #                   Error code
 
  */
-int ha_table_exists(THD* thd, const char* db, const char* name)
+int ha_table_exists_in_engine(THD* thd, const char* db, const char* name)
 {
-  int error= 2;
-  DBUG_ENTER("ha_table_exists");
+  int error= 0;
+  DBUG_ENTER("ha_table_exists_in_engine");
   DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
 #ifdef HAVE_NDBCLUSTER_DB
   if (have_ndbcluster == SHOW_OPTION_YES)
-    error= ndbcluster_table_exists(thd, db, name);
+    error= ndbcluster_table_exists_in_engine(thd, db, name);
 #endif
+  DBUG_PRINT("exit", ("error: %d", error));
   DBUG_RETURN(error);
 }
-
-#endif
 
 
 /*

--- 1.140/sql/handler.h	2005-05-18 19:40:35 +02:00
+++ 1.141/sql/handler.h	2005-06-08 13:31:56 +02:00
@@ -547,8 +547,7 @@
 my_bool ha_storage_engine_is_enabled(enum db_type database_type);
 int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
 		    bool update_create_info);
-int ha_create_table_from_engine(THD* thd, const char *db, const char *name,
-				bool create_if_found);
+int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
 int ha_delete_table(enum db_type db_type, const char *path);
 void ha_drop_database(char* path);
 int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
@@ -574,6 +573,6 @@
 		const void** frmblob, uint* frmlen);
 int ha_find_files(THD *thd,const char *db,const char *path,
 		  const char *wild, bool dir,List<char>* files);
-int ha_table_exists(THD* thd, const char* db, const char* name);
+int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
 TYPELIB *ha_known_exts(void);
 int ha_start_consistent_snapshot(THD *thd);

--- 1.248/sql/sql_base.cc	2005-05-16 19:16:43 +02:00
+++ 1.249/sql/sql_base.cc	2005-06-08 13:31:56 +02:00
@@ -1375,9 +1375,20 @@
        trying to discover the table at the same time.
       */
       if (discover_retry_count++ != 0)
-       goto err;
-      if (ha_create_table_from_engine(thd, db, name, TRUE) != 0)
-       goto err;
+        goto err;
+      if (ha_table_exists_in_engine(thd, db, name) &&
+          ha_create_table_from_engine(thd, db, name))
+      {
+        /* Give right error message */
+        thd->clear_error();
+        DBUG_PRINT("error", ("Dicovery of %s/%s failed", db, name));
+        my_printf_error(ER_UNKNOWN_ERROR,
+                        "Failed to open '%-.64s', error while "
+                        "unpacking from engine",
+                        MYF(0), name);
+
+        goto err;
+      }
 
       thd->clear_error(); // Clear error message
       continue;

--- 1.281/sql/sql_table.cc	2005-05-14 15:24:32 +02:00
+++ 1.282/sql/sql_table.cc	2005-06-08 13:31:56 +02:00
@@ -217,15 +217,18 @@
       strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
       (void) unpack_filename(path,path);
     }
-    if (drop_temporary || 
-	(access(path,F_OK) && ha_create_table_from_engine(thd,db,alias,TRUE)))
+    if (drop_temporary ||
+	(access(path,F_OK) &&
+         ha_create_table_from_engine(thd, db, alias)))
     {
+      // Table was not found on disk and table can't be created from engine
       if (if_exists)
 	push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 			    ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 			    table->real_name);
       else
-	error= 1;
+        error= 1;
+
     }
     else
     {
@@ -1371,15 +1374,14 @@
   {
     bool create_if_not_exists =
       create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
-    if (!ha_create_table_from_engine(thd, db, table_name,
-				     create_if_not_exists))
+    if (ha_table_exists_in_engine(thd, db, table_name))
     {
-      DBUG_PRINT("info", ("Table already existed in handler"));
+      DBUG_PRINT("info", ("Table with same name already existed in handler"));
 
       if (create_if_not_exists)
       {
-       create_info->table_existed= 1;   // Mark that table existed
-       error= 0;
+        create_info->table_existed= 1;   // Mark that table existed
+        error= 0;
       }
       else
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);

--- 1.11/mysql-test/r/ndb_autodiscover.result	2004-11-08 11:06:13 +01:00
+++ 1.12/mysql-test/r/ndb_autodiscover.result	2005-06-08 13:31:56 +02:00
@@ -93,7 +93,7 @@
 ERROR 42S01: Table 't3' already exists
 show status like 'handler_discover%';
 Variable_name	Value
-Handler_discover	1
+Handler_discover	0
 create table IF NOT EXISTS t3(
 id int not null primary key,
 id2 int not null,
@@ -101,7 +101,7 @@
 ) engine=ndb;
 show status like 'handler_discover%';
 Variable_name	Value
-Handler_discover	2
+Handler_discover	0
 SHOW CREATE TABLE t3;
 Table	Create Table
 t3	CREATE TABLE `t3` (
@@ -114,7 +114,7 @@
 1	Explorer
 show status like 'handler_discover%';
 Variable_name	Value
-Handler_discover	2
+Handler_discover	1
 drop table t3;
 flush status;
 create table t7(
@@ -358,6 +358,20 @@
 mysql
 test
 use test;
+CREATE TABLE sys.SYSTAB_0 (a int);
+ERROR 42S01: Table 'SYSTAB_0' already exists
+select * from sys.SYSTAB_0;
+ERROR HY000: Failed to open 'SYSTAB_0', error while unpacking from engine
+CREATE TABLE IF NOT EXISTS sys.SYSTAB_0 (a int);
+show warnings;
+Level	Code	Message
+select * from sys.SYSTAB_0;
+ERROR HY000: Failed to open 'SYSTAB_0', error while unpacking from engine
+drop table sys.SYSTAB_0;
+ERROR 42S02: Unknown table 'SYSTAB_0'
+drop table IF EXISTS sys.SYSTAB_0;
+Warnings:
+Note	1051	Unknown table 'SYSTAB_0'
 CREATE TABLE t9 (
 a int NOT NULL PRIMARY KEY,
 b int

--- 1.15/mysql-test/t/ndb_autodiscover.test	2005-04-19 17:23:00 +02:00
+++ 1.16/mysql-test/t/ndb_autodiscover.test	2005-06-08 13:31:56 +02:00
@@ -453,6 +453,27 @@
 show databases;
 use test;
 
+#####################################################
+# Test that it's not possible to create tables
+# with same name as NDB internal tables
+# This will also test that it's not possible to create
+# a table with tha same name as a table that can't be
+# discovered( for example a table created via NDBAPI)
+
+--error 1050
+CREATE TABLE sys.SYSTAB_0 (a int);
+--error 1105
+select * from sys.SYSTAB_0;
+
+CREATE TABLE IF NOT EXISTS sys.SYSTAB_0 (a int);
+show warnings;
+--error 1105
+select * from sys.SYSTAB_0;
+
+--error 1051
+drop table sys.SYSTAB_0;
+drop table IF EXISTS sys.SYSTAB_0;
+
 ######################################################
 # Note! This should always be the last step in this 
 # file, the table t9 will be used and dropped 

--- 1.6/ndb/test/ndbapi/create_tab.cpp	2004-09-15 11:43:33 +02:00
+++ 1.7/ndb/test/ndbapi/create_tab.cpp	2005-06-08 13:31:56 +02:00
@@ -77,8 +77,8 @@
      */
     
     // Connect to Ndb
+    Ndb::setConnectString(_connectstr);
     Ndb MyNdb( "TEST_DB" );
-    MyNdb.setConnectString(_connectstr);
     
     if(MyNdb.init() != 0){
       ERR(MyNdb.getNdbError());

--- 1.153/sql/ha_ndbcluster.cc	2005-05-26 12:09:09 +02:00
+++ 1.154/sql/ha_ndbcluster.cc	2005-06-08 13:31:56 +02:00
@@ -4308,13 +4308,15 @@
   len= tab->getFrmLength();  
   if (len == 0 || tab->getFrmData() == NULL)
   {
-    DBUG_PRINT("No frm data found",
-               ("Table is probably created via NdbApi")); 
-    DBUG_RETURN(2);
+    DBUG_PRINT("error", ("No frm data found."));
+    DBUG_RETURN(1);
   }
   
   if (unpackfrm(&data, &len, tab->getFrmData()))
-    DBUG_RETURN(3);
+  {
+    DBUG_PRINT("error", ("Could not unpack table"));
+    DBUG_RETURN(1);
+  }
 
   *frmlen= len;
   *frmblob= data;
@@ -4327,13 +4329,13 @@
    
  */
 
-int ndbcluster_table_exists(THD* thd, const char *db, const char *name)
+int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name)
 {
   uint len;
   const void* data;
   const NDBTAB* tab;
   Ndb* ndb;
-  DBUG_ENTER("ndbcluster_table_exists");
+  DBUG_ENTER("ndbcluster_table_exists_in_engine");
   DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); 
 
   if (!(ndb= check_ndb_in_thd(thd)))
@@ -4512,7 +4514,7 @@
     DBUG_PRINT("info", ("%s existed on disk", name));     
     // The .ndb file exists on disk, but it's not in list of tables in ndb
     // Verify that handler agrees table is gone.
-    if (ndbcluster_table_exists(thd, db, file_name) == 0)    
+    if (ndbcluster_table_exists_in_engine(thd, db, file_name) == 0)    
     {
       DBUG_PRINT("info", ("NDB says %s does not exists", file_name));     
       it.remove();
@@ -4563,7 +4565,7 @@
   while ((file_name=it2++))
   {  
     DBUG_PRINT("info", ("Table %s need discovery", name));
-    if (ha_create_table_from_engine(thd, db, file_name, TRUE) == 0)
+    if (ha_create_table_from_engine(thd, db, file_name) == 0)
       files->push_back(thd->strdup(file_name)); 
   }
 
@@ -4639,11 +4641,8 @@
   pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST);
 
   ndbcluster_inited= 1;
-#ifdef USE_DISCOVER_ON_STARTUP
-  if (ndb_discover_tables() != 0)
-    goto ndbcluster_init_error;    
-#endif
   DBUG_RETURN(FALSE);
+
  ndbcluster_init_error:
   ndbcluster_end();
   DBUG_RETURN(TRUE);

--- 1.53/sql/ha_ndbcluster.h	2005-05-04 15:05:53 +02:00
+++ 1.54/sql/ha_ndbcluster.h	2005-06-08 13:31:56 +02:00
@@ -275,7 +275,8 @@
 			const void** frmblob, uint* frmlen);
 int ndbcluster_find_files(THD *thd,const char *db,const char *path,
 			  const char *wild, bool dir, List<char> *files);
-int ndbcluster_table_exists(THD* thd, const char *db, const char *name);
+int ndbcluster_table_exists_in_engine(THD* thd,
+                                      const char *db, const char *name);
 int ndbcluster_drop_database(const char* path);
 
 void ndbcluster_print_error(int error, const NdbOperation *error_op);
Thread
bk commit into 4.1 tree (msvensson:1.2299) BUG#10365msvensson8 Jun