mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +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
|
s1 s2 s3
|
||||||
drop table t1;
|
drop table t1;
|
||||||
drop procedure bug4934;
|
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;
|
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
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
|
|
@ -2060,6 +2060,12 @@ typedef struct st_sp_table
|
||||||
LEX_STRING qname;
|
LEX_STRING qname;
|
||||||
bool temp;
|
bool temp;
|
||||||
TABLE_LIST *table;
|
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 lock_count;
|
||||||
uint query_lock_count;
|
uint query_lock_count;
|
||||||
} SP_TABLE;
|
} 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= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)))
|
||||||
{
|
{
|
||||||
if (tab->table->lock_type < table->lock_type)
|
if (tab->lock_type < table->lock_type)
|
||||||
tab->table= table; // Use the table with the highest lock type
|
tab->lock_type= table->lock_type; // Use the table with the highest lock type
|
||||||
tab->query_lock_count++;
|
tab->query_lock_count++;
|
||||||
if (tab->query_lock_count > tab->lock_count)
|
if (tab->query_lock_count > tab->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)
|
lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||||
tab->temp= TRUE;
|
tab->temp= TRUE;
|
||||||
tab->table= table;
|
tab->table= table;
|
||||||
|
tab->lock_type= table->lock_type;
|
||||||
tab->lock_count= tab->query_lock_count= 1;
|
tab->lock_count= tab->query_lock_count= 1;
|
||||||
my_hash_insert(&m_sptabs, (byte *)tab);
|
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->alias= otable->alias;
|
||||||
table->table_name= otable->table_name;
|
table->table_name= otable->table_name;
|
||||||
table->table_name_length= otable->table_name_length;
|
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->cacheable_table= 1;
|
||||||
table->prelocking_placeholder= 1;
|
table->prelocking_placeholder= 1;
|
||||||
|
|
||||||
|
|
|
@ -732,7 +732,7 @@ typedef struct st_lex
|
||||||
USER_RESOURCES mqh;
|
USER_RESOURCES mqh;
|
||||||
ulong type;
|
ulong type;
|
||||||
enum_sql_command sql_command, orig_sql_command;
|
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 SSL_type ssl_type; /* defined in violite.h */
|
||||||
enum my_lex_states next_state;
|
enum my_lex_states next_state;
|
||||||
enum enum_duplicates duplicates;
|
enum enum_duplicates duplicates;
|
||||||
|
|
|
@ -1012,11 +1012,6 @@ static int mysql_test_update(Prepared_statement *stmt,
|
||||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
/* pass counter value */
|
/* pass counter value */
|
||||||
thd->lex->table_count= table_count;
|
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 */
|
/* convert to multiupdate */
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,11 +145,6 @@ int mysql_update(THD *thd,
|
||||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
/* pass counter value */
|
/* pass counter value */
|
||||||
thd->lex->table_count= table_count;
|
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 */
|
/* convert to multiupdate */
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -692,8 +687,10 @@ bool mysql_multi_update_prepare(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
|
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
|
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->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
||||||
tl->updating= 0;
|
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 */
|
/* Check access privileges for table */
|
||||||
if (!tl->derived && !tl->belong_to_view)
|
if (!tl->derived && !tl->belong_to_view)
|
||||||
{
|
{
|
||||||
uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
|
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,
|
if (check_access(thd, want_privilege,
|
||||||
tl->db, &tl->grant.privilege, 0, 0) ||
|
tl->db, &tl->grant.privilege, 0, 0) ||
|
||||||
(grant_option && check_grant(thd, want_privilege, tl, 0, 1, 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);
|
result, unit, select_lex);
|
||||||
delete result;
|
delete result;
|
||||||
thd->abort_on_warning= 0;
|
thd->abort_on_warning= 0;
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5992,10 +5992,7 @@ update:
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
if (lex->select_lex.table_list.elements > 1)
|
if (lex->select_lex.table_list.elements > 1)
|
||||||
{
|
|
||||||
lex->sql_command= SQLCOM_UPDATE_MULTI;
|
lex->sql_command= SQLCOM_UPDATE_MULTI;
|
||||||
lex->multi_lock_option= $3;
|
|
||||||
}
|
|
||||||
else if (lex->select_lex.get_table_list()->derived)
|
else if (lex->select_lex.get_table_list()->derived)
|
||||||
{
|
{
|
||||||
/* it is single table update and it is update of derived table */
|
/* 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");
|
lex->select_lex.get_table_list()->alias, "UPDATE");
|
||||||
YYABORT;
|
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 {}
|
where_clause opt_order_clause delete_limit_clause {}
|
||||||
;
|
;
|
||||||
|
|
Loading…
Reference in a new issue