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