mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed bug mdev-11608.
The fix for bug mdev-11488 introduced the virtual method convert_to_basic_const_item for the class Item_cache. The implementation of this method for the class Item_cache_str was not quite correct: the server could crash if the cached item was null. A similar problem could appear for the implementation of this method for the class Item_cache_decimal. Although I could not reproduce the problem I decided to change the code appropriately.
This commit is contained in:
@ -8178,3 +8178,66 @@ EXPLAIN
|
||||
}
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-11608: pushdown of the predicate with cached null value
|
||||
#
|
||||
CREATE TABLE t1 (c VARCHAR(3));
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES ('foo'),('bar');
|
||||
CREATE TABLE t2 (c VARCHAR(3));
|
||||
INSERT INTO t2 VALUES ('foo'),('xyz');
|
||||
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
|
||||
c
|
||||
EXPLAIN FORMAT=JSON
|
||||
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "<subquery2>",
|
||||
"access_type": "system",
|
||||
"rows": 1,
|
||||
"filtered": 100,
|
||||
"materialized": {
|
||||
"unique": 1,
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"table": {
|
||||
"message": "Impossible WHERE"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"table_name": "<derived3>",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "v1.c = NULL",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t1.c = NULL"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (d DECIMAL(10,2));
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (5.37),(1.1);
|
||||
CREATE TABLE t2 (d DECIMAL(10,2));
|
||||
INSERT INTO t2 VALUES ('1.1'),('2.23');
|
||||
SELECT * FROM v1 WHERE v1.d IN ( SELECT MIN(d) FROM t2 WHERE 0 );
|
||||
d
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -1289,3 +1289,33 @@ SELECT * FROM v1 WHERE NULLIF(1, i);
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-11608: pushdown of the predicate with cached null value
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (c VARCHAR(3));
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES ('foo'),('bar');
|
||||
|
||||
CREATE TABLE t2 (c VARCHAR(3));
|
||||
INSERT INTO t2 VALUES ('foo'),('xyz');
|
||||
|
||||
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
|
||||
EXPLAIN FORMAT=JSON
|
||||
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
CREATE TABLE t1 (d DECIMAL(10,2));
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES (5.37),(1.1);
|
||||
|
||||
CREATE TABLE t2 (d DECIMAL(10,2));
|
||||
INSERT INTO t2 VALUES ('1.1'),('2.23');
|
||||
|
||||
SELECT * FROM v1 WHERE v1.d IN ( SELECT MIN(d) FROM t2 WHERE 0 );
|
||||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
19
sql/item.cc
19
sql/item.cc
@ -9703,12 +9703,15 @@ my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
|
||||
Item *Item_cache_decimal::convert_to_basic_const_item(THD *thd)
|
||||
{
|
||||
Item *new_item;
|
||||
my_decimal decimal_value;
|
||||
my_decimal *result= val_decimal(&decimal_value);
|
||||
DBUG_ASSERT(value_cached || example != 0);
|
||||
new_item= null_value ?
|
||||
(Item*) new (thd->mem_root) Item_null(thd) :
|
||||
(Item*) new (thd->mem_root) Item_decimal(thd, result);
|
||||
if (null_value)
|
||||
new_item= (Item*) new (thd->mem_root) Item_null(thd);
|
||||
else
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *result= val_decimal(&decimal_value);
|
||||
new_item= (Item*) new (thd->mem_root) Item_decimal(thd, result);
|
||||
}
|
||||
return new_item;
|
||||
}
|
||||
|
||||
@ -9795,14 +9798,14 @@ bool Item_cache_row::allocate(THD *thd, uint num)
|
||||
Item *Item_cache_str::convert_to_basic_const_item(THD *thd)
|
||||
{
|
||||
Item *new_item;
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff, sizeof(buff), value->charset());
|
||||
String *result= val_str(&tmp);
|
||||
DBUG_ASSERT(value_cached || example != 0);
|
||||
if (null_value)
|
||||
new_item= (Item*) new (thd->mem_root) Item_null(thd);
|
||||
else
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff, sizeof(buff), value->charset());
|
||||
String *result= val_str(&tmp);
|
||||
uint length= result->length();
|
||||
char *tmp_str= thd->strmake(result->ptr(), length);
|
||||
new_item= new (thd->mem_root) Item_string(thd, tmp_str, length,
|
||||
|
Reference in New Issue
Block a user