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));
|
select (select * from t1) = row(1,(2,2));
|
||||||
ERROR 21000: Operand should contain 1 column(s)
|
ERROR 21000: Operand should contain 1 column(s)
|
||||||
drop table t1;
|
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
|
-- error 1241
|
||||||
select (select * from t1) = row(1,(2,2));
|
select (select * from t1) = row(1,(2,2));
|
||||||
drop table t1;
|
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)
|
else if (refer != (Item **)not_found_item)
|
||||||
{
|
{
|
||||||
if (!(*refer)->fixed)
|
if (!last->ref_pointer_array[counter])
|
||||||
{
|
{
|
||||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||||
"forward reference in item list");
|
"forward reference in item list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
DBUG_ASSERT((*refer)->fixed);
|
||||||
/*
|
/*
|
||||||
Here, a subset of actions performed by Item_ref::set_properties
|
Here, a subset of actions performed by Item_ref::set_properties
|
||||||
is not enough. So we pass ptr to NULL into Item_[direct]_ref
|
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);
|
mark_as_dependent(thd, last, thd->lex->current_select, fld);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(*ref)->fixed)
|
if (!last->ref_pointer_array[counter])
|
||||||
{
|
{
|
||||||
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
my_error(ER_ILLEGAL_REFERENCE, MYF(0), name,
|
||||||
"forward reference in item list");
|
"forward reference in item list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
DBUG_ASSERT((*ref)->fixed);
|
||||||
mark_as_dependent(thd, last, thd->lex->current_select,
|
mark_as_dependent(thd, last, thd->lex->current_select,
|
||||||
this);
|
this);
|
||||||
if (place == IN_HAVING)
|
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->allow_sum_func= allow_sum_func;
|
||||||
thd->where="field list";
|
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;
|
Item **ref= ref_pointer_array;
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user