Commit 70a6d6c9 authored by konstantin@mysql.com's avatar konstantin@mysql.com

Post-merge fixes for Bug#9096 "select doesn't return all matched

 records if prepared statements is used" (see comments to 
the changed files).
parent 92e4e1a3
...@@ -570,3 +570,28 @@ id ...@@ -570,3 +570,28 @@ id
deallocate prepare stmt| deallocate prepare stmt|
drop procedure p1| drop procedure p1|
drop table t1| drop table t1|
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
create table t1 (c1 int(11) not null, c2 int(11) not null,
primary key (c1,c2), key c2 (c2), key c1 (c1));
insert into t1 values (200887, 860);
insert into t1 values (200887, 200887);
select * from t1 where (c1=200887 and c2=200887) or c2=860;
c1 c2
200887 860
200887 200887
prepare stmt from
"select * from t1 where (c1=200887 and c2=200887) or c2=860";
execute stmt;
c1 c2
200887 860
200887 200887
prepare stmt from
"select * from t1 where (c1=200887 and c2=?) or c2=?";
set @a=200887, @b=860;
execute stmt using @a, @b;
c1 c2
200887 860
200887 200887
deallocate prepare stmt;
...@@ -88,7 +88,7 @@ date numfacture expedition ...@@ -88,7 +88,7 @@ date numfacture expedition
0000-00-00 00:00:00 1212 0001-00-00 00:00:00 0000-00-00 00:00:00 1212 0001-00-00 00:00:00
EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00'; EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref expedition expedition 8 const 1 Using where 1 SIMPLE t1 ref expedition expedition 8 const 1
drop table t1; drop table t1;
create table t1 (a datetime not null, b datetime not null); create table t1 (a datetime not null, b datetime not null);
insert into t1 values (now(), now()); insert into t1 values (now(), now());
......
...@@ -1448,6 +1448,24 @@ void Item_decimal::print(String *str) ...@@ -1448,6 +1448,24 @@ void Item_decimal::print(String *str)
} }
bool Item_decimal::eq(const Item *item, bool binary_cmp) const
{
if (type() == item->type() && item->basic_const_item())
{
/*
We need to cast off const to call val_decimal(). This should
be OK for a basic constant. Additionally, we can pass 0 as
a true decimal constant will return its internal decimal
storage and ignore the argument.
*/
Item *arg= (Item*) item;
my_decimal *value= arg->val_decimal(0);
return !my_decimal_cmp(&decimal_value, value);
}
return 0;
}
String *Item_float::val_str(String *str) String *Item_float::val_str(String *str)
{ {
// following assert is redundant, because fixed=1 assigned in constructor // following assert is redundant, because fixed=1 assigned in constructor
...@@ -2217,7 +2235,7 @@ Item_param::new_item() ...@@ -2217,7 +2235,7 @@ Item_param::new_item()
case INT_VALUE: case INT_VALUE:
return new Item_int(name, value.integer, max_length); return new Item_int(name, value.integer, max_length);
case REAL_VALUE: case REAL_VALUE:
return new Item_real(name, value.real, decimals, max_length); return new Item_float(name, value.real, decimals, max_length);
case STRING_VALUE: case STRING_VALUE:
case LONG_DATA_VALUE: case LONG_DATA_VALUE:
return new Item_string(name, str_value.c_ptr_quick(), str_value.length(), return new Item_string(name, str_value.c_ptr_quick(), str_value.length(),
...@@ -2251,7 +2269,7 @@ Item_param::eq(const Item *arg, bool binary_cmp) const ...@@ -2251,7 +2269,7 @@ Item_param::eq(const Item *arg, bool binary_cmp) const
return value.integer == item->val_int() && return value.integer == item->val_int() &&
unsigned_flag == item->unsigned_flag; unsigned_flag == item->unsigned_flag;
case REAL_VALUE: case REAL_VALUE:
return value.real == item->val(); return value.real == item->val_real();
case STRING_VALUE: case STRING_VALUE:
case LONG_DATA_VALUE: case LONG_DATA_VALUE:
if (binary_cmp) if (binary_cmp)
...@@ -3520,7 +3538,7 @@ void Item_float::print(String *str) ...@@ -3520,7 +3538,7 @@ void Item_float::print(String *str)
In number context this is a longlong value. In number context this is a longlong value.
*/ */
bool Item_real::eq(const Item *arg, bool binary_cmp) const bool Item_float::eq(const Item *arg, bool binary_cmp) const
{ {
if (arg->basic_const_item() && arg->type() == type()) if (arg->basic_const_item() && arg->type() == type())
{ {
...@@ -3529,7 +3547,7 @@ bool Item_real::eq(const Item *arg, bool binary_cmp) const ...@@ -3529,7 +3547,7 @@ bool Item_real::eq(const Item *arg, bool binary_cmp) const
a basic constant. a basic constant.
*/ */
Item *item= (Item*) arg; Item *item= (Item*) arg;
return item->val() == value; return item->val_real() == value;
} }
return FALSE; return FALSE;
} }
...@@ -3605,7 +3623,7 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions) ...@@ -3605,7 +3623,7 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
} }
bool Item_varbinary::eq(const Item *arg, bool binary_cmp) const bool Item_hex_string::eq(const Item *arg, bool binary_cmp) const
{ {
if (arg->basic_const_item() && arg->type() == type()) if (arg->basic_const_item() && arg->type() == type())
{ {
......
...@@ -1039,8 +1039,10 @@ class Item_decimal :public Item_num ...@@ -1039,8 +1039,10 @@ class Item_decimal :public Item_num
unsigned_flag= !decimal_value.sign(); unsigned_flag= !decimal_value.sign();
return this; return this;
} }
bool eq(const Item *, bool binary_cmp) const;
}; };
class Item_float :public Item_num class Item_float :public Item_num
{ {
char *presentation; char *presentation;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment