Skip to content

Commit d284291

Browse files
authored
Merge pull request #27 from loloxwg/feat/execute
feat(execute): add create table PhysicalOperator
2 parents 50332a0 + b75de42 commit d284291

25 files changed

Lines changed: 304 additions & 143 deletions

rust-toolchain

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nightly

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: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,78 @@
1+
use crate::binder::BindError;
12
use anyhow::Result;
2-
use sqlparser::ast::Expr;
3+
use itertools::Itertools;
4+
use sqlparser::ast::{Expr, Ident};
5+
use std::slice;
36

47
use super::Binder;
58
use crate::expression::ScalarExpression;
69

710
impl Binder {
811
pub(crate) fn bind_expr(&mut self, expr: &Expr) -> Result<ScalarExpression> {
9-
todo!()
12+
match expr {
13+
Expr::Identifier(ident) => {
14+
self.bind_column_ref_from_identifiers(slice::from_ref(ident))
15+
}
16+
_ => {
17+
todo!()
18+
}
19+
}
20+
}
21+
22+
pub fn bind_column_ref_from_identifiers(
23+
&mut self,
24+
idents: &[Ident],
25+
) -> Result<ScalarExpression> {
26+
let idents = idents
27+
.iter()
28+
.map(|ident| Ident::new(ident.value.to_lowercase()))
29+
.collect_vec();
30+
let (_schema_name, table_name, column_name) = match idents.as_slice() {
31+
[column] => (None, None, &column.value),
32+
[table, column] => (None, Some(&table.value), &column.value),
33+
[schema, table, column] => (Some(&schema.value), Some(&table.value), &column.value),
34+
_ => {
35+
return Err(BindError::InvalidColumn(
36+
idents
37+
.iter()
38+
.map(|ident| ident.value.clone())
39+
.join(".")
40+
.to_string(),
41+
)
42+
.into())
43+
}
44+
};
45+
46+
if let Some(table) = table_name {
47+
let table_catalog = self
48+
.context
49+
.catalog
50+
.get_table_by_name(table)
51+
.ok_or_else(|| BindError::InvalidTable(table.to_string()))?;
52+
53+
let column_catalog = table_catalog
54+
.get_column_by_name(column_name)
55+
.ok_or_else(|| BindError::InvalidColumn(column_name.to_string()))?;
56+
Ok(ScalarExpression::ColumnRef(column_catalog.clone()))
57+
} else {
58+
// handle col syntax
59+
let mut got_column = None;
60+
for table_catalog in &self.context.catalog.tables {
61+
if let Some(column_catalog) = table_catalog.get_column_by_name(column_name) {
62+
if got_column.is_some() {
63+
return Err(BindError::InvalidColumn(column_name.to_string()).into());
64+
}
65+
got_column = Some(column_catalog);
66+
}
67+
}
68+
if got_column.is_none() {
69+
if let Some(expr) = self.context.aliases.get(column_name) {
70+
return Ok(expr.clone());
71+
}
72+
}
73+
let column_catalog =
74+
got_column.ok_or_else(|| BindError::InvalidColumn(column_name.to_string()))?;
75+
Ok(ScalarExpression::ColumnRef(column_catalog.clone()))
76+
}
1077
}
1178
}

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-
table_idxs: BTreeMap<String, TableId>,
9-
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: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +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

26+
pub(crate) fn get_column_by_name(&self, name: &str) -> Option<&ColumnCatalog> {
27+
let id = self.column_idxs.get(name)?;
28+
self.columns.get(*id)
29+
}
30+
2531
pub(crate) fn contains_column(&self, name: &str) -> bool {
2632
self.column_idxs.contains_key(name)
2733
}
2834

29-
pub(crate) fn get_all_columns(&self) -> Vec<(ColumnId, &ColumnCatalog)> {
35+
pub(crate) fn get_all_columns(&self) -> Vec<(ColumnIdx, &ColumnCatalog)> {
3036
self.columns
3137
.iter()
32-
.map(|(col_id, col)| (*col_id, col))
38+
.enumerate()
3339
.collect_vec()
3440
}
3541

3642
/// Add a column to the table catalog.
3743
pub(crate) fn add_column(
3844
&mut self,
39-
col_catalog: ColumnCatalog,
40-
) -> Result<ColumnId, CatalogError> {
45+
mut col_catalog: ColumnCatalog,
46+
) -> Result<ColumnIdx, CatalogError> {
4147
if self.column_idxs.contains_key(&col_catalog.name) {
4248
return Err(CatalogError::Duplicated("column", col_catalog.name.into()));
4349
}
4450

45-
let col_id = col_catalog.id;
51+
let col_id = self.generator.build();
4652

53+
col_catalog.id = Some(col_id);
4754
self.column_idxs.insert(col_catalog.name.to_owned(), col_id);
4855
self.columns.insert(col_id, col_catalog);
4956

@@ -55,10 +62,11 @@ impl TableCatalog {
5562
columns: Vec<ColumnCatalog>,
5663
) -> Result<TableCatalog, CatalogError> {
5764
let mut table_catalog = TableCatalog {
58-
id: IdGenerator::build(),
65+
id: None,
5966
name: table_name,
67+
generator: IdGenerator::new(),
6068
column_idxs: HashMap::new(),
61-
columns: BTreeMap::new(),
69+
columns: Vec::new(),
6270
};
6371

6472
for col_catalog in columns.into_iter() {

0 commit comments

Comments
 (0)