mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-25 16:34:04 +00:00
Snowflake: support for object constants (#1223)
This commit is contained in:
parent
2490034948
commit
deaa6d8151
6 changed files with 81 additions and 1 deletions
|
@ -37,4 +37,11 @@ impl Dialect for DuckDbDialect {
|
|||
fn supports_named_fn_args_with_eq_operator(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// DuckDB uses this syntax for `STRUCT`s.
|
||||
//
|
||||
// https://duckdb.org/docs/sql/data_types/struct.html#creating-structs
|
||||
fn supports_dictionary_syntax(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,4 +46,8 @@ impl Dialect for GenericDialect {
|
|||
fn supports_start_transaction_modifier(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_dictionary_syntax(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,6 +170,11 @@ pub trait Dialect: Debug + Any {
|
|||
fn supports_named_fn_args_with_eq_operator(&self) -> bool {
|
||||
false
|
||||
}
|
||||
/// Returns true if the dialect supports defining structs or objects using a
|
||||
/// syntax like `{'x': 1, 'y': 2, 'z': 3}`.
|
||||
fn supports_dictionary_syntax(&self) -> bool {
|
||||
false
|
||||
}
|
||||
/// Returns true if the dialect has a CONVERT function which accepts a type first
|
||||
/// and an expression second, e.g. `CONVERT(varchar, 1)`
|
||||
fn convert_type_before_value(&self) -> bool {
|
||||
|
|
|
@ -59,6 +59,14 @@ impl Dialect for SnowflakeDialect {
|
|||
true
|
||||
}
|
||||
|
||||
// Snowflake uses this syntax for "object constants" (the values of which
|
||||
// are not actually required to be constants).
|
||||
//
|
||||
// https://docs.snowflake.com/en/sql-reference/data-types-semistructured#label-object-constant
|
||||
fn supports_dictionary_syntax(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
|
||||
if parser.parse_keyword(Keyword::CREATE) {
|
||||
// possibly CREATE STAGE
|
||||
|
|
|
@ -1192,7 +1192,7 @@ impl<'a> Parser<'a> {
|
|||
self.prev_token();
|
||||
Ok(Expr::Value(self.parse_value()?))
|
||||
}
|
||||
Token::LBrace if dialect_of!(self is DuckDbDialect | GenericDialect) => {
|
||||
Token::LBrace if self.dialect.supports_dictionary_syntax() => {
|
||||
self.prev_token();
|
||||
self.parse_duckdb_struct_literal()
|
||||
}
|
||||
|
|
|
@ -9408,3 +9408,59 @@ fn insert_into_with_parentheses() {
|
|||
};
|
||||
dialects.verified_stmt("INSERT INTO t1 (id, name) (SELECT t2.id, t2.name FROM t2)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dictionary_syntax() {
|
||||
fn check(sql: &str, expect: Expr) {
|
||||
assert_eq!(
|
||||
all_dialects_where(|d| d.supports_dictionary_syntax()).verified_expr(sql),
|
||||
expect
|
||||
);
|
||||
}
|
||||
|
||||
check(
|
||||
"{'Alberta': 'Edmonton', 'Manitoba': 'Winnipeg'}",
|
||||
Expr::Dictionary(vec![
|
||||
DictionaryField {
|
||||
key: Ident::with_quote('\'', "Alberta"),
|
||||
value: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"Edmonton".to_owned(),
|
||||
))),
|
||||
},
|
||||
DictionaryField {
|
||||
key: Ident::with_quote('\'', "Manitoba"),
|
||||
value: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"Winnipeg".to_owned(),
|
||||
))),
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
check(
|
||||
"{'start': CAST('2023-04-01' AS TIMESTAMP), 'end': CAST('2023-04-05' AS TIMESTAMP)}",
|
||||
Expr::Dictionary(vec![
|
||||
DictionaryField {
|
||||
key: Ident::with_quote('\'', "start"),
|
||||
value: Box::new(Expr::Cast {
|
||||
kind: CastKind::Cast,
|
||||
expr: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"2023-04-01".to_owned(),
|
||||
))),
|
||||
data_type: DataType::Timestamp(None, TimezoneInfo::None),
|
||||
format: None,
|
||||
}),
|
||||
},
|
||||
DictionaryField {
|
||||
key: Ident::with_quote('\'', "end"),
|
||||
value: Box::new(Expr::Cast {
|
||||
kind: CastKind::Cast,
|
||||
expr: Box::new(Expr::Value(Value::SingleQuotedString(
|
||||
"2023-04-05".to_owned(),
|
||||
))),
|
||||
data_type: DataType::Timestamp(None, TimezoneInfo::None),
|
||||
format: None,
|
||||
}),
|
||||
},
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue