Commit c8130069 authored by unknown's avatar unknown

fixed update with subselect (FOR REVIEW)


mysql-test/r/subselect.result:
  update with subselect test
mysql-test/t/subselect.test:
  update with subselect test
sql/mysql_priv.h:
  fixed update with subselect
sql/sql_base.cc:
  fixed update with subselect
sql/sql_lex.cc:
  fixed update with subselect
sql/sql_select.cc:
  fixed update with subselect
sql/sql_update.cc:
  fixed update with subselect
sql/sql_yacc.yy:
  fixed update with subselect
parent 372b26e7
...@@ -205,3 +205,19 @@ SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03') ...@@ -205,3 +205,19 @@ SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03')
(SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03') (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03')
2002-08-03 2002-08-03
drop table searchconthardwarefr3; drop table searchconthardwarefr3;
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;
...@@ -111,3 +111,14 @@ EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002 ...@@ -111,3 +111,14 @@ EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002
SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'; SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'); SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
drop table searchconthardwarefr3; drop table searchconthardwarefr3;
#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;
...@@ -444,7 +444,8 @@ void kill_delayed_threads(void); ...@@ -444,7 +444,8 @@ void kill_delayed_threads(void);
int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order, int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order,
ha_rows rows, thr_lock_type lock_type, ulong options); ha_rows rows, thr_lock_type lock_type, ulong options);
int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0); int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
bool multiopen= 0);
TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias, TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
bool *refresh); bool *refresh);
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table); TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
......
...@@ -1567,16 +1567,24 @@ int open_tables(THD *thd,TABLE_LIST *start) ...@@ -1567,16 +1567,24 @@ int open_tables(THD *thd,TABLE_LIST *start)
} }
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
bool multiopen)
{ {
TABLE *table; TABLE *table;
bool refresh; bool refresh;
DBUG_ENTER("open_ltable"); DBUG_ENTER("open_ltable");
thd->proc_info="Opening table"; thd->proc_info="Opening table";
while (!(table=open_table(thd,table_list->db, if (table_list->next && multiopen)
{
while (open_tables(thd,table_list) && refresh) ;
table= table_list->table;
}
else
while (!(table= open_table(thd,table_list->db,
table_list->real_name,table_list->alias, table_list->real_name,table_list->alias,
&refresh)) && refresh) ; &refresh)) && refresh) ;
if (table) if (table)
{ {
int error; int error;
......
...@@ -148,6 +148,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) ...@@ -148,6 +148,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select_lex.expr_list.empty(); lex->select_lex.expr_list.empty();
lex->select_lex.ftfunc_list_alloc.empty(); lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select->ftfunc_list_alloc; lex->select_lex.ftfunc_list= &lex->select->ftfunc_list_alloc;
lex->select= &lex->select_lex;
lex->convert_set= (lex->thd= thd)->variables.convert_set; lex->convert_set= (lex->thd= thd)->variables.convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0; lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
...@@ -956,6 +957,7 @@ void st_select_lex::init_query() ...@@ -956,6 +957,7 @@ void st_select_lex::init_query()
table_list.next= (byte**) &table_list.first; table_list.next= (byte**) &table_list.first;
item_list.empty(); item_list.empty();
join= 0; join= 0;
having_fix_field= 0;
} }
void st_select_lex::init_select() void st_select_lex::init_select()
...@@ -973,7 +975,7 @@ void st_select_lex::init_select() ...@@ -973,7 +975,7 @@ void st_select_lex::init_select()
ftfunc_list_alloc.empty(); ftfunc_list_alloc.empty();
ftfunc_list= &ftfunc_list_alloc; ftfunc_list= &ftfunc_list_alloc;
linkage= UNSPECIFIED_TYPE; linkage= UNSPECIFIED_TYPE;
depended= having_fix_field= 0; depended= 0;
} }
/* /*
......
...@@ -5641,6 +5641,9 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table) ...@@ -5641,6 +5641,9 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
static Item * static Item *
part_of_refkey(TABLE *table,Field *field) 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; uint ref_parts=table->reginfo.join_tab->ref.key_parts;
if (ref_parts) if (ref_parts)
{ {
......
...@@ -62,12 +62,17 @@ int mysql_update(THD *thd, ...@@ -62,12 +62,17 @@ int mysql_update(THD *thd,
TABLE *table; TABLE *table;
SQL_SELECT *select; SQL_SELECT *select;
READ_RECORD info; READ_RECORD info;
TABLE_LIST *update_table_list= (TABLE_LIST*)
thd->lex.select_lex.table_list.first;
DBUG_ENTER("mysql_update"); DBUG_ENTER("mysql_update");
LINT_INIT(used_index); LINT_INIT(used_index);
LINT_INIT(timestamp_query_id); LINT_INIT(timestamp_query_id);
if (!(table = open_ltable(thd,table_list,lock_type))) table_list->lock_type= lock_type;
DBUG_RETURN(-1); /* purecov: inspected */ if (!(table = open_ltable(thd,table_list,lock_type, 1)))
DBUG_RETURN(-1);
fix_tables_pointers(&thd->lex.select_lex);
save_time_stamp=table->time_stamp; save_time_stamp=table->time_stamp;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init"; thd->proc_info="init";
...@@ -77,7 +82,8 @@ int mysql_update(THD *thd, ...@@ -77,7 +82,8 @@ int mysql_update(THD *thd,
table->quick_keys=0; table->quick_keys=0;
want_privilege=table->grant.want_privilege; want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.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)) || setup_ftfuncs(thd))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
old_used_keys=table->used_keys; // Keys used in WHERE old_used_keys=table->used_keys; // Keys used in WHERE
...@@ -94,7 +100,7 @@ int mysql_update(THD *thd, ...@@ -94,7 +100,7 @@ int mysql_update(THD *thd,
/* Check the fields we are going to modify */ /* Check the fields we are going to modify */
table->grant.want_privilege=want_privilege; 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 */ DBUG_RETURN(-1); /* purecov: inspected */
if (table->timestamp_field) if (table->timestamp_field)
{ {
...@@ -107,7 +113,7 @@ int mysql_update(THD *thd, ...@@ -107,7 +113,7 @@ int mysql_update(THD *thd,
/* Check values */ /* Check values */
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); 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 table->time_stamp=save_time_stamp; // Restore timestamp pointer
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
......
...@@ -1572,7 +1572,8 @@ select_init: ...@@ -1572,7 +1572,8 @@ select_init:
select_part2: select_part2:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->lock_option=TL_READ; if (lex->select == &lex->select_lex)
lex->lock_option= TL_READ; /* Only for global SELECT */
mysql_init_select(lex); mysql_init_select(lex);
} }
select_options select_item_list select_into select_lock_type; select_options select_item_list select_into select_lock_type;
......
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