Commit 1522a612 authored by unknown's avatar unknown

Better fix for CREATE TABLE IF NOT EXISTS ... SELECT

Fixed chsize() problem on windows
Extend default timeout on windows clients to 1 year (to avoid timeout problems)


include/mysql.h:
  Added client timeouts (for TCP/IP)
libmysql/libmysql.c:
  Added client timeouts (for TCP/IP)
mysql-test/r/create.result:
  More tests for CREATE TABLE IF NOT EXISTS ... SELECT
mysql-test/t/create.test:
  More tests for CREATE TABLE IF NOT EXISTS ... SELECT
mysys/my_chsize.c:
  Fix for windows
sql/handler.h:
  Remove not used field 'if_not_exists'
  Ordered fields to be more optimized for new CPU's
  Added field 'table_existed'
sql/slave.cc:
  Cleanup temporary tables when slave ends
sql/sql_class.h:
  Remove not used 'do_not_drop' field
sql/sql_insert.cc:
  Better fix for CREATE TABLE IF NOT EXISTS ... SELECT
sql/sql_table.cc:
  Better fix for CREATE TABLE IF NOT EXISTS ... SELECT
parent cfc20dd5
...@@ -60,6 +60,9 @@ typedef int my_socket; ...@@ -60,6 +60,9 @@ typedef int my_socket;
extern unsigned int mysql_port; extern unsigned int mysql_port;
extern char *mysql_unix_port; extern char *mysql_unix_port;
#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */
#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */
#ifdef __NETWARE__ #ifdef __NETWARE__
#pragma pack(push, 8) /* 8 byte alignment */ #pragma pack(push, 8) /* 8 byte alignment */
#endif #endif
......
...@@ -64,8 +64,8 @@ uint mysql_port=0; ...@@ -64,8 +64,8 @@ uint mysql_port=0;
my_string mysql_unix_port=0; my_string mysql_unix_port=0;
ulong net_buffer_length=8192; ulong net_buffer_length=8192;
ulong max_allowed_packet= 1024L*1024L*1024L; ulong max_allowed_packet= 1024L*1024L*1024L;
ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_read_timeout= CLIENT_NET_READ_TIMEOUT;
ulong net_write_timeout= NET_WRITE_TIMEOUT; ulong net_write_timeout= CLIENT_NET_WRITE_TIMEOUT;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS) #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
......
...@@ -200,3 +200,19 @@ select * from t1; ...@@ -200,3 +200,19 @@ select * from t1;
0 1 2 0 1 2
0 0 1 0 0 1
drop table t1; drop table t1;
create table t1 (a int not null, b int, primary key (a));
insert into t1 values (1,1);
create table if not exists t1 select 2;
select * from t1;
a b
1 1
0 2
create table if not exists t1 select 3 as 'a',4 as 'b';
create table if not exists t1 select 3 as 'a',3 as 'b';
Duplicate entry '3' for key 1
select * from t1;
a b
1 1
0 2
3 4
drop table t1;
...@@ -18,21 +18,30 @@ drop table if exists t1; ...@@ -18,21 +18,30 @@ drop table if exists t1;
# Test of some CREATE TABLE'S that should fail # Test of some CREATE TABLE'S that should fail
# #
!$1146 create table t2 type=heap select * from t1; --error 1146
!$1146 create table t2 select auto+1 from t1; create table t2 type=heap select * from t1;
--error 1146
create table t2 select auto+1 from t1;
drop table if exists t1,t2; drop table if exists t1,t2;
!$1167 create table t1 (b char(0) not null, index(b)); --error 1167
!$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap; create table t1 (b char(0) not null, index(b));
!$1163 create table t1 (a int not null,b text) type=heap; --error 1164
create table t1 (a int not null auto_increment,primary key (a)) type=heap;
--error 1163
create table t1 (a int not null,b text) type=heap;
drop table if exists t1; drop table if exists t1;
!$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap; --error 1164
create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
-- error 1044,1 -- error 1044,1
create table not_existing_database.test (a int); create table not_existing_database.test (a int);
!$1103 create table `a/a` (a int); --error 1103
!$1103 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int); create table `a/a` (a int);
!$1059 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int); --error 1103
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
--error 1059
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
# #
# test of dummy table names # test of dummy table names
...@@ -123,9 +132,12 @@ drop table t1; ...@@ -123,9 +132,12 @@ drop table t1;
# #
create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2)); create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
insert into t1 values ("a", 1), ("b", 2); insert into t1 values ("a", 1), ("b", 2);
!$1048 insert into t1 values ("c", NULL); --error 1048
!$1048 insert into t1 values (NULL, 3); insert into t1 values ("c", NULL);
!$1048 insert into t1 values (NULL, NULL); --error 1048
insert into t1 values (NULL, 3);
--error 1048
insert into t1 values (NULL, NULL);
drop table t1; drop table t1;
# #
...@@ -154,3 +166,16 @@ create table if not exists t1 select 1; ...@@ -154,3 +166,16 @@ create table if not exists t1 select 1;
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Test create table if not exists with duplicate key error
#
create table t1 (a int not null, b int, primary key (a));
insert into t1 values (1,1);
create table if not exists t1 select 2;
select * from t1;
create table if not exists t1 select 3 as 'a',4 as 'b';
--error 1062
create table if not exists t1 select 3 as 'a',3 as 'b';
select * from t1;
drop table t1;
...@@ -51,16 +51,17 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) ...@@ -51,16 +51,17 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
#if defined(HAVE_SETFILEPOINTER) #if defined(HAVE_SETFILEPOINTER)
/* This is for the moment only true on windows */ /* This is for the moment only true on windows */
{ {
long is_success;
HANDLE win_file= (HANDLE) _get_osfhandle(fd); HANDLE win_file= (HANDLE) _get_osfhandle(fd);
long length_low, length_high; long length_low, length_high;
length_low= (long) (ulong) newlength; length_low= (long) (ulong) newlength;
length_high= (long) ((ulonglong) newlength >> 32); length_high= (long) ((ulonglong) newlength >> 32);
if (SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN)) is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
{ if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
if (SetEndOfFile(win_file)) goto err;
DBUG_RETURN(0); if (SetEndOfFile(win_file))
} DBUG_RETURN(0);
my_errno= errno; my_errno= GetLastError();
goto err; goto err;
} }
#elif defined(HAVE_FTRUNCATE) #elif defined(HAVE_FTRUNCATE)
......
...@@ -149,21 +149,21 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, ...@@ -149,21 +149,21 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
typedef struct st_ha_create_information typedef struct st_ha_create_information
{ {
ulong table_options;
enum db_type db_type;
enum row_type row_type;
ulong avg_row_length;
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
char *comment,*password; char *comment,*password;
char *data_file_name, *index_file_name; char *data_file_name, *index_file_name;
uint options; /* OR of HA_CREATE_ options */ ulonglong max_rows,min_rows;
uint raid_type,raid_chunks; ulonglong auto_increment_value;
ulong table_options;
ulong avg_row_length;
ulong raid_chunksize; ulong raid_chunksize;
bool if_not_exists;
ulong used_fields; ulong used_fields;
SQL_LIST merge_list; SQL_LIST merge_list;
enum db_type db_type;
enum row_type row_type;
uint options; /* OR of HA_CREATE_ options */
uint raid_type,raid_chunks;
uint merge_insert_method; uint merge_insert_method;
bool table_existed; /* 1 in create if table existed */
} HA_CREATE_INFO; } HA_CREATE_INFO;
......
...@@ -2719,6 +2719,8 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ ...@@ -2719,6 +2719,8 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff));
err: err:
/* Free temporary tables etc */
thd->cleanup();
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety thd->query = thd->db = 0; // extra safety
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
......
...@@ -708,7 +708,6 @@ class select_create: public select_insert { ...@@ -708,7 +708,6 @@ class select_create: public select_insert {
HA_CREATE_INFO *create_info; HA_CREATE_INFO *create_info;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
Field **field; Field **field;
my_bool do_not_drop;
public: public:
select_create (const char *db_name, const char *table_name, select_create (const char *db_name, const char *table_name,
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_par,
...@@ -717,7 +716,7 @@ class select_create: public select_insert { ...@@ -717,7 +716,7 @@ class select_create: public select_insert {
List<Item> &select_fields,enum_duplicates duplic) List<Item> &select_fields,enum_duplicates duplic)
:select_insert (NULL, &select_fields, duplic), db(db_name), :select_insert (NULL, &select_fields, duplic), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par), name(table_name), extra_fields(&fields_par),keys(&keys_par),
create_info(create_info_par), lock(0), do_not_drop(0) create_info(create_info_par), lock(0)
{} {}
int prepare(List<Item> &list); int prepare(List<Item> &list);
bool send_data(List<Item> &values); bool send_data(List<Item> &values);
...@@ -725,6 +724,7 @@ class select_create: public select_insert { ...@@ -725,6 +724,7 @@ class select_create: public select_insert {
void abort(); void abort();
}; };
class select_union :public select_result { class select_union :public select_result {
public: public:
TABLE *table; TABLE *table;
......
...@@ -1440,7 +1440,6 @@ select_create::prepare(List<Item> &values) ...@@ -1440,7 +1440,6 @@ select_create::prepare(List<Item> &values)
if (table->fields < values.elements) if (table->fields < values.elements)
{ {
do_not_drop=1;
my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
ER(ER_WRONG_VALUE_COUNT_ON_ROW), ER(ER_WRONG_VALUE_COUNT_ON_ROW),
MYF(0),1); MYF(0),1);
...@@ -1528,7 +1527,7 @@ void select_create::abort() ...@@ -1528,7 +1527,7 @@ void select_create::abort()
enum db_type table_type=table->db_type; enum db_type table_type=table->db_type;
if (!table->tmp_table) if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table); hash_delete(&open_cache,(byte*) table);
if (!do_not_drop) if (!create_info->table_existed)
quick_rm_table(table_type,db,name); quick_rm_table(table_type,db,name);
table=0; table=0;
} }
......
...@@ -728,7 +728,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -728,7 +728,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
&& find_temporary_table(thd,db,table_name)) && find_temporary_table(thd,db,table_name))
{ {
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0); DBUG_RETURN(0);
}
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
...@@ -739,13 +742,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -739,13 +742,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{ {
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0); DBUG_RETURN(0);
}
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
} }
thd->proc_info="creating table"; thd->proc_info="creating table";
create_info->table_existed= 0; // Mark that table is created
if (thd->sql_mode & MODE_NO_DIR_IN_CREATE) if (thd->sql_mode & MODE_NO_DIR_IN_CREATE)
create_info->data_file_name= create_info->index_file_name= 0; create_info->data_file_name= create_info->index_file_name= 0;
......
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