1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/mysql-test/main/mdev_31342.result
Anway Durge ee7b76a270 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().
2026-10-23 08:29:11 +03:00

1028 lines
27 KiB
Plaintext

# MDEV-31342: Test I_S fast path optimization
#
# Test 1: Simple SELECT - should use fast path
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
TABLE_NAME
user
#
# Test 2: WHERE filter
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'information_schema' AND TABLE_NAME = 'TABLES';
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 = 'information_schema' and information_schema.`TABLES`.`TABLE_NAME` = 'TABLES'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'information_schema' AND TABLE_NAME = 'TABLES';
TABLE_NAME TABLE_SCHEMA
TABLES information_schema
#
# Test 3: Scalar subquery - should trigger single row early exit
#
EXPLAIN FORMAT=JSON SELECT (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user'
) AS result;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "No tables used"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0
}
}
]
}
}
]
}
}
SELECT (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user'
) AS result;
result
user
#
# Test 4: LIMIT 1 - should trigger early exit
#
EXPLAIN FORMAT=JSON SELECT COUNT(*) > 0 FROM (
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
LIMIT 1
) t;
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.010089369,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 1,
"rows": 2,
"cost": 0.010089369,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 2,
"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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1,
"is_fast_path": true
}
}
]
}
}
}
}
]
}
}
SELECT COUNT(*) > 0 FROM (
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
LIMIT 1
) t;
COUNT(*) > 0
1
#
# Test 5: Fallback path - ORDER BY should still work correctly
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
ORDER BY TABLE_NAME
LIMIT 3;
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"nested_loop": [
{
"read_sorted_file": {
"filesort": {
"sort_key": "information_schema.`TABLES`.`TABLE_NAME`",
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
ORDER BY TABLE_NAME
LIMIT 3;
TABLE_NAME
columns_priv
column_stats
db
#
# Test 6: Fallback path - GROUP BY should still work
#
EXPLAIN FORMAT=JSON SELECT TABLE_SCHEMA, COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
GROUP BY TABLE_SCHEMA;
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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT TABLE_SCHEMA, COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
GROUP BY TABLE_SCHEMA;
TABLE_SCHEMA COUNT(*)
mysql 31
#
# Test 7: Fallback path - DISTINCT should still work
#
EXPLAIN FORMAT=JSON SELECT DISTINCT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql';
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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT DISTINCT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql';
TABLE_SCHEMA
mysql
#
# Test 8: HAVING clause - should use fallback path
#
EXPLAIN FORMAT=JSON SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
HAVING TABLE_NAME = 'user';
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"having_condition": "information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"nested_loop": [
{
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
HAVING TABLE_NAME = 'user';
TABLE_SCHEMA TABLE_NAME
mysql user
#
# Test 9: WHERE TABLE_SCHEMA and TABLE_CATALOG mismatch - no rows
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_CATALOG = 'nope';
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 = 'mysql' and information_schema.`TABLES`.TABLE_CATALOG = 'nope'",
"skip_open_table": true,
"scanned_databases": 1,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_CATALOG = 'nope';
TABLE_NAME
#
# Test 10: LIMIT n > 1 without ORDER BY - not the single-row early-exit
# case, so is_simple_is_query() rejects it -> fallback path
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 3;
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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT COUNT(*) FROM (
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 3
) t;
COUNT(*)
3
# Test 11: LIMIT 1 OFFSET 1 - offset_limit set -> fallback path
# (regression coverage: fast path must not skip the offset row)
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 1 OFFSET 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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT COUNT(*) FROM (
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 1 OFFSET 1
) t;
COUNT(*)
1
# Test 12: SQL_CALC_FOUND_ROWS - OPTION_FOUND_ROWS set -> fallback path
# (regression coverage: fast path must not short-circuit the full scan
# needed for an accurate FOUND_ROWS() count)
#
EXPLAIN FORMAT=JSON SELECT SQL_CALC_FOUND_ROWS TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
]
}
}
SELECT SQL_CALC_FOUND_ROWS TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 1;
SELECT FOUND_ROWS();
FOUND_ROWS()
31
#
# Test 13: SELECT * - non-field item shape rejected -> fallback path
#
EXPLAIN FORMAT=JSON SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"open_full_table": true,
"scanned_databases": 0
}
}
]
}
}
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
def mysql user VIEW NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW NULL NULL
#
# Verify: simple query temp table behavior
#
FLUSH STATUS;
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
TABLE_NAME
user
SHOW SESSION STATUS LIKE 'Created_tmp_tables';
Variable_name Value
Created_tmp_tables 2
#
# Verify: ORDER BY uses fallback
#
FLUSH STATUS;
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
ORDER BY TABLE_NAME LIMIT 3;
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"nested_loop": [
{
"read_sorted_file": {
"filesort": {
"sort_key": "information_schema.`TABLES`.`TABLE_NAME`",
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql'
ORDER BY TABLE_NAME LIMIT 3;
TABLE_NAME
columns_priv
column_stats
db
SHOW SESSION STATUS LIKE 'Created_tmp_tables';
Variable_name Value
Created_tmp_tables 2
#
# EXPLAIN shows no filesort for fast-path query
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' LIMIT 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 = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1,
"is_fast_path": true
}
}
]
}
}
#
# EXPLAIN shows filesort for fallback query (ORDER BY)
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' ORDER BY TABLE_NAME LIMIT 3;
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"nested_loop": [
{
"read_sorted_file": {
"filesort": {
"sort_key": "information_schema.`TABLES`.`TABLE_NAME`",
"table": {
"table_name": "TABLES",
"access_type": "ALL",
"key": "TABLE_SCHEMA",
"loops": 1,
"cost": 0.01423506,
"attached_condition": "information_schema.`TABLES`.TABLE_SCHEMA = 'mysql'",
"skip_open_table": true,
"scanned_databases": 1
}
}
}
}
]
}
}
#
# Test: Prepared statements - fast path re-execution correctness
#
PREPARE stmt FROM 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?';
SET @db = 'mysql', @tbl = 'user';
EXECUTE stmt USING @db, @tbl;
TABLE_NAME
user
EXECUTE stmt USING @db, @tbl;
TABLE_NAME
user
DEALLOCATE PREPARE stmt;
#
# Test: Prepared statement with LIMIT 1
#
PREPARE stmt2 FROM 'SELECT COUNT(*) > 0 FROM (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? LIMIT 1) t';
SET @db = 'mysql';
EXECUTE stmt2 USING @db;
COUNT(*) > 0
1
EXECUTE stmt2 USING @db;
COUNT(*) > 0
1
DEALLOCATE PREPARE stmt2;
#
# Test: I_S query inside stored procedure
#
CREATE PROCEDURE test_is_proc()
BEGIN
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
END//
CALL test_is_proc();
TABLE_NAME
user
CALL test_is_proc();
TABLE_NAME
user
DROP PROCEDURE test_is_proc;
#
# Test: I_S query inside a merged view - still eligible for fast path
#
CREATE VIEW test_is_view AS
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql';
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM test_is_view WHERE TABLE_NAME = 'user';
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_NAME` = 'user' and information_schema.`TABLES`.TABLE_SCHEMA = 'mysql'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM test_is_view WHERE TABLE_NAME = 'user';
TABLE_NAME
user
DROP VIEW test_is_view;
#
# Test: WHERE with multiple conditions
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME LIKE 'user%'
LIMIT 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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` like 'user%'",
"skip_open_table": true,
"scanned_databases": 1,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME LIKE 'user%'
LIMIT 1;
TABLE_NAME
user
#
# Test: I_S query inside trigger
#
CREATE TABLE test_mdev31342 (id INT);
CREATE TRIGGER test_is_trigger BEFORE INSERT ON test_mdev31342
FOR EACH ROW
BEGIN
SET NEW.id = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql');
END//
INSERT INTO test_mdev31342 VALUES (0);
SELECT id > 0 AS has_tables FROM test_mdev31342;
has_tables
1
DROP TRIGGER test_is_trigger;
DROP TABLE test_mdev31342;
# End of 13.1 tests
#
# Test: Query cache - ensure results are not served from cache
#
SET SESSION query_cache_type = 0;
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
TABLE_NAME
user
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
TABLE_NAME
user
SET SESSION query_cache_type = DEFAULT;
#
# Test: Prepared statement with ? placeholders - second execution
#
PREPARE stmt3 FROM
'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?';
SET @s1= 'mysql', @t1= 'user';
EXECUTE stmt3 USING @s1, @t1;
TABLE_NAME
user
SET @s1= 'information_schema', @t1= 'TABLES';
EXECUTE stmt3 USING @s1, @t1;
TABLE_NAME
TABLES
DEALLOCATE PREPARE stmt3;
#
# Test: Verify fast path via EXPLAIN (no filesort = fast path engaged)
#
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0,
"is_fast_path": true
}
}
]
}
}
#
# MDEV-41164: SELECT INTO OUTFILE must use the fallback path
#
SELECT TABLE_NAME INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/mdev_31342_outfile.txt' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user';
user
#
# MDEV-41165: ANALYZE SELECT must not assert / double-EOF
#
ANALYZE SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='no_such_db_at_all';
SELECT 'analyze_ok' AS mdev_41165;
mdev_41165
analyze_ok
#
# MDEV-41167: LIMIT 1 must stop after a matching row, not the first scan
#
CREATE DATABASE mdev41167;
CREATE TABLE mdev41167.tb1(a INT);
CREATE TABLE mdev41167.tb2(a INT);
CREATE TABLE mdev41167.tb3(a INT);
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41167' AND (TABLE_NAME='tb1' OR TABLE_CATALOG='nope')
LIMIT 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 = 'mdev41167' and (information_schema.`TABLES`.`TABLE_NAME` = 'tb1' or information_schema.`TABLES`.TABLE_CATALOG = 'nope')",
"skip_open_table": true,
"scanned_databases": 1,
"is_fast_path": true
}
}
]
}
}
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41167' AND (TABLE_NAME='tb1' OR TABLE_CATALOG='nope')
LIMIT 1;
TABLE_NAME
tb1
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41167' AND (TABLE_NAME='tb2' OR TABLE_CATALOG='nope')
LIMIT 1;
TABLE_NAME
tb2
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mdev41167' AND (TABLE_NAME='tb3' OR TABLE_CATALOG='nope')
LIMIT 1;
TABLE_NAME
tb3
DROP DATABASE mdev41167;
#
# MDEV-41171: @@sql_select_limit and FOUND_ROWS() on the fast path
#
CREATE DATABASE mdev41171;
CREATE TABLE mdev41171.t1(i INT);
CREATE TABLE mdev41171.t2(i INT);
CREATE TABLE mdev41171.t3(i INT);
SET @@session.sql_select_limit=2;
SELECT TABLE_CATALOG FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mdev41171';
SET @@session.sql_select_limit=DEFAULT;
SELECT 1;
1
1
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mdev41171';
TABLE_NAME
t1
t2
t3
SELECT FOUND_ROWS();
FOUND_ROWS()
3
DROP DATABASE mdev41171;
#
# MDEV-41196: SQL_BUFFER_RESULT must not return empty column values
#
EXPLAIN FORMAT=JSON SELECT SQL_BUFFER_RESULT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user';
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.01423506,
"temporary_table": {
"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 = 'mysql' and information_schema.`TABLES`.`TABLE_NAME` = 'user'",
"skip_open_table": true,
"scanned_databases": 0
}
}
]
}
}
}
SELECT SQL_BUFFER_RESULT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
def mysql user
#
# MDEV-41199: PROCEDURE ANALYSE() must not be ignored
#
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user' PROCEDURE ANALYSE();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
information_schema.TABLES.TABLE_NAME user user 4 4 0 0 4.0000 NULL ENUM('user') NOT NULL
#
# 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;
#
# 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;