ClickHouse: create view with fields and data types (#1292)

This commit is contained in:
Aleksei Piianin 2024-05-30 18:24:12 +02:00 committed by GitHub
parent 029a999645
commit 375742d1fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 60 additions and 2 deletions

View file

@ -815,7 +815,7 @@ impl fmt::Display for ColumnDef {
///
/// Syntax
/// ```markdown
/// <name> [OPTIONS(option, ...)]
/// <name> [data_type][OPTIONS(option, ...)]
///
/// option: <name> = <value>
/// ```
@ -824,18 +824,23 @@ impl fmt::Display for ColumnDef {
/// ```sql
/// name
/// age OPTIONS(description = "age column", tag = "prod")
/// created_at DateTime64
/// ```
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ViewColumnDef {
pub name: Ident,
pub data_type: Option<DataType>,
pub options: Option<Vec<SqlOption>>,
}
impl fmt::Display for ViewColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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() {
write!(
f,

View file

@ -7282,7 +7282,16 @@ impl<'a> Parser<'a> {
} else {
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

View file

@ -261,10 +261,12 @@ fn parse_create_view_with_options() {
vec![
ViewColumnDef {
name: Ident::new("name"),
data_type: None,
options: None,
},
ViewColumnDef {
name: Ident::new("age"),
data_type: None,
options: Some(vec![SqlOption {
name: Ident::new("description"),
value: Expr::Value(Value::DoubleQuotedString("field age".to_string())),

View file

@ -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]
fn parse_double_equal() {
clickhouse().one_statement_parses_to(

View file

@ -6319,6 +6319,7 @@ fn parse_create_view_with_columns() {
.into_iter()
.map(|name| ViewColumnDef {
name,
data_type: None,
options: None
})
.collect::<Vec<_>>()