mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
fixed way of forward reference detection to support literal constant (BUG#8025)
mysql-test/r/subselect.result: Forward reference detection mysql-test/t/subselect.test: Forward reference detection sql/item.cc: now forward reference is detected via ref_pointer_array, because some literal constants are 'fixed' just after creation sql/sql_base.cc: fill ref_pointer_array with zerows for forward reference detection.
This commit is contained in:
@ -2182,3 +2182,17 @@ ERROR 21000: Operand should contain 2 column(s)
|
||||
select (select * from t1) = row(1,(2,2));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop table t1;
|
||||
create table t1 (a integer);
|
||||
insert into t1 values (1);
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
|
||||
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
|
||||
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
|
||||
select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
|
||||
xx 1 = ALL ( select 1 from t1 where 1 = xx )
|
||||
1 1
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
|
||||
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
|
||||
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
|
||||
drop table t1;
|
||||
|
@ -1449,3 +1449,19 @@ select row(1,(2,2)) = (select * from t1 );
|
||||
-- error 1241
|
||||
select (select * from t1) = row(1,(2,2));
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Forward reference detection
|
||||
#
|
||||
create table t1 (a integer);
|
||||
insert into t1 values (1);
|
||||
-- error 1247
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
|
||||
-- error 1247
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
|
||||
select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
|
||||
-- error 1247
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
|
||||
-- error 1247
|
||||
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
|
||||
drop table t1;
|
||||
|
@ -1482,12 +1482,13 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
}
|
||||
else if (refer != (Item **)not_found_item)
|
||||
{
|
||||
if (!(*refer)->fixed)
|
||||
if (!last->ref_pointer_array[counter])
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
DBUG_ASSERT((*refer)->fixed);
|
||||
/*
|
||||
Here, a subset of actions performed by Item_ref::set_properties
|
||||
is not enough. So we pass ptr to NULL into Item_[direct]_ref
|
||||
@ -2173,12 +2174,13 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||
mark_as_dependent(thd, last, thd->lex->current_select, fld);
|
||||
return 0;
|
||||
}
|
||||
if (!(*ref)->fixed)
|
||||
if (!last->ref_pointer_array[counter])
|
||||
{
|
||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||
"forward reference in item list");
|
||||
return -1;
|
||||
}
|
||||
DBUG_ASSERT((*ref)->fixed);
|
||||
mark_as_dependent(thd, last, thd->lex->current_select,
|
||||
this);
|
||||
if (place == IN_HAVING)
|
||||
|
@ -2405,6 +2405,20 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
thd->allow_sum_func= allow_sum_func;
|
||||
thd->where="field list";
|
||||
|
||||
/*
|
||||
To prevent fail on forward lookup we fill it with zerows,
|
||||
then if we got pointer on zero after find_item_in_list we will know
|
||||
that it is forward lookup.
|
||||
|
||||
There is other way to solve problem: fill array with pointers to list,
|
||||
but it will be slower.
|
||||
|
||||
TODO: remove it when (if) we made one list for allfields and
|
||||
ref_pointer_array
|
||||
*/
|
||||
if (ref_pointer_array)
|
||||
bzero(ref_pointer_array, sizeof(Item *) * fields.elements);
|
||||
|
||||
Item **ref= ref_pointer_array;
|
||||
while ((item= it++))
|
||||
{
|
||||
|
Reference in New Issue
Block a user