Commit 09944efd authored by unknown's avatar unknown
Browse files

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.


mysql-test/r/ndb_autodiscover.result:
  Add tests for reading from a table that can't be discovered(SYSTAB_0)
  Discovery is not performed during create table anymore.
mysql-test/t/ndb_autodiscover.test:
  Add tests for reading from a table that can't be discovered(SYSTAB_0)
  Discovery is not performed during create table anymore.
ndb/test/ndbapi/create_tab.cpp:
  Set connectstring before creating Ndb object.
sql/ha_ndbcluster.cc:
  Rename and use the function ndbcluster_table_exists_in_engine.
  Correct return valu from ndbcluster_discover
  Remove old code "ndb_discover_tables"
sql/ha_ndbcluster.h:
  Rename function ndbcluster_table_exists to ndb ndbcluster_table_exists_in_engine
sql/handler.cc:
  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/handler.h:
  Remove paramter create_if_cound from  ha_create_table_from_engine
  Rename ha_table_exists to ha_table_exists_in_engine
sql/sql_base.cc:
  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/sql_table.cc:
  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.
parent 5f767b11
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ name char(20), a int, b float, c char(24)
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 @@ name char(20)
) 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 @@ id name
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 @@ Database
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
+21 −0
Original line number Diff line number Diff line
@@ -453,6 +453,27 @@ drop database test2;
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 −1
Original line number Diff line number Diff line
@@ -77,8 +77,8 @@ int main(int argc, const char** argv){
     */
    
    // Connect to Ndb
    Ndb::setConnectString(_connectstr);
    Ndb MyNdb( "TEST_DB" );
    MyNdb.setConnectString(_connectstr);
    
    if(MyNdb.init() != 0){
      ERR(MyNdb.getNdbError());
+11 −12
Original line number Diff line number Diff line
@@ -4308,13 +4308,15 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
  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_discover(THD* thd, const char *db, const char *name,
   
 */

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 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
    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 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path,
  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 @@ bool ndbcluster_init()
  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);
+2 −1
Original line number Diff line number Diff line
@@ -275,7 +275,8 @@ int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
			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);
Loading