Skip to content

Commit f464886

Browse files
authored
feat: support include sql (#8)
* feat: support include sql Signed-off-by: Alex Chi <[email protected]> * bump sqlplannertest version Signed-off-by: Alex Chi Z <[email protected]> --------- Signed-off-by: Alex Chi Z <[email protected]>
1 parent c564280 commit f464886

File tree

8 files changed

+59
-15
lines changed

8 files changed

+59
-15
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlplannertest"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
edition = "2021"
55
description = "A yaml-based SQL planner test framework."
66
license = "MIT OR Apache-2.0"

naivedb/tests/include.sql

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CREATE TABLE t3(v3 int);

naivedb/tests/ok.planner.sql

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ SELECT * FROM t1, t2 WHERE t1.v1 = t2.v2;
1818
/*
1919
=== logical
2020
I'm a naive db, so I don't now how to process
21+
CREATE TABLE t3(v3 int);
22+
2123
CREATE TABLE t1(v1 int);
2224
2325
CREATE TABLE t2(v2 int);
@@ -28,6 +30,8 @@ SELECT * FROM t1, t2 WHERE t1.v1 = t2.v2;
2830
2931
=== physical
3032
I'm a naive db, so I don't now how to process
33+
CREATE TABLE t3(v3 int);
34+
3135
CREATE TABLE t1(v1 int);
3236
3337
CREATE TABLE t2(v2 int);

naivedb/tests/ok.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
- sql: |
88
SELECT * FROM t1, t2 WHERE t1.v1 = t2.v2;
99
desc: Test whether join works correctly.
10-
before: ["*sql1", "*sql2", "CREATE TABLE t3(v3 int);"]
10+
before: ["include_sql:include.sql", "*sql1", "*sql2", "CREATE TABLE t3(v3 int);"]
11+
tasks:
12+
- logical
13+
- physical
14+
- sql: |
15+
SELECT * FROM t1, t2 WHERE t1.v1 = t2.v2;
16+
desc: Test whether join works correctly.
17+
before: ["include_sql:include.sql", "*sql1", "*sql2", "CREATE TABLE t3(v3 int);"]
18+
no_capture: true
1119
tasks:
1220
- logical
1321
- physical

src/apply.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,20 @@ where
6262
tokio::spawn(async move {
6363
let testcases = tokio::fs::read(&path).await?;
6464
let testcases: Vec<TestCase> = serde_yaml::from_slice(&testcases)?;
65-
let testcases = parse_test_cases(testcases)?;
65+
let testcases = parse_test_cases(
66+
{
67+
let mut path = path.clone();
68+
path.pop();
69+
path
70+
},
71+
testcases,
72+
)?;
6673
let mut generated_result = String::new();
6774
for testcase in testcases {
6875
let runner_result = runner.run(&testcase).await;
69-
generate_result(&testcase, &runner_result, &mut generated_result)?;
76+
if !testcase.no_capture {
77+
generate_result(&testcase, &runner_result, &mut generated_result)?;
78+
}
7079
}
7180
let path = {
7281
let mut path = path;

src/lib.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct TestCase {
1919
pub desc: Option<String>,
2020
pub sql: String,
2121
pub before: Option<Vec<String>>,
22+
pub no_capture: Option<bool>,
2223
pub tasks: Option<Vec<String>>,
2324
}
2425

@@ -29,6 +30,7 @@ pub struct ParsedTestCase {
2930
pub desc: Option<String>,
3031
pub sql: String,
3132
pub before_sql: Vec<String>,
33+
pub no_capture: bool,
3234
pub tasks: Vec<String>,
3335
}
3436

@@ -39,8 +41,11 @@ pub trait PlannerTestRunner: Send {
3941
async fn run(&mut self, test_case: &ParsedTestCase) -> Result<String>;
4042
}
4143

42-
pub fn parse_test_cases(tests: Vec<TestCase>) -> Result<Vec<ParsedTestCase>> {
43-
resolve_testcase_id(tests)
44+
pub fn parse_test_cases(
45+
base_path: impl AsRef<Path>,
46+
tests: Vec<TestCase>,
47+
) -> Result<Vec<ParsedTestCase>> {
48+
resolve_testcase_id(base_path, tests)
4449
}
4550

4651
const TEST_SUFFIX: &str = ".yml";
@@ -77,7 +82,7 @@ mod tests {
7782
"#
7883
.trim();
7984
let test_case: Vec<TestCase> = serde_yaml::from_str(x).unwrap();
80-
let test_case = parse_test_cases(test_case).unwrap();
85+
let test_case = parse_test_cases("", test_case).unwrap();
8186
assert_eq!(test_case.len(), 3);
8287
assert_eq!(test_case[2].before_sql.len(), 3);
8388
assert_eq!(

src/resolve_id.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::collections::HashMap;
15+
use std::{collections::HashMap, path::Path};
1616

17-
use anyhow::{anyhow, Result};
17+
use anyhow::{anyhow, Context, Result};
1818

1919
use crate::{ParsedTestCase, TestCase};
2020

21-
pub fn resolve_testcase_id(testcases: Vec<TestCase>) -> Result<Vec<ParsedTestCase>> {
21+
pub fn resolve_testcase_id(
22+
base_path: impl AsRef<Path>,
23+
testcases: Vec<TestCase>,
24+
) -> Result<Vec<ParsedTestCase>> {
2225
let mut testcases_with_ids = HashMap::new();
2326
for testcase in &testcases {
2427
if let Some(id) = &testcase.id {
@@ -33,14 +36,18 @@ pub fn resolve_testcase_id(testcases: Vec<TestCase>) -> Result<Vec<ParsedTestCas
3336
Some(
3437
before
3538
.iter()
36-
.map(|id| {
37-
if let Some(id) = id.strip_prefix('*') {
39+
.map(|maybe_sql| {
40+
if let Some(id) = maybe_sql.strip_prefix('*') {
3841
testcases_with_ids
3942
.get(id)
4043
.map(|case| case.sql.clone())
4144
.ok_or_else(|| anyhow!("failed to resolve {}: not found", id))
45+
} else if let Some(include) = maybe_sql.strip_prefix("include_sql:") {
46+
let path = base_path.as_ref().join(include);
47+
std::fs::read_to_string(&path)
48+
.with_context(|| format!("failed to read: {}", include))
4249
} else {
43-
Ok(id.to_string())
50+
Ok(maybe_sql.to_string())
4451
}
4552
})
4653
.collect::<Result<Vec<_>>>()?,
@@ -54,6 +61,7 @@ pub fn resolve_testcase_id(testcases: Vec<TestCase>) -> Result<Vec<ParsedTestCas
5461
id: testcase.id,
5562
desc: testcase.desc,
5663
sql: testcase.sql,
64+
no_capture: testcase.no_capture == Some(true),
5765
tasks: testcase.tasks.unwrap_or_default(),
5866
})
5967
})

src/test_runner.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,20 @@ where
7979
let mut runner = runner_fn().await?;
8080
let testcases = tokio::fs::read(&path).await?;
8181
let testcases: Vec<TestCase> = serde_yaml::from_slice(&testcases)?;
82-
let testcases = parse_test_cases(testcases)?;
82+
let testcases = parse_test_cases(
83+
{
84+
let mut path = path.clone();
85+
path.pop();
86+
path
87+
},
88+
testcases,
89+
)?;
8390
let mut generated_result = String::new();
8491
for testcase in testcases {
8592
let runner_result = runner.run(&testcase).await;
86-
generate_result(&testcase, &runner_result, &mut generated_result)?;
93+
if !testcase.no_capture {
94+
generate_result(&testcase, &runner_result, &mut generated_result)?;
95+
}
8796
}
8897
let path = {
8998
let mut path = path;

0 commit comments

Comments
 (0)