From 6d9df93f5b440ea270f32e4914a681c55d58f377 Mon Sep 17 00:00:00 2001 From: Linwei Zhang Date: Sun, 25 Feb 2024 01:51:29 +0800 Subject: [PATCH] Add back physical create index node --- bustubx/src/catalog/catalog.rs | 68 ++++--------------- .../execution/physical_plan/create_index.rs | 24 ++++++- bustubx/src/execution/physical_plan/insert.rs | 2 +- 3 files changed, 36 insertions(+), 58 deletions(-) diff --git a/bustubx/src/catalog/catalog.rs b/bustubx/src/catalog/catalog.rs index 6bff6e1..944cf37 100644 --- a/bustubx/src/catalog/catalog.rs +++ b/bustubx/src/catalog/catalog.rs @@ -116,15 +116,10 @@ impl Catalog { &mut self, index_name: String, table_ref: &TableReference, - key_attrs: Vec, + key_schema: SchemaRef, ) -> BustubxResult> { let (catalog, schema, table) = table_ref.extend_to_full(); let full_index_ref = (catalog, schema, table, index_name.clone()); - - let table_info = self.table_heap(table_ref)?; - let tuple_schema = table_info.schema.clone(); - let key_schema = tuple_schema.project(&key_attrs)?; - let b_plus_tree_index = BPlusTreeIndex::new( key_schema.clone(), self.buffer_pool.clone(), @@ -214,60 +209,25 @@ mod tests { Column::new("b", DataType::Int16, true), Column::new("c", DataType::Int32, true), ])); - let _ = catalog.create_table(table_ref.clone(), schema); + let _ = catalog.create_table(table_ref.clone(), schema.clone()); let index_name1 = "test_index1".to_string(); - let key_attrs = vec![0, 2]; - let index_info = catalog - .create_index(index_name1.clone(), &table_ref, key_attrs) + let key_schema1 = schema.project(&vec![0, 2]).unwrap(); + let index1 = catalog + .create_index(index_name1.clone(), &table_ref, key_schema1.clone()) .unwrap(); - assert_eq!(index_info.key_schema.column_count(), 2); - assert_eq!( - index_info.key_schema.column_with_index(0).unwrap().name, - "a".to_string() - ); - assert_eq!( - index_info - .key_schema - .column_with_index(0) - .unwrap() - .data_type, - DataType::Int8 - ); - assert_eq!( - index_info.key_schema.column_with_index(1).unwrap().name, - "c".to_string() - ); - assert_eq!( - index_info - .key_schema - .column_with_index(1) - .unwrap() - .data_type, - DataType::Int32 - ); + assert_eq!(index1.key_schema, key_schema1); let index_name2 = "test_index2".to_string(); - let key_attrs = vec![1]; - let index_info = catalog - .create_index(index_name2.clone(), &table_ref, key_attrs) + let key_schema2 = schema.project(&vec![1]).unwrap(); + let index2 = catalog + .create_index(index_name2.clone(), &table_ref, key_schema2.clone()) .unwrap(); - assert_eq!(index_info.key_schema.column_count(), 1); - assert_eq!( - index_info.key_schema.column_with_index(0).unwrap().name, - "b".to_string() - ); - assert_eq!( - index_info - .key_schema - .column_with_index(0) - .unwrap() - .data_type, - DataType::Int16 - ); + assert_eq!(index2.key_schema, key_schema2); - let index_info = catalog.get_index_by_name(&table_ref, index_name1.as_str()); - assert!(index_info.is_some()); - let _index_info = index_info.unwrap(); + let index3 = catalog + .get_index_by_name(&table_ref, index_name1.as_str()) + .unwrap(); + assert_eq!(index3.key_schema, key_schema1); } } diff --git a/bustubx/src/execution/physical_plan/create_index.rs b/bustubx/src/execution/physical_plan/create_index.rs index 4f9a36a..a1e56f6 100644 --- a/bustubx/src/execution/physical_plan/create_index.rs +++ b/bustubx/src/execution/physical_plan/create_index.rs @@ -1,10 +1,11 @@ use crate::catalog::{SchemaRef, EMPTY_SCHEMA_REF}; use crate::common::TableReference; +use crate::expression::{ColumnExpr, Expr}; use crate::planner::logical_plan::OrderByExpr; use crate::{ execution::{ExecutionContext, VolcanoExecutor}, storage::Tuple, - BustubxResult, + BustubxError, BustubxResult, }; #[derive(Debug, derive_new::new)] @@ -16,8 +17,25 @@ pub struct PhysicalCreateIndex { } impl VolcanoExecutor for PhysicalCreateIndex { - fn next(&self, _context: &mut ExecutionContext) -> BustubxResult> { - // TODO implement + fn next(&self, context: &mut ExecutionContext) -> BustubxResult> { + let mut key_indices = vec![]; + for col in self.columns.iter() { + match col.expr.as_ref() { + Expr::Column(ColumnExpr { name, .. }) => { + key_indices.push(self.table_schema.index_of(None, name)?); + } + _ => { + return Err(BustubxError::Execution(format!( + "The expr should be column instead of {}", + col.expr + ))) + } + } + } + let key_schema = self.table_schema.project(&key_indices)?; + context + .catalog + .create_index(self.name.clone(), &self.table, key_schema)?; Ok(None) } fn output_schema(&self) -> SchemaRef { diff --git a/bustubx/src/execution/physical_plan/insert.rs b/bustubx/src/execution/physical_plan/insert.rs index a90501e..9bf4106 100644 --- a/bustubx/src/execution/physical_plan/insert.rs +++ b/bustubx/src/execution/physical_plan/insert.rs @@ -80,7 +80,7 @@ impl VolcanoExecutor for PhysicalInsert { }; // TODO update index if needed - let table_heap = &mut context.catalog.table_heap(&self.table)?; + let table_heap = context.catalog.table_heap(&self.table)?; let tuple_meta = TupleMeta { insert_txn_id: 0, delete_txn_id: 0,