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    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    LOGIN,
320    LOWER,
321    MAP,
322    MATCH,
323    MATERIALIZED,
324    MAX,
325    MEMBER,
326    MERGE,
327    MESSAGE,
328    METHOD,
329    MIN,
330    MINUTE,
331    MOD,
332    MODIFIES,
333    MODULE,
334    MONTH,
335    MULTISET,
336    NATIONAL,
337    NATIVE,
338    NATURAL,
339    NCHAR,
340    NCLOB,
341    NEW,
342    NEXT,
343    NO,
344    NOCREATEDB,
345    NOCREATEUSER,
346    NOLOGIN,
347    NONE,
348    NORMALIZE,
349    NOSCAN,
350    NOSUPERUSER,
351    NOT,
352    NOTHING,
353    NOTNULL,
354    NTH_VALUE,
355    NTILE,
356    NULL,
357    NULLIF,
358    NULLS,
359    NUMERIC,
360    OAUTH,
361    OBJECT,
362    OCCURRENCES_REGEX,
363    OCTET_LENGTH,
364    OF,
365    OFFSET,
366    OLD,
367    ON,
368    ONLY,
369    OPEN,
370    OPERATOR,
371    OPTION,
372    OR,
373    ORDER,
374    ORDINALITY,
375    OTHERS,
376    OUT,
377    OUTER,
378    OUTPUTFORMAT,
379    OVER,
380    OVERLAPS,
381    OVERLAY,
382    OVERWRITE,
383    OWNER,
384    PARALLELISM,
385    PARAMETER,
386    PARQUET,
387    PARTITION,
388    PARTITIONED,
389    PARTITIONS,
390    PASSWORD,
391    PERCENT,
392    PERCENTILE_CONT,
393    PERCENTILE_DISC,
394    PERCENT_RANK,
395    PERIOD,
396    PHYSICAL,
397    PLACING,
398    PORTION,
399    POSITION,
400    POSITION_REGEX,
401    POWER,
402    PRECEDES,
403    PRECEDING,
404    PRECISION,
405    PREPARE,
406    PRIMARY,
407    PRIVILEGES,
408    PROCEDURE,
409    PROCESSLIST,
410    PURGE,
411    RANGE,
412    RANK,
413    RCFILE,
414    READ,
415    READS,
416    REAL,
417    RECOVER,
418    RECURSIVE,
419    REF,
420    REFERENCES,
421    REFERENCING,
422    REFRESH,
423    REGISTRY,
424    REGR_AVGX,
425    REGR_AVGY,
426    REGR_COUNT,
427    REGR_INTERCEPT,
428    REGR_R2,
429    REGR_SLOPE,
430    REGR_SXX,
431    REGR_SXY,
432    REGR_SYY,
433    RELEASE,
434    RENAME,
435    REPAIR,
436    REPEATABLE,
437    REPLACE,
438    RESET,
439    RESOURCE_GROUP,
440    RESTRICT,
441    RESULT,
442    RETURN,
443    RETURNING,
444    RETURNS,
445    REVOKE,
446    RIGHT,
447    ROLLBACK,
448    ROLLUP,
449    ROW,
450    ROWID,
451    ROWS,
452    ROW_NUMBER,
453    RUNTIME,
454    SAVEPOINT,
455    SCALAR,
456    SCHEMA,
457    SCHEMAS,
458    SCOPE,
459    SCROLL,
460    SEARCH,
461    SECOND,
462    SECRET,
463    SECRETS,
464    SELECT,
465    SENSITIVE,
466    SEQUENCE,
467    SEQUENCEFILE,
468    SEQUENCES,
469    SERDE,
470    SERIALIZABLE,
471    SESSION,
472    SESSION_USER,
473    SET,
474    SETS,
475    SHOW,
476    SIMILAR,
477    SINCE,
478    SINK,
479    SINKS,
480    SMALLINT,
481    SNAPSHOT,
482    SOME,
483    SORT,
484    SOURCE,
485    SOURCES,
486    SPECIFIC,
487    SPECIFICTYPE,
488    SQL,
489    SQLEXCEPTION,
490    SQLSTATE,
491    SQLWARNING,
492    SQRT,
493    STABLE,
494    START,
495    STATIC,
496    STATISTICS,
497    STDDEV_POP,
498    STDDEV_SAMP,
499    STDIN,
500    STORED,
501    STRING,
502    STRUCT,
503    SUBMULTISET,
504    SUBSCRIPTION,
505    SUBSCRIPTIONS,
506    SUBSTRING,
507    SUBSTRING_REGEX,
508    SUCCEEDS,
509    SUM,
510    SUPERUSER,
511    SWAP,
512    SYMMETRIC,
513    SYNC,
514    SYSTEM,
515    SYSTEM_TIME,
516    SYSTEM_USER,
517    SYSTEM_VERSION,
518    TABLE,
519    TABLES,
520    TABLESAMPLE,
521    TBLPROPERTIES,
522    TEMP,
523    TEMPORARY,
524    TEXT,
525    TEXTFILE,
526    THEN,
527    TIES,
528    TIME,
529    TIMESTAMP,
530    TIMEZONE_HOUR,
531    TIMEZONE_MINUTE,
532    TINYINT,
533    TO,
534    TOP,
535    TRACE,
536    TRAILING,
537    TRANSACTION,
538    TRANSLATE,
539    TRANSLATE_REGEX,
540    TRANSLATION,
541    TREAT,
542    TRIGGER,
543    TRIM,
544    TRIM_ARRAY,
545    TRUE,
546    TRUNCATE,
547    TRY_CAST,
548    TYPE,
549    UESCAPE,
550    UNBOUNDED,
551    UNCOMMITTED,
552    UNION,
553    UNIQUE,
554    UNKNOWN,
555    UNNEST,
556    UPDATE,
557    UPPER,
558    USAGE,
559    USE,
560    USER,
561    USING,
562    UUID,
563    VALIDATE,
564    VALUE,
565    VALUES,
566    VALUE_OF,
567    VARBINARY,
568    VARCHAR,
569    VARIADIC,
570    VARYING,
571    VAR_POP,
572    VAR_SAMP,
573    VERBOSE,
574    VERSION,
575    VERSIONING,
576    VIEW,
577    VIEWS,
578    VIRTUAL,
579    VOLATILE,
580    WAIT,
581    WATERMARK,
582    WHEN,
583    WHENEVER,
584    WHERE,
585    WIDTH_BUCKET,
586    WINDOW,
587    WITH,
588    WITHIN,
589    WITHOUT,
590    WORK,
591    WRITE,
592    XML,
593    XOR,
594    YAML,
595    YEAR,
596    ZONE
597);
598
599/// These keywords can't be used as a table alias, so that `FROM table_name alias`
600/// can be parsed unambiguously without looking ahead.
601pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
602    // Reserved as both a table and a column alias:
603    Keyword::WITH,
604    Keyword::EXPLAIN,
605    Keyword::ANALYZE,
606    Keyword::SELECT,
607    Keyword::WHERE,
608    Keyword::GROUP,
609    Keyword::SORT,
610    Keyword::HAVING,
611    Keyword::ORDER,
612    Keyword::TOP,
613    Keyword::LATERAL,
614    Keyword::VIEW,
615    Keyword::LIMIT,
616    Keyword::OFFSET,
617    Keyword::FETCH,
618    Keyword::UNION,
619    Keyword::EXCEPT,
620    Keyword::INTERSECT,
621    // Reserved only as a table alias in the `FROM`/`JOIN` clauses:
622    Keyword::ON,
623    Keyword::JOIN,
624    Keyword::INNER,
625    Keyword::CROSS,
626    Keyword::FULL,
627    Keyword::LEFT,
628    Keyword::RIGHT,
629    Keyword::NATURAL,
630    Keyword::ASOF,
631    Keyword::USING,
632    Keyword::CLUSTER,
633    // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
634    Keyword::OUTER,
635    Keyword::SET,
636    Keyword::RETURNING,
637    Keyword::EMIT,
638];
639
640/// Can't be used as a column alias, so that `SELECT <expr> alias`
641/// can be parsed unambiguously without looking ahead.
642pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
643    // Reserved as both a table and a column alias:
644    Keyword::WITH,
645    Keyword::EXPLAIN,
646    Keyword::ANALYZE,
647    Keyword::SELECT,
648    Keyword::WHERE,
649    Keyword::GROUP,
650    Keyword::SORT,
651    Keyword::HAVING,
652    Keyword::ORDER,
653    Keyword::TOP,
654    Keyword::LATERAL,
655    Keyword::VIEW,
656    Keyword::LIMIT,
657    Keyword::OFFSET,
658    Keyword::FETCH,
659    Keyword::UNION,
660    Keyword::EXCEPT,
661    Keyword::INTERSECT,
662    Keyword::CLUSTER,
663    // Reserved only as a column alias in the `SELECT` clause
664    Keyword::FROM,
665];
666
667/// Can't be used as a column or table name in PostgreSQL.
668///
669/// This list is taken from the following table, for all "reserved" words in the PostgreSQL column,
670/// including "can be function or type" and "requires AS". <https://www.postgresql.org/docs/14/sql-keywords-appendix.html#KEYWORDS-TABLE>
671///
672/// `SELECT` and `WITH` were commented out because the following won't parse:
673/// `SELECT (SELECT 1)` or `SELECT (WITH a AS (SELECT 1) SELECT 1)`
674///
675/// Other commented ones like `CURRENT_SCHEMA` are actually functions invoked without parentheses.
676pub const RESERVED_FOR_COLUMN_OR_TABLE_NAME: &[Keyword] = &[
677    Keyword::ALL,
678    Keyword::ANALYSE,
679    Keyword::ANALYZE,
680    Keyword::AND,
681    Keyword::ANY,
682    Keyword::ARRAY,
683    Keyword::AS,
684    Keyword::ASC,
685    Keyword::ASYMMETRIC,
686    Keyword::AUTHORIZATION,
687    Keyword::BINARY,
688    Keyword::BOTH,
689    Keyword::CASE,
690    Keyword::CAST,
691    Keyword::CHECK,
692    Keyword::COLLATE,
693    Keyword::COLLATION,
694    Keyword::COLUMN,
695    Keyword::CONCURRENTLY,
696    Keyword::CONSTRAINT,
697    Keyword::CREATE,
698    Keyword::CROSS,
699    // Keyword::CURRENT_CATALOG,
700    // Keyword::CURRENT_DATE,
701    // Keyword::CURRENT_ROLE,
702    // Keyword::CURRENT_SCHEMA,
703    // Keyword::CURRENT_TIME,
704    // Keyword::CURRENT_TIMESTAMP,
705    // Keyword::CURRENT_USER,
706    Keyword::DEFAULT,
707    Keyword::DEFERRABLE,
708    Keyword::DESC,
709    Keyword::DISTINCT,
710    Keyword::DO,
711    Keyword::ELSE,
712    Keyword::END,
713    Keyword::EXCEPT,
714    Keyword::FALSE,
715    Keyword::FETCH,
716    Keyword::FOR,
717    Keyword::FOREIGN,
718    Keyword::FREEZE,
719    Keyword::FROM,
720    Keyword::FULL,
721    Keyword::GRANT,
722    Keyword::GROUP,
723    Keyword::HAVING,
724    Keyword::ILIKE,
725    Keyword::IN,
726    Keyword::INITIALLY,
727    Keyword::INNER,
728    Keyword::INTERSECT,
729    Keyword::INTO,
730    Keyword::IS,
731    Keyword::ISNULL,
732    Keyword::JOIN,
733    Keyword::LATERAL,
734    Keyword::LEADING,
735    Keyword::LEFT,
736    Keyword::LIKE,
737    Keyword::LIMIT,
738    // Keyword::LOCALTIME,
739    // Keyword::LOCALTIMESTAMP,
740    Keyword::NATURAL,
741    Keyword::NOT,
742    Keyword::NOTNULL,
743    Keyword::NULL,
744    Keyword::OFFSET,
745    Keyword::ON,
746    Keyword::ONLY,
747    Keyword::OR,
748    Keyword::ORDER,
749    Keyword::OUTER,
750    Keyword::OVERLAPS,
751    Keyword::PLACING,
752    Keyword::PRIMARY,
753    Keyword::REFERENCES,
754    Keyword::RETURNING,
755    Keyword::RIGHT,
756    // Keyword::SELECT,
757    // Keyword::SESSION_USER,
758    Keyword::SIMILAR,
759    Keyword::SOME,
760    Keyword::SYMMETRIC,
761    Keyword::TABLE,
762    Keyword::TABLESAMPLE,
763    Keyword::THEN,
764    Keyword::TO,
765    Keyword::TRAILING,
766    Keyword::TRUE,
767    Keyword::UNION,
768    Keyword::UNIQUE,
769    // Keyword::USER,
770    Keyword::USING,
771    Keyword::VARIADIC,
772    Keyword::VERBOSE,
773    Keyword::WHEN,
774    Keyword::WHERE,
775    Keyword::WINDOW,
776    // Keyword::WITH,
777];
778
779impl fmt::Display for Keyword {
780    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
781        write!(f, "{:?}", self)
782    }
783}