Commit 1cee49dd authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Reference to field in outer subelect fixed

Fixed context in error mesages
parent aa5983b4
...@@ -17,6 +17,16 @@ SELECT (SELECT 1),MAX(1) FROM (SELECT 1); ...@@ -17,6 +17,16 @@ SELECT (SELECT 1),MAX(1) FROM (SELECT 1);
1 1 1 1
SELECT (SELECT a) as a; SELECT (SELECT a) as a;
Reference 'a' not supported (forward reference in item list) Reference 'a' not supported (forward reference in item list)
EXPLAIN SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
3 DEPENDENT SUBSELECT No tables used
2 DERIVED No tables used
SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1;
1
1
SELECT (SELECT 1), a;
Unknown column 'a' in 'field list'
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
......
...@@ -8,6 +8,10 @@ SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVI ...@@ -8,6 +8,10 @@ SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVI
SELECT (SELECT 1),MAX(1) FROM (SELECT 1); SELECT (SELECT 1),MAX(1) FROM (SELECT 1);
-- error 1245 -- error 1245
SELECT (SELECT a) as a; SELECT (SELECT a) as a;
EXPLAIN SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1;
SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1;
-- error 1054
SELECT (SELECT 1), a;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
......
...@@ -468,7 +468,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -468,7 +468,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
(last= sl)->get_table_list(), (last= sl)->get_table_list(),
0)) != not_found_field) 0)) != not_found_field)
break; break;
if((refer= find_item_in_list(this, (last= sl)->item_list, if ((refer= find_item_in_list(this, sl->item_list,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **)not_found_item) (Item **)not_found_item)
break; break;
...@@ -867,6 +867,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -867,6 +867,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
REPORT_ALL_ERRORS))) == REPORT_ALL_ERRORS))) ==
(Item **)not_found_item) (Item **)not_found_item)
{ {
Field *tmp= (Field*) not_found_field;
/* /*
We can't find table field in table list of current select, We can't find table field in table list of current select,
consequently we have to find it in outer subselect(s). consequently we have to find it in outer subselect(s).
...@@ -878,16 +879,21 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -878,16 +879,21 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
*/ */
SELECT_LEX *last=0; SELECT_LEX *last=0;
for ( ; sl ; sl= sl->outer_select()) for ( ; sl ; sl= sl->outer_select())
if((ref= find_item_in_list(this, (last= sl)->item_list, {
if ((ref= find_item_in_list(this, (last= sl)->item_list,
REPORT_EXCEPT_NOT_FOUND)) != REPORT_EXCEPT_NOT_FOUND)) !=
(Item **)not_found_item) (Item **)not_found_item)
break; break;
if ((tmp= find_field_in_tables(thd, this,
sl->get_table_list(),
0)) != not_found_field);
}
if (!ref) if (!ref)
{
return 1; return 1;
} else if (!tmp)
else if (ref == (Item **)not_found_item) return -1;
else if (ref == (Item **)not_found_item && tmp == not_found_field)
{ {
// Call to report error // Call to report error
find_item_in_list(this, find_item_in_list(this,
...@@ -896,6 +902,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -896,6 +902,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
ref= 0; ref= 0;
return 1; return 1;
} }
else if (tmp != not_found_field)
{
ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item
Item_field* f;
if (!((*reference)= f= new Item_field(tmp)))
return 1;
f->depended_from= last;
thd->lex.current_select->mark_as_dependent(last);
return 0;
}
else else
{ {
depended_from= last; depended_from= last;
......
...@@ -81,6 +81,7 @@ void Item_subselect::make_field (Send_field *tmp_field) ...@@ -81,6 +81,7 @@ void Item_subselect::make_field (Send_field *tmp_field)
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
char const *save_where= thd->where;
int res= engine->prepare(); int res= engine->prepare();
if (!res) if (!res)
{ {
...@@ -93,6 +94,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -93,6 +94,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
fix_length_and_dec(); fix_length_and_dec();
} }
fixed= 1; fixed= 1;
thd->where= save_where;
return res; return res;
} }
...@@ -312,11 +314,13 @@ void subselect_union_engine::fix_length_and_dec() ...@@ -312,11 +314,13 @@ void subselect_union_engine::fix_length_and_dec()
int subselect_single_select_engine::exec() int subselect_single_select_engine::exec()
{ {
DBUG_ENTER("subselect_single_select_engine::exec"); DBUG_ENTER("subselect_single_select_engine::exec");
char const *save_where= join->thd->where;
if (!optimized) if (!optimized)
{ {
optimized=1; optimized=1;
if (join->optimize()) if (join->optimize())
{ {
join->thd->where= save_where;
executed= 1; executed= 1;
DBUG_RETURN(join->error?join->error:1); DBUG_RETURN(join->error?join->error:1);
} }
...@@ -324,7 +328,10 @@ int subselect_single_select_engine::exec() ...@@ -324,7 +328,10 @@ int subselect_single_select_engine::exec()
if (select_lex->dependent && executed) if (select_lex->dependent && executed)
{ {
if (join->reinit()) if (join->reinit())
{
join->thd->where= save_where;
DBUG_RETURN(1); DBUG_RETURN(1);
}
item->assign_null(); item->assign_null();
item->assigned((executed= 0)); item->assigned((executed= 0));
} }
...@@ -335,14 +342,19 @@ int subselect_single_select_engine::exec() ...@@ -335,14 +342,19 @@ int subselect_single_select_engine::exec()
join->exec(); join->exec();
join->thd->lex.current_select= save_select; join->thd->lex.current_select= save_select;
executed= 1; executed= 1;
join->thd->where= save_where;
DBUG_RETURN(join->error||thd->fatal_error); DBUG_RETURN(join->error||thd->fatal_error);
} }
join->thd->where= save_where;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int subselect_union_engine::exec() int subselect_union_engine::exec()
{ {
return unit->exec(); char const *save_where= unit->thd->where;
int res= unit->exec();
unit->thd->where= save_where;
return res;
} }
uint subselect_single_select_engine::cols() uint subselect_single_select_engine::cols()
......
...@@ -463,7 +463,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock); ...@@ -463,7 +463,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock);
bool drop_locked_tables(THD *thd,const char *db, const char *table_name); bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
void abort_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name);
extern const Field *not_found_field; extern const Field *not_found_field;
Field *find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
bool report_error); bool report_error);
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
bool check_grant,bool allow_rowid); bool check_grant,bool allow_rowid);
......
...@@ -1861,7 +1861,7 @@ const Field *not_found_field= (Field*) 0x1; ...@@ -1861,7 +1861,7 @@ const Field *not_found_field= (Field*) 0x1;
*/ */
Field * Field *
find_field_in_tables(THD *thd, Item_field *item, TABLE_LIST *tables, find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
bool report_error) bool report_error)
{ {
Field *found=0; Field *found=0;
......
...@@ -294,6 +294,7 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -294,6 +294,7 @@ class st_select_lex_unit: public st_select_lex_node {
int cleanup(); int cleanup();
friend void mysql_init_query(THD *thd); friend void mysql_init_query(THD *thd);
friend int subselect_union_engine::exec();
private: private:
bool create_total_list_n_last_return(THD *thd, st_lex *lex, bool create_total_list_n_last_return(THD *thd, st_lex *lex,
TABLE_LIST ***result); TABLE_LIST ***result);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment