Skip to content

[snowflake] Support FROM (table_name) alias #260

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 13, 2020

Conversation

eyalleshem
Copy link
Contributor

@eyalleshem eyalleshem commented Aug 12, 2020

Initially discussed in #223 and #244. Closes #223.

The description copied from the commit:

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 #154 by (ab)using TableFactor::NestedJoin to represent anything nested in extra set of parens.

Afterwards we learned in #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 Fail to parse - "select * from (table_name)" #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:

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

@coveralls
Copy link

coveralls commented Aug 12, 2020

Pull Request Test Coverage Report for Build 303837987

  • 51 of 56 (91.07%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-0.08%) to 91.941%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tests/sqlparser_snowflake.rs 21 23 91.3%
src/parser.rs 18 21 85.71%
Files with Coverage Reduction New Missed Lines %
src/parser.rs 1 89.23%
Totals Coverage Status
Change from base Build 300155852: -0.08%
Covered Lines: 4803
Relevant Lines: 5224

💛 - Coveralls

@nickolay nickolay changed the title support the single table in parnes with alias in snowflake by dialect [snowflake] Support FROM (table_name) alias Aug 12, 2020
Comment on lines 23 to 27
#[macro_use]
#[path = "utils/mod.rs"]
mod utils;

use utils::*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's test_utils.rs for that already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual reason that i don't use the test util is that i want to share the macro between the test ,
And if I understand it correct , the src and the the test are not considered in the same crate , so i can export macro only via #[macro_export] directive, but that mean the macro will be available not only for the test but to all users of the lib , and that something that i want to avoid (please correct me if i wrong..).
Anyway - I moved the join and table macros to test_utils.rs and change the utils dir that i crated to macros dir, hope you ok with that.
btw - why test_util.rs located inside the source ?

@eyalleshem eyalleshem force-pushed the single_tables_in_parens branch from 1ad467f to 44290ab Compare August 13, 2020 14:38
@eyalleshem eyalleshem requested a review from nickolay August 13, 2020 14:59
@eyalleshem eyalleshem force-pushed the single_tables_in_parens branch from 44290ab to 7355eff Compare August 13, 2020 15:00
@nickolay nickolay force-pushed the single_tables_in_parens branch 2 times, most recently from 2280580 to 92c6b49 Compare October 5, 2020 05:54
@nickolay
Copy link
Contributor

nickolay commented Oct 5, 2020

I first rebased this onto main without changes, then split into two commits (moving things around and implementing the new functionality), as I wanted to do all along...

@nickolay
Copy link
Contributor

nickolay commented Oct 5, 2020

Regarding the need to share helper macros, as well as helper functions, discussed in #260 (comment) -- I added a commit a3a0d7b that demonstrates how I'd like to solve this. I added some comments that I hope will explain my reasoning, please let me know if they're not clear.

The second part of the PR (and #260 (comment) ) I want to look over again before merging.

@eyalsatori
Copy link
Contributor

Thanks a lot for the rebasing and the fixes!
The solution of the test_utils indeed much more elegant .

Is there any change needed from me , or you just want to continue review it?

@nickolay
Copy link
Contributor

nickolay commented Oct 6, 2020

No, I was just running out of time that night, and wanted to share the part I believed to be ready. I'll try to get to the other one sometime "soon"...

To share helper macros between various tests/* we added a new module
(tests/macros/mod.rs). This made the prologue to be used in tests quite
long and a little weird:
```
#[macro_use]
#[path = "macros/mod.rs"]
mod macros;
use sqlparser::test_utils::*;
```

This simplifies it to:
```
#[macro_use]
mod test_utils;
use test_utils::*;
```
- and switches all existing tests to the new prologue simultaneously...

...while fixing a few other inconsistencies and adding a few comments
about the way `test_utils` work.
It was an omission of the original implementation.
@nickolay
Copy link
Contributor

Can't you use verified_only_select(sql).from instead of creating a new helper?

It's a problem to use it because we remove the information about we ignore the information about the redundant parenthesis in the AST , so the input sql will be different than the output .

I don't know why it took me so long to realize it, but we use one_statement_parses_to in cases like this. I added commits that do that to this PR and if you're OK with this, I'm ready to merge.

@eyalsatori
Copy link
Contributor

I am ok with that ,
Thanks a lot :)

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 apache#154
by (ab)using `TableFactor::NestedJoin` to represent anything nested in
extra set of parens.

Afterwards we learned in apache#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 apache#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 <[email protected]>
@nickolay nickolay force-pushed the single_tables_in_parens branch from 1c546de to ad72cda Compare October 13, 2020 06:55
@nickolay nickolay merged commit 929fc67 into apache:main Oct 13, 2020
@waitingkuo
Copy link
Contributor

@eyalleshem @nickolay i made a pull request #551 for nested table with alias

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fail to parse - "select * from (table_name) alias" (Snowflake)
5 participants