mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 22:08:55 +08:00 
			
		
		
		
	Iterate on both index constraint and usage
This commit is contained in:
		| @@ -91,8 +91,8 @@ unsafe impl<'vtab> VTab<'vtab> for ArrayTab { | ||||
|  | ||||
|     fn best_index(&self, info: &mut IndexInfo) -> Result<()> { | ||||
|         // Index of the pointer= constraint | ||||
|         let mut ptr_idx = None; | ||||
|         for (i, constraint) in info.constraints().enumerate() { | ||||
|         let mut ptr_idx = false; | ||||
|         for (constraint, mut constraint_usage) in info.constraints_and_usages() { | ||||
|             if !constraint.is_usable() { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -100,15 +100,12 @@ unsafe impl<'vtab> VTab<'vtab> for ArrayTab { | ||||
|                 continue; | ||||
|             } | ||||
|             if let CARRAY_COLUMN_POINTER = constraint.column() { | ||||
|                 ptr_idx = Some(i); | ||||
|             } | ||||
|         } | ||||
|         if let Some(ptr_idx) = ptr_idx { | ||||
|             { | ||||
|                 let mut constraint_usage = info.constraint_usage(ptr_idx); | ||||
|                 ptr_idx = true; | ||||
|                 constraint_usage.set_argv_index(1); | ||||
|                 constraint_usage.set_omit(true); | ||||
|             } | ||||
|         } | ||||
|         if ptr_idx { | ||||
|             info.set_estimated_cost(1f64); | ||||
|             info.set_estimated_rows(100); | ||||
|             info.set_idx_num(1); | ||||
|   | ||||
| @@ -309,6 +309,19 @@ impl From<u8> for IndexConstraintOp { | ||||
| pub struct IndexInfo(*mut ffi::sqlite3_index_info); | ||||
|  | ||||
| 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. | ||||
|     #[inline] | ||||
|     pub fn constraints(&self) -> IndexConstraintIter<'_> { | ||||
| @@ -384,6 +397,30 @@ impl IndexInfo { | ||||
|     // 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"` | ||||
| pub struct IndexConstraintIter<'a> { | ||||
|     iter: slice::Iter<'a, ffi::sqlite3_index_constraint>, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user