Merge pull request #1006 from gwenn/constraints_and_usages

Iterate on both index constraint and usage
This commit is contained in:
gwenn 2021-07-31 10:01:37 +02:00 committed by GitHub
commit 7e74952e2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 8 deletions

View File

@ -91,8 +91,8 @@ unsafe impl<'vtab> VTab<'vtab> for ArrayTab {
fn best_index(&self, info: &mut IndexInfo) -> Result<()> { fn best_index(&self, info: &mut IndexInfo) -> Result<()> {
// Index of the pointer= constraint // Index of the pointer= constraint
let mut ptr_idx = None; let mut ptr_idx = false;
for (i, constraint) in info.constraints().enumerate() { for (constraint, mut constraint_usage) in info.constraints_and_usages() {
if !constraint.is_usable() { if !constraint.is_usable() {
continue; continue;
} }
@ -100,15 +100,12 @@ unsafe impl<'vtab> VTab<'vtab> for ArrayTab {
continue; continue;
} }
if let CARRAY_COLUMN_POINTER = constraint.column() { if let CARRAY_COLUMN_POINTER = constraint.column() {
ptr_idx = Some(i); ptr_idx = true;
}
}
if let Some(ptr_idx) = ptr_idx {
{
let mut constraint_usage = info.constraint_usage(ptr_idx);
constraint_usage.set_argv_index(1); constraint_usage.set_argv_index(1);
constraint_usage.set_omit(true); constraint_usage.set_omit(true);
} }
}
if ptr_idx {
info.set_estimated_cost(1f64); info.set_estimated_cost(1f64);
info.set_estimated_rows(100); info.set_estimated_rows(100);
info.set_idx_num(1); info.set_idx_num(1);

View File

@ -309,6 +309,19 @@ impl From<u8> for IndexConstraintOp {
pub struct IndexInfo(*mut ffi::sqlite3_index_info); pub struct IndexInfo(*mut ffi::sqlite3_index_info);
impl IndexInfo { impl IndexInfo {
/// Iterate on index constraint and its associated usage.
#[inline]
pub fn constraints_and_usages(&mut self) -> IndexConstraintAndUsageIter<'_> {
let constraints =
unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
let constraint_usages = unsafe {
slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
};
IndexConstraintAndUsageIter {
iter: constraints.iter().zip(constraint_usages.iter_mut()),
}
}
/// Record WHERE clause constraints. /// Record WHERE clause constraints.
#[inline] #[inline]
pub fn constraints(&self) -> IndexConstraintIter<'_> { pub fn constraints(&self) -> IndexConstraintIter<'_> {
@ -384,6 +397,30 @@ impl IndexInfo {
// TODO sqlite3_vtab_collation (http://sqlite.org/c3ref/vtab_collation.html) // TODO sqlite3_vtab_collation (http://sqlite.org/c3ref/vtab_collation.html)
} }
/// Iterate on index constraint and its associated usage.
pub struct IndexConstraintAndUsageIter<'a> {
iter: std::iter::Zip<
slice::Iter<'a, ffi::sqlite3_index_constraint>,
slice::IterMut<'a, ffi::sqlite3_index_constraint_usage>,
>,
}
impl<'a> Iterator for IndexConstraintAndUsageIter<'a> {
type Item = (IndexConstraint<'a>, IndexConstraintUsage<'a>);
#[inline]
fn next(&mut self) -> Option<(IndexConstraint<'a>, IndexConstraintUsage<'a>)> {
self.iter
.next()
.map(|raw| (IndexConstraint(raw.0), IndexConstraintUsage(raw.1)))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
/// `feature = "vtab"` /// `feature = "vtab"`
pub struct IndexConstraintIter<'a> { pub struct IndexConstraintIter<'a> {
iter: slice::Iter<'a, ffi::sqlite3_index_constraint>, iter: slice::Iter<'a, ffi::sqlite3_index_constraint>,