Skip to content

Commit

Permalink
fix: Minimal order by tests
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Dec 21, 2023
1 parent 481b409 commit b99ac59
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 22 deletions.
25 changes: 22 additions & 3 deletions server/src/lang/ast/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ pub enum SqlProjection {
Expr { expr: SqlExpr, alias: Option<Token> },
}


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

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

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

#[derive(Debug, Eq, PartialEq)]
pub struct SqlJoin {
pub join_type: SqlJoinType,
Expand Down Expand Up @@ -80,7 +99,7 @@ pub struct SqlSelectCore {
#[derive(Debug, Eq, PartialEq)]
pub struct SqlSelect {
pub core: SqlSelectCore,
pub compound: Vec<(SqlCompoundOperator, SqlSelectCore)>,
pub order_by: Option<Vec<(SqlExpr, SqlOrdering)>>,
pub limit: Option<(SqlExpr, Option<SqlExpr>)>,
pub compound: Vec<SqlSelectCompound>,
pub order_by: Option<Vec<SqlOrderByClause>>,
pub limit: Option<SqlLimitClause>,
}
15 changes: 8 additions & 7 deletions server/src/lang/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::ast::expr::{Expr, ExprId};
use super::ast::sql::{
SqlCollectionSubquery, SqlCompoundOperator, SqlDistinct, SqlExpr, SqlJoin, SqlJoinType,
SqlOrdering, SqlProjection, SqlSelect, SqlSelectCore,
SqlOrdering, SqlProjection, SqlSelect, SqlSelectCore, SqlOrderByClause, SqlSelectCompound, SqlLimitClause,
};
use super::ast::stmt::{Stmt, StmtId};
use super::ast::{Literal, ParserArena};
Expand Down Expand Up @@ -481,7 +481,7 @@ impl<'a> Parser<'a> {
return self.call();
}
let core = self.sql_select_core()?;
let mut compounds: Vec<(SqlCompoundOperator, SqlSelectCore)> = vec![];
let mut compounds: Vec<SqlSelectCompound> = vec![];
while self.match_next_one_of(&[skw!(Union), skw!(Intersect), skw!(Except)]) {
let op = self.peek_bw(1);
let compound_op = if op.tok_type == skw!(Union) && self.match_next(skw!(All)) {
Expand All @@ -497,20 +497,21 @@ impl<'a> Parser<'a> {
}
};
let secondary_core = self.sql_select_core()?;
compounds.push((compound_op, secondary_core))
compounds.push(SqlSelectCompound { operator: compound_op, core: secondary_core })
}
let order_by = if self.match_next(skw!(Order)) {
self.expected(skw!(By))?;
let mut ordering: Vec<(SqlExpr, SqlOrdering)> = vec![];
let mut ordering: Vec<SqlOrderByClause> = vec![];

loop {
let order_expr = self.expression()?;
let order = if self.match_next(skw!(Desc)) {
Some(SqlOrdering::Desc)
} else {
self.match_next(skw!(Asc));
Some(SqlOrdering::Asc)
};
ordering.push((SqlExpr::Default(order_expr), order.unwrap()));
ordering.push(SqlOrderByClause { expr: SqlExpr::Default(order_expr), ordering: order.unwrap() });
if !self.match_next(sym!(Comma)) {
break;
}
Expand All @@ -532,9 +533,9 @@ impl<'a> Parser<'a> {
};

if second_expr.is_some() && reverse {
Some((second_expr.unwrap(), Some(first_expr)))
Some(SqlLimitClause { limit: second_expr.unwrap(), offset: Some(first_expr) })
} else {
Some((first_expr, second_expr))
Some(SqlLimitClause { limit: first_expr, offset: second_expr })
}
} else {
None
Expand Down
21 changes: 10 additions & 11 deletions server/src/lang/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{
},
parser::Program,
};
use std::{borrow::BorrowMut, rc::Rc};
use std::rc::Rc;

impl Program {
pub fn to_json(&self) -> Value {
Expand All @@ -28,36 +28,35 @@ impl ToString for Program {

impl ImmutableVisitor<Value, ()> for Program {
fn visit_select(&self, select: &SqlSelect) -> Result<Value, ()> {
let order_by: Value = select
let order_by: Option<Value> = select
.order_by
.as_ref()
.map(|x| {
x.iter()
.map(|order| {
let expr = if let SqlExpr::Default(eidx) = order.0 {
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.1),
"ordering": format!("{:?}", order.ordering),
});
val
})
.collect()
})
.unwrap();
});

let limit: Option<Value> = select.limit.as_ref().map(|x| {
let limit_part = if let SqlExpr::Default(eidx) = x.0 {
let limit_part = if let SqlExpr::Default(eidx) = x.limit {
self.visit_expr(eidx).unwrap()
} else {
panic!("Not implemented");
};

let offset_part = if x.1.is_some() {
if let SqlExpr::Default(eidx) = x.1.as_ref().unwrap() {
let offset_part = if x.offset.is_some() {
if let SqlExpr::Default(eidx) = x.offset.as_ref().unwrap() {
self.visit_expr(*eidx).unwrap()
} else {
panic!("Not implemented");
Expand All @@ -67,8 +66,8 @@ impl ImmutableVisitor<Value, ()> for Program {
};

json!({
"limit_part": limit_part,
"offset_part": offset_part
"limit": limit_part,
"offset": offset_part
})
});
/*
Expand Down
102 changes: 101 additions & 1 deletion server/src/lang/tests/sql/select_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,107 @@ use crate::assert_parsing;

#[cfg(test)]
assert_parsing! {
multiple_order: {
no_order: {
"SELECT * from users;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"limit": null,
"order_by": null
}
}
}
]
}
},
single_order: {
"SELECT * from users order by id desc;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"limit": null,
"order_by": [{
"expr": {
"name": "id",
"type": "Expr::Variable"
},
"ordering": "Desc"
}]
}
}
}
]
}
},
multiple_order_0: {
"SELECT * from users order by id, name;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"limit": null,
"order_by": [{
"expr": {
"name": "id",
"type": "Expr::Variable"
},
"ordering": "Asc"
},
{
"expr": {
"name": "name",
"type": "Expr::Variable"
},
"ordering": "Asc"
}]
}
}
}
]
}
},
multiple_order_1: {
"SELECT * from users order by id asc, name;" => {
"type": "Stmt::Program",
"body": [
{
"type": "Stmt::Expression",
"expr": {
"type": "Expr::Select",
"value": {
"limit": null,
"order_by": [{
"expr": {
"name": "id",
"type": "Expr::Variable"
},
"ordering": "Asc"
},
{
"expr": {
"name": "name",
"type": "Expr::Variable"
},
"ordering": "Asc"
}]
}
}
}
]
}
},
multiple_order_2: {
"SELECT * from users order by id, name desc;" => {
"type": "Stmt::Program",
"body": [
Expand Down

0 comments on commit b99ac59

Please sign in to comment.