Support CREATE MATERIALIZED VIEW

This commit is contained in:
Nikhil Benesch 2019-03-06 17:19:40 -05:00
parent 52e0f55b6f
commit 23a0fc79f5
No known key found for this signature in database
GPG key ID: F7386C5DEADABA7F
4 changed files with 26 additions and 5 deletions

View file

@ -191,6 +191,7 @@ keyword!(
LOCATION, LOCATION,
LOWER, LOWER,
MATCH, MATCH,
MATERIALIZED,
MAX, MAX,
MEMBER, MEMBER,
MERGE, MERGE,
@ -539,6 +540,7 @@ pub const ALL_KEYWORDS: &'static [&'static str] = &[
LOCATION, LOCATION,
LOWER, LOWER,
MATCH, MATCH,
MATERIALIZED,
MAX, MAX,
MEMBER, MEMBER,
MERGE, MERGE,

View file

@ -241,6 +241,7 @@ pub enum SQLStatement {
/// View name /// View name
name: SQLObjectName, name: SQLObjectName,
query: SQLQuery, query: SQLQuery,
materialized: bool,
}, },
/// CREATE TABLE /// CREATE TABLE
SQLCreateTable { SQLCreateTable {
@ -347,8 +348,9 @@ impl ToString for SQLStatement {
} }
s s
} }
SQLStatement::SQLCreateView { name, query } => { SQLStatement::SQLCreateView { name, query, materialized } => {
format!("CREATE VIEW {} AS {}", name.to_string(), query.to_string()) let modifier = if *materialized { " MATERIALIZED" } else { "" };
format!("CREATE{} VIEW {} AS {}", modifier, name.to_string(), query.to_string())
} }
SQLStatement::SQLCreateTable { name, columns } => format!( SQLStatement::SQLCreateTable { name, columns } => format!(
"CREATE TABLE {} ({})", "CREATE TABLE {} ({})",

View file

@ -617,7 +617,8 @@ impl Parser {
pub fn parse_create(&mut self) -> Result<SQLStatement, ParserError> { pub fn parse_create(&mut self) -> Result<SQLStatement, ParserError> {
if self.parse_keyword("TABLE") { if self.parse_keyword("TABLE") {
self.parse_create_table() self.parse_create_table()
} else if self.parse_keyword("VIEW") { } else if self.parse_keyword("MATERIALIZED") || self.parse_keyword("VIEW") {
self.prev_token();
self.parse_create_view() self.parse_create_view()
} else { } else {
parser_err!(format!( parser_err!(format!(
@ -628,6 +629,8 @@ impl Parser {
} }
pub fn parse_create_view(&mut self) -> Result<SQLStatement, ParserError> { pub fn parse_create_view(&mut self) -> Result<SQLStatement, ParserError> {
let materialized = self.parse_keyword("MATERIALIZED");
self.expect_keyword("VIEW")?;
// 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()?;
@ -637,7 +640,7 @@ impl Parser {
self.expect_keyword("AS")?; self.expect_keyword("AS")?;
let query = self.parse_query()?; let query = self.parse_query()?;
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here. // Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
Ok(SQLStatement::SQLCreateView { name, query }) Ok(SQLStatement::SQLCreateView { name, query, materialized })
} }
pub fn parse_create_table(&mut self) -> Result<SQLStatement, ParserError> { pub fn parse_create_table(&mut self) -> Result<SQLStatement, ParserError> {

View file

@ -901,9 +901,23 @@ fn parse_scalar_subqueries() {
fn parse_create_view() { fn parse_create_view() {
let sql = "CREATE VIEW myschema.myview AS SELECT foo FROM bar"; let sql = "CREATE VIEW myschema.myview AS SELECT foo FROM bar";
match verified_stmt(sql) { match verified_stmt(sql) {
SQLStatement::SQLCreateView { name, query } => { SQLStatement::SQLCreateView { name, query, materialized } => {
assert_eq!("myschema.myview", name.to_string()); assert_eq!("myschema.myview", name.to_string());
assert_eq!("SELECT foo FROM bar", query.to_string()); assert_eq!("SELECT foo FROM bar", query.to_string());
assert!(!materialized);
}
_ => assert!(false),
}
}
#[test]
fn parse_create_materialized_view() {
let sql = "CREATE MATERIALIZED VIEW myschema.myview AS SELECT foo FROM bar";
match verified_stmt(sql) {
SQLStatement::SQLCreateView { name, query, materialized } => {
assert_eq!("myschema.myview", name.to_string());
assert_eq!("SELECT foo FROM bar", query.to_string());
assert!(materialized);
} }
_ => assert!(false), _ => assert!(false),
} }