mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
discovery using sql CREATE TABLE statement
This commit is contained in:
@ -978,7 +978,7 @@ SHOW CREATE TABLE `tt+2`;
|
||||
Table Create Table
|
||||
tt+2 CREATE TEMPORARY TABLE `tt+2` (
|
||||
`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`;
|
||||
CREATE TABLE `#sql1` (c1 INT);
|
||||
CREATE TABLE `@0023sql2` (c1 INT);
|
||||
@ -1015,12 +1015,12 @@ SHOW CREATE TABLE `#sql2`;
|
||||
Table Create Table
|
||||
#sql2 CREATE TEMPORARY TABLE `#sql2` (
|
||||
`c1` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
|
||||
SHOW CREATE TABLE `@0023sql1`;
|
||||
Table Create Table
|
||||
@0023sql1 CREATE TEMPORARY TABLE `@0023sql1` (
|
||||
`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 IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
|
@ -2883,7 +2883,7 @@ Table Create Table
|
||||
m2 CREATE TEMPORARY TABLE `m2` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -2900,7 +2900,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -2989,7 +2989,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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);
|
||||
SELECT * FROM m1;
|
||||
c1 c2
|
||||
@ -3040,7 +3040,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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;
|
||||
SHOW CREATE TABLE m2;
|
||||
@ -3092,7 +3092,7 @@ Table Create Table
|
||||
m2 CREATE TABLE `m2` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -3118,7 +3118,7 @@ Table Create Table
|
||||
m2 CREATE TEMPORARY TABLE `m2` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -3288,7 +3288,7 @@ Table Create Table
|
||||
m2 CREATE TEMPORARY TABLE `m2` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -3305,7 +3305,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
@ -3396,7 +3396,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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);
|
||||
SELECT * FROM m1;
|
||||
c1 c2
|
||||
@ -3447,7 +3447,7 @@ Table Create Table
|
||||
m1 CREATE TEMPORARY TABLE `m1` (
|
||||
`c1` 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;
|
||||
ERROR HY000: Table 'm2' was not locked with LOCK TABLES
|
||||
#
|
||||
@ -3492,14 +3492,14 @@ Table Create Table
|
||||
m2 CREATE TEMPORARY TABLE `m2` (
|
||||
`c1` 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;
|
||||
SHOW CREATE TABLE m2;
|
||||
Table Create Table
|
||||
m2 CREATE TEMPORARY TABLE `m2` (
|
||||
`c1` 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;
|
||||
c1 c2
|
||||
111 121
|
||||
|
@ -198,7 +198,7 @@ show create table t2;
|
||||
Table Create Table
|
||||
t2 CREATE TEMPORARY TABLE `t2` (
|
||||
`a` int(11) NOT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
|
||||
drop table t2;
|
||||
create table t1 (
|
||||
test_set set( 'val1', 'val2', 'val3' ) not null default '',
|
||||
|
@ -12846,5 +12846,5 @@ Table Create Table
|
||||
t1 CREATE TEMPORARY TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` varchar(10) DEFAULT NULL
|
||||
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
|
||||
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
|
||||
drop table t1;
|
||||
|
@ -4317,6 +4317,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
|
||||
handlerton *hton= plugin_data(plugin, handlerton *);
|
||||
if (hton->state == SHOW_OPTION_YES && hton->discover_table)
|
||||
{
|
||||
share->db_plugin= plugin;
|
||||
int error= hton->discover_table(hton, thd, share);
|
||||
if (error != HA_ERR_NO_SUCH_TABLE)
|
||||
{
|
||||
@ -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
|
||||
my_error(ER_GET_ERRNO, MYF(0), error);
|
||||
share->db_plugin= 0;
|
||||
}
|
||||
else
|
||||
share->error= OPEN_FRM_OK;
|
||||
@ -4331,6 +4333,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
|
||||
status_var_increment(thd->status_var.ha_discover_count);
|
||||
return TRUE; // abort the search
|
||||
}
|
||||
share->db_plugin= 0;
|
||||
}
|
||||
|
||||
DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR);
|
||||
@ -4342,6 +4345,7 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share)
|
||||
DBUG_ENTER("ha_discover_table");
|
||||
|
||||
DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet
|
||||
DBUG_ASSERT(!share->db_plugin);
|
||||
|
||||
if (!plugin_foreach(thd, discover_handlerton,
|
||||
MYSQL_STORAGE_ENGINE_PLUGIN, share))
|
||||
|
@ -6600,3 +6600,6 @@ ER_SLAVE_STARTED
|
||||
eng "SLAVE '%.*s' started"
|
||||
ER_SLAVE_STOPPED
|
||||
eng "SLAVE '%.*s' stopped"
|
||||
ER_SQL_DISCOVER_ERROR
|
||||
eng "Engine %s failed to discover table %`-.192s.%`-.192s with '%s'"
|
||||
|
||||
|
275
sql/sql_table.cc
275
sql/sql_table.cc
@ -1703,13 +1703,23 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
||||
#endif
|
||||
/* Write shadow frm file */
|
||||
lpt->create_info->table_options= lpt->db_options;
|
||||
if ((mysql_create_frm(lpt->thd, shadow_path, lpt->db,
|
||||
lpt->table_name, lpt->create_info,
|
||||
lpt->alter_info->create_list, lpt->key_count,
|
||||
lpt->key_info_buffer, lpt->table->file)) ||
|
||||
lpt->table->file->ha_create_partitioning_metadata(shadow_path, NULL,
|
||||
CHF_CREATE_FLAG,
|
||||
lpt->create_info))
|
||||
LEX_CUSTRING frm= build_frm_image(lpt->thd, lpt->table_name,
|
||||
lpt->create_info,
|
||||
lpt->alter_info->create_list,
|
||||
lpt->key_count, lpt->key_info_buffer,
|
||||
lpt->table->file);
|
||||
if (!frm.str)
|
||||
{
|
||||
error= 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
int error= writefrm(shadow_path, lpt->db, lpt->table_name,
|
||||
!lpt->create_info->tmp_table(), frm.str, frm.length);
|
||||
my_free(const_cast<uchar*>(frm.str));
|
||||
|
||||
if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path,
|
||||
NULL, CHF_CREATE_FLAG, lpt->create_info))
|
||||
{
|
||||
mysql_file_delete(key_file_frm, shadow_frm_name, MYF(0));
|
||||
error= 1;
|
||||
@ -3857,6 +3867,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
}
|
||||
}
|
||||
|
||||
if (create_info->tmp_table())
|
||||
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
|
||||
|
||||
/* Give warnings for not supported table options */
|
||||
#if defined(WITH_ARIA_STORAGE_ENGINE)
|
||||
extern handlerton *maria_hton;
|
||||
if (file->ht != maria_hton)
|
||||
#endif
|
||||
if (create_info->transactional)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
file->engine_name()->str,
|
||||
"TRANSACTIONAL=1");
|
||||
|
||||
if (parse_option_list(thd, &create_info->option_struct,
|
||||
create_info->option_list,
|
||||
file->partition_ht()->table_options, FALSE,
|
||||
@ -4047,70 +4072,27 @@ static bool check_if_created_table_can_be_opened(THD *thd,
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Create a table
|
||||
|
||||
SYNOPSIS
|
||||
mysql_create_table_no_lock()
|
||||
thd Thread object
|
||||
db Database
|
||||
table_name Table name
|
||||
create_info Create information (like MAX_ROWS)
|
||||
fields List of fields to create
|
||||
keys List of keys to create
|
||||
internal_tmp_table Set to 1 if this is an internal temporary table
|
||||
(From ALTER TABLE)
|
||||
select_field_count
|
||||
is_trans identifies the type of engine where the table
|
||||
was created: either trans or non-trans.
|
||||
|
||||
DESCRIPTION
|
||||
If one creates a temporary table, this is automatically opened
|
||||
|
||||
Note that this function assumes that caller already have taken
|
||||
exclusive metadata lock on table being created or used some other
|
||||
way to ensure that concurrent operations won't intervene.
|
||||
mysql_create_table() is a wrapper that can be used for this.
|
||||
|
||||
no_log is needed for the case of CREATE ... SELECT,
|
||||
as the logging will be done later in sql_insert.cc
|
||||
select_field_count is also used for CREATE ... SELECT,
|
||||
and must be zero for standard create of table.
|
||||
|
||||
RETURN VALUES
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
bool mysql_create_table_no_lock(THD *thd,
|
||||
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,
|
||||
bool *is_trans)
|
||||
uint select_field_count, LEX_CUSTRING *frm)
|
||||
{
|
||||
char path[FN_REFLEN + 1];
|
||||
uint path_length;
|
||||
const char *alias;
|
||||
uint db_options, key_count;
|
||||
KEY *key_info_buffer;
|
||||
handler *file;
|
||||
bool error= TRUE;
|
||||
DBUG_ENTER("mysql_create_table_no_lock");
|
||||
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
|
||||
db, table_name, internal_tmp_table));
|
||||
|
||||
DBUG_ENTER("mysql_create_frm_image");
|
||||
|
||||
/* Check for duplicate fields and check type of table to create */
|
||||
if (!alter_info->create_list.elements)
|
||||
{
|
||||
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
|
||||
MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
if (check_engine(thd, db, table_name, create_info))
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
set_table_default_charset(thd, create_info, (char*) db);
|
||||
|
||||
@ -4119,12 +4101,11 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
create_info->row_type != ROW_TYPE_FIXED &&
|
||||
create_info->row_type != ROW_TYPE_DEFAULT)
|
||||
db_options|= HA_OPTION_PACK_RECORD;
|
||||
alias= table_case_name(create_info, table_name);
|
||||
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
|
||||
create_info->db_type)))
|
||||
{
|
||||
mem_alloc_error(sizeof(handler));
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
partition_info *part_info= thd->work_part_info;
|
||||
@ -4141,7 +4122,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
if (!part_info)
|
||||
{
|
||||
mem_alloc_error(sizeof(partition_info));
|
||||
DBUG_RETURN(TRUE);
|
||||
goto err;
|
||||
}
|
||||
file->set_auto_partitions(part_info);
|
||||
part_info->default_engine_type= create_info->db_type;
|
||||
@ -4166,7 +4147,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
char *part_syntax_buf;
|
||||
uint syntax_len;
|
||||
handlerton *engine_type;
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
|
||||
goto err;
|
||||
@ -4238,9 +4219,8 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
delete file;
|
||||
create_info->db_type= partition_hton;
|
||||
if (!(file= get_ha_partition(part_info)))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
/*
|
||||
If we have default number of partitions or subpartitions we
|
||||
might require to set-up the part_info object such that it
|
||||
@ -4282,65 +4262,90 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
engine_type)))
|
||||
{
|
||||
mem_alloc_error(sizeof(handler));
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mysql_prepare_create_table(thd, create_info, alter_info,
|
||||
internal_tmp_table,
|
||||
&db_options, file,
|
||||
internal_tmp_table, &db_options, file,
|
||||
&key_info_buffer, &key_count,
|
||||
select_field_count))
|
||||
goto err;
|
||||
create_info->table_options=db_options;
|
||||
|
||||
/* Check if table exists */
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
path_length= build_tmptable_filename(thd, path, sizeof(path));
|
||||
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext,
|
||||
internal_tmp_table ? FN_IS_TMP : 0);
|
||||
}
|
||||
*frm= build_frm_image(thd, table_name, create_info,
|
||||
alter_info->create_list, key_count,
|
||||
key_info_buffer, file);
|
||||
|
||||
/* Check if table already exists */
|
||||
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||
find_temporary_table(thd, db, table_name))
|
||||
{
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
goto warn;
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
|
||||
if (frm->str)
|
||||
DBUG_RETURN(file);
|
||||
|
||||
err:
|
||||
delete file;
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a table
|
||||
|
||||
SYNOPSIS
|
||||
mysql_create_table_no_lock()
|
||||
thd Thread object
|
||||
db Database
|
||||
table_name Table name
|
||||
create_info Create information (like MAX_ROWS)
|
||||
fields List of fields to create
|
||||
keys List of keys to create
|
||||
internal_tmp_table Set to 1 if this is an internal temporary table
|
||||
(From ALTER TABLE)
|
||||
select_field_count
|
||||
is_trans identifies the type of engine where the table
|
||||
was created: either trans or non-trans.
|
||||
|
||||
DESCRIPTION
|
||||
If one creates a temporary table, this is automatically opened
|
||||
|
||||
Note that this function assumes that caller already have taken
|
||||
exclusive metadata lock on table being created or used some other
|
||||
way to ensure that concurrent operations won't intervene.
|
||||
mysql_create_table() is a wrapper that can be used for this.
|
||||
|
||||
select_field_count is also used for CREATE ... SELECT,
|
||||
and must be zero for standard create of table.
|
||||
|
||||
RETURN VALUES
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
bool mysql_create_table_no_lock(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,
|
||||
bool *is_trans)
|
||||
{
|
||||
char path[FN_REFLEN + 1];
|
||||
uint path_length;
|
||||
const char *alias;
|
||||
handler *file;
|
||||
LEX_CUSTRING frm= {0,0};
|
||||
bool error= TRUE;
|
||||
DBUG_ENTER("mysql_create_table_no_lock");
|
||||
DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
|
||||
db, table_name, internal_tmp_table));
|
||||
|
||||
alias= table_case_name(create_info, table_name);
|
||||
|
||||
file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info,
|
||||
internal_tmp_table, select_field_count, &frm);
|
||||
|
||||
if (!file)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Give warnings for not supported table options */
|
||||
#if defined(WITH_ARIA_STORAGE_ENGINE)
|
||||
extern handlerton *maria_hton;
|
||||
if (file->ht != maria_hton)
|
||||
#endif
|
||||
if (create_info->transactional)
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||
ER(ER_ILLEGAL_HA_CREATE_OPTION),
|
||||
file->engine_name()->str,
|
||||
"TRANSACTIONAL=1");
|
||||
|
||||
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
|
||||
{
|
||||
if (ha_table_exists(thd, db, table_name))
|
||||
{
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
goto warn;
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
thd_proc_info(thd, "creating table");
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
{
|
||||
@ -4402,15 +4407,41 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
"INDEX DIRECTORY");
|
||||
create_info->data_file_name= create_info->index_file_name= 0;
|
||||
}
|
||||
create_info->table_options=db_options;
|
||||
|
||||
/* Check if table exists */
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
path_length= build_tmptable_filename(thd, path, sizeof(path));
|
||||
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
|
||||
if (rea_create_table(thd, path, db, table_name,
|
||||
create_info, alter_info->create_list,
|
||||
key_count, key_info_buffer, file))
|
||||
|
||||
if (find_temporary_table(thd, db, table_name))
|
||||
{
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
goto warn;
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
path_length= build_table_filename(path, sizeof(path) - 1, db, alias, "",
|
||||
internal_tmp_table ? FN_IS_TMP : 0);
|
||||
|
||||
if (!internal_tmp_table && ha_table_exists(thd, db, table_name))
|
||||
{
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
goto warn;
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
thd_proc_info(thd, "creating table");
|
||||
|
||||
if (rea_create_table(thd, &frm, path, db, table_name, create_info, file))
|
||||
goto err;
|
||||
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
/*
|
||||
Open a table (skipping table cache) and add it into
|
||||
@ -4431,7 +4462,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
thd->thread_specific_used= TRUE;
|
||||
}
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
else if (part_info && create_info->frm_only)
|
||||
else if (thd->work_part_info && create_info->frm_only)
|
||||
{
|
||||
/*
|
||||
For partitioned tables we can't find some problems with table
|
||||
@ -4457,6 +4488,7 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
error= FALSE;
|
||||
err:
|
||||
thd_proc_info(thd, "After create");
|
||||
my_free(const_cast<uchar*>(frm.str));
|
||||
delete file;
|
||||
DBUG_RETURN(error);
|
||||
|
||||
@ -4468,7 +4500,6 @@ warn:
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Implementation of SQLCOM_CREATE_TABLE.
|
||||
|
||||
@ -4514,7 +4545,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
||||
if (!result &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
(thd->is_current_stmt_binlog_format_row() &&
|
||||
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
|
||||
!(create_info->tmp_table()))))
|
||||
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans);
|
||||
|
||||
end:
|
||||
@ -4727,7 +4758,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
local_create_info.options|= create_info->options&HA_LEX_CREATE_IF_NOT_EXISTS;
|
||||
/* Replace type of source table with one specified in the statement. */
|
||||
local_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
|
||||
local_create_info.options|= create_info->options & HA_LEX_CREATE_TMP_TABLE;
|
||||
local_create_info.options|= create_info->tmp_table();
|
||||
/* Reset auto-increment counter for the new table. */
|
||||
local_create_info.auto_increment_value= 0;
|
||||
/*
|
||||
@ -4745,7 +4776,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
Ensure that we have an exclusive lock on target table if we are creating
|
||||
non-temporary table.
|
||||
*/
|
||||
DBUG_ASSERT((create_info->options & HA_LEX_CREATE_TMP_TABLE) ||
|
||||
DBUG_ASSERT((create_info->tmp_table()) ||
|
||||
thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
|
||||
table->table_name,
|
||||
MDL_EXCLUSIVE));
|
||||
@ -4772,7 +4803,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
|
||||
4 temporary temporary Nothing
|
||||
==== ========= ========= ==============================
|
||||
*/
|
||||
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
|
||||
if (!(create_info->tmp_table()))
|
||||
{
|
||||
if (src_table->table->s->tmp_table) // Case 2
|
||||
{
|
||||
@ -7227,7 +7258,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
|
||||
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
|
||||
thd->is_current_stmt_binlog_format_row() &&
|
||||
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
|
||||
(create_info->tmp_table())));
|
||||
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
@ -7852,7 +7883,7 @@ static bool check_engine(THD *thd, const char *db_name,
|
||||
ha_resolve_storage_engine_name(*new_engine),
|
||||
table_name);
|
||||
}
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
|
||||
if (create_info->tmp_table() &&
|
||||
ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
|
||||
{
|
||||
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
|
||||
|
@ -25,6 +25,7 @@ struct TABLE_LIST;
|
||||
class THD;
|
||||
struct TABLE;
|
||||
struct handlerton;
|
||||
class handler;
|
||||
typedef struct st_ha_check_opt HA_CHECK_OPT;
|
||||
struct HA_CREATE_INFO;
|
||||
typedef struct st_key KEY;
|
||||
@ -140,6 +141,12 @@ bool mysql_create_table_no_lock(THD *thd, const char *db,
|
||||
Alter_info *alter_info,
|
||||
bool tmp_table, uint select_field_count,
|
||||
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,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info);
|
||||
|
157
sql/table.cc
157
sql/table.cc
@ -693,7 +693,7 @@ err_not_open:
|
||||
|
||||
*/
|
||||
|
||||
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,
|
||||
size_t frm_length)
|
||||
{
|
||||
@ -729,10 +729,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
KEY_PART_INFO *first_key_part= NULL;
|
||||
uint ext_key_parts= 0;
|
||||
uint first_key_parts= 0;
|
||||
plugin_ref se_plugin= 0;
|
||||
keyinfo= &first_keyinfo;
|
||||
share->ext_key_parts= 0;
|
||||
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);
|
||||
old_root= *root_ptr;
|
||||
@ -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]));
|
||||
#endif
|
||||
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
|
||||
dynamically allocated legacy_db_type. We will resolve it later by name.
|
||||
*/
|
||||
if (legacy_db_type > DB_TYPE_UNKNOWN &&
|
||||
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
|
||||
share->db_plugin= ha_lock_engine(NULL,
|
||||
ha_checktype(thd, legacy_db_type, 0, 0));
|
||||
se_plugin= ha_lock_engine(NULL, ha_checktype(thd, legacy_db_type, 0, 0));
|
||||
share->db_create_options= db_create_options= uint2korr(frm_image+30);
|
||||
share->db_options_in_use= share->db_create_options;
|
||||
share->mysql_version= uint4korr(frm_image+51);
|
||||
@ -1045,7 +1044,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
name.length= str_db_type_length;
|
||||
|
||||
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 &&
|
||||
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
|
||||
@ -1057,14 +1056,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
}
|
||||
/*
|
||||
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
|
||||
*/
|
||||
plugin_unlock(NULL, share->db_plugin);
|
||||
share->db_plugin= my_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())));
|
||||
plugin_unlock(NULL, se_plugin);
|
||||
se_plugin= plugin_lock(NULL, tmp_plugin);
|
||||
}
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
else if (str_db_type_length == 9 &&
|
||||
@ -1073,7 +1069,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
/*
|
||||
Use partition handler
|
||||
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
|
||||
*/
|
||||
/* Check if the partitioning engine is ready */
|
||||
@ -1083,11 +1079,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
"--skip-partition");
|
||||
goto err;
|
||||
}
|
||||
plugin_unlock(NULL, share->db_plugin);
|
||||
share->db_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())));
|
||||
plugin_unlock(NULL, se_plugin);
|
||||
se_plugin= ha_lock_engine(NULL, partition_hton);
|
||||
}
|
||||
#endif
|
||||
else if (!tmp_plugin)
|
||||
@ -1284,7 +1277,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
|
||||
/* Allocate handler */
|
||||
if (!(handler_file= get_new_handler(share, thd->mem_root,
|
||||
share->db_type())))
|
||||
plugin_data(se_plugin, handlerton *))))
|
||||
goto err;
|
||||
|
||||
record= share->default_values-1; /* Fieldstart = 1 */
|
||||
@ -1909,6 +1902,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
(void) my_hash_check(&share->name_hash);
|
||||
#endif
|
||||
|
||||
DBUG_ASSERT(!share->db_plugin || plugin_equals(share->db_plugin, se_plugin));
|
||||
share->db_plugin= se_plugin;
|
||||
share->error= OPEN_FRM_OK;
|
||||
thd->status_var.opened_shares++;
|
||||
*root_ptr= old_root;
|
||||
@ -1918,6 +1913,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
share->error= OPEN_FRM_CORRUPTED;
|
||||
share->open_errno= my_errno;
|
||||
delete handler_file;
|
||||
plugin_unlock(0, se_plugin);
|
||||
my_hash_free(&share->name_hash);
|
||||
if (share->ha_data_destroy)
|
||||
{
|
||||
@ -1936,10 +1932,129 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno);
|
||||
|
||||
*root_ptr= old_root;
|
||||
DBUG_RETURN(1);
|
||||
} /* open_binary_frm */
|
||||
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
return writefrm(normalized_path.str, db.str, table_name.str, 1, frm, len);
|
||||
|
@ -989,8 +989,10 @@ struct TABLE_SHARE
|
||||
uint actual_n_key_parts(THD *thd);
|
||||
|
||||
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);
|
||||
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 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 *);
|
||||
static bool pack_fields(uchar *, List<Create_field> &, ulong);
|
||||
static size_t packed_fields_length(List<Create_field> &);
|
||||
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
|
||||
@ -67,27 +65,7 @@ static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *,
|
||||
true error
|
||||
*/
|
||||
|
||||
bool mysql_create_frm(THD *thd, const char *file_name,
|
||||
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,
|
||||
LEX_CUSTRING build_frm_image(THD *thd, const char *table,
|
||||
HA_CREATE_INFO *create_info,
|
||||
List<Create_field> &create_fields,
|
||||
uint keys, KEY *key_info, handler *db_file)
|
||||
@ -104,7 +82,7 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table,
|
||||
int error;
|
||||
uchar *frm_ptr, *pos;
|
||||
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 (!(create_info->table_options & HA_OPTION_PACK_RECORD))
|
||||
@ -373,37 +351,30 @@ err:
|
||||
1 error
|
||||
*/
|
||||
|
||||
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_fields,
|
||||
uint keys, KEY *key_info, handler *file)
|
||||
int rea_create_table(THD *thd, LEX_CUSTRING *frm,
|
||||
const char *path, const char *db, const char *table_name,
|
||||
HA_CREATE_INFO *create_info, handler *file)
|
||||
{
|
||||
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)
|
||||
create_info->options|= HA_CREATE_KEEP_FILES;
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO don't write frm for temp tables
|
||||
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;
|
||||
|
||||
if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG,
|
||||
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,
|
||||
create_info);
|
||||
@ -411,14 +382,12 @@ int rea_create_table(THD *thd, const char *path,
|
||||
}
|
||||
}
|
||||
|
||||
my_free(const_cast<uchar*>(frm.str));
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err_handler:
|
||||
char frm_name[FN_REFLEN];
|
||||
strxmov(frm_name, path, reg_ext, NullS);
|
||||
mysql_file_delete(key_file_frm, frm_name, MYF(0));
|
||||
my_free(const_cast<uchar*>(frm.str));
|
||||
DBUG_RETURN(1);
|
||||
} /* rea_create_table */
|
||||
|
||||
|
16
sql/unireg.h
16
sql/unireg.h
@ -167,17 +167,13 @@
|
||||
#include "sql_list.h" /* List<> */
|
||||
#include "field.h" /* Create_field */
|
||||
|
||||
bool mysql_create_frm(THD *thd, const char *file_name,
|
||||
const char *db, const char *table,
|
||||
int rea_create_table(THD *thd, LEX_CUSTRING *frm,
|
||||
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,
|
||||
List<Create_field> &create_field,
|
||||
uint key_count,KEY *key_info,handler *db_type);
|
||||
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);
|
||||
List<Create_field> &create_fields,
|
||||
uint keys, KEY *key_info, handler *db_file);
|
||||
|
||||
#define FRM_HEADER_SIZE 64
|
||||
#define FRM_FORMINFO_SIZE 288
|
||||
|
@ -302,9 +302,8 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share)
|
||||
|
||||
azclose(&frm_stream);
|
||||
|
||||
if (!share->init_from_binary_frm_image(thd, 1, frm_ptr, frm_stream.frm_length))
|
||||
my_errno= 0;
|
||||
|
||||
my_errno= share->init_from_binary_frm_image(thd, 1,
|
||||
frm_ptr, frm_stream.frm_length);
|
||||
ret:
|
||||
my_free(frm_ptr);
|
||||
DBUG_RETURN(my_errno);
|
||||
|
Reference in New Issue
Block a user