Skip to content
This repository was archived by the owner on Jan 7, 2025. It is now read-only.

Commit 30c76e8

Browse files
authored
feat: specify flags in a more flexible way in planner test (#103)
In planner test we might want to specify multiple flags for one task. For instance, for `explain` we might want `with_logical` and `verbose`. With the current syntax, however, we need to define multiple tasks for this: `explain_with_logical_verbose`, `explain_with_logical`, `explain_verbose`, ... This PR moves such options to a square bracket right after the task name, so where we used to have `explain_with_logical`/`explain_with_logical_verbose` we now have `explain[with_logical]`, `explain[with_logical, verbose]`.
1 parent 8dcc5a0 commit 30c76e8

File tree

9 files changed

+76
-44
lines changed

9 files changed

+76
-44
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

optd-perftest/src/datafusion_db_cardtest.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ impl CardtestRunnerDBHelper for DatafusionDb {
1919

2020
// helper functions for ```impl CardtestRunnerDBHelper for DatafusionDb```
2121
// they can't be put in an impl because DatafusionDb is a foreign struct
22-
async fn _eval_query_truecard(slf: &DatafusionDb, sql: &str) -> anyhow::Result<usize> {
23-
let rows = slf.execute(sql, true).await?;
22+
async fn _eval_query_truecard(db: &DatafusionDb, sql: &str) -> anyhow::Result<usize> {
23+
let rows = db.execute(sql, true).await?;
2424
let num_rows = rows.len();
2525
Ok(num_rows)
2626
}
2727

28-
async fn _eval_query_estcard(slf: &DatafusionDb, _sql: &str) -> anyhow::Result<usize> {
29-
let rows = slf.execute("EXPLAIN SELECT * FROM t1;", true).await?;
28+
async fn _eval_query_estcard(db: &DatafusionDb, _sql: &str) -> anyhow::Result<usize> {
29+
let rows = db.execute("EXPLAIN SELECT * FROM t1;", true).await?;
3030
println!("eval_est_card(): rows={:?}", rows);
3131
Ok(12)
3232
}

optd-sqlplannertest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ optd-datafusion-repr = { path = "../optd-datafusion-repr" }
3636
tracing-subscriber = "0.3"
3737
tracing = "0.1"
3838
itertools = "0.11"
39+
lazy_static = "1.4.0"
3940

4041
[[test]]
4142
name = "planner_test"

optd-sqlplannertest/README.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
1-
= Usage
1+
# Usage
22

3-
**Update the test cases**
3+
## Update the test cases
44

55
```shell
66
cargo run -p optd-sqlplannertest --bin planner_test_apply
77
```
88

9-
**Verify the test cases**
9+
## Verify the test cases
1010

1111
```shell
1212
cargo test -p optd-sqlplannertest
1313
# or use nextest
1414
cargo nextest run -p optd-sqlplannertest
1515
```
1616

17-
The `explain` and `execute` task will be run with datafusion's logical optimizer disabled. To keep using datafusion's logical optimizer, you could use the `execute_with_logical` and `explain_with_logical` tasks instead.
17+
## Tasks
18+
19+
The `explain` and `execute` task will be run with datafusion's logical optimizer disabled. Each task has some toggleable flags to control its behavior.
20+
21+
### `execute` Task
22+
23+
#### Flags
24+
25+
| Name | Description |
26+
| -- | -- |
27+
| with_logical | Enable Datafusion's logical optimizer |
28+
29+
### Explain Task
30+
31+
#### Flags
32+
33+
| Name | Description |
34+
| -- | -- |
35+
| with_logical | Enable Datafusion's logical optimizer |
36+
| verbose | Display estimated cost in physical plan |
1837

1938
Currently we have the following options for the explain task:
2039

@@ -24,4 +43,3 @@ Currently we have the following options for the explain task:
2443
- `physical_datafusion`: datafusion's physical plan.
2544
- `join_orders`: physical join orders.
2645
- `logical_join_orders`: logical join orders.
27-

optd-sqlplannertest/src/lib.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ use datafusion::sql::parser::DFParser;
77
use datafusion::sql::sqlparser::dialect::GenericDialect;
88
use datafusion_optd_cli::helper::unescape_input;
99
use itertools::Itertools;
10+
use lazy_static::lazy_static;
1011
use mimalloc::MiMalloc;
1112
use optd_datafusion_bridge::{DatafusionCatalog, OptdQueryPlanner};
1213
use optd_datafusion_repr::DatafusionOptimizer;
14+
use regex::Regex;
1315
use std::sync::Arc;
1416

1517
#[global_allocator]
@@ -118,8 +120,9 @@ impl DatafusionDb {
118120
}
119121

120122
/// Executes the `execute` task.
121-
async fn task_execute(&mut self, r: &mut String, sql: &str, with_logical: bool) -> Result<()> {
123+
async fn task_execute(&mut self, r: &mut String, sql: &str, flags: &[String]) -> Result<()> {
122124
use std::fmt::Write;
125+
let with_logical = flags.contains(&"with_logical".to_string());
123126
let result = self.execute(sql, with_logical).await?;
124127
writeln!(r, "{}", result.into_iter().map(|x| x.join(" ")).join("\n"))?;
125128
writeln!(r)?;
@@ -132,18 +135,17 @@ impl DatafusionDb {
132135
r: &mut String,
133136
sql: &str,
134137
task: &str,
135-
with_logical: bool,
138+
flags: &[String],
136139
) -> Result<()> {
137140
use std::fmt::Write;
138141

142+
let with_logical = flags.contains(&"with_logical".to_string());
143+
let _verbose = flags.contains(&"verbose".to_string());
144+
139145
let result = self
140146
.execute(&format!("explain {}", &sql), with_logical)
141147
.await?;
142-
let subtask_start_pos = if with_logical {
143-
"explain_with_logical:".len()
144-
} else {
145-
"explain:".len()
146-
};
148+
let subtask_start_pos = task.find(':').unwrap() + 1;
147149
for subtask in task[subtask_start_pos..].split(',') {
148150
let subtask = subtask.trim();
149151
if subtask == "logical_datafusion" {
@@ -227,16 +229,33 @@ impl sqlplannertest::PlannerTestRunner for DatafusionDb {
227229
let mut result = String::new();
228230
let r = &mut result;
229231
for task in &test_case.tasks {
230-
if task == "execute" {
231-
self.task_execute(r, &test_case.sql, false).await?;
232-
} else if task == "execute_with_logical" {
233-
self.task_execute(r, &test_case.sql, true).await?;
234-
} else if task.starts_with("explain:") {
235-
self.task_explain(r, &test_case.sql, task, false).await?;
236-
} else if task.starts_with("explain_with_logical:") {
237-
self.task_explain(r, &test_case.sql, task, true).await?;
232+
let flags = extract_flags(task)?;
233+
if task.starts_with("execute") {
234+
self.task_execute(r, &test_case.sql, &flags).await?;
235+
} else if task.starts_with("explain") {
236+
self.task_explain(r, &test_case.sql, task, &flags).await?;
238237
}
239238
}
240239
Ok(result)
241240
}
242241
}
242+
243+
lazy_static! {
244+
static ref FLAGS_REGEX: Regex = Regex::new(r"\[(.*)\]").unwrap();
245+
}
246+
247+
/// Extract the flags from a task. The flags are specified in square brackets.
248+
/// For example, the flags for the task `explain[with_logical, verbose]` are `["with_logical", "verbose"]`.
249+
fn extract_flags(task: &str) -> Result<Vec<String>> {
250+
if let Some(captures) = FLAGS_REGEX.captures(task) {
251+
Ok(captures
252+
.get(1)
253+
.unwrap()
254+
.as_str()
255+
.split(',')
256+
.map(|x| x.trim().to_string())
257+
.collect())
258+
} else {
259+
Ok(vec![])
260+
}
261+
}

optd-sqlplannertest/tests/constant_predicate.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
create table t1(t1v1 int, t1v2 int);
33
insert into t1 values (0, 0), (1, 1), (2, 2);
44
tasks:
5-
- execute_with_logical
5+
- execute[with_logical]
66
- sql: |
77
select * from t1 where t1v1 = 0;
88
desc: Test whether the optimizer handles integer equality predicates correctly.
99
tasks:
10-
- execute_with_logical
10+
- execute[with_logical]
1111
- sql: |
1212
select * from t1 where t1v1 = 0 and t1v2 = 1;
1313
desc: Test whether the optimizer handles multiple integer equality predicates correctly.
1414
tasks:
15-
- execute_with_logical
15+
- execute[with_logical]
1616
- sql: |
1717
select * from t1 where t1v1 = 0 and t1v2 != 1;
1818
desc: Test whether the optimizer handles multiple integer inequality predicates correctly.
1919
tasks:
20-
- execute_with_logical
20+
- execute[with_logical]

optd-sqlplannertest/tests/join_enumerate.planner.sql

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@ insert into t3 values (0, 300), (1, 301), (2, 302);
1616
select * from t2, t1, t3 where t1v1 = t2v1 and t1v2 = t3v2;
1717

1818
/*
19-
(Join t2 (Join t1 t3))
20-
(Join t2 (Join t3 t1))
21-
(Join t3 (Join t1 t2))
22-
(Join t3 (Join t2 t1))
23-
(Join (Join t1 t2) t3)
24-
(Join (Join t1 t3) t2)
2519
(Join (Join t2 t1) t3)
26-
(Join (Join t3 t1) t2)
2720
2821
0 200 0 0 0 300
2922
1 201 1 1 1 301

optd-sqlplannertest/tests/join_enumerate.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
insert into t2 values (0, 200), (1, 201), (2, 202);
77
insert into t3 values (0, 300), (1, 301), (2, 302);
88
tasks:
9-
- execute_with_logical
9+
- execute[with_logical]
1010
- sql: |
1111
select * from t2, t1, t3 where t1v1 = t2v1 and t1v2 = t3v2;
1212
desc: Test whether the optimizer enumerates all join orders.
1313
tasks:
14-
- explain_with_logical:logical_join_orders
15-
- execute_with_logical
14+
- explain[with_logcial]:logical_join_orders
15+
- execute[with_logical]
1616
- sql: |
1717
select * from t1, t2, t3 where t1v1 = t2v1 and t1v2 = t3v2;
1818
desc: Test whether the optimizer enumerates all join orders.
1919
tasks:
20-
- explain_with_logical:logical_join_orders
21-
- execute_with_logical
20+
- explain[with_logical]:logical_join_orders
21+
- execute[with_logical]

optd-sqlplannertest/tests/tpch.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@
156156
limit 100;
157157
desc: TPC-H Q2
158158
tasks:
159-
- explain_with_logical:logical_optd,physical_optd
159+
- explain[with_logical]:logical_optd,physical_optd
160160
- sql: |
161161
SELECT
162162
l_orderkey,
@@ -182,7 +182,7 @@
182182
o_orderdate LIMIT 10;
183183
desc: TPC-H Q3
184184
tasks:
185-
- explain_with_logical:logical_optd,physical_optd
185+
- explain[with_logical]:logical_optd,physical_optd
186186
- sql: |
187187
SELECT
188188
n_name AS nation,
@@ -493,7 +493,7 @@
493493
s_suppkey;
494494
desc: TPC-H Q15
495495
tasks:
496-
- explain_with_logical:logical_optd,physical_optd
496+
- explain[with_logical]:logical_optd,physical_optd
497497
- sql: |
498498
SELECT
499499
ROUND(SUM(l_extendedprice) / 7.0, 16) AS avg_yearly
@@ -514,7 +514,7 @@
514514
);
515515
desc: TPC-H Q17
516516
tasks:
517-
- explain_with_logical:logical_optd,physical_optd
517+
- explain[with_logical]:logical_optd,physical_optd
518518
- sql: |
519519
SELECT
520520
sum(l_extendedprice* (1 - l_discount)) as revenue

0 commit comments

Comments
 (0)