mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-09 21:42:05 +00:00
ClickHouse: create view with fields and data types (#1292)
This commit is contained in:
parent
029a999645
commit
375742d1fa
5 changed files with 60 additions and 2 deletions
|
@ -815,7 +815,7 @@ impl fmt::Display for ColumnDef {
|
||||||
///
|
///
|
||||||
/// Syntax
|
/// Syntax
|
||||||
/// ```markdown
|
/// ```markdown
|
||||||
/// <name> [OPTIONS(option, ...)]
|
/// <name> [data_type][OPTIONS(option, ...)]
|
||||||
///
|
///
|
||||||
/// option: <name> = <value>
|
/// option: <name> = <value>
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -824,18 +824,23 @@ impl fmt::Display for ColumnDef {
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// name
|
/// name
|
||||||
/// age OPTIONS(description = "age column", tag = "prod")
|
/// age OPTIONS(description = "age column", tag = "prod")
|
||||||
|
/// created_at DateTime64
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
pub struct ViewColumnDef {
|
pub struct ViewColumnDef {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
|
pub data_type: Option<DataType>,
|
||||||
pub options: Option<Vec<SqlOption>>,
|
pub options: Option<Vec<SqlOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ViewColumnDef {
|
impl fmt::Display for ViewColumnDef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.name)?;
|
write!(f, "{}", self.name)?;
|
||||||
|
if let Some(data_type) = self.data_type.as_ref() {
|
||||||
|
write!(f, " {}", data_type)?;
|
||||||
|
}
|
||||||
if let Some(options) = self.options.as_ref() {
|
if let Some(options) = self.options.as_ref() {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -7282,7 +7282,16 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(ViewColumnDef { name, options })
|
let data_type = if dialect_of!(self is ClickHouseDialect) {
|
||||||
|
Some(self.parse_data_type()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(ViewColumnDef {
|
||||||
|
name,
|
||||||
|
data_type,
|
||||||
|
options,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a parenthesized comma-separated list of unqualified, possibly quoted identifiers
|
/// Parse a parenthesized comma-separated list of unqualified, possibly quoted identifiers
|
||||||
|
|
|
@ -261,10 +261,12 @@ fn parse_create_view_with_options() {
|
||||||
vec![
|
vec![
|
||||||
ViewColumnDef {
|
ViewColumnDef {
|
||||||
name: Ident::new("name"),
|
name: Ident::new("name"),
|
||||||
|
data_type: None,
|
||||||
options: None,
|
options: None,
|
||||||
},
|
},
|
||||||
ViewColumnDef {
|
ViewColumnDef {
|
||||||
name: Ident::new("age"),
|
name: Ident::new("age"),
|
||||||
|
data_type: None,
|
||||||
options: Some(vec![SqlOption {
|
options: Some(vec![SqlOption {
|
||||||
name: Ident::new("description"),
|
name: Ident::new("description"),
|
||||||
value: Expr::Value(Value::DoubleQuotedString("field age".to_string())),
|
value: Expr::Value(Value::DoubleQuotedString("field age".to_string())),
|
||||||
|
|
|
@ -220,6 +220,47 @@ fn parse_create_table() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_create_view_with_fields_data_types() {
|
||||||
|
match clickhouse().verified_stmt(r#"CREATE VIEW v (i "int", f "String") AS SELECT * FROM t"#) {
|
||||||
|
Statement::CreateView { name, columns, .. } => {
|
||||||
|
assert_eq!(name, ObjectName(vec!["v".into()]));
|
||||||
|
assert_eq!(
|
||||||
|
columns,
|
||||||
|
vec![
|
||||||
|
ViewColumnDef {
|
||||||
|
name: "i".into(),
|
||||||
|
data_type: Some(DataType::Custom(
|
||||||
|
ObjectName(vec![Ident {
|
||||||
|
value: "int".into(),
|
||||||
|
quote_style: Some('"')
|
||||||
|
}]),
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
options: None
|
||||||
|
},
|
||||||
|
ViewColumnDef {
|
||||||
|
name: "f".into(),
|
||||||
|
data_type: Some(DataType::Custom(
|
||||||
|
ObjectName(vec![Ident {
|
||||||
|
value: "String".into(),
|
||||||
|
quote_style: Some('"')
|
||||||
|
}]),
|
||||||
|
vec![]
|
||||||
|
)),
|
||||||
|
options: None
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
clickhouse()
|
||||||
|
.parse_sql_statements(r#"CREATE VIEW v (i, f) AS SELECT * FROM t"#)
|
||||||
|
.expect_err("CREATE VIEW with fields and without data types should be invalid");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_double_equal() {
|
fn parse_double_equal() {
|
||||||
clickhouse().one_statement_parses_to(
|
clickhouse().one_statement_parses_to(
|
||||||
|
|
|
@ -6319,6 +6319,7 @@ fn parse_create_view_with_columns() {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|name| ViewColumnDef {
|
.map(|name| ViewColumnDef {
|
||||||
name,
|
name,
|
||||||
|
data_type: None,
|
||||||
options: None
|
options: None
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue