summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorgkodinov/kgeorge@macbook.gmz <>2006-11-03 18:48:16 +0200
committergkodinov/kgeorge@macbook.gmz <>2006-11-03 18:48:16 +0200
commit77acba320d5d95bea1956e232d36cb438496a346 (patch)
tree4614f1b556b2ec706434fe02a59bb11d736c99f3 /sql/item.cc
parente1a7fb7b2cfa52b00fe26f5dc2d93227d268a560 (diff)
downloadmariadb-git-77acba320d5d95bea1956e232d36cb438496a346.tar.gz
Bug #22457: Column alias in ORDER BY works, but not if in an expression
The parser is allocating Item_field for references by name in ORDER BY expressions. Such expressions however may point not only to Item_field in the select list (or to a table column) but also to an arbitrary Item. This causes Item_field::fix_fields to throw an error about missing column. The fix substitutes Item_field for the reference with an Item_ref when not pointing to Item_field.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc33
1 files changed, 30 insertions, 3 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 94f0a24fcc3..45d7856b2c1 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1761,10 +1761,37 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND,
&not_used);
- if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM)
+ if (res != (Item **)not_found_item)
{
- set_field((*((Item_field**)res))->field);
- return 0;
+ if ((*res)->type() == Item::FIELD_ITEM)
+ {
+ /*
+ It's an Item_field referencing another Item_field in the select
+ list.
+ use the field from the Item_field in the select list and leave
+ the Item_field instance in place.
+ */
+ set_field((*((Item_field**)res))->field);
+ return 0;
+ }
+ else
+ {
+ /*
+ It's not an Item_field in the select list so we must make a new
+ Item_ref to point to the Item in the select list and replace the
+ Item_field created by the parser with the new Item_ref.
+ */
+ Item_ref *rf= new Item_ref(db_name,table_name,field_name);
+ if (!rf)
+ return 1;
+ thd->change_item_tree(ref, rf);
+ /*
+ Because Item_ref never substitutes itself with other items
+ in Item_ref::fix_fields(), we can safely use the original
+ pointer to it even after fix_fields()
+ */
+ return rf->fix_fields(thd, tables, ref) || rf->check_cols(1);
+ }
}
}