From 76a5145def40dadee1cb35c4f1d00c19ffb798be Mon Sep 17 00:00:00 2001 From: Yingwen Date: Thu, 3 Jul 2025 21:46:02 +0800 Subject: [PATCH] fix: enable max_execution time for other read only statements (#6454) Also disable the timeout when timeout is 0 Signed-off-by: evenyag --- src/frontend/src/instance.rs | 10 +++-- src/sql/src/statements/statement.rs | 61 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/instance.rs b/src/frontend/src/instance.rs index ee30f83454..3743a5e84d 100644 --- a/src/frontend/src/instance.rs +++ b/src/frontend/src/instance.rs @@ -317,9 +317,13 @@ impl Instance { /// For MySQL, it applies only to read-only statements. fn derive_timeout(stmt: &Statement, query_ctx: &QueryContextRef) -> Option { let query_timeout = query_ctx.query_timeout()?; - match (query_ctx.channel(), stmt) { - (Channel::Mysql, Statement::Query(_)) | (Channel::Postgres, _) => Some(query_timeout), - (_, _) => None, + if query_timeout.is_zero() { + return None; + } + match query_ctx.channel() { + Channel::Mysql if stmt.is_readonly() => Some(query_timeout), + Channel::Postgres => Some(query_timeout), + _ => None, } } diff --git a/src/sql/src/statements/statement.rs b/src/sql/src/statements/statement.rs index 546b240757..63464e15c0 100644 --- a/src/sql/src/statements/statement.rs +++ b/src/sql/src/statements/statement.rs @@ -148,6 +148,67 @@ pub enum Statement { ShowProcesslist(ShowProcessList), } +impl Statement { + pub fn is_readonly(&self) -> bool { + match self { + // Read-only operations + Statement::Query(_) + | Statement::ShowDatabases(_) + | Statement::ShowTables(_) + | Statement::ShowTableStatus(_) + | Statement::ShowColumns(_) + | Statement::ShowCharset(_) + | Statement::ShowCollation(_) + | Statement::ShowIndex(_) + | Statement::ShowRegion(_) + | Statement::ShowCreateDatabase(_) + | Statement::ShowCreateTable(_) + | Statement::ShowCreateFlow(_) + | Statement::ShowFlows(_) + | Statement::ShowCreateView(_) + | Statement::ShowStatus(_) + | Statement::ShowSearchPath(_) + | Statement::ShowViews(_) + | Statement::DescribeTable(_) + | Statement::Explain(_) + | Statement::ShowVariables(_) + | Statement::ShowProcesslist(_) + | Statement::FetchCursor(_) + | Statement::Tql(_) => true, + + #[cfg(feature = "enterprise")] + Statement::ShowTriggers(_) => true, + + // Write operations + Statement::Insert(_) + | Statement::Delete(_) + | Statement::CreateTable(_) + | Statement::CreateExternalTable(_) + | Statement::CreateTableLike(_) + | Statement::CreateFlow(_) + | Statement::CreateView(_) + | Statement::DropTable(_) + | Statement::DropDatabase(_) + | Statement::DropFlow(_) + | Statement::DropView(_) + | Statement::CreateDatabase(_) + | Statement::AlterTable(_) + | Statement::AlterDatabase(_) + | Statement::Copy(_) + | Statement::TruncateTable(_) + | Statement::SetVariables(_) + | Statement::Use(_) + | Statement::DeclareCursor(_) + | Statement::CloseCursor(_) + | Statement::Kill(_) + | Statement::Admin(_) => false, + + #[cfg(feature = "enterprise")] + Statement::CreateTrigger(_) | Statement::DropTrigger(_) => false, + } + } +} + impl Display for Statement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self {