Postgres: allow reserved keywords as bare column alias - #2491
Conversation
PostgreSQL allows almost any keyword (SELECT, ANALYZE, LATERAL, AND, OR, COLLATE, ...) to be used as a bare (AS-less) column alias unless it is in a small set of keywords that require a leading AS. See https://www.postgresql.org/docs/current/sql-keywords-appendix.html Previously: SELECT (SELECT c FROM tbl_name LIMIT 1) select; failed to parse.
| /// [keywords::RESERVED_FOR_COLUMN_ALIAS]) to be used as a bare (`AS`-less) | ||
| /// column alias. | ||
| /// See <https://www.postgresql.org/docs/current/sql-keywords-appendix.html> | ||
| const ADDITIONALLY_ALLOWED_BARE_COLUMN_ALIASES: &[Keyword] = |
There was a problem hiding this comment.
I believe at least these other ones are missing, I am not sure which of these others should be included: https://github.com/postgres/postgres/blob/master/src/include/parser/kwlist.h
&[
Keyword::ANALYZE,
Keyword::CLUSTER,
Keyword::END,
Keyword::EXCLUDE,
Keyword::EXPLAIN,
Keyword::LATERAL,
Keyword::SELECT,
Keyword::VALUES,
Keyword::VIEW,
]
| // e.g. Postgres' `SELECT 1 and` or `SELECT 1 collate`. | ||
| if let Token::Word(w) = &self.peek_token_ref().token { | ||
| let kw = w.keyword; | ||
| if matches!(kw, Keyword::AND | Keyword::OR | Keyword::COLLATE) |
There was a problem hiding this comment.
PostgreSQL also permits these bare aliases before the following query clauses. For example, SELECT 1 and FROM t and SELECT 1 collate FROM t are valid, but FROM is not among these four lookahead tokens, so the parser still treats the alias as an operator and fails.
Please handle clause boundaries such as FROM, INTO, WHERE, and ORDER BY, and add tests with aliases followed by a clause. I may have missed some others, I may not recall all of them.
| @@ -1444,6 +1452,22 @@ impl<'a> Parser<'a> { | |||
| break; | |||
| } | |||
There was a problem hiding this comment.
This shared-parser change also enables these aliases for unrelated dialects. I am not sure about how to best handle excessive permissiveness.
For example, BigQueryDialect considers AND a column alias under its current predicate, so SELECT 1 AND now I believe would succeed instead of reporting the missing right-hand operand.
GoogleSQL explicitly requires reserved keywords such as AND, OR, and COLLATE to be quoted when used as identifiers.
Let's try to find a clean way to handle these cases and add negative non-PostgreSQL tests.
PostgreSQL allows almost any keyword (SELECT, ANALYZE, LATERAL, AND, OR, COLLATE, ...) to be used as a bare (AS-less) column alias unless it is in a small set of keywords that require a leading AS.
See https://www.postgresql.org/docs/current/sql-keywords-appendix.html
Previously:
SELECT (SELECT c FROM tbl_name LIMIT 1) select;(or analyze/lateral/and/or/collate)
failed to parse.
This PR fixes that