Assisted discovery
This commit is contained in:
parent
60aed41222
commit
32ee15d851
@ -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
|
|||||||
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)
|
|||||||
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 @@ err:
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
thd_proc_info(thd, "creating table");
|
thd_proc_info(thd, "creating table");
|
||||||
|
|
||||||
|
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,
|
if (rea_create_table(thd, &frm, path, db, table_name, create_info,
|
||||||
create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file))
|
create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file))
|
||||||
goto err;
|
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,
|
|||||||
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,
|
|||||||
/* 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,
|
|||||||
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,
|
|||||||
#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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user