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:
committed by
Jan Lindström
parent
74b0c78409
commit
3a682cb408
@@ -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;
|
||||
|
||||
@@ -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 #
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user