Fixed LP BUG#615378 Incorrect processing of NULL result in Item_cache fixed.
This commit is contained in:
parent
b67be0b23b
commit
05f21b21e4
@ -3272,3 +3272,41 @@ FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
|
||||
col_varchar_nokey
|
||||
drop table t1,t2;
|
||||
set @@optimizer_switch= default;
|
||||
# LP BUG#615378 (incorrect NULL result returning in Item_cache)
|
||||
CREATE TABLE `t1` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t1` VALUES (10,'v');
|
||||
INSERT INTO `t1` VALUES (11,'r');
|
||||
CREATE TABLE `t2` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t2` VALUES (1,'r');
|
||||
INSERT INTO `t2` VALUES (2,'c');
|
||||
CREATE TABLE `t3` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t3` VALUES (1,'w');
|
||||
SELECT SUM( DISTINCT table2 . `pk` ) AS field2 ,
|
||||
(SELECT SUM( SUBQUERY1_t2 . `pk` ) AS SUBQUERY1_field1
|
||||
FROM t2 AS SUBQUERY1_t2 STRAIGHT_JOIN
|
||||
t3 AS SUBQUERY1_t3 ON (SUBQUERY1_t3 . `pk` = SUBQUERY1_t2 . `pk` )
|
||||
WHERE table1 . `col_varchar_key` ) AS field3
|
||||
FROM ( t1 AS table1 LEFT JOIN
|
||||
( t2 AS table2 STRAIGHT_JOIN
|
||||
t3 AS table3 ON (table3 . `pk` = table2 . `pk` ) )
|
||||
ON (table3 . `col_varchar_key` = table1 . `col_varchar_key` ) )
|
||||
WHERE ( table1 . `pk` < 5 ) OR ( table1 . `col_varchar_key` IS NOT NULL)
|
||||
GROUP BY field3
|
||||
HAVING (field3 <= 'h' AND field2 != 4) ;
|
||||
field2 field3
|
||||
drop tables t1, t2, t3;
|
||||
|
@ -1566,3 +1566,48 @@ FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
|
||||
|
||||
drop table t1,t2;
|
||||
set @@optimizer_switch= default;
|
||||
|
||||
#
|
||||
--echo # LP BUG#615378 (incorrect NULL result returning in Item_cache)
|
||||
#
|
||||
# if bug present here will be valgrind warnings (due to attempt to process
|
||||
# uninialized decimal value) but the result will be correct (due to
|
||||
# Item::null_value)
|
||||
|
||||
CREATE TABLE `t1` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t1` VALUES (10,'v');
|
||||
INSERT INTO `t1` VALUES (11,'r');
|
||||
CREATE TABLE `t2` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t2` VALUES (1,'r');
|
||||
INSERT INTO `t2` VALUES (2,'c');
|
||||
CREATE TABLE `t3` (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`col_varchar_key` varchar(1) DEFAULT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
KEY `col_varchar_key` (`col_varchar_key`)
|
||||
) DEFAULT CHARSET=latin1;
|
||||
INSERT INTO `t3` VALUES (1,'w');
|
||||
|
||||
SELECT SUM( DISTINCT table2 . `pk` ) AS field2 ,
|
||||
(SELECT SUM( SUBQUERY1_t2 . `pk` ) AS SUBQUERY1_field1
|
||||
FROM t2 AS SUBQUERY1_t2 STRAIGHT_JOIN
|
||||
t3 AS SUBQUERY1_t3 ON (SUBQUERY1_t3 . `pk` = SUBQUERY1_t2 . `pk` )
|
||||
WHERE table1 . `col_varchar_key` ) AS field3
|
||||
FROM ( t1 AS table1 LEFT JOIN
|
||||
( t2 AS table2 STRAIGHT_JOIN
|
||||
t3 AS table3 ON (table3 . `pk` = table2 . `pk` ) )
|
||||
ON (table3 . `col_varchar_key` = table1 . `col_varchar_key` ) )
|
||||
WHERE ( table1 . `pk` < 5 ) OR ( table1 . `col_varchar_key` IS NOT NULL)
|
||||
GROUP BY field3
|
||||
HAVING (field3 <= 'h' AND field2 != 4) ;
|
||||
drop tables t1, t2, t3;
|
||||
|
94
sql/item.cc
94
sql/item.cc
@ -7750,8 +7750,11 @@ void Item_cache_int::store_longlong(Item *item, longlong val_arg)
|
||||
String *Item_cache_int::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
str->set(value, default_charset());
|
||||
return str;
|
||||
}
|
||||
@ -7760,8 +7763,11 @@ String *Item_cache_int::val_str(String *str)
|
||||
my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
|
||||
return decimal_val;
|
||||
}
|
||||
@ -7769,16 +7775,22 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
|
||||
double Item_cache_int::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0.0;
|
||||
}
|
||||
return (double) value;
|
||||
}
|
||||
|
||||
longlong Item_cache_int::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -7796,16 +7808,22 @@ bool Item_cache_real::cache_value()
|
||||
double Item_cache_real::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0.0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
longlong Item_cache_real::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
return (longlong) rint(value);
|
||||
}
|
||||
|
||||
@ -7813,8 +7831,11 @@ longlong Item_cache_real::val_int()
|
||||
String* Item_cache_real::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
str->set_real(value, decimals, default_charset());
|
||||
return str;
|
||||
}
|
||||
@ -7823,8 +7844,11 @@ String* Item_cache_real::val_str(String *str)
|
||||
my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
|
||||
return decimal_val;
|
||||
}
|
||||
@ -7845,8 +7869,11 @@ double Item_cache_decimal::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
double res;
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0.0;
|
||||
}
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
|
||||
return res;
|
||||
}
|
||||
@ -7855,8 +7882,11 @@ longlong Item_cache_decimal::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
longlong res;
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
|
||||
return res;
|
||||
}
|
||||
@ -7864,8 +7894,11 @@ longlong Item_cache_decimal::val_int()
|
||||
String* Item_cache_decimal::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
|
||||
&decimal_value);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
|
||||
@ -7875,8 +7908,11 @@ String* Item_cache_decimal::val_str(String *str)
|
||||
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
|
||||
{
|
||||
DBUG_ASSERT(fixed);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
return &decimal_value;
|
||||
}
|
||||
|
||||
@ -7911,12 +7947,13 @@ double Item_cache_str::val_real()
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int err_not_used;
|
||||
char *end_not_used;
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0.0;
|
||||
if (value)
|
||||
}
|
||||
return my_strntod(value->charset(), (char*) value->ptr(),
|
||||
value->length(), &end_not_used, &err_not_used);
|
||||
return (double) 0;
|
||||
}
|
||||
|
||||
|
||||
@ -7924,21 +7961,24 @@ longlong Item_cache_str::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int err;
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
if (value)
|
||||
}
|
||||
return my_strntoll(value->charset(), value->ptr(),
|
||||
value->length(), 10, (char**) 0, &err);
|
||||
else
|
||||
return (longlong)0;
|
||||
}
|
||||
|
||||
|
||||
String* Item_cache_str::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -7946,20 +7986,24 @@ String* Item_cache_str::val_str(String *str)
|
||||
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
if (value)
|
||||
}
|
||||
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
|
||||
else
|
||||
decimal_val= 0;
|
||||
return decimal_val;
|
||||
}
|
||||
|
||||
|
||||
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
if (!value_cached && !cache_value())
|
||||
if ((!value_cached && !cache_value()) || null_value)
|
||||
{
|
||||
field->set_notnull();
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
int res= Item_cache::save_in_field(field, no_conversions);
|
||||
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
|
||||
value->length() < field->field_length) ? 1 : res;
|
||||
|
Loading…
x
Reference in New Issue
Block a user