lists.mariadb.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

commits

Thread Start a new thread
Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
commits@lists.mariadb.org

  • 14603 discussions
[Commits] 4193ef4: MDEV-25631 Crash executing query with VIEW, aggregate and subquery
by IgorBabaev 06 Jan '22

06 Jan '22
revision-id: 4193ef4863771174c16c360a1c6ae780c2d03572 (mariadb-10.2.31-1296-g4193ef4) parent(s): e78668c32eed4a279613affbd4d18a7651817bdf author: Igor Babaev committer: Igor Babaev timestamp: 2022-01-06 00:31:42 -0800 message: MDEV-25631 Crash executing query with VIEW, aggregate and subquery This bug could cause a crash of the server for queries with a derived table whose specification contained the set function using a subquery over a view as its only argument. The crash could happen if the specification of the view contained an outer reference. In this case the aggregation select could be determined incorrectly. The crash also could be observed if a CTE is used instead of the view, but only for queries having at least two references to the CTE. --- mysql-test/r/view.result | 18 ++++++++++++++++++ mysql-test/t/view.test | 20 ++++++++++++++++++++ sql/item.cc | 5 +++++ 3 files changed, 43 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index d278eb1..4edbabf 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -6844,5 +6844,23 @@ drop view v1; CREATE VIEW v1 AS select `t1`.`12345678901234567890123456789012345678901234567890123456789012345` AS `Name_exp_1` from (select '12345678901234567890123456789012345678901234567890123456789012345') `t1`; drop view v1; # +# MDEV-25631: view with outer reference in select used +# as argument of set function +# +create table t1 (c int); +insert into t1 values (1); +create view v1 as select c from t1 where (select t1.c from t1 t) = 1; +select * from (select sum((select * from v1)) as r) dt; +r +1 +with cte as (select c from t1 where (select t1.c from t1 t) = 1) +select * from (select sum((select * from cte)) as r) dt1 +union +select * from (select sum((select * from cte)) as r) dt2; +r +1 +drop view v1; +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4fb1806..6265a51 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -6575,8 +6575,28 @@ drop view v1; eval CREATE VIEW v1 AS $definition; + drop view v1; --echo # +--echo # MDEV-25631: view with outer reference in select used +--echo # as argument of set function +--echo # + +create table t1 (c int); +insert into t1 values (1); +create view v1 as select c from t1 where (select t1.c from t1 t) = 1; + +select * from (select sum((select * from v1)) as r) dt; + +with cte as (select c from t1 where (select t1.c from t1 t) = 1) +select * from (select sum((select * from cte)) as r) dt1 +union +select * from (select sum((select * from cte)) as r) dt2; + +drop view v1; +drop table t1; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 109ca4e..598597b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5266,6 +5266,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) max_arg_level for the function if it's needed. */ if (thd->lex->in_sum_func && + thd->lex == context->select_lex->parent_lex && thd->lex->in_sum_func->nest_level >= select->nest_level) { Item::Type ref_type= (*reference)->type(); @@ -5291,6 +5292,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) (Item_ident*) (*reference) : 0), false); if (thd->lex->in_sum_func && + thd->lex == context->select_lex->parent_lex && thd->lex->in_sum_func->nest_level >= select->nest_level) { set_if_bigger(thd->lex->in_sum_func->max_arg_level, @@ -5619,6 +5621,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) if (!thd->lex->current_select->no_wrap_view_item && thd->lex->in_sum_func && + thd->lex == select->parent_lex && thd->lex->in_sum_func->nest_level == select->nest_level) set_if_bigger(thd->lex->in_sum_func->max_arg_level, @@ -7704,6 +7707,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) max_arg_level for the function if it's needed. */ if (thd->lex->in_sum_func && + thd->lex == context->select_lex->parent_lex && thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) set_if_bigger(thd->lex->in_sum_func->max_arg_level, @@ -7727,6 +7731,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) max_arg_level for the function if it's needed. */ if (thd->lex->in_sum_func && + thd->lex == context->select_lex->parent_lex && thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) set_if_bigger(thd->lex->in_sum_func->max_arg_level,
1 0
0 0
[Commits] e78668c: MDEV-25086 Stored Procedure Crashes Server
by IgorBabaev 06 Jan '22

06 Jan '22
revision-id: e78668c32eed4a279613affbd4d18a7651817bdf (mariadb-10.2.31-1295-ge78668c) parent(s): 07145ea7a08eed9bd86781849865fa106a247789 author: Igor Babaev committer: Igor Babaev timestamp: 2022-01-05 22:36:20 -0800 message: MDEV-25086 Stored Procedure Crashes Server The cause of this bug is the same as of the bug MDEV-24454. This bug manifested itself at the second execution of the queries that contained a set function whose only argument was outer reference to a column of a mergeable view or derived table or CTE. The first execution of such query worked fine, but the second execution of the query caused a crash of the server because the aggregation select for the used set function was determined incorrectly at the name resolution phase of the second execution. --- mysql-test/r/derived_view.result | 130 +++++++++++++++++++++++++++++++++++++++ mysql-test/t/derived_view.test | 111 +++++++++++++++++++++++++++++++++ sql/item.cc | 3 +- 3 files changed, 243 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index d8ee508..0c045e3 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -3456,4 +3456,134 @@ a 3 drop view v1; drop table t1; +# +# MDEV-24454 Second execution of SELECT containing set function +# MDEV-25086: whose only argument is an outer reference to a column +# of mergeable view/derived/table/CTE +# +create table t1 (a int); +create table t2 (b int); +insert into t1 values (3), (1), (3); +insert into t2 values (70), (30), (70); +create view v1 as select * from t2; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from v1; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from v1 where b > 50) dt; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from (select * from t2) dt1 where b > 50) dt; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +prepare stmt from " +with cte as (select * from (select * from t2) dt1 where b > 50) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from v1; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +create procedure sp1() +begin +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +drop view v1; +drop table t1,t2; +CREATE TABLE t1(f0 INT); +INSERT INTO t1 VALUES (3); +CREATE VIEW v1 AS SELECT f0 AS f1 FROM t1; +CREATE VIEW v2 AS +SELECT +(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') FROM v1 n) AS f2, +GROUP_CONCAT('aa' SEPARATOR ', ') AS f3 +FROM v1; +CREATE VIEW v3 AS SELECT * FROM v2; +CREATE PROCEDURE p1() +SELECT * FROM v3; +CALL p1(); +f2 f3 +3 aa +CALL p1(); +f2 f3 +3 aa +DROP PROCEDURE p1; +DROP VIEW v1,v2,v3; +DROP TABLE t1; # End of 10.2 tests diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index 89ada40..0f3d9b2 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -2265,4 +2265,115 @@ select * from ((select a from t1 limit 2) order by a desc) dt; drop view v1; drop table t1; +--echo # +--echo # MDEV-24454 Second execution of SELECT containing set function +--echo # MDEV-25086: whose only argument is an outer reference to a column +--echo # of mergeable view/derived/table/CTE +--echo # + +create table t1 (a int); +create table t2 (b int); +insert into t1 values (3), (1), (3); +insert into t2 values (70), (30), (70); +create view v1 as select * from t2; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from v1; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from v1 where b > 50) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from (select * from t2) dt1 where b > 50) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +with cte as (select * from (select * from t2) dt1 where b > 50) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +--delimiter | +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from v1; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +--delimiter | +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +--delimiter | +create procedure sp1() +begin +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +drop view v1; +drop table t1,t2; + +CREATE TABLE t1(f0 INT); +INSERT INTO t1 VALUES (3); +CREATE VIEW v1 AS SELECT f0 AS f1 FROM t1; +CREATE VIEW v2 AS +SELECT + (SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') FROM v1 n) AS f2, + GROUP_CONCAT('aa' SEPARATOR ', ') AS f3 +FROM v1; +CREATE VIEW v3 AS SELECT * FROM v2; + +CREATE PROCEDURE p1() + SELECT * FROM v3; +CALL p1(); +CALL p1(); + +DROP PROCEDURE p1; +DROP VIEW v1,v2,v3; +DROP TABLE t1; + --echo # End of 10.2 tests diff --git a/sql/item.cc b/sql/item.cc index 17c56fe..109ca4e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5617,7 +5617,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto mark_non_agg_field; } - if (thd->lex->in_sum_func && + if (!thd->lex->current_select->no_wrap_view_item && + thd->lex->in_sum_func && thd->lex->in_sum_func->nest_level == select->nest_level) set_if_bigger(thd->lex->in_sum_func->max_arg_level,
1 0
0 0
[Commits] 7ab00c4: MDEV-25086 Stored Procedure Crashes Server
by IgorBabaev 06 Jan '22

06 Jan '22
revision-id: 7ab00c4c7c165107ccf7a1311042a45bfa6a7c62 (mariadb-10.2.31-1295-g7ab00c4) parent(s): 07145ea7a08eed9bd86781849865fa106a247789 author: Igor Babaev committer: Igor Babaev timestamp: 2022-01-05 22:24:23 -0800 message: MDEV-25086 Stored Procedure Crashes Server The cause of this bug is the same as of the bug MDEV-24454. This bug manifested itself at the second execution of the queries that contained a set function whose only argument was outer reference to a column of a mergeable view or derived table or CTE. The first execution of such query worked fine, but the second execution of the query caused a crash of the server because the aggregation select for the used set function was determined incorrectly at the name resolution phase of the second execution. --- mysql-test/r/derived_view.result | 130 +++++++++++++++++++++++++++++++++++++++ mysql-test/t/derived_view.test | 111 +++++++++++++++++++++++++++++++++ sql/item.cc | 3 +- 3 files changed, 243 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index d8ee508..0d9b7e1 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -3456,4 +3456,134 @@ a 3 drop view v1; drop table t1; +# +# MDEV-24454 Second execution of SELECT containing set function +# MDEV-25086: whose only argument is an outer reference to a column +# of mergeable view/derived/table/CTE +# +create table t1 (a int); +create table t2 (b int); +insert into t1 values (3), (1), (3); +insert into t2 values (70), (30), (70); +create view v1 as select * from t2; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from v1; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +r +170 +execute stmt; +r +170 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from v1 where b > 50) dt; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from (select * from t2) dt1 where b > 50) dt; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +prepare stmt from " +with cte as (select * from (select * from t2) dt1 where b > 50) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +r +140 +execute stmt; +r +140 +deallocate prepare stmt; +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from v1; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +create procedure sp1() +begin +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +end | +call sp1(); +r +170 +call sp1(); +r +170 +drop procedure sp1; +drop view v1; +drop table t1,t2; +CREATE TABLE t1(f0 INT); +INSERT INTO t1 VALUES (3); +CREATE VIEW v1 AS SELECT f0 AS f1 FROM t1; +CREATE VIEW v2 AS +SELECT +(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') FROM v1 n) AS f2, +GROUP_CONCAT('aa' SEPARATOR ', ') AS f3 +FROM v1; +CREATE VIEW v3 AS SELECT * FROM v2; +CREATE PROCEDURE p1() +SELECT * FROM v3; +CALL p1(); +f2 f3 +3 aa +CALL p1(); +f2 f3 +3 aa +DROP PROCEDURE p1; +DROP VIEW v1,v2,v3; +DROP TABLE t1; # End of 10.2 tests diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index 89ada40..0f3d9b2 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -2265,4 +2265,115 @@ select * from ((select a from t1 limit 2) order by a desc) dt; drop view v1; drop table t1; +--echo # +--echo # MDEV-24454 Second execution of SELECT containing set function +--echo # MDEV-25086: whose only argument is an outer reference to a column +--echo # of mergeable view/derived/table/CTE +--echo # + +create table t1 (a int); +create table t2 (b int); +insert into t1 values (3), (1), (3); +insert into t2 values (70), (30), (70); +create view v1 as select * from t2; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from v1; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from v1 where b > 50) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +select (select sum(b) from t1 where a=1) as r +from (select * from (select * from t2) dt1 where b > 50) dt; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +prepare stmt from " +with cte as (select * from (select * from t2) dt1 where b > 50) +select (select sum(b) from t1 where a=1) as r from cte; +"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +--delimiter | +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from v1; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +--delimiter | +create procedure sp1() +begin +select (select sum(b) from t1 where a=1) as r from (select * from t2) dt; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +--delimiter | +create procedure sp1() +begin +with cte as (select * from t2) +select (select sum(b) from t1 where a=1) as r from cte; +end | +--delimiter ; +call sp1(); +call sp1(); +drop procedure sp1; + +drop view v1; +drop table t1,t2; + +CREATE TABLE t1(f0 INT); +INSERT INTO t1 VALUES (3); +CREATE VIEW v1 AS SELECT f0 AS f1 FROM t1; +CREATE VIEW v2 AS +SELECT + (SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') FROM v1 n) AS f2, + GROUP_CONCAT('aa' SEPARATOR ', ') AS f3 +FROM v1; +CREATE VIEW v3 AS SELECT * FROM v2; + +CREATE PROCEDURE p1() + SELECT * FROM v3; +CALL p1(); +CALL p1(); + +DROP PROCEDURE p1; +DROP VIEW v1,v2,v3; +DROP TABLE t1; + --echo # End of 10.2 tests diff --git a/sql/item.cc b/sql/item.cc index 17c56fe..109ca4e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5617,7 +5617,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto mark_non_agg_field; } - if (thd->lex->in_sum_func && + if (!thd->lex->current_select->no_wrap_view_item && + thd->lex->in_sum_func && thd->lex->in_sum_func->nest_level == select->nest_level) set_if_bigger(thd->lex->in_sum_func->max_arg_level,
1 0
0 0
[Commits] 07145ea: Revert "MDEV-24454 Crash at change_item_tree"
by IgorBabaev 06 Jan '22

06 Jan '22
revision-id: 07145ea7a08eed9bd86781849865fa106a247789 (mariadb-10.2.31-1294-g07145ea) parent(s): 42fea34d4a9f4ed1ae87cf8494f07bcdfcc49e83 author: Igor Babaev committer: Igor Babaev timestamp: 2022-01-05 20:23:52 -0800 message: Revert "MDEV-24454 Crash at change_item_tree" This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from the commit 3690c549c6e72646ba74f6b4c83813ee4ac3aea4. It leaves the changes in plugin/feedback/feedback.cc and corresponding test files introduced in this commit intact. Proper fixes for the bug MDEV-24454 and MDEV-25631 will follow immediately. --- mysql-test/r/view.result | 43 -------------------- mysql-test/t/view.test | 50 ----------------------- sql/item.cc | 104 ++++++++++++++++------------------------------- sql/item.h | 1 - sql/item_subselect.cc | 3 +- sql/item_sum.cc | 8 ++-- sql/sql_base.cc | 1 - sql/sql_prepare.cc | 2 +- 8 files changed, 39 insertions(+), 173 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 001d26f..d278eb1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -6833,49 +6833,6 @@ sum(z) DROP TABLE t1; DROP VIEW v1; # -# MDEV-24454: Crash at change_item_tree -# -CREATE TABLE t1(f0 INT); -CREATE VIEW v1 AS -SELECT -f0 AS f1 -FROM t1; -CREATE VIEW v2 AS -SELECT -(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') -FROM v1 n) AS f2, -GROUP_CONCAT('' SEPARATOR ', ') AS f3 -FROM v1; -CREATE VIEW v3 AS -SELECT 1 as f4 FROM v2; -CREATE PROCEDURE p1() -SELECT * FROM v3; -CALL p1(); -f4 -1 -CALL p1(); -f4 -1 -drop procedure p1; -drop view v1,v2,v3; -drop table t1; -# -# MDEV-25631: Crash in st_select_lex::mark_as_dependent with -# VIEW, aggregate and subquery -# -CREATE TABLE t1 (i1 int); -insert into t1 values (1),(2),(3); -CREATE VIEW v1 AS -SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b))); -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -ERROR 21000: Subquery returns more than 1 row -delete from t1 where i1 > 1; -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -1 -1 -drop view v1; -drop table t1; -# # MDEV-26299: Some views force server (and mysqldump) to generate # invalid SQL for their definitions # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index e6e6ccc..4fb1806 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -6560,56 +6560,6 @@ DROP TABLE t1; DROP VIEW v1; --echo # ---echo # MDEV-24454: Crash at change_item_tree ---echo # - -CREATE TABLE t1(f0 INT); - -CREATE VIEW v1 AS -SELECT - f0 AS f1 -FROM t1; - -CREATE VIEW v2 AS -SELECT - (SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') - FROM v1 n) AS f2, - GROUP_CONCAT('' SEPARATOR ', ') AS f3 -FROM v1; - -CREATE VIEW v3 AS -SELECT 1 as f4 FROM v2; - -CREATE PROCEDURE p1() - SELECT * FROM v3; - -CALL p1(); -CALL p1(); - -drop procedure p1; -drop view v1,v2,v3; -drop table t1; - ---echo # ---echo # MDEV-25631: Crash in st_select_lex::mark_as_dependent with ---echo # VIEW, aggregate and subquery ---echo # - -CREATE TABLE t1 (i1 int); -insert into t1 values (1),(2),(3); #not important -CREATE VIEW v1 AS - SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b))); - ---error ER_SUBQUERY_NO_1_ROW -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -delete from t1 where i1 > 1; -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; - -drop view v1; -drop table t1; - - ---echo # --echo # MDEV-26299: Some views force server (and mysqldump) to generate --echo # invalid SQL for their definitions --echo # diff --git a/sql/item.cc b/sql/item.cc index 3ff0219..17c56fe 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -61,12 +61,11 @@ bool cmp_items(Item *a, Item *b) /** Set max_sum_func_level if it is needed */ -inline void set_max_sum_func_level(SELECT_LEX *select) +inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select) { - LEX *lex_s= select->parent_lex; - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) - set_if_bigger(lex_s->in_sum_func->max_sum_func_level, + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) + set_if_bigger(thd->lex->in_sum_func->max_sum_func_level, select->nest_level - 1); } @@ -781,7 +780,6 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg, { name = (char*) field_name_arg; name_length= name ? strlen(name) : 0; - DBUG_ASSERT(!context || context->select_lex); } @@ -796,7 +794,6 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, const char *field_name_ar { name = (char*) field_name_arg; name_length= name ? strlen(name) : 0; - DBUG_ASSERT(!context || context->select_lex); } @@ -818,9 +815,7 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) cached_table(item->cached_table), depended_from(item->depended_from), can_be_depended(item->can_be_depended) -{ - DBUG_ASSERT(!context || context->select_lex); -} +{} void Item_ident::cleanup() { @@ -5162,14 +5157,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) */ Name_resolution_context *last_checked_context= context; Item **ref= (Item **) not_found_item; - /* - There are cases when name resolution context is absent (when we are not - doing name resolution), but here the name resolution context should - be present because we are doing name resolution - */ - DBUG_ASSERT(context); - SELECT_LEX *current_sel= context->select_lex; - LEX *lex_s= context->select_lex->parent_lex; + SELECT_LEX *current_sel= thd->lex->current_select; Name_resolution_context *outer_context= 0; SELECT_LEX *select= 0; /* Currently derived tables cannot be correlated */ @@ -5270,18 +5258,18 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) return -1; thd->change_item_tree(reference, rf); select->inner_refs_list.push_back(rf, thd->mem_root); - rf->in_sum_func= lex_s->in_sum_func; + rf->in_sum_func= thd->lex->in_sum_func; } /* A reference is resolved to a nest level that's outer or the same as the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) { Item::Type ref_type= (*reference)->type(); - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); set_field(*from_field); fixed= 1; @@ -5302,10 +5290,10 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? (Item_ident*) (*reference) : 0), false); - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) { - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); } /* @@ -5397,7 +5385,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) { outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf, thd->mem_root); - ((Item_outer_ref*)rf)->in_sum_func= lex_s->in_sum_func; + ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func; } thd->change_item_tree(reference, rf); /* @@ -5412,7 +5400,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, rf, rf, false); @@ -5425,7 +5413,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, this, (Item_ident*)*reference, false); @@ -5502,20 +5490,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) DBUG_ASSERT(fixed == 0); Field *from_field= (Field *)not_found_field; bool outer_fixed= false; - SELECT_LEX *select; - LEX *lex_s; - if (context) - { - select= context->select_lex; - lex_s= context->select_lex->parent_lex; - } - else - { - // No real name resolution, used somewhere in SP - DBUG_ASSERT(field); - select= NULL; - lex_s= NULL; - } + SELECT_LEX *select= thd->lex->current_select; if (!field) // If field is not checked { @@ -5576,7 +5551,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); set_field(new_field); depended_from= (*((Item_field**)res))->depended_from; return 0; @@ -5605,7 +5580,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); return FALSE; } } @@ -5642,11 +5617,10 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto mark_non_agg_field; } - if (lex_s && - lex_s->in_sum_func && - lex_s->in_sum_func->nest_level == + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level == select->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); /* if it is not expression from merged VIEW we will set this field. @@ -5712,9 +5686,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference) if (field->vcol_info) fix_session_vcol_expr_for_read(thd, field, field->vcol_info); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && - !outer_fixed && + !outer_fixed && !thd->lex->in_sum_func && select && - !lex_s->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS && select->join) { @@ -5749,13 +5722,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference) */ select_lex= context->select_lex; } - if (!lex_s || !lex_s->in_sum_func) + if (!thd->lex->in_sum_func) select_lex->set_non_agg_field_used(true); else { if (outer_fixed) - lex_s->in_sum_func->outer_fields.push_back(this, thd->mem_root); - else if (lex_s->in_sum_func->nest_level != + thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root); + else if (thd->lex->in_sum_func->nest_level != select->nest_level) select_lex->set_non_agg_field_used(true); } @@ -7248,12 +7221,6 @@ Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel) return NULL; } -Item *Item_ident::derived_field_transformer_for_having(THD *thd, uchar *arg) -{ - st_select_lex *sel= (st_select_lex *)arg; - context= &sel->context; - return this; -} Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) { @@ -7273,13 +7240,12 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd, uchar *arg) { - st_select_lex *sel= (st_select_lex *)arg; - context= &sel->context; if ((*ref)->marker & SUBSTITUTION_FL) { this->marker|= SUBSTITUTION_FL; return this; } + st_select_lex *sel= (st_select_lex *)arg; table_map tab_map= sel->master_unit()->derived->table->map; if ((item_equal && !(item_equal->used_tables() & tab_map)) || !item_equal) @@ -7575,9 +7541,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) { enum_parsing_place place= NO_MATTER; DBUG_ASSERT(fixed == 0); - - SELECT_LEX *current_sel= context->select_lex; - LEX *lex_s= context->select_lex->parent_lex; + SELECT_LEX *current_sel= thd->lex->current_select; if (set_properties_only) { @@ -7738,10 +7702,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, last_checked_context->select_lex->nest_level); return FALSE; } @@ -7761,10 +7725,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, last_checked_context->select_lex->nest_level); } } diff --git a/sql/item.h b/sql/item.h index 2a904c1..0000461 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2630,7 +2630,6 @@ class Item_ident :public Item_result_field Collect outer references */ virtual bool collect_outer_ref_processor(void *arg); - Item *derived_field_transformer_for_having(THD *thd, uchar *arg); friend bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator<Item> *it, diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 3f9a760..25621df 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -5190,9 +5190,8 @@ bool subselect_hash_sj_engine::make_semi_join_conds() NULL, TL_READ); tmp_table_ref->table= tmp_table; - context= new (thd->mem_root) Name_resolution_context; + context= new Name_resolution_context; context->init(); - context->select_lex= item_in->unit->first_select(); context->first_name_resolution_table= context->last_name_resolution_table= tmp_table_ref; semi_join_conds_context= context; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index f20be3b..dd65f04 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -68,7 +68,6 @@ size_t Item_sum::ram_limitation(THD *thd) bool Item_sum::init_sum_func_check(THD *thd) { SELECT_LEX *curr_sel= thd->lex->current_select; - LEX *lex_s= (curr_sel ? curr_sel->parent_lex : thd->lex); if (curr_sel && !curr_sel->name_visibility_map) { for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select()) @@ -83,9 +82,9 @@ bool Item_sum::init_sum_func_check(THD *thd) return TRUE; } /* Set a reference to the nesting set function if there is any */ - in_sum_func= lex_s->in_sum_func; + in_sum_func= thd->lex->in_sum_func; /* Save a pointer to object to be used in items for nested set functions */ - lex_s->in_sum_func= this; + thd->lex->in_sum_func= this; nest_level= thd->lex->current_select->nest_level; ref_by= 0; aggr_level= -1; @@ -152,7 +151,6 @@ bool Item_sum::init_sum_func_check(THD *thd) bool Item_sum::check_sum_func(THD *thd, Item **ref) { SELECT_LEX *curr_sel= thd->lex->current_select; - LEX *lex_s= curr_sel->parent_lex; nesting_map allow_sum_func= (thd->lex->allow_sum_func & curr_sel->name_visibility_map); bool invalid= FALSE; @@ -312,7 +310,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) } aggr_sel->set_agg_func_used(true); update_used_tables(); - lex_s->in_sum_func= in_sum_func; + thd->lex->in_sum_func= in_sum_func; return FALSE; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5173df2..9a66b27 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6440,7 +6440,6 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref) if (!(context= new (thd->mem_root) Name_resolution_context)) return TRUE; context->init(); - context->select_lex= table_ref->select_lex; context->first_name_resolution_table= context->last_name_resolution_table= table_ref; item->context= context; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9339cb9..624bcb9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3060,7 +3060,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } for (; sl; sl= sl->next_select_in_list()) { - sl->parent_lex->in_sum_func= NULL; if (sl->changed_elements & TOUCHED_SEL_COND) { /* remove option which was put by mysql_explain_union() */ @@ -3191,6 +3190,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) lex->result->set_thd(thd); } lex->allow_sum_func= 0; + lex->in_sum_func= NULL; DBUG_VOID_RETURN; }
1 0
0 0
[Commits] 7ca0384: Revert "MDEV-24454 Crash at change_item_tree"
by IgorBabaev 06 Jan '22

06 Jan '22
revision-id: 7ca0384c9a0bb54751898e0e8959b9ac8c45308b (mariadb-10.2.31-1294-g7ca0384) parent(s): 42fea34d4a9f4ed1ae87cf8494f07bcdfcc49e83 author: Igor Babaev committer: Igor Babaev timestamp: 2022-01-05 20:16:02 -0800 message: Revert "MDEV-24454 Crash at change_item_tree" This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from the commit 3690c549c6e72646ba74f6b4c83813ee4ac3aea4. --- mysql-test/r/view.result | 43 -------------------- mysql-test/t/view.test | 50 ----------------------- sql/item.cc | 104 ++++++++++++++++------------------------------- sql/item.h | 1 - sql/item_subselect.cc | 3 +- sql/item_sum.cc | 8 ++-- sql/sql_base.cc | 1 - sql/sql_prepare.cc | 2 +- 8 files changed, 39 insertions(+), 173 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 001d26f..d278eb1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -6833,49 +6833,6 @@ sum(z) DROP TABLE t1; DROP VIEW v1; # -# MDEV-24454: Crash at change_item_tree -# -CREATE TABLE t1(f0 INT); -CREATE VIEW v1 AS -SELECT -f0 AS f1 -FROM t1; -CREATE VIEW v2 AS -SELECT -(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') -FROM v1 n) AS f2, -GROUP_CONCAT('' SEPARATOR ', ') AS f3 -FROM v1; -CREATE VIEW v3 AS -SELECT 1 as f4 FROM v2; -CREATE PROCEDURE p1() -SELECT * FROM v3; -CALL p1(); -f4 -1 -CALL p1(); -f4 -1 -drop procedure p1; -drop view v1,v2,v3; -drop table t1; -# -# MDEV-25631: Crash in st_select_lex::mark_as_dependent with -# VIEW, aggregate and subquery -# -CREATE TABLE t1 (i1 int); -insert into t1 values (1),(2),(3); -CREATE VIEW v1 AS -SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b))); -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -ERROR 21000: Subquery returns more than 1 row -delete from t1 where i1 > 1; -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -1 -1 -drop view v1; -drop table t1; -# # MDEV-26299: Some views force server (and mysqldump) to generate # invalid SQL for their definitions # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index e6e6ccc..4fb1806 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -6560,56 +6560,6 @@ DROP TABLE t1; DROP VIEW v1; --echo # ---echo # MDEV-24454: Crash at change_item_tree ---echo # - -CREATE TABLE t1(f0 INT); - -CREATE VIEW v1 AS -SELECT - f0 AS f1 -FROM t1; - -CREATE VIEW v2 AS -SELECT - (SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ') - FROM v1 n) AS f2, - GROUP_CONCAT('' SEPARATOR ', ') AS f3 -FROM v1; - -CREATE VIEW v3 AS -SELECT 1 as f4 FROM v2; - -CREATE PROCEDURE p1() - SELECT * FROM v3; - -CALL p1(); -CALL p1(); - -drop procedure p1; -drop view v1,v2,v3; -drop table t1; - ---echo # ---echo # MDEV-25631: Crash in st_select_lex::mark_as_dependent with ---echo # VIEW, aggregate and subquery ---echo # - -CREATE TABLE t1 (i1 int); -insert into t1 values (1),(2),(3); #not important -CREATE VIEW v1 AS - SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b))); - ---error ER_SUBQUERY_NO_1_ROW -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; -delete from t1 where i1 > 1; -SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ; - -drop view v1; -drop table t1; - - ---echo # --echo # MDEV-26299: Some views force server (and mysqldump) to generate --echo # invalid SQL for their definitions --echo # diff --git a/sql/item.cc b/sql/item.cc index 3ff0219..17c56fe 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -61,12 +61,11 @@ bool cmp_items(Item *a, Item *b) /** Set max_sum_func_level if it is needed */ -inline void set_max_sum_func_level(SELECT_LEX *select) +inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select) { - LEX *lex_s= select->parent_lex; - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) - set_if_bigger(lex_s->in_sum_func->max_sum_func_level, + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) + set_if_bigger(thd->lex->in_sum_func->max_sum_func_level, select->nest_level - 1); } @@ -781,7 +780,6 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg, { name = (char*) field_name_arg; name_length= name ? strlen(name) : 0; - DBUG_ASSERT(!context || context->select_lex); } @@ -796,7 +794,6 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, const char *field_name_ar { name = (char*) field_name_arg; name_length= name ? strlen(name) : 0; - DBUG_ASSERT(!context || context->select_lex); } @@ -818,9 +815,7 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) cached_table(item->cached_table), depended_from(item->depended_from), can_be_depended(item->can_be_depended) -{ - DBUG_ASSERT(!context || context->select_lex); -} +{} void Item_ident::cleanup() { @@ -5162,14 +5157,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) */ Name_resolution_context *last_checked_context= context; Item **ref= (Item **) not_found_item; - /* - There are cases when name resolution context is absent (when we are not - doing name resolution), but here the name resolution context should - be present because we are doing name resolution - */ - DBUG_ASSERT(context); - SELECT_LEX *current_sel= context->select_lex; - LEX *lex_s= context->select_lex->parent_lex; + SELECT_LEX *current_sel= thd->lex->current_select; Name_resolution_context *outer_context= 0; SELECT_LEX *select= 0; /* Currently derived tables cannot be correlated */ @@ -5270,18 +5258,18 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) return -1; thd->change_item_tree(reference, rf); select->inner_refs_list.push_back(rf, thd->mem_root); - rf->in_sum_func= lex_s->in_sum_func; + rf->in_sum_func= thd->lex->in_sum_func; } /* A reference is resolved to a nest level that's outer or the same as the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) { Item::Type ref_type= (*reference)->type(); - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); set_field(*from_field); fixed= 1; @@ -5302,10 +5290,10 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? (Item_ident*) (*reference) : 0), false); - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= select->nest_level) + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= select->nest_level) { - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); } /* @@ -5397,7 +5385,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) { outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf, thd->mem_root); - ((Item_outer_ref*)rf)->in_sum_func= lex_s->in_sum_func; + ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func; } thd->change_item_tree(reference, rf); /* @@ -5412,7 +5400,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, rf, rf, false); @@ -5425,7 +5413,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, this, (Item_ident*)*reference, false); @@ -5502,20 +5490,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) DBUG_ASSERT(fixed == 0); Field *from_field= (Field *)not_found_field; bool outer_fixed= false; - SELECT_LEX *select; - LEX *lex_s; - if (context) - { - select= context->select_lex; - lex_s= context->select_lex->parent_lex; - } - else - { - // No real name resolution, used somewhere in SP - DBUG_ASSERT(field); - select= NULL; - lex_s= NULL; - } + SELECT_LEX *select= thd->lex->current_select; if (!field) // If field is not checked { @@ -5576,7 +5551,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); set_field(new_field); depended_from= (*((Item_field**)res))->depended_from; return 0; @@ -5605,7 +5580,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) We can not "move" aggregate function in the place where its arguments are not defined. */ - set_max_sum_func_level(select); + set_max_sum_func_level(thd, select); return FALSE; } } @@ -5642,11 +5617,10 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto mark_non_agg_field; } - if (lex_s && - lex_s->in_sum_func && - lex_s->in_sum_func->nest_level == + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level == select->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, select->nest_level); /* if it is not expression from merged VIEW we will set this field. @@ -5712,9 +5686,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference) if (field->vcol_info) fix_session_vcol_expr_for_read(thd, field, field->vcol_info); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && - !outer_fixed && + !outer_fixed && !thd->lex->in_sum_func && select && - !lex_s->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS && select->join) { @@ -5749,13 +5722,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference) */ select_lex= context->select_lex; } - if (!lex_s || !lex_s->in_sum_func) + if (!thd->lex->in_sum_func) select_lex->set_non_agg_field_used(true); else { if (outer_fixed) - lex_s->in_sum_func->outer_fields.push_back(this, thd->mem_root); - else if (lex_s->in_sum_func->nest_level != + thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root); + else if (thd->lex->in_sum_func->nest_level != select->nest_level) select_lex->set_non_agg_field_used(true); } @@ -7248,12 +7221,6 @@ Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel) return NULL; } -Item *Item_ident::derived_field_transformer_for_having(THD *thd, uchar *arg) -{ - st_select_lex *sel= (st_select_lex *)arg; - context= &sel->context; - return this; -} Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) { @@ -7273,13 +7240,12 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd, uchar *arg) { - st_select_lex *sel= (st_select_lex *)arg; - context= &sel->context; if ((*ref)->marker & SUBSTITUTION_FL) { this->marker|= SUBSTITUTION_FL; return this; } + st_select_lex *sel= (st_select_lex *)arg; table_map tab_map= sel->master_unit()->derived->table->map; if ((item_equal && !(item_equal->used_tables() & tab_map)) || !item_equal) @@ -7575,9 +7541,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) { enum_parsing_place place= NO_MATTER; DBUG_ASSERT(fixed == 0); - - SELECT_LEX *current_sel= context->select_lex; - LEX *lex_s= context->select_lex->parent_lex; + SELECT_LEX *current_sel= thd->lex->current_select; if (set_properties_only) { @@ -7738,10 +7702,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, last_checked_context->select_lex->nest_level); return FALSE; } @@ -7761,10 +7725,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) the nest level of the enclosing set function : adjust the value of max_arg_level for the function if it's needed. */ - if (lex_s->in_sum_func && - lex_s->in_sum_func->nest_level >= + if (thd->lex->in_sum_func && + thd->lex->in_sum_func->nest_level >= last_checked_context->select_lex->nest_level) - set_if_bigger(lex_s->in_sum_func->max_arg_level, + set_if_bigger(thd->lex->in_sum_func->max_arg_level, last_checked_context->select_lex->nest_level); } } diff --git a/sql/item.h b/sql/item.h index 2a904c1..0000461 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2630,7 +2630,6 @@ class Item_ident :public Item_result_field Collect outer references */ virtual bool collect_outer_ref_processor(void *arg); - Item *derived_field_transformer_for_having(THD *thd, uchar *arg); friend bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator<Item> *it, diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 3f9a760..25621df 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -5190,9 +5190,8 @@ bool subselect_hash_sj_engine::make_semi_join_conds() NULL, TL_READ); tmp_table_ref->table= tmp_table; - context= new (thd->mem_root) Name_resolution_context; + context= new Name_resolution_context; context->init(); - context->select_lex= item_in->unit->first_select(); context->first_name_resolution_table= context->last_name_resolution_table= tmp_table_ref; semi_join_conds_context= context; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index f20be3b..dd65f04 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -68,7 +68,6 @@ size_t Item_sum::ram_limitation(THD *thd) bool Item_sum::init_sum_func_check(THD *thd) { SELECT_LEX *curr_sel= thd->lex->current_select; - LEX *lex_s= (curr_sel ? curr_sel->parent_lex : thd->lex); if (curr_sel && !curr_sel->name_visibility_map) { for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select()) @@ -83,9 +82,9 @@ bool Item_sum::init_sum_func_check(THD *thd) return TRUE; } /* Set a reference to the nesting set function if there is any */ - in_sum_func= lex_s->in_sum_func; + in_sum_func= thd->lex->in_sum_func; /* Save a pointer to object to be used in items for nested set functions */ - lex_s->in_sum_func= this; + thd->lex->in_sum_func= this; nest_level= thd->lex->current_select->nest_level; ref_by= 0; aggr_level= -1; @@ -152,7 +151,6 @@ bool Item_sum::init_sum_func_check(THD *thd) bool Item_sum::check_sum_func(THD *thd, Item **ref) { SELECT_LEX *curr_sel= thd->lex->current_select; - LEX *lex_s= curr_sel->parent_lex; nesting_map allow_sum_func= (thd->lex->allow_sum_func & curr_sel->name_visibility_map); bool invalid= FALSE; @@ -312,7 +310,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) } aggr_sel->set_agg_func_used(true); update_used_tables(); - lex_s->in_sum_func= in_sum_func; + thd->lex->in_sum_func= in_sum_func; return FALSE; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5173df2..9a66b27 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6440,7 +6440,6 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref) if (!(context= new (thd->mem_root) Name_resolution_context)) return TRUE; context->init(); - context->select_lex= table_ref->select_lex; context->first_name_resolution_table= context->last_name_resolution_table= table_ref; item->context= context; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9339cb9..624bcb9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3060,7 +3060,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } for (; sl; sl= sl->next_select_in_list()) { - sl->parent_lex->in_sum_func= NULL; if (sl->changed_elements & TOUCHED_SEL_COND) { /* remove option which was put by mysql_explain_union() */ @@ -3191,6 +3190,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) lex->result->set_thd(thd); } lex->allow_sum_func= 0; + lex->in_sum_func= NULL; DBUG_VOID_RETURN; }
1 0
0 0
[Commits] d4aae0b47b3: MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values
by psergey 03 Jan '22

03 Jan '22
revision-id: d4aae0b47b396a142fd413ff5f5ac5df1ff3c560 (mariadb-10.3.31-70-gd4aae0b47b3) parent(s): 9962cda52722b77c2a7e0314bbaa2e4f963f55c1 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2022-01-04 00:01:52 +0300 message: MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values Disable LATERAL DERIVED optimization for subqueries that have WITH ROLLUP. --- mysql-test/main/derived_split_innodb.result | 42 +++++++++++++++++++++++++++++ mysql-test/main/derived_split_innodb.test | 36 +++++++++++++++++++++++++ sql/opt_split.cc | 5 +++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 7ea3b689f23..8162bfcdae7 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -234,4 +234,46 @@ id itemid id id 4 2 4 2 drop table t1,t2,t3; set optimizer_switch='split_materialized=default'; +# +# MDEV-26337: subquery with groupby and ROLLUP returns incorrect results +# (The testcase is taken from testcase for MDEV-13389 due to it being +# much smaller) +# +create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam; +insert into t3 values +(8,11,'aa'), (5,15,'cc'), (1,14,'bb'), (2,12,'aa'), (7,17,'cc'), +(7,18,'aa'), (2,11,'aa'), (7,10,'bb'), (3,11,'dd'), (4,12,'ee'), +(5,14,'dd'), (9,12,'ee'); +create table t4 (a int, b int, c char(127), index idx(a,c)) engine=myisam; +insert into t4 values +(7,10,'cc'), (1,20,'aa'), (2,23,'bb'), (7,18,'cc'), (1,30,'bb'), +(4,71,'xx'), (3,15,'aa'), (7,82,'aa'), (8,12,'dd'), (4,15,'aa'), +(11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'cc'), +(8,20,'dd'), (7,32,'bb'), (1,50,'aa'), (3,40,'bb'), (3,77,'aa'); +insert into t4 select a+10, b+10, concat(c,'f') from t4; +analyze table t3,t4; +Table Op Msg_type Msg_text +test.t3 analyze status OK +test.t4 analyze status OK +# This should use a plan with LATERAL DERIVED: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 range idx_b idx_b 5 NULL 3 Using index condition; Using where +1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 2 +2 LATERAL DERIVED t4 ref idx idx 133 test.t3.a,test.t3.c 1 +# ... and if one adds WITH ROLLUP, then LATERAL DERIVED is no longer used: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c with rollup) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 range idx_b idx_b 5 NULL 3 Using index condition; Using where +1 PRIMARY <derived2> ref key0 key0 133 test.t3.a,test.t3.c 4 +2 DERIVED t4 ALL NULL NULL NULL NULL 40 Using filesort +drop table t3, t4; # End of 10.3 tests diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index 6f33c71eede..2a3565be36f 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -186,4 +186,40 @@ eval $q; drop table t1,t2,t3; set optimizer_switch='split_materialized=default'; +--echo # +--echo # MDEV-26337: subquery with groupby and ROLLUP returns incorrect results +--echo # (The testcase is taken from testcase for MDEV-13389 due to it being +--echo # much smaller) +--echo # + +create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam; +insert into t3 values +(8,11,'aa'), (5,15,'cc'), (1,14,'bb'), (2,12,'aa'), (7,17,'cc'), +(7,18,'aa'), (2,11,'aa'), (7,10,'bb'), (3,11,'dd'), (4,12,'ee'), +(5,14,'dd'), (9,12,'ee'); +create table t4 (a int, b int, c char(127), index idx(a,c)) engine=myisam; +insert into t4 values +(7,10,'cc'), (1,20,'aa'), (2,23,'bb'), (7,18,'cc'), (1,30,'bb'), +(4,71,'xx'), (3,15,'aa'), (7,82,'aa'), (8,12,'dd'), (4,15,'aa'), +(11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'cc'), +(8,20,'dd'), (7,32,'bb'), (1,50,'aa'), (3,40,'bb'), (3,77,'aa'); +insert into t4 select a+10, b+10, concat(c,'f') from t4; +analyze table t3,t4; + +--echo # This should use a plan with LATERAL DERIVED: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; + +--echo # ... and if one adds WITH ROLLUP, then LATERAL DERIVED is no longer used: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c with rollup) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; + +drop table t3, t4; + --echo # End of 10.3 tests diff --git a/sql/opt_split.cc b/sql/opt_split.cc index edf9ae3deff..8a985095f3c 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -310,6 +310,8 @@ struct SplM_field_ext_info: public SplM_field_info occurred also in the select list of this join 9. There are defined some keys usable for ref access of fields from C with available statistics. + 10. The select doesn't use WITH ROLLUP (This limitation can probably be + lifted) @retval true if the answer is positive @@ -326,7 +328,8 @@ bool JOIN::check_for_splittable_materialized() (unit->first_select()->next_select()) || // !(3) (derived->prohibit_cond_pushdown) || // !(4) (derived->is_recursive_with_table()) || // !(5) - (table_count == 0 || const_tables == top_join_tab_count)) // !(6) + (table_count == 0 || const_tables == top_join_tab_count) || // !(6) + rollup.state != ROLLUP::STATE_NONE) // (10) return false; if (group_list) // (7.1) {
1 0
0 0
[Commits] f7648d8ef74: MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values
by psergey 03 Jan '22

03 Jan '22
revision-id: f7648d8ef74016a2d07433f38d12e3c22bdef4a9 (mariadb-10.3.31-70-gf7648d8ef74) parent(s): 9962cda52722b77c2a7e0314bbaa2e4f963f55c1 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2022-01-03 23:53:45 +0300 message: MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values Disable LATERAL DERIVED optimization for subqueries that have WITH ROLLUP. --- mysql-test/main/derived_split_innodb.result | 88 ++++++++++++++++ mysql-test/main/derived_split_innodb.test | 149 ++++++++++++++++++++++++++++ sql/opt_split.cc | 5 +- sql/sql_select.cc | 34 +++++++ 4 files changed, 275 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 7ea3b689f23..fcdba0d7d07 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -234,4 +234,92 @@ id itemid id id 4 2 4 2 drop table t1,t2,t3; set optimizer_switch='split_materialized=default'; +# +# MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values +# +CREATE TABLE t1 ( +the_date date NOT NULL +, PRIMARY KEY ( the_date ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +INSERT INTO t1 VALUES ('2021-08-10'),('2021-08-11'),('2021-08-12'),('2021-08-13'); +CREATE TABLE t2 ( +the_date date NOT NULL, +ptn_id char(5) CHARACTER SET utf8mb3 NOT NULL DEFAULT '', +cco_stk_ttl int, +PRIMARY KEY ( the_date , ptn_id ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +INSERT INTO t2 VALUES +('2021-08-11','10002',NULL),('2021-08-11','10741',128), +('2021-08-11','11001',4),('2021-08-11','11003',2048), +('2021-08-12','10001',4096),('2021-08-12','10002',1), +('2021-08-12','10429',256),('2021-08-12','10499',16), +('2021-08-12','10580',8),('2021-08-12','10740',32), +('2021-08-12','10741',64),('2021-08-12','10771',512), +('2021-08-12','11001',2),('2021-08-12','11003',1024); +CREATE TABLE t3 ( +id int NOT NULL AUTO_INCREMENT, +nsc_id char(5) NOT NULL, +dept_id char(4) NOT NULL, +district_id char(3) NOT NULL, +region_id char(2) NOT NULL, +PRIMARY KEY ( id ), +UNIQUE KEY dept_district ( dept_id , district_id ), +KEY region_id ( dept_id , region_id ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +INSERT INTO t3 VALUES +(1,'MMD','ADVB','10','1'), (2,'MMD','ADVB','11','1'), +(3,'MMD','ADVB','21','2'),(4,'MMD','ADVB','22','2'); +CREATE TABLE t4 ( +dept_id char(4) CHARACTER SET utf8mb3 NOT NULL, +ptn_id char(5) CHARACTER SET utf8mb3 NOT NULL, +district_id char(3) CHARACTER SET utf8mb3 NOT NULL DEFAULT '0', +nsc_id char(5) CHARACTER SET utf8mb3 NOT NULL +, PRIMARY KEY (ptn_id , dept_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +INSERT INTO t4 VALUES +('ADVB','10001','10','MMD'),('ADVB','10002','10','MMD'), +('ADVB','10003','10','MMD'),('ADVB','10429','22','MMD'), +('ADVB','10740','21','MMD'),('ADVB','10741','21','MMD'), +('ADVB','10771','23','MMD'),('ADVB','11001','11','MMD'), +('ADVB','11002','11','MMD'); +CREATE TABLE `t10` ( +`the_date` date NOT NULL, +`dept_id` char(4) CHARACTER SET utf8mb4 , +`org_id` varchar(3) CHARACTER SET utf8mb4 , +`district_id` char(3) CHARACTER SET utf8mb4 , +`region_id` char(2) CHARACTER SET utf8mb4 +); +insert into t10 +SELECT cal.the_date , +org.dept_id , +coalesce(org.district_id, org.region_id, 'MMD') AS org_id , +org.district_id , +org.region_id +FROM t1 cal +CROSS JOIN t3 org +WHERE org.nsc_id = 'MMD' + AND org.dept_id IN ('ADVB') +AND cal.the_date = '2021-08-12' +GROUP BY cal.the_date, +org.dept_id, +org.region_id, +org.district_id WITH ROLLUP HAVING NOT (cal.the_date IS NULL +OR org.dept_id IS NULL); +explain $q; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY org2 ALL NULL NULL NULL NULL 7 +1 PRIMARY <derived2> ref key0 key0 43 test.org2.the_date,test.org2.dept_id,test.org2.region_id,test.org2.district_id 2 Using where +2 LATERAL DERIVED sub ref PRIMARY PRIMARY 3 test.org2.the_date 1 Using temporary; Using filesort +2 LATERAL DERIVED org ref PRIMARY PRIMARY 15 test.sub.ptn_id 1 Using where +2 LATERAL DERIVED dis eq_ref dept_district,region_id dept_district 28 const,func 1 Using index condition; Using where +$q; +the_date org_id dept_id cco_stk_ttl +2021-08-12 10 ADVB 4097 +2021-08-12 11 ADVB 2 +2021-08-12 1 ADVB 4099 +2021-08-12 21 ADVB 96 +2021-08-12 22 ADVB 256 +2021-08-12 2 ADVB 352 +2021-08-12 MMD ADVB 4451 +drop table t1,t2,t3,t4,t10; # End of 10.3 tests diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index 6f33c71eede..dc283792c13 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -186,4 +186,153 @@ eval $q; drop table t1,t2,t3; set optimizer_switch='split_materialized=default'; +--echo # +--echo # MDEV-26337: subquery with groupby and ROLLUP returns incorrect results on LEFT JOIN on INDEXED values +--echo # + +CREATE TABLE t1 ( + the_date date NOT NULL + , PRIMARY KEY ( the_date ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +INSERT INTO t1 VALUES ('2021-08-10'),('2021-08-11'),('2021-08-12'),('2021-08-13'); + +CREATE TABLE t2 ( + the_date date NOT NULL, + ptn_id char(5) CHARACTER SET utf8mb3 NOT NULL DEFAULT '', + cco_stk_ttl int, + PRIMARY KEY ( the_date , ptn_id ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO t2 VALUES +('2021-08-11','10002',NULL),('2021-08-11','10741',128), +('2021-08-11','11001',4),('2021-08-11','11003',2048), +('2021-08-12','10001',4096),('2021-08-12','10002',1), +('2021-08-12','10429',256),('2021-08-12','10499',16), +('2021-08-12','10580',8),('2021-08-12','10740',32), +('2021-08-12','10741',64),('2021-08-12','10771',512), +('2021-08-12','11001',2),('2021-08-12','11003',1024); + +CREATE TABLE t3 ( + id int NOT NULL AUTO_INCREMENT, + nsc_id char(5) NOT NULL, + dept_id char(4) NOT NULL, + district_id char(3) NOT NULL, + region_id char(2) NOT NULL, + PRIMARY KEY ( id ), + UNIQUE KEY dept_district ( dept_id , district_id ), + KEY region_id ( dept_id , region_id ) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO t3 VALUES +(1,'MMD','ADVB','10','1'), (2,'MMD','ADVB','11','1'), +(3,'MMD','ADVB','21','2'),(4,'MMD','ADVB','22','2'); + +CREATE TABLE t4 ( + dept_id char(4) CHARACTER SET utf8mb3 NOT NULL, + ptn_id char(5) CHARACTER SET utf8mb3 NOT NULL, + district_id char(3) CHARACTER SET utf8mb3 NOT NULL DEFAULT '0', + nsc_id char(5) CHARACTER SET utf8mb3 NOT NULL + , PRIMARY KEY (ptn_id , dept_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO t4 VALUES +('ADVB','10001','10','MMD'),('ADVB','10002','10','MMD'), +('ADVB','10003','10','MMD'),('ADVB','10429','22','MMD'), +('ADVB','10740','21','MMD'),('ADVB','10741','21','MMD'), +('ADVB','10771','23','MMD'),('ADVB','11001','11','MMD'), +('ADVB','11002','11','MMD'); + +CREATE TABLE `t10` ( + `the_date` date NOT NULL, + `dept_id` char(4) CHARACTER SET utf8mb4 , + `org_id` varchar(3) CHARACTER SET utf8mb4 , + `district_id` char(3) CHARACTER SET utf8mb4 , + `region_id` char(2) CHARACTER SET utf8mb4 +); + +insert into t10 +SELECT cal.the_date , + org.dept_id , + coalesce(org.district_id, org.region_id, 'MMD') AS org_id , + org.district_id , + org.region_id +FROM t1 cal +CROSS JOIN t3 org +WHERE org.nsc_id = 'MMD' + AND org.dept_id IN ('ADVB') + AND cal.the_date = '2021-08-12' +GROUP BY cal.the_date, + org.dept_id, + org.region_id, + org.district_id WITH ROLLUP HAVING NOT (cal.the_date IS NULL + OR org.dept_id IS NULL); + +let $q= +SELECT sql_no_cache org2.the_date , + org2.org_id , + org2.dept_id , + msr. cco_stk_ttl +FROM + t10 org2 +LEFT JOIN + ( SELECT sub.the_date , + dis.dept_id , + dis.region_id , + dis.district_id , + sum(sub.cco_stk_ttl) AS cco_stk_ttl + FROM t2 sub + JOIN t4 org ON org.ptn_id = sub.ptn_id + JOIN t3 dis ON dis.dept_id = org.dept_id + AND dis.district_id = org.district_id + WHERE dis.nsc_id = 'MMD' + AND dis.dept_id IN ('ADVB') + GROUP BY sub.the_date, + dis.dept_id, + dis.region_id, + dis.district_id WITH ROLLUP ) msr ON msr.the_date = org2.the_date +AND msr.dept_id <=> org2.dept_id +AND msr.region_id <=> org2.region_id +AND msr.district_id <=> org2.district_id; + +evalp explain $q; +evalp $q; + +drop table t1,t2,t3,t4,t10; + +--echo # +--echo # MDEV-26337: subquery with groupby and ROLLUP returns incorrect results +--echo # (The testcase is taken from testcase for MDEV-13389 due to it being +--echo # much smaller) +--echo # + +create table t3 (a int, b int, c char(127), index idx_b(b)) engine=myisam; +insert into t3 values +(8,11,'aa'), (5,15,'cc'), (1,14,'bb'), (2,12,'aa'), (7,17,'cc'), +(7,18,'aa'), (2,11,'aa'), (7,10,'bb'), (3,11,'dd'), (4,12,'ee'), +(5,14,'dd'), (9,12,'ee'); +create table t4 (a int, b int, c char(127), index idx(a,c)) engine=myisam; +insert into t4 values +(7,10,'cc'), (1,20,'aa'), (2,23,'bb'), (7,18,'cc'), (1,30,'bb'), +(4,71,'xx'), (3,15,'aa'), (7,82,'aa'), (8,12,'dd'), (4,15,'aa'), +(11,33,'yy'), (10,42,'zz'), (4,53,'xx'), (10,17,'yy'), (7,12,'cc'), +(8,20,'dd'), (7,32,'bb'), (1,50,'aa'), (3,40,'bb'), (3,77,'aa'); +insert into t4 select a+10, b+10, concat(c,'f') from t4; +analyze table t3,t4; + +--echo # This should use a plan with LATERAL DERIVED: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; + +--echo # ... and if one adds WITH ROLLUP, then LATERAL DERIVED is no longer used: +explain select t3.a,t3.c,t.max,t.min +from t3 join +(select a, c, max(b) max, min(b) min from t4 group by a,c with rollup) t +on t3.a=t.a and t3.c=t.c +where t3.b > 15; + +drop table t3, t4; + --echo # End of 10.3 tests diff --git a/sql/opt_split.cc b/sql/opt_split.cc index edf9ae3deff..8a985095f3c 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -310,6 +310,8 @@ struct SplM_field_ext_info: public SplM_field_info occurred also in the select list of this join 9. There are defined some keys usable for ref access of fields from C with available statistics. + 10. The select doesn't use WITH ROLLUP (This limitation can probably be + lifted) @retval true if the answer is positive @@ -326,7 +328,8 @@ bool JOIN::check_for_splittable_materialized() (unit->first_select()->next_select()) || // !(3) (derived->prohibit_cond_pushdown) || // !(4) (derived->is_recursive_with_table()) || // !(5) - (table_count == 0 || const_tables == top_join_tab_count)) // !(6) + (table_count == 0 || const_tables == top_join_tab_count) || // !(6) + rollup.state != ROLLUP::STATE_NONE) // (10) return false; if (group_list) // (7.1) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fe02e7b44e4..0ea861987bd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17047,6 +17047,26 @@ const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field, Item *right_item= ((Item_func*) cond)->arguments()[1]; if (equal(left_item, comp_item, comp_field)) { + /* + If this condition + 1. Was injected by LATERAL DERIVED optimization, + 2. But is not used for ref access + then we ingore it. This is the same as what mmake_cond_for_table() does + when it is invoked from make_join_select(). + */ + if (func->functype() == Item_func::EQ_FUNC) + { + if (is_eq_cond_injected_for_split_opt((Item_func_eq*)func)) + { + bool used_for_ref= false; + if (left_item->type() == Item::FIELD_ITEM && + test_if_ref(func, (Item_field*)left_item, right_item)) + used_for_ref= true; + + if (!used_for_ref) + return 0; + } + } if (test_if_equality_guarantees_uniqueness (left_item, right_item)) { if (*const_item) @@ -17057,6 +17077,20 @@ const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field, } else if (equal(right_item, comp_item, comp_field)) { + /* Do the same as above */ + if (func->functype() == Item_func::EQ_FUNC) + { + if (is_eq_cond_injected_for_split_opt((Item_func_eq*)func)) + { + bool used_for_ref= false; + if (right_item->type() == Item::FIELD_ITEM && + test_if_ref(func, (Item_field*)right_item, left_item)) + used_for_ref= true; + + if (!used_for_ref) + return 0; + } + } if (test_if_equality_guarantees_uniqueness (right_item, left_item)) { if (*const_item)
1 0
0 0
[Commits] 0a47e770743: Fix typos in optimizer trace output
by psergey 23 Dec '21

23 Dec '21
revision-id: 0a47e770743d0be073e262b43fd85a1ea5e3856e (mariadb-10.4.22-53-g0a47e770743) parent(s): 03dff0fcf6ac5e12a76c8c680384ac8abd0c0f1d author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2021-12-23 12:03:09 +0300 message: Fix typos in optimizer trace output --- sql/sql_select.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 35925c0cd44..cfd1fbb3275 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11404,7 +11404,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) trace_const_cond.add("condition_on_constant_tables", const_cond); if (const_cond->is_expensive()) { - trace_const_cond.add("evalualted", "false") + trace_const_cond.add("evaluated", "false") .add("cause", "expensive cond"); } else @@ -11417,7 +11417,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!const_cond_result) { DBUG_PRINT("info",("Found impossible WHERE condition")); - trace_const_cond.add("evalualted", "true") + trace_const_cond.add("evaluated", "true") .add("found", "impossible where"); join->exec_const_cond= NULL; DBUG_RETURN(1);
1 0
0 0
[Commits] 03dff0fcf6a: MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer
by psergey 23 Dec '21

23 Dec '21
revision-id: 03dff0fcf6ac5e12a76c8c680384ac8abd0c0f1d (mariadb-10.4.22-52-g03dff0fcf6a) parent(s): 4eec6b99e177a644650057f2c14d2f10ddd0ada4 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2021-12-23 12:00:05 +0300 message: MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer make_join_select() calls const_cond->val_int(). There are edge cases where const_cond may have a not-yet optimized subquery. (The subquery will have used_tables() covered by join->const_tables. It will still have const_item()==false, so other parts of the optimizer will not try to evaluate it. We should probably mark such subqueries as constant but that is outside the scope of this MDEV) --- mysql-test/main/opt_trace.result | 27 +++++++++++++++++++++------ mysql-test/main/opt_trace.test | 10 ++++++++++ sql/sql_select.cc | 6 +++++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 0e4477e1fd9..34683d037ea 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -2393,7 +2393,8 @@ select t1.a from t1 left join t2 on t1.a=t2.a { "best_join_order": ["t2", "t1"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -2550,7 +2551,8 @@ explain select * from t1 left join t2 on t2.a=t1.a { "best_join_order": ["t1", "t2"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -2708,7 +2710,8 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and "best_join_order": ["t3", "t2", "t1"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -3021,7 +3024,8 @@ explain extended select * from t1 where a in (select pk from t10) { "best_join_order": ["t1", "<subquery2>"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -4719,7 +4723,8 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "best_join_order": ["t1", "<subquery2>"] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -7365,7 +7370,8 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { ] }, { - "condition_on_constant_tables": "1" + "condition_on_constant_tables": "1", + "computing_condition": [] }, { "attaching_conditions_to_tables": { @@ -8632,5 +8638,14 @@ SELECT 'a\0' LIMIT 0 { } SET optimizer_trace=DEFAULT; # +# MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer::on_start_object +# +CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=MEMORY; +SET optimizer_trace=1; +INSERT INTO t1 VALUES (0,0); +SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); +a +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 9d4794855e0..855ce11aaf5 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -643,6 +643,16 @@ SELECT 'a\0' LIMIT 0; SELECT query, trace FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; SET optimizer_trace=DEFAULT; +--echo # +--echo # MDEV-27238: Assertion `got_name == named_item_expected()' failed in Json_writer::on_start_object +--echo # + +CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=MEMORY; +SET optimizer_trace=1; +INSERT INTO t1 VALUES (0,0); +SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); +DROP TABLE t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 27fc27f242a..35925c0cd44 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11409,7 +11409,11 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } else { - const bool const_cond_result = const_cond->val_int() != 0; + bool const_cond_result; + { + Json_writer_array a(thd, "computing_condition"); + const_cond_result= const_cond->val_int() != 0; + } if (!const_cond_result) { DBUG_PRINT("info",("Found impossible WHERE condition"));
1 0
0 0
[Commits] 6450aab: MDEV-22846 Server crashes in handler_index_cond_check on SELECT
by IgorBabaev 23 Dec '21

23 Dec '21
revision-id: 6450aab26c73d0522da40b2ece0552dc2113f7a4 (mariadb-10.4.11-238-g6450aab) parent(s): bf2a244406c36cd12bc53f9a30c8a2cab191f235 author: Igor Babaev committer: Igor Babaev timestamp: 2021-12-22 18:57:19 -0800 message: MDEV-22846 Server crashes in handler_index_cond_check on SELECT If the optimizer decides to rewrites a NOT IN predicand of the form outer_expr IN (SELECT inner_col FROM ... WHERE subquery_where) into the EXISTS subquery EXISTS (SELECT 1 FROM ... WHERE subquery_where AND (outer_expr=inner_col OR inner_col IS NULL)) then the pushed equality predicate outer_expr=inner_col can be used for ref[or_null] access if inner_col is a reference to an indexed column. In this case if there is a selective range condition over this column then a Rowid filter may be employed coupled the with ref[or_null] access. The filter is 'pushed' into the engine and in InnoDB currently it cannot be used with index look-ups by primary key. The ref[or_null] access can be used only when outer_expr is not NULL. Otherwise the original predicand is evaluated to TRUE only if the result set returned by the query SELECT 1 FROM ... WHERE subquery_where is empty. When performing this evaluation the executor switches to the table scan by primary key. Before this patch the pushed filter still remained marked as active and the engine tried to apply the filter. This was incorrect and in InnoDB this attempt to use the filter led to an assertion failure. This patch fixes the problem by disabling usage of the filter when outer_expr is evaluated to NULL. Approved by Oleksandr Byelkin <sanja(a)mariadb.com> --- mysql-test/main/rowid_filter_innodb.result | 42 ++++++++++++++++++++++++++++++ mysql-test/main/rowid_filter_innodb.test | 34 ++++++++++++++++++++++++ sql/handler.h | 16 ++++++++++++ sql/item_subselect.cc | 4 +++ 4 files changed, 96 insertions(+) diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index 05d97b7..fcdaa94 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -2913,3 +2913,45 @@ set optimizer_switch=@save_optimizer_switch; set join_cache_level=@save_join_cache_level; drop table filt, acei, acli; set global innodb_stats_persistent= @stats.save; +# +# MDEV-22846: ref access with full scan on keys with NULLs + rowid_filter +# +CREATE TABLE t1 (pk int NOT NULL, c1 varchar(1)) engine=innodb; +INSERT INTO t1 VALUES +(1,NULL),(15,'o'),(16,'x'),(19,'t'),(35,'k'),(36,'h'),(42,'t'),(43,'h'), +(53,'l'),(62,'a'),(71,NULL),(79,'u'),(128,'y'),(129,NULL),(133,NULL); +CREATE TABLE t2 ( +i1 int, c1 varchar(1) NOT NULL, KEY c1 (c1), KEY i1 (i1) +) engine=innodb; +INSERT INTO t2 VALUES +(1,'1'),(NULL,'1'),(42,'t'),(NULL,'1'),(79,'u'),(NULL,'1'), +(NULL,'4'),(NULL,'4'),(NULL,'1'),(NULL,'u'),(2,'1'),(NULL,'w'); +INSERT INTO t2 SELECT * FROM t2; +SELECT * FROM t1 +WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 +WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL); +pk c1 +15 o +16 x +19 t +35 k +36 h +43 h +53 l +62 a +71 NULL +128 y +129 NULL +133 NULL +EXPLAIN EXTENDED SELECT * FROM t1 +WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 +WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 15 100.00 Using where +2 DEPENDENT SUBQUERY t2 ref|filter c1,i1 c1|i1 3|5 func 6 (33%) 33.33 Using where; Full scan on NULL key; Using rowid filter +2 DEPENDENT SUBQUERY a1 ALL NULL NULL NULL NULL 15 100.00 Using join buffer (flat, BNL join) +Warnings: +Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c1` AS `c1` from `test`.`t1` where !<expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#2 */ select `test`.`t2`.`c1` from `test`.`t2` join `test`.`t1` `a1` where `test`.`t2`.`i1` = `test`.`t1`.`pk` and `test`.`t2`.`i1` is not null and trigcond(<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c1`)))) +DROP TABLE t1,t2; +# End of 10.4 tests diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 74349b8..874f8d3 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -534,3 +534,37 @@ set join_cache_level=@save_join_cache_level; drop table filt, acei, acli; set global innodb_stats_persistent= @stats.save; + +--echo # +--echo # MDEV-22846: ref access with full scan on keys with NULLs + rowid_filter +--echo # + +# set @stats.save= @@innodb_stats_persistent; +# set global innodb_stats_persistent=on; + +CREATE TABLE t1 (pk int NOT NULL, c1 varchar(1)) engine=innodb; +INSERT INTO t1 VALUES +(1,NULL),(15,'o'),(16,'x'),(19,'t'),(35,'k'),(36,'h'),(42,'t'),(43,'h'), +(53,'l'),(62,'a'),(71,NULL),(79,'u'),(128,'y'),(129,NULL),(133,NULL); + +CREATE TABLE t2 ( +i1 int, c1 varchar(1) NOT NULL, KEY c1 (c1), KEY i1 (i1) +) engine=innodb; +INSERT INTO t2 VALUES +(1,'1'),(NULL,'1'),(42,'t'),(NULL,'1'),(79,'u'),(NULL,'1'), +(NULL,'4'),(NULL,'4'),(NULL,'1'),(NULL,'u'),(2,'1'),(NULL,'w'); +INSERT INTO t2 SELECT * FROM t2; + +let $q= +SELECT * FROM t1 +WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2, t1 AS a1 + WHERE t2.i1 = t1.pk AND t2.i1 IS NOT NULL); + +eval $q; +eval EXPLAIN EXTENDED $q; + +DROP TABLE t1,t2; + +# set global innodb_stats_persistent= @stats.save; + +--echo # End of 10.4 tests diff --git a/sql/handler.h b/sql/handler.h index cdcb117..0a429f1 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3095,6 +3095,8 @@ class handler :public Sql_alloc /* Rowid filter pushed into the engine */ Rowid_filter *pushed_rowid_filter; + /* Used for disabling/enabling pushed_rowid_filter */ + Rowid_filter *save_pushed_rowid_filter; /* true when the pushed rowid filter has been already filled */ bool rowid_filter_is_active; @@ -3167,6 +3169,7 @@ class handler :public Sql_alloc pushed_idx_cond(NULL), pushed_idx_cond_keyno(MAX_KEY), pushed_rowid_filter(NULL), + save_pushed_rowid_filter(NULL), rowid_filter_is_active(0), auto_inc_intervals_count(0), m_psi(NULL), set_top_table_fields(FALSE), top_table(0), @@ -4224,6 +4227,19 @@ class handler :public Sql_alloc rowid_filter_is_active= false; } + virtual void disable_pushed_rowid_filter() + { + save_pushed_rowid_filter= pushed_rowid_filter; + pushed_rowid_filter= NULL; + rowid_filter_is_active= false; + } + + virtual void enable_pushed_rowid_filter() + { + pushed_rowid_filter= save_pushed_rowid_filter; + rowid_filter_is_active= true; + } + virtual bool rowid_filter_push(Rowid_filter *rowid_filter) { return true; } /* Needed for partition / spider */ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c50f87c..8204586 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3924,6 +3924,8 @@ int subselect_single_select_engine::exec() tab->save_read_record= tab->read_record.read_record_func; tab->read_record.read_record_func= rr_sequential; tab->read_first_record= read_first_record_seq; + if (tab->rowid_filter) + tab->table->file->disable_pushed_rowid_filter(); tab->read_record.thd= join->thd; tab->read_record.ref_length= tab->table->file->ref_length; tab->read_record.unlock_row= rr_unlock_row; @@ -3944,6 +3946,8 @@ int subselect_single_select_engine::exec() tab->read_record.ref_length= 0; tab->read_first_record= tab->save_read_first_record; tab->read_record.read_record_func= tab->save_read_record; + if (tab->rowid_filter) + tab->table->file->enable_pushed_rowid_filter(); } executed= 1; if (!(uncacheable() & ~UNCACHEABLE_EXPLAIN) &&
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • ...
  • 1461
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.