Skip to content

Commit 2e0d009

Browse files
committed
better parser error message, harden query, add exhaustive tests [which led to query hardening lol]
1 parent 8895f44 commit 2e0d009

File tree

4 files changed

+242
-43
lines changed

4 files changed

+242
-43
lines changed

src/sql-parser/src/parser.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8869,17 +8869,18 @@ impl<'a> Parser<'a> {
88698869

88708870
self.expect_keyword(FOR)?;
88718871

8872-
let explainee = self.parse_explainee()?;
8873-
match &explainee {
8874-
Explainee::Index(_) => (),
8875-
Explainee::MaterializedView(_) => (),
8876-
_ => {
8877-
return Err(ParserError::new(
8878-
self.index,
8879-
"expected INDEX or MATERIALIZED VIEW",
8880-
));
8881-
}
8882-
}
8872+
let explainee = if self.parse_keywords(&[MATERIALIZED, VIEW]) {
8873+
// Parse: `MATERIALIZED VIEW name`
8874+
Explainee::MaterializedView(self.parse_raw_name()?)
8875+
} else if self.parse_keyword(INDEX) {
8876+
// Parse: `INDEX name`
8877+
Explainee::Index(self.parse_raw_name()?)
8878+
} else {
8879+
return Err(ParserError::new(
8880+
self.index,
8881+
"expected INDEX or MATERIALIZED VIEW",
8882+
));
8883+
};
88838884

88848885
let mut as_sql = false;
88858886
if self.parse_keywords(&[AS, SQL]) {

src/sql-parser/tests/testdata/explain

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,11 @@ EXPLAIN ANALYZE HINTS FOR SELECT 1
360360
----
361361
error: expected INDEX or MATERIALIZED VIEW
362362
EXPLAIN ANALYZE HINTS FOR SELECT 1
363-
^
363+
^
364+
365+
parse-statement
366+
EXPLAIN ANALYZE HINTS FOR idx_top_buyers
367+
----
368+
error: expected INDEX or MATERIALIZED VIEW
369+
EXPLAIN ANALYZE HINTS FOR idx_top_buyers
370+
^

src/sql/src/plan/statement/dml.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ pub fn describe_explain_analyze(
375375

376376
if skew {
377377
relation_desc =
378-
relation_desc.with_column("worker_id", ScalarType::UInt64.nullable(false));
378+
relation_desc.with_column("worker_id", ScalarType::UInt64.nullable(true));
379379
}
380380

381381
let mut seen_properties = BTreeSet::new();
@@ -843,8 +843,8 @@ pub fn plan_explain_analyze(
843843
SELECT mlm.lir_id AS lir_id,
844844
SUM(mas.size) AS total_memory,
845845
SUM(mas.records) AS total_records,
846-
SUM(mas.size) / COUNT(DISTINCT mas.worker_id) AS avg_memory,
847-
SUM(mas.records) / COUNT(DISTINCT mas.worker_id) AS avg_records
846+
CASE WHEN COUNT(DISTINCT mas.worker_id) <> 0 THEN SUM(mas.size) / COUNT(DISTINCT mas.worker_id) ELSE NULL END AS avg_memory,
847+
CASE WHEN COUNT(DISTINCT mas.worker_id) <> 0 THEN SUM(mas.records) / COUNT(DISTINCT mas.worker_id) ELSE NULL END AS avg_records
848848
FROM mz_introspection.mz_lir_mapping mlm
849849
LEFT JOIN mz_introspection.mz_arrangement_sizes_per_worker mas
850850
ON ( mlm.operator_id_start <= mas.operator_id
@@ -878,11 +878,11 @@ GROUP BY mlm.lir_id, mas.worker_id"#,
878878
}
879879

880880
columns.extend([
881-
"ROUND(pwm.worker_memory / sm.avg_memory, 2) AS memory_ratio",
881+
"CASE WHEN pwm.worker_id IS NOT NULL AND sm.avg_memory <> 0 THEN ROUND(pwm.worker_memory / sm.avg_memory, 2) ELSE NULL END AS memory_ratio",
882882
"pg_size_pretty(pwm.worker_memory) AS worker_memory",
883883
"pg_size_pretty(sm.avg_memory) AS avg_memory",
884884
"pg_size_pretty(sm.total_memory) AS total_memory",
885-
"ROUND(pwm.worker_records / sm.avg_records, 2) AS records_ratio",
885+
"CASE WHEN pwm.worker_id IS NOT NULL AND sm.avg_records <> 0 THEN ROUND(pwm.worker_records / sm.avg_records, 2) ELSE NULL END AS records_ratio",
886886
"pwm.worker_records AS worker_records",
887887
"sm.avg_records AS avg_records",
888888
"sm.total_records AS total_records",
@@ -900,7 +900,7 @@ GROUP BY mlm.lir_id, mas.worker_id"#,
900900
r#"
901901
SELECT mlm.lir_id AS lir_id,
902902
SUM(mse.elapsed_ns) AS total_ns,
903-
SUM(mse.elapsed_ns) / COUNT(DISTINCT mse.worker_id) AS avg_ns
903+
CASE WHEN COUNT(DISTINCT mse.worker_id) <> 0 THEN SUM(mse.elapsed_ns) / COUNT(DISTINCT mse.worker_id) ELSE NULL END AS avg_ns
904904
FROM mz_introspection.mz_lir_mapping mlm,
905905
mz_introspection.mz_scheduling_elapsed_per_worker mse
906906
WHERE mlm.operator_id_start <= mse.id AND mse.id < mlm.operator_id_end
@@ -931,7 +931,7 @@ GROUP BY mlm.lir_id, mse.worker_id"#,
931931
}
932932

933933
columns.extend([
934-
"ROUND(pwc.worker_ns / sc.avg_ns, 2) AS cpu_ratio",
934+
"CASE WHEN pwc.worker_id IS NOT NULL AND sc.avg_ns <> 0 THEN ROUND(pwc.worker_ns / sc.avg_ns, 2) ELSE NULL END AS cpu_ratio",
935935
"pwc.worker_ns / 1000 * '1 microsecond'::INTERVAL AS worker_elapsed",
936936
"sc.avg_ns / 1000 * '1 microsecond'::INTERVAL AS avg_elapsed",
937937
]);

0 commit comments

Comments
 (0)