From 76ecc179578a04763e2472d173bf0ce88edb3ea8 Mon Sep 17 00:00:00 2001 From: Vedat Can Keklik Date: Sat, 9 Dec 2023 17:11:52 +0300 Subject: [PATCH] feat: GROUP BY + HAVING clauses --- server/src/lang/ast/sql.rs | 2 +- server/src/lang/parser.rs | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/server/src/lang/ast/sql.rs b/server/src/lang/ast/sql.rs index cbed1c8f..d4136a0f 100644 --- a/server/src/lang/ast/sql.rs +++ b/server/src/lang/ast/sql.rs @@ -82,7 +82,7 @@ pub struct SelectCore { pub projection: Vec, pub from: Option, pub r#where: Option, - pub group_by: Option, + pub group_by: Option>, pub having: Option, } diff --git a/server/src/lang/parser.rs b/server/src/lang/parser.rs index 4c5c1ebb..457409e3 100644 --- a/server/src/lang/parser.rs +++ b/server/src/lang/parser.rs @@ -520,16 +520,44 @@ impl<'a> Parser<'a> { SqlDistinct::All }*/ + let projection = self.sql_projection(); + let from = self.sql_from()?; + let r#where = self.sql_where()?; + let group_by = self.sql_group_by()?; + let having = if group_by.is_some() && self.match_next(skw!(Having)) { + Some(SqlExpr::Default(self.expression()?)) + } else { + None + }; + Ok(SelectCore { distinct, - projection: self.sql_projection(), - from: self.sql_from()?, - r#where: self.sql_where()?, - group_by: None, // TODO(vck) - having: None, // TODO(vck) + projection, + from, + r#where, + group_by, + having, }) } + fn sql_group_by(&mut self) -> ParseResult>> { + if self.match_next(skw!(Group)) { + self.expected(skw!(By))?; + let mut groups: Vec = vec![]; + + loop { + let group_expr = self.expression()?; + groups.push(SqlExpr::Default(group_expr)); + if !self.match_next(sym!(Comma)) { + break; + } + } + Ok(Some(groups)) + } else { + Ok(None) + } + } + fn sql_projection(&mut self) -> Vec { let mut projections: Vec = vec![]; loop {