Commit 05f21b21 authored by unknown's avatar unknown

Fixed LP BUG#615378 Incorrect processing of NULL result in Item_cache fixed.

parent b67be0b2
......@@ -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;
......@@ -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;
}
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), &end_not_used, &err_not_used);
}
......@@ -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;
}
return my_strntoll(value->charset(), value->ptr(),
value->length(), 10, (char**) 0, &err);
}
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;
}
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
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;
......
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