Commit 38e664cf authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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;
+16 −0
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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)
+14 −0
Original line number Diff line number Diff line
@@ -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++))
  {