diff options
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r-- | sql/sql_union.cc | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 6ab2619e8e2..41f4234c13d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -68,7 +68,7 @@ void select_unit::change_select() curr_sel= current_select_number; /* New SELECT processing starts */ DBUG_ASSERT(table->file->inited == 0); - step= thd->lex->current_select->linkage; + step= thd->lex->current_select->get_linkage(); switch (step) { case INTERSECT_TYPE: @@ -248,7 +248,7 @@ bool select_unit::send_eof() { if (step != INTERSECT_TYPE || (thd->lex->current_select->next_select() && - thd->lex->current_select->next_select()->linkage == INTERSECT_TYPE)) + thd->lex->current_select->next_select()->get_linkage() == INTERSECT_TYPE)) { /* it is not INTESECT or next SELECT in the sequence is INTERSECT so no @@ -753,11 +753,11 @@ bool st_select_lex_unit::join_union_type_attributes(THD *thd_arg, been fixed yet. An Item_type_holder must be created based on a fixed Item, so use the inner Item instead. */ - DBUG_ASSERT(item_tmp->fixed || + DBUG_ASSERT(item_tmp->is_fixed() || (item_tmp->type() == Item::REF_ITEM && ((Item_ref *)(item_tmp))->ref_type() == Item_ref::OUTER_REF)); - if (!item_tmp->fixed) + if (!item_tmp->is_fixed()) item_tmp= item_tmp->real_item(); holders[holder_pos].add_argument(item_tmp); } @@ -982,7 +982,24 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, types= first_sl->item_list; goto cont; } - + + if (sl->tvc && sl->order_list.elements && + !sl->tvc->to_be_wrapped_as_with_tail()) + { + if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) + { + sl->master_unit()->fake_select_lex= 0; + sl->master_unit()->saved_fake_select_lex= 0; + } + else + { + sl->order_list.empty(); + sl->explicit_limit= 0; + sl->select_limit= 0; + sl->offset_limit= 0; + } + } + for (;sl; sl= sl->next_select(), union_part_count++) { if (sl->tvc) @@ -1102,12 +1119,12 @@ cont: while ((type= tp++)) { - if (type->cmp_type() == STRING_RESULT && - type->collation.derivation == DERIVATION_NONE) - { - my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION"); + /* + Test if the aggregated data type is OK for a UNION element. + E.g. in case of string data, DERIVATION_NONE is not allowed. + */ + if (type->type_handler()->union_element_finalize(type)) goto err; - } } /* @@ -1449,7 +1466,7 @@ bool st_select_lex_unit::exec() union_result->change_select(); if (fake_select_lex) { - if (sl != &thd->lex->select_lex) + if (sl != thd->lex->first_select_lex()) fake_select_lex->uncacheable|= sl->uncacheable; else fake_select_lex->uncacheable= 0; |