feat: support explain analyze verbose (#5763)

* Add explain_verbose to QueryContext

* feat: fmt plan by display type

* feat: update proto to use ExplainOptions

* feat: display more info in verbose mode

* chore: fix clippy

* test: add sqlness test

* test: update sqlness result

* chore: update proto version

* chore: Simplify QueryContextBuilder::explain_options using get_or_insert_default
This commit is contained in:
Yingwen
2025-03-25 11:48:36 +08:00
committed by GitHub
parent 3b547d9d13
commit d88482b996
15 changed files with 261 additions and 28 deletions

View File

@@ -19,6 +19,7 @@ use std::sync::{Arc, RwLock};
use std::time::Duration;
use api::v1::region::RegionRequestHeader;
use api::v1::ExplainOptions;
use arc_swap::ArcSwap;
use auth::UserInfoRef;
use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
@@ -69,6 +70,8 @@ pub struct QueryContextMutableFields {
warning: Option<String>,
// TODO: remove this when format is supported in datafusion
explain_format: Option<String>,
/// Explain options to control the verbose analyze output.
explain_options: Option<ExplainOptions>,
}
impl Display for QueryContext {
@@ -111,6 +114,15 @@ impl QueryContextBuilder {
.timezone = timezone;
self
}
pub fn explain_options(mut self, explain_options: Option<ExplainOptions>) -> Self {
self.mutable_query_context_data
.get_or_insert_default()
.write()
.unwrap()
.explain_options = explain_options;
self
}
}
impl From<&RegionRequestHeader> for QueryContext {
@@ -125,7 +137,8 @@ impl From<&RegionRequestHeader> for QueryContext {
.channel(ctx.channel.into())
.snapshot_seqs(Arc::new(RwLock::new(
ctx.snapshot_seqs.clone().unwrap_or_default().snapshot_seqs,
)));
)))
.explain_options(ctx.explain);
}
builder.build()
}
@@ -142,6 +155,7 @@ impl From<api::v1::QueryContext> for QueryContext {
.snapshot_seqs(Arc::new(RwLock::new(
ctx.snapshot_seqs.clone().unwrap_or_default().snapshot_seqs,
)))
.explain_options(ctx.explain)
.build()
}
}
@@ -154,9 +168,11 @@ impl From<QueryContext> for api::v1::QueryContext {
extensions,
channel,
snapshot_seqs,
mutable_query_context_data,
..
}: QueryContext,
) -> Self {
let explain = mutable_query_context_data.read().unwrap().explain_options;
let mutable_inner = mutable_inner.read().unwrap();
api::v1::QueryContext {
current_catalog,
@@ -167,6 +183,7 @@ impl From<QueryContext> for api::v1::QueryContext {
snapshot_seqs: Some(api::v1::SnapshotSequences {
snapshot_seqs: snapshot_seqs.read().unwrap().clone(),
}),
explain,
}
}
}
@@ -319,6 +336,24 @@ impl QueryContext {
.explain_format = Some(format);
}
pub fn explain_verbose(&self) -> bool {
self.mutable_query_context_data
.read()
.unwrap()
.explain_options
.map(|opts| opts.verbose)
.unwrap_or(false)
}
pub fn set_explain_verbose(&self, verbose: bool) {
self.mutable_query_context_data
.write()
.unwrap()
.explain_options
.get_or_insert_default()
.verbose = verbose;
}
pub fn query_timeout(&self) -> Option<Duration> {
self.mutable_session_data.read().unwrap().query_timeout
}