Loading mysql-test/r/create.result +0 −15 Original line number Diff line number Diff line Loading @@ -259,21 +259,6 @@ select * from t1; 0 1 2 0 0 1 drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; Warnings: Note 1050 Table 't1' already exists create table if not exists t1 select 1,2,3,4; ERROR 21S01: Column count doesn't match value count at row 1 create table if not exists t1 select 1; Warnings: Note 1050 Table 't1' already exists select * from t1; 1 2 3 1 2 3 0 1 2 0 0 1 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; Loading mysql-test/r/merge.result +49 −0 Original line number Diff line number Diff line Loading @@ -722,3 +722,52 @@ SELECT b FROM t2; b 3 DROP TABLE t1, t2; create table t1(a int); create table t2(a int); insert into t1 values (1); insert into t2 values (2); create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; select * from t3; a 1 2 insert t2 select * from t2; select * from t2; a 2 2 insert t3 select * from t1; select * from t3; a 1 1 2 2 insert t1 select * from t3; select * from t1; a 1 1 1 1 2 2 select * from t2; a 2 2 select * from t3; a 1 1 1 1 2 2 2 2 check table t1, t2; Table Op Msg_type Msg_text test.t1 check status OK test.t2 check status OK drop table t1, t2, t3; mysql-test/t/create.test +0 −7 Original line number Diff line number Diff line Loading @@ -211,13 +211,6 @@ drop table t1; # bug #1434 # create table t1 select 1,2,3; create table if not exists t1 select 1,2; --error 1136 create table if not exists t1 select 1,2,3,4; create table if not exists t1 select 1; select * from t1; drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; --error 1136 Loading mysql-test/t/merge.test +26 −0 Original line number Diff line number Diff line Loading @@ -355,4 +355,30 @@ INSERT INTO t2 (b) VALUES (1) ON DUPLICATE KEY UPDATE b=3; SELECT b FROM t2; DROP TABLE t1, t2; # # BUG#5390 - problems with merge tables # Problem #1: INSERT...SELECT # #drop table if exists t1, t2, t3; create table t1(a int); create table t2(a int); insert into t1 values (1); insert into t2 values (2); create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; select * from t3; # insert t2 select * from t2; select * from t2; # insert t3 select * from t1; select * from t3; # insert t1 select * from t3; select * from t1; select * from t2; select * from t3; check table t1, t2; drop table t1, t2, t3; # End of 4.1 tests sql/lock.cc +122 −1 Original line number Diff line number Diff line Loading @@ -428,6 +428,127 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) } /* Find duplicate lock in tables. SYNOPSIS mysql_lock_have_duplicate() thd The current thread. needle The table to check for duplicate lock. haystack The list of tables to search for the dup lock. NOTE This is mainly meant for MERGE tables in INSERT ... SELECT situations. The 'real', underlying tables can be found only after the table is opened. The easier way is to check this after the tables are locked. RETURN 1 A table from 'tables' matches a lock on 'table'. 0 No duplicate lock is present. -1 Error. */ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, TABLE_LIST *haystack) { uint count; uint dup_pos; TABLE *write_lock_used; /* dummy */ TABLE **tables1; TABLE **tables2; TABLE **table_ptr; TABLE_LIST *tlist_ptr; MYSQL_LOCK *sql_lock1; MYSQL_LOCK *sql_lock2; THR_LOCK_DATA **lock_data1; THR_LOCK_DATA **end_data1; THR_LOCK_DATA **lock_data2; THR_LOCK_DATA **end_data2; THR_LOCK *lock1; DBUG_ENTER("mysql_lock_have_duplicate"); /* Table may not be defined for derived or view tables. */ if (! needle->table) DBUG_RETURN(NULL); /* Get lock(s) for needle. */ tables1= &needle->table; if (! (sql_lock1= get_lock_data(thd, tables1, 1, 1, &write_lock_used))) goto err0; /* Count real tables in list. */ count=0; for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) count++; /* Allocate a table array. */ if (! (tables2= (TABLE**) sql_alloc(sizeof(TABLE*) * count))) goto err1; table_ptr= tables2; /* Assign table pointers. */ for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) *(table_ptr++)= tlist_ptr->table; /* Get lock(s) for haystack. */ if (! (sql_lock2= get_lock_data(thd, tables2, count, 1, &write_lock_used))) goto err1; /* Initialize duplicate position to an impossible value. */ dup_pos= UINT_MAX; /* Find a duplicate lock. In case of merge tables, sql_lock1 can have more than 1 lock. */ for (lock_data1= sql_lock1->locks, end_data1= lock_data1 + sql_lock1->lock_count; lock_data1 < end_data1; lock_data1++) { lock1= (*lock_data1)->lock; for (lock_data2= sql_lock2->locks, end_data2= lock_data2 + sql_lock2->lock_count; lock_data2 < end_data2; lock_data2++) { if ((*lock_data2)->lock == lock1) { DBUG_PRINT("ingo", ("duplicate lock found")); /* Change duplicate position to the real value. */ dup_pos= lock_data2 - sql_lock2->locks; goto end; } } } end: tlist_ptr= NULL; /* In case that no duplicate was found. */ if (dup_pos != UINT_MAX) { /* Duplicate found. Search the matching TABLE_LIST object. */ count= 0; for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) { if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) { count+= tlist_ptr->table->file->lock_count(); if (count > dup_pos) break; } } } my_free((gptr) sql_lock2, MYF(0)); my_free((gptr) sql_lock1, MYF(0)); DBUG_RETURN(tlist_ptr); err1: my_free((gptr) sql_lock1, MYF(0)); err0: /* This non-null but special value indicates error, if caller cares. */ DBUG_RETURN(needle); } /* unlock a set of external */ static int unlock_external(THD *thd, TABLE **table,uint count) Loading Loading @@ -465,8 +586,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, MYSQL_LOCK *sql_lock; THR_LOCK_DATA **locks; TABLE **to; DBUG_ENTER("get_lock_data"); DBUG_PRINT("info", ("count %d", count)); *write_lock_used=0; for (i=tables=lock_count=0 ; i < count ; i++) Loading Loading
mysql-test/r/create.result +0 −15 Original line number Diff line number Diff line Loading @@ -259,21 +259,6 @@ select * from t1; 0 1 2 0 0 1 drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; Warnings: Note 1050 Table 't1' already exists create table if not exists t1 select 1,2,3,4; ERROR 21S01: Column count doesn't match value count at row 1 create table if not exists t1 select 1; Warnings: Note 1050 Table 't1' already exists select * from t1; 1 2 3 1 2 3 0 1 2 0 0 1 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; Loading
mysql-test/r/merge.result +49 −0 Original line number Diff line number Diff line Loading @@ -722,3 +722,52 @@ SELECT b FROM t2; b 3 DROP TABLE t1, t2; create table t1(a int); create table t2(a int); insert into t1 values (1); insert into t2 values (2); create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; select * from t3; a 1 2 insert t2 select * from t2; select * from t2; a 2 2 insert t3 select * from t1; select * from t3; a 1 1 2 2 insert t1 select * from t3; select * from t1; a 1 1 1 1 2 2 select * from t2; a 2 2 select * from t3; a 1 1 1 1 2 2 2 2 check table t1, t2; Table Op Msg_type Msg_text test.t1 check status OK test.t2 check status OK drop table t1, t2, t3;
mysql-test/t/create.test +0 −7 Original line number Diff line number Diff line Loading @@ -211,13 +211,6 @@ drop table t1; # bug #1434 # create table t1 select 1,2,3; create table if not exists t1 select 1,2; --error 1136 create table if not exists t1 select 1,2,3,4; create table if not exists t1 select 1; select * from t1; drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; --error 1136 Loading
mysql-test/t/merge.test +26 −0 Original line number Diff line number Diff line Loading @@ -355,4 +355,30 @@ INSERT INTO t2 (b) VALUES (1) ON DUPLICATE KEY UPDATE b=3; SELECT b FROM t2; DROP TABLE t1, t2; # # BUG#5390 - problems with merge tables # Problem #1: INSERT...SELECT # #drop table if exists t1, t2, t3; create table t1(a int); create table t2(a int); insert into t1 values (1); insert into t2 values (2); create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; select * from t3; # insert t2 select * from t2; select * from t2; # insert t3 select * from t1; select * from t3; # insert t1 select * from t3; select * from t1; select * from t2; select * from t3; check table t1, t2; drop table t1, t2, t3; # End of 4.1 tests
sql/lock.cc +122 −1 Original line number Diff line number Diff line Loading @@ -428,6 +428,127 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) } /* Find duplicate lock in tables. SYNOPSIS mysql_lock_have_duplicate() thd The current thread. needle The table to check for duplicate lock. haystack The list of tables to search for the dup lock. NOTE This is mainly meant for MERGE tables in INSERT ... SELECT situations. The 'real', underlying tables can be found only after the table is opened. The easier way is to check this after the tables are locked. RETURN 1 A table from 'tables' matches a lock on 'table'. 0 No duplicate lock is present. -1 Error. */ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, TABLE_LIST *haystack) { uint count; uint dup_pos; TABLE *write_lock_used; /* dummy */ TABLE **tables1; TABLE **tables2; TABLE **table_ptr; TABLE_LIST *tlist_ptr; MYSQL_LOCK *sql_lock1; MYSQL_LOCK *sql_lock2; THR_LOCK_DATA **lock_data1; THR_LOCK_DATA **end_data1; THR_LOCK_DATA **lock_data2; THR_LOCK_DATA **end_data2; THR_LOCK *lock1; DBUG_ENTER("mysql_lock_have_duplicate"); /* Table may not be defined for derived or view tables. */ if (! needle->table) DBUG_RETURN(NULL); /* Get lock(s) for needle. */ tables1= &needle->table; if (! (sql_lock1= get_lock_data(thd, tables1, 1, 1, &write_lock_used))) goto err0; /* Count real tables in list. */ count=0; for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) count++; /* Allocate a table array. */ if (! (tables2= (TABLE**) sql_alloc(sizeof(TABLE*) * count))) goto err1; table_ptr= tables2; /* Assign table pointers. */ for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) *(table_ptr++)= tlist_ptr->table; /* Get lock(s) for haystack. */ if (! (sql_lock2= get_lock_data(thd, tables2, count, 1, &write_lock_used))) goto err1; /* Initialize duplicate position to an impossible value. */ dup_pos= UINT_MAX; /* Find a duplicate lock. In case of merge tables, sql_lock1 can have more than 1 lock. */ for (lock_data1= sql_lock1->locks, end_data1= lock_data1 + sql_lock1->lock_count; lock_data1 < end_data1; lock_data1++) { lock1= (*lock_data1)->lock; for (lock_data2= sql_lock2->locks, end_data2= lock_data2 + sql_lock2->lock_count; lock_data2 < end_data2; lock_data2++) { if ((*lock_data2)->lock == lock1) { DBUG_PRINT("ingo", ("duplicate lock found")); /* Change duplicate position to the real value. */ dup_pos= lock_data2 - sql_lock2->locks; goto end; } } } end: tlist_ptr= NULL; /* In case that no duplicate was found. */ if (dup_pos != UINT_MAX) { /* Duplicate found. Search the matching TABLE_LIST object. */ count= 0; for (tlist_ptr = haystack; tlist_ptr; tlist_ptr= tlist_ptr->next_global) { if (! tlist_ptr->placeholder() && ! tlist_ptr->schema_table) { count+= tlist_ptr->table->file->lock_count(); if (count > dup_pos) break; } } } my_free((gptr) sql_lock2, MYF(0)); my_free((gptr) sql_lock1, MYF(0)); DBUG_RETURN(tlist_ptr); err1: my_free((gptr) sql_lock1, MYF(0)); err0: /* This non-null but special value indicates error, if caller cares. */ DBUG_RETURN(needle); } /* unlock a set of external */ static int unlock_external(THD *thd, TABLE **table,uint count) Loading Loading @@ -465,8 +586,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, MYSQL_LOCK *sql_lock; THR_LOCK_DATA **locks; TABLE **to; DBUG_ENTER("get_lock_data"); DBUG_PRINT("info", ("count %d", count)); *write_lock_used=0; for (i=tables=lock_count=0 ; i < count ; i++) Loading