mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Reference to field in outer subelect fixed
Fixed context in error mesages
This commit is contained in:
@ -17,6 +17,16 @@ SELECT (SELECT 1),MAX(1) FROM (SELECT 1);
|
||||
1 1
|
||||
SELECT (SELECT a) as a;
|
||||
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;
|
||||
create table t1 (a 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
|
||||
SELECT (SELECT 1),MAX(1) FROM (SELECT 1);
|
||||
-- error 1245
|
||||
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;
|
||||
create table t1 (a int);
|
||||
create table t2 (a int, b int);
|
||||
|
26
sql/item.cc
26
sql/item.cc
@ -468,7 +468,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
(last= sl)->get_table_list(),
|
||||
0)) != not_found_field)
|
||||
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)) !=
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
@ -867,6 +867,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
REPORT_ALL_ERRORS))) ==
|
||||
(Item **)not_found_item)
|
||||
{
|
||||
Field *tmp= (Field*) not_found_field;
|
||||
/*
|
||||
We can't find table field in table list of current select,
|
||||
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)
|
||||
*/
|
||||
SELECT_LEX *last=0;
|
||||
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)) !=
|
||||
(Item **)not_found_item)
|
||||
break;
|
||||
if ((tmp= find_field_in_tables(thd, this,
|
||||
sl->get_table_list(),
|
||||
0)) != not_found_field);
|
||||
}
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (ref == (Item **)not_found_item)
|
||||
else if (!tmp)
|
||||
return -1;
|
||||
else if (ref == (Item **)not_found_item && tmp == not_found_field)
|
||||
{
|
||||
// Call to report error
|
||||
find_item_in_list(this,
|
||||
@ -896,6 +902,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
ref= 0;
|
||||
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
|
||||
{
|
||||
depended_from= last;
|
||||
|
@ -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)
|
||||
{
|
||||
char const *save_where= thd->where;
|
||||
int res= engine->prepare();
|
||||
if (!res)
|
||||
{
|
||||
@ -93,6 +94,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
fix_length_and_dec();
|
||||
}
|
||||
fixed= 1;
|
||||
thd->where= save_where;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -312,11 +314,13 @@ void subselect_union_engine::fix_length_and_dec()
|
||||
int subselect_single_select_engine::exec()
|
||||
{
|
||||
DBUG_ENTER("subselect_single_select_engine::exec");
|
||||
char const *save_where= join->thd->where;
|
||||
if (!optimized)
|
||||
{
|
||||
optimized=1;
|
||||
if (join->optimize())
|
||||
{
|
||||
join->thd->where= save_where;
|
||||
executed= 1;
|
||||
DBUG_RETURN(join->error?join->error:1);
|
||||
}
|
||||
@ -324,7 +328,10 @@ int subselect_single_select_engine::exec()
|
||||
if (select_lex->dependent && executed)
|
||||
{
|
||||
if (join->reinit())
|
||||
{
|
||||
join->thd->where= save_where;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
item->assign_null();
|
||||
item->assigned((executed= 0));
|
||||
}
|
||||
@ -335,14 +342,19 @@ int subselect_single_select_engine::exec()
|
||||
join->exec();
|
||||
join->thd->lex.current_select= save_select;
|
||||
executed= 1;
|
||||
join->thd->where= save_where;
|
||||
DBUG_RETURN(join->error||thd->fatal_error);
|
||||
}
|
||||
join->thd->where= save_where;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
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()
|
||||
|
@ -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);
|
||||
void abort_locked_tables(THD *thd,const char *db, const char *table_name);
|
||||
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);
|
||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
bool check_grant,bool allow_rowid);
|
||||
|
@ -1861,7 +1861,7 @@ const Field *not_found_field= (Field*) 0x1;
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
Field *found=0;
|
||||
|
@ -294,6 +294,7 @@ public:
|
||||
int cleanup();
|
||||
|
||||
friend void mysql_init_query(THD *thd);
|
||||
friend int subselect_union_engine::exec();
|
||||
private:
|
||||
bool create_total_list_n_last_return(THD *thd, st_lex *lex,
|
||||
TABLE_LIST ***result);
|
||||
|
Reference in New Issue
Block a user