Commit d514a06a authored by unknown's avatar unknown
Browse files

fixed column number fetchinmg for subqueries. (BUG#8020)

fixed cols() method call (it have to be called only after fix_fields())


mysql-test/r/subselect.result:
  Comparison subquery with * and row
mysql-test/t/subselect.test:
  Comparison subquery with * and row
sql/item_cmpfunc.h:
  initialization allowed_arg_cols for autodetection
sql/item_func.cc:
  support of allowed_arg_cols autodetection by first argument
sql/item_func.h:
  commant
sql/item_subselect.cc:
  correct column number fetching for subqueries
sql/sql_lex.h:
  method to check that UNION is prepared
parent 1850f749
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -2160,3 +2160,17 @@ ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery'
select * from t1 where a1 > any(select b1 from t2);
a1
drop table t1,t2;
create table t1 (a integer, b integer);
select (select * from t1) = (select 1,2);
(select * from t1) = (select 1,2)
NULL
select (select 1,2) = (select * from t1);
(select 1,2) = (select * from t1)
NULL
select  row(1,2) = ANY (select * from t1);
row(1,2) = ANY (select * from t1)
0
select  row(1,2) != ALL (select * from t1);
row(1,2) != ALL (select * from t1)
1
drop table t1;
+14 −0
Original line number Diff line number Diff line
@@ -1414,8 +1414,11 @@ SELECT f1 FROM t1
   WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);

drop table t1,t2;

#
# Test for BUG#7885: Server crash when 'any' subselect compared to
# non-existant field.
#
create table t1 (a1 int);
create table t2 (b1 int);
--error 1054
@@ -1423,3 +1426,14 @@ select * from t1 where a2 > any(select b1 from t2);
select * from t1 where a1 > any(select b1 from t2);
drop table t1,t2;


#
# Comparison subquery with * and row
#
create table t1 (a integer, b integer);
select (select * from t1) = (select 1,2);
select (select 1,2) = (select * from t1);
# queries whih can be converted to IN
select  row(1,2) = ANY (select * from t1);
select  row(1,2) != ALL (select * from t1);
drop table t1;
+6 −3
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2
public:
  Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
  {
    allowed_arg_cols= a->cols();
    allowed_arg_cols= 0;  // Fetch this value from first argument
  }
  Item *neg_transformer(THD *thd);
  virtual Item *negated_item();
@@ -390,7 +390,10 @@ class Item_func_interval :public Item_int_func
  double *intervals;
public:
  Item_func_interval(Item_row *a)
    :Item_int_func(a),row(a),intervals(0) { allowed_arg_cols= a->cols(); }
    :Item_int_func(a),row(a),intervals(0)
  {
    allowed_arg_cols= 0;    // Fetch this value from first argument
  }
  longlong val_int();
  void fix_length_and_dec();
  const char *func_name() const { return "interval"; }
@@ -743,7 +746,7 @@ class Item_func_in :public Item_int_func
  Item_func_in(List<Item> &list)
    :Item_int_func(list), array(0), in_item(0), have_null(0)
  {
    allowed_arg_cols= args[0]->cols();
    allowed_arg_cols= 0;  // Fetch this value from first argument
  }
  longlong val_int();
  void fix_length_and_dec();
+16 −2
Original line number Diff line number Diff line
@@ -303,10 +303,24 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
	We can't yet set item to *arg as fix_fields may change *arg
	We shouldn't call fix_fields() twice, so check 'fixed' field first
      */
      if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) ||
	  (*arg)->check_cols(allowed_arg_cols))
      if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)))
	return 1;				/* purecov: inspected */

      item= *arg;

      if (allowed_arg_cols)
      {
        if (item->check_cols(allowed_arg_cols))
          return 1;
      }
      else
      {
        /*  we have to fetch allowed_arg_cols from first argument */
        DBUG_ASSERT(arg == args); // it is first argument
        allowed_arg_cols= item->cols();
        DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more
      }

      if (item->maybe_null)
	maybe_null=1;

+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ class Item_func :public Item_result_field
{
protected:
  Item **args, *tmp_arg[2];
  /*
    Allowed numbers of columns in result (usually 1, which means scalar value)
    0 means get this number from first argument
  */
  uint allowed_arg_cols;
public:
  uint arg_count;
Loading