vibesql_parser/
keywords.rs

1use std::fmt;
2
3/// SQL Keywords supported by the parser.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Keyword {
6    Select,
7    Distinct,
8    From,
9    Where,
10    Insert,
11    Into,
12    Replace,
13    Ignore,
14    Update,
15    Delete,
16    Duplicate,
17    Create,
18    Table,
19    Truncate,
20    Drop,
21    Alter,
22    And,
23    Or,
24    Not,
25    Null,
26    True,
27    False,
28    As,
29    Join,
30    Left,
31    Right,
32    Inner,
33    Outer,
34    Cross,
35    Full,
36    Natural,
37    On,
38    Group,
39    By,
40    // OLAP extensions for GROUP BY
41    Rollup,
42    Cube,
43    Sets,
44    Grouping,
45    GroupingId,
46    Having,
47    Order,
48    Asc,
49    Desc,
50    Limit,
51    Offset,
52    Set,
53    Values,
54    In,
55    Between,
56    Asymmetric,
57    Symmetric,
58    Like,
59    Exists,
60    If,
61    All,
62    Any,
63    Some,
64    Union,
65    Intersect,
66    Except,
67    With,
68    Recursive,
69    Date,
70    Time,
71    Timestamp,
72    Interval,
73    Cast,
74    // CASE expression keywords
75    Case,
76    When,
77    Then,
78    Else,
79    End,
80    // Window function keywords
81    Over,
82    Partition,
83    Rows,
84    Range,
85    Preceding,
86    Following,
87    Unbounded,
88    Current,
89    // Note: Window function names (ROW_NUMBER, RANK, etc.) are identifiers, not keywords
90    // Constraint keywords
91    Primary,
92    Foreign,
93    Key,
94    Unique,
95    Check,
96    References,
97    // IS NULL keywords
98    Is,
99    // Transaction keywords
100    Begin,
101    Commit,
102    Rollback,
103    // SCHEMA keywords
104    Cascade,
105    Restrict,
106    Schema,
107    Start,
108    Transaction,
109    // ALTER TABLE keywords
110    Add,
111    Column,
112    Constraint,
113    Default,
114    Rename,
115    Modify,
116    Change,
117    // SAVEPOINT keywords
118    Savepoint,
119    Release,
120    To,
121    // Role management keywords
122    Role,
123    // TRIM function keywords
124    Both,
125    Leading,
126    Trailing,
127    // MySQL arithmetic operators
128    Div,
129    // Data type keywords
130    Varying,
131    Characters,
132    Octets,
133    Using,
134    // SUBSTRING function keywords
135    For,
136    // Current date/time function keywords
137    CurrentDate,
138    CurrentTime,
139    CurrentTimestamp,
140    // GRANT keywords
141    Grant,
142    Privileges,
143    Usage,
144    Option,
145    // REVOKE keywords
146    Revoke,
147    Granted,
148    // Advanced privilege keywords
149    Execute,
150    Trigger,
151    Under,
152    // Advanced SQL object keywords
153    Domain,
154    Sequence,
155    Type,
156    Collation,
157    Character,
158    Translation,
159    View,
160    Index,
161    Analyze,
162    Reindex,
163    Explain,
164    Assertion,
165    Specific,
166    // Trigger-specific keywords
167    Before,
168    After,
169    Instead,
170    Of,
171    Each,
172    Row,
173    Statement,
174    Enable,
175    Disable,
176    // SEQUENCE specific keywords
177    Increment,
178    Minvalue,
179    Maxvalue,
180    Cycle,
181    No,
182    Restart,
183    Next,
184    // Referential action keywords
185    Action,
186    // Session configuration keywords (SQL:1999)
187    Catalog,
188    Names,
189    Zone,
190    Local,
191    Session,
192    Global,
193    // Interval unit keywords
194    Year,
195    Quarter,
196    Month,
197    Week,
198    Day,
199    Hour,
200    Minute,
201    Second,
202    Microsecond,
203    // Callable object keywords (functions, procedures, methods)
204    Function,
205    Procedure,
206    Call,
207    Routine,
208    Method,
209    Constructor,
210    Static,
211    Instance,
212    // Procedure/Function parameter modes
213    Out,
214    InOut,
215    // Procedure/Function keywords
216    Returns,
217    While,
218    Do,
219    Loop,
220    Repeat,
221    Until,
222    Return,
223    Leave,
224    Iterate,
225    // Procedure/Function characteristics (Phase 6)
226    Deterministic,
227    Language,
228    Sql,
229    Security,
230    Definer,
231    Invoker,
232    // Internationalization keywords (SQL:1999)
233    Get,
234    Pad,
235    Space,
236    Collate,
237    // CURSOR keywords
238    Declare,
239    Cursor,
240    Insensitive,
241    // Prepared statement keywords
242    Prepare,
243    Deallocate,
244    Scroll,
245    Hold,
246    Without,
247    Read,
248    Only,
249    Oids,
250    Open,
251    Fetch,
252    Close,
253    Prior,
254    First,
255    Last,
256    Absolute,
257    Relative,
258    Serializable,
259    Isolation,
260    Level,
261    Write,
262    Comment,
263    // MySQL table option keywords
264    KeyBlockSize,
265    Connection,
266    InsertMethod,
267    RowFormat,
268    DelayKeyWrite,
269    TableChecksum,
270    Checksum,
271    StatsSamplePages,
272    Password,
273    AvgRowLength,
274    MinRows,
275    MaxRows,
276    SecondaryEngine,
277    // MySQL table option values
278    Dynamic,
279    Fixed,
280    Compressed,
281    Redundant,
282    Compact,
283    // Full-text search keywords
284    Fulltext,
285    Match,
286    Against,
287    Boolean,
288    Expansion,
289    Mode,
290    Query,
291    // Spatial index keywords
292    Spatial,
293    // Database introspection keywords
294    Show,
295    Describe,
296    Databases,
297    Tables,
298    Columns,
299    Fields,
300    Indexes,
301    Keys,
302    // Auto-increment keywords (MySQL and SQLite)
303    AutoIncrement,
304    // Temporary object keywords (SQLite)
305    Temp,
306    Temporary,
307    // VibeSQL storage format keywords
308    Storage,
309    Columnar,
310}
311
312impl Keyword {
313    /// Returns true if this keyword can be used as an unquoted column or table name.
314    /// These are "unreserved" keywords that are only treated as keywords in specific contexts.
315    ///
316    /// This follows SQLite's behavior where temporal type keywords (TIMESTAMP, DATE, TIME, INTERVAL)
317    /// and interval unit keywords (YEAR, MONTH, DAY, etc.) can be used as identifiers without quoting.
318    pub fn can_be_identifier(&self) -> bool {
319        matches!(
320            self,
321            // Temporal type keywords
322            Keyword::Timestamp | Keyword::Date | Keyword::Time | Keyword::Interval |
323            // Interval unit keywords (used in EXTRACT, DATE_ADD, etc. but also valid as identifiers)
324            Keyword::Year | Keyword::Quarter | Keyword::Month | Keyword::Week |
325            Keyword::Day | Keyword::Hour | Keyword::Minute | Keyword::Second |
326            Keyword::Microsecond
327        )
328    }
329}
330
331impl fmt::Display for Keyword {
332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333        let keyword_str = match self {
334            Keyword::Select => "SELECT",
335            Keyword::Distinct => "DISTINCT",
336            Keyword::From => "FROM",
337            Keyword::Where => "WHERE",
338            Keyword::Insert => "INSERT",
339            Keyword::Into => "INTO",
340            Keyword::Replace => "REPLACE",
341            Keyword::Ignore => "IGNORE",
342            Keyword::Update => "UPDATE",
343            Keyword::Delete => "DELETE",
344            Keyword::Duplicate => "DUPLICATE",
345            Keyword::Create => "CREATE",
346            Keyword::Table => "TABLE",
347            Keyword::Truncate => "TRUNCATE",
348            Keyword::Drop => "DROP",
349            Keyword::Alter => "ALTER",
350            Keyword::And => "AND",
351            Keyword::Or => "OR",
352            Keyword::Not => "NOT",
353            Keyword::Null => "NULL",
354            Keyword::True => "TRUE",
355            Keyword::False => "FALSE",
356            Keyword::As => "AS",
357            Keyword::Join => "JOIN",
358            Keyword::Left => "LEFT",
359            Keyword::Right => "RIGHT",
360            Keyword::Inner => "INNER",
361            Keyword::Outer => "OUTER",
362            Keyword::Cross => "CROSS",
363            Keyword::Full => "FULL",
364            Keyword::Natural => "NATURAL",
365            Keyword::On => "ON",
366            Keyword::Group => "GROUP",
367            Keyword::By => "BY",
368            Keyword::Rollup => "ROLLUP",
369            Keyword::Cube => "CUBE",
370            Keyword::Sets => "SETS",
371            Keyword::Grouping => "GROUPING",
372            Keyword::GroupingId => "GROUPING_ID",
373            Keyword::Having => "HAVING",
374            Keyword::Order => "ORDER",
375            Keyword::Asc => "ASC",
376            Keyword::Desc => "DESC",
377            Keyword::Limit => "LIMIT",
378            Keyword::Offset => "OFFSET",
379            Keyword::Set => "SET",
380            Keyword::Values => "VALUES",
381            Keyword::In => "IN",
382            Keyword::Between => "BETWEEN",
383            Keyword::Asymmetric => "ASYMMETRIC",
384            Keyword::Symmetric => "SYMMETRIC",
385            Keyword::Like => "LIKE",
386            Keyword::Exists => "EXISTS",
387            Keyword::If => "IF",
388            Keyword::All => "ALL",
389            Keyword::Any => "ANY",
390            Keyword::Some => "SOME",
391            Keyword::Union => "UNION",
392            Keyword::Intersect => "INTERSECT",
393            Keyword::Except => "EXCEPT",
394            Keyword::With => "WITH",
395            Keyword::Recursive => "RECURSIVE",
396            Keyword::Date => "DATE",
397            Keyword::Time => "TIME",
398            Keyword::Timestamp => "TIMESTAMP",
399            Keyword::Interval => "INTERVAL",
400            Keyword::Cast => "CAST",
401            Keyword::Case => "CASE",
402            Keyword::When => "WHEN",
403            Keyword::Then => "THEN",
404            Keyword::Else => "ELSE",
405            Keyword::End => "END",
406            Keyword::Over => "OVER",
407            Keyword::Partition => "PARTITION",
408            Keyword::Rows => "ROWS",
409            Keyword::Range => "RANGE",
410            Keyword::Preceding => "PRECEDING",
411            Keyword::Following => "FOLLOWING",
412            Keyword::Unbounded => "UNBOUNDED",
413            Keyword::Current => "CURRENT",
414            Keyword::Primary => "PRIMARY",
415            Keyword::Foreign => "FOREIGN",
416            Keyword::Key => "KEY",
417            Keyword::Unique => "UNIQUE",
418            Keyword::Check => "CHECK",
419            Keyword::References => "REFERENCES",
420            Keyword::Is => "IS",
421            Keyword::Begin => "BEGIN",
422            Keyword::Commit => "COMMIT",
423            Keyword::Rollback => "ROLLBACK",
424            Keyword::Cascade => "CASCADE",
425            Keyword::Restrict => "RESTRICT",
426            Keyword::Schema => "SCHEMA",
427            Keyword::Start => "START",
428            Keyword::Transaction => "TRANSACTION",
429            Keyword::Add => "ADD",
430            Keyword::Column => "COLUMN",
431            Keyword::Constraint => "CONSTRAINT",
432            Keyword::Default => "DEFAULT",
433            Keyword::Rename => "RENAME",
434            Keyword::Modify => "MODIFY",
435            Keyword::Change => "CHANGE",
436            Keyword::Savepoint => "SAVEPOINT",
437            Keyword::Release => "RELEASE",
438            Keyword::To => "TO",
439            Keyword::Role => "ROLE",
440            Keyword::Both => "BOTH",
441            Keyword::Leading => "LEADING",
442            Keyword::Trailing => "TRAILING",
443            Keyword::Div => "DIV",
444            Keyword::Varying => "VARYING",
445            Keyword::Characters => "CHARACTERS",
446            Keyword::Octets => "OCTETS",
447            Keyword::Using => "USING",
448            Keyword::For => "FOR",
449            Keyword::CurrentDate => "CURRENT_DATE",
450            Keyword::CurrentTime => "CURRENT_TIME",
451            Keyword::CurrentTimestamp => "CURRENT_TIMESTAMP",
452            Keyword::Grant => "GRANT",
453            Keyword::Privileges => "PRIVILEGES",
454            Keyword::Usage => "USAGE",
455            Keyword::Option => "OPTION",
456            Keyword::Revoke => "REVOKE",
457            Keyword::Granted => "GRANTED",
458            Keyword::Execute => "EXECUTE",
459            Keyword::Trigger => "TRIGGER",
460            Keyword::Under => "UNDER",
461            Keyword::Domain => "DOMAIN",
462            Keyword::Sequence => "SEQUENCE",
463            Keyword::Type => "TYPE",
464            Keyword::Collation => "COLLATION",
465            Keyword::Character => "CHARACTER",
466            Keyword::Translation => "TRANSLATION",
467            Keyword::View => "VIEW",
468            Keyword::Index => "INDEX",
469            Keyword::Analyze => "ANALYZE",
470            Keyword::Reindex => "REINDEX",
471            Keyword::Explain => "EXPLAIN",
472            Keyword::Assertion => "ASSERTION",
473            Keyword::Specific => "SPECIFIC",
474            Keyword::Before => "BEFORE",
475            Keyword::After => "AFTER",
476            Keyword::Instead => "INSTEAD",
477            Keyword::Of => "OF",
478            Keyword::Each => "EACH",
479            Keyword::Row => "ROW",
480            Keyword::Statement => "STATEMENT",
481            Keyword::Enable => "ENABLE",
482            Keyword::Disable => "DISABLE",
483            Keyword::Increment => "INCREMENT",
484            Keyword::Minvalue => "MINVALUE",
485            Keyword::Maxvalue => "MAXVALUE",
486            Keyword::Cycle => "CYCLE",
487            Keyword::No => "NO",
488            Keyword::Restart => "RESTART",
489            Keyword::Next => "NEXT",
490            Keyword::Action => "ACTION",
491            Keyword::Catalog => "CATALOG",
492            Keyword::Names => "NAMES",
493            Keyword::Zone => "ZONE",
494            Keyword::Local => "LOCAL",
495            Keyword::Session => "SESSION",
496            Keyword::Global => "GLOBAL",
497            Keyword::Year => "YEAR",
498            Keyword::Quarter => "QUARTER",
499            Keyword::Month => "MONTH",
500            Keyword::Week => "WEEK",
501            Keyword::Day => "DAY",
502            Keyword::Hour => "HOUR",
503            Keyword::Minute => "MINUTE",
504            Keyword::Second => "SECOND",
505            Keyword::Microsecond => "MICROSECOND",
506            Keyword::Function => "FUNCTION",
507            Keyword::Procedure => "PROCEDURE",
508            Keyword::Call => "CALL",
509            Keyword::Routine => "ROUTINE",
510            Keyword::Method => "METHOD",
511            Keyword::Constructor => "CONSTRUCTOR",
512            Keyword::Static => "STATIC",
513            Keyword::Instance => "INSTANCE",
514            Keyword::Out => "OUT",
515            Keyword::InOut => "INOUT",
516            Keyword::Returns => "RETURNS",
517            Keyword::While => "WHILE",
518            Keyword::Do => "DO",
519            Keyword::Loop => "LOOP",
520            Keyword::Repeat => "REPEAT",
521            Keyword::Until => "UNTIL",
522            Keyword::Return => "RETURN",
523            Keyword::Leave => "LEAVE",
524            Keyword::Iterate => "ITERATE",
525            Keyword::Deterministic => "DETERMINISTIC",
526            Keyword::Language => "LANGUAGE",
527            Keyword::Sql => "SQL",
528            Keyword::Security => "SECURITY",
529            Keyword::Definer => "DEFINER",
530            Keyword::Invoker => "INVOKER",
531            Keyword::Comment => "COMMENT",
532            Keyword::Get => "GET",
533            Keyword::Pad => "PAD",
534            Keyword::Space => "SPACE",
535            Keyword::Collate => "COLLATE",
536            Keyword::Declare => "DECLARE",
537            Keyword::Cursor => "CURSOR",
538            Keyword::Insensitive => "INSENSITIVE",
539            Keyword::Prepare => "PREPARE",
540            Keyword::Deallocate => "DEALLOCATE",
541            Keyword::Scroll => "SCROLL",
542            Keyword::Hold => "HOLD",
543            Keyword::Without => "WITHOUT",
544            Keyword::Read => "READ",
545            Keyword::Only => "ONLY",
546            Keyword::Oids => "OIDS",
547            Keyword::Open => "OPEN",
548            Keyword::Fetch => "FETCH",
549            Keyword::Close => "CLOSE",
550            Keyword::Prior => "PRIOR",
551            Keyword::First => "FIRST",
552            Keyword::Last => "LAST",
553            Keyword::Absolute => "ABSOLUTE",
554            Keyword::Relative => "RELATIVE",
555            Keyword::Serializable => "SERIALIZABLE",
556            Keyword::Isolation => "ISOLATION",
557            Keyword::Level => "LEVEL",
558            Keyword::Write => "WRITE",
559            // MySQL table option keywords
560            Keyword::KeyBlockSize => "KEY_BLOCK_SIZE",
561            Keyword::Connection => "CONNECTION",
562            Keyword::InsertMethod => "INSERT_METHOD",
563            Keyword::RowFormat => "ROW_FORMAT",
564            Keyword::DelayKeyWrite => "DELAY_KEY_WRITE",
565            Keyword::TableChecksum => "TABLE_CHECKSUM",
566            Keyword::Checksum => "CHECKSUM",
567            Keyword::StatsSamplePages => "STATS_SAMPLE_PAGES",
568            Keyword::Password => "PASSWORD",
569            Keyword::AvgRowLength => "AVG_ROW_LENGTH",
570            Keyword::MinRows => "MIN_ROWS",
571            Keyword::MaxRows => "MAX_ROWS",
572            Keyword::SecondaryEngine => "SECONDARY_ENGINE",
573            // MySQL table option values
574            Keyword::Dynamic => "DYNAMIC",
575            Keyword::Fixed => "FIXED",
576            Keyword::Compressed => "COMPRESSED",
577            Keyword::Redundant => "REDUNDANT",
578            Keyword::Compact => "COMPACT",
579            // Full-text search keywords
580            Keyword::Fulltext => "FULLTEXT",
581            Keyword::Match => "MATCH",
582            Keyword::Against => "AGAINST",
583            Keyword::Boolean => "BOOLEAN",
584            Keyword::Expansion => "EXPANSION",
585            Keyword::Mode => "MODE",
586            Keyword::Query => "QUERY",
587            // Spatial index keywords
588            Keyword::Spatial => "SPATIAL",
589            // Database introspection keywords
590            Keyword::Show => "SHOW",
591            Keyword::Describe => "DESCRIBE",
592            Keyword::Databases => "DATABASES",
593            Keyword::Tables => "TABLES",
594            Keyword::Columns => "COLUMNS",
595            Keyword::Fields => "FIELDS",
596            Keyword::Indexes => "INDEXES",
597            Keyword::Keys => "KEYS",
598            // Auto-increment keywords
599            Keyword::AutoIncrement => "AUTO_INCREMENT",
600            // Temporary object keywords
601            Keyword::Temp => "TEMP",
602            Keyword::Temporary => "TEMPORARY",
603            // VibeSQL storage format keywords
604            Keyword::Storage => "STORAGE",
605            Keyword::Columnar => "COLUMNAR",
606        };
607        write!(f, "{}", keyword_str)
608    }
609}