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