mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/dlenev/src/mysql-5.0-bg9486 sql/sp_head.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
commit
279880c2e7
7 changed files with 73 additions and 25 deletions
|
@ -23,3 +23,20 @@ select * from t1;
|
|||
s1 s2 s3
|
||||
drop table t1;
|
||||
drop procedure bug4934;
|
||||
drop procedure if exists bug9486;
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (id1 int, val int);
|
||||
create table t2 (id2 int);
|
||||
create procedure bug9486()
|
||||
update t1, t2 set val= 1 where id1=id2;
|
||||
call bug9486();
|
||||
lock tables t2 write;
|
||||
call bug9486();
|
||||
show processlist;
|
||||
Id User Host db Command Time State Info
|
||||
# root localhost test Sleep # NULL
|
||||
# root localhost test Query # Locked call bug9486()
|
||||
# root localhost test Query # NULL show processlist
|
||||
unlock tables;
|
||||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -54,6 +54,37 @@ drop table t1;
|
|||
drop procedure bug4934;
|
||||
|
||||
|
||||
#
|
||||
# BUG #9486 "Can't perform multi-update in stored procedure"
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug9486;
|
||||
drop table if exists t1, t2;
|
||||
--enable_warnings
|
||||
create table t1 (id1 int, val int);
|
||||
create table t2 (id2 int);
|
||||
|
||||
create procedure bug9486()
|
||||
update t1, t2 set val= 1 where id1=id2;
|
||||
call bug9486();
|
||||
# Let us check that SP invocation requires write lock for t2.
|
||||
connection con2root;
|
||||
lock tables t2 write;
|
||||
connection con1root;
|
||||
send call bug9486();
|
||||
connection con2root;
|
||||
--sleep 2
|
||||
# There should be call statement in locked state.
|
||||
--replace_column 1 # 6 #
|
||||
show processlist;
|
||||
unlock tables;
|
||||
connection con1root;
|
||||
reap;
|
||||
|
||||
drop procedure bug9486;
|
||||
drop table t1, t2;
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -2060,6 +2060,12 @@ typedef struct st_sp_table
|
|||
LEX_STRING qname;
|
||||
bool temp;
|
||||
TABLE_LIST *table;
|
||||
/*
|
||||
We can't use table->lock_type as lock type for table
|
||||
in multi-set since it can be changed by statement during
|
||||
its execution (e.g. as this happens for multi-update).
|
||||
*/
|
||||
thr_lock_type lock_type;
|
||||
uint lock_count;
|
||||
uint query_lock_count;
|
||||
} SP_TABLE;
|
||||
|
@ -2131,8 +2137,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
|
|||
*/
|
||||
if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)))
|
||||
{
|
||||
if (tab->table->lock_type < table->lock_type)
|
||||
tab->table= table; // Use the table with the highest lock type
|
||||
if (tab->lock_type < table->lock_type)
|
||||
tab->lock_type= table->lock_type; // Use the table with the highest lock type
|
||||
tab->query_lock_count++;
|
||||
if (tab->query_lock_count > tab->lock_count)
|
||||
tab->lock_count++;
|
||||
|
@ -2150,6 +2156,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
|
|||
lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||
tab->temp= TRUE;
|
||||
tab->table= table;
|
||||
tab->lock_type= table->lock_type;
|
||||
tab->lock_count= tab->query_lock_count= 1;
|
||||
my_hash_insert(&m_sptabs, (byte *)tab);
|
||||
}
|
||||
|
@ -2222,7 +2229,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
|
|||
table->alias= otable->alias;
|
||||
table->table_name= otable->table_name;
|
||||
table->table_name_length= otable->table_name_length;
|
||||
table->lock_type= otable->lock_type;
|
||||
table->lock_type= stab->lock_type;
|
||||
table->cacheable_table= 1;
|
||||
table->prelocking_placeholder= 1;
|
||||
|
||||
|
|
|
@ -732,7 +732,7 @@ typedef struct st_lex
|
|||
USER_RESOURCES mqh;
|
||||
ulong type;
|
||||
enum_sql_command sql_command, orig_sql_command;
|
||||
thr_lock_type lock_option, multi_lock_option;
|
||||
thr_lock_type lock_option;
|
||||
enum SSL_type ssl_type; /* defined in violite.h */
|
||||
enum my_lex_states next_state;
|
||||
enum enum_duplicates duplicates;
|
||||
|
|
|
@ -1012,11 +1012,6 @@ static int mysql_test_update(Prepared_statement *stmt,
|
|||
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||
/* pass counter value */
|
||||
thd->lex->table_count= table_count;
|
||||
/*
|
||||
give correct value to multi_lock_option, because it will be used
|
||||
in multiupdate
|
||||
*/
|
||||
thd->lex->multi_lock_option= table_list->lock_type;
|
||||
/* convert to multiupdate */
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -145,11 +145,6 @@ int mysql_update(THD *thd,
|
|||
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||
/* pass counter value */
|
||||
thd->lex->table_count= table_count;
|
||||
/*
|
||||
give correct value to multi_lock_option, because it will be used
|
||||
in multiupdate
|
||||
*/
|
||||
thd->lex->multi_lock_option= table_list->lock_type;
|
||||
/* convert to multiupdate */
|
||||
return 2;
|
||||
}
|
||||
|
@ -692,8 +687,10 @@ bool mysql_multi_update_prepare(THD *thd)
|
|||
}
|
||||
|
||||
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
|
||||
tl->lock_type= lex->multi_lock_option;
|
||||
tl->updating= 1;
|
||||
/*
|
||||
If table will be updated we should not downgrade lock for it and
|
||||
leave it as is.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -705,15 +702,15 @@ bool mysql_multi_update_prepare(THD *thd)
|
|||
*/
|
||||
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
||||
tl->updating= 0;
|
||||
/* Update TABLE::lock_type accordingly. */
|
||||
if (!tl->placeholder() && !tl->schema_table && !using_lock_tables)
|
||||
tl->table->reginfo.lock_type= tl->lock_type;
|
||||
}
|
||||
|
||||
/* Check access privileges for table */
|
||||
if (!tl->derived && !tl->belong_to_view)
|
||||
{
|
||||
uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
|
||||
if (!using_lock_tables)
|
||||
tl->table->reginfo.lock_type= tl->lock_type;
|
||||
|
||||
if (check_access(thd, want_privilege,
|
||||
tl->db, &tl->grant.privilege, 0, 0) ||
|
||||
(grant_option && check_grant(thd, want_privilege, tl, 0, 1, 0)))
|
||||
|
@ -847,7 +844,7 @@ bool mysql_multi_update(THD *thd,
|
|||
result, unit, select_lex);
|
||||
delete result;
|
||||
thd->abort_on_warning= 0;
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5992,10 +5992,7 @@ update:
|
|||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->select_lex.table_list.elements > 1)
|
||||
{
|
||||
lex->sql_command= SQLCOM_UPDATE_MULTI;
|
||||
lex->multi_lock_option= $3;
|
||||
}
|
||||
else if (lex->select_lex.get_table_list()->derived)
|
||||
{
|
||||
/* it is single table update and it is update of derived table */
|
||||
|
@ -6003,8 +6000,12 @@ update:
|
|||
lex->select_lex.get_table_list()->alias, "UPDATE");
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
Select->set_lock_for_tables($3);
|
||||
/*
|
||||
In case of multi-update setting write lock for all tables may
|
||||
be too pessimistic. We will decrease lock level if possible in
|
||||
mysql_multi_update().
|
||||
*/
|
||||
Select->set_lock_for_tables($3);
|
||||
}
|
||||
where_clause opt_order_clause delete_limit_clause {}
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue