diff options
author | unknown <msvensson@neptunus.(none)> | 2005-06-08 13:31:59 +0200 |
---|---|---|
committer | unknown <msvensson@neptunus.(none)> | 2005-06-08 13:31:59 +0200 |
commit | 09944efd71a7b11de5b06e76b8019aae53d9ca36 (patch) | |
tree | b82e8da8fb00ab3aeb74266b31c0094ac048b5a8 /sql | |
parent | 5f767b11e4de23d6843eebb886ddbcf185572747 (diff) | |
download | mariadb-git-09944efd71a7b11de5b06e76b8019aae53d9ca36.tar.gz |
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.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_ndbcluster.cc | 23 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 3 | ||||
-rw-r--r-- | sql/handler.cc | 91 | ||||
-rw-r--r-- | sql/handler.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 17 | ||||
-rw-r--r-- | sql/sql_table.cc | 18 |
6 files changed, 82 insertions, 75 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index eaa0473df1b..85b7ddc4892 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -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); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 439b4855147..5c1d121a157 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -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); diff --git a/sql/handler.cc b/sql/handler.cc index f14564b6629..ad5cd28d932 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1336,21 +1336,18 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, } /* - 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 @@ int ha_create_table_from_engine(THD* thd, 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; + my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR)); + DBUG_RETURN(1); + } - if (openfrm(path,"",0,(uint) READ_ALL, 0, &table)) - DBUG_RETURN(1); + 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; + 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)); + 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); } - -err_end: + 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 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, 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 @@ ha_find_files(THD *thd,const char *db,const char *path, 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,20 +1557,19 @@ ha_find_files(THD *thd,const char *db,const char *path, # 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 - /* Read first row between two ranges. diff --git a/sql/handler.h b/sql/handler.h index 75e83082d10..efcdee8f56c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -547,8 +547,7 @@ enum db_type ha_checktype(enum db_type database_type); 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 @@ int ha_discover(THD* thd, const char* dbname, const char* name, 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); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c580842ce06..0aa2f1ce4b8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1375,9 +1375,20 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, 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; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 67aade519f5..70dd17cc8bc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -217,15 +217,18 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, 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 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { 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); |