mirror of
https://github.com/MariaDB/server.git
synced 2025-12-28 08:10:14 +00:00
MDEV-37435 Make new vcols created in vcol index substitution inherit name resolution from the select_lex
Some checks failed
Build on Windows ARM64 / build (push) Has been cancelled
Some checks failed
Build on Windows ARM64 / build (push) Has been cancelled
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.
This commit is contained in:
parent
d29fb34b83
commit
0316c6e4f2
@ -193,3 +193,32 @@ explain select vc1, vc2 from t group by c + 1, 1 - c;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t index NULL vc1 10 NULL 10000 Using index
|
||||
drop table t;
|
||||
#
|
||||
# MDEV-37435 Assertion `field' failed in virtual bool Item_field::fix_fields(THD *, Item **)
|
||||
#
|
||||
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
|
||||
SELECT a FROM t1 GROUP BY a HAVING a>2;
|
||||
a
|
||||
SELECT a FROM t1 WHERE a=(SELECT a FROM t1 GROUP BY a HAVING a>2);
|
||||
a
|
||||
drop table t1;
|
||||
create table t1 (a int, a1 int as (a+1) virtual, index(a1));
|
||||
select a+1 as g from t1 group by g having g>2;
|
||||
g
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
|
||||
CREATE TABLE t2 (b INT,b1 INT AS (b) VIRTUAL,INDEX (b1));
|
||||
insert into t1 (a) select seq from seq_1_to_5;
|
||||
insert into t2 (b) select seq from seq_1_to_5;
|
||||
SELECT a, b FROM t1, t2 GROUP BY a, b HAVING a>2 and b>2;
|
||||
a b
|
||||
3 3
|
||||
3 4
|
||||
3 5
|
||||
4 3
|
||||
4 4
|
||||
4 5
|
||||
5 3
|
||||
5 4
|
||||
5 5
|
||||
drop table t1, t2;
|
||||
|
||||
@ -149,3 +149,22 @@ alter table t
|
||||
add index(vc1, vc2);
|
||||
explain select vc1, vc2 from t group by c + 1, 1 - c;
|
||||
drop table t;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-37435 Assertion `field' failed in virtual bool Item_field::fix_fields(THD *, Item **)
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
|
||||
SELECT a FROM t1 GROUP BY a HAVING a>2;
|
||||
SELECT a FROM t1 WHERE a=(SELECT a FROM t1 GROUP BY a HAVING a>2);
|
||||
drop table t1;
|
||||
|
||||
create table t1 (a int, a1 int as (a+1) virtual, index(a1));
|
||||
select a+1 as g from t1 group by g having g>2;
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE t1 (a INT,a1 INT AS (a) VIRTUAL,INDEX (a1));
|
||||
CREATE TABLE t2 (b INT,b1 INT AS (b) VIRTUAL,INDEX (b1));
|
||||
insert into t1 (a) select seq from seq_1_to_5;
|
||||
insert into t2 (b) select seq from seq_1_to_5;
|
||||
SELECT a, b FROM t1, t2 GROUP BY a, b HAVING a>2 and b>2;
|
||||
drop table t1, t2;
|
||||
|
||||
@ -105,6 +105,8 @@ class Vcol_subst_context
|
||||
THD *thd;
|
||||
/* Indexed virtual columns that we can try substituting */
|
||||
List<Field> vcol_fields;
|
||||
/* Name resolution context for new vcol Item_field's */
|
||||
Name_resolution_context *context;
|
||||
|
||||
/*
|
||||
How many times substitution was done. Used to determine whether to print
|
||||
@ -293,6 +295,7 @@ bool substitute_indexed_vcols_for_join(JOIN *join)
|
||||
if (!ctx.vcol_fields.elements)
|
||||
return false; // Ok, nothing to do
|
||||
|
||||
ctx.context= &join->select_lex->context;
|
||||
if (join->conds)
|
||||
subst_vcols_in_item(&ctx, join->conds, "WHERE");
|
||||
if (join->join_list)
|
||||
@ -463,6 +466,7 @@ void subst_vcol_if_compatible(Vcol_subst_context *ctx,
|
||||
Item_field *itf= new (thd->mem_root) Item_field(thd, vcol_field);
|
||||
if (!itf)
|
||||
return; // Out of memory, caller will know from thd->is_error()
|
||||
itf->context= ctx->context;
|
||||
bitmap_set_bit(vcol_field->table->read_set, vcol_field->field_index);
|
||||
DBUG_ASSERT(itf->fixed());
|
||||
thd->change_item_tree(vcol_expr_ref, itf);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user