diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index c0c67707231c4..ba4e6f17a957d 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -3373,4 +3373,27 @@ CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; (SELECT 0 GROUP BY c HAVING (SELECT c)) DROP TABLE t; +# +# MDEV-38476 Wrong Result (Empty Set) with derived_merge=on using AVG() on text column in HAVING clause +# +CREATE TABLE t1(c1 TEXT); +INSERT INTO t1(c1) VALUES ('a'),('ab'),('cc'); +SELECT MAX(ca1) FROM (SELECT c1 AS ca1 FROM t1) AS ta1 +GROUP BY ca1 +HAVING AVG(ca1) RLIKE (TRUE & CHARACTER_LENGTH(ca1)); +MAX(ca1) +ab +cc +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a' +Warning 1292 Truncated incorrect DOUBLE value: 'ab' +Warning 1292 Truncated incorrect DOUBLE value: 'cc' +TRUNCATE t1; +INSERT INTO t1 (c1) VALUES (NULL), ('abc'); +SELECT ca1 FROM (SELECT c1 AS ca1, c1 AS ca2 FROM t1) AS ta1 +GROUP BY ca2 +HAVING (ca2 = ANY (SELECT c1 FROM t1)) IS NOT TRUE; +ca1 +NULL +DROP TABLE t1; # End of 10.11 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 083da1647b27c..e76c4638ddf39 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2695,4 +2695,22 @@ CREATE TABLE t(c INT); SELECT (SELECT 0 GROUP BY c HAVING (SELECT c)) FROM t GROUP BY c; DROP TABLE t; +--echo # +--echo # MDEV-38476 Wrong Result (Empty Set) with derived_merge=on using AVG() on text column in HAVING clause +--echo # + +CREATE TABLE t1(c1 TEXT); +INSERT INTO t1(c1) VALUES ('a'),('ab'),('cc'); +SELECT MAX(ca1) FROM (SELECT c1 AS ca1 FROM t1) AS ta1 + GROUP BY ca1 + HAVING AVG(ca1) RLIKE (TRUE & CHARACTER_LENGTH(ca1)); + +TRUNCATE t1; +INSERT INTO t1 (c1) VALUES (NULL), ('abc'); +SELECT ca1 FROM (SELECT c1 AS ca1, c1 AS ca2 FROM t1) AS ta1 + GROUP BY ca2 + HAVING (ca2 = ANY (SELECT c1 FROM t1)) IS NOT TRUE; + +DROP TABLE t1; + --echo # End of 10.11 tests diff --git a/sql/item.cc b/sql/item.cc index da3219d7545e4..4e9100e131cbe 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5782,8 +5782,6 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) DBUG_ASSERT((*select_ref)->fixed()); return &select->ref_pointer_array[counter]; } - if (group_by_ref && (*group_by_ref)->type() == Item::REF_ITEM) - return ((Item_ref*)(*group_by_ref))->ref; if (group_by_ref) return group_by_ref; DBUG_ASSERT(FALSE); @@ -6063,8 +6061,24 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) return -1; /* Some error occurred (e.g. ambiguous names). */ if (ref != not_found_item) { - DBUG_ASSERT(*ref && (*ref)->fixed()); - prev_subselect_item->used_tables_and_const_cache_join(*ref); + DBUG_ASSERT(*ref); + + /* + If this item isn't yet fixed, it is an Item_outer_ref, wrapping an + item. If that item is fixed, we can fix this wrapper now. Otherwise + it will need to wait until the fix_inner_refs() in JOIN::prepare() + */ + if (!(*ref)->fixed() && + (*ref)->type() == Item::REF_ITEM) + { + Item_ref *item_ref= static_cast(*ref); + Item *refref= *(item_ref->ref); + if (refref->fixed()) + (*ref)->fix_fields_if_needed( thd, reference); + } + if ((*ref)->fixed()) + prev_subselect_item->used_tables_and_const_cache_join(*ref); + break; } } @@ -6105,8 +6119,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) Item *save; Item_ref *rf; - /* Should have been checked in resolve_ref_in_select_and_group(). */ - DBUG_ASSERT(*ref && (*ref)->fixed()); + DBUG_ASSERT(*ref); /* Here, a subset of actions performed by Item_ref::set_properties is not enough. So we pass ptr to NULL into Item_[direct]_ref