mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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<Item> &fields);
|
||||
table_map used_tables() const { return used_tables_cache; };
|
||||
bool const_item() const { return const_item_cache; };
|
||||
|
Reference in New Issue
Block a user