Commit 9b6e83f4 authored by unknown's avatar unknown
Browse files

A fix and a test case for Bug#16248 "WHERE (col1,col2) IN ((?,?))

gives wrong results". Implement previously missing 
Item_row::cleanup. The bug is not repeatable in 5.0, probably 
due to a coincidence: the problem is present in 5.0 as well.


mysql-test/r/ps.result:
  Update the result file (Bug#16248)
mysql-test/t/ps.test:
  Add a test case for Bug#16248 "WHERE (col1,col2) IN ((?,?)) gives 
  wrong results"
sql/item_row.cc:
  Implement Item_row::cleanup(): we should reset used_tables_cache
  before reexecution of a prepared statement. In case ROW
  arguments contain a placeholder, used_tables_cache has PARAM_TABLE
  bit set in statement prepare. As a result, when executing a statement,
  the condition push down algorithm (make_cond_for_table) would think
  that the WHERE clause belongs to the non-existent PARAM_TABLE and
  wouldn't attach the WHERE clause to any of the real tables, 
  effectively optimizing the clause away.
sql/item_row.h:
  Remove a never used member 'array_holder'. Add declaration for
  Item_row::cleanup.
parent 00cfd1a7
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -747,3 +747,23 @@ length(a)
10
drop table t1;
deallocate prepare stmt;
create table t1 (col1 integer, col2 integer);
insert into t1 values(100,100),(101,101),(102,102),(103,103);
prepare stmt from 'select col1, col2 from t1 where (col1, col2) in ((?,?))';
set @a=100, @b=100;
execute stmt using @a,@b;
col1	col2
100	100
set @a=101, @b=101;
execute stmt using @a,@b;
col1	col2
101	101
set @a=102, @b=102;
execute stmt using @a,@b;
col1	col2
102	102
set @a=102, @b=103;
execute stmt using @a,@b;
col1	col2
deallocate prepare stmt;
drop table t1;
+18 −0
Original line number Diff line number Diff line
@@ -785,4 +785,22 @@ select length(a) from t1;
drop table t1;
deallocate prepare stmt;

#
# Bug#16248 "WHERE (col1,col2) IN ((?,?)) gives wrong results":
# check that ROW implementation is reexecution-friendly.
#
create table t1 (col1 integer, col2 integer);
insert into t1 values(100,100),(101,101),(102,102),(103,103);
prepare stmt from 'select col1, col2 from t1 where (col1, col2) in ((?,?))';
set @a=100, @b=100;
execute stmt using @a,@b;
set @a=101, @b=101;
execute stmt using @a,@b;
set @a=102, @b=102;
execute stmt using @a,@b;
set @a=102, @b=103;
execute stmt using @a,@b;
deallocate prepare stmt;
drop table t1;

# End of 4.1 tests
+15 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
*/

Item_row::Item_row(List<Item> &arg):
  Item(), used_tables_cache(0), array_holder(1), const_item_cache(1), with_null(0)
  Item(), used_tables_cache(0), const_item_cache(1), with_null(0)
{

  //TODO: think placing 2-3 component items in item (as it done for function)
@@ -85,6 +85,20 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
}


void Item_row::cleanup()
{
  DBUG_ENTER("Item_row::cleanup");

  Item::cleanup();
  /* Reset to the original values */
  used_tables_cache= 0;
  const_item_cache= 1;
  with_null= 0;

  DBUG_VOID_RETURN;
}


void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
                              List<Item> &fields)
{
+1 −2
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ class Item_row: public Item
  Item **items;
  table_map used_tables_cache;
  uint arg_count;
  bool array_holder;
  bool const_item_cache;
  bool with_null;
public:
@@ -29,7 +28,6 @@ class Item_row: public Item
    items(item->items),
    used_tables_cache(item->used_tables_cache),
    arg_count(item->arg_count),
    array_holder(0), 
    const_item_cache(item->const_item_cache),
    with_null(0)
  {}
@@ -57,6 +55,7 @@ class Item_row: public Item
    return 0;
  };
  bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
  void cleanup();
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
  table_map used_tables() const { return used_tables_cache; };
  bool const_item() const { return const_item_cache; };