Skip to content

Commit cd17e4c

Browse files
committed
count and limit
1 parent 14ff1bf commit cd17e4c

File tree

3 files changed

+150
-20
lines changed

3 files changed

+150
-20
lines changed

crates/core/src/sql/compiler.rs

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,17 @@ fn compile_statement(db: &RelationalDB, statement: SqlAst) -> Result<CrudExpr, P
230230
mod tests {
231231
use super::*;
232232
use crate::db::datastore::traits::IsolationLevel;
233-
use crate::db::relational_db::tests_utils::{begin_tx, expect_query, expect_sub, insert, with_auto_commit, TestDB};
233+
use crate::db::relational_db::tests_utils::{
234+
begin_tx, expect_query, expect_query_with_auth, expect_sub, insert, with_auto_commit, TestDB,
235+
};
234236
use crate::execution_context::Workload;
235237
use crate::sql::execute::tests::run_for_testing;
236238
use expect_test::expect;
237239
use spacetimedb_lib::error::{ResultTest, TestError};
238240
use spacetimedb_lib::{ConnectionId, Identity};
239241
use spacetimedb_primitives::col_list;
240242
use spacetimedb_sats::{product, AlgebraicType, GroundSpacetimeType as _};
243+
use spacetimedb_schema::schema::RowLevelSecuritySchema;
241244
use std::convert::From;
242245

243246
#[test]
@@ -396,10 +399,10 @@ Seq Scan on test
396399
"select * from test where b = 2 and a = 1",
397400
expect![
398401
r#"
399-
Index Scan using Index test_b_idx_btree (test.b) on test)
400-
Index Cond: (test.b = U64(2))
401-
Output: test.a, test.b
402-
-> Filter: (test.a = U64(1))"#
402+
Index Scan using Index test_b_idx_btree (test.b) on test
403+
Index Cond: (test.b = U64(2))
404+
Output: test.a, test.b
405+
-> Filter: (test.a = U64(1))"#
403406
],
404407
);
405408

@@ -875,4 +878,78 @@ Hash Join: Lhs
875878
);
876879
Ok(())
877880
}
881+
882+
#[test]
883+
fn compile_limit() -> ResultTest<()> {
884+
let db = TestDB::durable()?;
885+
db.create_table_for_test("test", &[("a", AlgebraicType::U64)], &[0.into()])?;
886+
887+
let tx = db.begin_tx(Workload::ForTests);
888+
expect_query(
889+
&tx,
890+
"select * from test limit 1",
891+
expect![
892+
r#"
893+
Limit: 1
894+
Output: test.a
895+
-> Seq Scan on test
896+
Output: test.a"#
897+
],
898+
);
899+
900+
Ok(())
901+
}
902+
903+
#[test]
904+
fn compile_count() -> ResultTest<()> {
905+
let db = TestDB::durable()?;
906+
db.create_table_for_test("test", &[("a", AlgebraicType::U64)], &[0.into()])?;
907+
908+
let tx = db.begin_tx(Workload::ForTests);
909+
expect_query(
910+
&tx,
911+
"select count(*) as n from test",
912+
expect![
913+
r#"
914+
Count
915+
Output: n
916+
-> Seq Scan on test
917+
Output: test.a"#
918+
],
919+
);
920+
921+
// TODO: Currently, we don't support `count` with a `limit` clause.
922+
Ok(())
923+
}
924+
925+
#[test]
926+
fn compile_rls() -> ResultTest<()> {
927+
let db = TestDB::in_memory()?;
928+
let table_id = db.create_table_for_test("test", &[("a", AlgebraicType::U64)], &[0.into()])?;
929+
930+
let mut tx = db.begin_mut_tx(IsolationLevel::Serializable, Workload::ForTests);
931+
932+
let rls = RowLevelSecuritySchema {
933+
sql: "SELECT * FROM test WHERE a = 1".into(),
934+
table_id,
935+
};
936+
tx.create_row_level_security(rls.clone())?;
937+
938+
let user = Identity::from_be_byte_array([3; 32]);
939+
expect_query_with_auth(
940+
&tx,
941+
"select count(*) as n from test",
942+
AuthCtx::new(Identity::ONE, user),
943+
expect![
944+
r#"
945+
Count
946+
Output: n
947+
-> Seq Scan on test
948+
Output: test.a"#
949+
],
950+
);
951+
952+
// TODO: Currently, we don't support `count` with a `limit` clause.
953+
Ok(())
954+
}
878955
}

crates/core/src/subscription/subscription.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ mod tests {
679679
// Create table [lhs] with index on [b]
680680
let schema = &[("a", AlgebraicType::U64), ("b", AlgebraicType::U64)];
681681
let indexes = &[1.into()];
682-
let _ = db.create_table_for_test("lhs", schema, indexes)?;
682+
db.create_table_for_test("lhs", schema, indexes)?;
683683

684684
// Create table [rhs] with index on [b, c]
685685
let schema = &[
@@ -715,11 +715,12 @@ mod tests {
715715
expect![
716716
r#"
717717
Index Join: Rhs on lhs
718-
-> Seq Scan on rhs
719-
Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))
720718
Inner Unique: false
721719
Join Cond: (rhs.b = lhs.b)
722-
Output: lhs.a, lhs.b"#
720+
Output: lhs.a, lhs.b
721+
-> Seq Scan on rhs
722+
Output: rhs.b, rhs.c, rhs.d
723+
-> Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))"#
723724
],
724725
);
725726

@@ -783,7 +784,7 @@ Index Join: Rhs on lhs
783784
("d", AlgebraicType::U64),
784785
];
785786
let indexes = &[0.into(), 1.into()];
786-
let _ = db.create_table_for_test("rhs", schema, indexes)?;
787+
db.create_table_for_test("rhs", schema, indexes)?;
787788

788789
let tx = begin_tx(&db);
789790
// Should generate an index join since there is an index on `lhs.b`.
@@ -811,11 +812,12 @@ Index Join: Rhs on lhs
811812
expect![
812813
r#"
813814
Index Join: Rhs on lhs
814-
-> Seq Scan on rhs
815-
Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))
816815
Inner Unique: false
817816
Join Cond: (rhs.b = lhs.b)
818-
Output: lhs.a, lhs.b"#
817+
Output: lhs.a, lhs.b
818+
-> Seq Scan on rhs
819+
Output: rhs.b, rhs.c, rhs.d
820+
-> Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))"#
819821
],
820822
);
821823

@@ -870,8 +872,7 @@ Index Join: Rhs on lhs
870872
// Create table [lhs] with index on [b]
871873
let schema = &[("a", AlgebraicType::U64), ("b", AlgebraicType::U64)];
872874
let indexes = &[1.into()];
873-
let _lhs_id = db
874-
.create_table_for_test("lhs", schema, indexes)
875+
db.create_table_for_test("lhs", schema, indexes)
875876
.expect("Failed to create_table_for_test lhs");
876877

877878
// Create table [rhs] with index on [b, c]
@@ -881,8 +882,7 @@ Index Join: Rhs on lhs
881882
("d", AlgebraicType::U64),
882883
];
883884
let indexes = &[0.into(), 1.into()];
884-
let _rhs_id = db
885-
.create_table_for_test("rhs", schema, indexes)
885+
db.create_table_for_test("rhs", schema, indexes)
886886
.expect("Failed to create_table_for_test rhs");
887887

888888
let tx = begin_tx(&db);
@@ -916,11 +916,12 @@ Index Join: Rhs on lhs
916916
expect![
917917
r#"
918918
Index Join: Rhs on lhs
919-
-> Seq Scan on rhs
920-
Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))
921919
Inner Unique: false
922920
Join Cond: (rhs.b = lhs.b)
923-
Output: lhs.a, lhs.b"#
921+
Output: lhs.a, lhs.b
922+
-> Seq Scan on rhs
923+
Output: rhs.b, rhs.c, rhs.d
924+
-> Filter: (rhs.c > U64(2) AND rhs.c < U64(4) AND rhs.d = U64(3))"#
924925
],
925926
);
926927

crates/physical-plan/src/plan.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,4 +2055,56 @@ Delete on p
20552055
-> Filter: (p.id = U64(1))"#]],
20562056
);
20572057
}
2058+
2059+
#[test]
2060+
fn count() {
2061+
let db = data().with_options(ExplainOptions::default().optimize(true));
2062+
2063+
check_query(
2064+
&db,
2065+
"SELECT count(*) as n FROM p",
2066+
expect![[r#"
2067+
Count
2068+
Output: n
2069+
-> Seq Scan on p
2070+
Output: p.id, p.name"#]],
2071+
);
2072+
2073+
check_query(
2074+
&db,
2075+
"SELECT count(*) as n FROM p WHERE id = 1",
2076+
expect![[r#"
2077+
Count
2078+
Output: n
2079+
-> Index Scan using Index id 0 Unique(p.id) on p
2080+
Index Cond: (p.id = U64(1))
2081+
Output: p.id, p.name"#]],
2082+
);
2083+
}
2084+
2085+
#[test]
2086+
fn limit() {
2087+
let db = data().with_options(ExplainOptions::default().optimize(true));
2088+
2089+
check_query(
2090+
&db,
2091+
"SELECT * FROM p LIMIT 10",
2092+
expect![[r#"
2093+
Limit: 10
2094+
Output: p.id, p.name
2095+
-> Seq Scan on p
2096+
Output: p.id, p.name"#]],
2097+
);
2098+
2099+
check_query(
2100+
&db,
2101+
"SELECT * FROM p WHERE id = 1 LIMIT 10",
2102+
expect![[r#"
2103+
Limit: 10
2104+
Output: p.id, p.name
2105+
-> Index Scan using Index id 0 Unique(p.id) on p
2106+
Index Cond: (p.id = U64(1))
2107+
Output: p.id, p.name"#]],
2108+
);
2109+
}
20582110
}

0 commit comments

Comments
 (0)