Commit f532653c authored by Sergei Golubchik's avatar Sergei Golubchik

remove ha_create_table_from_engine()

replace enum read_frm_op with a bitmap flags.
remove always-unused 'error' argument of get_table_share
parent 6a839ff4
...@@ -313,7 +313,7 @@ enum ha_base_keytype { ...@@ -313,7 +313,7 @@ enum ha_base_keytype {
#define HA_OPTION_CHECKSUM 32 #define HA_OPTION_CHECKSUM 32
#define HA_OPTION_DELAY_KEY_WRITE 64 #define HA_OPTION_DELAY_KEY_WRITE 64
#define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */
#define HA_OPTION_CREATE_FROM_ENGINE 256 /* unused 256 */
#define HA_OPTION_RELIES_ON_SQL_LAYER 512 #define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024 #define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048 #define HA_OPTION_PAGE_CHECKSUM 2048
......
...@@ -4157,72 +4157,6 @@ err: ...@@ -4157,72 +4157,6 @@ err:
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);
} }
/**
Try to discover table from engine.
@note
If found, write the frm file to disk.
@retval
-1 Table did not exists
@retval
0 Table created ok
@retval
> 0 Error, table existed but could not be created
*/
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
{
int error;
uchar *frmblob;
size_t frmlen;
char path[FN_REFLEN + 1];
HA_CREATE_INFO create_info;
TABLE table;
TABLE_SHARE share;
DBUG_ENTER("ha_create_table_from_engine");
DBUG_PRINT("enter", ("name '%s'.'%s'", db, name));
bzero((uchar*) &create_info,sizeof(create_info));
if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
{
/* Table could not be discovered and thus not created */
DBUG_RETURN(error);
}
/*
Table exists in handler and could be discovered
frmblob and frmlen are set, write the frm to disk
*/
build_table_filename(path, sizeof(path) - 1, db, name, "", 0);
// Save the frm file
error= writefrm(path, frmblob, frmlen);
my_free(frmblob);
if (error)
DBUG_RETURN(2);
init_tmp_table_share(thd, &share, db, 0, name, path);
if (open_table_def(thd, &share))
{
DBUG_RETURN(3);
}
if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, FALSE))
{
free_table_share(&share);
DBUG_RETURN(3);
}
update_create_info_from_table(&create_info, &table);
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
get_canonical_filename(table.file, path, path);
error=table.file->ha_create(path, &table, &create_info);
(void) closefrm(&table, 1);
DBUG_RETURN(error != 0);
}
void st_ha_check_opt::init() void st_ha_check_opt::init()
{ {
flags= sql_flags= 0; flags= sql_flags= 0;
...@@ -4435,21 +4369,12 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name) ...@@ -4435,21 +4369,12 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name)
if (need_full_discover_for_existence) if (need_full_discover_for_existence)
{ {
enum open_frm_error err;
TABLE_LIST table; TABLE_LIST table;
DBUG_ASSERT(0); DBUG_ASSERT(0);
TABLE_SHARE *share= get_table_share(thd, db, table_name, TABLE_SHARE *share= get_table_share(thd, db, table_name,
FRM_READ_TABLE_ONLY, &err); GTS_TABLE | GTS_NOLOCK);
DBUG_RETURN(share != 0);
if (share)
{
mysql_mutex_lock(&LOCK_open);
release_table_share(share);
mysql_mutex_unlock(&LOCK_open);
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
} }
mysql_mutex_lock(&LOCK_open); mysql_mutex_lock(&LOCK_open);
......
...@@ -3088,7 +3088,6 @@ int ha_delete_table(THD *thd, handlerton *db_type, const char *path, ...@@ -3088,7 +3088,6 @@ int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
/* discovery */ /* discovery */
int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
int ha_discover(THD* thd, const char* dbname, const char* name, int ha_discover(THD* thd, const char* dbname, const char* name,
uchar** frmblob, size_t* frmlen); uchar** frmblob, size_t* frmlen);
int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp,
......
...@@ -81,7 +81,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, ...@@ -81,7 +81,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
HA_CHECK_OPT *check_opt) HA_CHECK_OPT *check_opt)
{ {
int error= 0; int error= 0;
enum open_frm_error not_used;
TABLE tmp_table, *table; TABLE tmp_table, *table;
TABLE_LIST *pos_in_locked_tables= 0; TABLE_LIST *pos_in_locked_tables= 0;
TABLE_SHARE *share; TABLE_SHARE *share;
...@@ -124,7 +123,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, ...@@ -124,7 +123,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
has_mdl_lock= TRUE; has_mdl_lock= TRUE;
share= get_table_share(thd, table_list->db, table_list->table_name, share= get_table_share(thd, table_list->db, table_list->table_name,
FRM_READ_TABLE_ONLY, &not_used); GTS_TABLE);
if (share == NULL) if (share == NULL)
DBUG_RETURN(0); // Can't open frm file DBUG_RETURN(0); // Can't open frm file
......
...@@ -569,8 +569,8 @@ static void table_def_unuse_table(TABLE *table) ...@@ -569,8 +569,8 @@ static void table_def_unuse_table(TABLE *table)
table_list Table that should be opened table_list Table that should be opened
key Table cache key key Table cache key
key_length Length of key key_length Length of key
op operation: what to open table or view flags operation: what to open table or view
error out: Error code from open_table_def() hash_value = my_calc_hash(&table_def_cache, key, key_length)
IMPLEMENTATION IMPLEMENTATION
Get a table definition from the table definition cache. Get a table definition from the table definition cache.
...@@ -582,15 +582,14 @@ static void table_def_unuse_table(TABLE *table) ...@@ -582,15 +582,14 @@ static void table_def_unuse_table(TABLE *table)
*/ */
TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
char *key, uint key_length, char *key, uint key_length, uint flags,
enum read_frm_op op, enum open_frm_error *error,
my_hash_value_type hash_value) my_hash_value_type hash_value)
{ {
bool open_failed; bool open_failed;
TABLE_SHARE *share; TABLE_SHARE *share;
DBUG_ENTER("get_table_share"); DBUG_ENTER("get_table_share");
*error= OPEN_FRM_OK; DBUG_ASSERT(!(flags & GTS_FORCE_DISCOVERY)); // FIXME not implemented
mysql_mutex_lock(&LOCK_open); mysql_mutex_lock(&LOCK_open);
...@@ -634,14 +633,13 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, ...@@ -634,14 +633,13 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_lock(&share->LOCK_ha_data);
mysql_mutex_unlock(&LOCK_open); mysql_mutex_unlock(&LOCK_open);
open_failed= open_table_def(thd, share, op); open_failed= open_table_def(thd, share, flags);
mysql_mutex_unlock(&share->LOCK_ha_data); mysql_mutex_unlock(&share->LOCK_ha_data);
mysql_mutex_lock(&LOCK_open); mysql_mutex_lock(&LOCK_open);
if (open_failed) if (open_failed)
{ {
*error= share->error;
share->ref_count--; share->ref_count--;
(void) my_hash_delete(&table_def_cache, (uchar*) share); (void) my_hash_delete(&table_def_cache, (uchar*) share);
goto err; goto err;
...@@ -660,21 +658,20 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, ...@@ -660,21 +658,20 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
We found an existing table definition. Return it if we didn't get We found an existing table definition. Return it if we didn't get
an error when reading the table definition from file. an error when reading the table definition from file.
*/ */
if (share->is_view && op == FRM_READ_TABLE_ONLY) if (share->error)
{ {
open_table_error(share, OPEN_FRM_NOT_A_TABLE, ENOENT); open_table_error(share, share->error, share->open_errno);
goto err; goto err;
} }
if (!share->is_view && op == FRM_READ_VIEW_ONLY)
if (share->is_view && !(flags & GTS_VIEW))
{ {
open_table_error(share, OPEN_FRM_NOT_A_VIEW, ENOENT); open_table_error(share, OPEN_FRM_NOT_A_TABLE, ENOENT);
goto err; goto err;
} }
if (!share->is_view && !(flags & GTS_TABLE))
if (share->error)
{ {
/* Table definition contained an error */ open_table_error(share, OPEN_FRM_NOT_A_VIEW, ENOENT);
open_table_error(share, share->error, share->open_errno);
goto err; goto err;
} }
...@@ -703,8 +700,23 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, ...@@ -703,8 +700,23 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
goto end; goto end;
err: err:
share= 0; mysql_mutex_unlock(&LOCK_open);
DBUG_RETURN(0);
end: end:
if (flags & GTS_NOLOCK)
{
share->ref_count--;
/*
if GTS_NOLOCK is requested, the returned share pointer cannot be used,
the share it points to may go away any moment.
But perhaps the caller is only interested to know whether a share or
table existed?
Let's return an invalid pointer here to catch dereferencing attempts.
*/
share= (TABLE_SHARE*) 1;
}
mysql_mutex_unlock(&LOCK_open); mysql_mutex_unlock(&LOCK_open);
DBUG_RETURN(share); DBUG_RETURN(share);
} }
...@@ -2610,10 +2622,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -2610,10 +2622,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
char *alias= table_list->alias; char *alias= table_list->alias;
uint flags= ot_ctx->get_flags(); uint flags= ot_ctx->get_flags();
MDL_ticket *mdl_ticket; MDL_ticket *mdl_ticket;
enum open_frm_error error;
TABLE_SHARE *share; TABLE_SHARE *share;
my_hash_value_type hash_value; my_hash_value_type hash_value;
enum read_frm_op read_op; uint gts_flags;
DBUG_ENTER("open_table"); DBUG_ENTER("open_table");
/* an open table operation needs a lot of the stack space */ /* an open table operation needs a lot of the stack space */
...@@ -2883,17 +2894,16 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -2883,17 +2894,16 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) if (table_list->i_s_requested_object & OPEN_TABLE_ONLY)
read_op = FRM_READ_TABLE_ONLY; gts_flags= GTS_TABLE;
else if (table_list->i_s_requested_object & OPEN_VIEW_ONLY)
gts_flags= GTS_VIEW;
else else
if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) gts_flags= GTS_TABLE | GTS_VIEW;
read_op = FRM_READ_VIEW_ONLY;
else
read_op = FRM_READ_TABLE_OR_VIEW;
retry_share: retry_share:
share= get_table_share(thd, table_list->db, table_list->table_name, share= get_table_share(thd, table_list->db, table_list->table_name,
key, key_length, read_op, &error, hash_value); key, key_length, gts_flags, hash_value);
if (!share) if (!share)
{ {
...@@ -3019,6 +3029,8 @@ retry_share: ...@@ -3019,6 +3029,8 @@ retry_share:
} }
else else
{ {
enum open_frm_error error;
/* If we have too many TABLE instances around, try to get rid of them */ /* If we have too many TABLE instances around, try to get rid of them */
while (table_cache_count > table_cache_size && unused_tables) while (table_cache_count > table_cache_size && unused_tables)
free_cache_entry(unused_tables); free_cache_entry(unused_tables);
...@@ -3716,12 +3728,10 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, ...@@ -3716,12 +3728,10 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
MEM_ROOT *mem_root, uint flags) MEM_ROOT *mem_root, uint flags)
{ {
TABLE not_used; TABLE not_used;
enum open_frm_error error;
TABLE_SHARE *share; TABLE_SHARE *share;
if (!(share= get_table_share(thd, table_list->db, table_list->table_name, if (!(share= get_table_share(thd, table_list->db, table_list->table_name,
cache_key, cache_key_length, cache_key, cache_key_length, GTS_VIEW)))
FRM_READ_VIEW_ONLY, &error)))
return TRUE; return TRUE;
DBUG_ASSERT(share->is_view); DBUG_ASSERT(share->is_view);
...@@ -3792,7 +3802,6 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) ...@@ -3792,7 +3802,6 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
{ {
TABLE_SHARE *share; TABLE_SHARE *share;
TABLE *entry; TABLE *entry;
enum open_frm_error not_used;
bool result= TRUE; bool result= TRUE;
thd->clear_error(); thd->clear_error();
...@@ -3801,7 +3810,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) ...@@ -3801,7 +3810,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
return result; return result;
if (!(share= get_table_share(thd, table_list->db, table_list->table_name, if (!(share= get_table_share(thd, table_list->db, table_list->table_name,
FRM_READ_TABLE_ONLY, &not_used))) GTS_TABLE)))
goto end_free; goto end_free;
DBUG_ASSERT(! share->is_view); DBUG_ASSERT(! share->is_view);
...@@ -3979,8 +3988,9 @@ recover_from_failed_open(THD *thd) ...@@ -3979,8 +3988,9 @@ recover_from_failed_open(THD *thd)
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
m_failed_table->table_name, FALSE); m_failed_table->table_name, FALSE);
ha_create_table_from_engine(thd, m_failed_table->db, get_table_share(thd, m_failed_table->db,
m_failed_table->table_name); m_failed_table->table_name,
GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK);
thd->warning_info->clear_warning_info(thd->query_id); thd->warning_info->clear_warning_info(thd->query_id);
thd->clear_error(); // Clear error message thd->clear_error(); // Clear error message
......
...@@ -109,8 +109,7 @@ create_table_def_key(char *key, const char *db, const char *table_name) ...@@ -109,8 +109,7 @@ create_table_def_key(char *key, const char *db, const char *table_name)
uint create_tmp_table_def_key(THD *thd, char *key, const char *db, uint create_tmp_table_def_key(THD *thd, char *key, const char *db,
const char *table_name); const char *table_name);
TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
char *key, uint key_length, enum read_frm_op op, char *key, uint key_length, uint flags,
enum open_frm_error *error,
my_hash_value_type hash_value); my_hash_value_type hash_value);
void release_table_share(TABLE_SHARE *share); void release_table_share(TABLE_SHARE *share);
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
...@@ -119,23 +118,20 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); ...@@ -119,23 +118,20 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, static inline TABLE_SHARE *get_table_share(THD *thd, const char *db,
const char *table_name, const char *table_name,
char *key, uint key_length, char *key, uint key_length,
enum read_frm_op op, uint flags)
enum open_frm_error *error)
{ {
return get_table_share(thd, db, table_name, key, key_length, op, error, return get_table_share(thd, db, table_name, key, key_length, flags,
my_calc_hash(&table_def_cache, (uchar*) key, key_length)); my_calc_hash(&table_def_cache, (uchar*) key, key_length));
} }
// convenience helper: call get_table_share() without precomputed cache key // convenience helper: call get_table_share() without precomputed cache key
static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, static inline TABLE_SHARE *get_table_share(THD *thd, const char *db,
const char *table_name, const char *table_name, uint flags)
enum read_frm_op op,
enum open_frm_error *error)
{ {
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
key_length= create_table_def_key(key, db, table_name); key_length= create_table_def_key(key, db, table_name);
return get_table_share(thd, db, table_name, key, key_length, op, error); return get_table_share(thd, db, table_name, key, key_length, flags);
} }
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
......
...@@ -4307,7 +4307,6 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, ...@@ -4307,7 +4307,6 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
TABLE tbl; TABLE tbl;
TABLE_LIST table_list; TABLE_LIST table_list;
uint res= 0; uint res= 0;
enum open_frm_error not_used;
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
bzero((char*) &table_list, sizeof(TABLE_LIST)); bzero((char*) &table_list, sizeof(TABLE_LIST));
...@@ -4380,7 +4379,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, ...@@ -4380,7 +4379,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
} }
share= get_table_share(thd, table_list.db, table_list.table_name, share= get_table_share(thd, table_list.db, table_list.table_name,
FRM_READ_TABLE_OR_VIEW, &not_used); GTS_TABLE | GTS_VIEW);
if (!share) if (!share)
{ {
res= 0; res= 0;
......
...@@ -607,8 +607,7 @@ static bool has_disabled_path_chars(const char *str) ...@@ -607,8 +607,7 @@ static bool has_disabled_path_chars(const char *str)
alloc_table_share().. The code assumes that share is initialized. alloc_table_share().. The code assumes that share is initialized.
*/ */
enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
enum read_frm_op op)
{ {
bool error_given= false; bool error_given= false;
File file; File file;
...@@ -683,8 +682,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, ...@@ -683,8 +682,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0) if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0)
{ {
share->is_view= 1; share->is_view= 1;
share->error= op == FRM_READ_TABLE_ONLY share->error= flags & GTS_VIEW ? OPEN_FRM_OK : OPEN_FRM_NOT_A_TABLE;
? OPEN_FRM_NOT_A_TABLE : OPEN_FRM_OK;
goto err; goto err;
} }
if (!is_binary_frm_header(head)) if (!is_binary_frm_header(head))
...@@ -693,7 +691,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, ...@@ -693,7 +691,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
share->error = OPEN_FRM_CORRUPTED; share->error = OPEN_FRM_CORRUPTED;
goto err; goto err;
} }
if (op == FRM_READ_VIEW_ONLY) if (!(flags & GTS_TABLE))
{ {
share->error = OPEN_FRM_NOT_A_VIEW; share->error = OPEN_FRM_NOT_A_VIEW;
goto err; goto err;
......
...@@ -2447,10 +2447,11 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, ...@@ -2447,10 +2447,11 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set,
#endif #endif
} }
enum read_frm_op { enum get_table_share_flags {
FRM_READ_TABLE_ONLY, GTS_TABLE = 1,
FRM_READ_VIEW_ONLY, GTS_VIEW = 2,
FRM_READ_TABLE_OR_VIEW GTS_NOLOCK = 4, // don't increase share->ref_count
GTS_FORCE_DISCOVERY = 8 // don't use the .frm file
}; };
size_t max_row_length(TABLE *table, const uchar *data); size_t max_row_length(TABLE *table, const uchar *data);
...@@ -2471,7 +2472,7 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, ...@@ -2471,7 +2472,7 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
const char *table_name, const char *path); const char *table_name, const char *path);
void free_table_share(TABLE_SHARE *share); void free_table_share(TABLE_SHARE *share);
enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share,
enum read_frm_op op = FRM_READ_TABLE_ONLY); uint flags = GTS_TABLE);
void open_table_error(TABLE_SHARE *share, enum open_frm_error error, void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
int db_errno); int db_errno);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment