mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-11 22:42:02 +00:00
Support views with explicit column names
A `CREATE VIEW` statement may provide names for its columns that override the names of the columns derived from the view's query.
This commit is contained in:
parent
2f4cd8f6c8
commit
73ed685879
3 changed files with 37 additions and 3 deletions
|
@ -377,6 +377,7 @@ pub enum SQLStatement {
|
||||||
SQLCreateView {
|
SQLCreateView {
|
||||||
/// View name
|
/// View name
|
||||||
name: SQLObjectName,
|
name: SQLObjectName,
|
||||||
|
columns: Vec<SQLIdent>,
|
||||||
query: Box<SQLQuery>,
|
query: Box<SQLQuery>,
|
||||||
materialized: bool,
|
materialized: bool,
|
||||||
with_options: Vec<SQLOption>,
|
with_options: Vec<SQLOption>,
|
||||||
|
@ -474,6 +475,7 @@ impl ToString for SQLStatement {
|
||||||
}
|
}
|
||||||
SQLStatement::SQLCreateView {
|
SQLStatement::SQLCreateView {
|
||||||
name,
|
name,
|
||||||
|
columns,
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
|
@ -484,12 +486,18 @@ impl ToString for SQLStatement {
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
"".into()
|
||||||
};
|
};
|
||||||
|
let columns = if !columns.is_empty() {
|
||||||
|
format!(" ({})", comma_separated_string(columns))
|
||||||
|
} else {
|
||||||
|
"".into()
|
||||||
|
};
|
||||||
format!(
|
format!(
|
||||||
"CREATE{} VIEW {}{} AS {}",
|
"CREATE{} VIEW {}{}{} AS {}",
|
||||||
modifier,
|
modifier,
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
with_options,
|
with_options,
|
||||||
query.to_string()
|
columns,
|
||||||
|
query.to_string(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SQLStatement::SQLCreateTable {
|
SQLStatement::SQLCreateTable {
|
||||||
|
|
|
@ -775,7 +775,7 @@ impl Parser {
|
||||||
// Many dialects support `OR REPLACE` | `OR ALTER` right after `CREATE`, but we don't (yet).
|
// Many dialects support `OR REPLACE` | `OR ALTER` right after `CREATE`, but we don't (yet).
|
||||||
// ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
|
// ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
|
||||||
let name = self.parse_object_name()?;
|
let name = self.parse_object_name()?;
|
||||||
// Parenthesized "output" columns list could be handled here.
|
let columns = self.parse_parenthesized_column_list(Optional)?;
|
||||||
let with_options = if self.parse_keyword("WITH") {
|
let with_options = if self.parse_keyword("WITH") {
|
||||||
self.parse_with_options()?
|
self.parse_with_options()?
|
||||||
} else {
|
} else {
|
||||||
|
@ -786,6 +786,7 @@ impl Parser {
|
||||||
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
|
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
|
||||||
Ok(SQLStatement::SQLCreateView {
|
Ok(SQLStatement::SQLCreateView {
|
||||||
name,
|
name,
|
||||||
|
columns,
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
|
|
|
@ -1589,11 +1589,13 @@ fn parse_create_view() {
|
||||||
match verified_stmt(sql) {
|
match verified_stmt(sql) {
|
||||||
SQLStatement::SQLCreateView {
|
SQLStatement::SQLCreateView {
|
||||||
name,
|
name,
|
||||||
|
columns,
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("myschema.myview", name.to_string());
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
|
assert_eq!(Vec::<SQLIdent>::new(), columns);
|
||||||
assert_eq!("SELECT foo FROM bar", query.to_string());
|
assert_eq!("SELECT foo FROM bar", query.to_string());
|
||||||
assert!(!materialized);
|
assert!(!materialized);
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
|
@ -1625,17 +1627,40 @@ fn parse_create_view_with_options() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_create_view_with_columns() {
|
||||||
|
let sql = "CREATE VIEW v (has, cols) AS SELECT 1, 2";
|
||||||
|
match verified_stmt(sql) {
|
||||||
|
SQLStatement::SQLCreateView {
|
||||||
|
name,
|
||||||
|
columns,
|
||||||
|
with_options,
|
||||||
|
query,
|
||||||
|
materialized,
|
||||||
|
} => {
|
||||||
|
assert_eq!("v", name.to_string());
|
||||||
|
assert_eq!(columns, vec!["has".to_string(), "cols".to_string()]);
|
||||||
|
assert_eq!(with_options, vec![]);
|
||||||
|
assert_eq!("SELECT 1, 2", query.to_string());
|
||||||
|
assert!(!materialized);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_create_materialized_view() {
|
fn parse_create_materialized_view() {
|
||||||
let sql = "CREATE MATERIALIZED VIEW myschema.myview AS SELECT foo FROM bar";
|
let sql = "CREATE MATERIALIZED VIEW myschema.myview AS SELECT foo FROM bar";
|
||||||
match verified_stmt(sql) {
|
match verified_stmt(sql) {
|
||||||
SQLStatement::SQLCreateView {
|
SQLStatement::SQLCreateView {
|
||||||
name,
|
name,
|
||||||
|
columns,
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("myschema.myview", name.to_string());
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
|
assert_eq!(Vec::<SQLIdent>::new(), columns);
|
||||||
assert_eq!("SELECT foo FROM bar", query.to_string());
|
assert_eq!("SELECT foo FROM bar", query.to_string());
|
||||||
assert!(materialized);
|
assert!(materialized);
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue