Skip to content

Commit f96633d

Browse files
committed
feat(catalog): implement multi-field select and create table plan
1 parent 0ea995f commit f96633d

19 files changed

Lines changed: 149 additions & 151 deletions

File tree

src/binder/create.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,19 @@ impl Binder {
3131

3232
let columns: Vec<ColumnCatalog> = columns
3333
.iter()
34-
.enumerate()
35-
.map(|(_, col)| ColumnCatalog::from(col.clone()))
34+
.map(|col| ColumnCatalog::from(col.clone()))
3635
.collect();
3736

3837
let plan = LogicalCreateTablePlan {
3938
table_name: table_name.to_string(),
40-
columns: columns
41-
.into_iter()
42-
.map(|col| (col.name.to_string(), col.nullable, col.desc.clone()))
43-
.collect(),
39+
columns,
4440
};
4541
Ok(plan)
4642
}
4743
}
4844

4945
#[cfg(test)]
5046
mod tests {
51-
use sqlparser::ast::CharacterLength;
52-
5347
use super::*;
5448
use crate::binder::BinderContext;
5549
use crate::catalog::{ColumnDesc, RootCatalog};
@@ -66,16 +60,16 @@ mod tests {
6660
let plan2 = LogicalPlan::CreateTable(LogicalCreateTablePlan {
6761
table_name: "t1".to_string(),
6862
columns: vec![
69-
(
63+
ColumnCatalog::new(
7064
"id".to_string(),
7165
false,
72-
ColumnDesc::new(LogicalType::Integer, false),
66+
ColumnDesc::new(LogicalType::Integer, false)
7367
),
74-
(
68+
ColumnCatalog::new(
7569
"name".to_string(),
7670
false,
77-
ColumnDesc::new(LogicalType::Varchar, false),
78-
),
71+
ColumnDesc::new(LogicalType::Varchar, false)
72+
)
7973
],
8074
});
8175

src/binder/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Binder {
5757
} else {
5858
// handle col syntax
5959
let mut got_column = None;
60-
for table_catalog in self.context.catalog.tables.values() {
60+
for table_catalog in &self.context.catalog.tables {
6161
if let Some(column_catalog) = table_catalog.get_column_by_name(column_name) {
6262
if got_column.is_some() {
6363
return Err(BindError::InvalidColumn(column_name.to_string()).into());

src/binder/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ use sqlparser::ast::{Ident, ObjectName, Statement};
1111
use crate::catalog::{RootCatalog, DEFAULT_SCHEMA_NAME, CatalogError};
1212
use crate::expression::ScalarExpression;
1313
use crate::planner::LogicalPlan;
14-
use crate::types::TableId;
14+
use crate::types::TableIdx;
1515
#[derive(Clone)]
1616
pub struct BinderContext {
1717
catalog: RootCatalog,
18-
bind_table: HashMap<String, TableId>,
18+
bind_table: HashMap<String, TableIdx>,
1919
aliases: HashMap<String, ScalarExpression>,
2020
group_by_exprs: Vec<ScalarExpression>,
2121
agg_calls: Vec<ScalarExpression>,

src/catalog/column.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use arrow::datatypes::{DataType, Field};
22
use sqlparser::ast::{ColumnDef, ColumnOption};
33

4-
use crate::types::{ColumnId, IdGenerator, LogicalType};
4+
use crate::types::{ColumnIdx, LogicalType};
55

66
#[derive(Debug, Clone, PartialEq)]
77
pub struct ColumnCatalog {
8-
pub id: ColumnId,
8+
pub id: Option<ColumnIdx>,
99
pub name: String,
1010
pub nullable: bool,
1111
pub desc: ColumnDesc,
@@ -14,7 +14,7 @@ pub struct ColumnCatalog {
1414
impl ColumnCatalog {
1515
pub(crate) fn new(column_name: String, nullable: bool, column_desc: ColumnDesc) -> ColumnCatalog {
1616
ColumnCatalog {
17-
id: IdGenerator::build(),
17+
id: None,
1818
name: column_name,
1919
nullable,
2020
desc: column_desc,
@@ -25,10 +25,6 @@ impl ColumnCatalog {
2525
&self.desc.column_datatype
2626
}
2727

28-
pub(crate) fn id(&self) -> ColumnId {
29-
self.id
30-
}
31-
3228
pub fn desc(&self) -> &ColumnDesc {
3329
&self.desc
3430
}

src/catalog/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::sync::Arc;
44
pub(crate) use self::column::*;
55
pub(crate) use self::root::*;
66
pub(crate) use self::table::*;
7-
use crate::types::{ColumnId, TableId};
7+
use crate::types::{ColumnIdx, TableIdx};
88

99
/// The type of catalog reference.
1010
pub type CatalogRef = Arc<RootCatalog>;
@@ -19,12 +19,12 @@ mod table;
1919
/// The reference ID of a column.
2020
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
2121
pub struct ColumnRefId {
22-
pub table_id: TableId,
23-
pub column_id: ColumnId,
22+
pub table_id: TableIdx,
23+
pub column_id: ColumnIdx,
2424
}
2525

2626
impl ColumnRefId {
27-
pub const fn from_table(table_id: TableId, column_id: ColumnId) -> Self {
27+
pub const fn from_table(table_id: TableIdx, column_id: ColumnIdx) -> Self {
2828
ColumnRefId {
2929
table_id,
3030
column_id,
@@ -34,11 +34,11 @@ impl ColumnRefId {
3434

3535
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
3636
pub struct TableRefId {
37-
pub table_id: TableId,
37+
pub table_id: TableIdx,
3838
}
3939

4040
impl TableRefId {
41-
pub const fn new(table_id: TableId) -> Self {
41+
pub const fn new(table_id: TableIdx) -> Self {
4242
TableRefId { table_id }
4343
}
4444
}

src/catalog/root.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use std::collections::BTreeMap;
22

33
use crate::catalog::{CatalogError, ColumnCatalog, TableCatalog};
4-
use crate::types::TableId;
4+
use crate::types::{IdGenerator, TableIdx};
55

66
#[derive(Debug, Clone)]
77
pub struct RootCatalog {
8-
pub table_idxs: BTreeMap<String, TableId>,
9-
pub tables: BTreeMap<TableId, TableCatalog>,
8+
generator: IdGenerator,
9+
pub table_idxs: BTreeMap<String, TableIdx>,
10+
pub tables: Vec<TableCatalog>,
1011
}
1112

1213
impl Default for RootCatalog {
@@ -19,35 +20,37 @@ impl RootCatalog {
1920
#[allow(dead_code)]
2021
pub fn new() -> Self {
2122
RootCatalog {
23+
generator: IdGenerator::new(),
2224
table_idxs: Default::default(),
2325
tables: Default::default(),
2426
}
2527
}
2628

27-
pub(crate) fn get_table_id_by_name(&self, name: &str) -> Option<TableId> {
29+
pub(crate) fn get_table_id_by_name(&self, name: &str) -> Option<TableIdx> {
2830
self.table_idxs.get(name).cloned()
2931
}
3032

31-
pub(crate) fn get_table(&self, table_id: TableId) -> Option<&TableCatalog> {
32-
self.tables.get(&table_id)
33+
pub(crate) fn get_table(&self, table_id: TableIdx) -> Option<&TableCatalog> {
34+
self.tables.get(table_id)
3335
}
3436

3537
pub(crate) fn get_table_by_name(&self, name: &str) -> Option<&TableCatalog> {
3638
let id = self.table_idxs.get(name)?;
37-
self.tables.get(id)
39+
self.tables.get(*id)
3840
}
3941

4042
pub(crate) fn add_table(
4143
&mut self,
4244
table_name: String,
4345
columns: Vec<ColumnCatalog>,
44-
) -> Result<TableId, CatalogError> {
46+
) -> Result<TableIdx, CatalogError> {
4547
if self.table_idxs.contains_key(&table_name) {
4648
return Err(CatalogError::Duplicated("column", table_name));
4749
}
48-
let table = TableCatalog::new(table_name.to_owned(), columns)?;
49-
let table_id = table.id;
50+
let mut table = TableCatalog::new(table_name.to_owned(), columns)?;
51+
let table_id = self.generator.build();
5052

53+
table.id = Some(table_id);
5154
self.table_idxs.insert(table_name, table_id);
5255
self.tables.insert(table_id, table);
5356

src/catalog/table.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,56 @@
1-
use std::collections::{BTreeMap, HashMap};
1+
use std::collections::HashMap;
22

33
use itertools::Itertools;
44

55
use crate::catalog::{CatalogError, ColumnCatalog};
6-
use crate::types::{ColumnId, IdGenerator, TableId};
6+
use crate::types::{ColumnIdx, IdGenerator, TableIdx};
77
#[derive(Debug, Clone)]
88
pub struct TableCatalog {
9-
pub id: TableId,
9+
pub id: Option<TableIdx>,
1010
pub name: String,
11+
generator: IdGenerator,
1112
/// Mapping from column names to column ids
12-
column_idxs: HashMap<String, ColumnId>,
13-
pub(crate) columns: BTreeMap<ColumnId, ColumnCatalog>,
13+
column_idxs: HashMap<String, ColumnIdx>,
14+
pub(crate) columns: Vec<ColumnCatalog>,
1415
}
1516

1617
impl TableCatalog {
17-
pub(crate) fn get_column_by_id(&self, id: ColumnId) -> Option<&ColumnCatalog> {
18-
self.columns.get(&id)
18+
pub(crate) fn get_column_by_id(&self, id: ColumnIdx) -> Option<&ColumnCatalog> {
19+
self.columns.get(id)
1920
}
2021

21-
pub(crate) fn get_column_id_by_name(&self, name: &str) -> Option<ColumnId> {
22+
pub(crate) fn get_column_id_by_name(&self, name: &str) -> Option<ColumnIdx> {
2223
self.column_idxs.get(name).cloned()
2324
}
2425

2526
pub(crate) fn get_column_by_name(&self, name: &str) -> Option<&ColumnCatalog> {
2627
let id = self.column_idxs.get(name)?;
27-
self.columns.get(id)
28+
self.columns.get(*id)
2829
}
2930

3031
pub(crate) fn contains_column(&self, name: &str) -> bool {
3132
self.column_idxs.contains_key(name)
3233
}
3334

34-
pub(crate) fn get_all_columns(&self) -> Vec<(ColumnId, &ColumnCatalog)> {
35+
pub(crate) fn get_all_columns(&self) -> Vec<(ColumnIdx, &ColumnCatalog)> {
3536
self.columns
3637
.iter()
37-
.map(|(col_id, col)| (*col_id, col))
38+
.enumerate()
3839
.collect_vec()
3940
}
4041

4142
/// Add a column to the table catalog.
4243
pub(crate) fn add_column(
4344
&mut self,
44-
col_catalog: ColumnCatalog,
45-
) -> Result<ColumnId, CatalogError> {
45+
mut col_catalog: ColumnCatalog,
46+
) -> Result<ColumnIdx, CatalogError> {
4647
if self.column_idxs.contains_key(&col_catalog.name) {
4748
return Err(CatalogError::Duplicated("column", col_catalog.name.into()));
4849
}
4950

50-
let col_id = col_catalog.id;
51+
let col_id = self.generator.build();
5152

53+
col_catalog.id = Some(col_id);
5254
self.column_idxs.insert(col_catalog.name.to_owned(), col_id);
5355
self.columns.insert(col_id, col_catalog);
5456

@@ -60,10 +62,11 @@ impl TableCatalog {
6062
columns: Vec<ColumnCatalog>,
6163
) -> Result<TableCatalog, CatalogError> {
6264
let mut table_catalog = TableCatalog {
63-
id: IdGenerator::build(),
65+
id: None,
6466
name: table_name,
67+
generator: IdGenerator::new(),
6568
column_idxs: HashMap::new(),
66-
columns: BTreeMap::new(),
69+
columns: Vec::new(),
6770
};
6871

6972
for col_catalog in columns.into_iter() {

src/db.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
use std::sync::Arc;
2-
31
use anyhow::Result;
4-
use arrow::datatypes::Schema;
52
use arrow::error::ArrowError;
63
use arrow::record_batch::RecordBatch;
74
use sqlparser::parser::ParserError;
85

96
use crate::binder::{BindError, Binder, BinderContext};
10-
use crate::catalog::ColumnCatalog;
117
use crate::execution_v1::physical_plan::physical_plan_builder::PhysicalPlanBuilder;
128
use crate::execution_v1::volcano_executor::VolcanoExecutor;
139
use crate::parser::parse_sql;
14-
use crate::planner::LogicalPlan;
1510
use crate::storage::memory::InMemoryStorage;
1611
use crate::storage::{Storage, StorageError, StorageImpl};
17-
use crate::types::IdGenerator;
1812

1913
#[derive(Debug)]
2014
pub struct Database {
@@ -51,10 +45,11 @@ impl Database {
5145
/// Limit(1)
5246
/// Project(a,b)
5347
let logical_plan = binder.bind(&stmts[0])?;
54-
println!("logic plan {:#?}", logical_plan);
48+
println!("logic plan: {:#?}", logical_plan);
5549

5650
let mut builder = PhysicalPlanBuilder::new();
5751
let operator = builder.build_plan(&logical_plan)?;
52+
println!("operator: {:#?}", logical_plan);
5853

5954
let storage = StorageImpl::InMemoryStorage(self.storage.clone());
6055
let executor = VolcanoExecutor::new(storage);
@@ -127,7 +122,7 @@ pub enum DatabaseError {
127122
#[cfg(test)]
128123
mod test {
129124
use std::sync::Arc;
130-
use arrow::array::Int32Array;
125+
use arrow::array::{BooleanArray, Int32Array};
131126
use arrow::datatypes::Schema;
132127
use arrow::record_batch::RecordBatch;
133128
use itertools::Itertools;
@@ -136,22 +131,32 @@ mod test {
136131
use crate::execution_v1::ExecutorError;
137132
use crate::storage::{Storage, StorageError};
138133
use crate::storage::memory::InMemoryStorage;
139-
use crate::types::{IdGenerator, LogicalType, TableId};
140-
141-
fn build_table(storage: &impl Storage) -> Result<TableId, StorageError> {
142-
let fields = vec![
143-
ColumnCatalog::new(
144-
"c1".to_string(),
145-
false,
146-
ColumnDesc::new(LogicalType::Integer, true)
147-
).to_field(),
148-
];
149-
let batch = RecordBatch::try_new(
150-
Arc::new(Schema::new(fields)),
151-
vec![Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]))]
134+
use crate::types::{IdGenerator, LogicalType, TableIdx};
135+
136+
fn build_table(storage: &impl Storage) -> Result<TableIdx, StorageError> {
137+
let schema = Arc::new(Schema::new(
138+
vec![
139+
ColumnCatalog::new(
140+
"c1".to_string(),
141+
false,
142+
ColumnDesc::new(LogicalType::Integer, true)
143+
).to_field(),
144+
ColumnCatalog::new(
145+
"c2".to_string(),
146+
false,
147+
ColumnDesc::new(LogicalType::Boolean, false)
148+
).to_field(),
149+
]
150+
));
151+
let batch_1 = RecordBatch::try_new(
152+
schema.clone(),
153+
vec![
154+
Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])),
155+
Arc::new(BooleanArray::from(vec![true, true, false, true, false]))
156+
]
152157
).unwrap();
153158

154-
Ok(storage.create_table("t1", vec![batch])?)
159+
Ok(storage.create_table("t1", vec![batch_1])?)
155160
}
156161

157162
#[test]
@@ -172,8 +177,8 @@ mod test {
172177
let database = Database::new_on_mem();
173178

174179
tokio_test::block_on(async move {
175-
let _batch = database.run("create table t1 (a int)").await?;
176-
let batch = database.run("select a from t1").await?;
180+
let _batch = database.run("create table t1 (a int, b int)").await?;
181+
let batch = database.run("select * from t1").await?;
177182
println!("{:#?}", batch);
178183

179184
Ok(())

0 commit comments

Comments
 (0)