Skip to main content

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    ORPHAN,
367    OTHERS,
368    OUT,
369    OUTER,
370    OUTPUTFORMAT,
371    OVER,
372    OVERLAPS,
373    OVERLAY,
374    OVERWRITE,
375    OWNER,
376    PARALLELISM,
377    PARAMETER,
378    PARQUET,
379    PARTITION,
380    PARTITIONED,
381    PARTITIONS,
382    PERCENT,
383    PERCENTILE_CONT,
384    PERCENTILE_DISC,
385    PERCENT_RANK,
386    PERIOD,
387    PLACING,
388    PLAN,
389    PORTION,
390    POSITION,
391    POSITION_REGEX,
392    POWER,
393    PRECEDES,
394    PRECEDING,
395    PRECISION,
396    PREPARE,
397    PRIMARY,
398    PRIVILEGES,
399    PROCEDURE,
400    PROCESSLIST,
401    PURGE,
402    RANGE,
403    RANK,
404    RCFILE,
405    READ,
406    READS,
407    REAL,
408    RECOVER,
409    RECURSIVE,
410    REF,
411    REFERENCES,
412    REFERENCING,
413    REFRESH,
414    REGISTRY,
415    REGR_AVGX,
416    REGR_AVGY,
417    REGR_COUNT,
418    REGR_INTERCEPT,
419    REGR_R2,
420    REGR_SLOPE,
421    REGR_SXX,
422    REGR_SXY,
423    REGR_SYY,
424    RELEASE,
425    RENAME,
426    REPAIR,
427    REPEATABLE,
428    REPLACE,
429    RESET,
430    RESOURCE_GROUP,
431    RESTRICT,
432    RESULT,
433    RETENTION,
434    RETURN,
435    RETURNING,
436    RETURNS,
437    REVOKE,
438    RIGHT,
439    ROLLBACK,
440    ROLLUP,
441    ROW,
442    ROWID,
443    ROWS,
444    ROW_NUMBER,
445    RUNTIME,
446    SAVEPOINT,
447    SCALAR,
448    SCHEMA,
449    SCHEMAS,
450    SCOPE,
451    SCROLL,
452    SEARCH,
453    SECOND,
454    SECRET,
455    SECRETS,
456    SELECT,
457    SENSITIVE,
458    SEQUENCE,
459    SEQUENCEFILE,
460    SEQUENCES,
461    SERDE,
462    SERIALIZABLE,
463    SESSION,
464    SESSION_USER,
465    SET,
466    SETS,
467    SHOW,
468    SIMILAR,
469    SINCE,
470    SINK,
471    SINKS,
472    SMALLINT,
473    SNAPSHOT,
474    SNAPSHOTS,
475    SOME,
476    SORT,
477    SOURCE,
478    SOURCES,
479    SPECIFIC,
480    SPECIFICTYPE,
481    SQL,
482    SQLEXCEPTION,
483    SQLSTATE,
484    SQLWARNING,
485    SQRT,
486    STABLE,
487    START,
488    STATIC,
489    STATISTICS,
490    STDDEV_POP,
491    STDDEV_SAMP,
492    STDIN,
493    STDOUT,
494    STORED,
495    STRING,
496    STRUCT,
497    SUBMULTISET,
498    SUBSCRIPTION,
499    SUBSCRIPTIONS,
500    SUBSTRING,
501    SUBSTRING_REGEX,
502    SUCCEEDS,
503    SUM,
504    SWAP,
505    SYMMETRIC,
506    SYNC,
507    SYSTEM,
508    SYSTEM_TIME,
509    SYSTEM_USER,
510    SYSTEM_VERSION,
511    TABLE,
512    TABLES,
513    TABLESAMPLE,
514    TBLPROPERTIES,
515    TEMP,
516    TEMPORARY,
517    TEXT,
518    TEXTFILE,
519    THEN,
520    TIES,
521    TIME,
522    TIMESTAMP,
523    TIMEZONE_HOUR,
524    TIMEZONE_MINUTE,
525    TINYINT,
526    TO,
527    TOP,
528    TRAILING,
529    TRANSACTION,
530    TRANSLATE,
531    TRANSLATE_REGEX,
532    TRANSLATION,
533    TREAT,
534    TRIGGER,
535    TRIM,
536    TRIM_ARRAY,
537    TRUE,
538    TRUNCATE,
539    TRY_CAST,
540    TTL,
541    TYPE,
542    UESCAPE,
543    UNBOUNDED,
544    UNCOMMITTED,
545    UNION,
546    UNIQUE,
547    UNKNOWN,
548    UNNEST,
549    UPDATE,
550    UPPER,
551    USAGE,
552    USE,
553    USER,
554    USING,
555    UUID,
556    VACUUM,
557    VALIDATE,
558    VALUE,
559    VALUES,
560    VALUE_OF,
561    VARBINARY,
562    VARCHAR,
563    VARIADIC,
564    VARYING,
565    VAR_POP,
566    VAR_SAMP,
567    VERBOSE,
568    VERSION,
569    VERSIONING,
570    VIEW,
571    VIEWS,
572    VIRTUAL,
573    VOLATILE,
574    WAIT,
575    WATERMARK,
576    WHEN,
577    WHENEVER,
578    WHERE,
579    WIDTH_BUCKET,
580    WINDOW,
581    WITH,
582    WITHIN,
583    WITHOUT,
584    WORK,
585    WRITE,
586    XML,
587    XOR,
588    YAML,
589    YEAR,
590    ZONE
591);
592
593/// These keywords can't be used as a table alias, so that `FROM table_name alias`
594/// can be parsed unambiguously without looking ahead.
595pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
596    // Reserved as both a table and a column alias:
597    Keyword::WITH,
598    Keyword::EXPLAIN,
599    Keyword::ANALYZE,
600    Keyword::SELECT,
601    Keyword::WHERE,
602    Keyword::GROUP,
603    Keyword::SORT,
604    Keyword::HAVING,
605    Keyword::ORDER,
606    Keyword::TOP,
607    Keyword::LATERAL,
608    Keyword::VIEW,
609    Keyword::LIMIT,
610    Keyword::OFFSET,
611    Keyword::FETCH,
612    Keyword::UNION,
613    Keyword::EXCEPT,
614    Keyword::INTERSECT,
615    // Reserved only as a table alias in the `FROM`/`JOIN` clauses:
616    Keyword::ON,
617    Keyword::JOIN,
618    Keyword::INNER,
619    Keyword::CROSS,
620    Keyword::FULL,
621    Keyword::LEFT,
622    Keyword::RIGHT,
623    Keyword::NATURAL,
624    Keyword::ASOF,
625    Keyword::USING,
626    Keyword::CLUSTER,
627    // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
628    Keyword::OUTER,
629    Keyword::SET,
630    Keyword::RETURNING,
631    Keyword::EMIT,
632    Keyword::WINDOW,
633];
634
635/// Can't be used as a column alias, so that `SELECT <expr> alias`
636/// can be parsed unambiguously without looking ahead.
637pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
638    // Reserved as both a table and a column alias:
639    Keyword::WITH,
640    Keyword::EXPLAIN,
641    Keyword::ANALYZE,
642    Keyword::SELECT,
643    Keyword::WHERE,
644    Keyword::GROUP,
645    Keyword::SORT,
646    Keyword::HAVING,
647    Keyword::ORDER,
648    Keyword::TOP,
649    Keyword::LATERAL,
650    Keyword::VIEW,
651    Keyword::LIMIT,
652    Keyword::OFFSET,
653    Keyword::FETCH,
654    Keyword::UNION,
655    Keyword::EXCEPT,
656    Keyword::INTERSECT,
657    Keyword::CLUSTER,
658    // Reserved only as a column alias in the `SELECT` clause
659    Keyword::FROM,
660];
661
662/// Can't be used as a column or table name in PostgreSQL.
663///
664/// This list is taken from the following table, for all "reserved" words in the PostgreSQL column,
665/// including "can be function or type" and "requires AS". <https://www.postgresql.org/docs/14/sql-keywords-appendix.html#KEYWORDS-TABLE>
666///
667/// `SELECT` and `WITH` were commented out because the following won't parse:
668/// `SELECT (SELECT 1)` or `SELECT (WITH a AS (SELECT 1) SELECT 1)`
669///
670/// Other commented ones like `CURRENT_SCHEMA` are actually functions invoked without parentheses.
671pub const RESERVED_FOR_COLUMN_OR_TABLE_NAME: &[Keyword] = &[
672    Keyword::ALL,
673    Keyword::ANALYSE,
674    Keyword::ANALYZE,
675    Keyword::AND,
676    Keyword::ANY,
677    Keyword::ARRAY,
678    Keyword::AS,
679    Keyword::ASC,
680    Keyword::ASYMMETRIC,
681    Keyword::AUTHORIZATION,
682    Keyword::BINARY,
683    Keyword::BOTH,
684    Keyword::CASE,
685    Keyword::CAST,
686    Keyword::CHECK,
687    Keyword::COLLATE,
688    Keyword::COLLATION,
689    Keyword::COLUMN,
690    Keyword::CONCURRENTLY,
691    Keyword::CONSTRAINT,
692    Keyword::CREATE,
693    Keyword::CROSS,
694    // Keyword::CURRENT_CATALOG,
695    // Keyword::CURRENT_DATE,
696    // Keyword::CURRENT_ROLE,
697    // Keyword::CURRENT_SCHEMA,
698    // Keyword::CURRENT_TIME,
699    // Keyword::CURRENT_TIMESTAMP,
700    // Keyword::CURRENT_USER,
701    Keyword::DEFAULT,
702    Keyword::DEFERRABLE,
703    Keyword::DESC,
704    Keyword::DISTINCT,
705    Keyword::DO,
706    Keyword::ELSE,
707    Keyword::END,
708    Keyword::EXCEPT,
709    Keyword::FALSE,
710    Keyword::FETCH,
711    Keyword::FOR,
712    Keyword::FOREIGN,
713    Keyword::FREEZE,
714    Keyword::FROM,
715    Keyword::FULL,
716    Keyword::GRANT,
717    Keyword::GROUP,
718    Keyword::HAVING,
719    Keyword::ILIKE,
720    Keyword::IN,
721    Keyword::INITIALLY,
722    Keyword::INNER,
723    Keyword::INTERSECT,
724    Keyword::INTO,
725    Keyword::IS,
726    Keyword::ISNULL,
727    Keyword::JOIN,
728    Keyword::LATERAL,
729    Keyword::LEADING,
730    Keyword::LEFT,
731    Keyword::LIKE,
732    Keyword::LIMIT,
733    // Keyword::LOCALTIME,
734    // Keyword::LOCALTIMESTAMP,
735    Keyword::NATURAL,
736    Keyword::NOT,
737    Keyword::NOTNULL,
738    Keyword::NULL,
739    Keyword::OFFSET,
740    Keyword::ON,
741    Keyword::ONLY,
742    Keyword::OR,
743    Keyword::ORDER,
744    Keyword::OUTER,
745    Keyword::OVERLAPS,
746    Keyword::PLACING,
747    Keyword::PRIMARY,
748    Keyword::REFERENCES,
749    Keyword::RETURNING,
750    Keyword::RIGHT,
751    // Keyword::SELECT,
752    // Keyword::SESSION_USER,
753    Keyword::SIMILAR,
754    Keyword::SOME,
755    Keyword::SYMMETRIC,
756    Keyword::TABLE,
757    Keyword::TABLESAMPLE,
758    Keyword::THEN,
759    Keyword::TO,
760    Keyword::TRAILING,
761    Keyword::TRUE,
762    Keyword::UNION,
763    Keyword::UNIQUE,
764    // Keyword::USER,
765    Keyword::USING,
766    Keyword::VARIADIC,
767    Keyword::VERBOSE,
768    Keyword::WHEN,
769    Keyword::WHERE,
770    Keyword::WINDOW,
771    // Keyword::WITH,
772];
773
774impl fmt::Display for Keyword {
775    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
776        write!(f, "{:?}", self)
777    }
778}