Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
12.3.1
-
None
-
None
-
Version: 12.3.1-MariaDB
ubuntu22.04
Description
Summary
Potential wrong error-handling return value in st_select_lex::collect_grouping_fields() (HAVING pushdown path), causing inconsistent behavior under tight max_session_mem_used limits.
Affected Area
- Component: Optimizer
- File: sql/sql_lex.cc
- Function: st_select_lex::collect_grouping_fields()
Source Analysis
In collect_grouping_fields(), push_back failure appears to return false:
if (grouping_tmp_fields.push_back(grouping_tmp_field, thd->mem_root)) |
return false; |
But in the sibling function collect_fields_equal_to_grouping(), push_back failure returns true:
if (grouping_tmp_fields.push_back(grouping_tmp_field, thd->mem_root)) |
return true; |
And list push_back semantics are:
- success => 0
- failure => 1
So this looks like an inverted error return in collect_grouping_fields().
Reproducible Behavior (Runtime)
I can trigger a behavioral divergence between:
- optimizer_switch='condition_pushdown_from_having=on'
- optimizer_switch='condition_pushdown_from_having=off'
under the same query and low max_session_mem_used.
Repro Script (SQL-driven generation + execution)
DROP DATABASE IF EXISTS bug_oom_test3; |
CREATE DATABASE bug_oom_test3; |
USE bug_oom_test3; |
SET SESSION group_concat_max_len = 1024 * 1024; |
SET @cols := 420; |
SET @having_cols := 220; |
WITH RECURSIVE seq AS ( |
SELECT 1 AS n |
UNION ALL |
SELECT n + 1 FROM seq WHERE n < @cols |
)
|
SELECT CONCAT( |
'CREATE TABLE t(', |
GROUP_CONCAT(CONCAT('c', n, ' INT') ORDER BY n SEPARATOR ','), |
');' |
) INTO @ddl |
FROM seq; |
PREPARE stmt FROM @ddl; |
EXECUTE stmt; |
DEALLOCATE PREPARE stmt; |
WITH RECURSIVE seq AS ( |
SELECT 1 AS n |
UNION ALL |
SELECT n + 1 FROM seq WHERE n < @cols |
)
|
SELECT CONCAT( |
'INSERT INTO t VALUES (', |
GROUP_CONCAT('1' ORDER BY n SEPARATOR ','), |
');' |
) INTO @ins |
FROM seq; |
PREPARE stmt FROM @ins; |
EXECUTE stmt; |
DEALLOCATE PREPARE stmt; |
WITH RECURSIVE seq AS ( |
SELECT 1 AS n |
UNION ALL |
SELECT n + 1 FROM seq WHERE n < @cols |
)
|
SELECT GROUP_CONCAT(CONCAT('c', n) ORDER BY n SEPARATOR ',') |
INTO @sel_list |
FROM seq; |
WITH RECURSIVE seq AS ( |
SELECT 1 AS n |
UNION ALL |
SELECT n + 1 FROM seq WHERE n < @having_cols |
)
|
SELECT GROUP_CONCAT(CONCAT('c', n, '=1') ORDER BY n SEPARATOR ' AND ') |
INTO @having_cond |
FROM seq; |
SET @q := CONCAT( |
'SELECT ', @sel_list, |
' FROM t GROUP BY ', @sel_list, |
' HAVING ', @having_cond |
);
|
SELECT LENGTH(@q) AS query_len; |
2) Case A: pushdown ON (expected to fail under tight memory)
USE bug_oom_test3; |
SET SESSION max_session_mem_used = 2800000; |
SET SESSION optimizer_switch = 'condition_pushdown_from_having=on'; |
PREPARE stmt FROM @q; |
EXECUTE stmt; |
DEALLOCATE PREPARE stmt; |
3) Case B: pushdown OFF (same query, control case)
USE bug_oom_test3; |
SET SESSION max_session_mem_used = 2800000; |
SET SESSION optimizer_switch = 'condition_pushdown_from_having=off'; |
PREPARE stmt FROM @q; |
EXECUTE stmt; |
DEALLOCATE PREPARE stmt; |
At max_session_mem_used=2800000:
- Case A (pushdown ON):
ERROR 1290 (HY000): The MariaDB server is running with the --max-session-mem-used=2800000 option so it cannot execute this statement - Case B (pushdown OFF):
Query executes successfully.
Expected Result
OOM/error handling should be semantically consistent; no suspicious error-path inversion between sibling helper functions in the same pushdown chain.