summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorunknown <holyfoot/hf@mysql.com/deer.(none)>2006-11-16 23:16:44 +0400
committerunknown <holyfoot/hf@mysql.com/deer.(none)>2006-11-16 23:16:44 +0400
commite971334eced6516f92ea5b63b06ac703e145192b (patch)
tree5400912843b70b171dc06c8cdc96a6f3329a25db /sql/item.cc
parentdaaddeb656c26c685962fef69d19e7f264620e2b (diff)
parente78fd1d14b7b151c4968702a28292d1d41b4f2ea (diff)
downloadmariadb-git-e971334eced6516f92ea5b63b06ac703e145192b.tar.gz
Merge mysql.com:/home/hf/work/mysql-4.1-mrg
into mysql.com:/home/hf/work/mysql-5.0-mrg client/mysqltest.c: Auto merged mysql-test/t/flush.test: Auto merged mysql-test/t/flush_block_commit.test: Auto merged mysql-test/t/innodb-deadlock.test: Auto merged mysql-test/t/innodb-lock.test: Auto merged mysql-test/t/lock_multi.test: Auto merged mysql-test/t/rename.test: Auto merged mysql-test/t/show_check.test: Auto merged mysql-test/t/status.test: Auto merged sql/item.cc: Auto merged sql/protocol.h: Auto merged sql-common/client.c: Auto merged Makefile.am: merging BitKeeper/deleted/.del-mysql_client.test: merging include/mysql.h: SCCS merged libmysql/libmysql.c: merging libmysqld/lib_sql.cc: merging mysql-test/r/order_by.result: SCCS merged mysql-test/r/subselect.result: SCCS merged mysql-test/t/order_by.test: merging mysql-test/t/subselect.test: SCCS merged sql/item_subselect.cc: merging sql/item_subselect.h: merging sql/protocol.cc: merging sql/sql_class.h: merging
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 f3081551299..3864ee966c4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3638,10 +3638,37 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
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);
+ }
}
}
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)