mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-03 22:08:16 +00:00
Improve parsing of JSON accesses on Postgres and Snowflake (#1215)
Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
parent
0606024353
commit
4bfa399919
7 changed files with 432 additions and 199 deletions
|
@ -2235,9 +2235,9 @@ fn test_json() {
|
|||
let sql = "SELECT params ->> 'name' FROM events";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("params"))),
|
||||
operator: JsonOperator::LongArrow,
|
||||
op: BinaryOperator::LongArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString("name".to_string()))),
|
||||
}),
|
||||
select.projection[0]
|
||||
|
@ -2246,9 +2246,9 @@ fn test_json() {
|
|||
let sql = "SELECT params -> 'name' FROM events";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("params"))),
|
||||
operator: JsonOperator::Arrow,
|
||||
op: BinaryOperator::Arrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString("name".to_string()))),
|
||||
}),
|
||||
select.projection[0]
|
||||
|
@ -2257,15 +2257,55 @@ fn test_json() {
|
|||
let sql = "SELECT info -> 'items' ->> 'product' FROM orders";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
left: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
operator: JsonOperator::Arrow,
|
||||
right: Box::new(Expr::JsonAccess {
|
||||
left: Box::new(Expr::Value(Value::SingleQuotedString("items".to_string()))),
|
||||
operator: JsonOperator::LongArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"product".to_string()
|
||||
)))
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
op: BinaryOperator::Arrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString("items".to_string())))
|
||||
}),
|
||||
op: BinaryOperator::LongArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"product".to_string()
|
||||
))),
|
||||
}),
|
||||
select.projection[0]
|
||||
);
|
||||
|
||||
// the RHS can be a number (array element access)
|
||||
let sql = "SELECT obj -> 42";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("obj"))),
|
||||
op: BinaryOperator::Arrow,
|
||||
right: Box::new(Expr::Value(number("42"))),
|
||||
}),
|
||||
select.projection[0]
|
||||
);
|
||||
|
||||
// the RHS can be an identifier
|
||||
let sql = "SELECT obj -> key";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("obj"))),
|
||||
op: BinaryOperator::Arrow,
|
||||
right: Box::new(Expr::Identifier(Ident::new("key"))),
|
||||
}),
|
||||
select.projection[0]
|
||||
);
|
||||
|
||||
// -> operator has lower precedence than arithmetic ops
|
||||
let sql = "SELECT obj -> 3 * 2";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("obj"))),
|
||||
op: BinaryOperator::Arrow,
|
||||
right: Box::new(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Value(number("3"))),
|
||||
op: BinaryOperator::Multiply,
|
||||
right: Box::new(Expr::Value(number("2"))),
|
||||
}),
|
||||
}),
|
||||
select.projection[0]
|
||||
|
@ -2274,9 +2314,9 @@ fn test_json() {
|
|||
let sql = "SELECT info #> '{a,b,c}' FROM orders";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
operator: JsonOperator::HashArrow,
|
||||
op: BinaryOperator::HashArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"{a,b,c}".to_string()
|
||||
))),
|
||||
|
@ -2287,9 +2327,9 @@ fn test_json() {
|
|||
let sql = "SELECT info #>> '{a,b,c}' FROM orders";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
operator: JsonOperator::HashLongArrow,
|
||||
op: BinaryOperator::HashLongArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"{a,b,c}".to_string()
|
||||
))),
|
||||
|
@ -2300,9 +2340,9 @@ fn test_json() {
|
|||
let sql = "SELECT info FROM orders WHERE info @> '{\"a\": 1}'";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
Expr::JsonAccess {
|
||||
Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
operator: JsonOperator::AtArrow,
|
||||
op: BinaryOperator::AtArrow,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"{\"a\": 1}".to_string()
|
||||
))),
|
||||
|
@ -2313,11 +2353,11 @@ fn test_json() {
|
|||
let sql = "SELECT info FROM orders WHERE '{\"a\": 1}' <@ info";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
Expr::JsonAccess {
|
||||
Expr::BinaryOp {
|
||||
left: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"{\"a\": 1}".to_string()
|
||||
))),
|
||||
operator: JsonOperator::ArrowAt,
|
||||
op: BinaryOperator::ArrowAt,
|
||||
right: Box::new(Expr::Identifier(Ident::new("info"))),
|
||||
},
|
||||
select.selection.unwrap(),
|
||||
|
@ -2326,9 +2366,9 @@ fn test_json() {
|
|||
let sql = "SELECT info #- ARRAY['a', 'b'] FROM orders";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
SelectItem::UnnamedExpr(Expr::JsonAccess {
|
||||
SelectItem::UnnamedExpr(Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::from("info"))),
|
||||
operator: JsonOperator::HashMinus,
|
||||
op: BinaryOperator::HashMinus,
|
||||
right: Box::new(Expr::Array(Array {
|
||||
elem: vec![
|
||||
Expr::Value(Value::SingleQuotedString("a".to_string())),
|
||||
|
@ -2343,9 +2383,9 @@ fn test_json() {
|
|||
let sql = "SELECT info FROM orders WHERE info @? '$.a'";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
Expr::JsonAccess {
|
||||
Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::from("info"))),
|
||||
operator: JsonOperator::AtQuestion,
|
||||
op: BinaryOperator::AtQuestion,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString("$.a".to_string())),),
|
||||
},
|
||||
select.selection.unwrap(),
|
||||
|
@ -2354,9 +2394,9 @@ fn test_json() {
|
|||
let sql = "SELECT info FROM orders WHERE info @@ '$.a'";
|
||||
let select = pg().verified_only_select(sql);
|
||||
assert_eq!(
|
||||
Expr::JsonAccess {
|
||||
Expr::BinaryOp {
|
||||
left: Box::new(Expr::Identifier(Ident::from("info"))),
|
||||
operator: JsonOperator::AtAt,
|
||||
op: BinaryOperator::AtAt,
|
||||
right: Box::new(Expr::Value(Value::SingleQuotedString("$.a".to_string())),),
|
||||
},
|
||||
select.selection.unwrap(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue