Support arbitrary WITH options for CREATE [TABLE|VIEW]

Both Postgres and MSSQL accept this syntax, though the particular
options they accept differ.
This commit is contained in:
Nikhil Benesch 2019-05-21 14:51:56 -04:00
parent 1931c76eb8
commit 69f0082db6
No known key found for this signature in database
GPG key ID: F7386C5DEADABA7F
4 changed files with 140 additions and 4 deletions

View file

@ -761,6 +761,7 @@ impl Parser {
name: table_name,
columns,
constraints,
with_options: vec![],
external: true,
file_format: Some(file_format),
location: Some(location),
@ -774,8 +775,11 @@ impl Parser {
// ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
let name = self.parse_object_name()?;
// Parenthesized "output" columns list could be handled here.
// Some dialects allow WITH here, followed by some keywords (e.g. MS SQL)
// or `(k1=v1, k2=v2, ...)` (Postgres)
let with_options = if self.parse_keyword("WITH") {
self.parse_with_options()?
} else {
vec![]
};
self.expect_keyword("AS")?;
let query = Box::new(self.parse_query()?);
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
@ -783,6 +787,7 @@ impl Parser {
name,
query,
materialized,
with_options,
})
}
@ -828,10 +833,17 @@ impl Parser {
// parse optional column list (schema)
let (columns, constraints) = self.parse_columns()?;
let with_options = if self.parse_keyword("WITH") {
self.parse_with_options()?
} else {
vec![]
};
Ok(SQLStatement::SQLCreateTable {
name: table_name,
columns,
constraints,
with_options,
external: false,
file_format: None,
location: None,
@ -941,6 +953,23 @@ impl Parser {
}
}
pub fn parse_with_options(&mut self) -> Result<Vec<SQLOption>, ParserError> {
self.expect_token(&Token::LParen)?;
let mut options = vec![];
loop {
let name = self.parse_identifier()?;
self.expect_token(&Token::Eq)?;
let value = self.parse_value()?;
options.push(SQLOption { name, value });
match self.peek_token() {
Some(Token::Comma) => self.next_token(),
_ => break,
};
}
self.expect_token(&Token::RParen)?;
Ok(options)
}
pub fn parse_alter(&mut self) -> Result<SQLStatement, ParserError> {
self.expect_keyword("TABLE")?;
let _ = self.parse_keyword("ONLY");