mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
support json_object('k':'v')
in postgres (#1546)
This commit is contained in:
parent
fd21fae297
commit
525d1780e8
3 changed files with 191 additions and 160 deletions
|
@ -211,6 +211,26 @@ impl Dialect for PostgreSqlDialect {
|
|||
fn supports_load_extension(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// See <https://www.postgresql.org/docs/current/functions-json.html>
|
||||
///
|
||||
/// Required to support the colon in:
|
||||
/// ```sql
|
||||
/// SELECT json_object('a': 'b')
|
||||
/// ```
|
||||
fn supports_named_fn_args_with_colon_operator(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// See <https://www.postgresql.org/docs/current/functions-json.html>
|
||||
///
|
||||
/// Required to support the label in:
|
||||
/// ```sql
|
||||
/// SELECT json_object('label': 'value')
|
||||
/// ```
|
||||
fn supports_named_fn_args_with_expr_name(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
|
||||
|
|
|
@ -1471,6 +1471,173 @@ fn parse_json_ops_without_colon() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_json_object() {
|
||||
let dialects = TestedDialects::new(vec![
|
||||
Box::new(MsSqlDialect {}),
|
||||
Box::new(PostgreSqlDialect {}),
|
||||
]);
|
||||
let select = dialects.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : 1)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, .. }),
|
||||
..
|
||||
}) => assert_eq!(
|
||||
&[
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("type".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(number("1"))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
],
|
||||
&args[..]
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = dialects
|
||||
.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : NULL ABSENT ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&[
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("type".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::Null)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
],
|
||||
&args[..]
|
||||
);
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = dialects.verified_only_select("SELECT JSON_OBJECT(NULL ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert!(args.is_empty());
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::NullOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = dialects.verified_only_select("SELECT JSON_OBJECT(ABSENT ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert!(args.is_empty());
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = dialects.verified_only_select(
|
||||
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_ARRAY(1, 2) ABSENT ON NULL)",
|
||||
);
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
&args[0]
|
||||
);
|
||||
assert!(matches!(
|
||||
args[1],
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString(_)),
|
||||
arg: FunctionArgExpr::Expr(Expr::Function(_)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
));
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = dialects.verified_only_select(
|
||||
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_OBJECT('type_id' : 1, 'name' : 'a') NULL ON NULL)",
|
||||
);
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
&args[0]
|
||||
);
|
||||
assert!(matches!(
|
||||
args[1],
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString(_)),
|
||||
arg: FunctionArgExpr::Expr(Expr::Function(_)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
));
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::NullOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_mod_no_spaces() {
|
||||
use self::Expr::*;
|
||||
|
@ -4416,7 +4583,10 @@ fn parse_explain_query_plan() {
|
|||
|
||||
#[test]
|
||||
fn parse_named_argument_function() {
|
||||
let dialects = all_dialects_where(|d| d.supports_named_fn_args_with_rarrow_operator());
|
||||
let dialects = all_dialects_where(|d| {
|
||||
d.supports_named_fn_args_with_rarrow_operator()
|
||||
&& !d.supports_named_fn_args_with_expr_name()
|
||||
});
|
||||
let sql = "SELECT FUN(a => '1', b => '2') FROM foo";
|
||||
let select = dialects.verified_only_select(sql);
|
||||
|
||||
|
|
|
@ -793,165 +793,6 @@ fn parse_for_json_expect_ast() {
|
|||
|
||||
#[test]
|
||||
fn parse_mssql_json_object() {
|
||||
let select = ms().verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : 1)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, .. }),
|
||||
..
|
||||
}) => assert_eq!(
|
||||
&[
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("type".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(number("1"))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
],
|
||||
&args[..]
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms()
|
||||
.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : NULL ABSENT ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&[
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("type".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::Null)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
],
|
||||
&args[..]
|
||||
);
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms().verified_only_select("SELECT JSON_OBJECT(NULL ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert!(args.is_empty());
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::NullOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms().verified_only_select("SELECT JSON_OBJECT(ABSENT ON NULL)");
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert!(args.is_empty());
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms().verified_only_select(
|
||||
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_ARRAY(1, 2) ABSENT ON NULL)",
|
||||
);
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
&args[0]
|
||||
);
|
||||
assert!(matches!(
|
||||
args[1],
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString(_)),
|
||||
arg: FunctionArgExpr::Expr(Expr::Function(_)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
));
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::AbsentOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms().verified_only_select(
|
||||
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_OBJECT('type_id' : 1, 'name' : 'a') NULL ON NULL)",
|
||||
);
|
||||
match expr_from_projection(&select.projection[0]) {
|
||||
Expr::Function(Function {
|
||||
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
&FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString("name".into())),
|
||||
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
|
||||
"value".into()
|
||||
))),
|
||||
operator: FunctionArgOperator::Colon
|
||||
},
|
||||
&args[0]
|
||||
);
|
||||
assert!(matches!(
|
||||
args[1],
|
||||
FunctionArg::ExprNamed {
|
||||
name: Expr::Value(Value::SingleQuotedString(_)),
|
||||
arg: FunctionArgExpr::Expr(Expr::Function(_)),
|
||||
operator: FunctionArgOperator::Colon
|
||||
}
|
||||
));
|
||||
assert_eq!(
|
||||
&[FunctionArgumentClause::JsonNullClause(
|
||||
JsonNullClause::NullOnNull
|
||||
)],
|
||||
&clauses[..]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let select = ms().verified_only_select(
|
||||
"SELECT JSON_OBJECT('user_name' : USER_NAME(), LOWER(@id_key) : @id_value, 'sid' : (SELECT @@SPID) ABSENT ON NULL)",
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue