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