1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Final solution for bug# 4302 "Ambiguos order by when renamed column is

identical to another in result"
According to SQL standard queries like 
"select t1.a as col from t1, t2 order by a" should return an error if
both tables contain field a.


mysql-test/r/order_by.result:
  Updated test to conform SQL-standard.
mysql-test/t/order_by.test:
  Updated test to conform SQL-standard.
sql/item.cc:
  find_item_in_list() has now one more out parameter which is not used
  in item.cc functions.
sql/mysql_priv.h:
  find_item_in_list(): Added boolean out parameter "unaliased" which
  indicates that we have found field by its original name and not by
  its alias in item (select) list.
sql/sql_base.cc:
  find_item_in_list(): Added boolean out parameter "unaliased" which
  indicates that we have found field by its original name and not by
  its alias in item (select) list. This means that additional check is
  required to ensure there will be no ambiguity if we would search for this
  field in all tables.
sql/sql_select.cc:
  find_order_in_list(): If we have found field in select list by its
  original name and not by its alias then we should perform additional
  check to ensure that there will be no ambiguity if we will search for
  this field in all tables. Also small cleanup.
This commit is contained in:
unknown
2004-09-30 16:28:17 +04:00
parent ccf52b4fd5
commit 53edc92cd0
6 changed files with 62 additions and 40 deletions

View File

@@ -7946,15 +7946,14 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
TABLE_LIST *tables,ORDER *order, List<Item> &fields,
List<Item> &all_fields)
{
Item *itemptr=*order->item;
if (itemptr->type() == Item::INT_ITEM)
Item *it= *order->item;
if (it->type() == Item::INT_ITEM)
{ /* Order by position */
uint count= (uint) itemptr->val_int();
uint count= (uint) it->val_int();
if (!count || count > fields.elements)
{
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),
MYF(0),itemptr->full_name(),
thd->where);
MYF(0), it->full_name(), thd->where);
return 1;
}
order->item= ref_pointer_array + count-1;
@@ -7962,20 +7961,28 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
return 0;
}
uint counter;
Item **item= find_item_in_list(itemptr, fields, &counter,
REPORT_EXCEPT_NOT_FOUND);
bool unaliased;
Item **item= find_item_in_list(it, fields, &counter,
REPORT_EXCEPT_NOT_FOUND, &unaliased);
if (!item)
return 1;
if (item != (Item **)not_found_item)
{
/*
If we have found field not by its alias in select list but by its
original field name, we should additionaly check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
if (unaliased && !it->fixed && it->fix_fields(thd, tables, order->item))
return 1;
order->item= ref_pointer_array + counter;
order->in_field_list=1;
return 0;
}
order->in_field_list=0;
Item *it= *order->item;
/*
We check it->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called.
@@ -8104,10 +8111,11 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd->set_query_id=1; // Not really needed, but...
uint counter;
bool not_used;
for (; new_field ; new_field= new_field->next)
{
if ((item= find_item_in_list(*new_field->item, fields, &counter,
IGNORE_ERRORS)))
IGNORE_ERRORS, &not_used)))
new_field->item=item; /* Change to shared Item */
else
{