Skip to content

Commit 46c1ae7

Browse files
committed
working implementation, with tests
1 parent 97680ed commit 46c1ae7

File tree

13 files changed

+771
-167
lines changed

13 files changed

+771
-167
lines changed

src/adapter/src/command.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,8 @@ impl ExecuteResponse {
644644
DropObjects => &[DroppedObject],
645645
DropOwned => &[DroppedOwned],
646646
PlanKind::EmptyQuery => &[ExecuteResponseKind::EmptyQuery],
647-
ExplainPlan | ExplainPushdown | ExplainAnalyze | ExplainTimestamp | Select
648-
| ShowAllVariables | ShowCreate | ShowColumns | ShowVariable | InspectShard
649-
| ExplainSinkSchema => &[
647+
ExplainPlan | ExplainPushdown | ExplainTimestamp | Select | ShowAllVariables
648+
| ShowCreate | ShowColumns | ShowVariable | InspectShard | ExplainSinkSchema => &[
650649
ExecuteResponseKind::CopyTo,
651650
SendingRows,
652651
SendingRowsImmediate,

src/adapter/src/coord/appends.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,6 @@ pub(crate) fn waiting_on_startup_appends(
984984
| Plan::CopyTo(_)
985985
| Plan::ExplainPlan(_)
986986
| Plan::ExplainPushdown(_)
987-
| Plan::ExplainAnalyze(_)
988987
| Plan::ExplainSinkSchema(_)
989988
| Plan::Insert(_)
990989
| Plan::AlterNetworkPolicy(_)

src/adapter/src/coord/catalog_serving.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ pub fn auto_run_on_catalog_server<'a, 's, 'p>(
105105
| Plan::CopyTo(_)
106106
| Plan::ExplainPlan(_)
107107
| Plan::ExplainPushdown(_)
108-
| Plan::ExplainAnalyze(_)
109108
| Plan::ExplainSinkSchema(_)
110109
| Plan::Insert(_)
111110
| Plan::AlterNetworkPolicy(_)

src/adapter/src/coord/sequencer.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,6 @@ impl Coordinator {
420420
self.sequence_explain_pushdown(ctx, plan, target_cluster)
421421
.await;
422422
}
423-
Plan::ExplainAnalyze(plan) => {
424-
self.sequence_explain_analyze(ctx, plan, target_cluster).await;
425-
}
426423
Plan::ExplainSinkSchema(plan) => {
427424
let result = self.sequence_explain_schema(plan);
428425
ctx.retire(result);

src/adapter/src/coord/sequencer/inner.rs

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use mz_expr::{
3333
};
3434
use mz_ore::cast::CastFrom;
3535
use mz_ore::collections::{CollectionExt, HashSet};
36-
use mz_ore::str::separated;
3736
use mz_ore::task::{self, JoinHandle, spawn};
3837
use mz_ore::tracing::OpenTelemetryContext;
3938
use mz_ore::vec::VecExt;
@@ -49,8 +48,7 @@ use mz_repr::{
4948
RelationVersionSelector, Row, RowArena, RowIterator, Timestamp,
5049
};
5150
use mz_sql::ast::{
52-
AlterSourceAddSubsourceOption, ExplainAnalyzeComputationProperty, ExplainAnalyzeProperty,
53-
SqlServerConfigOption, SqlServerConfigOptionName,
51+
AlterSourceAddSubsourceOption, SqlServerConfigOption, SqlServerConfigOptionName,
5452
};
5553
use mz_sql::ast::{CreateSubsourceStatement, MySqlConfigOptionName, UnresolvedItemName};
5654
use mz_sql::catalog::{
@@ -2720,98 +2718,6 @@ impl Coordinator {
27202718
fut
27212719
}
27222720

2723-
pub(super) async fn sequence_explain_analyze(
2724-
&mut self,
2725-
ctx: ExecuteContext,
2726-
plan: plan::ExplainAnalyzePlan,
2727-
target_cluster: TargetCluster,
2728-
) {
2729-
match plan.explainee {
2730-
Explainee::Index(index_id) => (),
2731-
Explainee::MaterializedView(item_id) => (),
2732-
_ => {
2733-
ctx.retire(Err(AdapterError::Unsupported(
2734-
"EXPLAIN ANALYZE queries for this explainee type",
2735-
)));
2736-
return;
2737-
}
2738-
};
2739-
2740-
// generate SQL query
2741-
2742-
/* SELECT REPEAT(' ', nesting * 2) || operator AS operator
2743-
fields for each property
2744-
FROM mz_introspection.mz_lir_mapping mlm
2745-
LEFT JOIN tables for each property
2746-
[CROSS JOIN LATERAL (sums per worker and averages for each property) IF SKEW]
2747-
JOIN mz_introspection.mz_mappable_objects mo
2748-
ON (mlm.global_id = mo.global_id)
2749-
WHERE mo.name = {plan.explainee_name}
2750-
GROUP BY lir_id, nesting, operator, [worker_id IF SKEW]
2751-
ORDER BY lir_id DESC
2752-
*/
2753-
let mut columns = vec!["REPEAT(' ', nesting * 2) || operator AS operator"];
2754-
let mut from = vec!["mz_introspection.mz_lir_mapping mlm"];
2755-
let mut group_by = vec!["lir_id", "nesting", "operator"];
2756-
let mut order_by = vec!["lir_id DESC"];
2757-
2758-
match plan.properties {
2759-
ExplainAnalyzeProperty::Computation {
2760-
properties,
2761-
skew: true,
2762-
} => {
2763-
for property in properties {
2764-
match property {
2765-
ExplainAnalyzeComputationProperty::Cpu => todo!(),
2766-
ExplainAnalyzeComputationProperty::Memory => todo!(),
2767-
}
2768-
}
2769-
}
2770-
ExplainAnalyzeProperty::Computation {
2771-
properties,
2772-
skew: false,
2773-
} => {
2774-
for property in properties {
2775-
match property {
2776-
ExplainAnalyzeComputationProperty::Cpu => todo!(),
2777-
ExplainAnalyzeComputationProperty::Memory => todo!(),
2778-
}
2779-
}
2780-
}
2781-
ExplainAnalyzeProperty::Hints => {
2782-
columns.extend([
2783-
"levels",
2784-
"to_cut",
2785-
"hint",
2786-
"pg_size_pretty(savings) AS savings",
2787-
]);
2788-
from.extend(["JOIN mz_introspection.mz_dataflow_global_ids mdgi ON (mlm.global_id = mdgi.global_id)",
2789-
"LEFT JOIN mz_introspection.mz_expected_group_size_advice megsa ON (megsa.dataflow_id = mdgi.id AND mlm.operator_id_start <= megsa.region_id AND megsa.region_id < mlm.operator_id_end)"]);
2790-
}
2791-
}
2792-
2793-
from.push("JOIN mz_introspection.mz_mappable_objects mo ON (mlm.global_id = mo.global_id)");
2794-
2795-
let columns = separated(", ", columns);
2796-
let from = separated(" ", from);
2797-
let explainee_name = plan.explainee_name;
2798-
let group_by = separated(", ", group_by);
2799-
let order_by = separated(", ", order_by);
2800-
let query = format!(
2801-
r#"SELECT {columns}
2802-
FROM {from}
2803-
WHERE mo.name = '{explainee_name}'
2804-
GROUP BY {group_by}
2805-
ORDER BY {order_by}"#
2806-
);
2807-
2808-
if plan.as_sql {
2809-
todo!("send query as immediate response")
2810-
} else {
2811-
todo!("execute the query")
2812-
}
2813-
}
2814-
28152721
#[instrument]
28162722
pub(super) async fn sequence_insert(
28172723
&mut self,

src/sql-parser/src/ast/defs/statement.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,7 +4036,7 @@ impl<T: AstInfo> AstDisplay for ExplainPushdownStatement<T> {
40364036
}
40374037
impl_display_t!(ExplainPushdownStatement);
40384038

4039-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4039+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
40404040
pub enum ExplainAnalyzeComputationProperty {
40414041
Cpu,
40424042
Memory,
@@ -4068,21 +4068,20 @@ impl<T: AstInfo> AstDisplay for ExplainAnalyzeStatement<T> {
40684068
let mut first = true;
40694069
for property in properties {
40704070
if first {
4071-
f.write_str(" ");
40724071
first = false;
40734072
} else {
4074-
f.write_str(", ");
4073+
f.write_str(",");
40754074
}
40764075
match property {
4077-
ExplainAnalyzeComputationProperty::Cpu => f.write_str("CPU"),
4078-
ExplainAnalyzeComputationProperty::Memory => f.write_str("MEMORY"),
4076+
ExplainAnalyzeComputationProperty::Cpu => f.write_str(" CPU"),
4077+
ExplainAnalyzeComputationProperty::Memory => f.write_str(" MEMORY"),
40794078
}
40804079
}
40814080
if *skew {
40824081
f.write_str(" WITH SKEW");
40834082
}
40844083
}
4085-
ExplainAnalyzeProperty::Hints => f.write_str("HINTS"),
4084+
ExplainAnalyzeProperty::Hints => f.write_str(" HINTS"),
40864085
}
40874086
f.write_str(" FOR ");
40884087
f.write_node(&self.explainee);

src/sql-parser/src/parser.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8897,6 +8897,13 @@ impl<'a> Parser<'a> {
88978897
&mut self,
88988898
properties: &[Keyword],
88998899
) -> Result<(Keyword, ExplainAnalyzeComputationProperty), ParserError> {
8900+
if properties.is_empty() {
8901+
return Err(ParserError::new(
8902+
self.index,
8903+
"both CPU and MEMORY were specified, expected WITH SKEW or FOR",
8904+
));
8905+
}
8906+
89008907
match self.parse_one_of_keywords(properties) {
89018908
Some(kw) if kw == CPU => Ok((kw, ExplainAnalyzeComputationProperty::Cpu)),
89028909
Some(kw) if kw == MEMORY => Ok((kw, ExplainAnalyzeComputationProperty::Memory)),

src/sql-parser/tests/testdata/explain

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,45 @@ EXPLAIN WITH (ARITY, EQUIVALENCES, HUMANIZED EXPRESSIONS) CREATE MATERIALIZED VI
319319
EXPLAIN WITH (ARITY, EQUIVALENCES, HUMANIZED EXPRESSIONS) CREATE MATERIALIZED VIEW mv AS SELECT 665
320320
=>
321321
ExplainPlan(ExplainPlanStatement { stage: None, with_options: [ExplainPlanOption { name: Arity, value: None }, ExplainPlanOption { name: Equivalences, value: None }, ExplainPlanOption { name: HumanizedExpressions, value: None }], format: None, explainee: CreateMaterializedView(CreateMaterializedViewStatement { if_exists: Error, name: UnresolvedItemName([Ident("mv")]), columns: [], in_cluster: None, query: Query { ctes: Simple([]), body: Select(Select { distinct: None, projection: [Expr { expr: Value(Number("665")), alias: None }], from: [], selection: None, group_by: [], having: None, qualify: None, options: [] }), order_by: [], limit: None, offset: None }, as_of: None, with_options: [] }, false) })
322+
323+
parse-statement
324+
EXPLAIN ANALYZE MEMORY FOR INDEX i AS SQL
325+
----
326+
EXPLAIN ANALYZE MEMORY FOR INDEX i AS SQL
327+
=>
328+
ExplainAnalyze(ExplainAnalyzeStatement { properties: Computation { properties: [Memory], skew: false }, explainee: Index(Name(UnresolvedItemName([Ident("i")]))), as_sql: true })
329+
330+
parse-statement
331+
EXPLAIN ANALYZE HINTS FOR INDEX i AS SQL
332+
----
333+
EXPLAIN ANALYZE HINTS FOR INDEX i AS SQL
334+
=>
335+
ExplainAnalyze(ExplainAnalyzeStatement { properties: Hints, explainee: Index(Name(UnresolvedItemName([Ident("i")]))), as_sql: true })
336+
337+
parse-statement
338+
EXPLAIN ANALYZE MEMORY, CPU WITH SKEW FOR INDEX i AS SQL
339+
----
340+
EXPLAIN ANALYZE MEMORY, CPU WITH SKEW FOR INDEX i AS SQL
341+
=>
342+
ExplainAnalyze(ExplainAnalyzeStatement { properties: Computation { properties: [Memory, Cpu], skew: true }, explainee: Index(Name(UnresolvedItemName([Ident("i")]))), as_sql: true })
343+
344+
parse-statement
345+
EXPLAIN ANALYZE MEMORY, CPU WITH SKEW FOR MATERIALIZED VIEW w
346+
----
347+
EXPLAIN ANALYZE MEMORY, CPU WITH SKEW FOR MATERIALIZED VIEW w
348+
=>
349+
ExplainAnalyze(ExplainAnalyzeStatement { properties: Computation { properties: [Memory, Cpu], skew: true }, explainee: MaterializedView(Name(UnresolvedItemName([Ident("w")]))), as_sql: false })
350+
351+
parse-statement
352+
EXPLAIN ANALYZE MEMORY, CPU, CPU WITH SKEW FOR MATERIALIZED VIEW w
353+
----
354+
error: both CPU and MEMORY were specified, expected WITH SKEW or FOR
355+
EXPLAIN ANALYZE MEMORY, CPU, CPU WITH SKEW FOR MATERIALIZED VIEW w
356+
^
357+
358+
parse-statement
359+
EXPLAIN ANALYZE HINTS FOR SELECT 1
360+
----
361+
error: expected INDEX or MATERIALIZED VIEW
362+
EXPLAIN ANALYZE HINTS FOR SELECT 1
363+
^

src/sql/src/plan.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ use mz_repr::optimize::OptimizerFeatureOverrides;
4949
use mz_repr::refresh_schedule::RefreshSchedule;
5050
use mz_repr::role_id::RoleId;
5151
use mz_repr::{
52-
CatalogItemId, ColumnIndex, ColumnName, ColumnType, Diff, GlobalId, RelationDesc, Row,
53-
ScalarType, Timestamp, VersionedRelationDesc,
52+
CatalogItemId, ColumnIndex, ColumnName, ColumnType, Diff, GlobalId, RelationDesc, RelationType,
53+
Row, ScalarType, Timestamp, VersionedRelationDesc,
5454
};
5555
use mz_sql_parser::ast::{
56-
AlterSourceAddSubsourceOption, ClusterAlterOptionValue, ConnectionOptionName, ExplainAnalyzeProperty, QualifiedReplica, RawDataType, SelectStatement, TransactionIsolationLevel, TransactionMode, UnresolvedItemName, Value, WithOptionValue
56+
AlterSourceAddSubsourceOption, ClusterAlterOptionValue, ConnectionOptionName, QualifiedReplica,
57+
RawDataType, SelectStatement, TransactionIsolationLevel, TransactionMode, UnresolvedItemName,
58+
Value, WithOptionValue,
5759
};
5860
use mz_ssh_util::keys::SshKeyPair;
5961
use mz_storage_types::connections::aws::AwsConnection;
@@ -169,7 +171,6 @@ pub enum Plan {
169171
CopyTo(CopyToPlan),
170172
ExplainPlan(ExplainPlanPlan),
171173
ExplainPushdown(ExplainPushdownPlan),
172-
ExplainAnalyze(ExplainAnalyzePlan),
173174
ExplainTimestamp(ExplainTimestampPlan),
174175
ExplainSinkSchema(ExplainSinkSchemaPlan),
175176
Insert(InsertPlan),
@@ -290,7 +291,7 @@ impl Plan {
290291
StatementKind::Execute => &[PlanKind::Execute],
291292
StatementKind::ExplainPlan => &[PlanKind::ExplainPlan],
292293
StatementKind::ExplainPushdown => &[PlanKind::ExplainPushdown],
293-
StatementKind::ExplainAnalyze => &[PlanKind::ExplainAnalyze, PlanKind::Select],
294+
StatementKind::ExplainAnalyze => &[PlanKind::Select],
294295
StatementKind::ExplainTimestamp => &[PlanKind::ExplainTimestamp],
295296
StatementKind::ExplainSinkSchema => &[PlanKind::ExplainSinkSchema],
296297
StatementKind::Fetch => &[PlanKind::Fetch],
@@ -384,7 +385,6 @@ impl Plan {
384385
Plan::CopyTo(_) => "copy to",
385386
Plan::ExplainPlan(_) => "explain plan",
386387
Plan::ExplainPushdown(_) => "EXPLAIN FILTER PUSHDOWN",
387-
Plan::ExplainAnalyze(_) => "explain analyze",
388388
Plan::ExplainTimestamp(_) => "explain timestamp",
389389
Plan::ExplainSinkSchema(_) => "explain schema",
390390
Plan::Insert(_) => "insert",
@@ -863,6 +863,19 @@ pub struct SelectPlan {
863863
pub copy_to: Option<CopyFormat>,
864864
}
865865

866+
impl SelectPlan {
867+
pub fn immediate(rows: Vec<Row>, typ: RelationType) -> Self {
868+
let arity = typ.arity();
869+
SelectPlan {
870+
select: None,
871+
source: HirRelationExpr::Constant { rows, typ },
872+
when: QueryWhen::Immediately,
873+
finishing: RowSetFinishing::trivial(arity),
874+
copy_to: None,
875+
}
876+
}
877+
}
878+
866879
#[derive(Debug)]
867880
pub enum SubscribeOutput {
868881
Diffs,
@@ -1106,14 +1119,6 @@ pub struct ExplainPushdownPlan {
11061119
pub explainee: Explainee,
11071120
}
11081121

1109-
#[derive(Clone, Debug)]
1110-
pub struct ExplainAnalyzePlan {
1111-
pub properties: ExplainAnalyzeProperty,
1112-
pub explainee: Explainee,
1113-
pub explainee_name: String,
1114-
pub as_sql: bool,
1115-
}
1116-
11171122
#[derive(Clone, Debug)]
11181123
pub struct ExplainTimestampPlan {
11191124
pub format: ExplainFormat,

0 commit comments

Comments
 (0)