Skip to content

Postgres: allow reserved keywords as bare column alias - #2491

Open
BenSatori wants to merge 1 commit into
apache:mainfrom
BenSatori:postgres-bare-keyword-column-alias
Open

Postgres: allow reserved keywords as bare column alias#2491
BenSatori wants to merge 1 commit into
apache:mainfrom
BenSatori:postgres-bare-keyword-column-alias

Conversation

@BenSatori

Copy link
Copy Markdown
Contributor

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

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.
Comment thread src/dialect/postgresql.rs
/// [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] =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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,
]

Comment thread src/parser/mod.rs
// 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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread src/parser/mod.rs
@@ -1444,6 +1452,22 @@ impl<'a> Parser<'a> {
break;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

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.

2 participants