Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Minimal planner infra #35

Merged
merged 14 commits into from
Aug 28, 2024
2 changes: 1 addition & 1 deletion lykiadb-connect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use tokio::net::TcpStream;
pub mod session;
mod tcp;

pub use lykiadb_server::comm::{Message, Request, Response};
pub use lykiadb_server::engine::error::report_error;
pub use lykiadb_server::net::{Message, Request, Response};

pub enum Protocol {
Tcp,
Expand Down
2 changes: 1 addition & 1 deletion lykiadb-connect/src/session.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use lykiadb_server::net::Message;
use lykiadb_server::comm::Message;

pub trait ClientSession {
async fn send_receive(&mut self, msg: Message) -> Result<Message, ()>;
Expand Down
4 changes: 2 additions & 2 deletions lykiadb-connect/src/tcp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::session::ClientSession;
use lykiadb_server::net::tcp::TcpConnection;
use lykiadb_server::net::{CommunicationError, Message, Request};
use lykiadb_server::comm::tcp::TcpConnection;
use lykiadb_server::comm::{CommunicationError, Message, Request};
use tokio::net::TcpStream;

pub(crate) struct TcpClientSession {
Expand Down
24 changes: 12 additions & 12 deletions lykiadb-lang/src/ast/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pub enum SqlDistinct {
pub enum SqlJoinType {
#[serde(rename = "SqlJoinType::Left")]
Left,
#[serde(rename = "SqlJoinType::LeftOuter")]
LeftOuter,
#[serde(rename = "SqlJoinType::Right")]
Right,
#[serde(rename = "SqlJoinType::Inner")]
Inner,
#[serde(rename = "SqlJoinType::Cross")]
Cross,
}

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -144,21 +144,21 @@ pub struct SqlSelectCompound {

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)]
#[serde(tag = "@type")]
pub enum SqlCollectionSubquery {
#[serde(rename = "SqlCollectionSubquery::Group")]
Group { values: Vec<SqlCollectionSubquery> },
#[serde(rename = "SqlCollectionSubquery::Collection")]
pub enum SqlFrom {
#[serde(rename = "SqlFrom::Group")]
Group { values: Vec<SqlFrom> },
#[serde(rename = "SqlFrom::Collection")]
Collection(SqlCollectionIdentifier),
#[serde(rename = "SqlCollectionSubquery::Select")]
#[serde(rename = "SqlFrom::Select")]
Select {
expr: Box<Expr>,
subquery: Box<SqlSelect>,
alias: Option<Identifier>,
},
#[serde(rename = "SqlCollectionSubquery::Join")]
#[serde(rename = "SqlFrom::Join")]
Join {
left: Box<SqlCollectionSubquery>,
left: Box<SqlFrom>,
join_type: SqlJoinType,
right: Box<SqlCollectionSubquery>,
right: Box<SqlFrom>,
constraint: Option<Box<SqlExpr>>,
},
}
Expand All @@ -168,7 +168,7 @@ pub enum SqlCollectionSubquery {
pub struct SqlSelectCore {
pub distinct: SqlDistinct,
pub projection: Vec<SqlProjection>,
pub from: Option<SqlCollectionSubquery>,
pub from: Option<SqlFrom>,
pub r#where: Option<Box<SqlExpr>>,
pub group_by: Option<Vec<SqlExpr>>,
pub having: Option<Box<SqlExpr>>,
Expand Down
34 changes: 5 additions & 29 deletions lykiadb-lang/src/ast/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use super::{
expr::Expr,
sql::{
SqlCollectionSubquery, SqlDelete, SqlExpr, SqlInsert, SqlSelect, SqlSelectCore, SqlUpdate,
},
stmt::Stmt,
};
use super::{expr::Expr, stmt::Stmt};

pub trait ExprEvaluator<O, E> {
fn eval(&mut self, e: &Expr) -> Result<O, E>;
}

pub trait Visitor<O, E> {
fn visit_expr(&self, e: &Expr) -> Result<O, E>;
Expand All @@ -14,25 +12,3 @@ pub trait VisitorMut<O, E> {
fn visit_expr(&mut self, e: &Expr) -> Result<O, E>;
fn visit_stmt(&mut self, s: &Stmt) -> Result<O, E>;
}

pub trait SqlVisitor<T, Q> {
fn visit_sql_select(&self, e: &SqlSelect) -> Result<T, Q>;
fn visit_sql_insert(&self, sql_insert: &SqlInsert) -> Result<T, Q>;
fn visit_sql_update(&self, sql_update: &SqlUpdate) -> Result<T, Q>;
fn visit_sql_delete(&self, sql_delete: &SqlDelete) -> Result<T, Q>;
//
fn visit_sql_select_core(&self, core: &SqlSelectCore) -> Result<T, Q>;
fn visit_sql_subquery(&self, subquery: &SqlCollectionSubquery) -> Result<T, Q>;
fn visit_sql_expr(&self, sql_expr: &SqlExpr) -> Result<T, Q>;
}

pub trait SqlVisitorMut<T, Q> {
fn visit_sql_select(&mut self, e: &SqlSelect) -> Result<T, Q>;
fn visit_sql_insert(&mut self, sql_insert: &SqlInsert) -> Result<T, Q>;
fn visit_sql_update(&mut self, sql_update: &SqlUpdate) -> Result<T, Q>;
fn visit_sql_delete(&mut self, sql_delete: &SqlDelete) -> Result<T, Q>;
//
fn visit_sql_select_core(&mut self, core: &SqlSelectCore) -> Result<T, Q>;
fn visit_sql_subquery(&mut self, subquery: &SqlCollectionSubquery) -> Result<T, Q>;
fn visit_sql_expr(&mut self, sql_expr: &SqlExpr) -> Result<T, Q>;
}
81 changes: 42 additions & 39 deletions lykiadb-lang/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@
}

use crate::ast::sql::{
SqlCollectionIdentifier, SqlCollectionSubquery, SqlCompoundOperator, SqlDelete, SqlDistinct,
SqlExpr, SqlInsert, SqlJoinType, SqlLimitClause, SqlOrderByClause, SqlOrdering, SqlProjection,
SqlCollectionIdentifier, SqlCompoundOperator, SqlDelete, SqlDistinct, SqlExpr, SqlFrom,
SqlInsert, SqlJoinType, SqlLimitClause, SqlOrderByClause, SqlOrdering, SqlProjection,
SqlSelect, SqlSelectCompound, SqlSelectCore, SqlUpdate, SqlValues,
};

Expand Down Expand Up @@ -1114,48 +1114,53 @@
Ok(projections)
}

fn sql_select_from(&mut self) -> ParseResult<Option<SqlCollectionSubquery>> {
fn sql_select_from(&mut self) -> ParseResult<Option<SqlFrom>> {
if self.match_next(skw!(From)) {
return Ok(Some(self.sql_select_subquery_join()?));
return Ok(Some(self.sql_select_from_join()?));
}
Ok(None)
}

fn sql_select_subquery_join(&mut self) -> ParseResult<SqlCollectionSubquery> {
let mut subquery_group: Vec<SqlCollectionSubquery> = vec![];
fn sql_select_from_join(&mut self) -> ParseResult<SqlFrom> {
let mut from_group: Vec<SqlFrom> = vec![];

loop {
let left = self.sql_select_subquery_collection()?;
subquery_group.push(left);
while self.match_next_one_of(&[skw!(Left), skw!(Right), skw!(Inner), skw!(Join)]) {
// If the next token is a join keyword, then it must be a join subquery
let left = self.sql_select_from_collection()?;
from_group.push(left);
while self.match_next_one_of(&[
skw!(Left),
skw!(Right),
skw!(Inner),
skw!(Cross),
skw!(Join),
]) {
// If the next token is a join keyword, then it must be a join from
let peek = self.peek_bw(1);
let join_type = if peek.tok_type == skw!(Inner) {
if peek.tok_type != SqlKeyword(Join) {
self.expected(skw!(Join))?;
SqlJoinType::Inner
} else if peek.tok_type == skw!(Left) {
optional_with_expected!(self, skw!(Outer), skw!(Join));
SqlJoinType::Left
} else if peek.tok_type == skw!(Right) {
optional_with_expected!(self, skw!(Outer), skw!(Join));
SqlJoinType::Right
} else if peek.tok_type == skw!(Join) {
SqlJoinType::Inner
} else {
return Err(ParseError::UnexpectedToken {
token: peek.clone(),
});
}
let join_type = match peek.tok_type {
SqlKeyword(Inner) => SqlJoinType::Inner,
SqlKeyword(Left) => SqlJoinType::Left,
SqlKeyword(Right) => SqlJoinType::Right,
SqlKeyword(Cross) => SqlJoinType::Cross,

Check warning on line 1146 in lykiadb-lang/src/parser/mod.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-lang/src/parser/mod.rs#L1145-L1146

Added lines #L1145 - L1146 were not covered by tests
SqlKeyword(Join) => SqlJoinType::Inner,
_ => {
return Err(ParseError::UnexpectedToken {
token: peek.clone(),
});

Check warning on line 1151 in lykiadb-lang/src/parser/mod.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-lang/src/parser/mod.rs#L1149-L1151

Added lines #L1149 - L1151 were not covered by tests
}
};
let right = self.sql_select_subquery_collection()?;
let right = self.sql_select_from_collection()?;
let join_constraint: Option<Box<SqlExpr>> = if self.match_next(skw!(On)) {
Some(self.sql_expression()?)
} else {
None
};

let left_popped = subquery_group.pop().unwrap();
let left_popped = from_group.pop().unwrap();

subquery_group.push(SqlCollectionSubquery::Join {
from_group.push(SqlFrom::Join {
left: Box::new(left_popped),
right: Box::new(right),
join_type,
Expand All @@ -1167,9 +1172,7 @@
}
}

Ok(SqlCollectionSubquery::Group {
values: subquery_group,
})
Ok(SqlFrom::Group { values: from_group })
}

fn sql_select_where(&mut self) -> ParseResult<Option<Box<SqlExpr>>> {
Expand Down Expand Up @@ -1197,24 +1200,24 @@
}
}

fn sql_select_subquery_collection(&mut self) -> ParseResult<SqlCollectionSubquery> {
fn sql_select_from_collection(&mut self) -> ParseResult<SqlFrom> {
if self.match_next(sym!(LeftParen)) {
if self.cmp_tok(&skw!(Select)) {
let expr = self.sql_select()?;
self.expected(sym!(RightParen))?; // closing paren
let subquery = Box::new(self.sql_select_inner()?);
self.expected(sym!(RightParen))?;
let alias: Option<Token> =
optional_with_expected!(self, skw!(As), Identifier { dollar: false });
return Ok(SqlCollectionSubquery::Select {
expr,
return Ok(SqlFrom::Select {
subquery,
alias: alias.map(|t| t.extract_identifier().unwrap()),
});
}
// If the next token is a left paren, then it must be either a select statement or a recursive subquery
let parsed = self.sql_select_subquery_join()?; // TODO(vck): Check if using _collection variant makes sense.
self.expected(sym!(RightParen))?; // closing paren
// If the next token is a left paren, then it must be either a select statement or a recursive "from" clause
let parsed = self.sql_select_from_join()?;
self.expected(sym!(RightParen))?;
Ok(parsed)
} else if let Some(collection) = self.sql_collection_identifier()? {
return Ok(SqlCollectionSubquery::Collection(collection));
return Ok(SqlFrom::Collection(collection));
} else {
Err(ParseError::UnexpectedToken {
token: self.peek_bw(0).clone(),
Expand Down
Loading
Loading