1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-35910 Conditions with SP local variables are not pushed into derived table

This bug prevented building conditions that could be pushed into a derived
table if the derived table was used in a query of a stored procedure and
the conditions contained local variables of the procedure. This could lead
to a slow execution of the procedure.
Also in some cases the bug prevented building conditions that could be
pushed from the HAVING condition into the WHERE condition of a query if
the conditions to be built used local variables of a stored procedure.

To failure to build such pushable conditions was due to lack of a proper
implementation of the virtual method to copy items for the objects of the
class Item_splocal.

Approved by Igor Babaev <igor@mariadb.com>
who had to change the original fix that just added the regular copying of
the nodes of the Item_splocal class to take into account the wrappers
do_get_copy() and do_build_clone() introduced after the fix had been
prepared. He also changed the test case to demonstrate that the fix
was really needed for pushdown from HAVING into WHERE.
This commit is contained in:
Galina Shalygina
2025-01-26 20:39:38 -08:00
committed by Igor Babaev
parent 765458c93c
commit dffe3d1fb2
3 changed files with 267 additions and 2 deletions

View File

@@ -8974,3 +8974,179 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2; DROP PROCEDURE p2;
# End of 10.4 tests # End of 10.4 tests
# #
#
# MDEV-35910: Pushdown of conditions with local SP variables
# into materialized derived table
# Pushdown of conditions with local variables from HAVING
# into WHERE
#
CREATE TABLE t1(
pk INT PRIMARY KEY AUTO_INCREMENT,
a INT,
b INT
);
INSERT INTO t1(a,b) VALUES (1, 2), (3, 2), (4, 5);
INSERT INTO t1(a,b) VALUES (3, 7), (4, 1), (3, 4);
CREATE PROCEDURE pushdownDerivedSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
SELECT dt.a
FROM (
SELECT t1.a, MIN(t1.b) as minB
FROM t1
GROUP BY t1.a
) AS dt
WHERE dt.minB = localB AND dt.a = localA + localB;
END$$
CREATE PROCEDURE explainPushdownDerivedSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
EXPLAIN format=json SELECT dt.a
FROM (
SELECT t1.a, MIN(t1.b) as minB
FROM t1
GROUP BY t1.a
) AS dt
WHERE dt.minB = localB AND dt.a = localA + localB;
END$$
CREATE PROCEDURE pushdownFromHavingSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
SELECT t1.a, SUM(b)
FROM t1
GROUP BY t1.a
HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2;
END$$
CREATE PROCEDURE explainPushdownFromHavingSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
EXPLAIN format=json
SELECT t1.a, SUM(b)
FROM t1
GROUP BY t1.a
HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2;
END$$
CALL pushdownDerivedSp();
a
3
set statement optimizer_switch='condition_pushdown_for_derived=off'
for CALL pushdownDerivedSp();
a
3
CALL explainPushdownDerivedSp();
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 6,
"filtered": 100,
"attached_condition": "dt.minB = <cache>(localB@1) and dt.a = <cache>(localA@0 + localB@1)",
"materialized": {
"query_block": {
"select_id": 2,
"having_condition": "minB = <cache>(localB@1)",
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100,
"attached_condition": "t1.a = <cache>(localA@0 + localB@1)"
}
}
}
}
}
}
set statement optimizer_switch='condition_pushdown_for_derived=off' for
CALL explainPushdownDerivedSp();
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 6,
"filtered": 100,
"attached_condition": "dt.minB = <cache>(localB@1) and dt.a = <cache>(localA@0 + localB@1)",
"materialized": {
"query_block": {
"select_id": 2,
"filesort": {
"sort_key": "t1.a",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
}
}
}
}
}
}
CALL pushdownFromHavingSp();
a SUM(b)
1 2
3 13
set statement optimizer_switch='condition_pushdown_from_having=off' for
CALL pushdownFromHavingSp();
a SUM(b)
1 2
3 13
CALL explainPushdownFromHavingSp();
EXPLAIN
{
"query_block": {
"select_id": 1,
"having_condition": "t1.a > <cache>(localA@0) and sum(t1.b) > 10 or t1.a <= <cache>(localB@1) and sum(t1.b) <= 2",
"filesort": {
"sort_key": "t1.a",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100,
"attached_condition": "t1.a > <cache>(localA@0) or t1.a <= <cache>(localB@1)"
}
}
}
}
}
set statement optimizer_switch='condition_pushdown_from_having=off' for
CALL explainPushdownFromHavingSp();
EXPLAIN
{
"query_block": {
"select_id": 1,
"having_condition": "t1.a > <cache>(localA@0) and sum(t1.b) > 10 or t1.a <= <cache>(localB@1) and sum(t1.b) <= 2",
"filesort": {
"sort_key": "t1.a",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
}
}
}
DROP PROCEDURE pushdownDerivedSp;
DROP PROCEDURE explainPushdownDerivedSp;
DROP PROCEDURE pushdownFromHavingSp;
DROP PROCEDURE explainPushdownFromHavingSp;
DROP TABLE t1;
# End of 10.5 tests

View File

@@ -10593,3 +10593,91 @@ DROP PROCEDURE p2;
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #
--echo #
--echo # MDEV-35910: Pushdown of conditions with local SP variables
--echo # into materialized derived table
--echo # Pushdown of conditions with local variables from HAVING
--echo # into WHERE
--echo #
CREATE TABLE t1(
pk INT PRIMARY KEY AUTO_INCREMENT,
a INT,
b INT
);
INSERT INTO t1(a,b) VALUES (1, 2), (3, 2), (4, 5);
INSERT INTO t1(a,b) VALUES (3, 7), (4, 1), (3, 4);
DELIMITER $$;
CREATE PROCEDURE pushdownDerivedSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
SELECT dt.a
FROM (
SELECT t1.a, MIN(t1.b) as minB
FROM t1
GROUP BY t1.a
) AS dt
WHERE dt.minB = localB AND dt.a = localA + localB;
END$$
CREATE PROCEDURE explainPushdownDerivedSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
EXPLAIN format=json SELECT dt.a
FROM (
SELECT t1.a, MIN(t1.b) as minB
FROM t1
GROUP BY t1.a
) AS dt
WHERE dt.minB = localB AND dt.a = localA + localB;
END$$
CREATE PROCEDURE pushdownFromHavingSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
SELECT t1.a, SUM(b)
FROM t1
GROUP BY t1.a
HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2;
END$$
CREATE PROCEDURE explainPushdownFromHavingSp()
BEGIN
DECLARE localA INT DEFAULT 1;
DECLARE localB INT DEFAULT 2;
EXPLAIN format=json
SELECT t1.a, SUM(b)
FROM t1
GROUP BY t1.a
HAVING t1.a > localA AND SUM(b) > 10 OR t1.a <= localB AND SUM(b) <= 2;
END$$
DELIMITER ;$$
CALL pushdownDerivedSp();
set statement optimizer_switch='condition_pushdown_for_derived=off'
for CALL pushdownDerivedSp();
CALL explainPushdownDerivedSp();
set statement optimizer_switch='condition_pushdown_for_derived=off' for
CALL explainPushdownDerivedSp();
CALL pushdownFromHavingSp();
set statement optimizer_switch='condition_pushdown_from_having=off' for
CALL pushdownFromHavingSp();
CALL explainPushdownFromHavingSp();
set statement optimizer_switch='condition_pushdown_from_having=off' for
CALL explainPushdownFromHavingSp();
DROP PROCEDURE pushdownDerivedSp;
DROP PROCEDURE explainPushdownDerivedSp;
DROP PROCEDURE pushdownFromHavingSp;
DROP PROCEDURE explainPushdownFromHavingSp;
DROP TABLE t1;
--echo # End of 10.5 tests

View File

@@ -3099,8 +3099,9 @@ public:
bool append_for_log(THD *thd, String *str) override; bool append_for_log(THD *thd, String *str) override;
Item *do_get_copy(THD *) const override { return nullptr; } Item *do_get_copy(THD *thd) const override
Item *do_build_clone(THD *thd) const override { return nullptr; } { return get_item_copy<Item_splocal>(thd, this); }
Item *do_build_clone(THD *thd) const override { return get_copy(thd); }
/* /*
Override the inherited create_field_for_create_select(), Override the inherited create_field_for_create_select(),