Commit 1248c654 authored by Igor Babaev's avatar Igor Babaev

MDEV-19179 Regression: SELECT ... UNION ... with inconsistent column names fails

A bogus error message was issued when a condition was pushed into a
materialized derived table or view specified as union of selects with
aggregation when the corresponding columns of the selects had different
names. This happened because the expression pushed into having clauses of
the selects was adjusted for the names of the first select of the union.
The easiest solution was to rename the columns of the other selects to be
name compatible with the columns of the first select.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
parent bbbab821
......@@ -10593,4 +10593,45 @@ a
abc
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-19179: pushdown into UNION of aggregation selects whose
# corresponding columns have different names
#
create table t1 (a int);
insert into t1 values (3), (7), (1);
select *
from (select min(a) as x from t1 union all select max(a) as y from t1) t
where x>0;
x
1
7
explain extended select *
from (select min(a) as x from t1 union all select max(a) as y from t1) t
where x>0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 100.00 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00
3 UNION t1 ALL NULL NULL NULL NULL 3 100.00
Warnings:
Note 1003 select `t`.`x` AS `x` from (select min(`test`.`t1`.`a`) AS `x` from `test`.`t1` having `x` > 0 union all select max(`test`.`t1`.`a`) AS `x` from `test`.`t1` having `x` > 0) `t` where `t`.`x` > 0
prepare stmt from "select *
from (select min(a) as x from t1 union all select max(a) as y from t1) t
where x>0";
execute stmt;
x
1
7
execute stmt;
x
1
7
deallocate prepare stmt;
create view v1(m) as
select min(a) as x from t1 union all select max(a) as y from t1;
select * from v1 where m > 0;
m
1
7
drop view v1;
drop table t1;
# End of 10.2 tests
......@@ -2184,4 +2184,32 @@ SELECT * FROM v1 WHERE IF( a REGEXP 'def', 'foo', a ) IN ('abc', 'foobar');
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # MDEV-19179: pushdown into UNION of aggregation selects whose
--echo # corresponding columns have different names
--echo #
create table t1 (a int);
insert into t1 values (3), (7), (1);
let $q=
select *
from (select min(a) as x from t1 union all select max(a) as y from t1) t
where x>0;
eval $q;
eval explain extended $q;
eval prepare stmt from "$q";
execute stmt;
execute stmt;
deallocate prepare stmt;
create view v1(m) as
select min(a) as x from t1 union all select max(a) as y from t1;
select * from v1 where m > 0;
drop view v1;
drop table t1;
--echo # End of 10.2 tests
......@@ -818,6 +818,12 @@ class Item: public Value_source,
void set_name_for_rollback(THD *thd, const char *str, uint length,
CHARSET_INFO *cs);
void rename(char *new_name);
void share_name_with(Item *item)
{
name= item->name;
name_length= item->name_length;
is_autogenerated_name= item->is_autogenerated_name;
}
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup();
virtual void make_field(THD *thd, Send_field *field);
......
......@@ -1199,7 +1199,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
DBUG_RETURN(false);
st_select_lex_unit *unit= derived->get_unit();
st_select_lex *sl= unit->first_select();
st_select_lex *first_sl= unit->first_select();
st_select_lex *sl= first_sl;
if (derived->prohibit_cond_pushdown)
DBUG_RETURN(false);
......@@ -1312,6 +1313,23 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
continue;
}
/*
Rename the columns of all non-first selects of a union to be compatible
by names with the columns of the first select. It will allow to use copies
of the same expression pushed into having clauses of different selects.
*/
if (sl != first_sl)
{
DBUG_ASSERT(sl->item_list.elements == first_sl->item_list.elements);
List_iterator_fast<Item> it(sl->item_list);
List_iterator_fast<Item> nm_it(unit->types);
Item * item;
while((item= it++))
{
item->share_name_with(nm_it++);
}
}
/*
Transform the references to the 'derived' columns from the condition
pushed into the having clause of sl to make them usable in the new context
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment