Commit 5ad3ed8c authored by unknown's avatar unknown
Browse files

Merge macbook.gmz:/Users/kgeorge/mysql/work/B11032-4.1-opt

into  macbook.gmz:/Users/kgeorge/mysql/work/B11032-5.0-opt


mysql-test/r/subselect.result:
  merge fixes
mysql-test/t/subselect.test:
  merge fixes
sql/item_subselect.cc:
  merge fixes
sql/item_subselect.h:
  merge fixes
parents c0487fb9 5af4fd25
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -3017,6 +3017,23 @@ a a IN (SELECT a FROM t1)
2	NULL
3	1
DROP TABLE t1,t2;
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT 
(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a 
FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2;
Table	Create Table
t2	CREATE TABLE `t2` (
  `sub_a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
SHOW CREATE TABLE t3;
Table	Create Table
t3	CREATE TABLE `t3` (
  `a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t3;
create table t1 (df decimal(5,1));
insert into t1 values(1.1);
insert into t1 values(2.2);
+16 −0
Original line number Diff line number Diff line
@@ -1972,6 +1972,22 @@ SELECT a, a IN (SELECT a FROM t1) FROM t2;

DROP TABLE t1,t2;

#
# Bug #11302: getObject() returns a String for a sub-query of type datetime
#
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');

CREATE TABLE t2 AS SELECT 
  (SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a 
   FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2;

CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01'); 
SHOW CREATE TABLE t3;

DROP TABLE t1,t2,t3;

# End of 4.1 tests

#
+24 −10
Original line number Diff line number Diff line
@@ -391,6 +391,15 @@ enum Item_result Item_singlerow_subselect::result_type() const
  return engine->type();
}

/* 
 Don't rely on the result type to calculate field type. 
 Ask the engine instead.
*/
enum_field_types Item_singlerow_subselect::field_type() const
{
  return engine->field_type();
}

void Item_singlerow_subselect::fix_length_and_dec()
{
  if ((max_columns= engine->cols()) == 1)
@@ -1613,32 +1622,36 @@ bool subselect_single_select_engine::no_rows()
}


static Item_result set_row(List<Item> &item_list, Item *item,
			   Item_cache **row, bool *maybe_null)
/* 
 makes storage for the output values for the subquery and calcuates 
 their data and column types and their nullability.
*/ 
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
{
  Item_result res_type= STRING_RESULT;
  Item *sel_item;
  List_iterator_fast<Item> li(item_list);
  res_type= STRING_RESULT;
  res_field_type= FIELD_TYPE_VAR_STRING;
  for (uint i= 0; (sel_item= li++); i++)
  {
    item->max_length= sel_item->max_length;
    res_type= sel_item->result_type();
    res_field_type= sel_item->field_type();
    item->decimals= sel_item->decimals;
    item->unsigned_flag= sel_item->unsigned_flag;
    *maybe_null= sel_item->maybe_null;
    maybe_null= sel_item->maybe_null;
    if (!(row[i]= Item_cache::get_cache(res_type)))
      return STRING_RESULT; // we should return something
      return;
    row[i]->setup(sel_item);
  }
  if (item_list.elements > 1)
    res_type= ROW_RESULT;
  return res_type;
}

void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
{
  DBUG_ASSERT(row || select_lex->item_list.elements==1);
  res_type= set_row(select_lex->item_list, item, row, &maybe_null);
  set_row(select_lex->item_list, row);
  item->collation.set(row[0]->collation);
  if (cols() != 1)
    maybe_null= 0;
@@ -1650,13 +1663,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)

  if (unit->first_select()->item_list.elements == 1)
  {
    res_type= set_row(unit->types, item, row, &maybe_null);
    set_row(unit->types, row);
    item->collation.set(row[0]->collation);
  }
  else
  {
    bool fake= 0;
    res_type= set_row(unit->types, item, row, &fake);
    bool maybe_null_saved= maybe_null;
    set_row(unit->types, row);
    maybe_null= maybe_null_saved;
  }
}

+7 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ class Item_singlerow_subselect :public Item_subselect
  my_decimal *val_decimal(my_decimal *);
  bool val_bool();
  enum Item_result result_type() const;
  enum_field_types field_type() const;
  void fix_length_and_dec();

  uint cols();
@@ -311,6 +312,7 @@ class subselect_engine: public Sql_alloc
  THD *thd; /* pointer to current THD */
  Item_subselect *item; /* item, that use this engine */
  enum Item_result res_type; /* type of results */
  enum_field_types res_field_type; /* column type of the results */
  bool maybe_null; /* may be null (first item in select) */
public:

@@ -320,6 +322,7 @@ class subselect_engine: public Sql_alloc
    result= res;
    item= si;
    res_type= STRING_RESULT;
    res_field_type= FIELD_TYPE_VAR_STRING;
    maybe_null= 0;
  }
  virtual ~subselect_engine() {}; // to satisfy compiler
@@ -358,6 +361,7 @@ class subselect_engine: public Sql_alloc
  virtual uint cols()= 0; /* return number of columns in select */
  virtual uint8 uncacheable()= 0; /* query is uncacheable */
  enum Item_result type() { return res_type; }
  enum_field_types field_type() { return res_field_type; }
  virtual void exclude()= 0;
  bool may_be_null() { return maybe_null; };
  virtual table_map upper_select_const_tables()= 0;
@@ -368,6 +372,9 @@ class subselect_engine: public Sql_alloc
  virtual bool is_executed() const { return FALSE; }
  /* Check if subquery produced any rows during last query execution */
  virtual bool no_rows() = 0;

protected:
  void set_row(List<Item> &item_list, Item_cache **row);
};