mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-17411 Wrong WHERE optimization with simple CASE and searched CASE
This commit is contained in:
@ -546,5 +546,32 @@ Warnings:
|
|||||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a'
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-17411 Wrong WHERE optimization with simple CASE and searched CASE
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
||||||
|
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||||
|
SELECT * FROM t1 WHERE CASE a WHEN b THEN 1 END=1;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
SELECT * FROM t1 WHERE CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
a b
|
||||||
|
3 3
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
CASE a WHEN b THEN 1 END=1 AND
|
||||||
|
CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
a b
|
||||||
|
3 3
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
CASE a WHEN b THEN 1 END=1 AND
|
||||||
|
CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (case `test`.`t1`.`a` when `test`.`t1`.`b` then 1 end) = 1 and (case when `test`.`t1`.`a` then `test`.`t1`.`b` else 1 end) = 3
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.3 test
|
# End of 10.3 test
|
||||||
#
|
#
|
||||||
|
@ -390,6 +390,28 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a' AND CASE 'a' WHEN 'a' THEN 'a' ELS
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-17411 Wrong WHERE optimization with simple CASE and searched CASE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
||||||
|
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||||
|
SELECT * FROM t1 WHERE CASE a WHEN b THEN 1 END=1;
|
||||||
|
SELECT * FROM t1 WHERE CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
CASE a WHEN b THEN 1 END=1 AND
|
||||||
|
CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 WHERE
|
||||||
|
CASE a WHEN b THEN 1 END=1 AND
|
||||||
|
CASE WHEN a THEN b ELSE 1 END=3;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 test
|
--echo # End of 10.3 test
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -2211,6 +2211,15 @@ protected:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool eq(const Item_args *other, bool binary_cmp) const
|
||||||
|
{
|
||||||
|
for (uint i= 0; i < arg_count ; i++)
|
||||||
|
{
|
||||||
|
if (!args[i]->eq(other->args[i], binary_cmp))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
Item_args(void)
|
Item_args(void)
|
||||||
:args(NULL), arg_count(0)
|
:args(NULL), arg_count(0)
|
||||||
|
@ -1813,10 +1813,7 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
|
|||||||
return 0;
|
return 0;
|
||||||
if (negated != ((Item_func_opt_neg *) item_func)->negated)
|
if (negated != ((Item_func_opt_neg *) item_func)->negated)
|
||||||
return 0;
|
return 0;
|
||||||
for (uint i=0; i < arg_count ; i++)
|
return Item_args::eq(item_func, binary_cmp);
|
||||||
if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2154,6 +2154,7 @@ public:
|
|||||||
DBUG_ASSERT(arg_count >= 2);
|
DBUG_ASSERT(arg_count >= 2);
|
||||||
reorder_args(0);
|
reorder_args(0);
|
||||||
}
|
}
|
||||||
|
enum Functype functype() const { return CASE_SEARCHED_FUNC; }
|
||||||
void print(String *str, enum_query_type query_type);
|
void print(String *str, enum_query_type query_type);
|
||||||
bool fix_length_and_dec();
|
bool fix_length_and_dec();
|
||||||
Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
|
||||||
@ -2206,6 +2207,7 @@ public:
|
|||||||
Predicant_to_list_comparator::cleanup();
|
Predicant_to_list_comparator::cleanup();
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
enum Functype functype() const { return CASE_SIMPLE_FUNC; }
|
||||||
void print(String *str, enum_query_type query_type);
|
void print(String *str, enum_query_type query_type);
|
||||||
bool fix_length_and_dec();
|
bool fix_length_and_dec();
|
||||||
Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
|
Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
|
||||||
|
@ -647,10 +647,7 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const
|
|||||||
(func_type == Item_func::FUNC_SP &&
|
(func_type == Item_func::FUNC_SP &&
|
||||||
my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
|
my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
|
||||||
return 0;
|
return 0;
|
||||||
for (uint i=0; i < arg_count ; i++)
|
return Item_args::eq(item_func, binary_cmp);
|
||||||
if (!args[i]->eq(item_func->args[i], binary_cmp))
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,10 @@ public:
|
|||||||
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
||||||
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
|
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
|
||||||
NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC, DYNCOL_FUNC,
|
NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC, DYNCOL_FUNC,
|
||||||
JSON_EXTRACT_FUNC };
|
JSON_EXTRACT_FUNC,
|
||||||
|
CASE_SEARCHED_FUNC, // Used by ColumnStore/Spider
|
||||||
|
CASE_SIMPLE_FUNC // Used by ColumnStore/spider
|
||||||
|
};
|
||||||
enum Type type() const { return FUNC_ITEM; }
|
enum Type type() const { return FUNC_ITEM; }
|
||||||
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
|
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
|
||||||
Item_func(THD *thd): Item_func_or_sum(thd)
|
Item_func(THD *thd): Item_func_or_sum(thd)
|
||||||
|
Reference in New Issue
Block a user