[snowflake] Support specifying an alias after FROM (table_factor)

Snowflake diverges from the standard and from most of the other
implementations by allowing extra parentheses not only around a join,
but around lone table names (e.g. `FROM (mytable [AS alias])`) and
around derived tables (e.g. `FROM ((SELECT ...)  [AS alias])`) as well.

Initially this was implemented in https://github.com/ballista-compute/sqlparser-rs/issues/154
by (ab)using `TableFactor::NestedJoin` to represent anything nested in
extra set of parens.

Afterwards we learned in https://github.com/ballista-compute/sqlparser-rs/issues/223
that in cases of such extraneous nesting Snowflake allows specifying the
alias both inside and outside parens, but not both - consider:

    FROM (table_factor AS inner_alias) AS outer_alias

We've considered implementing this by changing `TableFactor::NestedJoin`
to a `TableFactor::Nested { inner: TableWithJoins, alias:
Option<TableAlias> }`, but that seemed too generic, as no known dialect
supports duplicate aliases, as shown above, nor naming nested joins
`(foo NATURAL JOIN bar) alias`. So we decided on making a smaller change
(with no modifications to the AST), that is also more appropriate to the
contributors to the Snowflake dialect:


1) Revert #154 by rejecting `FROM (table or derived table)` in most dialects.

2) For `dialect_of!(self is SnowflakeDialect | GenericDialect)` parse
and strip the extraneous parentheses, e.g.

   `(mytable) AS alias` -> `(mytable AS alias)`


Co-authored-by: Eyal Leshem <eyal@satoricyber.com>
This commit is contained in:
Nickolay Ponomarev 2020-10-13 09:29:16 +03:00
parent d9e044aabb
commit ad72cda6b0
5 changed files with 131 additions and 46 deletions

View file

@ -156,6 +156,13 @@ pub fn number(n: &'static str) -> Value {
Value::Number(n.parse().unwrap())
}
pub fn table_alias(name: impl Into<String>) -> Option<TableAlias> {
Some(TableAlias {
name: Ident::new(name),
columns: vec![],
})
}
pub fn table(name: impl Into<String>) -> TableFactor {
TableFactor::Table {
name: ObjectName(vec![Ident::new(name.into())]),