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    BACKFILL,
100    BASE64,
101    BEGIN,
102    BEGIN_FRAME,
103    BEGIN_PARTITION,
104    BETWEEN,
105    BIGINT,
106    BINARY,
107    BIT_LENGTH,
108    BLOB,
109    BOOL,
110    BOOLEAN,
111    BOTH,
112    BY,
113    BYTEA,
114    CACHE,
115    CALL,
116    CALLED,
117    CANCEL,
118    CARDINALITY,
119    CASCADE,
120    CASCADED,
121    CASE,
122    CAST,
123    CEIL,
124    CEILING,
125    CHAIN,
126    CHAR,
127    CHARACTER,
128    CHARACTERISTICS,
129    CHARACTER_LENGTH,
130    CHAR_LENGTH,
131    CHECK,
132    CLOB,
133    CLOSE,
134    CLUSTER,
135    COALESCE,
136    COLLATE,
137    COLLATION,
138    COLLECT,
139    COLUMN,
140    COLUMNS,
141    COMMENT,
142    COMMIT,
143    COMMITTED,
144    CONCURRENTLY,
145    CONDITION,
146    CONFLICT,
147    CONFLUENT,
148    CONNECT,
149    CONNECTION,
150    CONNECTIONS,
151    CONNECTOR,
152    CONSTRAINT,
153    CONTAINS,
154    CONVERT,
155    COPY,
156    CORR,
157    CORRESPONDING,
158    COUNT,
159    COVAR_POP,
160    COVAR_SAMP,
161    CREATE,
162    CROSS,
163    CUBE,
164    CUME_DIST,
165    CURRENT,
166    CURRENT_CATALOG,
167    CURRENT_DATE,
168    CURRENT_DEFAULT_TRANSFORM_GROUP,
169    CURRENT_PATH,
170    CURRENT_ROLE,
171    CURRENT_ROW,
172    CURRENT_SCHEMA,
173    CURRENT_TIME,
174    CURRENT_TIMESTAMP,
175    CURRENT_TRANSFORM_GROUP_FOR_TYPE,
176    CURRENT_USER,
177    CURSOR,
178    CURSORS,
179    CYCLE,
180    DATA,
181    DATABASE,
182    DATABASES,
183    DATE,
184    DAY,
185    DEALLOCATE,
186    DEC,
187    DECIMAL,
188    DECLARE,
189    DEFAULT,
190    DEFERRABLE,
191    DEFERRED,
192    DELETE,
193    DELIMITED,
194    DENSE_RANK,
195    DEREF,
196    DESC,
197    DESCRIBE,
198    DETERMINISTIC,
199    DIRECTORY,
200    DISCARD,
201    DISCONNECT,
202    DISTINCT,
203    DISTRIBUTED,
204    DISTSQL,
205    DO,
206    DOT,
207    DOUBLE,
208    DROP,
209    DURATION_SECS,
210    DYNAMIC,
211    EACH,
212    ELEMENT,
213    ELSE,
214    EMIT,
215    ENCODE,
216    END,
217    END_EXEC = "END-EXEC",
218    END_FRAME,
219    END_PARTITION,
220    ENGINE,
221    EQUALS,
222    ERROR,
223    ESCAPE,
224    EVENT,
225    EVERY,
226    EXCEPT,
227    EXCLUDE,
228    EXEC,
229    EXECUTE,
230    EXISTS,
231    EXP,
232    EXPLAIN,
233    EXTERNAL,
234    EXTRACT,
235    FALSE,
236    FETCH,
237    FILE,
238    FILTER,
239    FIRST,
240    FIRST_VALUE,
241    FLOAT,
242    FLOOR,
243    FLUSH,
244    FOLLOWING,
245    FOR,
246    FOREIGN,
247    FORMAT,
248    FRAGMENT,
249    FRAGMENTS,
250    FRAME_ROW,
251    FREE,
252    FREEZE,
253    FROM,
254    FULL,
255    FUNCTION,
256    FUNCTIONS,
257    FUSION,
258    GAP,
259    GET,
260    GLOBAL,
261    GRANT,
262    GRANTED,
263    GROUP,
264    GROUPING,
265    GROUPS,
266    HAVING,
267    HEADER,
268    HOLD,
269    HOUR,
270    IDENTITY,
271    IF,
272    IGNORE,
273    ILIKE,
274    IMMEDIATELY,
275    IMMUTABLE,
276    IN,
277    INCLUDE,
278    INDEX,
279    INDEXES,
280    INDICATOR,
281    INITIALLY,
282    INNER,
283    INOUT,
284    INSENSITIVE,
285    INSERT,
286    INT,
287    INTEGER,
288    INTERNAL,
289    INTERSECT,
290    INTERSECTION,
291    INTERVAL,
292    INTO,
293    IS,
294    ISNULL,
295    ISOLATION,
296    JOB,
297    JOBS,
298    JOIN,
299    JSON,
300    KEY,
301    KEYS,
302    KILL,
303    LANGUAGE,
304    LARGE,
305    LAST,
306    LATERAL,
307    LEADING,
308    LEFT,
309    LEVEL,
310    LIKE,
311    LIMIT,
312    LINK,
313    LN,
314    LOCAL,
315    LOCALTIME,
316    LOCALTIMESTAMP,
317    LOCATION,
318    LOGICAL,
319    LOWER,
320    MAP,
321    MATCH,
322    MATERIALIZED,
323    MAX,
324    MEMBER,
325    MERGE,
326    MESSAGE,
327    METHOD,
328    MIN,
329    MINUTE,
330    MOD,
331    MODIFIES,
332    MODULE,
333    MONTH,
334    MULTISET,
335    NATIONAL,
336    NATIVE,
337    NATURAL,
338    NCHAR,
339    NCLOB,
340    NEW,
341    NEXT,
342    NO,
343    NONE,
344    NORMALIZE,
345    NOSCAN,
346    NOT,
347    NOTHING,
348    NOTNULL,
349    NTH_VALUE,
350    NTILE,
351    NULL,
352    NULLIF,
353    NULLS,
354    NUMERIC,
355    OBJECT,
356    OCCURRENCES_REGEX,
357    OCTET_LENGTH,
358    OF,
359    OFFSET,
360    OLD,
361    ON,
362    ONLY,
363    OPEN,
364    OPERATOR,
365    OPTION,
366    OR,
367    ORDER,
368    ORDINALITY,
369    OTHERS,
370    OUT,
371    OUTER,
372    OUTPUTFORMAT,
373    OVER,
374    OVERLAPS,
375    OVERLAY,
376    OVERWRITE,
377    OWNER,
378    PARALLELISM,
379    PARAMETER,
380    PARQUET,
381    PARTITION,
382    PARTITIONED,
383    PARTITIONS,
384    PERCENT,
385    PERCENTILE_CONT,
386    PERCENTILE_DISC,
387    PERCENT_RANK,
388    PERIOD,
389    PHYSICAL,
390    PLACING,
391    PLAN,
392    PORTION,
393    POSITION,
394    POSITION_REGEX,
395    POWER,
396    PRECEDES,
397    PRECEDING,
398    PRECISION,
399    PREPARE,
400    PRIMARY,
401    PRIVILEGES,
402    PROCEDURE,
403    PROCESSLIST,
404    PURGE,
405    RANGE,
406    RANK,
407    RCFILE,
408    READ,
409    READS,
410    REAL,
411    RECOVER,
412    RECURSIVE,
413    REF,
414    REFERENCES,
415    REFERENCING,
416    REFRESH,
417    REGISTRY,
418    REGR_AVGX,
419    REGR_AVGY,
420    REGR_COUNT,
421    REGR_INTERCEPT,
422    REGR_R2,
423    REGR_SLOPE,
424    REGR_SXX,
425    REGR_SXY,
426    REGR_SYY,
427    RELEASE,
428    RENAME,
429    REPAIR,
430    REPEATABLE,
431    REPLACE,
432    RESET,
433    RESOURCE_GROUP,
434    RESTRICT,
435    RESULT,
436    RETURN,
437    RETURNING,
438    RETURNS,
439    REVOKE,
440    RIGHT,
441    ROLLBACK,
442    ROLLUP,
443    ROW,
444    ROWID,
445    ROWS,
446    ROW_NUMBER,
447    RUNTIME,
448    SAVEPOINT,
449    SCALAR,
450    SCHEMA,
451    SCHEMAS,
452    SCOPE,
453    SCROLL,
454    SEARCH,
455    SECOND,
456    SECRET,
457    SECRETS,
458    SELECT,
459    SENSITIVE,
460    SEQUENCE,
461    SEQUENCEFILE,
462    SEQUENCES,
463    SERDE,
464    SERIALIZABLE,
465    SESSION,
466    SESSION_USER,
467    SET,
468    SETS,
469    SHOW,
470    SIMILAR,
471    SINCE,
472    SINK,
473    SINKS,
474    SMALLINT,
475    SNAPSHOT,
476    SOME,
477    SORT,
478    SOURCE,
479    SOURCES,
480    SPECIFIC,
481    SPECIFICTYPE,
482    SQL,
483    SQLEXCEPTION,
484    SQLSTATE,
485    SQLWARNING,
486    SQRT,
487    STABLE,
488    START,
489    STATIC,
490    STATISTICS,
491    STDDEV_POP,
492    STDDEV_SAMP,
493    STDIN,
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    TRACE,
529    TRAILING,
530    TRANSACTION,
531    TRANSLATE,
532    TRANSLATE_REGEX,
533    TRANSLATION,
534    TREAT,
535    TRIGGER,
536    TRIM,
537    TRIM_ARRAY,
538    TRUE,
539    TRUNCATE,
540    TRY_CAST,
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}