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    CONCURRENTLY,
142    CONDITION,
143    CONFIG,
144    CONFLICT,
145    CONFLUENT,
146    CONNECT,
147    CONNECTION,
148    CONNECTIONS,
149    CONNECTOR,
150    CONSTRAINT,
151    CONTAINS,
152    CONVERT,
153    COPY,
154    CORR,
155    CORRESPONDING,
156    COUNT,
157    COVAR_POP,
158    COVAR_SAMP,
159    CREATE,
160    CROSS,
161    CUBE,
162    CUME_DIST,
163    CURRENT,
164    CURRENT_CATALOG,
165    CURRENT_DATE,
166    CURRENT_DEFAULT_TRANSFORM_GROUP,
167    CURRENT_PATH,
168    CURRENT_ROLE,
169    CURRENT_ROW,
170    CURRENT_SCHEMA,
171    CURRENT_TIME,
172    CURRENT_TIMESTAMP,
173    CURRENT_TRANSFORM_GROUP_FOR_TYPE,
174    CURRENT_USER,
175    CURSOR,
176    CURSORS,
177    CYCLE,
178    DATA,
179    DATABASE,
180    DATABASES,
181    DATE,
182    DAY,
183    DEALLOCATE,
184    DEC,
185    DECIMAL,
186    DECLARE,
187    DEFAULT,
188    DEFERRABLE,
189    DEFERRED,
190    DELETE,
191    DELIMITED,
192    DENSE_RANK,
193    DEREF,
194    DESC,
195    DESCRIBE,
196    DETERMINISTIC,
197    DIRECTORY,
198    DISCARD,
199    DISCONNECT,
200    DISTINCT,
201    DISTRIBUTED,
202    DO,
203    DOT,
204    DOUBLE,
205    DROP,
206    DYNAMIC,
207    EACH,
208    ELEMENT,
209    ELSE,
210    EMIT,
211    ENCODE,
212    END,
213    END_EXEC = "END-EXEC",
214    END_FRAME,
215    END_PARTITION,
216    ENGINE,
217    EQUALS,
218    ERROR,
219    ESCAPE,
220    EVENT,
221    EVERY,
222    EXCEPT,
223    EXCLUDE,
224    EXEC,
225    EXECUTE,
226    EXISTS,
227    EXP,
228    EXPLAIN,
229    EXTERNAL,
230    EXTRACT,
231    FALSE,
232    FETCH,
233    FILE,
234    FILTER,
235    FIRST,
236    FIRST_VALUE,
237    FLOAT,
238    FLOOR,
239    FLUSH,
240    FOLLOWING,
241    FOR,
242    FOREIGN,
243    FORMAT,
244    FRAGMENT,
245    FRAGMENTS,
246    FRAME_ROW,
247    FREE,
248    FREEZE,
249    FROM,
250    FULL,
251    FUNCTION,
252    FUNCTIONS,
253    FUSION,
254    GAP,
255    GET,
256    GLOBAL,
257    GRANT,
258    GRANTED,
259    GROUP,
260    GROUPING,
261    GROUPS,
262    HAVING,
263    HEADER,
264    HOLD,
265    HOUR,
266    IDENTITY,
267    IF,
268    IGNORE,
269    ILIKE,
270    IMMEDIATELY,
271    IMMUTABLE,
272    IN,
273    INCLUDE,
274    INDEX,
275    INDEXES,
276    INDICATOR,
277    INITIALLY,
278    INNER,
279    INOUT,
280    INSENSITIVE,
281    INSERT,
282    INT,
283    INTEGER,
284    INTERNAL,
285    INTERSECT,
286    INTERSECTION,
287    INTERVAL,
288    INTO,
289    IS,
290    ISNULL,
291    ISOLATION,
292    JOB,
293    JOBS,
294    JOIN,
295    JSON,
296    KEY,
297    KEYS,
298    KILL,
299    LANGUAGE,
300    LARGE,
301    LAST,
302    LATERAL,
303    LEADING,
304    LEFT,
305    LEVEL,
306    LIKE,
307    LIMIT,
308    LINK,
309    LN,
310    LOCAL,
311    LOCALTIME,
312    LOCALTIMESTAMP,
313    LOCATION,
314    LOWER,
315    MAP,
316    MATCH,
317    MATERIALIZED,
318    MAX,
319    MEMBER,
320    MERGE,
321    MESSAGE,
322    META,
323    METHOD,
324    MIN,
325    MINUTE,
326    MOD,
327    MODIFIES,
328    MODULE,
329    MONTH,
330    MULTISET,
331    NATIONAL,
332    NATIVE,
333    NATURAL,
334    NCHAR,
335    NCLOB,
336    NEW,
337    NEXT,
338    NO,
339    NONE,
340    NORMALIZE,
341    NOSCAN,
342    NOT,
343    NOTHING,
344    NOTNULL,
345    NTH_VALUE,
346    NTILE,
347    NULL,
348    NULLIF,
349    NULLS,
350    NUMERIC,
351    OBJECT,
352    OCCURRENCES_REGEX,
353    OCTET_LENGTH,
354    OF,
355    OFFSET,
356    OLD,
357    ON,
358    ONLY,
359    OPEN,
360    OPERATOR,
361    OPTION,
362    OR,
363    ORDER,
364    ORDINALITY,
365    OTHERS,
366    OUT,
367    OUTER,
368    OUTPUTFORMAT,
369    OVER,
370    OVERLAPS,
371    OVERLAY,
372    OVERWRITE,
373    OWNER,
374    PARALLELISM,
375    PARAMETER,
376    PARQUET,
377    PARTITION,
378    PARTITIONED,
379    PARTITIONS,
380    PERCENT,
381    PERCENTILE_CONT,
382    PERCENTILE_DISC,
383    PERCENT_RANK,
384    PERIOD,
385    PLACING,
386    PLAN,
387    PORTION,
388    POSITION,
389    POSITION_REGEX,
390    POWER,
391    PRECEDES,
392    PRECEDING,
393    PRECISION,
394    PREPARE,
395    PRIMARY,
396    PRIVILEGES,
397    PROCEDURE,
398    PROCESSLIST,
399    PURGE,
400    RANGE,
401    RANK,
402    RCFILE,
403    READ,
404    READS,
405    REAL,
406    RECOVER,
407    RECURSIVE,
408    REF,
409    REFERENCES,
410    REFERENCING,
411    REFRESH,
412    REGISTRY,
413    REGR_AVGX,
414    REGR_AVGY,
415    REGR_COUNT,
416    REGR_INTERCEPT,
417    REGR_R2,
418    REGR_SLOPE,
419    REGR_SXX,
420    REGR_SXY,
421    REGR_SYY,
422    RELEASE,
423    RENAME,
424    REPAIR,
425    REPEATABLE,
426    REPLACE,
427    RESET,
428    RESOURCE_GROUP,
429    RESTRICT,
430    RESULT,
431    RETENTION,
432    RETURN,
433    RETURNING,
434    RETURNS,
435    REVOKE,
436    RIGHT,
437    ROLLBACK,
438    ROLLUP,
439    ROW,
440    ROWID,
441    ROWS,
442    ROW_NUMBER,
443    RUNTIME,
444    SAVEPOINT,
445    SCALAR,
446    SCHEMA,
447    SCHEMAS,
448    SCOPE,
449    SCROLL,
450    SEARCH,
451    SECOND,
452    SECRET,
453    SECRETS,
454    SELECT,
455    SENSITIVE,
456    SEQUENCE,
457    SEQUENCEFILE,
458    SEQUENCES,
459    SERDE,
460    SERIALIZABLE,
461    SESSION,
462    SESSION_USER,
463    SET,
464    SETS,
465    SHOW,
466    SIMILAR,
467    SINCE,
468    SINK,
469    SINKS,
470    SMALLINT,
471    SNAPSHOT,
472    SNAPSHOTS,
473    SOME,
474    SORT,
475    SOURCE,
476    SOURCES,
477    SPECIFIC,
478    SPECIFICTYPE,
479    SQL,
480    SQLEXCEPTION,
481    SQLSTATE,
482    SQLWARNING,
483    SQRT,
484    STABLE,
485    START,
486    STATIC,
487    STATISTICS,
488    STDDEV_POP,
489    STDDEV_SAMP,
490    STDIN,
491    STDOUT,
492    STORED,
493    STRING,
494    STRUCT,
495    SUBMULTISET,
496    SUBSCRIPTION,
497    SUBSCRIPTIONS,
498    SUBSTRING,
499    SUBSTRING_REGEX,
500    SUCCEEDS,
501    SUM,
502    SWAP,
503    SYMMETRIC,
504    SYNC,
505    SYSTEM,
506    SYSTEM_TIME,
507    SYSTEM_USER,
508    SYSTEM_VERSION,
509    TABLE,
510    TABLES,
511    TABLESAMPLE,
512    TBLPROPERTIES,
513    TEMP,
514    TEMPORARY,
515    TEXT,
516    TEXTFILE,
517    THEN,
518    TIES,
519    TIME,
520    TIMESTAMP,
521    TIMEZONE_HOUR,
522    TIMEZONE_MINUTE,
523    TINYINT,
524    TO,
525    TOP,
526    TRAILING,
527    TRANSACTION,
528    TRANSLATE,
529    TRANSLATE_REGEX,
530    TRANSLATION,
531    TREAT,
532    TRIGGER,
533    TRIM,
534    TRIM_ARRAY,
535    TRUE,
536    TRUNCATE,
537    TRY_CAST,
538    TTL,
539    TYPE,
540    UESCAPE,
541    UNBOUNDED,
542    UNCOMMITTED,
543    UNION,
544    UNIQUE,
545    UNKNOWN,
546    UNNEST,
547    UPDATE,
548    UPPER,
549    USAGE,
550    USE,
551    USER,
552    USING,
553    UUID,
554    VACUUM,
555    VALIDATE,
556    VALUE,
557    VALUES,
558    VALUE_OF,
559    VARBINARY,
560    VARCHAR,
561    VARIADIC,
562    VARYING,
563    VAR_POP,
564    VAR_SAMP,
565    VERBOSE,
566    VERSION,
567    VERSIONING,
568    VIEW,
569    VIEWS,
570    VIRTUAL,
571    VOLATILE,
572    WAIT,
573    WATERMARK,
574    WHEN,
575    WHENEVER,
576    WHERE,
577    WIDTH_BUCKET,
578    WINDOW,
579    WITH,
580    WITHIN,
581    WITHOUT,
582    WORK,
583    WRITE,
584    XML,
585    XOR,
586    YAML,
587    YEAR,
588    ZONE
589);
590
591/// These keywords can't be used as a table alias, so that `FROM table_name alias`
592/// can be parsed unambiguously without looking ahead.
593pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
594    // Reserved as both a table and a column alias:
595    Keyword::WITH,
596    Keyword::EXPLAIN,
597    Keyword::ANALYZE,
598    Keyword::SELECT,
599    Keyword::WHERE,
600    Keyword::GROUP,
601    Keyword::SORT,
602    Keyword::HAVING,
603    Keyword::ORDER,
604    Keyword::TOP,
605    Keyword::LATERAL,
606    Keyword::VIEW,
607    Keyword::LIMIT,
608    Keyword::OFFSET,
609    Keyword::FETCH,
610    Keyword::UNION,
611    Keyword::EXCEPT,
612    Keyword::INTERSECT,
613    // Reserved only as a table alias in the `FROM`/`JOIN` clauses:
614    Keyword::ON,
615    Keyword::JOIN,
616    Keyword::INNER,
617    Keyword::CROSS,
618    Keyword::FULL,
619    Keyword::LEFT,
620    Keyword::RIGHT,
621    Keyword::NATURAL,
622    Keyword::ASOF,
623    Keyword::USING,
624    Keyword::CLUSTER,
625    // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
626    Keyword::OUTER,
627    Keyword::SET,
628    Keyword::RETURNING,
629    Keyword::EMIT,
630    Keyword::WINDOW,
631];
632
633/// Can't be used as a column alias, so that `SELECT <expr> alias`
634/// can be parsed unambiguously without looking ahead.
635pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
636    // Reserved as both a table and a column alias:
637    Keyword::WITH,
638    Keyword::EXPLAIN,
639    Keyword::ANALYZE,
640    Keyword::SELECT,
641    Keyword::WHERE,
642    Keyword::GROUP,
643    Keyword::SORT,
644    Keyword::HAVING,
645    Keyword::ORDER,
646    Keyword::TOP,
647    Keyword::LATERAL,
648    Keyword::VIEW,
649    Keyword::LIMIT,
650    Keyword::OFFSET,
651    Keyword::FETCH,
652    Keyword::UNION,
653    Keyword::EXCEPT,
654    Keyword::INTERSECT,
655    Keyword::CLUSTER,
656    // Reserved only as a column alias in the `SELECT` clause
657    Keyword::FROM,
658];
659
660/// Can't be used as a column or table name in PostgreSQL.
661///
662/// This list is taken from the following table, for all "reserved" words in the PostgreSQL column,
663/// including "can be function or type" and "requires AS". <https://www.postgresql.org/docs/14/sql-keywords-appendix.html#KEYWORDS-TABLE>
664///
665/// `SELECT` and `WITH` were commented out because the following won't parse:
666/// `SELECT (SELECT 1)` or `SELECT (WITH a AS (SELECT 1) SELECT 1)`
667///
668/// Other commented ones like `CURRENT_SCHEMA` are actually functions invoked without parentheses.
669pub const RESERVED_FOR_COLUMN_OR_TABLE_NAME: &[Keyword] = &[
670    Keyword::ALL,
671    Keyword::ANALYSE,
672    Keyword::ANALYZE,
673    Keyword::AND,
674    Keyword::ANY,
675    Keyword::ARRAY,
676    Keyword::AS,
677    Keyword::ASC,
678    Keyword::ASYMMETRIC,
679    Keyword::AUTHORIZATION,
680    Keyword::BINARY,
681    Keyword::BOTH,
682    Keyword::CASE,
683    Keyword::CAST,
684    Keyword::CHECK,
685    Keyword::COLLATE,
686    Keyword::COLLATION,
687    Keyword::COLUMN,
688    Keyword::CONCURRENTLY,
689    Keyword::CONSTRAINT,
690    Keyword::CREATE,
691    Keyword::CROSS,
692    // Keyword::CURRENT_CATALOG,
693    // Keyword::CURRENT_DATE,
694    // Keyword::CURRENT_ROLE,
695    // Keyword::CURRENT_SCHEMA,
696    // Keyword::CURRENT_TIME,
697    // Keyword::CURRENT_TIMESTAMP,
698    // Keyword::CURRENT_USER,
699    Keyword::DEFAULT,
700    Keyword::DEFERRABLE,
701    Keyword::DESC,
702    Keyword::DISTINCT,
703    Keyword::DO,
704    Keyword::ELSE,
705    Keyword::END,
706    Keyword::EXCEPT,
707    Keyword::FALSE,
708    Keyword::FETCH,
709    Keyword::FOR,
710    Keyword::FOREIGN,
711    Keyword::FREEZE,
712    Keyword::FROM,
713    Keyword::FULL,
714    Keyword::GRANT,
715    Keyword::GROUP,
716    Keyword::HAVING,
717    Keyword::ILIKE,
718    Keyword::IN,
719    Keyword::INITIALLY,
720    Keyword::INNER,
721    Keyword::INTERSECT,
722    Keyword::INTO,
723    Keyword::IS,
724    Keyword::ISNULL,
725    Keyword::JOIN,
726    Keyword::LATERAL,
727    Keyword::LEADING,
728    Keyword::LEFT,
729    Keyword::LIKE,
730    Keyword::LIMIT,
731    // Keyword::LOCALTIME,
732    // Keyword::LOCALTIMESTAMP,
733    Keyword::NATURAL,
734    Keyword::NOT,
735    Keyword::NOTNULL,
736    Keyword::NULL,
737    Keyword::OFFSET,
738    Keyword::ON,
739    Keyword::ONLY,
740    Keyword::OR,
741    Keyword::ORDER,
742    Keyword::OUTER,
743    Keyword::OVERLAPS,
744    Keyword::PLACING,
745    Keyword::PRIMARY,
746    Keyword::REFERENCES,
747    Keyword::RETURNING,
748    Keyword::RIGHT,
749    // Keyword::SELECT,
750    // Keyword::SESSION_USER,
751    Keyword::SIMILAR,
752    Keyword::SOME,
753    Keyword::SYMMETRIC,
754    Keyword::TABLE,
755    Keyword::TABLESAMPLE,
756    Keyword::THEN,
757    Keyword::TO,
758    Keyword::TRAILING,
759    Keyword::TRUE,
760    Keyword::UNION,
761    Keyword::UNIQUE,
762    // Keyword::USER,
763    Keyword::USING,
764    Keyword::VARIADIC,
765    Keyword::VERBOSE,
766    Keyword::WHEN,
767    Keyword::WHERE,
768    Keyword::WINDOW,
769    // Keyword::WITH,
770];
771
772impl fmt::Display for Keyword {
773    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
774        write!(f, "{:?}", self)
775    }
776}