From 6bfc2d4b895120378a26e24eaa1b732f103d7ae2 Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Sun, 9 Oct 2005 23:05:44 +0400 Subject: Fix bug#7672 Unknown column error in order clause When fixing Item_func_plus in ORDER BY clause field c is searched in all opened tables, but because c is an alias it wasn't found there. This patch adds a flag to select_lex which allows Item_field::fix_fields() to look up in select's item_list to find aliased fields. --- sql/item.cc | 11 +++++++++++ sql/sql_lex.cc | 1 + sql/sql_lex.h | 2 +- sql/sql_select.cc | 6 ++++++ 4 files changed, 19 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 8737cc06bbd..c3845db904c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -348,7 +348,18 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) { Field *tmp; if (!(tmp=find_field_in_tables(thd,this,tables))) + { + if (thd->lex.select_lex.is_item_list_lookup) + { + Item** res= find_item_in_list(this, thd->lex.select_lex.item_list); + if (res && *res && (*res)->type() == Item::FIELD_ITEM) + { + set_field((*((Item_field**)res))->field); + return 0; + } + } return 1; + } set_field(tmp); } else if (thd && thd->set_query_id && field->query_id != thd->query_id) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 20aacf42be0..9fb35e3f914 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -154,6 +154,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->slave_thd_opt=0; lex->sql_command=SQLCOM_END; bzero((char *)&lex->mi,sizeof(lex->mi)); + lex->select_lex.is_item_list_lookup= 0; return lex; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ab78555262f..d4b20c69bf2 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -121,7 +121,7 @@ typedef struct st_select_lex ignore_index, *ignore_index_ptr; List ftfunc_list; uint in_sum_expr, sort_default; - bool create_refs, braces; + bool create_refs, braces, is_item_list_lookup; st_select_lex *next; } SELECT_LEX; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 29c15741347..5292a1fc0e0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6845,8 +6845,14 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List &fields, return 0; } order->in_field_list=0; + /* Allow lookup in select's item_list to find aliased fields */ + thd->lex.select_lex.is_item_list_lookup= 1; if ((*order->item)->fix_fields(thd,tables) || thd->fatal_error) + { + thd->lex.select_lex.is_item_list_lookup= 0; return 1; // Wrong field + } + thd->lex.select_lex.is_item_list_lookup= 0; all_fields.push_front(*order->item); // Add new field to field list order->item=(Item**) all_fields.head_ref(); return 0; -- cgit v1.2.1 From 551961b2079802afcbc703d340a58e71902a3bcf Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Thu, 13 Oct 2005 00:58:59 +0400 Subject: select.test, sql_select.cc, sql_lex.cc, item.cc: Bug #7672 after merge fix --- sql/item.cc | 11 ++++++++--- sql/sql_lex.cc | 3 ++- sql/sql_select.cc | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 3c3a6d273fe..8df839baa5c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1760,10 +1760,15 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if ((tmp= find_field_in_tables(thd, this, tables, &where, 0)) == not_found_field) { - if (thd->lex.select_lex.is_item_list_lookup) + /* Look up in current select's item_list to find aliased fields */ + if (thd->lex->current_select->is_item_list_lookup) { - Item** res= find_item_in_list(this, thd->lex.select_lex.item_list); - if (res && *res && (*res)->type() == Item::FIELD_ITEM) + uint counter; + bool not_used; + Item** res= find_item_in_list(this, thd->lex->current_select->item_list, + &counter, REPORT_EXCEPT_NOT_FOUND, + ¬_used); + if (res != not_found_item && (*res)->type() == Item::FIELD_ITEM) { set_field((*((Item_field**)res))->field); return 0; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 47de2ff36c7..16641ad6dd5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -160,7 +160,6 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->duplicates= DUP_ERROR; lex->ignore= 0; lex->proc_list.first= 0; - lex->select_lex.is_item_list_lookup= 0; } void lex_end(LEX *lex) @@ -1084,6 +1083,7 @@ void st_select_lex::init_query() prep_where= 0; subquery_in_having= explicit_limit= 0; parsing_place= NO_MATTER; + is_item_list_lookup= 0; } void st_select_lex::init_select() @@ -1110,6 +1110,7 @@ void st_select_lex::init_select() select_limit= HA_POS_ERROR; offset_limit= 0; with_sum_func= 0; + } /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0d9cab6a36b..f72d897e22d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8348,11 +8348,16 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, 'it' reassigned in if condition because fix_field can change it. */ + thd->lex->current_select->is_item_list_lookup= 1; if (!it->fixed && (it->fix_fields(thd, tables, order->item) || (it= *order->item)->check_cols(1) || thd->is_fatal_error)) + { + thd->lex->current_select->is_item_list_lookup= 0; return 1; // Wrong field + } + thd->lex->current_select->is_item_list_lookup= 0; uint el= all_fields.elements; all_fields.push_front(it); // Add new field to field list ref_pointer_array[el]= it; -- cgit v1.2.1