mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into bodhi.(none):/opt/local/work/mysql-5.1-runtime
This commit is contained in:
@ -1516,6 +1516,22 @@ t1 CREATE TABLE `t1` (
|
|||||||
`c17` int(11) DEFAULT NULL
|
`c17` int(11) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
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
|
End of 5.0 tests
|
||||||
CREATE TABLE t1 (a int, b int);
|
CREATE TABLE t1 (a int, b int);
|
||||||
insert into t1 values (1,1),(1,2);
|
insert into t1 values (1,1),(1,2);
|
||||||
|
@ -1640,7 +1640,7 @@ t2 CREATE TABLE `t2` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
drop table t2;
|
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;
|
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;
|
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;
|
show create table t2;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
|
@ -267,4 +267,26 @@ drop table bug_27907_logs;
|
|||||||
insert into bug_27907_t1(a) values (1);
|
insert into bug_27907_t1(a) values (1);
|
||||||
ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist
|
ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist
|
||||||
drop table bug_27907_t1;
|
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
|
End of 5.0 tests
|
||||||
|
@ -1933,6 +1933,34 @@ 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
|
After UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1, t2, t1_op_log;
|
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
|
End of 5.0 tests
|
||||||
drop table if exists table_25411_a;
|
drop table if exists table_25411_a;
|
||||||
drop table if exists table_25411_b;
|
drop table if exists table_25411_b;
|
||||||
|
@ -1122,6 +1122,25 @@ show create table t1;
|
|||||||
|
|
||||||
drop 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
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
@ -1178,7 +1178,7 @@ drop table t2;
|
|||||||
# Clean up filename -- embedded server reports whole path without .frm,
|
# Clean up filename -- embedded server reports whole path without .frm,
|
||||||
# regular server reports relative path with .frm (argh!)
|
# regular server reports relative path with .frm (argh!)
|
||||||
--replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t2.frm t2
|
--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;
|
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
|
# bug#3749
|
||||||
|
@ -333,4 +333,27 @@ insert into bug_27907_t1(a) values (1);
|
|||||||
|
|
||||||
drop table bug_27907_t1;
|
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
|
--echo End of 5.0 tests
|
||||||
|
@ -2194,6 +2194,29 @@ drop table t1, t2, t1_op_log;
|
|||||||
|
|
||||||
#
|
#
|
||||||
# TODO: test LOAD DATA INFILE
|
# 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
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -64,11 +64,11 @@ Prelock_error_handler::handle_error(uint sql_errno,
|
|||||||
if (sql_errno == ER_NO_SUCH_TABLE)
|
if (sql_errno == ER_NO_SUCH_TABLE)
|
||||||
{
|
{
|
||||||
m_handled_errors++;
|
m_handled_errors++;
|
||||||
return TRUE; // 'TRUE', as per coding style
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_unhandled_errors++;
|
m_unhandled_errors++;
|
||||||
return FALSE; // 'FALSE', as per coding style
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3533,7 +3533,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
*/
|
*/
|
||||||
for (tables= *start; tables ;tables= tables->next_global)
|
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)
|
if (tables->lock_type == TL_WRITE_DEFAULT)
|
||||||
{
|
{
|
||||||
|
@ -189,7 +189,7 @@ public:
|
|||||||
Table_ident *table, List<Key_part_spec> &ref_cols,
|
Table_ident *table, List<Key_part_spec> &ref_cols,
|
||||||
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
||||||
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
|
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 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),
|
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
|
||||||
match_opt(match_opt_arg)
|
match_opt(match_opt_arg)
|
||||||
{}
|
{}
|
||||||
|
@ -1763,18 +1763,18 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
|
|||||||
thd->proc_info="waiting for delay_list";
|
thd->proc_info="waiting for delay_list";
|
||||||
pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list
|
pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list
|
||||||
I_List_iterator<Delayed_insert> it(delayed_threads);
|
I_List_iterator<Delayed_insert> it(delayed_threads);
|
||||||
Delayed_insert *tmp;
|
Delayed_insert *di;
|
||||||
while ((tmp=it++))
|
while ((di= it++))
|
||||||
{
|
{
|
||||||
if (!strcmp(tmp->thd.db, table_list->db) &&
|
if (!strcmp(table_list->db, di->table_list.db) &&
|
||||||
!strcmp(table_list->table_name, tmp->table->s->table_name.str))
|
!strcmp(table_list->table_name, di->table_list.table_name))
|
||||||
{
|
{
|
||||||
tmp->lock();
|
di->lock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list
|
pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list
|
||||||
return tmp;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1800,21 +1800,41 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
|
|||||||
Two latter cases indicate a request for lock upgrade.
|
Two latter cases indicate a request for lock upgrade.
|
||||||
|
|
||||||
XXX: why do we regard INSERT DELAYED into a view as an error and
|
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
|
static
|
||||||
bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
Delayed_insert *tmp;
|
Delayed_insert *di;
|
||||||
DBUG_ENTER("delayed_get_table");
|
DBUG_ENTER("delayed_get_table");
|
||||||
|
|
||||||
/* Must be set in the parser */
|
/* Must be set in the parser */
|
||||||
DBUG_ASSERT(table_list->db);
|
DBUG_ASSERT(table_list->db);
|
||||||
|
|
||||||
/* Find the thread which handles this table. */
|
/* 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
|
No match. Create a new thread to handle the table, but
|
||||||
@ -1828,9 +1848,9 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
The first search above was done without LOCK_delayed_create.
|
The first search above was done without LOCK_delayed_create.
|
||||||
Another thread might have created the handler in between. Search again.
|
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));
|
my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert));
|
||||||
thd->fatal_error();
|
thd->fatal_error();
|
||||||
@ -1839,28 +1859,30 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
pthread_mutex_lock(&LOCK_thread_count);
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
thread_count++;
|
thread_count++;
|
||||||
pthread_mutex_unlock(&LOCK_thread_count);
|
pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
tmp->thd.set_db(table_list->db, strlen(table_list->db));
|
di->thd.set_db(table_list->db, strlen(table_list->db));
|
||||||
tmp->thd.query= my_strdup(table_list->table_name,MYF(MY_WME));
|
di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME));
|
||||||
if (tmp->thd.db == NULL || tmp->thd.query == NULL)
|
if (di->thd.db == NULL || di->thd.query == NULL)
|
||||||
{
|
{
|
||||||
/* The error is reported */
|
/* The error is reported */
|
||||||
delete tmp;
|
delete di;
|
||||||
thd->fatal_error();
|
thd->fatal_error();
|
||||||
goto end_create;
|
goto end_create;
|
||||||
}
|
}
|
||||||
tmp->table_list= *table_list; // Needed to open table
|
di->table_list= *table_list; // Needed to open table
|
||||||
tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
|
/* Replace volatile strings with local copies */
|
||||||
tmp->lock();
|
di->table_list.alias= di->table_list.table_name= di->thd.query;
|
||||||
pthread_mutex_lock(&tmp->mutex);
|
di->table_list.db= di->thd.db;
|
||||||
if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,
|
di->lock();
|
||||||
handle_delayed_insert,(void*) tmp)))
|
pthread_mutex_lock(&di->mutex);
|
||||||
|
if ((error= pthread_create(&di->thd.real_id, &connection_attrib,
|
||||||
|
handle_delayed_insert, (void*) di)))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",
|
DBUG_PRINT("error",
|
||||||
("Can't create thread to handle delayed insert (error %d)",
|
("Can't create thread to handle delayed insert (error %d)",
|
||||||
error));
|
error));
|
||||||
pthread_mutex_unlock(&tmp->mutex);
|
pthread_mutex_unlock(&di->mutex);
|
||||||
tmp->unlock();
|
di->unlock();
|
||||||
delete tmp;
|
delete di;
|
||||||
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
|
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
|
||||||
thd->fatal_error();
|
thd->fatal_error();
|
||||||
goto end_create;
|
goto end_create;
|
||||||
@ -1868,15 +1890,15 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
|
|
||||||
/* Wait until table is open */
|
/* Wait until table is open */
|
||||||
thd->proc_info="waiting for handler 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";
|
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
|
Copy the error message. Note that we don't treat fatal
|
||||||
@ -1884,31 +1906,34 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||||||
main thread. Use of my_message will enable stored
|
main thread. Use of my_message will enable stored
|
||||||
procedures continue handlers.
|
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));
|
MYF(0));
|
||||||
}
|
}
|
||||||
tmp->unlock();
|
di->unlock();
|
||||||
goto end_create;
|
goto end_create;
|
||||||
}
|
}
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
{
|
{
|
||||||
tmp->unlock();
|
di->unlock();
|
||||||
goto end_create;
|
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_unlock(&LOCK_delayed_create);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&tmp->mutex);
|
pthread_mutex_lock(&di->mutex);
|
||||||
table_list->table= tmp->get_local_table(thd);
|
table_list->table= di->get_local_table(thd);
|
||||||
pthread_mutex_unlock(&tmp->mutex);
|
pthread_mutex_unlock(&di->mutex);
|
||||||
if (table_list->table)
|
if (table_list->table)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(thd->net.report_error == 0);
|
DBUG_ASSERT(thd->net.report_error == 0);
|
||||||
thd->di=tmp;
|
thd->di= di;
|
||||||
}
|
}
|
||||||
/* Unlock the delayed insert object after its last access. */
|
/* Unlock the delayed insert object after its last access. */
|
||||||
tmp->unlock();
|
di->unlock();
|
||||||
DBUG_RETURN((table_list->table == NULL));
|
DBUG_RETURN((table_list->table == NULL));
|
||||||
|
|
||||||
end_create:
|
end_create:
|
||||||
@ -1938,7 +1963,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||||||
my_ptrdiff_t adjust_ptrs;
|
my_ptrdiff_t adjust_ptrs;
|
||||||
Field **field,**org_field, *found_next_number_field;
|
Field **field,**org_field, *found_next_number_field;
|
||||||
TABLE *copy;
|
TABLE *copy;
|
||||||
TABLE_SHARE *share= table->s;
|
TABLE_SHARE *share;
|
||||||
uchar *bitmap;
|
uchar *bitmap;
|
||||||
DBUG_ENTER("Delayed_insert::get_local_table");
|
DBUG_ENTER("Delayed_insert::get_local_table");
|
||||||
|
|
||||||
@ -1962,6 +1987,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
share= table->s;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Allocate memory for the TABLE object, the field pointers array, and
|
Allocate memory for the TABLE object, the field pointers array, and
|
||||||
@ -2157,26 +2183,26 @@ void kill_delayed_threads(void)
|
|||||||
VOID(pthread_mutex_lock(&LOCK_delayed_insert)); // For unlink from list
|
VOID(pthread_mutex_lock(&LOCK_delayed_insert)); // For unlink from list
|
||||||
|
|
||||||
I_List_iterator<Delayed_insert> it(delayed_threads);
|
I_List_iterator<Delayed_insert> it(delayed_threads);
|
||||||
Delayed_insert *tmp;
|
Delayed_insert *di;
|
||||||
while ((tmp=it++))
|
while ((di= it++))
|
||||||
{
|
{
|
||||||
tmp->thd.killed= THD::KILL_CONNECTION;
|
di->thd.killed= THD::KILL_CONNECTION;
|
||||||
if (tmp->thd.mysys_var)
|
if (di->thd.mysys_var)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&tmp->thd.mysys_var->mutex);
|
pthread_mutex_lock(&di->thd.mysys_var->mutex);
|
||||||
if (tmp->thd.mysys_var->current_cond)
|
if (di->thd.mysys_var->current_cond)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We need the following test because the main mutex may be locked
|
We need the following test because the main mutex may be locked
|
||||||
in handle_delayed_insert()
|
in handle_delayed_insert()
|
||||||
*/
|
*/
|
||||||
if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
|
if (&di->mutex != di->thd.mysys_var->current_mutex)
|
||||||
pthread_mutex_lock(tmp->thd.mysys_var->current_mutex);
|
pthread_mutex_lock(di->thd.mysys_var->current_mutex);
|
||||||
pthread_cond_broadcast(tmp->thd.mysys_var->current_cond);
|
pthread_cond_broadcast(di->thd.mysys_var->current_cond);
|
||||||
if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
|
if (&di->mutex != di->thd.mysys_var->current_mutex)
|
||||||
pthread_mutex_unlock(tmp->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
|
VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list
|
||||||
@ -2250,11 +2276,6 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||||||
}
|
}
|
||||||
di->table->copy_blobs=1;
|
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 */
|
/* Tell client that the thread is initialized */
|
||||||
pthread_cond_signal(&di->cond_client);
|
pthread_cond_signal(&di->cond_client);
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ Lex_input_stream::Lex_input_stream(THD *thd,
|
|||||||
m_tok_start_prev(NULL),
|
m_tok_start_prev(NULL),
|
||||||
m_buf(buffer),
|
m_buf(buffer),
|
||||||
m_buf_length(length),
|
m_buf_length(length),
|
||||||
m_echo(true),
|
m_echo(TRUE),
|
||||||
m_cpp_tok_start(NULL),
|
m_cpp_tok_start(NULL),
|
||||||
m_cpp_tok_start_prev(NULL),
|
m_cpp_tok_start_prev(NULL),
|
||||||
m_cpp_tok_end(NULL),
|
m_cpp_tok_end(NULL),
|
||||||
@ -1200,7 +1200,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
{
|
{
|
||||||
lip->in_comment= DISCARD_COMMENT;
|
lip->in_comment= DISCARD_COMMENT;
|
||||||
/* Accept '/' '*' '!', but do not keep this marker. */
|
/* Accept '/' '*' '!', but do not keep this marker. */
|
||||||
lip->set_echo(false);
|
lip->set_echo(FALSE);
|
||||||
lip->yySkip();
|
lip->yySkip();
|
||||||
lip->yySkip();
|
lip->yySkip();
|
||||||
lip->yySkip();
|
lip->yySkip();
|
||||||
@ -1233,7 +1233,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
if (version <= MYSQL_VERSION_ID)
|
if (version <= MYSQL_VERSION_ID)
|
||||||
{
|
{
|
||||||
/* Expand the content of the special comment as real code */
|
/* Expand the content of the special comment as real code */
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
state=MY_LEX_START;
|
state=MY_LEX_START;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1241,7 +1241,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
state=MY_LEX_START;
|
state=MY_LEX_START;
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1261,7 +1261,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
if (! lip->eof())
|
if (! lip->eof())
|
||||||
lip->yySkip(); // remove last '/'
|
lip->yySkip(); // remove last '/'
|
||||||
state = MY_LEX_START; // Try again
|
state = MY_LEX_START; // Try again
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
break;
|
break;
|
||||||
case MY_LEX_END_LONG_COMMENT:
|
case MY_LEX_END_LONG_COMMENT:
|
||||||
if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
|
if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
|
||||||
@ -1272,7 +1272,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
|
lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
|
||||||
lip->yySkipn(2);
|
lip->yySkipn(2);
|
||||||
/* And start recording the tokens again */
|
/* And start recording the tokens again */
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
lip->in_comment=NO_COMMENT;
|
lip->in_comment=NO_COMMENT;
|
||||||
state=MY_LEX_START;
|
state=MY_LEX_START;
|
||||||
}
|
}
|
||||||
@ -1297,7 +1297,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
lip->found_semicolon= lip->get_ptr();
|
lip->found_semicolon= lip->get_ptr();
|
||||||
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
|
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
|
||||||
lip->next_state= MY_LEX_END;
|
lip->next_state= MY_LEX_END;
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
return (END_OF_INPUT);
|
return (END_OF_INPUT);
|
||||||
}
|
}
|
||||||
state= MY_LEX_CHAR; // Return ';'
|
state= MY_LEX_CHAR; // Return ';'
|
||||||
@ -1309,9 +1309,9 @@ int MYSQLlex(void *arg, void *yythd)
|
|||||||
if (lip->eof())
|
if (lip->eof())
|
||||||
{
|
{
|
||||||
lip->yyUnget(); // Reject the last '\0'
|
lip->yyUnget(); // Reject the last '\0'
|
||||||
lip->set_echo(false);
|
lip->set_echo(FALSE);
|
||||||
lip->yySkip();
|
lip->yySkip();
|
||||||
lip->set_echo(true);
|
lip->set_echo(TRUE);
|
||||||
lip->next_state=MY_LEX_END; // Mark for next loop
|
lip->next_state=MY_LEX_END; // Mark for next loop
|
||||||
return(END_OF_INPUT);
|
return(END_OF_INPUT);
|
||||||
}
|
}
|
||||||
|
@ -1239,19 +1239,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Get the raw query buffer. */
|
/** Get the raw query buffer. */
|
||||||
const char* get_buf()
|
const char *get_buf()
|
||||||
{
|
{
|
||||||
return m_buf;
|
return m_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the pre-processed query buffer. */
|
/** Get the pre-processed query buffer. */
|
||||||
const char* get_cpp_buf()
|
const char *get_cpp_buf()
|
||||||
{
|
{
|
||||||
return m_cpp_buf;
|
return m_cpp_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the end of the raw query buffer. */
|
/** Get the end of the raw query buffer. */
|
||||||
const char* get_end_of_query()
|
const char *get_end_of_query()
|
||||||
{
|
{
|
||||||
return m_end_of_query;
|
return m_end_of_query;
|
||||||
}
|
}
|
||||||
@ -1279,43 +1279,43 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Get the token start position, in the raw buffer. */
|
/** Get the token start position, in the raw buffer. */
|
||||||
const char* get_tok_start()
|
const char *get_tok_start()
|
||||||
{
|
{
|
||||||
return m_tok_start;
|
return m_tok_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the token start position, in the pre-processed buffer. */
|
/** Get the token start position, in the pre-processed buffer. */
|
||||||
const char* get_cpp_tok_start()
|
const char *get_cpp_tok_start()
|
||||||
{
|
{
|
||||||
return m_cpp_tok_start;
|
return m_cpp_tok_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the token end position, in the raw buffer. */
|
/** Get the token end position, in the raw buffer. */
|
||||||
const char* get_tok_end()
|
const char *get_tok_end()
|
||||||
{
|
{
|
||||||
return m_tok_end;
|
return m_tok_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the token end position, in the pre-processed buffer. */
|
/** Get the token end position, in the pre-processed buffer. */
|
||||||
const char* get_cpp_tok_end()
|
const char *get_cpp_tok_end()
|
||||||
{
|
{
|
||||||
return m_cpp_tok_end;
|
return m_cpp_tok_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the previous token start position, in the raw buffer. */
|
/** Get the previous token start position, in the raw buffer. */
|
||||||
const char* get_tok_start_prev()
|
const char *get_tok_start_prev()
|
||||||
{
|
{
|
||||||
return m_tok_start_prev;
|
return m_tok_start_prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the current stream pointer, in the raw buffer. */
|
/** Get the current stream pointer, in the raw buffer. */
|
||||||
const char* get_ptr()
|
const char *get_ptr()
|
||||||
{
|
{
|
||||||
return m_ptr;
|
return m_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the current stream pointer, in the pre-processed buffer. */
|
/** Get the current stream pointer, in the pre-processed buffer. */
|
||||||
const char* get_cpp_ptr()
|
const char *get_cpp_ptr()
|
||||||
{
|
{
|
||||||
return m_cpp_ptr;
|
return m_cpp_ptr;
|
||||||
}
|
}
|
||||||
@ -1365,22 +1365,22 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/** Pointer to the current position in the raw input stream. */
|
/** Pointer to the current position in the raw input stream. */
|
||||||
const char* m_ptr;
|
const char *m_ptr;
|
||||||
|
|
||||||
/** Starting position of the last token parsed, in the raw buffer. */
|
/** Starting position of the last token parsed, in the raw buffer. */
|
||||||
const char* m_tok_start;
|
const char *m_tok_start;
|
||||||
|
|
||||||
/** Ending position of the previous token parsed, in the raw buffer. */
|
/** Ending position of the previous token parsed, in the raw buffer. */
|
||||||
const char* m_tok_end;
|
const char *m_tok_end;
|
||||||
|
|
||||||
/** End of the query text in the input stream, in the raw buffer. */
|
/** End of the query text in the input stream, in the raw buffer. */
|
||||||
const char* m_end_of_query;
|
const char *m_end_of_query;
|
||||||
|
|
||||||
/** Starting position of the previous token parsed, in the raw buffer. */
|
/** Starting position of the previous token parsed, in the raw buffer. */
|
||||||
const char* m_tok_start_prev;
|
const char *m_tok_start_prev;
|
||||||
|
|
||||||
/** Begining of the query text in the input stream, in the raw buffer. */
|
/** Begining of the query text in the input stream, in the raw buffer. */
|
||||||
const char* m_buf;
|
const char *m_buf;
|
||||||
|
|
||||||
/** Length of the raw buffer. */
|
/** Length of the raw buffer. */
|
||||||
uint m_buf_length;
|
uint m_buf_length;
|
||||||
@ -1389,28 +1389,28 @@ private:
|
|||||||
bool m_echo;
|
bool m_echo;
|
||||||
|
|
||||||
/** Pre-processed buffer. */
|
/** Pre-processed buffer. */
|
||||||
char* m_cpp_buf;
|
char *m_cpp_buf;
|
||||||
|
|
||||||
/** Pointer to the current position in the pre-processed input stream. */
|
/** Pointer to the current position in the pre-processed input stream. */
|
||||||
char* m_cpp_ptr;
|
char *m_cpp_ptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Starting position of the last token parsed,
|
Starting position of the last token parsed,
|
||||||
in the pre-processed buffer.
|
in the pre-processed buffer.
|
||||||
*/
|
*/
|
||||||
const char* m_cpp_tok_start;
|
const char *m_cpp_tok_start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Starting position of the previous token parsed,
|
Starting position of the previous token parsed,
|
||||||
in the pre-procedded buffer.
|
in the pre-procedded buffer.
|
||||||
*/
|
*/
|
||||||
const char* m_cpp_tok_start_prev;
|
const char *m_cpp_tok_start_prev;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Ending position of the previous token parsed,
|
Ending position of the previous token parsed,
|
||||||
in the pre-processed buffer.
|
in the pre-processed buffer.
|
||||||
*/
|
*/
|
||||||
const char* m_cpp_tok_end;
|
const char *m_cpp_tok_end;
|
||||||
|
|
||||||
/** UTF8-body buffer created during parsing. */
|
/** UTF8-body buffer created during parsing. */
|
||||||
char *m_body_utf8;
|
char *m_body_utf8;
|
||||||
@ -1433,7 +1433,7 @@ public:
|
|||||||
Position of ';' in the stream, to delimit multiple queries.
|
Position of ';' in the stream, to delimit multiple queries.
|
||||||
This delimiter is in the raw buffer.
|
This delimiter is in the raw buffer.
|
||||||
*/
|
*/
|
||||||
const char* found_semicolon;
|
const char *found_semicolon;
|
||||||
|
|
||||||
/** SQL_MODE = IGNORE_SPACE. */
|
/** SQL_MODE = IGNORE_SPACE. */
|
||||||
bool ignore_space;
|
bool ignore_space;
|
||||||
|
Reference in New Issue
Block a user