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

MDEV-41241 I_S.TABLES assert when a function creates a temp table

Do not use the fast path when the statement uses a stored routine.
Evaluating that function during fill changes THD open-table state and
trips restore_backup_open_tables_state().
This commit is contained in:
Anway Durge
2026-10-01 10:58:14 +05:30
committed by Jan Lindström
parent 9cdcb266dd
commit ee7b76a270
3 changed files with 78 additions and 0 deletions

View File

@@ -983,3 +983,45 @@ WHERE TABLE_SCHEMA='mdev41240' AND TABLE_NAME='t1'
TABLE_NAME
t1
DROP DATABASE mdev41240;
#
# MDEV-41241: stored function must not assert in get_all_tables
#
CREATE DATABASE mdev41241;
CREATE TABLE mdev41241.t1(a INT);
CREATE TABLE mdev41241.t2(a INT);
CREATE FUNCTION mdev41241.f_ct2(s VARCHAR(64)) RETURNS INT
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS mdev41241.ttx(a INT);
RETURN 1;
END//
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41241' AND mdev41241.f_ct2(TABLE_CATALOG)=1;
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"nested_loop": [
{
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mdev41241' and mdev41241.f_ct2(information_schema.`TABLES`.TABLE_CATALOG) = 1",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41241' AND mdev41241.f_ct2(TABLE_CATALOG)=1;
TABLE_NAME
t1
t2
DROP FUNCTION mdev41241.f_ct2;
DROP TEMPORARY TABLE IF EXISTS mdev41241.ttx;
DROP DATABASE mdev41241;

View File

@@ -410,3 +410,29 @@ 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;
--echo #
--echo # MDEV-41241: stored function must not assert in get_all_tables
--echo #
CREATE DATABASE mdev41241;
CREATE TABLE mdev41241.t1(a INT);
CREATE TABLE mdev41241.t2(a INT);
DELIMITER //;
CREATE FUNCTION mdev41241.f_ct2(s VARCHAR(64)) RETURNS INT
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS mdev41241.ttx(a INT);
RETURN 1;
END//
DELIMITER ;//
--replace_regex /`tables`/`TABLES`/ /"tables"/"TABLES"/
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41241' AND mdev41241.f_ct2(TABLE_CATALOG)=1;
# --ps-protocol runs the SELECT twice; the second pass also sees ttx.
--disable_ps_protocol
--sorted_result
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41241' AND mdev41241.f_ct2(TABLE_CATALOG)=1;
--enable_ps_protocol
DROP FUNCTION mdev41241.f_ct2;
DROP TEMPORARY TABLE IF EXISTS mdev41241.ttx;
DROP DATABASE mdev41241;

View File

@@ -4283,6 +4283,16 @@ static bool is_simple_is_query(THD *thd)
DBUG_PRINT("info", ("subquery in I_S query, using fallback path"));
return false;
}
/*
A stored function can create tables or otherwise change THD open
table state. get_all_tables() then fails
restore_backup_open_tables_state().
*/
if (thd->lex->uses_stored_routines())
{
DBUG_PRINT("info", ("stored routine, 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.