Commit 38e664cf authored by unknown's avatar unknown

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.
parent 91827869
......@@ -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++))
{
......
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