Skip to content

Commit 32bc559

Browse files
committed
sql-parser: select (having clause)
1 parent 8441158 commit 32bc559

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

src/parser/expression/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,8 @@ impl<'a> ExpressionParser for Parser<'a> {
396396
pub(crate) mod test_utils {
397397
use crate::ast::{Expression, SelectItem};
398398
use crate::{
399-
BinaryMatchingExpression, BinaryOp, DataType, ExistsStatement, Function, FunctionArg,
400-
Identifier, LiteralValue, Parser, RaiseFunction, SelectStatementType, Statement, UnaryOp,
401-
WindowDefinition,
399+
BinaryOp, DataType, ExistsStatement, Function, FunctionArg, Identifier, LiteralValue,
400+
Parser, RaiseFunction, SelectStatementType, Statement, UnaryOp, WindowDefinition,
402401
};
403402

404403
pub fn run_sunny_day_test_with_multiple_expressions(

src/parser/select/mod.rs

+48-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl<'a> SelectStatementParser for Parser<'a> {
6666
from: self.parse_select_from_clause()?,
6767
where_clause: self.parse_where_clause()?,
6868
group_by: self.parse_group_by_clause()?,
69+
having: self.parse_having_clause()?,
6970
..Default::default()
7071
};
7172

@@ -358,7 +359,11 @@ impl<'a> SelectStatementParser for Parser<'a> {
358359
}
359360

360361
fn parse_having_clause(&mut self) -> Result<Option<Box<Expression>>, ParsingError> {
361-
todo!()
362+
if self.consume_as_keyword(Keyword::Having).is_ok() {
363+
Ok(Some(Box::new(self.parse_expression()?)))
364+
} else {
365+
Ok(None)
366+
}
362367
}
363368
}
364369

@@ -423,6 +428,24 @@ mod test_utils {
423428
..Default::default()
424429
})
425430
}
431+
432+
pub fn select_statement_with_having_clause(having: Expression) -> SelectStatementType {
433+
SelectStatementType::Select(SelectStatement {
434+
distinct_type: DistinctType::None,
435+
columns: vec![SelectItem::Expression(Expression::Identifier(
436+
Identifier::Wildcard,
437+
))],
438+
from: Some(SelectFrom::Table(SelectFromTable {
439+
table_id: Identifier::Single("table_1".to_string()),
440+
alias: None,
441+
indexed_type: None,
442+
})),
443+
where_clause: None,
444+
group_by: None,
445+
having: Some(Box::new(having)),
446+
..Default::default()
447+
})
448+
}
426449
}
427450

428451
#[cfg(test)]
@@ -1318,3 +1341,27 @@ mod test_select_group_by_clause {
13181341
);
13191342
}
13201343
}
1344+
1345+
#[cfg(test)]
1346+
mod test_select_having_clause {
1347+
use super::test_utils::select_statement_with_having_clause;
1348+
use crate::expression::test_utils::{
1349+
binary_op_expression, identifier_expression, numeric_literal_expression,
1350+
};
1351+
use crate::parser::test_utils::*;
1352+
use crate::{BinaryOp, Statement};
1353+
1354+
#[test]
1355+
fn test_select_having_clause() {
1356+
let expected_statement = select_statement_with_having_clause(binary_op_expression(
1357+
BinaryOp::GreaterThan,
1358+
identifier_expression(&["col1"]),
1359+
numeric_literal_expression("1"),
1360+
));
1361+
1362+
run_sunny_day_test(
1363+
"SELECT * FROM table_1 HAVING col1 > 1",
1364+
Statement::Select(expected_statement),
1365+
);
1366+
}
1367+
}

0 commit comments

Comments
 (0)