Commit 4853c719 authored by Sergei Golubchik's avatar Sergei Golubchik

discovery using sql CREATE TABLE statement

parent 474f45b3
...@@ -978,7 +978,7 @@ SHOW CREATE TABLE `tt+2`; ...@@ -978,7 +978,7 @@ SHOW CREATE TABLE `tt+2`;
Table Create Table Table Create Table
tt+2 CREATE TEMPORARY TABLE `tt+2` ( tt+2 CREATE TEMPORARY TABLE `tt+2` (
`c1` int(11) DEFAULT NULL `c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
DROP TABLE `tt+1`, `tt+2`; DROP TABLE `tt+1`, `tt+2`;
CREATE TABLE `#sql1` (c1 INT); CREATE TABLE `#sql1` (c1 INT);
CREATE TABLE `@0023sql2` (c1 INT); CREATE TABLE `@0023sql2` (c1 INT);
...@@ -1015,12 +1015,12 @@ SHOW CREATE TABLE `#sql2`; ...@@ -1015,12 +1015,12 @@ SHOW CREATE TABLE `#sql2`;
Table Create Table Table Create Table
#sql2 CREATE TEMPORARY TABLE `#sql2` ( #sql2 CREATE TEMPORARY TABLE `#sql2` (
`c1` int(11) DEFAULT NULL `c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
SHOW CREATE TABLE `@0023sql1`; SHOW CREATE TABLE `@0023sql1`;
Table Create Table Table Create Table
@0023sql1 CREATE TEMPORARY TABLE `@0023sql1` ( @0023sql1 CREATE TEMPORARY TABLE `@0023sql1` (
`c1` int(11) DEFAULT NULL `c1` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
DROP TABLE `#sql2`, `@0023sql1`; DROP TABLE `#sql2`, `@0023sql1`;
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t2;
......
...@@ -2883,7 +2883,7 @@ Table Create Table ...@@ -2883,7 +2883,7 @@ Table Create Table
m2 CREATE TEMPORARY TABLE `m2` ( m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2; SELECT * FROM m2;
c1 c2 c1 c2
111 121 111 121
...@@ -2900,7 +2900,7 @@ Table Create Table ...@@ -2900,7 +2900,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1; SELECT * FROM m1;
c1 c2 c1 c2
111 121 111 121
...@@ -2989,7 +2989,7 @@ Table Create Table ...@@ -2989,7 +2989,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
INSERT INTO m1 VALUES (511, 521); INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1; SELECT * FROM m1;
c1 c2 c1 c2
...@@ -3040,7 +3040,7 @@ Table Create Table ...@@ -3040,7 +3040,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
# #
CREATE TABLE m2 SELECT * FROM m1; CREATE TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2; SHOW CREATE TABLE m2;
...@@ -3092,7 +3092,7 @@ Table Create Table ...@@ -3092,7 +3092,7 @@ Table Create Table
m2 CREATE TABLE `m2` ( m2 CREATE TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2; SELECT * FROM m2;
c1 c2 c1 c2
111 121 111 121
...@@ -3118,7 +3118,7 @@ Table Create Table ...@@ -3118,7 +3118,7 @@ Table Create Table
m2 CREATE TEMPORARY TABLE `m2` ( m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2; SELECT * FROM m2;
c1 c2 c1 c2
111 121 111 121
...@@ -3288,7 +3288,7 @@ Table Create Table ...@@ -3288,7 +3288,7 @@ Table Create Table
m2 CREATE TEMPORARY TABLE `m2` ( m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2; SELECT * FROM m2;
c1 c2 c1 c2
111 121 111 121
...@@ -3305,7 +3305,7 @@ Table Create Table ...@@ -3305,7 +3305,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1; SELECT * FROM m1;
c1 c2 c1 c2
111 121 111 121
...@@ -3396,7 +3396,7 @@ Table Create Table ...@@ -3396,7 +3396,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
INSERT INTO m1 VALUES (511, 521); INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1; SELECT * FROM m1;
c1 c2 c1 c2
...@@ -3447,7 +3447,7 @@ Table Create Table ...@@ -3447,7 +3447,7 @@ Table Create Table
m1 CREATE TEMPORARY TABLE `m1` ( m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
CREATE TABLE m2 SELECT * FROM m1; CREATE TABLE m2 SELECT * FROM m1;
ERROR HY000: Table 'm2' was not locked with LOCK TABLES ERROR HY000: Table 'm2' was not locked with LOCK TABLES
# #
...@@ -3492,14 +3492,14 @@ Table Create Table ...@@ -3492,14 +3492,14 @@ Table Create Table
m2 CREATE TEMPORARY TABLE `m2` ( m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
LOCK TABLE m1 WRITE, m2 WRITE; LOCK TABLE m1 WRITE, m2 WRITE;
SHOW CREATE TABLE m2; SHOW CREATE TABLE m2;
Table Create Table Table Create Table
m2 CREATE TEMPORARY TABLE `m2` ( m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL, `c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL `c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2; SELECT * FROM m2;
c1 c2 c1 c2
111 121 111 121
......
...@@ -198,7 +198,7 @@ show create table t2; ...@@ -198,7 +198,7 @@ show create table t2;
Table Create Table Table Create Table
t2 CREATE TEMPORARY TABLE `t2` ( t2 CREATE TEMPORARY TABLE `t2` (
`a` int(11) NOT NULL `a` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
drop table t2; drop table t2;
create table t1 ( create table t1 (
test_set set( 'val1', 'val2', 'val3' ) not null default '', test_set set( 'val1', 'val2', 'val3' ) not null default '',
......
...@@ -12846,5 +12846,5 @@ Table Create Table ...@@ -12846,5 +12846,5 @@ Table Create Table
t1 CREATE TEMPORARY TABLE `t1` ( t1 CREATE TEMPORARY TABLE `t1` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL `b` varchar(10) DEFAULT NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 ) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
drop table t1; drop table t1;
...@@ -4317,6 +4317,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, ...@@ -4317,6 +4317,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
handlerton *hton= plugin_data(plugin, handlerton *); handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->discover_table) if (hton->state == SHOW_OPTION_YES && hton->discover_table)
{ {
share->db_plugin= plugin;
int error= hton->discover_table(hton, thd, share); int error= hton->discover_table(hton, thd, share);
if (error != HA_ERR_NO_SUCH_TABLE) if (error != HA_ERR_NO_SUCH_TABLE)
{ {
...@@ -4324,6 +4325,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, ...@@ -4324,6 +4325,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
{ {
DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work
my_error(ER_GET_ERRNO, MYF(0), error); my_error(ER_GET_ERRNO, MYF(0), error);
share->db_plugin= 0;
} }
else else
share->error= OPEN_FRM_OK; share->error= OPEN_FRM_OK;
...@@ -4331,6 +4333,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, ...@@ -4331,6 +4333,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
status_var_increment(thd->status_var.ha_discover_count); status_var_increment(thd->status_var.ha_discover_count);
return TRUE; // abort the search return TRUE; // abort the search
} }
share->db_plugin= 0;
} }
DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR);
...@@ -4342,6 +4345,7 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share) ...@@ -4342,6 +4345,7 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share)
DBUG_ENTER("ha_discover_table"); DBUG_ENTER("ha_discover_table");
DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet
DBUG_ASSERT(!share->db_plugin);
if (!plugin_foreach(thd, discover_handlerton, if (!plugin_foreach(thd, discover_handlerton,
MYSQL_STORAGE_ENGINE_PLUGIN, share)) MYSQL_STORAGE_ENGINE_PLUGIN, share))
......
...@@ -6600,3 +6600,6 @@ ER_SLAVE_STARTED ...@@ -6600,3 +6600,6 @@ ER_SLAVE_STARTED
eng "SLAVE '%.*s' started" eng "SLAVE '%.*s' started"
ER_SLAVE_STOPPED ER_SLAVE_STOPPED
eng "SLAVE '%.*s' stopped" eng "SLAVE '%.*s' stopped"
ER_SQL_DISCOVER_ERROR
eng "Engine %s failed to discover table %`-.192s.%`-.192s with '%s'"
This diff is collapsed.
...@@ -25,6 +25,7 @@ struct TABLE_LIST; ...@@ -25,6 +25,7 @@ struct TABLE_LIST;
class THD; class THD;
struct TABLE; struct TABLE;
struct handlerton; struct handlerton;
class handler;
typedef struct st_ha_check_opt HA_CHECK_OPT; typedef struct st_ha_check_opt HA_CHECK_OPT;
struct HA_CREATE_INFO; struct HA_CREATE_INFO;
typedef struct st_key KEY; typedef struct st_key KEY;
...@@ -140,6 +141,12 @@ bool mysql_create_table_no_lock(THD *thd, const char *db, ...@@ -140,6 +141,12 @@ bool mysql_create_table_no_lock(THD *thd, const char *db,
Alter_info *alter_info, Alter_info *alter_info,
bool tmp_table, uint select_field_count, bool tmp_table, uint select_field_count,
bool *is_trans); bool *is_trans);
handler *mysql_create_frm_image(THD *thd,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
Alter_info *alter_info,
bool internal_tmp_table,
uint select_field_count, LEX_CUSTRING *frm);
bool mysql_prepare_alter_table(THD *thd, TABLE *table, bool mysql_prepare_alter_table(THD *thd, TABLE *table,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
Alter_info *alter_info); Alter_info *alter_info);
......
...@@ -693,7 +693,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) ...@@ -693,7 +693,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
*/ */
bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
const uchar *frm_image, const uchar *frm_image,
size_t frm_length) size_t frm_length)
{ {
...@@ -729,10 +729,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -729,10 +729,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
KEY_PART_INFO *first_key_part= NULL; KEY_PART_INFO *first_key_part= NULL;
uint ext_key_parts= 0; uint ext_key_parts= 0;
uint first_key_parts= 0; uint first_key_parts= 0;
plugin_ref se_plugin= 0;
keyinfo= &first_keyinfo; keyinfo= &first_keyinfo;
share->ext_key_parts= 0; share->ext_key_parts= 0;
MEM_ROOT **root_ptr, *old_root; MEM_ROOT **root_ptr, *old_root;
DBUG_ENTER("open_binary_frm"); DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
old_root= *root_ptr; old_root= *root_ptr;
...@@ -776,15 +777,13 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -776,15 +777,13 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61]));
#endif #endif
legacy_db_type= (enum legacy_db_type) (uint) frm_image[3]; legacy_db_type= (enum legacy_db_type) (uint) frm_image[3];
DBUG_ASSERT(share->db_plugin == NULL);
/* /*
if the storage engine is dynamic, no point in resolving it by its if the storage engine is dynamic, no point in resolving it by its
dynamically allocated legacy_db_type. We will resolve it later by name. dynamically allocated legacy_db_type. We will resolve it later by name.
*/ */
if (legacy_db_type > DB_TYPE_UNKNOWN && if (legacy_db_type > DB_TYPE_UNKNOWN &&
legacy_db_type < DB_TYPE_FIRST_DYNAMIC) legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
share->db_plugin= ha_lock_engine(NULL, se_plugin= ha_lock_engine(NULL, ha_checktype(thd, legacy_db_type, 0, 0));
ha_checktype(thd, legacy_db_type, 0, 0));
share->db_create_options= db_create_options= uint2korr(frm_image+30); share->db_create_options= db_create_options= uint2korr(frm_image+30);
share->db_options_in_use= share->db_create_options; share->db_options_in_use= share->db_create_options;
share->mysql_version= uint4korr(frm_image+51); share->mysql_version= uint4korr(frm_image+51);
...@@ -1045,7 +1044,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1045,7 +1044,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
name.length= str_db_type_length; name.length= str_db_type_length;
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name); plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin)) if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, se_plugin))
{ {
if (legacy_db_type > DB_TYPE_UNKNOWN && if (legacy_db_type > DB_TYPE_UNKNOWN &&
legacy_db_type < DB_TYPE_FIRST_DYNAMIC && legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
...@@ -1057,14 +1056,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1057,14 +1056,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
} }
/* /*
tmp_plugin is locked with a local lock. tmp_plugin is locked with a local lock.
we unlock the old value of share->db_plugin before we unlock the old value of se_plugin before
replacing it with a globally locked version of tmp_plugin replacing it with a globally locked version of tmp_plugin
*/ */
plugin_unlock(NULL, share->db_plugin); plugin_unlock(NULL, se_plugin);
share->db_plugin= my_plugin_lock(NULL, tmp_plugin); se_plugin= plugin_lock(NULL, tmp_plugin);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
ha_legacy_type(share->db_type())));
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
else if (str_db_type_length == 9 && else if (str_db_type_length == 9 &&
...@@ -1073,7 +1069,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1073,7 +1069,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
/* /*
Use partition handler Use partition handler
tmp_plugin is locked with a local lock. tmp_plugin is locked with a local lock.
we unlock the old value of share->db_plugin before we unlock the old value of se_plugin before
replacing it with a globally locked version of tmp_plugin replacing it with a globally locked version of tmp_plugin
*/ */
/* Check if the partitioning engine is ready */ /* Check if the partitioning engine is ready */
...@@ -1083,11 +1079,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1083,11 +1079,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
"--skip-partition"); "--skip-partition");
goto err; goto err;
} }
plugin_unlock(NULL, share->db_plugin); plugin_unlock(NULL, se_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton); se_plugin= ha_lock_engine(NULL, partition_hton);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
ha_legacy_type(share->db_type())));
} }
#endif #endif
else if (!tmp_plugin) else if (!tmp_plugin)
...@@ -1284,7 +1277,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1284,7 +1277,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
/* Allocate handler */ /* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root, if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type()))) plugin_data(se_plugin, handlerton *))))
goto err; goto err;
record= share->default_values-1; /* Fieldstart = 1 */ record= share->default_values-1; /* Fieldstart = 1 */
...@@ -1909,6 +1902,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1909,6 +1902,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
(void) my_hash_check(&share->name_hash); (void) my_hash_check(&share->name_hash);
#endif #endif
DBUG_ASSERT(!share->db_plugin || plugin_equals(share->db_plugin, se_plugin));
share->db_plugin= se_plugin;
share->error= OPEN_FRM_OK; share->error= OPEN_FRM_OK;
thd->status_var.opened_shares++; thd->status_var.opened_shares++;
*root_ptr= old_root; *root_ptr= old_root;
...@@ -1918,6 +1913,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1918,6 +1913,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->error= OPEN_FRM_CORRUPTED; share->error= OPEN_FRM_CORRUPTED;
share->open_errno= my_errno; share->open_errno= my_errno;
delete handler_file; delete handler_file;
plugin_unlock(0, se_plugin);
my_hash_free(&share->name_hash); my_hash_free(&share->name_hash);
if (share->ha_data_destroy) if (share->ha_data_destroy)
{ {
...@@ -1936,9 +1932,128 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, ...@@ -1936,9 +1932,128 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
*root_ptr= old_root; *root_ptr= old_root;
DBUG_RETURN(1); DBUG_RETURN(HA_ERR_NOT_A_TABLE);
} /* open_binary_frm */ }
static bool sql_unusable_for_discovery(THD *thd, const char *sql)
{
LEX *lex= thd->lex;
HA_CREATE_INFO *create_info= &lex->create_info;
// ... not CREATE TABLE
if (lex->sql_command != SQLCOM_CREATE_TABLE)
return 1;
// ... create like
if (create_info->options & HA_LEX_CREATE_TABLE_LIKE)
return 1;
// ... create select
if (lex->select_lex.item_list.elements)
return 1;
// ... temporary
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
return 1;
// ... if exists
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
return 1;
// XXX error out or rather ignore the following:
// ... partitioning
if (lex->part_info)
return 1;
// ... union
if (create_info->used_fields & HA_CREATE_USED_UNION)
return 1;
// ... index/data directory
if (create_info->data_file_name || create_info->index_file_name)
return 1;
// ... engine
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
return 1;
return 0;
}
int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
const char *sql, size_t sql_length)
{
ulonglong saved_mode= thd->variables.sql_mode;
CHARSET_INFO *old_cs= thd->variables.character_set_client;
Parser_state parser_state;
bool error;
char *sql_copy;
handler *file;
LEX *old_lex;
Query_arena *arena, backup;
LEX tmp_lex;
LEX_CUSTRING frm= {0,0};
DBUG_ENTER("TABLE_SHARE::init_from_sql_statement_string");
/*
Ouch. Parser may *change* the string it's working on.
Currently (2013-02-26) it is used to permanently disable
conditional comments.
Anyway, let's copy the caller's string...
*/
if (!(sql_copy= thd->strmake(sql, sql_length)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
if (parser_state.init(thd, sql_copy, sql_length))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
thd->variables.sql_mode= MODE_NO_ENGINE_SUBSTITUTION | MODE_NO_DIR_IN_CREATE;
thd->variables.character_set_client= system_charset_info;
tmp_disable_binlog(thd);
old_lex= thd->lex;
thd->lex= &tmp_lex;
arena= thd->stmt_arena;
if (arena->is_conventional())
arena= 0;
else
thd->set_n_backup_active_arena(arena, &backup);
lex_start(thd);
if ((error= parse_sql(thd, & parser_state, NULL)))
goto ret;
if (sql_unusable_for_discovery(thd, sql_copy))
{
my_error(ER_SQL_DISCOVER_ERROR, MYF(0), plugin_name(db_plugin)->str,
db.str, table_name.str, sql_copy);
goto ret;
}
thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *);
file= mysql_create_frm_image(thd, db.str, table_name.str,
&thd->lex->create_info, &thd->lex->alter_info,
0, 0, &frm);
error|= file == 0;
delete file;
if (frm.str)
error= init_from_binary_frm_image(thd, write, frm.str, frm.length);
ret:
my_free(const_cast<uchar*>(frm.str));
lex_end(thd->lex);
thd->lex= old_lex;
if (arena)
thd->restore_active_arena(arena, &backup);
reenable_binlog(thd);
thd->variables.sql_mode= saved_mode;
thd->variables.character_set_client= old_cs;
if (thd->is_error() || error)
{
thd->clear_error();
my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
}
DBUG_RETURN(0);
}
bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len) bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len)
{ {
......
...@@ -989,8 +989,10 @@ struct TABLE_SHARE ...@@ -989,8 +989,10 @@ struct TABLE_SHARE
uint actual_n_key_parts(THD *thd); uint actual_n_key_parts(THD *thd);
LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table) LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table)
bool init_from_binary_frm_image(THD *thd, bool write, int init_from_binary_frm_image(THD *thd, bool write,
const uchar *frm_image, size_t frm_length); const uchar *frm_image, size_t frm_length);
int init_from_sql_statement_string(THD *thd, bool write,
const char *sql, size_t sql_length);
bool write_frm_image(const uchar *frm_image, size_t frm_length); bool write_frm_image(const uchar *frm_image, size_t frm_length);
bool read_frm_image(const uchar **frm_image, size_t *frm_length); bool read_frm_image(const uchar **frm_image, size_t *frm_length);
}; };
......
...@@ -44,8 +44,6 @@ static uint get_interval_id(uint *,List<Create_field> &, Create_field *); ...@@ -44,8 +44,6 @@ static uint get_interval_id(uint *,List<Create_field> &, Create_field *);
static bool pack_fields(uchar *, List<Create_field> &, ulong); static bool pack_fields(uchar *, List<Create_field> &, ulong);
static size_t packed_fields_length(List<Create_field> &); static size_t packed_fields_length(List<Create_field> &);
static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, ulong); static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, ulong);
static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *,
List<Create_field> &, uint, KEY *, handler *);
/* /*
Create a frm (table definition) file Create a frm (table definition) file
...@@ -67,27 +65,7 @@ static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *, ...@@ -67,27 +65,7 @@ static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *,
true error true error
*/ */
bool mysql_create_frm(THD *thd, const char *file_name, LEX_CUSTRING build_frm_image(THD *thd, const char *table,
const char *db, const char *table,
HA_CREATE_INFO *create_info,
List<Create_field> &create_fields,
uint keys, KEY *key_info,
handler *db_file)
{
DBUG_ENTER("mysql_create_frm");
LEX_CUSTRING frm= create_frm_image(thd, table, create_info,
create_fields, keys, key_info, db_file);
if (!frm.str)
DBUG_RETURN(1);
int error= writefrm(file_name, db, table, !create_info->tmp_table(),
frm.str, frm.length);
my_free(const_cast<uchar*>(frm.str));
DBUG_RETURN(error);
}
LEX_CUSTRING create_frm_image(THD *thd, const char *table,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<Create_field> &create_fields, List<Create_field> &create_fields,
uint keys, KEY *key_info, handler *db_file) uint keys, KEY *key_info, handler *db_file)
...@@ -104,7 +82,7 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table, ...@@ -104,7 +82,7 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table,
int error; int error;
uchar *frm_ptr, *pos; uchar *frm_ptr, *pos;
LEX_CUSTRING frm= {0,0}; LEX_CUSTRING frm= {0,0};
DBUG_ENTER("create_frm_image"); DBUG_ENTER("build_frm_image");
/* If fixed row records, we need one bit to check for deleted rows */ /* If fixed row records, we need one bit to check for deleted rows */
if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) if (!(create_info->table_options & HA_OPTION_PACK_RECORD))
...@@ -373,37 +351,30 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table, ...@@ -373,37 +351,30 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table,
1 error 1 error
*/ */
int rea_create_table(THD *thd, const char *path, int rea_create_table(THD *thd, LEX_CUSTRING *frm,
const char *db, const char *table_name, const char *path, const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info, handler *file)
List<Create_field> &create_fields,
uint keys, KEY *key_info, handler *file)
{ {
DBUG_ENTER("rea_create_table"); DBUG_ENTER("rea_create_table");
LEX_CUSTRING frm= create_frm_image(thd, table_name, create_info,
create_fields, keys, key_info, file);
if (!frm.str)
DBUG_RETURN(1);
if (thd->variables.keep_files_on_create) if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES; create_info->options|= HA_CREATE_KEEP_FILES;
if (create_info->frm_only) if (create_info->frm_only)
{ {
if (writefrm(path, db, table_name, 1, frm.str, frm.length)) if (writefrm(path, db, table_name, 1, frm->str, frm->length))
goto err_handler; goto err_handler;
} }
else else
{ {
// TODO don't write frm for temp tables // TODO don't write frm for temp tables
if (create_info->tmp_table() && if (create_info->tmp_table() &&
writefrm(path, db, table_name, 0, frm.str, frm.length)) writefrm(path, db, table_name, 0, frm->str, frm->length))
goto err_handler; goto err_handler;
if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG,
create_info) || create_info) ||
ha_create_table(thd, path, db, table_name, create_info, &frm)) ha_create_table(thd, path, db, table_name, create_info, frm))
{ {
file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG,
create_info); create_info);
...@@ -411,14 +382,12 @@ int rea_create_table(THD *thd, const char *path, ...@@ -411,14 +382,12 @@ int rea_create_table(THD *thd, const char *path,
} }
} }
my_free(const_cast<uchar*>(frm.str));
DBUG_RETURN(0); DBUG_RETURN(0);
err_handler: err_handler:
char frm_name[FN_REFLEN]; char frm_name[FN_REFLEN];
strxmov(frm_name, path, reg_ext, NullS); strxmov(frm_name, path, reg_ext, NullS);
mysql_file_delete(key_file_frm, frm_name, MYF(0)); mysql_file_delete(key_file_frm, frm_name, MYF(0));
my_free(const_cast<uchar*>(frm.str));
DBUG_RETURN(1); DBUG_RETURN(1);
} /* rea_create_table */ } /* rea_create_table */
......
...@@ -167,17 +167,13 @@ ...@@ -167,17 +167,13 @@
#include "sql_list.h" /* List<> */ #include "sql_list.h" /* List<> */
#include "field.h" /* Create_field */ #include "field.h" /* Create_field */
bool mysql_create_frm(THD *thd, const char *file_name, int rea_create_table(THD *thd, LEX_CUSTRING *frm,
const char *db, const char *table, const char *path, const char *db, const char *table_name,
HA_CREATE_INFO *create_info, handler *file);
LEX_CUSTRING build_frm_image(THD *thd, const char *table,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<Create_field> &create_field, List<Create_field> &create_fields,
uint key_count,KEY *key_info,handler *db_type); uint keys, KEY *key_info, handler *db_file);
int rea_create_table(THD *thd, const char *path,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<Create_field> &create_field,
uint key_count,KEY *key_info,
handler *file);
#define FRM_HEADER_SIZE 64 #define FRM_HEADER_SIZE 64
#define FRM_FORMINFO_SIZE 288 #define FRM_FORMINFO_SIZE 288
......
...@@ -302,9 +302,8 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) ...@@ -302,9 +302,8 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share)
azclose(&frm_stream); azclose(&frm_stream);
if (!share->init_from_binary_frm_image(thd, 1, frm_ptr, frm_stream.frm_length)) my_errno= share->init_from_binary_frm_image(thd, 1,
my_errno= 0; frm_ptr, frm_stream.frm_length);
ret: ret:
my_free(frm_ptr); my_free(frm_ptr);
DBUG_RETURN(my_errno); DBUG_RETURN(my_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