summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com>2018-10-09 12:03:35 +0530
committerSergei Golubchik <serg@mariadb.org>2019-01-23 12:39:17 +0100
commitb20d94da356fa274a49ac38497e0cb20ce760d93 (patch)
tree796c1b394f27b940828b3bc9f13f7cc718b137cc
parent6de2928d5bf912ace5fb5a1e2254025efe202b67 (diff)
downloadmariadb-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.
-rw-r--r--sql/sql_yacc.yy22
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;
+ }
}
;