Skip to content

Commit 8952f83

Browse files
authored
Merge pull request #39 from GE-fighting/main
add testing framework for kipsql
2 parents cab8ac8 + 43fc52f commit 8952f83

10 files changed

Lines changed: 294 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,8 @@ ctor = "0.2.0"
4747
env_logger = "0.10"
4848
paste = "^1.0"
4949
rstest = "0.17"
50+
51+
[workspace]
52+
members = [
53+
"tests/sqllogictest",
54+
]

src/execution/executor_graph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ impl ExecutorGraph {
196196
Ok(())
197197
}
198198

199+
#[allow(invalid_reference_casting)]
199200
pub async fn init_schedule_event_queue(&self, global_execution_queue: &mut ExecutionQueue) {
200201
// Schedule source node.
201202
for node_idx in self.graph.externals(Direction::Outgoing) {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ pub mod parser;
1414
pub mod planner;
1515
pub mod storage;
1616
pub mod types;
17+
pub mod util;
1718
mod execution_v1;

src/util/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
use arrow::record_batch::RecordBatch;
3+
use arrow::datatypes::{DataType, Field, Schema, SchemaRef};
4+
use arrow::error::ArrowError;
5+
use arrow::util::display::array_value_to_string;
6+
7+
pub fn record_batch_to_string(batch: &RecordBatch) -> Result<String, ArrowError> {
8+
let mut output = String::new();
9+
for row in 0..batch.num_rows() {
10+
for col in 0..batch.num_columns() {
11+
if col != 0 {
12+
output.push(' ');
13+
}
14+
let column = batch.column(col);
15+
16+
// NULL values are rendered as "NULL".
17+
if column.is_null(row) {
18+
output.push_str("NULL");
19+
continue;
20+
}
21+
let string = array_value_to_string(column, row)?;
22+
23+
// Empty strings are rendered as "(empty)".
24+
if *column.data_type() == DataType::Utf8 && string.is_empty() {
25+
output.push_str("(empty)");
26+
continue;
27+
}
28+
output.push_str(&string);
29+
}
30+
output.push('\n');
31+
}
32+
33+
Ok(output)
34+
}

tests/slt/create_table.slt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
statement ok
2+
create table t1(v1 varchar, v2 varchar, v3 varchar);
3+
4+
statement ok
5+
insert into t1 values('a', 'b', 'c');
6+
7+
statement error
8+
create table t1(v1 int);
9+
10+
11+
statement ok
12+
create table t2(v1 boolean, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 varchar);
13+
14+
statement ok
15+
insert into t2 values(true, 1, 2, 3, 4, 5.1, 6.2, '7');
16+
17+
18+
statement ok
19+
create table t3(v1 boolean, v2 tinyint unsigned, v3 smallint unsigned, v4 int unsigned, v5 bigint unsigned, v6 float, v7 double, v8 varchar);
20+
21+
statement ok
22+
insert into t3 values(true, 1, 2, 3, 4, 5.1, 6.2, '7');
23+
24+
25+
statement ok
26+
create table t4(v1 int);
27+
28+
statement ok
29+
select v1 from t4;
30+
31+
32+
statement ok
33+
create table read_csv_table as select * from read_csv('tests/csv/t2.csv');
34+
35+
36+
query I
37+
select a from read_csv_table limit 1;
38+
----
39+
10

tests/slt/insert_table.slt

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Test common insert case
2+
3+
statement ok
4+
create table t1(v1 varchar, v2 varchar, v3 varchar);
5+
6+
7+
statement error
8+
insert into t1(v3) values ('0','4');
9+
10+
11+
statement ok
12+
insert into t1(v3, v2) values ('0','4'), ('1','5');
13+
14+
15+
statement ok
16+
insert into t1 values ('2','7','9');
17+
18+
19+
query III
20+
select v1, v3, v2 from t1;
21+
----
22+
NULL 0 4
23+
NULL 1 5
24+
2 9 7
25+
26+
27+
# Test insert value cast type
28+
29+
statement ok
30+
create table t2(v1 int, v2 int, v3 int);
31+
32+
33+
statement ok
34+
insert into t2(v3, v2, v1) values (0, 4, 1), (1, 5, 2);
35+
36+
37+
query III
38+
select v3, v2, v1 from t2;
39+
----
40+
0 4 1
41+
1 5 2
42+
43+
44+
# Test insert type cast
45+
46+
statement ok
47+
create table t3(v1 TINYINT UNSIGNED);
48+
49+
50+
statement error
51+
insert into t3(v1) values (1481);
52+
53+
54+
# Test insert null values
55+
56+
statement ok
57+
create table t4(v1 varchar, v2 smallint unsigned, v3 bigint unsigned);
58+
59+
60+
statement ok
61+
insert into t4 values (NULL, 1, 2), ('', 3, NULL);
62+
63+
64+
statement ok
65+
insert into t4 values (NULL, NULL, NULL);
66+
67+
68+
query III
69+
select v1, v2, v3 from t4;
70+
----
71+
NULL 1 2
72+
(empty) 3 NULL
73+
NULL NULL NULL
74+
75+
76+
# Test insert from select
77+
78+
statement ok
79+
CREATE TABLE integers(i INTEGER);
80+
81+
82+
statement ok
83+
INSERT INTO integers SELECT 42;
84+
85+
statement ok
86+
INSERT INTO integers SELECT null;
87+
88+
89+
query I
90+
SELECT * FROM integers
91+
----
92+
42
93+
NULL

tests/slt/select.slt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# test insert projection with cast expression
2+
3+
statement ok
4+
create table t2(v1 tinyint);
5+
6+
statement ok
7+
insert into t2(v1) values (1), (5);
8+
9+
10+
statement ok
11+
create table t1(v1 int, v2 int, v3 int);
12+
13+
statement ok
14+
insert into t1(v3, v2, v1) values (0, 4, 1), (1, 5, 2);
15+
16+
17+
18+
query III
19+
select t1.v1, v2 from t1;
20+
----
21+
1 4
22+
2 5
23+
24+
25+
26+
query III
27+
select *, t1.* from t1;
28+
----
29+
1 4 0 1 4 0
30+
2 5 1 2 5 1
31+
32+
33+
# TODO: use alias function to verify output column names
34+
35+
query III
36+
select t.v1 as a, v2 as b from t1 as t;
37+
----
38+
1 4
39+
2 5
40+
41+
42+
43+
query III
44+
select 1, 2.3, '😇', true, null;
45+
----
46+
1 2.3 😇 true NULL

tests/sqllogictest/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "sqllogictest-test"
3+
version = "0.4.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
"kip-sql" = { path = "../.." }
8+
sqllogictest = "0.6"
9+
glob = "0.3"
10+
async-trait = "0.1"
11+
libtest-mimic = "0.6"
12+
anyhow = { version = "1.0.71", features = ["std"] }
13+
[[test]]
14+
name = "sqllogictest"
15+
harness = false

tests/sqllogictest/src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(iterator_try_collect)]
2+
use std::sync::Arc;
3+
4+
use kip_sql::db::{Database, DatabaseError};
5+
use kip_sql::util::record_batch_to_string;
6+
use sqllogictest::{AsyncDB, Runner};
7+
pub fn test_run(sqlfile: &str) {
8+
let db = Arc::new(Database::new_on_mem());
9+
let mut tester = Runner::new(DatabaseWrapper { db });
10+
tester.run_file(sqlfile).unwrap()
11+
}
12+
13+
struct DatabaseWrapper {
14+
db: Arc<Database>,
15+
}
16+
17+
#[async_trait::async_trait]
18+
impl AsyncDB for DatabaseWrapper {
19+
type Error = DatabaseError;
20+
async fn run(&mut self, sql: &str) -> Result<String, Self::Error> {
21+
let chunks = self.db.run(sql).await.unwrap();
22+
let output = chunks.iter().map(record_batch_to_string).try_collect();
23+
Ok(output?)
24+
}
25+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use std::path::Path;
2+
3+
use libtest_mimic::{Arguments, Trial};
4+
use sqllogictest_test::test_run;
5+
6+
fn main() {
7+
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("..").join("..");
8+
std::env::set_current_dir(path).unwrap();
9+
10+
const SLT_PATTERN: &str = "tests/slt/**/*.slt";
11+
12+
let args = Arguments::from_args();
13+
let mut tests = vec![];
14+
15+
let slt_files = glob::glob(SLT_PATTERN).expect("failed to find slt files");
16+
for slt_file in slt_files {
17+
let filepath = slt_file.expect("failed to read slt file");
18+
let filename = filepath
19+
.file_stem()
20+
.expect("failed to get file name")
21+
.to_str()
22+
.unwrap()
23+
.to_string();
24+
let filepath = filepath.to_str().unwrap().to_string();
25+
26+
let test = Trial::test(filename, move || {
27+
test_run(filepath.as_str());
28+
Ok(())
29+
});
30+
31+
tests.push(test);
32+
}
33+
34+
libtest_mimic::run(&args, tests).exit();
35+
}

0 commit comments

Comments
 (0)