risingwave_sqlparser/
keywords.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! This module defines
14//! 1. a list of constants for every keyword that
15//!    can appear in [crate::tokenizer::Word::keyword]:
16//!
17//!    pub const KEYWORD = "KEYWORD"
18//! 2. an `ALL_KEYWORDS` array with every keyword in it
19//!    This is not a list of *reserved* keywords: some of these can be
20//!    parsed as identifiers if the parser decides so. This means that
21//!    new keywords can be added here without affecting the parse result.
22//!
23//!    As a matter of fact, most of these keywords are not used at all
24//!    and could be removed.
25//! 3. a `RESERVED_FOR_TABLE_ALIAS` array with keywords reserved in a
26//!    "table alias" context.
27
28use std::fmt;
29
30/// Defines a string constant for a single keyword: `kw_def!(SELECT);`
31/// expands to `pub const SELECT = "SELECT";`
32macro_rules! kw_def {
33    ($ident:ident = $string_keyword:expr) => {
34        pub const $ident: &'static str = $string_keyword;
35    };
36    ($ident:ident) => {
37        kw_def!($ident = stringify!($ident));
38    };
39}
40
41/// Expands to a list of `kw_def!()` invocations for each keyword
42/// and defines an ALL_KEYWORDS array of the defined constants.
43macro_rules! define_keywords {
44    ($(
45        $ident:ident $(= $string_keyword:expr)?
46    ),*) => {
47        #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
48        #[expect(non_camel_case_types, clippy::enum_variant_names)]
49        pub enum Keyword {
50            NoKeyword,
51            $($ident),*
52        }
53
54        pub const ALL_KEYWORDS_INDEX: &[Keyword] = &[
55            $(Keyword::$ident),*
56        ];
57
58        $(kw_def!($ident $(= $string_keyword)?);)*
59        pub const ALL_KEYWORDS: &[&'static str] = &[
60            $($ident),*
61        ];
62    };
63}
64
65// The following keywords should be sorted to be able to match using binary search
66define_keywords!(
67    ABORT,
68    ABS,
69    ACTION,
70    ADAPTIVE,
71    ADD,
72    AGGREGATE,
73    ALL,
74    ALLOCATE,
75    ALTER,
76    ANALYSE,
77    ANALYZE,
78    AND,
79    ANY,
80    APPEND,
81    ARE,
82    ARRAY,
83    ARRAY_AGG,
84    ARRAY_MAX_CARDINALITY,
85    AS,
86    ASC,
87    ASENSITIVE,
88    ASOF,
89    ASYMMETRIC,
90    AT,
91    ATOMIC,
92    AUTHORIZATION,
93    AUTO,
94    AVG,
95    BACKFILL_PARALLELISM,
96    BACKUP,
97    BASE64,
98    BEGIN,
99    BEGIN_FRAME,
100    BEGIN_PARTITION,
101    BETWEEN,
102    BIGINT,
103    BINARY,
104    BIT_LENGTH,
105    BLOB,
106    BOOL,
107    BOOLEAN,
108    BOTH,
109    BY,
110    BYTEA,
111    CACHE,
112    CALL,
113    CALLED,
114    CANCEL,
115    CARDINALITY,
116    CASCADE,
117    CASCADED,
118    CASE,
119    CAST,
120    CEIL,
121    CEILING,
122    CHAIN,
123    CHAR,
124    CHARACTER,
125    CHARACTERISTICS,
126    CHARACTER_LENGTH,
127    CHAR_LENGTH,
128    CHECK,
129    CLOB,
130    CLOSE,
131    CLUSTER,
132    COALESCE,
133    COLLATE,
134    COLLATION,
135    COLLECT,
136    COLUMN,
137    COLUMNS,
138    COMMENT,
139    COMMIT,
140    COMMITTED,
141    COMPACTION,
142    CONCURRENTLY,
143    CONDITION,
144    CONFIG,
145    CONFLICT,
146    CONFLUENT,
147    CONNECT,
148    CONNECTION,
149    CONNECTIONS,
150    CONNECTOR,
151    CONSTRAINT,
152    CONTAINS,
153    CONVERT,
154    COPY,
155    CORR,
156    CORRESPONDING,
157    COUNT,
158    COVAR_POP,
159    COVAR_SAMP,
160    CREATE,
161    CROSS,
162    CUBE,
163    CUME_DIST,
164    CURRENT,
165    CURRENT_CATALOG,
166    CURRENT_DATE,
167    CURRENT_DEFAULT_TRANSFORM_GROUP,
168    CURRENT_PATH,
169    CURRENT_ROLE,
170    CURRENT_ROW,
171    CURRENT_SCHEMA,
172    CURRENT_TIME,
173    CURRENT_TIMESTAMP,
174    CURRENT_TRANSFORM_GROUP_FOR_TYPE,
175    CURRENT_USER,
176    CURSOR,
177    CURSORS,
178    CYCLE,
179    DATA,
180    DATABASE,
181    DATABASES,
182    DATE,
183    DAY,
184    DEALLOCATE,
185    DEC,
186    DECIMAL,
187    DECLARE,
188    DEFAULT,
189    DEFERRABLE,
190    DEFERRED,
191    DELETE,
192    DELIMITED,
193    DENSE_RANK,
194    DEREF,
195    DESC,
196    DESCRIBE,
197    DETERMINISTIC,
198    DIRECTORY,
199    DISCARD,
200    DISCONNECT,
201    DISTINCT,
202    DISTRIBUTED,
203    DO,
204    DOT,
205    DOUBLE,
206    DROP,
207    DYNAMIC,
208    EACH,
209    ELEMENT,
210    ELSE,
211    EMIT,
212    ENCODE,
213    END,
214    END_EXEC = "END-EXEC",
215    END_FRAME,
216    END_PARTITION,
217    ENGINE,
218    EQUALS,
219    ERROR,
220    ESCAPE,
221    EVENT,
222    EVERY,
223    EXCEPT,
224    EXCLUDE,
225    EXEC,
226    EXECUTE,
227    EXISTS,
228    EXP,
229    EXPLAIN,
230    EXTERNAL,
231    EXTRACT,
232    FALSE,
233    FETCH,
234    FILE,
235    FILTER,
236    FIRST,
237    FIRST_VALUE,
238    FLOAT,
239    FLOOR,
240    FLUSH,
241    FOLLOWING,
242    FOR,
243    FOREIGN,
244    FORMAT,
245    FRAGMENT,
246    FRAGMENTS,
247    FRAME_ROW,
248    FREE,
249    FREEZE,
250    FROM,
251    FULL,
252    FUNCTION,
253    FUNCTIONS,
254    FUSION,
255    GAP,
256    GET,
257    GLOBAL,
258    GRANT,
259    GRANTED,
260    GROUP,
261    GROUPING,
262    GROUPS,
263    HAVING,
264    HEADER,
265    HOLD,
266    HOUR,
267    IDENTITY,
268    IF,
269    IGNORE,
270    ILIKE,
271    IMMEDIATELY,
272    IMMUTABLE,
273    IN,
274    INCLUDE,
275    INDEX,
276    INDEXES,
277    INDICATOR,
278    INITIALLY,
279    INNER,
280    INOUT,
281    INSENSITIVE,
282    INSERT,
283    INT,
284    INTEGER,
285    INTERNAL,
286    INTERSECT,
287    INTERSECTION,
288    INTERVAL,
289    INTO,
290    IS,
291    ISNULL,
292    ISOLATION,
293    JOB,
294    JOBS,
295    JOIN,
296    JSON,
297    KEY,
298    KEYS,
299    KILL,
300    LANGUAGE,
301    LARGE,
302    LAST,
303    LATERAL,
304    LEADING,
305    LEFT,
306    LEVEL,
307    LIKE,
308    LIMIT,
309    LINK,
310    LN,
311    LOCAL,
312    LOCALTIME,
313    LOCALTIMESTAMP,
314    LOCATION,
315    LOWER,
316    MAP,
317    MATCH,
318    MATERIALIZED,
319    MAX,
320    MEMBER,
321    MERGE,
322    MESSAGE,
323    META,
324    METHOD,
325    MIN,
326    MINUTE,
327    MOD,
328    MODIFIES,
329    MODULE,
330    MONTH,
331    MULTISET,
332    NATIONAL,
333    NATIVE,
334    NATURAL,
335    NCHAR,
336    NCLOB,
337    NEW,
338    NEXT,
339    NO,
340    NONE,
341    NORMALIZE,
342    NOSCAN,
343    NOT,
344    NOTHING,
345    NOTNULL,
346    NTH_VALUE,
347    NTILE,
348    NULL,
349    NULLIF,
350    NULLS,
351    NUMERIC,
352    OBJECT,
353    OCCURRENCES_REGEX,
354    OCTET_LENGTH,
355    OF,
356    OFFSET,
357    OLD,
358    ON,
359    ONLY,
360    OPEN,
361    OPERATOR,
362    OPTION,
363    OR,
364    ORDER,
365    ORDINALITY,
366    OTHERS,
367    OUT,
368    OUTER,
369    OUTPUTFORMAT,
370    OVER,
371    OVERLAPS,
372    OVERLAY,
373    OVERWRITE,
374    OWNER,
375    PARALLELISM,
376    PARAMETER,
377    PARQUET,
378    PARTITION,
379    PARTITIONED,
380    PARTITIONS,
381    PERCENT,
382    PERCENTILE_CONT,
383    PERCENTILE_DISC,
384    PERCENT_RANK,
385    PERIOD,
386    PLACING,
387    PLAN,
388    PORTION,
389    POSITION,
390    POSITION_REGEX,
391    POWER,
392    PRECEDES,
393    PRECEDING,
394    PRECISION,
395    PREPARE,
396    PRIMARY,
397    PRIVILEGES,
398    PROCEDURE,
399    PROCESSLIST,
400    PURGE,
401    RANGE,
402    RANK,
403    RCFILE,
404    READ,
405    READS,
406    REAL,
407    RECOVER,
408    RECURSIVE,
409    REF,
410    REFERENCES,
411    REFERENCING,
412    REFRESH,
413    REGISTRY,
414    REGR_AVGX,
415    REGR_AVGY,
416    REGR_COUNT,
417    REGR_INTERCEPT,
418    REGR_R2,
419    REGR_SLOPE,
420    REGR_SXX,
421    REGR_SXY,
422    REGR_SYY,
423    RELEASE,
424    RENAME,
425    REPAIR,
426    REPEATABLE,
427    REPLACE,
428    RESET,
429    RESOURCE_GROUP,
430    RESTRICT,
431    RESULT,
432    RETENTION,
433    RETURN,
434    RETURNING,
435    RETURNS,
436    REVOKE,
437    RIGHT,
438    ROLLBACK,
439    ROLLUP,
440    ROW,
441    ROWID,
442    ROWS,
443    ROW_NUMBER,
444    RUNTIME,
445    SAVEPOINT,
446    SCALAR,
447    SCHEMA,
448    SCHEMAS,
449    SCOPE,
450    SCROLL,
451    SEARCH,
452    SECOND,
453    SECRET,
454    SECRETS,
455    SELECT,
456    SENSITIVE,
457    SEQUENCE,
458    SEQUENCEFILE,
459    SEQUENCES,
460    SERDE,
461    SERIALIZABLE,
462    SESSION,
463    SESSION_USER,
464    SET,
465    SETS,
466    SHOW,
467    SIMILAR,
468    SINCE,
469    SINK,
470    SINKS,
471    SMALLINT,
472    SNAPSHOT,
473    SNAPSHOTS,
474    SOME,
475    SORT,
476    SOURCE,
477    SOURCES,
478    SPECIFIC,
479    SPECIFICTYPE,
480    SQL,
481    SQLEXCEPTION,
482    SQLSTATE,
483    SQLWARNING,
484    SQRT,
485    STABLE,
486    START,
487    STATIC,
488    STATISTICS,
489    STDDEV_POP,
490    STDDEV_SAMP,
491    STDIN,
492    STDOUT,
493    STORED,
494    STRING,
495    STRUCT,
496    SUBMULTISET,
497    SUBSCRIPTION,
498    SUBSCRIPTIONS,
499    SUBSTRING,
500    SUBSTRING_REGEX,
501    SUCCEEDS,
502    SUM,
503    SWAP,
504    SYMMETRIC,
505    SYNC,
506    SYSTEM,
507    SYSTEM_TIME,
508    SYSTEM_USER,
509    SYSTEM_VERSION,
510    TABLE,
511    TABLES,
512    TABLESAMPLE,
513    TBLPROPERTIES,
514    TEMP,
515    TEMPORARY,
516    TEXT,
517    TEXTFILE,
518    THEN,
519    TIES,
520    TIME,
521    TIMESTAMP,
522    TIMEZONE_HOUR,
523    TIMEZONE_MINUTE,
524    TINYINT,
525    TO,
526    TOP,
527    TRAILING,
528    TRANSACTION,
529    TRANSLATE,
530    TRANSLATE_REGEX,
531    TRANSLATION,
532    TREAT,
533    TRIGGER,
534    TRIM,
535    TRIM_ARRAY,
536    TRUE,
537    TRUNCATE,
538    TRY_CAST,
539    TTL,
540    TYPE,
541    UESCAPE,
542    UNBOUNDED,
543    UNCOMMITTED,
544    UNION,
545    UNIQUE,
546    UNKNOWN,
547    UNNEST,
548    UPDATE,
549    UPPER,
550    USAGE,
551    USE,
552    USER,
553    USING,
554    UUID,
555    VACUUM,
556    VALIDATE,
557    VALUE,
558    VALUES,
559    VALUE_OF,
560    VARBINARY,
561    VARCHAR,
562    VARIADIC,
563    VARYING,
564    VAR_POP,
565    VAR_SAMP,
566    VERBOSE,
567    VERSION,
568    VERSIONING,
569    VIEW,
570    VIEWS,
571    VIRTUAL,
572    VOLATILE,
573    WAIT,
574    WATERMARK,
575    WHEN,
576    WHENEVER,
577    WHERE,
578    WIDTH_BUCKET,
579    WINDOW,
580    WITH,
581    WITHIN,
582    WITHOUT,
583    WORK,
584    WRITE,
585    XML,
586    XOR,
587    YAML,
588    YEAR,
589    ZONE
590);
591
592/// These keywords can't be used as a table alias, so that `FROM table_name alias`
593/// can be parsed unambiguously without looking ahead.
594pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
595    // Reserved as both a table and a column alias:
596    Keyword::WITH,
597    Keyword::EXPLAIN,
598    Keyword::ANALYZE,
599    Keyword::SELECT,
600    Keyword::WHERE,
601    Keyword::GROUP,
602    Keyword::SORT,
603    Keyword::HAVING,
604    Keyword::ORDER,
605    Keyword::TOP,
606    Keyword::LATERAL,
607    Keyword::VIEW,
608    Keyword::LIMIT,
609    Keyword::OFFSET,
610    Keyword::FETCH,
611    Keyword::UNION,
612    Keyword::EXCEPT,
613    Keyword::INTERSECT,
614    // Reserved only as a table alias in the `FROM`/`JOIN` clauses:
615    Keyword::ON,
616    Keyword::JOIN,
617    Keyword::INNER,
618    Keyword::CROSS,
619    Keyword::FULL,
620    Keyword::LEFT,
621    Keyword::RIGHT,
622    Keyword::NATURAL,
623    Keyword::ASOF,
624    Keyword::USING,
625    Keyword::CLUSTER,
626    // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
627    Keyword::OUTER,
628    Keyword::SET,
629    Keyword::RETURNING,
630    Keyword::EMIT,
631    Keyword::WINDOW,
632];
633
634/// Can't be used as a column alias, so that `SELECT <expr> alias`
635/// can be parsed unambiguously without looking ahead.
636pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
637    // Reserved as both a table and a column alias:
638    Keyword::WITH,
639    Keyword::EXPLAIN,
640    Keyword::ANALYZE,
641    Keyword::SELECT,
642    Keyword::WHERE,
643    Keyword::GROUP,
644    Keyword::SORT,
645    Keyword::HAVING,
646    Keyword::ORDER,
647    Keyword::TOP,
648    Keyword::LATERAL,
649    Keyword::VIEW,
650    Keyword::LIMIT,
651    Keyword::OFFSET,
652    Keyword::FETCH,
653    Keyword::UNION,
654    Keyword::EXCEPT,
655    Keyword::INTERSECT,
656    Keyword::CLUSTER,
657    // Reserved only as a column alias in the `SELECT` clause
658    Keyword::FROM,
659];
660
661/// Can't be used as a column or table name in PostgreSQL.
662///
663/// This list is taken from the following table, for all "reserved" words in the PostgreSQL column,
664/// including "can be function or type" and "requires AS". <https://www.postgresql.org/docs/14/sql-keywords-appendix.html#KEYWORDS-TABLE>
665///
666/// `SELECT` and `WITH` were commented out because the following won't parse:
667/// `SELECT (SELECT 1)` or `SELECT (WITH a AS (SELECT 1) SELECT 1)`
668///
669/// Other commented ones like `CURRENT_SCHEMA` are actually functions invoked without parentheses.
670pub const RESERVED_FOR_COLUMN_OR_TABLE_NAME: &[Keyword] = &[
671    Keyword::ALL,
672    Keyword::ANALYSE,
673    Keyword::ANALYZE,
674    Keyword::AND,
675    Keyword::ANY,
676    Keyword::ARRAY,
677    Keyword::AS,
678    Keyword::ASC,
679    Keyword::ASYMMETRIC,
680    Keyword::AUTHORIZATION,
681    Keyword::BINARY,
682    Keyword::BOTH,
683    Keyword::CASE,
684    Keyword::CAST,
685    Keyword::CHECK,
686    Keyword::COLLATE,
687    Keyword::COLLATION,
688    Keyword::COLUMN,
689    Keyword::CONCURRENTLY,
690    Keyword::CONSTRAINT,
691    Keyword::CREATE,
692    Keyword::CROSS,
693    // Keyword::CURRENT_CATALOG,
694    // Keyword::CURRENT_DATE,
695    // Keyword::CURRENT_ROLE,
696    // Keyword::CURRENT_SCHEMA,
697    // Keyword::CURRENT_TIME,
698    // Keyword::CURRENT_TIMESTAMP,
699    // Keyword::CURRENT_USER,
700    Keyword::DEFAULT,
701    Keyword::DEFERRABLE,
702    Keyword::DESC,
703    Keyword::DISTINCT,
704    Keyword::DO,
705    Keyword::ELSE,
706    Keyword::END,
707    Keyword::EXCEPT,
708    Keyword::FALSE,
709    Keyword::FETCH,
710    Keyword::FOR,
711    Keyword::FOREIGN,
712    Keyword::FREEZE,
713    Keyword::FROM,
714    Keyword::FULL,
715    Keyword::GRANT,
716    Keyword::GROUP,
717    Keyword::HAVING,
718    Keyword::ILIKE,
719    Keyword::IN,
720    Keyword::INITIALLY,
721    Keyword::INNER,
722    Keyword::INTERSECT,
723    Keyword::INTO,
724    Keyword::IS,
725    Keyword::ISNULL,
726    Keyword::JOIN,
727    Keyword::LATERAL,
728    Keyword::LEADING,
729    Keyword::LEFT,
730    Keyword::LIKE,
731    Keyword::LIMIT,
732    // Keyword::LOCALTIME,
733    // Keyword::LOCALTIMESTAMP,
734    Keyword::NATURAL,
735    Keyword::NOT,
736    Keyword::NOTNULL,
737    Keyword::NULL,
738    Keyword::OFFSET,
739    Keyword::ON,
740    Keyword::ONLY,
741    Keyword::OR,
742    Keyword::ORDER,
743    Keyword::OUTER,
744    Keyword::OVERLAPS,
745    Keyword::PLACING,
746    Keyword::PRIMARY,
747    Keyword::REFERENCES,
748    Keyword::RETURNING,
749    Keyword::RIGHT,
750    // Keyword::SELECT,
751    // Keyword::SESSION_USER,
752    Keyword::SIMILAR,
753    Keyword::SOME,
754    Keyword::SYMMETRIC,
755    Keyword::TABLE,
756    Keyword::TABLESAMPLE,
757    Keyword::THEN,
758    Keyword::TO,
759    Keyword::TRAILING,
760    Keyword::TRUE,
761    Keyword::UNION,
762    Keyword::UNIQUE,
763    // Keyword::USER,
764    Keyword::USING,
765    Keyword::VARIADIC,
766    Keyword::VERBOSE,
767    Keyword::WHEN,
768    Keyword::WHERE,
769    Keyword::WINDOW,
770    // Keyword::WITH,
771];
772
773impl fmt::Display for Keyword {
774    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
775        write!(f, "{:?}", self)
776    }
777}