Skip to content

Commit

Permalink
fix: Projection tests
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Dec 22, 2023
1 parent 2a436e9 commit 47b8781
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 30 deletions.
7 changes: 3 additions & 4 deletions server/src/lang/ast/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,22 @@ pub enum SqlProjection {
Expr { expr: SqlExpr, alias: Option<Token> },
}


#[derive(Debug, Eq, PartialEq)]
pub struct SqlLimitClause {
pub count: SqlExpr,
pub offset: Option<SqlExpr>
pub offset: Option<SqlExpr>,
}

#[derive(Debug, Eq, PartialEq)]
pub struct SqlOrderByClause {
pub expr: SqlExpr,
pub ordering: SqlOrdering
pub ordering: SqlOrdering,
}

#[derive(Debug, Eq, PartialEq)]
pub struct SqlSelectCompound {
pub operator: SqlCompoundOperator,
pub core: SqlSelectCore
pub core: SqlSelectCore,
}

#[derive(Debug, Eq, PartialEq)]
Expand Down
23 changes: 18 additions & 5 deletions server/src/lang/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::ast::expr::{Expr, ExprId};
use super::ast::sql::{
SqlCollectionSubquery, SqlCompoundOperator, SqlDistinct, SqlExpr, SqlJoin, SqlJoinType,
SqlOrdering, SqlProjection, SqlSelect, SqlSelectCore, SqlOrderByClause, SqlSelectCompound, SqlLimitClause,
SqlLimitClause, SqlOrderByClause, SqlOrdering, SqlProjection, SqlSelect, SqlSelectCompound,
SqlSelectCore,
};
use super::ast::stmt::{Stmt, StmtId};
use super::ast::{Literal, ParserArena};
Expand Down Expand Up @@ -497,7 +498,10 @@ impl<'a> Parser<'a> {
}
};
let secondary_core = self.sql_select_core()?;
compounds.push(SqlSelectCompound { operator: compound_op, core: secondary_core })
compounds.push(SqlSelectCompound {
operator: compound_op,
core: secondary_core,
})
}
let order_by = if self.match_next(skw!(Order)) {
self.expected(skw!(By))?;
Expand All @@ -511,7 +515,10 @@ impl<'a> Parser<'a> {
self.match_next(skw!(Asc));
Some(SqlOrdering::Asc)
};
ordering.push(SqlOrderByClause { expr: SqlExpr::Default(order_expr), ordering: order.unwrap() });
ordering.push(SqlOrderByClause {
expr: SqlExpr::Default(order_expr),
ordering: order.unwrap(),
});
if !self.match_next(sym!(Comma)) {
break;
}
Expand All @@ -533,9 +540,15 @@ impl<'a> Parser<'a> {
};

if second_expr.is_some() && reverse {
Some(SqlLimitClause { count: second_expr.unwrap(), offset: Some(first_expr) })
Some(SqlLimitClause {
count: second_expr.unwrap(),
offset: Some(first_expr),
})
} else {
Some(SqlLimitClause { count: first_expr, offset: second_expr })
Some(SqlLimitClause {
count: first_expr,
offset: second_expr,
})
}
} else {
None
Expand Down
66 changes: 46 additions & 20 deletions server/src/lang/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde_json::{json, Value};
use super::{
ast::{
expr::{Expr, ExprId},
sql::{SqlExpr, SqlSelect},
sql::{SqlExpr, SqlProjection, SqlSelect, SqlSelectCore},
stmt::{Stmt, StmtId},
ImmutableVisitor,
},
Expand All @@ -28,25 +28,22 @@ impl ToString for Program {

impl ImmutableVisitor<Value, ()> for Program {
fn visit_select(&self, select: &SqlSelect) -> Result<Value, ()> {
let order_by: Option<Value> = select
.order_by
.as_ref()
.map(|x| {
x.iter()
.map(|order| {
let expr = if let SqlExpr::Default(eidx) = order.expr {
self.visit_expr(eidx).unwrap()
} else {
panic!("Not implemented");
};
let val = json!({
"expr": expr,
"ordering": format!("{:?}", order.ordering),
});
val
})
.collect()
});
let order_by: Option<Value> = select.order_by.as_ref().map(|x| {
x.iter()
.map(|order| {
let expr = if let SqlExpr::Default(eidx) = order.expr {
self.visit_expr(eidx).unwrap()
} else {
panic!("Not implemented");
};
let val = json!({
"expr": expr,
"ordering": format!("{:?}", order.ordering),
});
val
})
.collect()
});

let limit: Option<Value> = select.limit.as_ref().map(|x| {
let count_part = if let SqlExpr::Default(eidx) = x.count {
Expand All @@ -70,6 +67,34 @@ impl ImmutableVisitor<Value, ()> for Program {
"offset": offset_part
})
});

let serialize_sql_core =
|core: &SqlSelectCore| {
let core_projection: Value = core.projection.iter().map(|x| {
match x {
SqlProjection::All { collection } => {
json!({
"collection": collection.as_ref().map(|token| token.lexeme.to_owned())
})
},
SqlProjection::Expr { expr, alias } => {
json!({
"expr": if let SqlExpr::Default(eidx) = expr {
self.visit_expr(*eidx).unwrap()
} else {
panic!("Not implemented");
},
"alias": alias.as_ref().map(|token| token.lexeme.to_owned())
})
}
}
}).collect();

json!({
"projection": core_projection
})
};

/*
{
pub core: SqlSelectCore,
Expand All @@ -79,6 +104,7 @@ impl ImmutableVisitor<Value, ()> for Program {
}
*/
Ok(json!({
"core": serialize_sql_core(&select.core),
"order_by": order_by,
"limit": limit
}))
Expand Down
3 changes: 2 additions & 1 deletion server/src/lang/tests/sql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod select_limit;
pub mod select_order;
pub mod select_limit;
pub mod select_projection;
15 changes: 15 additions & 0 deletions server/src/lang/tests/sql/select_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": {
"count": {
"type": "Expr::Literal",
Expand All @@ -42,6 +47,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": {
"count": {
"type": "Expr::Literal",
Expand Down Expand Up @@ -70,6 +80,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": {
"count": {
"type": "Expr::Literal",
Expand Down
25 changes: 25 additions & 0 deletions server/src/lang/tests/sql/select_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": null
}
Expand All @@ -35,6 +40,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": [{
"expr": {
Expand All @@ -58,6 +68,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": [{
"expr": {
Expand Down Expand Up @@ -88,6 +103,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": [{
"expr": {
Expand Down Expand Up @@ -118,6 +138,11 @@ assert_parsing! {
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": [{
"expr": {
Expand Down
94 changes: 94 additions & 0 deletions server/src/lang/tests/sql/select_projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#[cfg(test)]
use crate::lang::tests::helpers::compare_parsed_to_expected;

#[cfg(test)]
use serde_json::json;

#[cfg(test)]
use crate::assert_parsing;

#[cfg(test)]
assert_parsing! {
plain: {
"SELECT * from users;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": null
}]
},
"limit": null,
"order_by": null
}
}
}
]
}
},

collection: {
"SELECT users.* from users;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"collection": "users"
}]
},
"limit": null,
"order_by": null
}
}
}
]
}
},
mixed_0: {
"SELECT id, users.name as username from users;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"core": {
"projection": [{
"expr": {
"type": "Expr::Variable",
"name": "id"
},
"alias": null
},
{
"expr": {
"type": "Expr::Get",
"object": {
"type": "Expr::Variable",
"name": "users"
},
"name": "name"
},
"alias": "username"
}]
},
"limit": null,
"order_by": null
}
}
}
]
}
}
}

0 comments on commit 47b8781

Please sign in to comment.