diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 366bf4d25..970486719 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -5528,6 +5528,8 @@ pub enum FunctionArgOperator { Assignment, /// function(arg1 : value1) Colon, + /// function(arg1 VALUE value1) + Value, } impl fmt::Display for FunctionArgOperator { @@ -5537,6 +5539,7 @@ impl fmt::Display for FunctionArgOperator { FunctionArgOperator::RightArrow => f.write_str("=>"), FunctionArgOperator::Assignment => f.write_str(":="), FunctionArgOperator::Colon => f.write_str(":"), + FunctionArgOperator::Value => f.write_str("VALUE"), } } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index b7f5cb866..90c9a4ff5 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -11478,6 +11478,9 @@ impl<'a> Parser<'a> { } fn parse_function_named_arg_operator(&mut self) -> Result { + if self.parse_keyword(Keyword::VALUE) { + return Ok(FunctionArgOperator::Value); + } let tok = self.next_token(); match tok.token { Token::RArrow if self.dialect.supports_named_fn_args_with_rarrow_operator() => { diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 54f77b7be..f94e2f540 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2824,6 +2824,19 @@ fn test_json() { ); } +#[test] +fn test_fn_arg_with_value_operator() { + match pg().verified_expr("JSON_OBJECT('name' VALUE 'value')") { + Expr::Function(Function { args: FunctionArguments::List(FunctionArgumentList { args, .. }), .. }) => { + assert!(matches!( + &args[..], + &[FunctionArg::ExprNamed { operator: FunctionArgOperator::Value, .. }] + ), "Invalid function argument: {:?}", args); + } + other => panic!("Expected: JSON_OBJECT('name' VALUE 'value') to be parsed as a function, but got {other:?}"), + } +} + #[test] fn parse_json_table_is_not_reserved() { // JSON_TABLE is not a reserved keyword in PostgreSQL, even though it is in SQL:2023