1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-41240 I_S.TABLES crash with TABLE_NAME and a subquery

Do not use the fast path when the query has a subquery. Evaluating
that predicate while get_all_tables() uses a temporary MEM_ROOT
freed the subquery JOIN before outer JOIN cleanup.
This commit is contained in:
Anway Durge
2026-10-01 10:56:11 +05:30
committed by Jan Lindström
parent 9cee6ffa1a
commit 9cdcb266dd
3 changed files with 89 additions and 0 deletions

View File

@@ -919,3 +919,67 @@ information_schema.TABLES.TABLE_NAME user user 4 4 0 0 4.0000 NULL ENUM('user')
# MDEV-41204: client cursor protocol uses fallback
# (also covered by running this test with --cursor-protocol)
#
#
# MDEV-41240: exact TABLE_NAME lookup plus a materialised subquery
#
CREATE DATABASE mdev41240;
CREATE TABLE mdev41240.t1(a INT);
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41240' AND TABLE_NAME='t1'
AND TABLE_NAME IN (SELECT 't1' UNION SELECT 'x');
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"nested_loop": [
{
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA,TABLE_NAME",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mdev41240' and information_schema.`TABLES`.`TABLE_NAME` = 't1' and <in_optimizer>(information_schema.`TABLES`.`TABLE_NAME`,<exists>(subquery#2))",
"skip_open_table": true,
"scanned_databases": 0
}
}
],
"subqueries": [
{
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"table": {
"message": "No tables used"
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"table": {
"message": "No tables used"
}
}
}
]
}
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41240' AND TABLE_NAME='t1'
AND TABLE_NAME IN (SELECT 't1' UNION SELECT 'x');
TABLE_NAME
t1
DROP DATABASE mdev41240;

View File

@@ -396,3 +396,17 @@ WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user' PROCEDURE ANALYSE();
--echo # MDEV-41204: client cursor protocol uses fallback
--echo # (also covered by running this test with --cursor-protocol)
--echo #
--echo #
--echo # MDEV-41240: exact TABLE_NAME lookup plus a materialised subquery
--echo #
CREATE DATABASE mdev41240;
CREATE TABLE mdev41240.t1(a INT);
--replace_regex /`tables`/`TABLES`/ /"tables"/"TABLES"/
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41240' AND TABLE_NAME='t1'
AND TABLE_NAME IN (SELECT 't1' UNION SELECT 'x');
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41240' AND TABLE_NAME='t1'
AND TABLE_NAME IN (SELECT 't1' UNION SELECT 'x');
DROP DATABASE mdev41240;

View File

@@ -4272,6 +4272,17 @@ static bool is_simple_is_query(THD *thd)
DBUG_PRINT("info", ("SQL_BUFFER_RESULT, using fallback path"));
return false;
}
/*
A subquery in WHERE is evaluated from schema_table_store_record()
while get_all_tables() may be using a temporary MEM_ROOT. Freeing
that root leaves the subquery JOIN dangling.
*/
if (sel->first_inner_unit() ||
(sel->where && sel->where->with_subquery()))
{
DBUG_PRINT("info", ("subquery in I_S query, using fallback path"));
return false;
}
/*
Only allow no LIMIT, or LIMIT 1 exactly. Any other explicit LIMIT n
is rejected until a general LIMIT implementation is validated.