Translates into IN (v1, v2, ...) if possible
(
expr: &rq::Expr,
args: &[rq::Expr],
ctx: &mut Context,
)
| 169 | |
| 170 | /// Translates into IN (v1, v2, ...) if possible |
| 171 | fn process_array_in( |
| 172 | expr: &rq::Expr, |
| 173 | args: &[rq::Expr], |
| 174 | ctx: &mut Context, |
| 175 | ) -> Result<sql_ast::Expr> { |
| 176 | match args { |
| 177 | [col_expr @ rq::Expr { |
| 178 | kind: |
| 179 | rq::ExprKind::ColumnRef(_) |
| 180 | | rq::ExprKind::Literal(_) |
| 181 | | rq::ExprKind::SString(_) |
| 182 | | rq::ExprKind::Param(_) |
| 183 | | rq::ExprKind::Operator { name: _, args: _ }, |
| 184 | .. |
| 185 | }, rq::Expr { |
| 186 | kind: rq::ExprKind::Array(in_values), |
| 187 | .. |
| 188 | }] => { |
| 189 | if in_values.is_empty() { |
| 190 | // We avoid producing `in ()` expressions since they are not syntactically valid |
| 191 | // in some engines like PostgreSQL or MySQL. |
| 192 | // We can instead optimize this to a condition that is always false |
| 193 | Ok(sql_ast::Expr::Value(Value::Boolean(false).into())) |
| 194 | } else { |
| 195 | Ok(sql_ast::Expr::InList { |
| 196 | expr: Box::new(translate_expr(col_expr.clone(), ctx)?.into_ast()), |
| 197 | list: in_values |
| 198 | .iter() |
| 199 | .map(|a| Ok(translate_expr(a.clone(), ctx)?.into_ast())) |
| 200 | .collect::<Result<Vec<sql_ast::Expr>>>()?, |
| 201 | negated: false, |
| 202 | }) |
| 203 | } |
| 204 | } |
| 205 | _ => Err( |
| 206 | Error::new_simple("args to `std.array_in` must be an expression and an array") |
| 207 | .with_span(expr.span), |
| 208 | ), |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | /// Translates PRQL date truncation to dialect-specific SQL. |
| 213 | /// BigQuery uses unquoted uppercase date_part after the column: DATE_TRUNC(col, DAY) |
no test coverage detected