diff options
-rw-r--r-- | sql/handler.h | 20 | ||||
-rw-r--r-- | sql/sql_table.cc | 72 | ||||
-rw-r--r-- | sql/sql_table.h | 3 |
3 files changed, 81 insertions, 14 deletions
diff --git a/sql/handler.h b/sql/handler.h index 3424fa22edf..2290b8f37fd 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -634,6 +634,7 @@ enum enum_schema_tables }; struct TABLE_SHARE; +struct HA_CREATE_INFO; struct st_foreign_key_info; typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len, @@ -1169,6 +1170,25 @@ struct handlerton int (*discover_table_existence)(handlerton *hton, const char *db, const char *table_name); + /* + This is the assisted table discovery method. Unlike the fully + automatic discovery as above, here a user is expected to issue an + explicit CREATE TABLE with the appropriate table attributes to + "assist" the discovery of a table. But this "discovering" CREATE TABLE + statement will not specify the table structure - the engine discovers + it using this method. For example, FederatedX uses it in + + CREATE TABLE t1 ENGINE=FEDERATED CONNECTION="mysql://foo/bar/t1"; + + Given a TABLE_SHARE discover_table_structure() fills it in with a correct + table structure using one of the TABLE_SHARE::init_from_* methods. + + Assisted discovery works independently from the automatic discover. + An engine is allowed to support only assisted discovery and not + support automatic one. Or vice versa. + */ + int (*discover_table_structure)(handlerton *hton, THD* thd, + TABLE_SHARE *share, HA_CREATE_INFO *info); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4f1fdc2e0db..09220a41983 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2907,7 +2907,7 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions) key_info_buffer OUT An array of KEY structs for the indexes. key_count OUT The number of elements in the array. create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, - C_CREATE_SELECT + C_CREATE_SELECT, C_ASSISTED_DISCOVERY DESCRIPTION Prepares the table and key structures for table creation. @@ -4293,7 +4293,7 @@ err: keys List of keys to create is_trans identifies the type of engine where the table was created: either trans or non-trans. - create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, + create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, C_ASSISTED_DISCOVERY or any positive number (for C_CREATE_SELECT). DESCRIPTION @@ -4321,7 +4321,7 @@ bool mysql_create_table_no_lock(THD *thd, char path[FN_REFLEN + 1]; uint path_length; const char *alias; - handler *file; + handler *file= 0; LEX_CUSTRING frm= {0,0}; bool error= TRUE; bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || @@ -4330,12 +4330,6 @@ bool mysql_create_table_no_lock(THD *thd, DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); - file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, - create_table_mode, &frm); - - if (!file) - goto err; - if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)) { if (create_info->data_file_name) @@ -4386,9 +4380,53 @@ bool mysql_create_table_no_lock(THD *thd, thd_proc_info(thd, "creating table"); - if (rea_create_table(thd, &frm, path, db, table_name, create_info, - create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) - goto err; + if (create_table_mode == C_ASSISTED_DISCOVERY) + { + /* check that it's used correctly */ + DBUG_ASSERT(alter_info->create_list.elements == 0); + DBUG_ASSERT(alter_info->key_list.elements == 0); + + TABLE_SHARE share; + handlerton *hton= create_info->db_type; + int ha_err; + Field *no_fields= 0; + + if (!hton->discover_table_structure) + { + my_error(ER_ILLEGAL_HA, MYF(0), table_name); + goto err; + } + + init_tmp_table_share(thd, &share, db, 0, table_name, path); + + /* prepare everything for discovery */ + share.field= &no_fields; + share.db_plugin= plugin_int_to_ref(hton2plugin[hton->slot]); + share.option_list= create_info->option_list; + share.connect_string= create_info->connect_string; + + if (parse_engine_table_options(thd, hton, &share)) + goto err; + + ha_err= hton->discover_table_structure(hton, thd, &share, create_info); + free_table_share(&share); + + if (ha_err) + { + my_error(ER_GET_ERRNO, MYF(0), ha_err); + goto err; + } + } + else + { + file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, + create_table_mode, &frm); + if (!file) + goto err; + if (rea_create_table(thd, &frm, path, db, table_name, create_info, + create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) + goto err; + } if (create_info->tmp_table()) { @@ -4466,6 +4504,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, const char *db= create_table->db; const char *table_name= create_table->table_name; bool is_trans= FALSE; + int create_table_mode; DBUG_ENTER("mysql_create_table"); /* Open or obtain an exclusive metadata lock on table being created */ @@ -4478,9 +4517,14 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, /* Got lock. */ DEBUG_SYNC(thd, "locked_table_name"); + if (alter_info->create_list.elements || alter_info->key_list.elements) + create_table_mode= C_ORDINARY_CREATE; + else + create_table_mode= C_ASSISTED_DISCOVERY; + promote_first_timestamp_column(&alter_info->create_list); - if (mysql_create_table_no_lock(thd, db, table_name, create_info, - alter_info, &is_trans, C_ORDINARY_CREATE)) + if (mysql_create_table_no_lock(thd, db, table_name, create_info, alter_info, + &is_trans, create_table_mode)) DBUG_RETURN(1); /* In RBR we don't need to log CREATE TEMPORARY TABLE */ diff --git a/sql/sql_table.h b/sql/sql_table.h index 3bed73f67c3..8bc6865decd 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -160,6 +160,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, creates an frm file for the #sql-xxx, the table in the engine is not created. + - Assisted discovery, CREATE TABLE statement without the table structure. + These situations are distinguished by the following "create table mode" values, where a CREATE ... SELECT is denoted by any non-negative number (which should be the number of fields in the SELECT ... part), and other @@ -169,6 +171,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, #define C_ORDINARY_CREATE 0 #define C_ALTER_TABLE -1 #define C_ALTER_TABLE_FRM_ONLY -2 +#define C_ASSISTED_DISCOVERY -3 bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, |