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 core::fmt;
29
30#[cfg(feature = "serde")]
31use serde::{Deserialize, Serialize};
32
33/// Defines a string constant for a single keyword: `kw_def!(SELECT);`
34/// expands to `pub const SELECT = "SELECT";`
35macro_rules! kw_def {
36    ($ident:ident = $string_keyword:expr) => {
37        pub const $ident: &'static str = $string_keyword;
38    };
39    ($ident:ident) => {
40        kw_def!($ident = stringify!($ident));
41    };
42}
43
44/// Expands to a list of `kw_def!()` invocations for each keyword
45/// and defines an ALL_KEYWORDS array of the defined constants.
46macro_rules! define_keywords {
47    ($(
48        $ident:ident $(= $string_keyword:expr)?
49    ),*) => {
50        #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
51        #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
52        #[expect(non_camel_case_types, clippy::enum_variant_names)]
53        pub enum Keyword {
54            NoKeyword,
55            $($ident),*
56        }
57
58        pub const ALL_KEYWORDS_INDEX: &[Keyword] = &[
59            $(Keyword::$ident),*
60        ];
61
62        $(kw_def!($ident $(= $string_keyword)?);)*
63        pub const ALL_KEYWORDS: &[&'static str] = &[
64            $($ident),*
65        ];
66    };
67}
68
69// The following keywords should be sorted to be able to match using binary search
70define_keywords!(
71    ABORT,
72    ABS,
73    ACTION,
74    ADAPTIVE,
75    ADD,
76    AGGREGATE,
77    ALL,
78    ALLOCATE,
79    ALTER,
80    ANALYSE,
81    ANALYZE,
82    AND,
83    ANY,
84    APPEND,
85    ARE,
86    ARRAY,
87    ARRAY_AGG,
88    ARRAY_MAX_CARDINALITY,
89    AS,
90    ASC,
91    ASENSITIVE,
92    ASOF,
93    ASYMMETRIC,
94    AT,
95    ATOMIC,
96    AUTHORIZATION,
97    AUTO,
98    AVG,
99    BASE64,
100    BEGIN,
101    BEGIN_FRAME,
102    BEGIN_PARTITION,
103    BETWEEN,
104    BIGINT,
105    BINARY,
106    BIT_LENGTH,
107    BLOB,
108    BOOL,
109    BOOLEAN,
110    BOTH,
111    BY,
112    BYTEA,
113    CACHE,
114    CALL,
115    CALLED,
116    CANCEL,
117    CARDINALITY,
118    CASCADE,
119    CASCADED,
120    CASE,
121    CAST,
122    CEIL,
123    CEILING,
124    CHAIN,
125    CHAR,
126    CHARACTER,
127    CHARACTERISTICS,
128    CHARACTER_LENGTH,
129    CHAR_LENGTH,
130    CHECK,
131    CLOB,
132    CLOSE,
133    CLUSTER,
134    COALESCE,
135    COLLATE,
136    COLLATION,
137    COLLECT,
138    COLUMN,
139    COLUMNS,
140    COMMENT,
141    COMMIT,
142    COMMITTED,
143    CONCURRENTLY,
144    CONDITION,
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    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    RETURN,
432    RETURNING,
433    RETURNS,
434    REVOKE,
435    RIGHT,
436    ROLLBACK,
437    ROLLUP,
438    ROW,
439    ROWID,
440    ROWS,
441    ROW_NUMBER,
442    RUNTIME,
443    SAVEPOINT,
444    SCALAR,
445    SCHEMA,
446    SCHEMAS,
447    SCOPE,
448    SCROLL,
449    SEARCH,
450    SECOND,
451    SECRET,
452    SECRETS,
453    SELECT,
454    SENSITIVE,
455    SEQUENCE,
456    SEQUENCEFILE,
457    SEQUENCES,
458    SERDE,
459    SERIALIZABLE,
460    SESSION,
461    SESSION_USER,
462    SET,
463    SETS,
464    SHOW,
465    SIMILAR,
466    SINCE,
467    SINK,
468    SINKS,
469    SMALLINT,
470    SNAPSHOT,
471    SOME,
472    SORT,
473    SOURCE,
474    SOURCES,
475    SPECIFIC,
476    SPECIFICTYPE,
477    SQL,
478    SQLEXCEPTION,
479    SQLSTATE,
480    SQLWARNING,
481    SQRT,
482    STABLE,
483    START,
484    STATIC,
485    STATISTICS,
486    STDDEV_POP,
487    STDDEV_SAMP,
488    STDIN,
489    STDOUT,
490    STORED,
491    STRING,
492    STRUCT,
493    SUBMULTISET,
494    SUBSCRIPTION,
495    SUBSCRIPTIONS,
496    SUBSTRING,
497    SUBSTRING_REGEX,
498    SUCCEEDS,
499    SUM,
500    SWAP,
501    SYMMETRIC,
502    SYNC,
503    SYSTEM,
504    SYSTEM_TIME,
505    SYSTEM_USER,
506    SYSTEM_VERSION,
507    TABLE,
508    TABLES,
509    TABLESAMPLE,
510    TBLPROPERTIES,
511    TEMP,
512    TEMPORARY,
513    TEXT,
514    TEXTFILE,
515    THEN,
516    TIES,
517    TIME,
518    TIMESTAMP,
519    TIMEZONE_HOUR,
520    TIMEZONE_MINUTE,
521    TINYINT,
522    TO,
523    TOP,
524    TRAILING,
525    TRANSACTION,
526    TRANSLATE,
527    TRANSLATE_REGEX,
528    TRANSLATION,
529    TREAT,
530    TRIGGER,
531    TRIM,
532    TRIM_ARRAY,
533    TRUE,
534    TRUNCATE,
535    TRY_CAST,
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}