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

MDEV-41164 SELECT INTO OUTFILE from INFORMATION_SCHEMA.TABLES

Keep the I_S.TABLES fast path only for plain client SELECTs. Fall back
when the result must go through a file, ANALYZE, SQL_BUFFER_RESULT,
PROCEDURE ANALYSE(), or the cursor protocol.
This commit is contained in:
Anway Durge
2026-10-01 10:32:15 +05:30
committed by Jan Lindström
parent 74b0c78409
commit 3a682cb408
3 changed files with 53 additions and 1 deletions

View File

@@ -794,6 +794,11 @@ EXPLAIN
}
}
#
# 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-41167: LIMIT 1 must stop after a matching row, not the first scan
#
CREATE DATABASE mdev41167;

View File

@@ -302,6 +302,15 @@ DEALLOCATE PREPARE stmt3;
EXPLAIN FORMAT=JSON SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND TABLE_NAME = 'user';
--echo #
--echo # MDEV-41164: SELECT INTO OUTFILE must use the fallback path
--echo #
--let $outfile= $MYSQLTEST_VARDIR/tmp/mdev_31342_outfile.txt
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT TABLE_NAME INTO OUTFILE '$outfile' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user'
--cat_file $outfile
--remove_file $outfile
--echo #
--echo # MDEV-41167: LIMIT 1 must stop after a matching row, not the first scan
--echo #

View File

@@ -4241,6 +4241,37 @@ static bool is_simple_is_query(THD *thd)
}
}
}
/*
ANALYZE SELECT also executes the query, then sends EXPLAIN via a
second result set. Streaming + my_eof() here races that.
*/
if (thd->lex->analyze_stmt)
{
DBUG_PRINT("info", ("ANALYZE statement, using fallback path"));
return false;
}
/*
INTO OUTFILE / DUMPFILE / @var need the interceptor result sink,
not the client protocol.
*/
if (thd->lex->exchange ||
(thd->lex->result && thd->lex->result->result_interceptor()))
{
DBUG_PRINT("info", ("result interceptor, using fallback path"));
return false;
}
/* PROCEDURE ANALYSE() rewrites the result set. */
if (thd->lex->proc_list.elements)
{
DBUG_PRINT("info", ("PROCEDURE ANALYSE, using fallback path"));
return false;
}
/* SQL_BUFFER_RESULT materializes into a tmp table first. */
if (sel->options & OPTION_BUFFER_RESULT)
{
DBUG_PRINT("info", ("SQL_BUFFER_RESULT, 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.
@@ -10234,8 +10265,15 @@ bool get_schema_tables_result(JOIN *join,
!thd->bootstrap && !thd->spcont &&
!is_show_command(thd) &&
join->result &&
!join->result->result_interceptor() &&
!thd->lex->analyze_stmt &&
!thd->lex->exchange &&
!thd->lex->proc_list.elements &&
!thd->is_cursor_execution() &&
thd->lex->sql_command == SQLCOM_SELECT &&
!(join->select_options & SELECT_DESCRIBE) &&
!(join->select_options &
(SELECT_DESCRIBE | OPTION_BUFFER_RESULT)) &&
thd->protocol->type() != Protocol::PROTOCOL_DISCARD &&
join->table_count == 1 &&
thd->lex->query_tables == table_list &&
!table_list->next_global &&