Skip to content

Commit 0316c6e

Browse files
MDEV-37435 Make new vcols created in vcol index substitution inherit name resolution from the select_lex
When a column or alias is the GROUP BY item, and a HAVING conjunct depends on this column/alias only, the HAVING conjunct could contain an Item_ref pointing to the GROUP BY Item_field. If the column/alias happens to the be the expression of a vcol, the GROUP BY item would be substituted with a newly created vcol Item_field (MDEV-36132). This causes the Item_ref in HAVING to point to the new vcol Item_field as well. Subsequently in the HAVING to WHERE pushdown optimization, the conjunct is moved to WHERE and fix_fields is called on it, where it expects the vcol Item_field to have a name resolution context. So we let the vcol Item_field inherit the context from the select_lex.
1 parent d29fb34 commit 0316c6e

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

mysql-test/suite/vcol/r/order_by_group_by_subst.result

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,32 @@ explain select vc1, vc2 from t group by c + 1, 1 - c;
193193
id select_type table type possible_keys key key_len ref rows Extra
194194
1 SIMPLE t index NULL vc1 10 NULL 10000 Using index
195195
drop table t;
196+
#
197+
# MDEV-37435 Assertion `field' failed in virtual bool Item_field::fix_fields(THD *, Item **)
198+
#
199+
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
200+
SELECT a FROM t1 GROUP BY a HAVING a>2;
201+
a
202+
SELECT a FROM t1 WHERE a=(SELECT a FROM t1 GROUP BY a HAVING a>2);
203+
a
204+
drop table t1;
205+
create table t1 (a int, a1 int as (a+1) virtual, index(a1));
206+
select a+1 as g from t1 group by g having g>2;
207+
g
208+
drop table t1;
209+
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
210+
CREATE TABLE t2 (b INT,b1 INT AS (b) VIRTUAL,INDEX (b1));
211+
insert into t1 (a) select seq from seq_1_to_5;
212+
insert into t2 (b) select seq from seq_1_to_5;
213+
SELECT a, b FROM t1, t2 GROUP BY a, b HAVING a>2 and b>2;
214+
a b
215+
3 3
216+
3 4
217+
3 5
218+
4 3
219+
4 4
220+
4 5
221+
5 3
222+
5 4
223+
5 5
224+
drop table t1, t2;

mysql-test/suite/vcol/t/order_by_group_by_subst.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,22 @@ alter table t
149149
add index(vc1, vc2);
150150
explain select vc1, vc2 from t group by c + 1, 1 - c;
151151
drop table t;
152+
153+
--echo #
154+
--echo # MDEV-37435 Assertion `field' failed in virtual bool Item_field::fix_fields(THD *, Item **)
155+
--echo #
156+
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
157+
SELECT a FROM t1 GROUP BY a HAVING a>2;
158+
SELECT a FROM t1 WHERE a=(SELECT a FROM t1 GROUP BY a HAVING a>2);
159+
drop table t1;
160+
161+
create table t1 (a int, a1 int as (a+1) virtual, index(a1));
162+
select a+1 as g from t1 group by g having g>2;
163+
drop table t1;
164+
165+
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
166+
CREATE TABLE t2 (b INT,b1 INT AS (b) VIRTUAL,INDEX (b1));
167+
insert into t1 (a) select seq from seq_1_to_5;
168+
insert into t2 (b) select seq from seq_1_to_5;
169+
SELECT a, b FROM t1, t2 GROUP BY a, b HAVING a>2 and b>2;
170+
drop table t1, t2;

sql/opt_vcol_substitution.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class Vcol_subst_context
105105
THD *thd;
106106
/* Indexed virtual columns that we can try substituting */
107107
List<Field> vcol_fields;
108+
/* Name resolution context for new vcol Item_field's */
109+
Name_resolution_context *context;
108110

109111
/*
110112
How many times substitution was done. Used to determine whether to print
@@ -293,6 +295,7 @@ bool substitute_indexed_vcols_for_join(JOIN *join)
293295
if (!ctx.vcol_fields.elements)
294296
return false; // Ok, nothing to do
295297

298+
ctx.context= &join->select_lex->context;
296299
if (join->conds)
297300
subst_vcols_in_item(&ctx, join->conds, "WHERE");
298301
if (join->join_list)
@@ -463,6 +466,7 @@ void subst_vcol_if_compatible(Vcol_subst_context *ctx,
463466
Item_field *itf= new (thd->mem_root) Item_field(thd, vcol_field);
464467
if (!itf)
465468
return; // Out of memory, caller will know from thd->is_error()
469+
itf->context= ctx->context;
466470
bitmap_set_bit(vcol_field->table->read_set, vcol_field->field_index);
467471
DBUG_ASSERT(itf->fixed());
468472
thd->change_item_tree(vcol_expr_ref, itf);

0 commit comments

Comments
 (0)