From a16e00a6c4bcb4308ce07e56438151a5ad135027 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 23 Aug 2012 16:29:41 +0200 Subject: [PATCH] Bug#14463247 ORDER BY SUBQUERY REFERENCING OUTER ALIAS FAILS Documentation for class Item_outer_ref was wrong: (*ref) may point to Item_field as well (see e.g. Item_outer_ref::fix_fields) So this casting in get_store_key() was wrong: (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() --- sql/item.h | 1 + sql/sql_select.cc | 38 ++++++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sql/item.h b/sql/item.h index bd43689e91b..71eb725e76e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2676,6 +2676,7 @@ public: resolved is a grouping one. After it has been fixed the ref field will point to either an Item_ref or an Item_direct_ref object which will be used to access the field. + The ref field may also point to an Item_field instance. See also comments for the fix_inner_refs() and the Item_field::fix_outer_field() functions. */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7169a834ff7..808af9d69ab 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6019,19 +6019,33 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, key_part->length, keyuse->val); } - else if (keyuse->val->type() == Item::FIELD_ITEM || - (keyuse->val->type() == Item::REF_ITEM && - ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF && - (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() == - Item_ref::DIRECT_REF && - keyuse->val->real_item()->type() == Item::FIELD_ITEM)) + + Item_field *field_item= NULL; + if (keyuse->val->type() == Item::FIELD_ITEM) + field_item= static_cast(keyuse->val->real_item()); + else if (keyuse->val->type() == Item::REF_ITEM) + { + Item_ref *item_ref= static_cast(keyuse->val); + if (item_ref->ref_type() == Item_ref::OUTER_REF) + { + if ((*item_ref->ref)->type() == Item::FIELD_ITEM) + field_item= static_cast(item_ref->real_item()); + else if ((*(Item_ref**)(item_ref)->ref)->ref_type() + == Item_ref::DIRECT_REF + && + item_ref->real_item()->type() == Item::FIELD_ITEM) + field_item= static_cast(item_ref->real_item()); + } + } + if (field_item) return new store_key_field(thd, - key_part->field, - key_buff + maybe_null, - maybe_null ? key_buff : 0, - key_part->length, - ((Item_field*) keyuse->val->real_item())->field, - keyuse->val->full_name()); + key_part->field, + key_buff + maybe_null, + maybe_null ? key_buff : 0, + key_part->length, + field_item->field, + keyuse->val->full_name()); + return new store_key_item(thd, key_part->field, key_buff + maybe_null,