Skip to content

Commit 5883604

Browse files
Chaithra Gopalareddydahlerlend
authored andcommitted
Bug #30520714: MYSQL SERVER RETURNS UNEXPECTED ROWS WHEN USING STORED
FUNCTIONS IN WHERE CLAUSE When optimizer extracts conditions on constant tables for early evaluation, it does not include conditions that are expensive to evaluate which includes conditions involving stored functions. However, "make_join_select" wrongly concludes that it can remove the entire "where condition" when the extracted condition evaluates to true because it involves only const tables (values are available). Solution: Added a check for "expensive conditions" before removing the "where_cond" Reviewed By: Roy Lyseng <[email protected]>
1 parent 4b06e4a commit 5883604

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

mysql-test/r/sp.result

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8385,3 +8385,22 @@ y
83858385
15
83868386
DROP PROCEDURE v1;
83878387
DROP TABLE t1;
8388+
#
8389+
# Bug#30520714 - MYSQL SERVER RETURNS UNEXPECTED ROWS WHEN USING STORED
8390+
# FUNCTIONS IN WHERE CLAUSE
8391+
#
8392+
CREATE TABLE t1( f1 INT NOT NULL PRIMARY KEY, f2 INT);
8393+
INSERT INTO t1 VALUES (1, 1);
8394+
CREATE FUNCTION ReturnFalse() RETURNS BOOL
8395+
DETERMINISTIC
8396+
BEGIN
8397+
DECLARE result BOOL;
8398+
SET result = FALSE;
8399+
RETURN result;
8400+
END$$
8401+
SELECT IF (COUNT(*) > 0, 'affected', 'not affected') FROM t1
8402+
WHERE f1 = 1 AND f2 AND ReturnFalse();
8403+
IF (COUNT(*) > 0, 'affected', 'not affected')
8404+
not affected
8405+
DROP FUNCTION ReturnFalse;
8406+
DROP TABLE t1;

mysql-test/t/sp.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9780,3 +9780,28 @@ DELIMITER ;$$
97809780
CALL v1(3,2);
97819781
DROP PROCEDURE v1;
97829782
DROP TABLE t1;
9783+
9784+
--echo #
9785+
--echo # Bug#30520714 - MYSQL SERVER RETURNS UNEXPECTED ROWS WHEN USING STORED
9786+
--echo # FUNCTIONS IN WHERE CLAUSE
9787+
--echo #
9788+
9789+
CREATE TABLE t1( f1 INT NOT NULL PRIMARY KEY, f2 INT);
9790+
INSERT INTO t1 VALUES (1, 1);
9791+
9792+
DELIMITER $$;
9793+
9794+
CREATE FUNCTION ReturnFalse() RETURNS BOOL
9795+
DETERMINISTIC
9796+
BEGIN
9797+
DECLARE result BOOL;
9798+
SET result = FALSE;
9799+
RETURN result;
9800+
END$$
9801+
DELIMITER ;$$
9802+
9803+
SELECT IF (COUNT(*) > 0, 'affected', 'not affected') FROM t1
9804+
WHERE f1 = 1 AND f2 AND ReturnFalse();
9805+
9806+
DROP FUNCTION ReturnFalse;
9807+
DROP TABLE t1;

sql/sql_optimizer.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9179,8 +9179,14 @@ static bool make_join_select(JOIN *join, Item *cond) {
91799179
trace_const_cond.add("condition_on_constant_tables", const_cond)
91809180
.add("condition_value", const_cond_result);
91819181
if (const_cond_result) {
9182+
/*
9183+
If all the tables referred by the condition are const tables and
9184+
if the condition is not expensive, we can remove the where condition
9185+
as it will always evaluate to "true".
9186+
*/
91829187
if (join->plan_is_const() &&
9183-
!(cond->used_tables() & ~join->const_table_map)) {
9188+
!(cond->used_tables() & ~join->const_table_map) &&
9189+
!cond->is_expensive()) {
91849190
DBUG_PRINT("info", ("Found always true WHERE condition"));
91859191
join->where_cond = NULL;
91869192
}

0 commit comments

Comments
 (0)