(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 1091 | } |
| 1092 | |
| 1093 | fn parse_having_statement( |
| 1094 | context: &mut ParserContext, |
| 1095 | env: &mut Environment, |
| 1096 | tokens: &[Token], |
| 1097 | position: &mut usize, |
| 1098 | ) -> Result<Statement, Box<Diagnostic>> { |
| 1099 | context.inside_having = true; |
| 1100 | |
| 1101 | // Consume `HAVING` token |
| 1102 | *position += 1; |
| 1103 | |
| 1104 | if *position >= tokens.len() { |
| 1105 | return Err( |
| 1106 | Diagnostic::error("Expect expression after `HAVING` keyword") |
| 1107 | .add_help("Try to add boolean expression after `HAVING` keyword") |
| 1108 | .add_note("`HAVING` statement expects expression as condition") |
| 1109 | .with_location(calculate_safe_location(tokens, *position - 1)) |
| 1110 | .as_boxed(), |
| 1111 | ); |
| 1112 | } |
| 1113 | |
| 1114 | // Make sure HAVING condition expression has boolean type |
| 1115 | let condition_location = tokens[*position].location; |
| 1116 | let mut condition = parse_expression(context, env, tokens, position)?; |
| 1117 | |
| 1118 | // Make sure that the condition type is boolean, or can implicit cast to boolean. |
| 1119 | if !condition.expr_type().is_bool() { |
| 1120 | let expected_type: Box<dyn DataType> = Box::new(BoolType); |
| 1121 | if !expected_type.has_implicit_cast_from(&condition) { |
| 1122 | return Err(Diagnostic::error(&format!( |
| 1123 | "Expect `HAVING` condition to be type {} but got {}", |
| 1124 | "Boolean", |
| 1125 | condition.expr_type().literal() |
| 1126 | )) |
| 1127 | .add_note("`HAVING` statement condition must be Boolean") |
| 1128 | .with_location(condition_location) |
| 1129 | .as_boxed()); |
| 1130 | } |
| 1131 | |
| 1132 | // Implicit cast the condition to boolean |
| 1133 | condition = Box::new(CastExpr { |
| 1134 | value: condition, |
| 1135 | result_type: expected_type.clone(), |
| 1136 | }) |
| 1137 | } |
| 1138 | |
| 1139 | context.inside_having = false; |
| 1140 | Ok(Statement::Having(HavingStatement { condition })) |
| 1141 | } |
| 1142 | |
| 1143 | fn parse_qualify_statement( |
| 1144 | context: &mut ParserContext, |
no test coverage detected
searching dependent graphs…