Commit 32ee15d8 authored by Sergei Golubchik's avatar Sergei Golubchik

Assisted discovery

parent 60aed412
...@@ -634,6 +634,7 @@ enum enum_schema_tables ...@@ -634,6 +634,7 @@ enum enum_schema_tables
}; };
struct TABLE_SHARE; struct TABLE_SHARE;
struct HA_CREATE_INFO;
struct st_foreign_key_info; struct st_foreign_key_info;
typedef struct st_foreign_key_info 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, typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
...@@ -1169,6 +1170,25 @@ struct handlerton ...@@ -1169,6 +1170,25 @@ struct handlerton
int (*discover_table_existence)(handlerton *hton, const char *db, int (*discover_table_existence)(handlerton *hton, const char *db,
const char *table_name); 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);
}; };
......
...@@ -2907,7 +2907,7 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions) ...@@ -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_info_buffer OUT An array of KEY structs for the indexes.
key_count OUT The number of elements in the array. key_count OUT The number of elements in the array.
create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE,
C_CREATE_SELECT C_CREATE_SELECT, C_ASSISTED_DISCOVERY
DESCRIPTION DESCRIPTION
Prepares the table and key structures for table creation. Prepares the table and key structures for table creation.
...@@ -4293,7 +4293,7 @@ handler *mysql_create_frm_image(THD *thd, ...@@ -4293,7 +4293,7 @@ handler *mysql_create_frm_image(THD *thd,
keys List of keys to create keys List of keys to create
is_trans identifies the type of engine where the table is_trans identifies the type of engine where the table
was created: either trans or non-trans. 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). or any positive number (for C_CREATE_SELECT).
DESCRIPTION DESCRIPTION
...@@ -4321,7 +4321,7 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4321,7 +4321,7 @@ bool mysql_create_table_no_lock(THD *thd,
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
uint path_length; uint path_length;
const char *alias; const char *alias;
handler *file; handler *file= 0;
LEX_CUSTRING frm= {0,0}; LEX_CUSTRING frm= {0,0};
bool error= TRUE; bool error= TRUE;
bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || bool internal_tmp_table= create_table_mode == C_ALTER_TABLE ||
...@@ -4330,12 +4330,6 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4330,12 +4330,6 @@ bool mysql_create_table_no_lock(THD *thd,
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
db, table_name, internal_tmp_table)); 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 (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
{ {
if (create_info->data_file_name) if (create_info->data_file_name)
...@@ -4386,9 +4380,53 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4386,9 +4380,53 @@ bool mysql_create_table_no_lock(THD *thd,
thd_proc_info(thd, "creating table"); thd_proc_info(thd, "creating table");
if (rea_create_table(thd, &frm, path, db, table_name, create_info, if (create_table_mode == C_ASSISTED_DISCOVERY)
create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) {
goto err; /* 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()) if (create_info->tmp_table())
{ {
...@@ -4466,6 +4504,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, ...@@ -4466,6 +4504,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
const char *db= create_table->db; const char *db= create_table->db;
const char *table_name= create_table->table_name; const char *table_name= create_table->table_name;
bool is_trans= FALSE; bool is_trans= FALSE;
int create_table_mode;
DBUG_ENTER("mysql_create_table"); DBUG_ENTER("mysql_create_table");
/* Open or obtain an exclusive metadata lock on table being created */ /* 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, ...@@ -4478,9 +4517,14 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
/* Got lock. */ /* Got lock. */
DEBUG_SYNC(thd, "locked_table_name"); 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); promote_first_timestamp_column(&alter_info->create_list);
if (mysql_create_table_no_lock(thd, db, table_name, create_info, if (mysql_create_table_no_lock(thd, db, table_name, create_info, alter_info,
alter_info, &is_trans, C_ORDINARY_CREATE)) &is_trans, create_table_mode))
DBUG_RETURN(1); DBUG_RETURN(1);
/* In RBR we don't need to log CREATE TEMPORARY TABLE */ /* In RBR we don't need to log CREATE TEMPORARY TABLE */
......
...@@ -160,6 +160,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, ...@@ -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 creates an frm file for the #sql-xxx, the table in the engine is not
created. created.
- Assisted discovery, CREATE TABLE statement without the table structure.
These situations are distinguished by the following "create table mode" These situations are distinguished by the following "create table mode"
values, where a CREATE ... SELECT is denoted by any non-negative number 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 (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, ...@@ -169,6 +171,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
#define C_ORDINARY_CREATE 0 #define C_ORDINARY_CREATE 0
#define C_ALTER_TABLE -1 #define C_ALTER_TABLE -1
#define C_ALTER_TABLE_FRM_ONLY -2 #define C_ALTER_TABLE_FRM_ONLY -2
#define C_ASSISTED_DISCOVERY -3
bool mysql_create_table_no_lock(THD *thd, const char *db, bool mysql_create_table_no_lock(THD *thd, const char *db,
const char *table_name, const char *table_name,
......
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