diff options
-rw-r--r-- | mysql-test/r/multi_update.result | 11 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_multi_update.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb_multi_update.test | 6 | ||||
-rw-r--r-- | mysql-test/suite/innodb_plugin/r/innodb_multi_update.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb_plugin/t/innodb_multi_update.test | 6 | ||||
-rw-r--r-- | mysql-test/t/multi_update.test | 7 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 24 | ||||
-rw-r--r-- | sql/sql_update.cc | 4 | ||||
-rw-r--r-- | sql/table.cc | 8 |
10 files changed, 55 insertions, 17 deletions
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index f58861ec8ce..793763312b7 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -654,6 +654,9 @@ INSERT INTO t3 VALUES (1), (2); UPDATE IGNORE ( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3 SET t3.a = 0; +Warnings: +Error 1242 Subquery returns more than 1 row +Error 1242 Subquery returns more than 1 row DROP TABLE t1, t2, t3; SET SESSION sql_safe_updates = DEFAULT; # @@ -662,6 +665,14 @@ SET SESSION sql_safe_updates = DEFAULT; CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; CREATE TABLE t1 (f1 DATE); INSERT INTO t1 VALUES('2001-01-01'); +UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +CREATE view v1 as SELECT f1() FROM t1; +UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1; +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +DROP VIEW v1; DROP FUNCTION f1; DROP TABLE t1; end of tests diff --git a/mysql-test/suite/innodb/r/innodb_multi_update.result b/mysql-test/suite/innodb/r/innodb_multi_update.result index 924470faedd..558fc3938a8 100644 --- a/mysql-test/suite/innodb/r/innodb_multi_update.result +++ b/mysql-test/suite/innodb/r/innodb_multi_update.result @@ -79,4 +79,6 @@ drop table bug38999_1,bug38999_2; # CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_multi_update.test b/mysql-test/suite/innodb/t/innodb_multi_update.test index f51dc74e3af..8356c20c88f 100644 --- a/mysql-test/suite/innodb/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb/t/innodb_multi_update.test @@ -34,9 +34,7 @@ drop table bug38999_1,bug38999_2; --echo # CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); -# !!! This query returns a wrong error due to a bug in the code of mwl106 -# !!! Uncomment it when the bug is fixed -# --error ER_OPERAND_COLUMNS -# UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +--error ER_OPERAND_COLUMNS +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result b/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result index 924470faedd..558fc3938a8 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result @@ -79,4 +79,6 @@ drop table bug38999_1,bug38999_2; # CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test index 84ab8746a91..3d9a9a53193 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test @@ -34,9 +34,7 @@ drop table bug38999_1,bug38999_2; --echo # CREATE TABLE t1(f1 INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); -# !!! This query returns a wrong error due to a bug in the code of mwl106 -# !!! Uncomment it when the bug is fixed -# --error ER_OPERAND_COLUMNS -# UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; +--error ER_OPERAND_COLUMNS +UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1; DROP TABLE t1; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 914a1a3b4a1..58a614e3a11 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -684,9 +684,10 @@ SET SESSION sql_safe_updates = DEFAULT; CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; CREATE TABLE t1 (f1 DATE); INSERT INTO t1 VALUES('2001-01-01'); -# !!! This query returns a wrong error due to a bug in the code of mwl106 -# !!! Uncomment it when the bug is fixed -# UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +CREATE view v1 as SELECT f1() FROM t1; +UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1; +DROP VIEW v1; DROP FUNCTION f1; DROP TABLE t1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a587a01b3f4..014bcfdfd65 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -585,6 +585,8 @@ public: void set_thd(THD *thd_arg) { thd= thd_arg; } inline bool is_union (); + void set_unique_exlude(); + friend void lex_start(THD *thd); friend int subselect_union_engine::exec(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 255f5311ac3..c6a6349fd4e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -944,3 +944,27 @@ void st_select_lex::cleanup_all_joins(bool full) for (sl= unit->first_select(); sl; sl= sl->next_select()) sl->cleanup_all_joins(full); } + + +/** + Set exclude_from_table_unique_test for selects of this unit and all + underlying selects. + + @note used to exclude materialized derived tables (views) from unique + table check. +*/ + +void st_select_lex_unit::set_unique_exlude() +{ + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + { + sl->exclude_from_table_unique_test= TRUE; + for (SELECT_LEX_UNIT *unit= sl->first_inner_unit(); + unit; + unit= unit->next_unit()) + { + unit->set_unique_exlude(); + } + } +} + diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 215c5cbd4b3..4821fc2bd8f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1040,8 +1040,8 @@ reopen_tables: //We need to merge for insert prior to prepare. if (mysql_handle_list_of_derived(lex, table_list, DT_MERGE_FOR_INSERT)) DBUG_RETURN(1); - if (mysql_handle_list_of_derived(lex, table_list, DT_PREPARE)) - DBUG_RETURN(1); + if (mysql_handle_derived(lex, DT_PREPARE)) + DBUG_RETURN(TRUE); if (setup_tables_and_check_access(thd, &lex->select_lex.context, &lex->select_lex.top_join_list, diff --git a/sql/table.cc b/sql/table.cc index 290a82eb56a..3e6b683eafb 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5851,7 +5851,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) if (!is_view()) { /* A subquery might be forced to be materialized due to a side-effect. */ - if (!is_materialized_derived() && first_select->is_mergeable()) + if (!is_materialized_derived() && first_select->is_mergeable() && + !(thd->lex->sql_command == SQLCOM_UPDATE_MULTI || + thd->lex->sql_command == SQLCOM_UPDATE)) set_merged_derived(); else set_materialized_derived(); @@ -5862,9 +5864,7 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) */ if (is_materialized_derived()) { - SELECT_LEX *sl; - for (sl= first_select ;sl ; sl= sl->next_select()) - sl->exclude_from_table_unique_test= TRUE; + unit->master_unit()->set_unique_exlude(); } /* Create field translation for mergeable derived tables/views. |