diff --git a/src/binder/mod.rs b/src/binder/mod.rs index 2c6d36b..4343cec 100644 --- a/src/binder/mod.rs +++ b/src/binder/mod.rs @@ -14,15 +14,18 @@ use crate::catalog::{RootCatalogRef, TableCatalog}; pub struct Binder { catalog: RootCatalogRef, context: BinderContext, + subquery_base_index: usize, } -#[derive(Default)] +// FIXME: remove dead_code after we used parent context +#[derive(Default, Clone, Debug)] +#[allow(dead_code)] struct BinderContext { /// table_name == table_id /// table_id -> table_catalog tables: HashMap, aliases: HashMap, - subquery_base_index: usize, + parent: Option>, } impl Binder { @@ -30,6 +33,7 @@ impl Binder { Self { catalog, context: BinderContext::default(), + subquery_base_index: 0, } } @@ -44,6 +48,15 @@ impl Binder { } } +impl BinderContext { + pub fn with_parent(parent: Box) -> Self { + Self { + parent: Some(parent), + ..Default::default() + } + } +} + #[derive(thiserror::Error, Debug)] pub enum BindError { #[error("unsupported statement {0}")] diff --git a/src/binder/table/mod.rs b/src/binder/table/mod.rs index f2b86a3..d57c010 100644 --- a/src/binder/table/mod.rs +++ b/src/binder/table/mod.rs @@ -7,7 +7,7 @@ pub use join::*; use sqlparser::ast::{TableFactor, TableWithJoins}; pub use subquery::*; -use super::{BindError, Binder}; +use super::{BindError, Binder, BinderContext}; use crate::catalog::{ColumnCatalog, ColumnId, TableCatalog, TableId}; pub static DEFAULT_DATABASE_NAME: &str = "postgres"; @@ -186,6 +186,7 @@ impl Binder { } => { // handle subquery as source let query = self.bind_select(subquery)?; + self.context = BinderContext::with_parent(Box::new(self.context.clone())); let alias = alias .clone() .map(|a| a.to_string().to_lowercase()) diff --git a/src/binder/table/subquery.rs b/src/binder/table/subquery.rs index 935b529..0683add 100644 --- a/src/binder/table/subquery.rs +++ b/src/binder/table/subquery.rs @@ -53,8 +53,8 @@ impl BoundSubquery { impl Binder { pub fn gen_subquery_table_id(&mut self) -> String { - let id = format!("subquery_{}", self.context.subquery_base_index); - self.context.subquery_base_index += 1; + let id = format!("subquery_{}", self.subquery_base_index); + self.subquery_base_index += 1; id } } diff --git a/tests/slt/subquery.slt b/tests/slt/subquery.slt index fce8229..8b6d938 100644 --- a/tests/slt/subquery.slt +++ b/tests/slt/subquery.slt @@ -2,8 +2,11 @@ statement error select * from (select * from t1 where a > 1) where b > 7; -# TODO: handle multi-layer binder context to resolve current context all columns -# select * from (select * from t1 where a > 1) t where t.b > 7; +query III +select * from (select * from (select * from t1 where c < 2) t_1 where t_1.a > 1) t_2 where t_2.b > 7; +---- +2 8 1 + query III select t.* from (select * from t1 where a > 1) t where t.b > 7;