Skip to content

Commit

Permalink
feat: Expression source type in sql from
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Nov 27, 2024
1 parent d1bece7 commit ff4cf0b
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 13 deletions.
18 changes: 16 additions & 2 deletions lykiadb-lang/src/ast/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,27 @@ pub struct SqlSelectCompound {
pub core: SqlSelectCore,
}

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone, Hash)]
#[serde(tag = "@type")]
pub struct SqlExpressionSource {
pub expr: Box<Expr>,
pub alias: Identifier,
}

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone, Hash)]
#[serde(tag = "@type")]
pub enum SqlSource {
Collection(SqlCollectionIdentifier),
Expr(SqlExpressionSource),
}

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone, Hash)]
#[serde(tag = "@type")]
pub enum SqlFrom {
#[serde(rename = "SqlFrom::Source")]
Source(SqlSource),
#[serde(rename = "SqlFrom::Group")]
Group { values: Vec<SqlFrom> },
#[serde(rename = "SqlFrom::Collection")]
Collection(SqlCollectionIdentifier),
#[serde(rename = "SqlFrom::Select")]
Select {
subquery: Box<SqlSelect>,
Expand Down
22 changes: 12 additions & 10 deletions lykiadb-lang/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,9 +868,7 @@ impl<'a> Parser<'a> {
}

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

macro_rules! optional_with_expected {
Expand Down Expand Up @@ -1201,7 +1199,7 @@ impl<'a> Parser<'a> {
let mut from_group: Vec<SqlFrom> = vec![];

loop {
let left = self.sql_select_from_collection()?;
let left = self.sql_select_from_source()?;
from_group.push(left);
while self.match_next_one_of(&[
skw!(Left),
Expand All @@ -1227,7 +1225,7 @@ impl<'a> Parser<'a> {
});
}
};
let right = self.sql_select_from_collection()?;
let right = self.sql_select_from_source()?;
let join_constraint: Option<Box<Expr>> = if self.match_next(skw!(On)) {
Some(self.expression()?)
} else {
Expand Down Expand Up @@ -1276,7 +1274,7 @@ impl<'a> Parser<'a> {
}
}

fn sql_select_from_collection(&mut self) -> ParseResult<SqlFrom> {
fn sql_select_from_source(&mut self) -> ParseResult<SqlFrom> {
if self.match_next(sym!(LeftParen)) {
if self.cmp_tok(&skw!(Select)) {
let subquery = Box::new(self.sql_select_inner()?);
Expand All @@ -1293,11 +1291,15 @@ impl<'a> Parser<'a> {
self.expected(sym!(RightParen))?;
Ok(parsed)
} else if let Some(collection) = self.sql_collection_identifier()? {
return Ok(SqlFrom::Collection(collection));
return Ok(SqlFrom::Source(SqlSource::Collection(collection)));
} else {
Err(ParseError::UnexpectedToken {
token: self.peek_bw(0).clone(),
})
let expr = self.expression()?;
self.expected(skw!(As))?;
let identifier = self.expected(Identifier { dollar: false })?.clone();
return Ok(SqlFrom::Source(SqlSource::Expr(SqlExpressionSource{
expr,
alias: identifier.extract_identifier().unwrap()
})));
}
}
}
141 changes: 140 additions & 1 deletion lykiadb-lang/tests/lang/sql/select_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,144 @@ assert_parsing! {
}
]
}
}
},
expr_source: {
"SELECT * from $users as u;" => {
"@type": "Stmt::Program",
"body": [
{
"@type": "Stmt::Expression",
"expr": {
"@type": "Expr::Select",
"query": {
"@type": "SqlSelect",
"core": {
"@type": "SqlSelectCore",
"compound": null,
"distinct": {
"@type": "SqlDistinct::ImplicitAll"
},
"from": {
"@type": "SqlFrom::Group",
"values": [
{
"@type": "SqlExpressionSource",
"alias": {
"@type": "Identifier",
"dollar": false,
"name": "u"
},
"expr":{
"@type": "Expr::Variable",
"name": {
"@type": "Identifier",
"dollar": true,
"name": "$users"
}
}
}
]
},
"group_by": null,
"having": null,
"projection": [
{
"@type": "SqlProjection::All",
"collection": null
}
],
"where": null
},
"limit": null,
"order_by": null
}
}
}
]
}
},
expr_source_complex: {
"SELECT * from items i, ['user1', 'user2'] as u;" => {
"@type": "Stmt::Program",
"body": [
{
"@type": "Stmt::Expression",
"expr": {
"@type": "Expr::Select",
"query": {
"@type": "SqlSelect",
"core": {
"@type": "SqlSelectCore",
"compound": null,
"distinct": {
"@type": "SqlDistinct::ImplicitAll"
},
"from": {
"@type": "SqlFrom::Group",
"values": [
{
"@type": "SqlCollectionIdentifier",
"alias": {
"@type": "Identifier",
"dollar": false,
"name": "i"
},
"name": {
"@type": "Identifier",
"dollar": false,
"name": "items"
},
"namespace": null
},
{
"@type": "SqlExpressionSource",
"alias": {
"@type": "Identifier",
"dollar": false,
"name": "u"
},
"expr": {
"@type": "Expr::Literal",
"raw": "",
"value": {
"Array": [
{
"@type": "Expr::Literal",
"raw": "user1",
"value": {
"Str": "user1"
}
},
{
"@type": "Expr::Literal",
"raw": "user2",
"value": {
"Str": "user2"
}
}
]
}
}
}
]
},
"group_by": null,
"having": null,
"projection": [
{
"@type": "SqlProjection::All",
"collection": null
}
],
"where": null
},
"limit": null,
"order_by": null
}
}
}
]
}
}

}

0 comments on commit ff4cf0b

Please sign in to comment.