(expr: &Expr, depth: &mut usize)
| 55 | } |
| 56 | |
| 57 | fn convert_expr_inner(expr: &Expr, depth: &mut usize) -> Result<SqlExpr> { |
| 58 | match expr { |
| 59 | Expr::Identifier(ident) => { |
| 60 | let name = normalize_ident(ident); |
| 61 | // SQL-standard zero-arg keyword functions parse as bare |
| 62 | // identifiers (no parentheses): `SELECT current_timestamp`, |
| 63 | // `SELECT current_user`, etc. Promote them to function calls |
| 64 | // so const folding evaluates them like the parenthesised form. |
| 65 | if is_zero_arg_keyword_function(&name) { |
| 66 | return Ok(SqlExpr::Function { |
| 67 | name, |
| 68 | args: vec![], |
| 69 | distinct: false, |
| 70 | }); |
| 71 | } |
| 72 | Ok(SqlExpr::Column { table: None, name }) |
| 73 | } |
| 74 | Expr::CompoundIdentifier(parts) if parts.len() >= 3 => { |
| 75 | let qualified: String = parts |
| 76 | .iter() |
| 77 | .map(normalize_ident) |
| 78 | .collect::<Vec<_>>() |
| 79 | .join("."); |
| 80 | Err(SqlError::Unsupported { |
| 81 | detail: format!( |
| 82 | "schema-qualified column reference '{qualified}': {SCHEMA_QUALIFIED_MSG}" |
| 83 | ), |
| 84 | }) |
| 85 | } |
| 86 | Expr::CompoundIdentifier(parts) if parts.len() == 2 => Ok(SqlExpr::Column { |
| 87 | table: Some(normalize_ident(&parts[0])), |
| 88 | name: normalize_ident(&parts[1]), |
| 89 | }), |
| 90 | Expr::Value(val) => Ok(SqlExpr::Literal(convert_value(&val.value)?)), |
| 91 | Expr::BinaryOp { left, op, right } => { |
| 92 | // JSON and FTS operators are lowered to function calls before the |
| 93 | // generic binary-op path so they are never passed to |
| 94 | // convert_binary_op. |
| 95 | use ast::BinaryOperator; |
| 96 | let json_fn: Option<&str> = match op { |
| 97 | BinaryOperator::Arrow => Some("pg_json_get"), |
| 98 | BinaryOperator::LongArrow => Some("pg_json_get_text"), |
| 99 | BinaryOperator::HashArrow => Some("pg_json_path_get"), |
| 100 | BinaryOperator::HashLongArrow => Some("pg_json_path_get_text"), |
| 101 | BinaryOperator::AtArrow => Some("pg_json_contains"), |
| 102 | BinaryOperator::ArrowAt => Some("pg_json_contained_by"), |
| 103 | BinaryOperator::Question => Some("pg_json_has_key"), |
| 104 | BinaryOperator::QuestionAnd => Some("pg_json_has_all_keys"), |
| 105 | BinaryOperator::QuestionPipe => Some("pg_json_has_any_key"), |
| 106 | _ => None, |
| 107 | }; |
| 108 | if let Some(name) = json_fn { |
| 109 | return Ok(SqlExpr::Function { |
| 110 | name: name.into(), |
| 111 | args: vec![ |
| 112 | convert_expr_depth(left, depth)?, |
| 113 | convert_expr_depth(right, depth)?, |
| 114 | ], |
no test coverage detected