diff options
-rw-r--r-- | mysql-test/r/subselect.result | 49 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 55 | ||||
-rw-r--r-- | sql/item_subselect.cc | 8 | ||||
-rw-r--r-- | sql/table.cc | 1 |
4 files changed, 112 insertions, 1 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 26e8e3ad0ef..26fe129feed 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4461,6 +4461,55 @@ ERROR 21000: Subquery returns more than 1 row SET SESSION sql_mode=@old_sql_mode; DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; End of 5.0 tests. CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 VALUES (2,22),(1,11),(2,22); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 4c5ecbd9ee6..aec0db59843 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3427,6 +3427,61 @@ SET SESSION sql_mode=@old_sql_mode; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +## All these are subject to the transformation +## '1 < some (...)' => '1 < max(...)' +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1, t2; + +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +create table t2(i int); +insert into t2 values(0); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; + +CREATE TABLE t1 ( + pk int NOT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +); + +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; + +SET SESSION sql_mode=@old_sql_mode; + +drop table t2, t1; +drop view v1; + --echo End of 5.0 tests. # diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e9e2e8bacf9..bfd0e1c21c3 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1020,7 +1020,13 @@ Item_in_subselect::single_value_transformer(JOIN *join, print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { - DBUG_ASSERT(select_lex->non_agg_field_used()); + /* + If the argument is a field, we assume that fix_fields() has + tagged the select_lex with non_agg_field_used. + We reverse that decision after this rewrite with MIN/MAX. + */ + if (item->get_arg(0)->type() == Item::FIELD_ITEM) + DBUG_ASSERT(select_lex->non_agg_field_used()); select_lex->set_non_agg_field_used(false); } diff --git a/sql/table.cc b/sql/table.cc index 9b7f3e66ea6..4577778285f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3979,6 +3979,7 @@ Item *Field_iterator_table::create_item(THD *thd) { select->non_agg_fields.push_back(item); item->marker= select->cur_pos_in_select_list; + select->set_non_agg_field_used(true); } return item; } |