summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorTor Didriksen <tor.didriksen@oracle.com>2012-08-23 16:29:41 +0200
committerTor Didriksen <tor.didriksen@oracle.com>2012-08-23 16:29:41 +0200
commita16e00a6c4bcb4308ce07e56438151a5ad135027 (patch)
treed46deac2b4bbc9601a885fa4db8e7c448c7f8673 /sql
parent61f064eb6d69e4c5116ee1f7d56c67c5fad9477c (diff)
downloadmariadb-git-a16e00a6c4bcb4308ce07e56438151a5ad135027.tar.gz
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()
Diffstat (limited to 'sql')
-rw-r--r--sql/item.h1
-rw-r--r--sql/sql_select.cc38
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<Item_field*>(keyuse->val->real_item());
+ else if (keyuse->val->type() == Item::REF_ITEM)
+ {
+ Item_ref *item_ref= static_cast<Item_ref*>(keyuse->val);
+ if (item_ref->ref_type() == Item_ref::OUTER_REF)
+ {
+ if ((*item_ref->ref)->type() == Item::FIELD_ITEM)
+ field_item= static_cast<Item_field*>(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_field*>(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,