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