diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dccad7ac011..87459a4441b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014 Oracle and/or its affiliates. +/* Copyright (c) 2000, 2015 Oracle and/or its affiliates. Copyright (c) 2009, 2015 MariaDB This program is free software; you can redistribute it and/or modify @@ -709,9 +709,7 @@ JOIN::prepare(Item ***rref_pointer_array, if (!(select_options & OPTION_SETUP_TABLES_DONE) && setup_tables_and_check_access(thd, &select_lex->context, join_list, tables_list, select_lex->leaf_tables, - FALSE, SELECT_ACL, SELECT_ACL, - (thd->lex->sql_command == - SQLCOM_UPDATE_MULTI))) + FALSE, SELECT_ACL, SELECT_ACL, FALSE)) DBUG_RETURN(-1); /* @@ -6493,7 +6491,6 @@ choose_plan(JOIN *join, table_map join_tables) DBUG_ENTER("choose_plan"); join->cur_embedding_map= 0; - join->cur_dups_producing_tables= 0; reset_nj_counters(join, join->join_list); qsort2_cmp jtab_sort_func; @@ -21435,18 +21432,33 @@ SORT_FIELD *make_unireg_sortorder(THD *thd, ORDER *order, uint *length, for (;order;order=order->next,pos++) { - Item *item= order->item[0]->real_item(); + Item *const item= order->item[0], *const real_item= item->real_item(); pos->field= 0; pos->item= 0; - if (item->type() == Item::FIELD_ITEM) - pos->field= ((Item_field*) item)->field; - else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item()) - pos->field= ((Item_sum*) item)->get_tmp_table_field(); - else if (item->type() == Item::COPY_STR_ITEM) - { // Blob patch - pos->item= ((Item_copy*) item)->get_item(); + if (real_item->type() == Item::FIELD_ITEM) + { + // Could be a field, or Item_direct_view_ref wrapping a field + DBUG_ASSERT(item->type() == Item::FIELD_ITEM || + (item->type() == Item::REF_ITEM && + static_cast<Item_ref*>(item)->ref_type() == + Item_ref::VIEW_REF)); + pos->field= static_cast<Item_field*>(real_item)->field; + } + else if (real_item->type() == Item::SUM_FUNC_ITEM && + !real_item->const_item()) + { + // Aggregate, or Item_aggregate_ref + DBUG_ASSERT(item->type() == Item::SUM_FUNC_ITEM || + (item->type() == Item::REF_ITEM && + static_cast<Item_ref*>(item)->ref_type() == + Item_ref::AGGREGATE_REF)); + pos->field= item->get_tmp_table_field(); + } + else if (real_item->type() == Item::COPY_STR_ITEM) + { // Blob patch + pos->item= static_cast<Item_copy*>(real_item)->get_item(); } else - pos->item= *order->item; + pos->item= item; pos->reverse=! order->asc; DBUG_ASSERT(pos->field != NULL || pos->item != NULL); } @@ -21690,6 +21702,17 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, uint el= all_fields.elements; all_fields.push_front(order_item); /* Add new field to field list. */ ref_pointer_array[el]= order_item; + /* + If the order_item is a SUM_FUNC_ITEM, when fix_fields is called + ref_by is set to order->item which is the address of order_item. + But this needs to be address of order_item in the all_fields list. + As a result, when it gets replaced with Item_aggregate_ref + object in Item::split_sum_func2, we will be able to retrieve the + newly created object. + */ + if (order_item->type() == Item::SUM_FUNC_ITEM) + ((Item_sum *)order_item)->ref_by= all_fields.head_ref(); + order->item= ref_pointer_array + el; return FALSE; } |