mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge macbook.gmz:/Users/kgeorge/mysql/work/mysql-5.0-opt
into macbook.gmz:/Users/kgeorge/mysql/work/merge-5.1-opt
This commit is contained in:
@ -8954,8 +8954,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
|
||||
if (type != Item::FIELD_ITEM &&
|
||||
item->real_item()->type() == Item::FIELD_ITEM &&
|
||||
(item->type() != Item::REF_ITEM ||
|
||||
!((Item_ref *) item)->depended_from))
|
||||
!((Item_ref *) item)->depended_from)
|
||||
{
|
||||
orig_item= item;
|
||||
item= item->real_item();
|
||||
@ -12499,7 +12498,7 @@ static int
|
||||
create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
ha_rows filesort_limit, ha_rows select_limit)
|
||||
{
|
||||
uint length;
|
||||
uint length= 0;
|
||||
ha_rows examined_rows;
|
||||
TABLE *table;
|
||||
SQL_SELECT *select;
|
||||
@ -12520,8 +12519,10 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
!(join->select_options & SELECT_BIG_RESULT)) &&
|
||||
test_if_skip_sort_order(tab,order,select_limit,0))
|
||||
DBUG_RETURN(0);
|
||||
for (ORDER *ord= join->order; ord; ord= ord->next)
|
||||
length++;
|
||||
if (!(join->sortorder=
|
||||
make_unireg_sortorder(order,&length,join->sortorder)))
|
||||
make_unireg_sortorder(order, &length, join->sortorder)))
|
||||
goto err; /* purecov: inspected */
|
||||
|
||||
table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
@ -12929,8 +12930,10 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
|
||||
for (ORDER *tmp = order; tmp; tmp=tmp->next)
|
||||
count++;
|
||||
if (!sortorder)
|
||||
sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD)*(count+1));
|
||||
pos=sort=sortorder;
|
||||
sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
|
||||
(max(count, *length) + 1));
|
||||
pos= sort= sortorder;
|
||||
|
||||
if (!pos)
|
||||
return 0;
|
||||
|
||||
@ -13458,49 +13461,83 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
bool *hidden_group_fields)
|
||||
{
|
||||
*hidden_group_fields=0;
|
||||
ORDER *ord;
|
||||
|
||||
if (!order)
|
||||
return 0; /* Everything is ok */
|
||||
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
{
|
||||
Item *item;
|
||||
List_iterator<Item> li(fields);
|
||||
while ((item=li++))
|
||||
item->marker=0; /* Marker that field is not used */
|
||||
}
|
||||
uint org_fields=all_fields.elements;
|
||||
|
||||
thd->where="group statement";
|
||||
for (; order; order=order->next)
|
||||
for (ord= order; ord; ord= ord->next)
|
||||
{
|
||||
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
|
||||
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
|
||||
all_fields, TRUE))
|
||||
return 1;
|
||||
(*order->item)->marker=1; /* Mark found */
|
||||
if ((*order->item)->with_sum_func)
|
||||
(*ord->item)->marker= UNDEF_POS; /* Mark found */
|
||||
if ((*ord->item)->with_sum_func)
|
||||
{
|
||||
my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*order->item)->full_name());
|
||||
my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
{
|
||||
/* Don't allow one to use fields that is not used in GROUP BY */
|
||||
Item *item;
|
||||
List_iterator<Item> li(fields);
|
||||
/*
|
||||
Don't allow one to use fields that is not used in GROUP BY
|
||||
For each select a list of field references that aren't under an
|
||||
aggregate function is created. Each field in this list keeps the
|
||||
position of the select list expression which it belongs to.
|
||||
|
||||
while ((item=li++))
|
||||
First we check an expression from the select list against the GROUP BY
|
||||
list. If it's found there then it's ok. It's also ok if this expression
|
||||
is a constant or an aggregate function. Otherwise we scan the list
|
||||
of non-aggregated fields and if we'll find at least one field reference
|
||||
that belongs to this expression and doesn't occur in the GROUP BY list
|
||||
we throw an error. If there are no fields in the created list for a
|
||||
select list expression this means that all fields in it are used under
|
||||
aggregate functions.
|
||||
*/
|
||||
Item *item;
|
||||
Item_field *field;
|
||||
int cur_pos_in_select_list= 0;
|
||||
List_iterator<Item> li(fields);
|
||||
List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
|
||||
|
||||
field= naf_it++;
|
||||
while (field && (item=li++))
|
||||
{
|
||||
if (item->type() != Item::SUM_FUNC_ITEM && !item->marker &&
|
||||
!item->const_item())
|
||||
if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 &&
|
||||
!item->const_item() &&
|
||||
!(item->real_item()->type() == Item::FIELD_ITEM &&
|
||||
item->used_tables() & OUTER_REF_TABLE_BIT))
|
||||
{
|
||||
/*
|
||||
TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
|
||||
ER_NON_GROUPING_FIELD_USED
|
||||
*/
|
||||
my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name());
|
||||
return 1;
|
||||
while (field)
|
||||
{
|
||||
/* Skip fields from previous expressions. */
|
||||
if (field->marker < cur_pos_in_select_list)
|
||||
goto next_field;
|
||||
/* Found a field from the next expression. */
|
||||
if (field->marker > cur_pos_in_select_list)
|
||||
break;
|
||||
/*
|
||||
Check whether the field occur in the GROUP BY list.
|
||||
Throw the error later if the field isn't found.
|
||||
*/
|
||||
for (ord= order; ord; ord= ord->next)
|
||||
if ((*ord->item)->eq((Item*)field, 0))
|
||||
goto next_field;
|
||||
/*
|
||||
TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
|
||||
ER_NON_GROUPING_FIELD_USED
|
||||
*/
|
||||
my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
|
||||
return 1;
|
||||
next_field:
|
||||
field= naf_it++;
|
||||
}
|
||||
}
|
||||
cur_pos_in_select_list++;
|
||||
}
|
||||
}
|
||||
if (org_fields != all_fields.elements)
|
||||
@ -13626,10 +13663,12 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||
param->quick_group=1;
|
||||
while ((field=li++))
|
||||
{
|
||||
Item::Type type=field->real_item()->type();
|
||||
if (type == Item::FIELD_ITEM)
|
||||
Item::Type type=field->type();
|
||||
Item::Type real_type= field->real_item()->type();
|
||||
if (type == Item::FIELD_ITEM || (real_type == Item::FIELD_ITEM &&
|
||||
!((Item_ref *) field)->depended_from))
|
||||
param->field_count++;
|
||||
else if (type == Item::SUM_FUNC_ITEM)
|
||||
else if (real_type == Item::SUM_FUNC_ITEM)
|
||||
{
|
||||
if (! field->const_item())
|
||||
{
|
||||
|
Reference in New Issue
Block a user