mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-27 21:49:42 +00:00
Support DuckDB struct syntax and support list of struct syntax (#1372)
Signed-off-by: jayzhan211 <jayzhan211@gmail.com> Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org> Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
parent
fab834dca3
commit
8c4d30bb6d
6 changed files with 209 additions and 33 deletions
|
|
@ -302,7 +302,7 @@ pub enum DataType {
|
|||
///
|
||||
/// [hive]: https://docs.cloudera.com/cdw-runtime/cloud/impala-sql-reference/topics/impala-struct.html
|
||||
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
|
||||
Struct(Vec<StructField>),
|
||||
Struct(Vec<StructField>, StructBracketKind),
|
||||
/// Union
|
||||
///
|
||||
/// [duckdb]: https://duckdb.org/docs/sql/data_types/union.html
|
||||
|
|
@ -517,9 +517,16 @@ impl fmt::Display for DataType {
|
|||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
DataType::Struct(fields) => {
|
||||
DataType::Struct(fields, bracket) => {
|
||||
if !fields.is_empty() {
|
||||
write!(f, "STRUCT<{}>", display_comma_separated(fields))
|
||||
match bracket {
|
||||
StructBracketKind::Parentheses => {
|
||||
write!(f, "STRUCT({})", display_comma_separated(fields))
|
||||
}
|
||||
StructBracketKind::AngleBrackets => {
|
||||
write!(f, "STRUCT<{}>", display_comma_separated(fields))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
write!(f, "STRUCT")
|
||||
}
|
||||
|
|
@ -618,6 +625,17 @@ fn format_clickhouse_datetime_precision_and_timezone(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Type of brackets used for `STRUCT` literals.
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum StructBracketKind {
|
||||
/// Example: `STRUCT(a INT, b STRING)`
|
||||
Parentheses,
|
||||
/// Example: `STRUCT<a INT, b STRING>`
|
||||
AngleBrackets,
|
||||
}
|
||||
|
||||
/// Timestamp and Time data types information about TimeZone formatting.
|
||||
///
|
||||
/// This is more related to a display information than real differences between each variant. To
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ use serde::{Deserialize, Serialize};
|
|||
use sqlparser_derive::{Visit, VisitMut};
|
||||
|
||||
pub use self::data_type::{
|
||||
ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
|
||||
ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo,
|
||||
StructBracketKind, TimezoneInfo,
|
||||
};
|
||||
pub use self::dcl::{AlterRoleOperation, ResetConfig, RoleOption, SetConfigValue};
|
||||
pub use self::ddl::{
|
||||
|
|
|
|||
|
|
@ -2266,6 +2266,23 @@ impl<'a> Parser<'a> {
|
|||
))
|
||||
}
|
||||
|
||||
/// Duckdb Struct Data Type <https://duckdb.org/docs/sql/data_types/struct.html#retrieving-from-structs>
|
||||
fn parse_duckdb_struct_type_def(&mut self) -> Result<Vec<StructField>, ParserError> {
|
||||
self.expect_keyword(Keyword::STRUCT)?;
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let struct_body = self.parse_comma_separated(|parser| {
|
||||
let field_name = parser.parse_identifier(false)?;
|
||||
let field_type = parser.parse_data_type()?;
|
||||
|
||||
Ok(StructField {
|
||||
field_name: Some(field_name),
|
||||
field_type,
|
||||
})
|
||||
});
|
||||
self.expect_token(&Token::RParen)?;
|
||||
struct_body
|
||||
}
|
||||
|
||||
/// Parse a field definition in a [struct] or [tuple].
|
||||
/// Syntax:
|
||||
///
|
||||
|
|
@ -7495,12 +7512,20 @@ impl<'a> Parser<'a> {
|
|||
))))
|
||||
}
|
||||
}
|
||||
Keyword::STRUCT if dialect_of!(self is DuckDbDialect) => {
|
||||
self.prev_token();
|
||||
let field_defs = self.parse_duckdb_struct_type_def()?;
|
||||
Ok(DataType::Struct(field_defs, StructBracketKind::Parentheses))
|
||||
}
|
||||
Keyword::STRUCT if dialect_of!(self is BigQueryDialect | GenericDialect) => {
|
||||
self.prev_token();
|
||||
let (field_defs, _trailing_bracket) =
|
||||
self.parse_struct_type_def(Self::parse_struct_field_def)?;
|
||||
trailing_bracket = _trailing_bracket;
|
||||
Ok(DataType::Struct(field_defs))
|
||||
Ok(DataType::Struct(
|
||||
field_defs,
|
||||
StructBracketKind::AngleBrackets,
|
||||
))
|
||||
}
|
||||
Keyword::UNION if dialect_of!(self is DuckDbDialect | GenericDialect) => {
|
||||
self.prev_token();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue