Skip to content

Commit 2eb0bd6

Browse files
committed
json_object('k':'v') in postgres
This just updates the postgres dialect definition to add support for the json_object syntax added in apache#1507 The syntax was initially added for mssql but also works in postgres See https://www.postgresql.org/docs/current/functions-json.html See apache#1545
1 parent 0fb2ef3 commit 2eb0bd6

File tree

3 files changed

+191
-160
lines changed

3 files changed

+191
-160
lines changed

src/dialect/postgresql.rs

+20
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,26 @@ impl Dialect for PostgreSqlDialect {
211211
fn supports_load_extension(&self) -> bool {
212212
true
213213
}
214+
215+
/// See <https://www.postgresql.org/docs/current/functions-json.html>
216+
///
217+
/// Required to support the colon in:
218+
/// ```sql
219+
/// SELECT json_object('a': 'b')
220+
/// ```
221+
fn supports_named_fn_args_with_colon_operator(&self) -> bool {
222+
true
223+
}
224+
225+
/// See <https://www.postgresql.org/docs/current/functions-json.html>
226+
///
227+
/// Required to support the label in:
228+
/// ```sql
229+
/// SELECT json_object('label': 'value')
230+
/// ```
231+
fn supports_named_fn_args_with_expr_name(&self) -> bool {
232+
true
233+
}
214234
}
215235

216236
pub fn parse_create(parser: &mut Parser) -> Option<Result<Statement, ParserError>> {

tests/sqlparser_common.rs

+171-1
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,173 @@ fn parse_json_ops_without_colon() {
14711471
}
14721472
}
14731473

1474+
#[test]
1475+
fn parse_json_object() {
1476+
let dialects = TestedDialects::new(vec![
1477+
Box::new(MsSqlDialect {}),
1478+
Box::new(PostgreSqlDialect {}),
1479+
]);
1480+
let select = dialects.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : 1)");
1481+
match expr_from_projection(&select.projection[0]) {
1482+
Expr::Function(Function {
1483+
args: FunctionArguments::List(FunctionArgumentList { args, .. }),
1484+
..
1485+
}) => assert_eq!(
1486+
&[
1487+
FunctionArg::ExprNamed {
1488+
name: Expr::Value(Value::SingleQuotedString("name".into())),
1489+
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
1490+
"value".into()
1491+
))),
1492+
operator: FunctionArgOperator::Colon
1493+
},
1494+
FunctionArg::ExprNamed {
1495+
name: Expr::Value(Value::SingleQuotedString("type".into())),
1496+
arg: FunctionArgExpr::Expr(Expr::Value(number("1"))),
1497+
operator: FunctionArgOperator::Colon
1498+
}
1499+
],
1500+
&args[..]
1501+
),
1502+
_ => unreachable!(),
1503+
}
1504+
let select = dialects
1505+
.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : NULL ABSENT ON NULL)");
1506+
match expr_from_projection(&select.projection[0]) {
1507+
Expr::Function(Function {
1508+
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
1509+
..
1510+
}) => {
1511+
assert_eq!(
1512+
&[
1513+
FunctionArg::ExprNamed {
1514+
name: Expr::Value(Value::SingleQuotedString("name".into())),
1515+
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
1516+
"value".into()
1517+
))),
1518+
operator: FunctionArgOperator::Colon
1519+
},
1520+
FunctionArg::ExprNamed {
1521+
name: Expr::Value(Value::SingleQuotedString("type".into())),
1522+
arg: FunctionArgExpr::Expr(Expr::Value(Value::Null)),
1523+
operator: FunctionArgOperator::Colon
1524+
}
1525+
],
1526+
&args[..]
1527+
);
1528+
assert_eq!(
1529+
&[FunctionArgumentClause::JsonNullClause(
1530+
JsonNullClause::AbsentOnNull
1531+
)],
1532+
&clauses[..]
1533+
);
1534+
}
1535+
_ => unreachable!(),
1536+
}
1537+
let select = dialects.verified_only_select("SELECT JSON_OBJECT(NULL ON NULL)");
1538+
match expr_from_projection(&select.projection[0]) {
1539+
Expr::Function(Function {
1540+
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
1541+
..
1542+
}) => {
1543+
assert!(args.is_empty());
1544+
assert_eq!(
1545+
&[FunctionArgumentClause::JsonNullClause(
1546+
JsonNullClause::NullOnNull
1547+
)],
1548+
&clauses[..]
1549+
);
1550+
}
1551+
_ => unreachable!(),
1552+
}
1553+
let select = dialects.verified_only_select("SELECT JSON_OBJECT(ABSENT ON NULL)");
1554+
match expr_from_projection(&select.projection[0]) {
1555+
Expr::Function(Function {
1556+
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
1557+
..
1558+
}) => {
1559+
assert!(args.is_empty());
1560+
assert_eq!(
1561+
&[FunctionArgumentClause::JsonNullClause(
1562+
JsonNullClause::AbsentOnNull
1563+
)],
1564+
&clauses[..]
1565+
);
1566+
}
1567+
_ => unreachable!(),
1568+
}
1569+
let select = dialects.verified_only_select(
1570+
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_ARRAY(1, 2) ABSENT ON NULL)",
1571+
);
1572+
match expr_from_projection(&select.projection[0]) {
1573+
Expr::Function(Function {
1574+
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
1575+
..
1576+
}) => {
1577+
assert_eq!(
1578+
&FunctionArg::ExprNamed {
1579+
name: Expr::Value(Value::SingleQuotedString("name".into())),
1580+
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
1581+
"value".into()
1582+
))),
1583+
operator: FunctionArgOperator::Colon
1584+
},
1585+
&args[0]
1586+
);
1587+
assert!(matches!(
1588+
args[1],
1589+
FunctionArg::ExprNamed {
1590+
name: Expr::Value(Value::SingleQuotedString(_)),
1591+
arg: FunctionArgExpr::Expr(Expr::Function(_)),
1592+
operator: FunctionArgOperator::Colon
1593+
}
1594+
));
1595+
assert_eq!(
1596+
&[FunctionArgumentClause::JsonNullClause(
1597+
JsonNullClause::AbsentOnNull
1598+
)],
1599+
&clauses[..]
1600+
);
1601+
}
1602+
_ => unreachable!(),
1603+
}
1604+
let select = dialects.verified_only_select(
1605+
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_OBJECT('type_id' : 1, 'name' : 'a') NULL ON NULL)",
1606+
);
1607+
match expr_from_projection(&select.projection[0]) {
1608+
Expr::Function(Function {
1609+
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
1610+
..
1611+
}) => {
1612+
assert_eq!(
1613+
&FunctionArg::ExprNamed {
1614+
name: Expr::Value(Value::SingleQuotedString("name".into())),
1615+
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
1616+
"value".into()
1617+
))),
1618+
operator: FunctionArgOperator::Colon
1619+
},
1620+
&args[0]
1621+
);
1622+
assert!(matches!(
1623+
args[1],
1624+
FunctionArg::ExprNamed {
1625+
name: Expr::Value(Value::SingleQuotedString(_)),
1626+
arg: FunctionArgExpr::Expr(Expr::Function(_)),
1627+
operator: FunctionArgOperator::Colon
1628+
}
1629+
));
1630+
assert_eq!(
1631+
&[FunctionArgumentClause::JsonNullClause(
1632+
JsonNullClause::NullOnNull
1633+
)],
1634+
&clauses[..]
1635+
);
1636+
}
1637+
_ => unreachable!(),
1638+
}
1639+
}
1640+
14741641
#[test]
14751642
fn parse_mod_no_spaces() {
14761643
use self::Expr::*;
@@ -4416,7 +4583,10 @@ fn parse_explain_query_plan() {
44164583

44174584
#[test]
44184585
fn parse_named_argument_function() {
4419-
let dialects = all_dialects_where(|d| d.supports_named_fn_args_with_rarrow_operator());
4586+
let dialects = all_dialects_where(|d| {
4587+
d.supports_named_fn_args_with_rarrow_operator()
4588+
&& !d.supports_named_fn_args_with_expr_name()
4589+
});
44204590
let sql = "SELECT FUN(a => '1', b => '2') FROM foo";
44214591
let select = dialects.verified_only_select(sql);
44224592

tests/sqlparser_mssql.rs

-159
Original file line numberDiff line numberDiff line change
@@ -793,165 +793,6 @@ fn parse_for_json_expect_ast() {
793793

794794
#[test]
795795
fn parse_mssql_json_object() {
796-
let select = ms().verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : 1)");
797-
match expr_from_projection(&select.projection[0]) {
798-
Expr::Function(Function {
799-
args: FunctionArguments::List(FunctionArgumentList { args, .. }),
800-
..
801-
}) => assert_eq!(
802-
&[
803-
FunctionArg::ExprNamed {
804-
name: Expr::Value(Value::SingleQuotedString("name".into())),
805-
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
806-
"value".into()
807-
))),
808-
operator: FunctionArgOperator::Colon
809-
},
810-
FunctionArg::ExprNamed {
811-
name: Expr::Value(Value::SingleQuotedString("type".into())),
812-
arg: FunctionArgExpr::Expr(Expr::Value(number("1"))),
813-
operator: FunctionArgOperator::Colon
814-
}
815-
],
816-
&args[..]
817-
),
818-
_ => unreachable!(),
819-
}
820-
let select = ms()
821-
.verified_only_select("SELECT JSON_OBJECT('name' : 'value', 'type' : NULL ABSENT ON NULL)");
822-
match expr_from_projection(&select.projection[0]) {
823-
Expr::Function(Function {
824-
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
825-
..
826-
}) => {
827-
assert_eq!(
828-
&[
829-
FunctionArg::ExprNamed {
830-
name: Expr::Value(Value::SingleQuotedString("name".into())),
831-
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
832-
"value".into()
833-
))),
834-
operator: FunctionArgOperator::Colon
835-
},
836-
FunctionArg::ExprNamed {
837-
name: Expr::Value(Value::SingleQuotedString("type".into())),
838-
arg: FunctionArgExpr::Expr(Expr::Value(Value::Null)),
839-
operator: FunctionArgOperator::Colon
840-
}
841-
],
842-
&args[..]
843-
);
844-
assert_eq!(
845-
&[FunctionArgumentClause::JsonNullClause(
846-
JsonNullClause::AbsentOnNull
847-
)],
848-
&clauses[..]
849-
);
850-
}
851-
_ => unreachable!(),
852-
}
853-
let select = ms().verified_only_select("SELECT JSON_OBJECT(NULL ON NULL)");
854-
match expr_from_projection(&select.projection[0]) {
855-
Expr::Function(Function {
856-
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
857-
..
858-
}) => {
859-
assert!(args.is_empty());
860-
assert_eq!(
861-
&[FunctionArgumentClause::JsonNullClause(
862-
JsonNullClause::NullOnNull
863-
)],
864-
&clauses[..]
865-
);
866-
}
867-
_ => unreachable!(),
868-
}
869-
let select = ms().verified_only_select("SELECT JSON_OBJECT(ABSENT ON NULL)");
870-
match expr_from_projection(&select.projection[0]) {
871-
Expr::Function(Function {
872-
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
873-
..
874-
}) => {
875-
assert!(args.is_empty());
876-
assert_eq!(
877-
&[FunctionArgumentClause::JsonNullClause(
878-
JsonNullClause::AbsentOnNull
879-
)],
880-
&clauses[..]
881-
);
882-
}
883-
_ => unreachable!(),
884-
}
885-
let select = ms().verified_only_select(
886-
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_ARRAY(1, 2) ABSENT ON NULL)",
887-
);
888-
match expr_from_projection(&select.projection[0]) {
889-
Expr::Function(Function {
890-
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
891-
..
892-
}) => {
893-
assert_eq!(
894-
&FunctionArg::ExprNamed {
895-
name: Expr::Value(Value::SingleQuotedString("name".into())),
896-
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
897-
"value".into()
898-
))),
899-
operator: FunctionArgOperator::Colon
900-
},
901-
&args[0]
902-
);
903-
assert!(matches!(
904-
args[1],
905-
FunctionArg::ExprNamed {
906-
name: Expr::Value(Value::SingleQuotedString(_)),
907-
arg: FunctionArgExpr::Expr(Expr::Function(_)),
908-
operator: FunctionArgOperator::Colon
909-
}
910-
));
911-
assert_eq!(
912-
&[FunctionArgumentClause::JsonNullClause(
913-
JsonNullClause::AbsentOnNull
914-
)],
915-
&clauses[..]
916-
);
917-
}
918-
_ => unreachable!(),
919-
}
920-
let select = ms().verified_only_select(
921-
"SELECT JSON_OBJECT('name' : 'value', 'type' : JSON_OBJECT('type_id' : 1, 'name' : 'a') NULL ON NULL)",
922-
);
923-
match expr_from_projection(&select.projection[0]) {
924-
Expr::Function(Function {
925-
args: FunctionArguments::List(FunctionArgumentList { args, clauses, .. }),
926-
..
927-
}) => {
928-
assert_eq!(
929-
&FunctionArg::ExprNamed {
930-
name: Expr::Value(Value::SingleQuotedString("name".into())),
931-
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
932-
"value".into()
933-
))),
934-
operator: FunctionArgOperator::Colon
935-
},
936-
&args[0]
937-
);
938-
assert!(matches!(
939-
args[1],
940-
FunctionArg::ExprNamed {
941-
name: Expr::Value(Value::SingleQuotedString(_)),
942-
arg: FunctionArgExpr::Expr(Expr::Function(_)),
943-
operator: FunctionArgOperator::Colon
944-
}
945-
));
946-
assert_eq!(
947-
&[FunctionArgumentClause::JsonNullClause(
948-
JsonNullClause::NullOnNull
949-
)],
950-
&clauses[..]
951-
);
952-
}
953-
_ => unreachable!(),
954-
}
955796
let select = ms().verified_only_select(
956797
"SELECT JSON_OBJECT('user_name' : USER_NAME(), LOWER(@id_key) : @id_value, 'sid' : (SELECT @@SPID) ABSENT ON NULL)",
957798
);

0 commit comments

Comments
 (0)