Skip to content

Commit 73ed685

Browse files
committed
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.
1 parent 2f4cd8f commit 73ed685

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

src/sqlast/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub enum SQLStatement {
377377
SQLCreateView {
378378
/// View name
379379
name: SQLObjectName,
380+
columns: Vec<SQLIdent>,
380381
query: Box<SQLQuery>,
381382
materialized: bool,
382383
with_options: Vec<SQLOption>,
@@ -474,6 +475,7 @@ impl ToString for SQLStatement {
474475
}
475476
SQLStatement::SQLCreateView {
476477
name,
478+
columns,
477479
query,
478480
materialized,
479481
with_options,
@@ -484,12 +486,18 @@ impl ToString for SQLStatement {
484486
} else {
485487
"".into()
486488
};
489+
let columns = if !columns.is_empty() {
490+
format!(" ({})", comma_separated_string(columns))
491+
} else {
492+
"".into()
493+
};
487494
format!(
488-
"CREATE{} VIEW {}{} AS {}",
495+
"CREATE{} VIEW {}{}{} AS {}",
489496
modifier,
490497
name.to_string(),
491498
with_options,
492-
query.to_string()
499+
columns,
500+
query.to_string(),
493501
)
494502
}
495503
SQLStatement::SQLCreateTable {

src/sqlparser.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ impl Parser {
775775
// Many dialects support `OR REPLACE` | `OR ALTER` right after `CREATE`, but we don't (yet).
776776
// ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
777777
let name = self.parse_object_name()?;
778-
// Parenthesized "output" columns list could be handled here.
778+
let columns = self.parse_parenthesized_column_list(Optional)?;
779779
let with_options = if self.parse_keyword("WITH") {
780780
self.parse_with_options()?
781781
} else {
@@ -786,6 +786,7 @@ impl Parser {
786786
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
787787
Ok(SQLStatement::SQLCreateView {
788788
name,
789+
columns,
789790
query,
790791
materialized,
791792
with_options,

tests/sqlparser_common.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1589,11 +1589,13 @@ fn parse_create_view() {
15891589
match verified_stmt(sql) {
15901590
SQLStatement::SQLCreateView {
15911591
name,
1592+
columns,
15921593
query,
15931594
materialized,
15941595
with_options,
15951596
} => {
15961597
assert_eq!("myschema.myview", name.to_string());
1598+
assert_eq!(Vec::<SQLIdent>::new(), columns);
15971599
assert_eq!("SELECT foo FROM bar", query.to_string());
15981600
assert!(!materialized);
15991601
assert_eq!(with_options, vec![]);
@@ -1625,17 +1627,40 @@ fn parse_create_view_with_options() {
16251627
}
16261628
}
16271629

1630+
#[test]
1631+
fn parse_create_view_with_columns() {
1632+
let sql = "CREATE VIEW v (has, cols) AS SELECT 1, 2";
1633+
match verified_stmt(sql) {
1634+
SQLStatement::SQLCreateView {
1635+
name,
1636+
columns,
1637+
with_options,
1638+
query,
1639+
materialized,
1640+
} => {
1641+
assert_eq!("v", name.to_string());
1642+
assert_eq!(columns, vec!["has".to_string(), "cols".to_string()]);
1643+
assert_eq!(with_options, vec![]);
1644+
assert_eq!("SELECT 1, 2", query.to_string());
1645+
assert!(!materialized);
1646+
}
1647+
_ => unreachable!(),
1648+
}
1649+
}
1650+
16281651
#[test]
16291652
fn parse_create_materialized_view() {
16301653
let sql = "CREATE MATERIALIZED VIEW myschema.myview AS SELECT foo FROM bar";
16311654
match verified_stmt(sql) {
16321655
SQLStatement::SQLCreateView {
16331656
name,
1657+
columns,
16341658
query,
16351659
materialized,
16361660
with_options,
16371661
} => {
16381662
assert_eq!("myschema.myview", name.to_string());
1663+
assert_eq!(Vec::<SQLIdent>::new(), columns);
16391664
assert_eq!("SELECT foo FROM bar", query.to_string());
16401665
assert!(materialized);
16411666
assert_eq!(with_options, vec![]);

0 commit comments

Comments
 (0)