Support table aliases without AS (7/8)

...as in `FROM foo bar WHERE bar.x > 1`.

To avoid ambiguity as to whether a token is an alias or a keyword, we
maintain a blacklist of keywords, that can follow a "table factor", to
prevent parsing them as an alias. This "context-specific reserved
keyword" approach lets us accept more SQL that's valid in some dialects,
than a list of globally reserved keywords. Also some dialects (e.g.
Oracle) apparently don't reserve some keywords (like JOIN), while
presumably they won't accept them as an alias (`FROM foo JOIN` meaning
`FROM foo AS JOIN`).
This commit is contained in:
Nickolay Ponomarev 2019-01-21 01:28:59 +03:00
parent 536fa6e428
commit 76ec175d20
3 changed files with 36 additions and 11 deletions

View file

@ -1,14 +1,16 @@
///! This module defines a list of constants for every keyword that
///! This module defines
/// 1) a list of constants for every keyword that
/// can appear in SQLWord::keyword:
/// pub const KEYWORD = "KEYWORD"
/// and an `ALL_KEYWORDS` array with every keyword in it.
/// 2) an `ALL_KEYWORDS` array with every keyword in it
/// This is not a list of *reserved* keywords: some of these can be
/// parsed as identifiers if the parser decides so. This means that
/// new keywords can be added here without affecting the parse result.
///
/// This is not a list of *reserved* keywords: some of these can be
/// parsed as identifiers if the parser decides so. This means that
/// new keywords can be added here without affecting the parse result.
///
/// As a matter of fact, most of these keywords are not used at all
/// and could be removed.
/// As a matter of fact, most of these keywords are not used at all
/// and could be removed.
/// 3) a `RESERVED_FOR_TABLE_ALIAS` array with keywords reserved in a
/// "table alias" context.
macro_rules! keyword {
($($ident:ident),*) => {
@ -707,3 +709,12 @@ pub const ALL_KEYWORDS: &'static [&'static str] = &[
ZONE,
END_EXEC,
];
/// These keywords can't be used as a table alias, so that `FROM table_name alias`
/// can be parsed unambiguously without looking ahead.
pub const RESERVED_FOR_TABLE_ALIAS: &'static [&'static str] = &[
WHERE, GROUP, ON, // keyword is 'reserved' in most dialects
JOIN, INNER, CROSS, FULL, LEFT, RIGHT, // not reserved in Oracle
NATURAL, USING, // not reserved in Oracle & MSSQL
// UNION, EXCEPT, INTERSECT, ORDER // TODO add these with tests.
];