mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
WL#1972 "Evaluate HAVING before SELECT select-list"
- Changed name resolution for GROUP BY so that derived columns do not shadow table columns from the FROM clause. As a result GROUP BY now is handled as a true ANSI extentsion. - Issue a warning when HAVING is resolved into ambiguous columns, and prefer the columns from the GROUP BY clause over SELECT columns. mysql-test/r/having.result: Correct result for updated GROUP BY name resolution. sql/item.cc: - prefer GROUP columns, but if none is found use SELECT list - issue a waring when a field may be resolved ambiguously - more/fixed comments sql/mysql_priv.h: More flexible find_field_in_tables(). sql/sp.cc: More flexible find_field_in_tables(). sql/sql_base.cc: More flexible find_field_in_tables(). sql/sql_help.cc: More flexible find_field_in_tables(). sql/sql_select.cc: - name resolution of GROUP/ORDER BY column references is differentiated: - GROUP BY is resolved in SELECT and FROM clauses - ORDER BY is resolved only in SELECT (as before) - more informative variable names - more comments
This commit is contained in:
parent
637c08d7cc
commit
048d731a31
7 changed files with 171 additions and 75 deletions
|
@ -221,6 +221,9 @@ select count(*) from wl1972 group by s1 having s1 is null;
|
|||
count(*)
|
||||
select s1*0 as s1 from wl1972 group by s1 having s1 <> 0;
|
||||
s1
|
||||
0
|
||||
0
|
||||
0
|
||||
select s1*0 from wl1972 group by s1 having s1 = 0;
|
||||
s1*0
|
||||
select s1 from wl1972 group by 1 having 1 = 0;
|
||||
|
|
69
sql/item.cc
69
sql/item.cc
|
@ -1397,7 +1397,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
{
|
||||
bool upward_lookup= 0;
|
||||
Field *tmp= (Field *)not_found_field;
|
||||
if ((tmp= find_field_in_tables(thd, this, tables, ref, 0,
|
||||
if ((tmp= find_field_in_tables(thd, this, tables, ref,
|
||||
IGNORE_EXCEPT_NON_UNIQUE,
|
||||
!any_privileges)) ==
|
||||
not_found_field)
|
||||
{
|
||||
|
@ -1449,7 +1450,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
(sl->with_sum_func == 0 && sl->group_list.elements == 0)) &&
|
||||
(tmp= find_field_in_tables(thd, this,
|
||||
table_list, ref,
|
||||
0, 1)) != not_found_field)
|
||||
IGNORE_EXCEPT_NON_UNIQUE, 1)) !=
|
||||
not_found_field)
|
||||
{
|
||||
if (tmp)
|
||||
{
|
||||
|
@ -1505,7 +1507,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
else
|
||||
{
|
||||
// Call to report error
|
||||
find_field_in_tables(thd, this, tables, ref, 1, 1);
|
||||
find_field_in_tables(thd, this, tables, ref, REPORT_ALL_ERRORS, 1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -2347,31 +2349,39 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
|
|||
|
||||
SYNOPSIS
|
||||
Item_ref::fix_fields()
|
||||
thd [in] Current thread
|
||||
tables [in] The tables in the FROM clause
|
||||
reference [in/out] View column if this item was resolved to a view column
|
||||
thd [in] current thread
|
||||
tables [in] the tables in the FROM clause
|
||||
reference [in/out] view column if this item was resolved to a view column
|
||||
|
||||
DESCRIPTION
|
||||
The method resolves the column reference represented by this as an Item
|
||||
present in either of: GROUP BY clause, SELECT clause, outer queries. It is
|
||||
The method resolves the column reference represented by 'this' as a column
|
||||
present in one of: GROUP BY clause, SELECT clause, outer queries. It is
|
||||
used for columns in the HAVING clause which are not under aggregate
|
||||
functions.
|
||||
|
||||
NOTES
|
||||
The general idea behind the name resolution algorithm is that it searches
|
||||
both the SELECT and GROUP BY clauses, and in case of a name conflict
|
||||
prefers GROUP BY column names over SELECT names. We extend ANSI SQL in that
|
||||
when no GROUP BY column is found, then a HAVING name is resolved as a
|
||||
possibly derived SELECT column.
|
||||
|
||||
The name resolution algorithm used is:
|
||||
|
||||
resolve_extended([T_j].col_ref_i)
|
||||
{
|
||||
Search for a column named col_ref_i [in table T_j]
|
||||
in the GROUP BY clause of Q.
|
||||
|
||||
Search for a column or derived column named col_ref_i [in table T_j]
|
||||
in the SELECT list of Q.
|
||||
|
||||
if found different columns with the same name in GROUP BY and SELECT
|
||||
issue an error.
|
||||
Search for a column named col_ref_i [in table T_j]
|
||||
in the GROUP BY clause of Q.
|
||||
|
||||
// Lookup in outer queries.
|
||||
if such a column is NOT found AND there are outer queries
|
||||
If found different columns with the same name in GROUP BY and SELECT
|
||||
issue a warning and return the GROUP BY column,
|
||||
otherwise return the found SELECT column.
|
||||
|
||||
if such a column is NOT found AND // Lookup in outer queries.
|
||||
there are outer queries
|
||||
{
|
||||
for each outer query Q_k beginning from the inner-most one
|
||||
{
|
||||
|
@ -2385,8 +2395,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
|
|||
}
|
||||
}
|
||||
}
|
||||
This procedure treats GROUP BY and SELECT as one namespace for column
|
||||
references in HAVING.
|
||||
|
||||
This procedure treats GROUP BY and SELECT clauses as one namespace for
|
||||
column references in HAVING.
|
||||
|
||||
RETURN
|
||||
TRUE if error
|
||||
|
@ -2398,9 +2409,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
DBUG_ASSERT(fixed == 0);
|
||||
uint counter;
|
||||
SELECT_LEX *current_sel= thd->lex->current_select;
|
||||
List<Item> *search_namespace= current_sel->get_item_list();
|
||||
List<Item> *select_fields= current_sel->get_item_list();
|
||||
bool is_having_field= current_sel->having_fix_field;
|
||||
Item **group_by_ref= NULL;
|
||||
bool ambiguous_fields= FALSE;
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
|
@ -2413,7 +2425,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
Search for a column or derived column named as 'this' in the SELECT
|
||||
clause of current_select.
|
||||
*/
|
||||
if (!(ref= find_item_in_list(this, *search_namespace, &counter,
|
||||
if (!(ref= find_item_in_list(this, *select_fields, &counter,
|
||||
REPORT_EXCEPT_NOT_FOUND)))
|
||||
return TRUE; /* Some error occurred. */
|
||||
|
||||
|
@ -2422,20 +2434,22 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
{
|
||||
group_by_ref= find_field_in_group_list(this, (ORDER*)
|
||||
current_sel->group_list.first);
|
||||
|
||||
/* Check if the fields found in SELECT and GROUP BY are the same field. */
|
||||
if (group_by_ref && ref != (Item **) not_found_item &&
|
||||
!((*group_by_ref)->eq(*ref, 0)))
|
||||
{
|
||||
my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR),
|
||||
MYF(0), this->full_name(), current_thd->where);
|
||||
return TRUE;
|
||||
ambiguous_fields= TRUE;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR),
|
||||
this->full_name(), current_thd->where);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If we didn't find such a column in the current query, and if there is an
|
||||
outer select, and this is not a derived table (which do not support the
|
||||
outer select, and it is not a derived table (which do not support the
|
||||
use of outer fields for now), search the outer select(s) for a column
|
||||
named as 'this'.
|
||||
*/
|
||||
|
@ -2494,7 +2508,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
outer_sel->group_list.elements == 0)) &&
|
||||
(tmp= find_field_in_tables(thd, this,
|
||||
table_list, reference,
|
||||
0, 1)) != not_found_field)
|
||||
IGNORE_EXCEPT_NON_UNIQUE, TRUE)) !=
|
||||
not_found_field)
|
||||
{
|
||||
if (tmp)
|
||||
{
|
||||
|
@ -2538,7 +2553,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
else
|
||||
{
|
||||
// Call to report error
|
||||
find_item_in_list(this, *search_namespace, &counter,
|
||||
find_item_in_list(this, *select_fields, &counter,
|
||||
REPORT_ALL_ERRORS);
|
||||
}
|
||||
ref= 0;
|
||||
|
@ -2588,7 +2603,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ref != (Item **) not_found_item)
|
||||
if (ref != (Item **) not_found_item && !ambiguous_fields)
|
||||
ref= current_sel->ref_pointer_array + counter;
|
||||
else if (group_by_ref)
|
||||
ref= group_by_ref;
|
||||
|
|
|
@ -650,8 +650,13 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
|
|||
rw_lock_t *var_mutex);
|
||||
extern const Field *not_found_field;
|
||||
extern const Field *view_ref_found;
|
||||
|
||||
enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
|
||||
IGNORE_EXCEPT_NON_UNIQUE};
|
||||
Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
Item **ref, bool report_error,
|
||||
Item **ref,
|
||||
find_item_error_report_type report_error,
|
||||
bool check_privileges);
|
||||
Field *
|
||||
find_field_in_table(THD *thd, TABLE_LIST *table_list,
|
||||
|
@ -765,8 +770,6 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
|
|||
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||
table_map read_tables, COND *conds, int *error,
|
||||
bool allow_null_cond= false);
|
||||
enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_ERRORS};
|
||||
extern const Item **not_found_item;
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
|
||||
find_item_error_report_type report_error);
|
||||
|
|
|
@ -615,7 +615,7 @@ db_show_routine_status(THD *thd, int type, const char *wild)
|
|||
Item_field *field= new Item_field("mysql", "proc",
|
||||
used_field->field_name);
|
||||
if (!(used_field->field= find_field_in_tables(thd, field, &tables,
|
||||
0, TRUE, 1)))
|
||||
0, REPORT_ALL_ERRORS, 1)))
|
||||
{
|
||||
res= SP_INTERNAL_ERROR;
|
||||
goto err_case1;
|
||||
|
|
|
@ -2173,25 +2173,33 @@ Field *find_field_in_real_table(THD *thd, TABLE *table,
|
|||
find_field_in_tables()
|
||||
thd Pointer to current thread structure
|
||||
item Field item that should be found
|
||||
tables Tables for scanning
|
||||
ref if view field is found, pointer to view item will
|
||||
be returned via this parameter
|
||||
report_error If FALSE then do not report error if item not found
|
||||
and return not_found_field
|
||||
tables Tables to be searched for item
|
||||
ref If 'item' is resolved to a view field, ref is set to
|
||||
point to the found view field
|
||||
report_error Degree of error reporting:
|
||||
- IGNORE_ERRORS then do not report any error
|
||||
- IGNORE_EXCEPT_NON_UNIQUE report only non-unique
|
||||
fields, suppress all other errors
|
||||
- REPORT_EXCEPT_NON_UNIQUE report all other errors
|
||||
except when non-unique fields were found
|
||||
- REPORT_ALL_ERRORS
|
||||
check_privileges need to check privileges
|
||||
|
||||
RETURN VALUES
|
||||
0 Field is not found or field is not unique- error
|
||||
message is reported
|
||||
not_found_field Function was called with report_error == FALSE and
|
||||
field was not found. no error message reported.
|
||||
view_ref_found view field is found, item passed through ref parameter
|
||||
found field
|
||||
0 No field was found, or the found field is not unique, or
|
||||
there are no sufficient access priviligaes for the
|
||||
found field, or the field is qualified with non-existing
|
||||
table.
|
||||
not_found_field The function was called with report_error ==
|
||||
(IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a
|
||||
field was not found.
|
||||
view_ref_found View field is found, item passed through ref parameter
|
||||
found field If a item was resolved to some field
|
||||
*/
|
||||
|
||||
Field *
|
||||
find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
Item **ref, bool report_error,
|
||||
Item **ref, find_item_error_report_type report_error,
|
||||
bool check_privileges)
|
||||
{
|
||||
Field *found=0;
|
||||
|
@ -2268,8 +2276,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
return find;
|
||||
if (found)
|
||||
{
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
item->full_name(),thd->where);
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == IGNORE_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
item->full_name(),thd->where);
|
||||
return (Field*) 0;
|
||||
}
|
||||
found=find;
|
||||
|
@ -2278,7 +2288,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
}
|
||||
if (found)
|
||||
return found;
|
||||
if (!found_table && report_error)
|
||||
if (!found_table && (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == REPORT_EXCEPT_NON_UNIQUE))
|
||||
{
|
||||
char buff[NAME_LEN*2+1];
|
||||
if (db && db[0])
|
||||
|
@ -2286,28 +2297,30 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
|
||||
table_name=buff;
|
||||
}
|
||||
if (report_error)
|
||||
{
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
|
||||
table_name, thd->where);
|
||||
}
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
}
|
||||
else
|
||||
if (report_error)
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
||||
item->full_name(),thd->where);
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
return (Field*) 0;
|
||||
}
|
||||
|
||||
bool allow_rowid= tables && !tables->next_local; // Only one table
|
||||
for (; tables ; tables= tables->next_local)
|
||||
{
|
||||
if (!tables->table)
|
||||
{
|
||||
if (report_error)
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
||||
item->full_name(),thd->where);
|
||||
return (Field*) not_found_field;
|
||||
|
@ -2332,8 +2345,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
{
|
||||
if (!thd->where) // Returns first found
|
||||
break;
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
name,thd->where);
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == IGNORE_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
|
||||
name,thd->where);
|
||||
return (Field*) 0;
|
||||
}
|
||||
found=field;
|
||||
|
@ -2341,7 +2356,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
}
|
||||
if (found)
|
||||
return found;
|
||||
if (report_error)
|
||||
if (report_error == REPORT_ALL_ERRORS ||
|
||||
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
||||
my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR),
|
||||
MYF(0), item->full_name(), thd->where);
|
||||
else
|
||||
|
@ -2377,7 +2393,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
found field
|
||||
*/
|
||||
|
||||
// Special Item pointer for find_item_in_list returning
|
||||
/* Special Item pointer to serve as a return value from find_item_in_list(). */
|
||||
const Item **not_found_item= (const Item**) 0x1;
|
||||
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
|
|||
Item_field *field= new Item_field("mysql", find_fields->table_name,
|
||||
find_fields->field_name);
|
||||
if (!(find_fields->field= find_field_in_tables(thd, field, tables,
|
||||
0, TRUE, 1)))
|
||||
0, REPORT_ALL_ERRORS, 1)))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -11115,24 +11115,53 @@ cp_buffer_from_ref(TABLE_REF *ref)
|
|||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Find order/group item in requested columns and change the item to point at
|
||||
it. If item doesn't exists, add it first in the field list
|
||||
Return 0 if ok.
|
||||
Resolve an ORDER BY or GROUP BY column reference.
|
||||
|
||||
SYNOPSIS
|
||||
find_order_in_list()
|
||||
thd [in] Pointer to current thread structure
|
||||
ref_pointer_array [in/out] All select, group and order by fields
|
||||
tables [in] List of tables to search in (usually FROM clause)
|
||||
order [in] Column reference to be resolved
|
||||
fields [in] List of fields to search in (usually SELECT list)
|
||||
all_fields [in/out] All select, group and order by fields
|
||||
is_group_field [in] True if order is a GROUP field, false if
|
||||
ORDER by field
|
||||
|
||||
DESCRIPTION
|
||||
Given a column reference (represented by 'order') from a GROUP BY or ORDER
|
||||
BY clause, find the actual column it represents. If the column being
|
||||
resolved is from the GROUP BY clause, the procedure searches the SELECT
|
||||
list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
|
||||
the ORDER BY clause, only the SELECT list is being searched.
|
||||
|
||||
If 'order' is resolved to an Item, then order->item is set to the found
|
||||
Item. If there is no item for the found column (that is, it was resolved
|
||||
into a table field), order->item is 'fixed' and is added to all_fields and
|
||||
ref_pointer_array.
|
||||
|
||||
RETURN
|
||||
0 if ok
|
||||
1 if error occurred
|
||||
*/
|
||||
|
||||
static int
|
||||
find_order_in_list(THD *thd, Item **ref_pointer_array,
|
||||
TABLE_LIST *tables,ORDER *order, List<Item> &fields,
|
||||
List<Item> &all_fields)
|
||||
find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
ORDER *order, List<Item> &fields, List<Item> &all_fields,
|
||||
bool is_group_field)
|
||||
{
|
||||
Item *itemptr=*order->item;
|
||||
if (itemptr->type() == Item::INT_ITEM)
|
||||
Item *order_item=*order->item; /* The item from the GROUP/ORDER caluse. */
|
||||
Item::Type order_item_type;
|
||||
Item **select_item; /* The corresponding item from the SELECT clause. */
|
||||
Field *from_field; /* The corresponding field from the FROM clause. */
|
||||
|
||||
if (order_item->type() == Item::INT_ITEM)
|
||||
{ /* Order by position */
|
||||
uint count= (uint) itemptr->val_int();
|
||||
uint count= (uint) order_item->val_int();
|
||||
if (!count || count > fields.elements)
|
||||
{
|
||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),
|
||||
MYF(0),itemptr->full_name(),
|
||||
MYF(0),order_item->full_name(),
|
||||
thd->where);
|
||||
return 1;
|
||||
}
|
||||
|
@ -11142,17 +11171,47 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
|
|||
order->counter_used= 1;
|
||||
return 0;
|
||||
}
|
||||
/* Lookup the current GROUP/ORDER field in the SELECT clause. */
|
||||
uint counter;
|
||||
Item **item= find_item_in_list(itemptr, fields, &counter,
|
||||
select_item= find_item_in_list(order_item, fields, &counter,
|
||||
REPORT_EXCEPT_NOT_FOUND);
|
||||
if (!item)
|
||||
return 1;
|
||||
if (!select_item)
|
||||
return 1; /* Some error occured. */
|
||||
|
||||
if (item != (Item **)not_found_item)
|
||||
|
||||
/* Check whether the resolved field is not ambiguos. */
|
||||
if (select_item != not_found_item)
|
||||
{
|
||||
order->item= ref_pointer_array + counter;
|
||||
order->in_field_list=1;
|
||||
return 0;
|
||||
/* Lookup the current GROUP field in the FROM clause. */
|
||||
order_item_type= order_item->type();
|
||||
if (is_group_field &&
|
||||
order_item_type == Item::FIELD_ITEM || order_item_type == Item::REF_ITEM)
|
||||
{
|
||||
Item **view_ref= NULL;
|
||||
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
||||
view_ref, IGNORE_ERRORS, TRUE);
|
||||
if(!from_field)
|
||||
from_field= (Field*) not_found_field;
|
||||
}
|
||||
else
|
||||
from_field= (Field*) not_found_field;
|
||||
|
||||
if (from_field == not_found_field ||
|
||||
from_field && from_field != view_ref_found &&
|
||||
(*select_item)->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) (*select_item))->field->eq(from_field))
|
||||
/*
|
||||
If there is no such field in the FROM clause, or it is the same field as
|
||||
the one found in the SELECT clause, then use the Item created for the
|
||||
SELECT field. As a result if there was a derived field that 'shadowed'
|
||||
a table field with the same name, the table field will be chosen over
|
||||
the derived field.
|
||||
*/
|
||||
{
|
||||
order->item= ref_pointer_array + counter;
|
||||
order->in_field_list=1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
order->in_field_list=0;
|
||||
|
@ -11187,7 +11246,7 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
for (; order; order=order->next)
|
||||
{
|
||||
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
|
||||
all_fields))
|
||||
all_fields, FALSE))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -11239,7 +11298,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
for (; order; order=order->next)
|
||||
{
|
||||
if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
|
||||
all_fields))
|
||||
all_fields, TRUE))
|
||||
return 1;
|
||||
(*order->item)->marker=1; /* Mark found */
|
||||
if ((*order->item)->with_sum_func)
|
||||
|
|
Loading…
Reference in a new issue