Commit d40bec68 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Merge

parents 3d1af24f 0c546b65
drop table if exists t1, t2;
create table t1 (id integer, x integer) type=INNODB;
create table t2 (b integer, a integer) type=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 10), (1, 20), (2, 30);
set autocommit=0;
select * from t2;
b a
0 10
1 20
2 30
update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE);
select * from t2;
b a
0 100
1 20
2 30
select * from t1;
id x
0 0
300 300
set autocommit=0;
update t1 set x=2 where id = 0;
update t1 set x=1 where id = 0;
select * from t1;
id x
0 1
300 300
commit;
commit;
select * from t1;
id x
0 2
300 300
commit;
drop table t1, t2;
create table t1 (id integer, x integer) type=INNODB;
create table t2 (b integer, a integer) type=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
a b
0 0
20 1
30 2
300 300
select * from t2;
b a
0 0
1 20
2 30
select * from t1;
id x
0 0
300 300
update t2 set a=2 where b = 0;
select * from t2;
b a
0 2
1 20
2 30
update t1 set x=2 where id = 0;
update t1 set x=1 where id = 0;
select * from t1;
id x
0 1
300 300
commit;
commit;
select * from t1;
id x
0 2
300 300
commit;
drop table t1, t2;
......@@ -319,3 +319,19 @@ SELECT 1 FROM (SELECT a FROM t1) HAVING (SELECT a)=1;
1
1
drop table t1;
create table t1 (a int NOT NULL, b int, primary key (a));
create table t2 (a int NOT NULL, b int, primary key (a));
insert into t1 values (0, 10),(1, 11),(2, 12);
insert into t2 values (1, 21),(2, 22),(3, 23);
select * from t1;
a b
0 10
1 11
2 12
update t1 set b= (select b from t2 where t1.a = t2.a);
select * from t1;
a b
0 NULL
1 21
2 22
drop table t1, t2;
-- source include/have_innodb.inc
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
drop table if exists t1, t2;
#
# Testing of FOR UPDATE
#
connection con1;
create table t1 (id integer, x integer) type=INNODB;
create table t2 (b integer, a integer) type=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 10), (1, 20), (2, 30);
set autocommit=0;
select * from t2;
update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE);
select * from t2;
select * from t1;
connection con2;
set autocommit=0;
# The following query should hang because con1 is locking the page
--send
update t1 set x=2 where id = 0;
--sleep 2;
connection con1;
update t1 set x=1 where id = 0;
select * from t1;
commit;
connection con2;
reap;
commit;
connection con1;
select * from t1;
commit;
drop table t1, t2;
create table t1 (id integer, x integer) type=INNODB;
create table t2 (b integer, a integer) type=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
connection con1;
select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
select * from t2;
select * from t1;
connection con2;
# The following query should hang because con1 is locking the page
update t2 set a=2 where b = 0;
select * from t2;
--send
update t1 set x=2 where id = 0;
--sleep 2;
connection con1;
update t1 set x=1 where id = 0;
select * from t1;
commit;
connection con2;
reap;
commit;
connection con1;
select * from t1;
commit;
drop table t1, t2;
\ No newline at end of file
......@@ -204,3 +204,14 @@ CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
SELECT 1 FROM (SELECT a FROM t1) HAVING (SELECT a)=1;
drop table t1;
#update with subselects
create table t1 (a int NOT NULL, b int, primary key (a));
create table t2 (a int NOT NULL, b int, primary key (a));
insert into t1 values (0, 10),(1, 11),(2, 12);
insert into t2 values (1, 21),(2, 22),(3, 23);
select * from t1;
update t1 set b= (select b from t2 where t1.a = t2.a);
select * from t1;
drop table t1, t2;
......@@ -1625,6 +1625,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
while (!(table=open_table(thd,table_list->db,
table_list->real_name,table_list->alias,
&refresh)) && refresh) ;
if (table)
{
#if defined( __WIN__) || defined(OS2)
......
......@@ -163,6 +163,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select_lex.expr_list.empty();
lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
lex->current_select= &lex->select_lex;
lex->convert_set= (lex->thd= thd)->variables.convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
......@@ -970,6 +971,7 @@ void st_select_lex::init_query()
item_list.empty();
join= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
}
void st_select_lex::init_select()
......@@ -987,7 +989,6 @@ void st_select_lex::init_select()
ftfunc_list_alloc.empty();
ftfunc_list= &ftfunc_list_alloc;
linkage= UNSPECIFIED_TYPE;
having_fix_field= 0;
}
/*
......@@ -1293,4 +1294,7 @@ List<String>* st_select_lex::get_ignore_index()
return ignore_index_ptr;
}
// There are st_select_lex::add_table_to_list in sql_parse.cc
/*
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables in sql_parse.cc
*/
......@@ -1426,20 +1426,7 @@ mysql_execute_command(THD *thd)
{
if (!result)
{
if ((result=new select_send()))
{
/*
Normal select:
Change lock if we are using SELECT HIGH PRIORITY,
FOR UPDATE or IN SHARE MODE
TODO: Delete the following loop when locks is set by sql_yacc
*/
TABLE_LIST *table;
for (table = tables ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
else
if (!(result=new select_send()))
{
res= -1;
#ifdef DELETE_ITEMS
......@@ -1663,9 +1650,6 @@ mysql_execute_command(THD *thd)
TABLE_LIST *table;
if (check_table_access(thd, SELECT_ACL, tables->next))
goto error; // Error message is given
/* TODO: Delete the following loop when locks is set by sql_yacc */
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
unit->offset_limit_cnt= select_lex->offset_limit;
unit->select_limit_cnt= select_lex->select_limit+
......@@ -2023,12 +2007,6 @@ mysql_execute_command(THD *thd)
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
}
{
/* TODO: Delete the following loop when locks is set by sql_yacc */
TABLE_LIST *table;
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
/* Skip first table, which is the table we are inserting in */
lex->select_lex.table_list.first=
......
......@@ -5716,6 +5716,9 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
static Item *
part_of_refkey(TABLE *table,Field *field)
{
if (!table->reginfo.join_tab)
return (Item*) 0; // field from outer non-select (UPDATE,...)
uint ref_parts=table->reginfo.join_tab->ref.key_parts;
if (ref_parts)
{
......
......@@ -62,12 +62,17 @@ int mysql_update(THD *thd,
TABLE *table;
SQL_SELECT *select;
READ_RECORD info;
TABLE_LIST *update_table_list= (TABLE_LIST*)
thd->lex.select_lex.table_list.first;
DBUG_ENTER("mysql_update");
LINT_INIT(used_index);
LINT_INIT(timestamp_query_id);
if (!(table = open_ltable(thd,table_list,table_list->lock_type)))
DBUG_RETURN(-1); /* purecov: inspected */
if ((open_and_lock_tables(thd, table_list)))
DBUG_RETURN(-1);
fix_tables_pointers(&thd->lex.select_lex);
table= table_list->table;
save_time_stamp=table->time_stamp;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
......@@ -77,7 +82,8 @@ int mysql_update(THD *thd,
table->quick_keys=0;
want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
if (setup_tables(table_list) || setup_conds(thd,table_list,&conds)
if (setup_tables(update_table_list) ||
setup_conds(thd,update_table_list,&conds)
|| setup_ftfuncs(&thd->lex.select_lex))
DBUG_RETURN(-1); /* purecov: inspected */
old_used_keys=table->used_keys; // Keys used in WHERE
......@@ -94,7 +100,7 @@ int mysql_update(THD *thd,
/* Check the fields we are going to modify */
table->grant.want_privilege=want_privilege;
if (setup_fields(thd,table_list,fields,1,0,0))
if (setup_fields(thd,update_table_list,fields,1,0,0))
DBUG_RETURN(-1); /* purecov: inspected */
if (table->timestamp_field)
{
......@@ -107,7 +113,7 @@ int mysql_update(THD *thd,
/* Check values */
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
if (setup_fields(thd,table_list,values,0,0,0))
if (setup_fields(thd,update_table_list,values,0,0,0))
{
table->time_stamp=save_time_stamp; // Restore timestamp pointer
DBUG_RETURN(-1); /* purecov: inspected */
......
......@@ -798,7 +798,10 @@ create:
($2 &
HA_LEX_CREATE_TMP_TABLE ?
&tmp_table_alias :
(LEX_STRING*) 0),1))
(LEX_STRING*) 0),1,
((using_update_log)?
TL_READ_NO_INSERT:
TL_READ)))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
......@@ -1646,7 +1649,8 @@ select_init:
select_part2:
{
LEX *lex=Lex;
lex->lock_option=TL_READ;
if (lex->current_select == &lex->select_lex)
lex->lock_option= TL_READ; /* Only for global SELECT */
mysql_init_select(lex);
}
select_options select_item_list select_into select_lock_type;
......@@ -1704,17 +1708,14 @@ select_lock_type:
| FOR_SYM UPDATE_SYM
{
LEX *lex=Lex;
if (check_simple_select())
YYABORT;
lex->lock_option= TL_WRITE;
lex->current_select->set_lock_for_tables(TL_WRITE);
lex->safe_to_cache_query=0;
}
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
{
LEX *lex=Lex;
if (check_simple_select())
YYABORT;
lex->lock_option= TL_READ_WITH_SHARED_LOCKS;
lex->current_select->
set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
lex->safe_to_cache_query=0;
}
;
......@@ -2394,8 +2395,9 @@ join_table:
}
table_ident opt_table_alias opt_key_definition
{
SELECT_LEX_NODE *sel=Select;
if (!($$= sel->add_table_to_list($2, $3, 0, TL_UNLOCK,
LEX *lex= Lex;
SELECT_LEX_NODE *sel= lex->current_select;
if (!($$= sel->add_table_to_list($2, $3, 0, lex->lock_option,
sel->get_use_index(),
sel->get_ignore_index())))
YYABORT;
......@@ -2408,7 +2410,8 @@ join_table:
SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
lex->current_select= unit->outer_select();
if (!($$= lex->current_select->
add_table_to_list(new Table_ident(unit), $5, 0, TL_UNLOCK)))
add_table_to_list(new Table_ident(unit), $5, 0,
lex->lock_option)))
YYABORT;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment