diff options
author | Sreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com> | 2018-10-09 12:03:35 +0530 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-01-23 12:39:17 +0100 |
commit | b20d94da356fa274a49ac38497e0cb20ce760d93 (patch) | |
tree | 796c1b394f27b940828b3bc9f13f7cc718b137cc /sql | |
parent | 6de2928d5bf912ace5fb5a1e2254025efe202b67 (diff) | |
download | mariadb-git-b20d94da356fa274a49ac38497e0cb20ce760d93.tar.gz |
Bug #28499924: INCORRECT BEHAVIOR WITH UNION IN SUBQUERY
Issue:
------
When a subquery contains UNION the count of the number of
subquery columns is calculated incorrectly. Only the first
query block in the subquery's UNION is considered and an
array indexing goes out-of-bounds, and this is caught by an
assert.
Solution:
---------
Sum up the columns from all query blocks of the query
expression.
Change specific to 5.6/5.5:
---------------------------
The "child" points to the last query block of the UNION
(as opposed to 5.7+ where it points to the first member of
UNION). So "child->master_unit()->first_select()" is used
to reach the first query block of UNION.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_yacc.yy | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 34f7c6e3481..ba0041cf477 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14627,19 +14627,21 @@ subselect_end: lex->current_select = lex->current_select->return_after_parsing(); lex->nest_level--; lex->current_select->n_child_sum_items += child->n_sum_items; - /* - A subselect can add fields to an outer select. Reserve space for - them. - */ - lex->current_select->select_n_where_fields+= - child->select_n_where_fields; /* - Aggregate functions in having clause may add fields to an outer - select. Count them also. + A subquery (and all the subsequent query blocks in a UNION) can + add columns to an outer query block. Reserve space for them. + Aggregate functions in having clause can also add fields to an + outer select. */ - lex->current_select->select_n_having_items+= - child->select_n_having_items; + for (SELECT_LEX *temp= child->master_unit()->first_select(); + temp != NULL; temp= temp->next_select()) + { + lex->current_select->select_n_where_fields+= + temp->select_n_where_fields; + lex->current_select->select_n_having_items+= + temp->select_n_having_items; + } } ; |