From fdb3eaf3d72b95a27e24b4fd9560dddbc5378e29 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Tue, 26 Nov 2002 01:00:05 +0200 Subject: [PATCH] subselects in insert/replace (SCRUM) --- mysql-test/r/subselect.result | 62 ++++++++++++++++++++++++++++++++++- mysql-test/t/subselect.test | 39 +++++++++++++++++++++- sql/sql_insert.cc | 31 +++++++++++++----- sql/sql_yacc.yy | 8 ++++- 4 files changed, 128 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 02f05ce50d6..ce5e7d2032f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -335,7 +335,6 @@ a b 1 21 2 22 drop table t1, t2; -drop table if exists t1, t2; 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); @@ -354,3 +353,64 @@ a b 0 10 1 11 drop table t1, t2; +CREATE TABLE t1 (x int); +create table t2 (a int); +insert into t2 values (1); +INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); +select * from t1; +x +1 +insert into t2 values (1); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); +select * from t1; +x +1 +2 +INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; +select * from t1; +x +1 +2 +3 +3 +INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; +INSERT TABLE 't1' isn't allowed in FROM table list +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); +select * from t1; +x +1 +2 +3 +3 +9 +drop table t1, t2; +CREATE TABLE t1 (x int not null, y int, primary key (x)); +create table t2 (a int); +insert into t2 values (1); +select * from t1; +x y +replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); +select * from t1; +x y +1 2 +replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2)); +select * from t1; +x y +1 3 +replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2)); +select * from t1; +x y +1 3 +4 1 +replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2)); +select * from t1; +x y +1 3 +4 2 +replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2)); +select * from t1; +x y +1 3 +4 2 +2 1 +drop table t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3f20abe803a..4dea1ab5bca 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -216,7 +216,6 @@ select * from t1; drop table t1, t2; #delete with subselects -drop table if exists t1, t2; 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); @@ -226,3 +225,41 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); delete from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1; drop table t1, t2; + +#insert with subselects +CREATE TABLE t1 (x int); +create table t2 (a int); +insert into t2 values (1); +INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); +select * from t1; +insert into t2 values (1); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); +-- sleep 1 +select * from t1; +INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; +select * from t1; +-- error 1093 +INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); +-- sleep 1 +select * from t1; +drop table t1, t2; + +#replace with subselects +CREATE TABLE t1 (x int not null, y int, primary key (x)); +create table t2 (a int); +insert into t2 values (1); +select * from t1; +replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); +select * from t1; +replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2)); +select * from t1; +replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2)); +-- sleep 1 +select * from t1; +replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2)); +-- sleep 1 +select * from t1; +replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2)); +select * from t1; +drop table t1, t2; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c8a29dcd8da..295c1e339c5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -114,6 +114,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, List_item *values; char *query=thd->query; thr_lock_type lock_type = table_list->lock_type; + TABLE_LIST *insert_table_list= (TABLE_LIST*) + thd->lex.select_lex.table_list.first; DBUG_ENTER("mysql_insert"); /* @@ -126,7 +128,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, thd->slave_thread)) || (lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE)) lock_type=TL_WRITE; + table_list->lock_type= lock_type; + int res; if (lock_type == TL_WRITE_DELAYED) { if (thd->locked_tables) @@ -141,25 +145,34 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, DBUG_RETURN(-1); } } - if (!(table = delayed_get_table(thd,table_list)) && !thd->fatal_error) - table = open_ltable(thd,table_list,lock_type=thd->update_lock_default); + if ((table= delayed_get_table(thd,table_list)) && !thd->fatal_error) + if (table_list->next && table) + res= open_and_lock_tables(thd, table_list->next); + else + res= (table == 0); + else + res= open_and_lock_tables(thd, table_list); } else - table = open_ltable(thd,table_list,lock_type); - if (!table) + res= open_and_lock_tables(thd, table_list); + if (res) DBUG_RETURN(-1); + fix_tables_pointers(&thd->lex.select_lex); + + table= table_list->table; thd->proc_info="init"; thd->used_tables=0; save_time_stamp=table->time_stamp; values= its++; if (check_insert_fields(thd,table,fields,*values,1) || - setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0,0)) + setup_tables(insert_table_list) || + setup_fields(thd, insert_table_list, *values, 0, 0, 0)) { - table->time_stamp=save_time_stamp; + table->time_stamp= save_time_stamp; goto abort; } value_count= values->elements; - while ((values = its++)) + while ((values= its++)) { counter++; if (values->elements != value_count) @@ -170,9 +183,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, table->time_stamp=save_time_stamp; goto abort; } - if (setup_fields(thd,table_list,*values,0,0,0)) + if (setup_fields(thd,insert_table_list,*values,0,0,0)) { - table->time_stamp=save_time_stamp; + table->time_stamp= save_time_stamp; goto abort; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4465a6d8695..187ba63e92f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2837,7 +2837,13 @@ opt_temporary: */ insert: - INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option + INSERT + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_INSERT; + /* for subselects */ + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + } insert_lock_option opt_ignore insert2 { Select->set_lock_for_tables($3);