From 9b6e83f4b83abcd33c8cf20b95d3e3f4e7a7851a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Apr 2006 22:26:25 +0400 Subject: [PATCH] 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. --- mysql-test/r/ps.result | 20 ++++++++++++++++++++ mysql-test/t/ps.test | 18 ++++++++++++++++++ sql/item_row.cc | 16 +++++++++++++++- sql/item_row.h | 3 +-- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index e94c2952893..3f0b9e4fa8b 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -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; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index af885a5c02f..9b6082eeaf6 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -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 diff --git a/sql/item_row.cc b/sql/item_row.cc index 12d202a1699..493eefc9ff0 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -26,7 +26,7 @@ */ Item_row::Item_row(List &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 &fields) { diff --git a/sql/item_row.h b/sql/item_row.h index 39bc4513e1e..28cb47b6815 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -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 @@ public: 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 @@ public: 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 &fields); table_map used_tables() const { return used_tables_cache; }; bool const_item() const { return const_item_cache; };