mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-13 01:16:18 +00:00
Support basic CREATE VIEW
This commit is contained in:
parent
346d1ff2e4
commit
0c0cbcaff4
4 changed files with 100 additions and 59 deletions
|
@ -350,6 +350,7 @@ keyword!(
|
||||||
VARCHAR,
|
VARCHAR,
|
||||||
VARYING,
|
VARYING,
|
||||||
VERSIONING,
|
VERSIONING,
|
||||||
|
VIEW,
|
||||||
WHEN,
|
WHEN,
|
||||||
WHENEVER,
|
WHENEVER,
|
||||||
WHERE,
|
WHERE,
|
||||||
|
@ -697,6 +698,7 @@ pub const ALL_KEYWORDS: &'static [&'static str] = &[
|
||||||
VARCHAR,
|
VARCHAR,
|
||||||
VARYING,
|
VARYING,
|
||||||
VERSIONING,
|
VERSIONING,
|
||||||
|
VIEW,
|
||||||
WHEN,
|
WHEN,
|
||||||
WHENEVER,
|
WHENEVER,
|
||||||
WHERE,
|
WHERE,
|
||||||
|
|
|
@ -173,6 +173,12 @@ pub enum SQLStatement {
|
||||||
/// WHERE
|
/// WHERE
|
||||||
selection: Option<ASTNode>,
|
selection: Option<ASTNode>,
|
||||||
},
|
},
|
||||||
|
/// CREATE VIEW
|
||||||
|
SQLCreateView {
|
||||||
|
/// View name
|
||||||
|
name: SQLObjectName,
|
||||||
|
query: SQLSelect,
|
||||||
|
},
|
||||||
/// CREATE TABLE
|
/// CREATE TABLE
|
||||||
SQLCreateTable {
|
SQLCreateTable {
|
||||||
/// Table name
|
/// Table name
|
||||||
|
@ -278,6 +284,9 @@ impl ToString for SQLStatement {
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
SQLStatement::SQLCreateView { name, query } => {
|
||||||
|
format!("CREATE VIEW {} AS {}", name.to_string(), query.to_string())
|
||||||
|
}
|
||||||
SQLStatement::SQLCreateTable { name, columns } => format!(
|
SQLStatement::SQLCreateTable { name, columns } => format!(
|
||||||
"CREATE TABLE {} ({})",
|
"CREATE TABLE {} ({})",
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
|
|
|
@ -546,7 +546,33 @@ impl Parser {
|
||||||
|
|
||||||
/// Parse a SQL CREATE statement
|
/// Parse a SQL CREATE statement
|
||||||
pub fn parse_create(&mut self) -> Result<SQLStatement, ParserError> {
|
pub fn parse_create(&mut self) -> Result<SQLStatement, ParserError> {
|
||||||
if self.parse_keywords(vec!["TABLE"]) {
|
if self.parse_keyword("TABLE") {
|
||||||
|
self.parse_create_table()
|
||||||
|
} else if self.parse_keyword("VIEW") {
|
||||||
|
self.parse_create_view()
|
||||||
|
} else {
|
||||||
|
parser_err!(format!(
|
||||||
|
"Unexpected token after CREATE: {:?}",
|
||||||
|
self.peek_token()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_create_view(&mut self) -> Result<SQLStatement, ParserError> {
|
||||||
|
// 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.
|
||||||
|
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)
|
||||||
|
self.expect_keyword("AS")?;
|
||||||
|
self.expect_keyword("SELECT")?;
|
||||||
|
let query = self.parse_select()?;
|
||||||
|
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
|
||||||
|
Ok(SQLStatement::SQLCreateView { name, query })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_create_table(&mut self) -> Result<SQLStatement, ParserError> {
|
||||||
let table_name = self.parse_object_name()?;
|
let table_name = self.parse_object_name()?;
|
||||||
// parse optional column list (schema)
|
// parse optional column list (schema)
|
||||||
let mut columns = vec![];
|
let mut columns = vec![];
|
||||||
|
@ -586,17 +612,15 @@ impl Parser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
return parser_err!(
|
return parser_err!(format!(
|
||||||
format!("Expected ',' or ')' after column definition but found {:?}", other)
|
"Expected ',' or ')' after column definition but found {:?}",
|
||||||
);
|
other
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unexpected => {
|
unexpected => {
|
||||||
return parser_err!(format!(
|
return parser_err!(format!("Expected column name, got {:?}", unexpected));
|
||||||
"Expected column name, got {:?}",
|
|
||||||
unexpected
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,12 +629,6 @@ impl Parser {
|
||||||
name: table_name,
|
name: table_name,
|
||||||
columns,
|
columns,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
parser_err!(format!(
|
|
||||||
"Unexpected token after CREATE: {:?}",
|
|
||||||
self.peek_token()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_table_key(&mut self, constraint_name: SQLIdent) -> Result<TableKey, ParserError> {
|
pub fn parse_table_key(&mut self, constraint_name: SQLIdent) -> Result<TableKey, ParserError> {
|
||||||
|
|
|
@ -700,6 +700,18 @@ fn parse_scalar_subqueries() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_create_view() {
|
||||||
|
let sql = "CREATE VIEW myschema.myview AS SELECT foo FROM bar";
|
||||||
|
match verified_stmt(sql) {
|
||||||
|
SQLStatement::SQLCreateView { name, query } => {
|
||||||
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
|
assert_eq!("SELECT foo FROM bar", query.to_string());
|
||||||
|
}
|
||||||
|
_ => assert!(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_invalid_subquery_without_parens() {
|
fn parse_invalid_subquery_without_parens() {
|
||||||
let res = parse_sql_statements("SELECT SELECT 1 FROM bar WHERE 1=1 FROM baz");
|
let res = parse_sql_statements("SELECT SELECT 1 FROM bar WHERE 1=1 FROM baz");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue