ajust code to accommodate index_experimental feature

This commit is contained in:
meteorgan 2025-06-21 23:59:34 +08:00
parent c060905d00
commit 2c4847210f
3 changed files with 113 additions and 109 deletions

View file

@ -154,12 +154,8 @@ fn emit_compound_select(
(cursor_id, index.clone())
}
_ => {
if !schema.indexes_enabled() {
crate::bail_parse_error!("UNION not supported without indexes");
} else {
new_dedupe_index = true;
create_dedupe_index(program, &right_most)
}
new_dedupe_index = true;
create_dedupe_index(program, &right_most, schema)?
}
};
plan.query_destination = QueryDestination::EphemeralIndex {
@ -210,7 +206,7 @@ fn emit_compound_select(
target_cursor_id = Some(cursor_id);
}
let (left_cursor_id, left_index) = create_dedupe_index(program, &right_most);
let (left_cursor_id, left_index) = create_dedupe_index(program, &right_most, schema)?;
plan.query_destination = QueryDestination::EphemeralIndex {
cursor_id: left_cursor_id,
index: left_index.clone(),
@ -232,7 +228,7 @@ fn emit_compound_select(
reg_result_cols_start,
)?;
let (right_cursor_id, right_index) = create_dedupe_index(program, &right_most);
let (right_cursor_id, right_index) = create_dedupe_index(program, &right_most, schema)?;
right_most.query_destination = QueryDestination::EphemeralIndex {
cursor_id: right_cursor_id,
index: right_index,
@ -265,7 +261,15 @@ fn emit_compound_select(
}
// Creates an ephemeral index that will be used to deduplicate the results of any sub-selects
fn create_dedupe_index(program: &mut ProgramBuilder, select: &SelectPlan) -> (usize, Arc<Index>) {
fn create_dedupe_index(
program: &mut ProgramBuilder,
select: &SelectPlan,
schema: &Schema
) -> crate::Result<(usize, Arc<Index>)> {
if !schema.indexes_enabled {
crate::bail_parse_error!("UNION OR INTERSECT is not supported without indexes");
}
let dedupe_index = Arc::new(Index {
columns: select
.result_columns
@ -293,7 +297,7 @@ fn create_dedupe_index(program: &mut ProgramBuilder, select: &SelectPlan) -> (us
cursor_id,
is_table: false,
});
(cursor_id, dedupe_index.clone())
Ok((cursor_id, dedupe_index.clone()))
}
/// Emits the bytecode for reading deduplicated rows from the ephemeral index created for UNION operators.

View file

@ -336,32 +336,32 @@ if {[info exists ::env(SQLITE_EXEC)] && ($::env(SQLITE_EXEC) eq "scripts/limbo-s
SELECT * FROM t;
} {1|100
2|200}
do_execsql_test_on_specific_db {:memory:} insert_from_select_intersect {
CREATE TABLE t(a, b);
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t1 VALUES (1, 100), (2, 200);
INSERT INTO t2 VALUES (2, 200), (3, 300);
INSERT INTO t SELECT * FROM t1 INTERSECT SELECT * FROM t2;
SELECT * FROM t;
} {2|200}
do_execsql_test_on_specific_db {:memory:} insert_from_select_intersect-2 {
CREATE TABLE t(a, b);
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
CREATE TABLE t3(a, b);
INSERT INTO t1 VALUES (1, 100), (2, 200);
INSERT INTO t2 VALUES (2, 200), (3, 300);
INSERT INTO t3 VALUES (2, 200), (4, 400);
INSERT INTO t SELECT * FROM t1 INTERSECT SELECT * FROM t2 INTERSECT SELECT * FROM t3;
SELECT * FROM t;
} {2|200}
}
do_execsql_test_on_specific_db {:memory:} insert_from_select_intersect {
CREATE TABLE t(a, b);
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t1 VALUES (1, 100), (2, 200);
INSERT INTO t2 VALUES (2, 200), (3, 300);
INSERT INTO t SELECT * FROM t1 INTERSECT SELECT * FROM t2;
SELECT * FROM t;
} {2|200}
do_execsql_test_on_specific_db {:memory:} insert_from_select_intersect-2 {
CREATE TABLE t(a, b);
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
CREATE TABLE t3(a, b);
INSERT INTO t1 VALUES (1, 100), (2, 200);
INSERT INTO t2 VALUES (2, 200), (3, 300);
INSERT INTO t3 VALUES (2, 200), (4, 400);
INSERT INTO t SELECT * FROM t1 INTERSECT SELECT * FROM t2;
SELECT * FROM t;
} {2|200}
do_execsql_test_on_specific_db {:memory:} negative-primary-integer-key {
CREATE TABLE t(a INTEGER PRIMARY KEY);
insert into t values (-2),(13);

View file

@ -359,94 +359,94 @@ if {[info exists ::env(SQLITE_EXEC)] && ($::env(SQLITE_EXEC) eq "scripts/limbo-s
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');
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}
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');
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}
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');
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}
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');
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}
select * from t UNION select * from u INTERSECT select * from v;
} {x|x}
do_execsql_test_on_specific_db {:memory:} select-union-all-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');
do_execsql_test_on_specific_db {:memory:} select-union-all-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 ALL select * from u INTERSECT select * from v;
} {x|x}
select * from t UNION ALL select * from u INTERSECT select * from v;
} {x|x}
do_execsql_test_on_specific_db {:memory:} select-intersect-union-all {
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');
do_execsql_test_on_specific_db {:memory:} select-intersect-union-all {
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 ALL select * from v;
} {x|x
x|x
z|z}
select * from t INTERSECT select * from u UNION ALL select * from v;
} {x|x
x|x
z|z}
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');
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
y|y}
select * from t INTERSECT select * from u limit 2;
} {x|x
y|y}
do_execsql_test_on_specific_db {:memory:} select-intersect-union-with-limit {
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'), ('z','z');
INSERT INTO u VALUES('d','d'),('e','e'), ('z','z');
INSERT INTO v VALUES('a','a'),('b','b');
do_execsql_test_on_specific_db {:memory:} select-intersect-union-with-limit {
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'), ('z','z');
INSERT INTO u VALUES('d','d'),('e','e'), ('z','z');
INSERT INTO v VALUES('a','a'),('b','b');
select * from t INTERSECT select * from u UNION select * from v limit 3;
} {a|a
b|b
z|z}
select * from t INTERSECT select * from u UNION select * from v limit 3;
} {a|a
b|b
z|z}
}