From 4f44d62d7d4552dccc57a24632b7f88b6d828f3d Mon Sep 17 00:00:00 2001 From: Kould <2435992353@qq.com> Date: Fri, 1 Mar 2024 21:37:52 +0800 Subject: [PATCH] test: add `where_by_index.slt` to verify the correctness of `IndexScan` (#148) --- src/expression/simplify.rs | 6 +- .../rule/normalization/pushdown_predicates.rs | 2 +- src/storage/mod.rs | 1 + tests/slt/where_by_index.slt | 101 ++++++++++++++++++ tests/sqllogictest/Cargo.toml | 3 +- tests/sqllogictest/src/main.rs | 12 ++- 6 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 tests/slt/where_by_index.slt diff --git a/src/expression/simplify.rs b/src/expression/simplify.rs index 680c3277..ca95e5c9 100644 --- a/src/expression/simplify.rs +++ b/src/expression/simplify.rs @@ -915,10 +915,10 @@ impl ScalarExpression { ); } - /// The definition of Or is not the Or in the Where condition. + /// Tips: The definition of `Or` is not the `Or` in the Where condition. /// The And and Or of ConstantBinary are concerned with the data range that needs to be aggregated. - /// - `ConstantBinary::And`: Aggregate the minimum range of all conditions in and - /// - `ConstantBinary::Or`: Rearrange and sort the range of each OR data + /// - [`ConstantBinary::And`]: Aggregate the minimum range of all conditions in and + /// - [`ConstantBinary::Or`]: Rearrange and sort the range of each OR data pub fn convert_binary( &self, table_name: &str, diff --git a/src/optimizer/rule/normalization/pushdown_predicates.rs b/src/optimizer/rule/normalization/pushdown_predicates.rs index 293e11f4..c67a0608 100644 --- a/src/optimizer/rule/normalization/pushdown_predicates.rs +++ b/src/optimizer/rule/normalization/pushdown_predicates.rs @@ -217,7 +217,7 @@ impl NormalizationRule for PushPredicateIntoScan { if let Operator::Filter(op) = graph.operator(node_id).clone() { if let Some(child_id) = graph.eldest_child_at(node_id) { if let Operator::Scan(child_op) = graph.operator_mut(child_id) { - //FIXME: now only support unique + //FIXME: now only support `unique` and `primary key` for IndexInfo { meta, binaries } in &mut child_op.index_infos { let mut option = op .predicate diff --git a/src/storage/mod.rs b/src/storage/mod.rs index c124b211..d7711252 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -98,6 +98,7 @@ pub trait Transaction: Sync + Send + 'static { async fn commit(self) -> Result<(), DatabaseError>; } +#[derive(Debug)] enum IndexValue { PrimaryKey(Tuple), Normal(TupleId), diff --git a/tests/slt/where_by_index.slt b/tests/slt/where_by_index.slt new file mode 100644 index 00000000..8bc7ecd4 --- /dev/null +++ b/tests/slt/where_by_index.slt @@ -0,0 +1,101 @@ +statement ok +create table t1(id int primary key, c1 int, c2 int); + +statement ok +copy t1 from 'tests/data/row_20000.csv' ( DELIMITER '|' ); + +statement ok +analyze table t1; + +query IIT +select * from t1 limit 10; +---- +0 1 2 +3 4 5 +6 7 8 +9 10 11 +12 13 14 +15 16 17 +18 19 20 +21 22 23 +24 25 26 +27 28 29 + +query IIT +select * from t1 where id = 0; +---- +0 1 2 + +query IIT +select * from t1 where id = 0 and id != 0 and id = 3; +---- + +query IIT +select * from t1 where id = 0 and id != 0 or id = 3; +---- +3 4 5 + +query IIT +select * from t1 where id > 0 and id = 3; +---- +3 4 5 + +query IIT +select * from t1 where id >= 0 and id <= 3; +---- +0 1 2 +3 4 5 + +query IIT +select * from t1 where id <= 0 and id >= 3; +---- + +query IIT +select * from t1 where id >= 3 or id <= 9 limit 10; +---- +0 1 2 +3 4 5 +6 7 8 +9 10 11 +12 13 14 +15 16 17 +18 19 20 +21 22 23 +24 25 26 +27 28 29 + +query IIT +select * from t1 where id <= 3 or id >= 9 limit 10; +---- +0 1 2 +3 4 5 +9 10 11 +12 13 14 +15 16 17 +18 19 20 +21 22 23 +24 25 26 +27 28 29 +30 31 32 + +query IIT +select * from t1 where (id >= 0 and id <= 3) or (id >= 9 and id <= 12); +---- +0 1 2 +3 4 5 +9 10 11 +12 13 14 + +query IIT +select * from t1 where (id >= 0 or id <= 3) and (id >= 9 or id <= 12) limit 10; +---- +0 1 2 +3 4 5 +6 7 8 +9 10 11 +12 13 14 +15 16 17 +18 19 20 +21 22 23 +24 25 26 +27 28 29 \ No newline at end of file diff --git a/tests/sqllogictest/Cargo.toml b/tests/sqllogictest/Cargo.toml index b54def18..5eb16852 100644 --- a/tests/sqllogictest/Cargo.toml +++ b/tests/sqllogictest/Cargo.toml @@ -10,4 +10,5 @@ async-trait = "0.1" tokio = "1.29.1" sqllogictest = "0.14.0" tokio-test = "0.4.2" -tempfile = "3.0.7" \ No newline at end of file +tempfile = "3.0.7" +clap = "4.4.11" \ No newline at end of file diff --git a/tests/sqllogictest/src/main.rs b/tests/sqllogictest/src/main.rs index ecb9fb8c..fb9e5645 100644 --- a/tests/sqllogictest/src/main.rs +++ b/tests/sqllogictest/src/main.rs @@ -1,3 +1,4 @@ +use clap::Parser; use fnck_sql::db::DataBaseBuilder; use sqllogictest::Runner; use sqllogictest_test::SQLBase; @@ -8,9 +9,16 @@ use std::path::Path; use std::time::Instant; use tempfile::TempDir; +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + #[clap(long, default_value = "tests/slt/**/*.slt")] + path: String, +} + #[tokio::main] async fn main() { - const SLT_PATTERN: &str = "tests/slt/**/*.slt"; + let args = Args::parse(); let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("..").join(".."); std::env::set_current_dir(path).unwrap(); @@ -20,7 +28,7 @@ async fn main() { let mut file_num = 0; let start = Instant::now(); - for slt_file in glob::glob(SLT_PATTERN).expect("failed to find slt files") { + for slt_file in glob::glob(&args.path).expect("failed to find slt files") { let temp_dir = TempDir::new().expect("unable to create temporary working directory"); let filepath = slt_file.expect("failed to read slt file"); println!(