Add support for PostgreSQL JSON function 'RETURNING' clauses (#2001)

This commit is contained in:
Adam Johnson 2025-08-26 20:22:26 +01:00 committed by GitHub
parent cffff30961
commit 9f515bf8c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 139 additions and 7 deletions

View file

@ -3351,7 +3351,31 @@ fn test_json() {
}
#[test]
fn test_fn_arg_with_value_operator() {
fn json_object_colon_syntax() {
match pg().verified_expr("JSON_OBJECT('name' : 'value')") {
Expr::Function(Function {
args: FunctionArguments::List(FunctionArgumentList { args, .. }),
..
}) => {
assert!(
matches!(
&args[..],
&[FunctionArg::ExprNamed {
operator: FunctionArgOperator::Colon,
..
}]
),
"Invalid function argument: {args:?}"
);
}
other => panic!(
"Expected: JSON_OBJECT('name' : 'value') to be parsed as a function, but got {other:?}"
),
}
}
#[test]
fn json_object_value_syntax() {
match pg().verified_expr("JSON_OBJECT('name' VALUE 'value')") {
Expr::Function(Function { args: FunctionArguments::List(FunctionArgumentList { args, .. }), .. }) => {
assert!(matches!(
@ -3363,6 +3387,63 @@ fn test_fn_arg_with_value_operator() {
}
}
#[test]
fn parse_json_object() {
let sql = "JSON_OBJECT('name' VALUE 'value' NULL ON NULL)";
let expr = pg().verified_expr(sql);
assert!(
matches!(
expr.clone(),
Expr::Function(Function {
name: ObjectName(parts),
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
..
}) if parts == vec![ObjectNamePart::Identifier(Ident::new("JSON_OBJECT"))]
&& matches!(
&args[..],
&[FunctionArg::ExprNamed { operator: FunctionArgOperator::Value, .. }]
)
&& clauses == vec![FunctionArgumentClause::JsonNullClause(JsonNullClause::NullOnNull)]
),
"Failed to parse JSON_OBJECT with expected structure, got: {expr:?}"
);
let sql = "JSON_OBJECT('name' VALUE 'value' RETURNING JSONB)";
let expr = pg().verified_expr(sql);
assert!(
matches!(
expr.clone(),
Expr::Function(Function {
name: ObjectName(parts),
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
..
}) if parts == vec![ObjectNamePart::Identifier(Ident::new("JSON_OBJECT"))]
&& matches!(
&args[..],
&[FunctionArg::ExprNamed { operator: FunctionArgOperator::Value, .. }]
)
&& clauses == vec![FunctionArgumentClause::JsonReturningClause(JsonReturningClause { data_type: DataType::JSONB })]
),
"Failed to parse JSON_OBJECT with expected structure, got: {expr:?}"
);
let sql = "JSON_OBJECT(RETURNING JSONB)";
let expr = pg().verified_expr(sql);
assert!(
matches!(
expr.clone(),
Expr::Function(Function {
name: ObjectName(parts),
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
..
}) if parts == vec![ObjectNamePart::Identifier(Ident::new("JSON_OBJECT"))]
&& args.is_empty()
&& clauses == vec![FunctionArgumentClause::JsonReturningClause(JsonReturningClause { data_type: DataType::JSONB })]
),
"Failed to parse JSON_OBJECT with expected structure, got: {expr:?}"
);
}
#[test]
fn parse_json_table_is_not_reserved() {
// JSON_TABLE is not a reserved keyword in PostgreSQL, even though it is in SQL:2023