|
|
|
@ -189,6 +189,7 @@ static bool setup_new_fields(THD *thd, List<Item> &fields, |
|
|
|
List<Item> &all_fields, ORDER *new_order); |
|
|
|
static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array, |
|
|
|
ORDER *order, List<Item> &fields, |
|
|
|
List<Item> &all_fields, |
|
|
|
bool *all_order_by_fields_used); |
|
|
|
static bool test_if_subpart(ORDER *a,ORDER *b); |
|
|
|
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables); |
|
|
|
@ -537,6 +538,28 @@ JOIN::prepare(Item ***rref_pointer_array, |
|
|
|
fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array)) |
|
|
|
DBUG_RETURN(-1); |
|
|
|
|
|
|
|
if (group_list) |
|
|
|
{ |
|
|
|
/*
|
|
|
|
Because HEAP tables can't index BIT fields we need to use an |
|
|
|
additional hidden field for grouping because later it will be |
|
|
|
converted to a LONG field. Original field will remain of the |
|
|
|
BIT type and will be returned to a client. |
|
|
|
*/ |
|
|
|
for (ORDER *ord= group_list; ord; ord= ord->next) |
|
|
|
{ |
|
|
|
if ((*ord->item)->type() == Item::FIELD_ITEM && |
|
|
|
(*ord->item)->field_type() == MYSQL_TYPE_BIT) |
|
|
|
{ |
|
|
|
Item_field *field= new Item_field(thd, *(Item_field**)ord->item); |
|
|
|
int el= all_fields.elements; |
|
|
|
ref_pointer_array[el]= field; |
|
|
|
all_fields.push_front(field); |
|
|
|
ord->item= ref_pointer_array + el; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ |
|
|
|
DBUG_RETURN(-1); |
|
|
|
|
|
|
|
@ -1068,12 +1091,13 @@ JOIN::optimize() |
|
|
|
if (order) |
|
|
|
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1); |
|
|
|
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array, |
|
|
|
order, fields_list, |
|
|
|
order, fields_list, all_fields, |
|
|
|
&all_order_fields_used))) |
|
|
|
{ |
|
|
|
bool skip_group= (skip_sort_order && |
|
|
|
test_if_skip_sort_order(tab, group_list, select_limit, |
|
|
|
1) != 0); |
|
|
|
count_field_types(select_lex, &tmp_table_param, all_fields, 0); |
|
|
|
if ((skip_group && all_order_fields_used) || |
|
|
|
select_limit == HA_POS_ERROR || |
|
|
|
(order && !skip_sort_order)) |
|
|
|
@ -13629,11 +13653,12 @@ setup_new_fields(THD *thd, List<Item> &fields, |
|
|
|
|
|
|
|
static ORDER * |
|
|
|
create_distinct_group(THD *thd, Item **ref_pointer_array, |
|
|
|
ORDER *order_list, List<Item> &fields, |
|
|
|
ORDER *order_list, List<Item> &fields, |
|
|
|
List<Item> &all_fields, |
|
|
|
bool *all_order_by_fields_used) |
|
|
|
{ |
|
|
|
List_iterator<Item> li(fields); |
|
|
|
Item *item; |
|
|
|
Item *item, **orig_ref_pointer_array= ref_pointer_array; |
|
|
|
ORDER *order,*group,**prev; |
|
|
|
|
|
|
|
*all_order_by_fields_used= 1; |
|
|
|
@ -13673,12 +13698,31 @@ create_distinct_group(THD *thd, Item **ref_pointer_array, |
|
|
|
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); |
|
|
|
if (!ord) |
|
|
|
return 0; |
|
|
|
/*
|
|
|
|
We have here only field_list (not all_field_list), so we can use |
|
|
|
simple indexing of ref_pointer_array (order in the array and in the |
|
|
|
list are same) |
|
|
|
*/ |
|
|
|
ord->item= ref_pointer_array; |
|
|
|
|
|
|
|
if (item->type() == Item::FIELD_ITEM && |
|
|
|
item->field_type() == MYSQL_TYPE_BIT) |
|
|
|
{ |
|
|
|
/*
|
|
|
|
Because HEAP tables can't index BIT fields we need to use an |
|
|
|
additional hidden field for grouping because later it will be |
|
|
|
converted to a LONG field. Original field will remain of the |
|
|
|
BIT type and will be returned to a client. |
|
|
|
*/ |
|
|
|
Item_field *new_item= new Item_field(thd, (Item_field*)item); |
|
|
|
int el= all_fields.elements; |
|
|
|
orig_ref_pointer_array[el]= new_item; |
|
|
|
all_fields.push_front(new_item); |
|
|
|
ord->item= orig_ref_pointer_array + el; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/*
|
|
|
|
We have here only field_list (not all_field_list), so we can use |
|
|
|
simple indexing of ref_pointer_array (order in the array and in the |
|
|
|
list are same) |
|
|
|
*/ |
|
|
|
ord->item= ref_pointer_array; |
|
|
|
} |
|
|
|
ord->asc=1; |
|
|
|
*prev=ord; |
|
|
|
prev= &ord->next; |
|
|
|
|