mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +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
|
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
|
|||||||
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);
|
||||||
|
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(),
|
(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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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()
|
|||||||
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()
|
|||||||
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()
|
|||||||
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);
|
|||||||
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;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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 @@ public:
|
|||||||
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);
|
||||||
|
Reference in New Issue
Block a user