add tests

This commit is contained in:
meteorgan 2025-06-16 22:31:06 +08:00
parent cd36fc26fd
commit d4789d0a05
4 changed files with 93 additions and 11 deletions

View file

@ -66,6 +66,10 @@ test-compat:
SQLITE_EXEC=$(SQLITE_EXEC) ./testing/all.test
.PHONY: test-compat
test-select:
SQLITE_EXEC=$(SQLITE_EXEC) ./testing/select.test
.PHONY: test-select
test-vector:
SQLITE_EXEC=$(SQLITE_EXEC) ./testing/vector.test
.PHONY: test-vector

View file

@ -361,7 +361,7 @@ fn read_intersect_rows(
left_cursor_id: usize,
index: &Index,
right_cursor_id: usize,
target_cursor_id: Option<usize>,
target_cursor: Option<usize>,
) {
let label_close = program.allocate_label();
let label_loop_start = program.allocate_label();
@ -372,8 +372,10 @@ fn read_intersect_rows(
program.preassign_label_to_next_insn(label_loop_start);
let row_content_reg = program.alloc_register();
// we need to emit opcode RowData here
program.emit_insn(Insn::RowData {
cursor_id: left_cursor_id,
dest: row_content_reg,
});
let label_next = program.allocate_label();
program.emit_insn(Insn::NotFound {
cursor_id: right_cursor_id,
@ -381,18 +383,36 @@ fn read_intersect_rows(
record_reg: row_content_reg,
num_regs: 0,
});
let cols_start_reg = program.alloc_registers(index.columns.len());
for i in 0..index.columns.len() {
let column_count = index.columns.len();
let cols_start_reg = program.alloc_registers(column_count);
for i in 0..column_count {
program.emit_insn(Insn::Column {
cursor_id: left_cursor_id,
column: i,
dest: cols_start_reg + i,
default: None,
});
}
if let Some(target_cursor_id) = target_cursor {
program.emit_insn(Insn::MakeRecord {
start_reg: cols_start_reg,
count: column_count,
dest_reg: row_content_reg,
index_name: None,
});
program.emit_insn(Insn::IdxInsert {
cursor_id: target_cursor_id,
record_reg: row_content_reg,
unpacked_start: Some(cols_start_reg),
unpacked_count: Some(column_count as u16),
flags: Default::default(),
});
} else {
program.emit_insn(Insn::ResultRow {
start_reg: cols_start_reg,
count: column_count,
});
}
program.emit_insn(Insn::ResultRow {
start_reg: cols_start_reg,
count: index.columns.len(),
});
program.preassign_label_to_next_insn(label_next);
program.emit_insn(Insn::Next {
cursor_id: left_cursor_id,

View file

@ -127,12 +127,13 @@ pub fn prepare_select_plan(
let mut left = Vec::with_capacity(compounds.len());
for CompoundSelect { select, operator } in compounds {
// TODO: add support for EXCEPT and INTERSECT
// TODO: add support for INTERSECT
if operator != ast::CompoundOperator::UnionAll
&& operator != ast::CompoundOperator::Union
&& operator != ast::CompoundOperator::Intersect
{
crate::bail_parse_error!(
"only UNION ALL and UNION are supported for compound SELECTs"
"only UNION ALL, UNION and INTERSECT are supported for compound SELECTs"
);
}
left.push((last, operator));

View file

@ -361,3 +361,60 @@ if {[info exists ::env(SQLITE_EXEC)] && ($::env(SQLITE_EXEC) eq "scripts/limbo-s
y|y}
}
select * from t UNION select * from u UNION select * from v UNION ALL select * from t;
} {x|x
y|y
x|x
y|y}
do_execsql_test_on_specific_db {:memory:} select-intersect-1 {
CREATE TABLE t(x TEXT, y TEXT);
CREATE TABLE u(x TEXT, y TEXT);
INSERT INTO t VALUES('x','x'),('y','y');
INSERT INTO u VALUES('x','x'),('z','y');
select * from t INTERSECT select * from u;
} {x|x}
do_execsql_test_on_specific_db {:memory:} select-intersect-2 {
CREATE TABLE t(x TEXT, y TEXT);
CREATE TABLE u(x TEXT, y TEXT);
CREATE TABLE v(x TEXT, y TEXT);
INSERT INTO t VALUES('x','x'),('y','y');
INSERT INTO u VALUES('x','x'),('y','y');
INSERT INTO v VALUES('a','x'),('y','y');
select * from t INTERSECT select * from u INTERSECT select * from v INTERSECT select * from t;
} {y|y}
do_execsql_test_on_specific_db {:memory:} select-intersect-union {
CREATE TABLE t(x TEXT, y TEXT);
CREATE TABLE u(x TEXT, y TEXT);
CREATE TABLE v(x TEXT, y TEXT);
INSERT INTO t VALUES('x','x'),('y','y');
INSERT INTO u VALUES('x','x'),('z','y');
INSERT INTO v VALUES('x','x'),('z','z');
select * from t INTERSECT select * from u UNION select * from v;
} {x|x
z|z}
do_execsql_test_on_specific_db {:memory:} select-union-intersect {
CREATE TABLE t(x TEXT, y TEXT);
CREATE TABLE u(x TEXT, y TEXT);
CREATE TABLE v(x TEXT, y TEXT);
INSERT INTO t VALUES('x','x'),('y','y');
INSERT INTO u VALUES('x','x'),('z','y');
INSERT INTO v VALUES('x','x'),('z','z');
select * from t UNION select * from u INTERSECT select * from v;
} {x|x}
#do_execsql_test_on_specific_db {:memory:} select-intersect-with-limit {
# CREATE TABLE t(x TEXT, y TEXT);
# CREATE TABLE u(x TEXT, y TEXT);
# INSERT INTO t VALUES('x','x'),('y','y'), ('z','z');
# INSERT INTO u VALUES('x','x'),('y','y'), ('z','z');
# select * from t INTERSECT select * from u limit 2;
#} {x|x}