mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Post-merge fixes for Bug#9096 "select doesn't return all matched
records if prepared statements is used" (see comments to the changed files). mysql-test/r/ps.result: Post-merge fix for Bug#9096: test results fixed. mysql-test/r/type_datetime.result: Post-merge fix for Bug#9096: now we do better constants comparison, so the optimizer is able to guess from the index that we don't need to evaluate WHERE clause. sql/item.cc: Post-merge fixes for Bug#9096: implement by-value comparison for new 5.0 DECIMAL type. Item_real is renamed to Item_float in 5.0 Item_varbinary is renamed to Item_hex_string in 5.0 sql/item.h: Post-merge fixes for Bug#9096: declaration for Item_decimal::eq
This commit is contained in:
@ -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
|
|||||||
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());
|
||||||
|
28
sql/item.cc
28
sql/item.cc
@ -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()
|
|||||||
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
|
|||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 @@ public:
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user