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:
committed by
Jan Lindström
parent
9cdcb266dd
commit
ee7b76a270
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user