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<()> { |     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); | ||||||
|   | |||||||
| @@ -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>, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user