Commit 4e56ad92 authored by unknown's avatar unknown

sql_table.cc:

  Fix CREATE LIKE TABLE .. temporary case


sql/sql_table.cc:
  Fix CREATE LIKE TABLE .. temporary case
parent 5265a165
...@@ -161,3 +161,63 @@ drop table if exists t1; ...@@ -161,3 +161,63 @@ drop table if exists t1;
create table t1 (a int, key(a)); create table t1 (a int, key(a));
create table t2 (b int, foreign key(b) references t1(a), key(b)); create table t2 (b int, foreign key(b) references t1(a), key(b));
drop table if exists t1,t2; drop table if exists t1,t2;
drop table if exists t1, t2, t3;
create table t1(id int not null, name char(20));
insert into t1 values(10,'mysql'),(20,'monty- the creator');
create table t2(id int not null);
insert into t2 values(10),(20);
create table t3 like t1;
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
) TYPE=MyISAM CHARSET=latin1
select * from t3;
id name
create table if not exists t3 like t1;
Warnings:
Warning 1050 Table 't3' already exists
select @@warning_count;
@@warning_count
1
create temporary table t3 like t2;
show create table t3;
Table Create Table
t3 CREATE TEMPORARY TABLE `t3` (
`id` int(11) NOT NULL default '0'
) TYPE=MyISAM CHARSET=latin1
select * from t3;
id
drop table t3;
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
) TYPE=MyISAM CHARSET=latin1
select * from t3;
id name
drop table t3;
create database test_$1;
drop table if exists test_$1.t3;
create table test_$1.t3 like t1;
create temporary table t3 like test_$1.t3;
show create table t3;
Table Create Table
t3 CREATE TEMPORARY TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
) TYPE=MyISAM CHARSET=latin1
create table t3 like t1;
create table t3 like test_$1.t3;
Table 't3' already exists
create table non_existing_database.t1 like t1;
Got one of the listed errors
create table t3 like non_existing_table;
Unknown table 'non_existing_table'
create temporary table t3 like t1;
Table 't3' already exists
drop table t1, t2, t3;
drop table t3;
drop database test_$1;
...@@ -113,3 +113,40 @@ drop table if exists t1; ...@@ -113,3 +113,40 @@ drop table if exists t1;
create table t1 (a int, key(a)); create table t1 (a int, key(a));
create table t2 (b int, foreign key(b) references t1(a), key(b)); create table t2 (b int, foreign key(b) references t1(a), key(b));
drop table if exists t1,t2; drop table if exists t1,t2;
#
# Test for CREATE TABLE .. LIKE ..
#
drop table if exists t1, t2, t3;
create table t1(id int not null, name char(20));
insert into t1 values(10,'mysql'),(20,'monty- the creator');
create table t2(id int not null);
insert into t2 values(10),(20);
create table t3 like t1;
show create table t3;
select * from t3;
create table if not exists t3 like t1;
select @@warning_count;
create temporary table t3 like t2;
show create table t3;
select * from t3;
drop table t3;
show create table t3;
select * from t3;
drop table t3;
create database test_$1;
drop table if exists test_$1.t3;
create table test_$1.t3 like t1;
create temporary table t3 like test_$1.t3;
show create table t3;
create table t3 like t1;
!$1050 create table t3 like test_$1.t3;
--error 1044,1
create table non_existing_database.t1 like t1;
!$1051 create table t3 like non_existing_table;
!$1050 create temporary table t3 like t1;
drop table t1, t2, t3;
drop table t3;
drop database test_$1;
...@@ -422,6 +422,9 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, ...@@ -422,6 +422,9 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
bool simple_alter=0); bool simple_alter=0);
int mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info,
Table_ident *src_table);
bool mysql_rename_table(enum db_type base, bool mysql_rename_table(enum db_type base,
const char *old_db, const char *old_db,
const char * old_name, const char * old_name,
......
...@@ -1830,10 +1830,14 @@ mysql_execute_command(THD *thd) ...@@ -1830,10 +1830,14 @@ mysql_execute_command(THD *thd)
} }
else // regular create else // regular create
{ {
res = mysql_create_table(thd,tables->db ? tables->db : thd->db, if (lex->name)
tables->real_name, &lex->create_info, res= mysql_create_like_table(thd, tables, &lex->create_info,
lex->create_list, (Table_ident *)lex->name);
lex->key_list,0,0,0); // do logging else
res= mysql_create_table(thd,tables->db ? tables->db : thd->db,
tables->real_name, &lex->create_info,
lex->create_list,
lex->key_list,0,0,0); // do logging
if (!res) if (!res)
send_ok(thd); send_ok(thd);
} }
......
...@@ -1376,6 +1376,125 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) ...@@ -1376,6 +1376,125 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
} }
/*
Create a table identical to the specified table
SYNOPSIS
mysql_create_like_table()
thd Thread object
table Table list (one table only)
create_info Create info
table_ident Src table_ident
RETURN VALUES
0 ok
-1 error
*/
int mysql_create_like_table(THD* thd, TABLE_LIST* table,
HA_CREATE_INFO *create_info,
Table_ident *table_ident)
{
TABLE **tmp_table;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char *db= table->db;
char *table_name= table->real_name;
char *src_db= thd->db;
char *src_table= table_ident->table.str;
int err;
DBUG_ENTER("mysql_create_like_table");
/*
Validate the source table
*/
if (table_ident->table.length > NAME_LEN ||
(table_ident->table.length &&
check_table_name(src_table,table_ident->table.length)) ||
table_ident->db.str && check_db_name((src_db= table_ident->db.str)))
{
net_printf(thd,ER_WRONG_TABLE_NAME,src_table);
DBUG_RETURN(0);
}
if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
strxmov(src_path, (*tmp_table)->path, reg_ext, NullS);
else
{
strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
reg_ext, NullS);
if (access(src_path, F_OK))
{
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
DBUG_RETURN(-1);
}
}
/*
Validate the destination table
skip the destination table name checking as this is already
validated.
*/
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (find_temporary_table(thd, db, table_name))
goto table_exists;
sprintf(dst_path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
}
else
{
strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
reg_ext, NullS);
if (!access(dst_path, F_OK))
goto table_exists;
}
/*
Create a new table by copying from source table
*/
if (my_copy(src_path, dst_path, MYF(MY_WME)))
DBUG_RETURN(-1);
/*
As mysql_truncate don't work on a new table at this stage of
creation, instead create the table directly (for both normal
and temporary tables).
*/
*fn_ext(dst_path)= 0;
err= ha_create_table(dst_path, create_info, 1);
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
{
(void) rm_temporary_table(create_info->db_type, dst_path);
DBUG_RETURN(-1);
}
}
else if (err)
{
(void) quick_rm_table(create_info->db_type, db, table_name);
DBUG_RETURN(-1);
}
DBUG_RETURN(0);
table_exists:
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff,ER(ER_TABLE_EXISTS_ERROR),table_name);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TABLE_EXISTS_ERROR,warn_buff);
DBUG_RETURN(0);
}
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
DBUG_RETURN(-1);
}
int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{ {
#ifdef OS2 #ifdef OS2
......
...@@ -835,6 +835,7 @@ create: ...@@ -835,6 +835,7 @@ create:
lex->create_info.options=$2 | $4; lex->create_info.options=$2 | $4;
lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info; lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info;
lex->name=0;
} }
create2 create2
{} {}
...@@ -883,7 +884,13 @@ create: ...@@ -883,7 +884,13 @@ create:
create2: create2:
'(' field_list ')' opt_create_table_options create3 {} '(' field_list ')' opt_create_table_options create3 {}
| opt_create_table_options create3 {} | opt_create_table_options create3 {}
; | LIKE table_ident
{
LEX *lex=Lex;
if (!(lex->name= (char *)$2))
YYABORT;
}
;
create3: create3:
/* empty */ {} /* empty */ {}
......
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