Skip to content

Commit 79dbefc

Browse files
Fix index scan rewrite rule
1 parent 74ad4a1 commit 79dbefc

3 files changed

Lines changed: 67 additions & 17 deletions

File tree

crates/core/src/sql/execute.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,39 @@ pub(crate) mod tests {
495495
);
496496
}
497497

498+
/// Test a query that uses a multi-column index
499+
#[test]
500+
fn test_multi_column_index() -> anyhow::Result<()> {
501+
let db = TestDB::in_memory()?;
502+
503+
let schema = [
504+
("a", AlgebraicType::U64),
505+
("b", AlgebraicType::U64),
506+
("c", AlgebraicType::U64),
507+
];
508+
509+
let table_id = db.create_table_for_test_multi_column("t", &schema, [1, 2].into())?;
510+
511+
insert_rows(
512+
&db,
513+
table_id,
514+
vec![
515+
product![0_u64, 1_u64, 2_u64],
516+
product![1_u64, 2_u64, 1_u64],
517+
product![2_u64, 2_u64, 2_u64],
518+
],
519+
)?;
520+
521+
assert_query_results(
522+
&db,
523+
"select * from t where c = 1 and b = 2",
524+
&AuthCtx::for_testing(),
525+
[product![1_u64, 2_u64, 1_u64]],
526+
);
527+
528+
Ok(())
529+
}
530+
498531
/// Test querying a table with RLS rules
499532
#[test]
500533
fn test_rls_rules() -> anyhow::Result<()> {

crates/physical-plan/src/plan.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,10 +1830,10 @@ mod tests {
18301830
_,
18311831
)) => {
18321832
assert_eq!(schema.table_id, t_id);
1833-
assert_eq!(arg, Sarg::Eq(ColId(1), AlgebraicValue::U8(3)));
1833+
assert_eq!(arg, Sarg::Eq(ColId(3), AlgebraicValue::U8(5)));
18341834
assert_eq!(
18351835
prefix,
1836-
vec![(ColId(3), AlgebraicValue::U8(5)), (ColId(2), AlgebraicValue::U8(4))]
1836+
vec![(ColId(1), AlgebraicValue::U8(3)), (ColId(2), AlgebraicValue::U8(4))]
18371837
);
18381838
}
18391839
proj => panic!("unexpected plan: {:#?}", proj),
@@ -1941,8 +1941,8 @@ mod tests {
19411941
_,
19421942
)) => {
19431943
assert_eq!(schema.table_id, t_id);
1944-
assert_eq!(arg, Sarg::Eq(ColId(2), AlgebraicValue::U8(1)));
1945-
assert_eq!(prefix, vec![(ColId(3), AlgebraicValue::U8(2))]);
1944+
assert_eq!(arg, Sarg::Eq(ColId(3), AlgebraicValue::U8(2)));
1945+
assert_eq!(prefix, vec![(ColId(2), AlgebraicValue::U8(1))]);
19461946
}
19471947
proj => panic!("unexpected plan: {:#?}", proj),
19481948
};

crates/physical-plan/src/rules.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -622,13 +622,20 @@ impl RewriteRule for IxScanEq2Col {
622622
.indexes
623623
.iter()
624624
.filter(|idx| idx.index_algorithm.columns().len() == 2) // TODO: Support prefix scans
625-
.find_map(|idx| {
625+
.map(|idx| (idx.index_id, idx.index_algorithm.columns()))
626+
.find_map(|(index_id, columns)| {
627+
let mut columns = columns.iter();
628+
let x = columns.next()?;
629+
if x.idx() != u.field_pos {
630+
return None;
631+
}
632+
let y = columns.next()?;
633+
if y.idx() != v.field_pos {
634+
return None;
635+
}
626636
Some(IxScanInfo {
627-
index_id: idx.index_id,
628-
cols: vec![
629-
(i, idx.index_algorithm.find_col_index(u.field_pos)?),
630-
(j, idx.index_algorithm.find_col_index(v.field_pos)?),
631-
],
637+
index_id,
638+
cols: vec![(i, x), (j, y)],
632639
})
633640
})
634641
{
@@ -795,14 +802,24 @@ impl RewriteRule for IxScanEq3Col {
795802
.indexes
796803
.iter()
797804
.filter(|idx| idx.index_algorithm.columns().len() == 3)
798-
.find_map(|idx| {
805+
.map(|idx| (idx.index_id, idx.index_algorithm.columns()))
806+
.find_map(|(index_id, columns)| {
807+
let mut columns = columns.iter();
808+
let x = columns.next()?;
809+
if x.idx() != u.field_pos {
810+
return None;
811+
}
812+
let y = columns.next()?;
813+
if y.idx() != v.field_pos {
814+
return None;
815+
}
816+
let z = columns.next()?;
817+
if z.idx() != w.field_pos {
818+
return None;
819+
}
799820
Some(IxScanInfo {
800-
index_id: idx.index_id,
801-
cols: vec![
802-
(i, idx.index_algorithm.find_col_index(u.field_pos)?),
803-
(j, idx.index_algorithm.find_col_index(v.field_pos)?),
804-
(k, idx.index_algorithm.find_col_index(w.field_pos)?),
805-
],
821+
index_id,
822+
cols: vec![(i, x), (j, y), (k, z)],
806823
})
807824
})
808825
{

0 commit comments

Comments
 (0)