mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-26 15:39:12 +00:00
add support for postgres composite types (#466)
* add support for postgres composite types Signed-off-by: password <rbalajis25@gmail.com> * fix composite test for bigdecimal feature Signed-off-by: password <rbalajis25@gmail.com>
This commit is contained in:
parent
6b2fc8102f
commit
ed86c6d53d
3 changed files with 81 additions and 1 deletions
|
@ -231,6 +231,11 @@ pub enum Expr {
|
||||||
operator: JsonOperator,
|
operator: JsonOperator,
|
||||||
right: Box<Expr>,
|
right: Box<Expr>,
|
||||||
},
|
},
|
||||||
|
/// CompositeAccess (postgres) eg: SELECT (information_schema._pg_expandarray(array['i','i'])).n
|
||||||
|
CompositeAccess {
|
||||||
|
expr: Box<Expr>,
|
||||||
|
key: Ident,
|
||||||
|
},
|
||||||
/// `IS NULL` operator
|
/// `IS NULL` operator
|
||||||
IsNull(Box<Expr>),
|
IsNull(Box<Expr>),
|
||||||
/// `IS NOT NULL` operator
|
/// `IS NOT NULL` operator
|
||||||
|
@ -565,6 +570,9 @@ impl fmt::Display for Expr {
|
||||||
} => {
|
} => {
|
||||||
write!(f, "{} {} {}", left, operator, right)
|
write!(f, "{} {} {}", left, operator, right)
|
||||||
}
|
}
|
||||||
|
Expr::CompositeAccess { expr, key } => {
|
||||||
|
write!(f, "{}.{}", expr, key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,7 +518,18 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.expect_token(&Token::RParen)?;
|
self.expect_token(&Token::RParen)?;
|
||||||
Ok(expr)
|
if !self.consume_token(&Token::Period) {
|
||||||
|
return Ok(expr);
|
||||||
|
}
|
||||||
|
let tok = self.next_token();
|
||||||
|
let key = match tok {
|
||||||
|
Token::Word(word) => word.to_ident(),
|
||||||
|
_ => return parser_err!(format!("Expected identifier, found: {}", tok)),
|
||||||
|
};
|
||||||
|
Ok(Expr::CompositeAccess {
|
||||||
|
expr: Box::new(expr),
|
||||||
|
key,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Token::Placeholder(_) => {
|
Token::Placeholder(_) => {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
|
|
|
@ -1334,6 +1334,67 @@ fn test_json() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_composite_value() {
|
||||||
|
let sql = "SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9";
|
||||||
|
let select = pg().verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
SelectItem::UnnamedExpr(Expr::CompositeAccess {
|
||||||
|
key: Ident::new("name"),
|
||||||
|
expr: Box::new(Expr::Nested(Box::new(Expr::CompoundIdentifier(vec![
|
||||||
|
Ident::new("on_hand"),
|
||||||
|
Ident::new("item")
|
||||||
|
]))))
|
||||||
|
}),
|
||||||
|
select.projection[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "bigdecimal")]
|
||||||
|
let num: Expr = Expr::Value(Value::Number(bigdecimal::BigDecimal::from(9), false));
|
||||||
|
#[cfg(not(feature = "bigdecimal"))]
|
||||||
|
let num: Expr = Expr::Value(Value::Number("9".to_string(), false));
|
||||||
|
assert_eq!(
|
||||||
|
select.selection,
|
||||||
|
Some(Expr::BinaryOp {
|
||||||
|
left: Box::new(Expr::CompositeAccess {
|
||||||
|
key: Ident::new("price"),
|
||||||
|
expr: Box::new(Expr::Nested(Box::new(Expr::CompoundIdentifier(vec![
|
||||||
|
Ident::new("on_hand"),
|
||||||
|
Ident::new("item")
|
||||||
|
]))))
|
||||||
|
}),
|
||||||
|
op: BinaryOperator::Gt,
|
||||||
|
right: Box::new(num)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
let sql = "SELECT (information_schema._pg_expandarray(ARRAY['i', 'i'])).n";
|
||||||
|
let select = pg().verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
SelectItem::UnnamedExpr(Expr::CompositeAccess {
|
||||||
|
key: Ident::new("n"),
|
||||||
|
expr: Box::new(Expr::Nested(Box::new(Expr::Function(Function {
|
||||||
|
name: ObjectName(vec![
|
||||||
|
Ident::new("information_schema"),
|
||||||
|
Ident::new("_pg_expandarray")
|
||||||
|
]),
|
||||||
|
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Array(
|
||||||
|
Array {
|
||||||
|
elem: vec![
|
||||||
|
Expr::Value(Value::SingleQuotedString("i".to_string())),
|
||||||
|
Expr::Value(Value::SingleQuotedString("i".to_string())),
|
||||||
|
],
|
||||||
|
named: true
|
||||||
|
}
|
||||||
|
)))],
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
}))))
|
||||||
|
}),
|
||||||
|
select.projection[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_comments() {
|
fn parse_comments() {
|
||||||
match pg().verified_stmt("COMMENT ON COLUMN tab.name IS 'comment'") {
|
match pg().verified_stmt("COMMENT ON COLUMN tab.name IS 'comment'") {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue