summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkostja@bodhi.(none) <>2007-07-24 22:57:26 +0400
committerkostja@bodhi.(none) <>2007-07-24 22:57:26 +0400
commit4c208499a409d9e558ca019e9e101115d801bab7 (patch)
tree0c08dbb0f6adf471efce8ca848950431c0a9380c
parent9d247f296a8086f6379a32cece568ada279f9f8c (diff)
parent2ecd75ef24297389c2052bfedb7e25c83ff5760a (diff)
downloadmariadb-git-4c208499a409d9e558ca019e9e101115d801bab7.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.(none):/opt/local/work/mysql-5.0-runtime
-rw-r--r--mysql-test/r/create.result16
-rw-r--r--mysql-test/r/innodb.result2
-rw-r--r--mysql-test/r/sp-prelocking.result22
-rw-r--r--mysql-test/r/trigger.result28
-rw-r--r--mysql-test/t/create.test19
-rw-r--r--mysql-test/t/innodb.test2
-rw-r--r--mysql-test/t/sp-prelocking.test23
-rw-r--r--mysql-test/t/trigger.test23
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_insert.cc128
11 files changed, 211 insertions, 60 deletions
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index e692dbf3938..a1843573794 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1503,4 +1503,20 @@ t1 CREATE TABLE `t1` (
`c17` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+
+Bug #26104 Bug on foreign key class constructor
+
+Check that ref_columns is initalized correctly in the constructor
+and semantic checks in mysql_prepare_table work.
+
+We do not need a storage engine that supports foreign keys
+for this test, as the checks are purely syntax-based, and the
+syntax is supported for all engines.
+
+drop table if exists t1,t2;
+create table t1(a int not null, b int not null, primary key (a, b));
+create table t2(a int not null, b int not null, c int not null, primary key (a),
+foreign key fk_bug26104 (b,c) references t1(a));
+ERROR 42000: Incorrect foreign key definition for 'fk_bug26104': Key reference and table reference don't match
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 80b46e5098a..6082a30bce3 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1648,7 +1648,7 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2;
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
-ERROR HY000: Can't create table './test/t2' (errno: 150)
+ERROR 42000: Incorrect foreign key definition for 't1_id_fk': Key reference and table reference don't match
create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb;
show create table t2;
Table Create Table
diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result
index 5eac54803f0..c19bd1abd26 100644
--- a/mysql-test/r/sp-prelocking.result
+++ b/mysql-test/r/sp-prelocking.result
@@ -267,4 +267,26 @@ drop table bug_27907_logs;
insert into bug_27907_t1(a) values (1);
ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist
drop table bug_27907_t1;
+
+Bug#22427 create table if not exists + stored function results in
+inconsistent behavior
+
+Add a test case, the bug itself was fixed by the patch for
+Bug#20662
+
+drop table if exists t1;
+drop function if exists f_bug22427;
+create table t1 (i int);
+insert into t1 values (1);
+create function f_bug22427() returns int return (select max(i) from t1);
+select f_bug22427();
+f_bug22427()
+1
+create table if not exists t1 select f_bug22427() as i;
+Warnings:
+Note 1050 Table 't1' already exists
+create table t1 select f_bug22427() as i;
+ERROR 42S01: Table 't1' already exists
+drop table t1;
+drop function f_bug22427;
End of 5.0 tests
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 4b18e525e62..a07318435f6 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -1933,4 +1933,32 @@ Before UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi
After UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
drop view v1;
drop table t1, t2, t1_op_log;
+
+Bug#27248 Triggers: error if insert affects temporary table
+
+The bug was fixed by the fix for Bug#26141
+
+drop table if exists t1;
+drop temporary table if exists t2;
+create table t1 (s1 int);
+create temporary table t2 (s1 int);
+create trigger t1_bi before insert on t1 for each row insert into t2 values (0);
+create trigger t1_bd before delete on t1 for each row delete from t2;
+insert into t1 values (0);
+insert into t1 values (0);
+select * from t1;
+s1
+0
+0
+select * from t2;
+s1
+0
+0
+delete from t1;
+select * from t1;
+s1
+select * from t2;
+s1
+drop table t1;
+drop temporary table t2;
End of 5.0 tests
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 99f3fea416a..a6679cd674a 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1118,5 +1118,24 @@ show create table t1;
drop table t1;
+--echo
+--echo Bug #26104 Bug on foreign key class constructor
+--echo
+--echo Check that ref_columns is initalized correctly in the constructor
+--echo and semantic checks in mysql_prepare_table work.
+--echo
+--echo We do not need a storage engine that supports foreign keys
+--echo for this test, as the checks are purely syntax-based, and the
+--echo syntax is supported for all engines.
+--echo
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+create table t1(a int not null, b int not null, primary key (a, b));
+--error ER_WRONG_FK_DEF
+create table t2(a int not null, b int not null, c int not null, primary key (a),
+foreign key fk_bug26104 (b,c) references t1(a));
+drop table t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index a9679c01071..04dfa1d0836 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1180,7 +1180,7 @@ drop table t2;
# Clean up filename -- embedded server reports whole path without .frm,
# regular server reports relative path with .frm (argh!)
--replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t2.frm t2
---error 1005
+--error ER_WRONG_FK_DEF
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
# bug#3749
diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test
index ec5b7fbad7c..60e97260839 100644
--- a/mysql-test/t/sp-prelocking.test
+++ b/mysql-test/t/sp-prelocking.test
@@ -333,4 +333,27 @@ insert into bug_27907_t1(a) values (1);
drop table bug_27907_t1;
+--echo
+--echo Bug#22427 create table if not exists + stored function results in
+--echo inconsistent behavior
+--echo
+--echo Add a test case, the bug itself was fixed by the patch for
+--echo Bug#20662
+--echo
+--disable_warnings
+drop table if exists t1;
+drop function if exists f_bug22427;
+--enable_warnings
+create table t1 (i int);
+insert into t1 values (1);
+create function f_bug22427() returns int return (select max(i) from t1);
+select f_bug22427();
+# Until this bug was fixed, the following emitted error
+# ERROR 1213: Deadlock found when trying to get lock
+create table if not exists t1 select f_bug22427() as i;
+--error ER_TABLE_EXISTS_ERROR
+create table t1 select f_bug22427() as i;
+drop table t1;
+drop function f_bug22427;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index a6390036322..2f62ad38621 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2194,4 +2194,27 @@ drop table t1, t2, t1_op_log;
#
# TODO: test LOAD DATA INFILE
+#
+--echo
+--echo Bug#27248 Triggers: error if insert affects temporary table
+--echo
+--echo The bug was fixed by the fix for Bug#26141
+--echo
+--disable_warnings
+drop table if exists t1;
+drop temporary table if exists t2;
+--enable_warnings
+create table t1 (s1 int);
+create temporary table t2 (s1 int);
+create trigger t1_bi before insert on t1 for each row insert into t2 values (0);
+create trigger t1_bd before delete on t1 for each row delete from t2;
+insert into t1 values (0);
+insert into t1 values (0);
+select * from t1;
+select * from t2;
+delete from t1;
+select * from t1;
+select * from t2;
+drop table t1;
+drop temporary table t2;
--echo End of 5.0 tests
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index bf1c6d7cb0d..3860dfa1ded 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -62,11 +62,11 @@ Prelock_error_handler::handle_error(uint sql_errno,
if (sql_errno == ER_NO_SUCH_TABLE)
{
m_handled_errors++;
- return TRUE; // 'TRUE', as per coding style
+ return TRUE;
}
m_unhandled_errors++;
- return FALSE; // 'FALSE', as per coding style
+ return FALSE;
}
@@ -2674,7 +2674,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
*/
for (tables= *start; tables ;tables= tables->next_global)
{
- safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
+ safe_to_ignore_table= FALSE;
if (tables->lock_type == TL_WRITE_DEFAULT)
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 445a3ce437c..058f130d4e7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -450,7 +450,7 @@ public:
Table_ident *table, List<key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
:Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, 0, cols),
- ref_table(table), ref_columns(cols),
+ ref_table(table), ref_columns(ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg)
{}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 73f8c5e4418..19c9360b0ed 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1702,18 +1702,18 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
thd->proc_info="waiting for delay_list";
pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list
I_List_iterator<Delayed_insert> it(delayed_threads);
- Delayed_insert *tmp;
- while ((tmp=it++))
+ Delayed_insert *di;
+ while ((di= it++))
{
- if (!strcmp(tmp->thd.db,table_list->db) &&
- !strcmp(table_list->table_name,tmp->table->s->table_name))
+ if (!strcmp(table_list->db, di->table_list.db) &&
+ !strcmp(table_list->table_name, di->table_list.table_name))
{
- tmp->lock();
+ di->lock();
break;
}
}
pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list
- return tmp;
+ return di;
}
@@ -1739,21 +1739,41 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
Two latter cases indicate a request for lock upgrade.
XXX: why do we regard INSERT DELAYED into a view as an error and
- do not simply a lock upgrade?
+ do not simply perform a lock upgrade?
+
+ TODO: The approach with using two mutexes to work with the
+ delayed thread list -- LOCK_delayed_insert and
+ LOCK_delayed_create -- is redundant, and we only need one of
+ them to protect the list. The reason we have two locks is that
+ we do not want to block look-ups in the list while we're waiting
+ for the newly created thread to open the delayed table. However,
+ this wait itself is redundant -- we always call get_local_table
+ later on, and there wait again until the created thread acquires
+ a table lock.
+
+ As is redundant the concept of locks_in_memory, since we already
+ have another counter with similar semantics - tables_in_use,
+ both of them are devoted to counting the number of producers for
+ a given consumer (delayed insert thread), only at different
+ stages of producer-consumer relationship.
+
+ 'dead' and 'status' variables in Delayed_insert are redundant
+ too, since there is already 'di->thd.killed' and
+ di->stacked_inserts.
*/
static
bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
{
int error;
- Delayed_insert *tmp;
+ Delayed_insert *di;
DBUG_ENTER("delayed_get_table");
/* Must be set in the parser */
DBUG_ASSERT(table_list->db);
/* Find the thread which handles this table. */
- if (!(tmp=find_handler(thd,table_list)))
+ if (!(di= find_handler(thd, table_list)))
{
/*
No match. Create a new thread to handle the table, but
@@ -1767,9 +1787,9 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
The first search above was done without LOCK_delayed_create.
Another thread might have created the handler in between. Search again.
*/
- if (! (tmp= find_handler(thd, table_list)))
+ if (! (di= find_handler(thd, table_list)))
{
- if (!(tmp=new Delayed_insert()))
+ if (!(di= new Delayed_insert()))
{
my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert));
thd->fatal_error();
@@ -1778,28 +1798,30 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
pthread_mutex_unlock(&LOCK_thread_count);
- tmp->thd.set_db(table_list->db, strlen(table_list->db));
- tmp->thd.query= my_strdup(table_list->table_name,MYF(MY_WME));
- if (tmp->thd.db == NULL || tmp->thd.query == NULL)
+ di->thd.set_db(table_list->db, strlen(table_list->db));
+ di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME));
+ if (di->thd.db == NULL || di->thd.query == NULL)
{
/* The error is reported */
- delete tmp;
+ delete di;
thd->fatal_error();
goto end_create;
}
- tmp->table_list= *table_list; // Needed to open table
- tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
- tmp->lock();
- pthread_mutex_lock(&tmp->mutex);
- if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,
- handle_delayed_insert,(void*) tmp)))
+ di->table_list= *table_list; // Needed to open table
+ /* Replace volatile strings with local copies */
+ di->table_list.alias= di->table_list.table_name= di->thd.query;
+ di->table_list.db= di->thd.db;
+ di->lock();
+ pthread_mutex_lock(&di->mutex);
+ if ((error= pthread_create(&di->thd.real_id, &connection_attrib,
+ handle_delayed_insert, (void*) di)))
{
DBUG_PRINT("error",
("Can't create thread to handle delayed insert (error %d)",
error));
- pthread_mutex_unlock(&tmp->mutex);
- tmp->unlock();
- delete tmp;
+ pthread_mutex_unlock(&di->mutex);
+ di->unlock();
+ delete di;
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
thd->fatal_error();
goto end_create;
@@ -1807,15 +1829,15 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
/* Wait until table is open */
thd->proc_info="waiting for handler open";
- while (!tmp->thd.killed && !tmp->table && !thd->killed)
+ while (!di->thd.killed && !di->table && !thd->killed)
{
- pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
+ pthread_cond_wait(&di->cond_client, &di->mutex);
}
- pthread_mutex_unlock(&tmp->mutex);
+ pthread_mutex_unlock(&di->mutex);
thd->proc_info="got old table";
- if (tmp->thd.killed)
+ if (di->thd.killed)
{
- if (tmp->thd.net.report_error)
+ if (di->thd.net.report_error)
{
/*
Copy the error message. Note that we don't treat fatal
@@ -1823,31 +1845,34 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
main thread. Use of my_message will enable stored
procedures continue handlers.
*/
- my_message(tmp->thd.net.last_errno, tmp->thd.net.last_error,
+ my_message(di->thd.net.last_errno, di->thd.net.last_error,
MYF(0));
}
- tmp->unlock();
+ di->unlock();
goto end_create;
}
if (thd->killed)
{
- tmp->unlock();
+ di->unlock();
goto end_create;
}
+ pthread_mutex_lock(&LOCK_delayed_insert);
+ delayed_threads.append(di);
+ pthread_mutex_unlock(&LOCK_delayed_insert);
}
pthread_mutex_unlock(&LOCK_delayed_create);
}
- pthread_mutex_lock(&tmp->mutex);
- table_list->table= tmp->get_local_table(thd);
- pthread_mutex_unlock(&tmp->mutex);
+ pthread_mutex_lock(&di->mutex);
+ table_list->table= di->get_local_table(thd);
+ pthread_mutex_unlock(&di->mutex);
if (table_list->table)
{
DBUG_ASSERT(thd->net.report_error == 0);
- thd->di=tmp;
+ thd->di= di;
}
/* Unlock the delayed insert object after its last access. */
- tmp->unlock();
+ di->unlock();
DBUG_RETURN(table_list->table == NULL);
end_create:
@@ -2077,26 +2102,26 @@ void kill_delayed_threads(void)
VOID(pthread_mutex_lock(&LOCK_delayed_insert)); // For unlink from list
I_List_iterator<Delayed_insert> it(delayed_threads);
- Delayed_insert *tmp;
- while ((tmp=it++))
+ Delayed_insert *di;
+ while ((di= it++))
{
- tmp->thd.killed= THD::KILL_CONNECTION;
- if (tmp->thd.mysys_var)
+ di->thd.killed= THD::KILL_CONNECTION;
+ if (di->thd.mysys_var)
{
- pthread_mutex_lock(&tmp->thd.mysys_var->mutex);
- if (tmp->thd.mysys_var->current_cond)
+ pthread_mutex_lock(&di->thd.mysys_var->mutex);
+ if (di->thd.mysys_var->current_cond)
{
/*
We need the following test because the main mutex may be locked
in handle_delayed_insert()
*/
- if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
- pthread_mutex_lock(tmp->thd.mysys_var->current_mutex);
- pthread_cond_broadcast(tmp->thd.mysys_var->current_cond);
- if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
- pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex);
+ if (&di->mutex != di->thd.mysys_var->current_mutex)
+ pthread_mutex_lock(di->thd.mysys_var->current_mutex);
+ pthread_cond_broadcast(di->thd.mysys_var->current_cond);
+ if (&di->mutex != di->thd.mysys_var->current_mutex)
+ pthread_mutex_unlock(di->thd.mysys_var->current_mutex);
}
- pthread_mutex_unlock(&tmp->thd.mysys_var->mutex);
+ pthread_mutex_unlock(&di->thd.mysys_var->mutex);
}
}
VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list
@@ -2176,11 +2201,6 @@ pthread_handler_t handle_delayed_insert(void *arg)
}
di->table->copy_blobs=1;
- /* One can now use this */
- pthread_mutex_lock(&LOCK_delayed_insert);
- delayed_threads.append(di);
- pthread_mutex_unlock(&LOCK_delayed_insert);
-
/* Tell client that the thread is initialized */
pthread_cond_signal(&di->cond_client);