Files
turso/parser/src/token.rs
Pekka Enberg 433b60555f Add BEGIN CONCURRENT support for MVCC mode
Currently, when MVCC is enabled, every transaction mode supports
concurrent reads and writes, which makes it hard to adopt for existing
applications that use `BEGIN DEFERRED` or `BEGIN IMMEDIATE`.

Therefore, add support for `BEGIN CONCURRENT` transactions when MVCC is
enabled. The transaction mode allows multiple concurrent read/write
transactions that don't block each other, with conflicts resolved at
commit time. Furthermore, implement the correct semantics for `BEGIN
DEFERRED` and `BEGIN IMMEDIATE` by taking advantage of the pager level
write lock when transaction upgrades to write. This means that now
concurrent MVCC transactions are serialized against the legacy ones when
needed.

The implementation includes:

- Parser support for CONCURRENT keyword in BEGIN statements

- New Concurrent variant in TransactionMode to distinguish from regular
  read/write transactions

- MVCC store tracking of exclusive transactions to support IMMEDIATE and
  EXCLUSIVE modes alongside CONCURRENT

- Proper transaction state management for all transaction types in MVCC

This enables better concurrency for applications that can handle
optimistic concurrency control, while still supporting traditional
SQLite transaction semantics via IMMEDIATE and EXCLUSIVE modes.
2025-09-11 16:05:52 +03:00

552 lines
19 KiB
Rust

use std::fmt::Display;
/// Token classes
// Generated by lemon (parse.h).
// Renamed manually.
// To be keep in sync.
#[non_exhaustive]
#[allow(non_camel_case_types, missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)]
#[repr(u16)]
pub enum TokenType {
TK_EOF = 0,
TK_SEMI = 1,
TK_EXPLAIN = 2,
TK_QUERY = 3,
TK_PLAN = 4,
TK_BEGIN = 5,
TK_TRANSACTION = 6,
TK_DEFERRED = 7,
TK_IMMEDIATE = 8,
TK_EXCLUSIVE = 9,
TK_COMMIT = 10,
TK_END = 11,
TK_ROLLBACK = 12,
TK_SAVEPOINT = 13,
TK_RELEASE = 14,
TK_TO = 15,
TK_TABLE = 16,
TK_CREATE = 17,
TK_IF = 18,
TK_NOT = 19,
TK_EXISTS = 20,
TK_TEMP = 21,
TK_LP = 22,
TK_RP = 23,
TK_AS = 24,
TK_COMMA = 25,
TK_WITHOUT = 26,
TK_ABORT = 27,
TK_ACTION = 28,
TK_AFTER = 29,
TK_ANALYZE = 30,
TK_ASC = 31,
TK_ATTACH = 32,
TK_BEFORE = 33,
TK_BY = 34,
TK_CASCADE = 35,
TK_CAST = 36,
TK_CONFLICT = 37,
TK_DATABASE = 38,
TK_DESC = 39,
TK_DETACH = 40,
TK_EACH = 41,
TK_FAIL = 42,
TK_OR = 43,
TK_AND = 44,
TK_IS = 45,
TK_ISNOT = 46,
TK_MATCH = 47,
TK_LIKE_KW = 48,
TK_BETWEEN = 49,
TK_IN = 50,
TK_ISNULL = 51,
TK_NOTNULL = 52,
TK_NE = 53,
TK_EQ = 54,
TK_GT = 55,
TK_LE = 56,
TK_LT = 57,
TK_GE = 58,
TK_ESCAPE = 59,
TK_ID = 60,
TK_COLUMNKW = 61,
TK_DO = 62,
TK_FOR = 63,
TK_IGNORE = 64,
TK_INITIALLY = 65,
TK_INSTEAD = 66,
TK_NO = 67,
TK_KEY = 68,
TK_OF = 69,
TK_OFFSET = 70,
TK_PRAGMA = 71,
TK_RAISE = 72,
TK_RECURSIVE = 73,
TK_REPLACE = 74,
TK_RESTRICT = 75,
TK_ROW = 76,
TK_ROWS = 77,
TK_TRIGGER = 78,
TK_VACUUM = 79,
TK_VIEW = 80,
TK_VIRTUAL = 81,
TK_WITH = 82,
TK_NULLS = 83,
TK_FIRST = 84,
TK_LAST = 85,
TK_CURRENT = 86,
TK_FOLLOWING = 87,
TK_PARTITION = 88,
TK_PRECEDING = 89,
TK_RANGE = 90,
TK_UNBOUNDED = 91,
TK_EXCLUDE = 92,
TK_GROUPS = 93,
TK_OTHERS = 94,
TK_TIES = 95,
TK_GENERATED = 96,
TK_ALWAYS = 97,
TK_MATERIALIZED = 98,
TK_REINDEX = 99,
TK_RENAME = 100,
TK_CTIME_KW = 101,
TK_ANY = 102,
TK_BITAND = 103,
TK_BITOR = 104,
TK_LSHIFT = 105,
TK_RSHIFT = 106,
TK_PLUS = 107,
TK_MINUS = 108,
TK_STAR = 109,
TK_SLASH = 110,
TK_REM = 111,
TK_CONCAT = 112,
TK_PTR = 113,
TK_COLLATE = 114,
TK_BITNOT = 115,
TK_ON = 116,
TK_INDEXED = 117,
TK_STRING = 118,
TK_JOIN_KW = 119,
TK_CONSTRAINT = 120,
TK_DEFAULT = 121,
TK_NULL = 122,
TK_PRIMARY = 123,
TK_UNIQUE = 124,
TK_CHECK = 125,
TK_REFERENCES = 126,
TK_AUTOINCR = 127,
TK_INSERT = 128,
TK_DELETE = 129,
TK_UPDATE = 130,
TK_SET = 131,
TK_DEFERRABLE = 132,
TK_FOREIGN = 133,
TK_DROP = 134,
TK_UNION = 135,
TK_ALL = 136,
TK_EXCEPT = 137,
TK_INTERSECT = 138,
TK_SELECT = 139,
TK_VALUES = 140,
TK_DISTINCT = 141,
TK_DOT = 142,
TK_FROM = 143,
TK_JOIN = 144,
TK_USING = 145,
TK_ORDER = 146,
TK_GROUP = 147,
TK_HAVING = 148,
TK_LIMIT = 149,
TK_WHERE = 150,
TK_RETURNING = 151,
TK_INTO = 152,
TK_NOTHING = 153,
TK_BLOB = 154,
TK_FLOAT = 155,
TK_INTEGER = 156,
TK_VARIABLE = 157,
TK_CASE = 158,
TK_WHEN = 159,
TK_THEN = 160,
TK_ELSE = 161,
TK_INDEX = 162,
TK_ALTER = 163,
TK_ADD = 164,
TK_WINDOW = 165,
TK_OVER = 166,
TK_FILTER = 167,
TK_ILLEGAL = 185,
TK_CONCURRENT = 186,
}
impl TokenType {
/// Return the associated string (mainly for testing)
pub const fn as_str(&self) -> Option<&'static str> {
match self {
TokenType::TK_ABORT => Some("ABORT"),
TokenType::TK_ACTION => Some("ACTION"),
TokenType::TK_ADD => Some("ADD"),
TokenType::TK_AFTER => Some("AFTER"),
TokenType::TK_ALL => Some("ALL"),
TokenType::TK_ALTER => Some("ALTER"),
TokenType::TK_ANALYZE => Some("ANALYZE"),
TokenType::TK_ALWAYS => Some("ALWAYS"),
TokenType::TK_AND => Some("AND"),
TokenType::TK_AS => Some("AS"),
TokenType::TK_ASC => Some("ASC"),
TokenType::TK_ATTACH => Some("ATTACH"),
TokenType::TK_AUTOINCR => Some("AUTOINCREMENT"),
TokenType::TK_BEFORE => Some("BEFORE"),
TokenType::TK_BEGIN => Some("BEGIN"),
TokenType::TK_BETWEEN => Some("BETWEEN"),
TokenType::TK_BY => Some("BY"),
TokenType::TK_CASCADE => Some("CASCADE"),
TokenType::TK_CASE => Some("CASE"),
TokenType::TK_CAST => Some("CAST"),
TokenType::TK_CHECK => Some("CHECK"),
TokenType::TK_COLLATE => Some("COLLATE"),
TokenType::TK_COLUMNKW => Some("COLUMN"),
TokenType::TK_COMMIT => Some("COMMIT"),
TokenType::TK_CONFLICT => Some("CONFLICT"),
TokenType::TK_CONSTRAINT => Some("CONSTRAINT"),
TokenType::TK_CREATE => Some("CREATE"),
TokenType::TK_CURRENT => Some("CURRENT"),
TokenType::TK_DATABASE => Some("DATABASE"),
TokenType::TK_DEFAULT => Some("DEFAULT"),
TokenType::TK_DEFERRABLE => Some("DEFERRABLE"),
TokenType::TK_DEFERRED => Some("DEFERRED"),
TokenType::TK_DELETE => Some("DELETE"),
TokenType::TK_DESC => Some("DESC"),
TokenType::TK_DETACH => Some("DETACH"),
TokenType::TK_DISTINCT => Some("DISTINCT"),
TokenType::TK_DO => Some("DO"),
TokenType::TK_DROP => Some("DROP"),
TokenType::TK_EACH => Some("EACH"),
TokenType::TK_ELSE => Some("ELSE"),
TokenType::TK_END => Some("END"),
TokenType::TK_ESCAPE => Some("ESCAPE"),
TokenType::TK_EXCEPT => Some("EXCEPT"),
TokenType::TK_EXCLUDE => Some("EXCLUDE"),
TokenType::TK_EXCLUSIVE => Some("EXCLUSIVE"),
TokenType::TK_CONCURRENT => Some("CONCURRENT"),
TokenType::TK_EXISTS => Some("EXISTS"),
TokenType::TK_EXPLAIN => Some("EXPLAIN"),
TokenType::TK_FAIL => Some("FAIL"),
TokenType::TK_FILTER => Some("FILTER"),
TokenType::TK_FIRST => Some("FIRST"),
TokenType::TK_FOLLOWING => Some("FOLLOWING"),
TokenType::TK_FOR => Some("FOR"),
TokenType::TK_FOREIGN => Some("FOREIGN"),
TokenType::TK_FROM => Some("FROM"),
TokenType::TK_GENERATED => Some("GENERATED"),
TokenType::TK_GROUP => Some("GROUP"),
TokenType::TK_GROUPS => Some("GROUPS"),
TokenType::TK_HAVING => Some("HAVING"),
TokenType::TK_IF => Some("IF"),
TokenType::TK_IGNORE => Some("IGNORE"),
TokenType::TK_IMMEDIATE => Some("IMMEDIATE"),
TokenType::TK_IN => Some("IN"),
TokenType::TK_INDEX => Some("INDEX"),
TokenType::TK_INDEXED => Some("INDEXED"),
TokenType::TK_INITIALLY => Some("INITIALLY"),
TokenType::TK_INSERT => Some("INSERT"),
TokenType::TK_INSTEAD => Some("INSTEAD"),
TokenType::TK_INTERSECT => Some("INTERSECT"),
TokenType::TK_INTO => Some("INTO"),
TokenType::TK_IS => Some("IS"),
TokenType::TK_ISNULL => Some("ISNULL"),
TokenType::TK_JOIN => Some("JOIN"),
TokenType::TK_KEY => Some("KEY"),
TokenType::TK_LAST => Some("LAST"),
TokenType::TK_LIMIT => Some("LIMIT"),
TokenType::TK_MATCH => Some("MATCH"),
TokenType::TK_MATERIALIZED => Some("MATERIALIZED"),
TokenType::TK_NO => Some("NO"),
TokenType::TK_NOT => Some("NOT"),
TokenType::TK_NOTHING => Some("NOTHING"),
TokenType::TK_NOTNULL => Some("NOTNULL"),
TokenType::TK_NULL => Some("NULL"),
TokenType::TK_NULLS => Some("NULLS"),
TokenType::TK_OF => Some("OF"),
TokenType::TK_OFFSET => Some("OFFSET"),
TokenType::TK_ON => Some("ON"),
TokenType::TK_OR => Some("OR"),
TokenType::TK_ORDER => Some("ORDER"),
TokenType::TK_OTHERS => Some("OTHERS"),
TokenType::TK_OVER => Some("OVER"),
TokenType::TK_PARTITION => Some("PARTITION"),
TokenType::TK_PLAN => Some("PLAN"),
TokenType::TK_PRAGMA => Some("PRAGMA"),
TokenType::TK_PRECEDING => Some("PRECEDING"),
TokenType::TK_PRIMARY => Some("PRIMARY"),
TokenType::TK_QUERY => Some("QUERY"),
TokenType::TK_RAISE => Some("RAISE"),
TokenType::TK_RANGE => Some("RANGE"),
TokenType::TK_RECURSIVE => Some("RECURSIVE"),
TokenType::TK_REFERENCES => Some("REFERENCES"),
TokenType::TK_REINDEX => Some("REINDEX"),
TokenType::TK_RELEASE => Some("RELEASE"),
TokenType::TK_RENAME => Some("RENAME"),
TokenType::TK_REPLACE => Some("REPLACE"),
TokenType::TK_RETURNING => Some("RETURNING"),
TokenType::TK_RESTRICT => Some("RESTRICT"),
TokenType::TK_ROLLBACK => Some("ROLLBACK"),
TokenType::TK_ROW => Some("ROW"),
TokenType::TK_ROWS => Some("ROWS"),
TokenType::TK_SAVEPOINT => Some("SAVEPOINT"),
TokenType::TK_SELECT => Some("SELECT"),
TokenType::TK_SET => Some("SET"),
TokenType::TK_TABLE => Some("TABLE"),
TokenType::TK_TEMP => Some("TEMP"), // or TEMPORARY
TokenType::TK_TIES => Some("TIES"),
TokenType::TK_THEN => Some("THEN"),
TokenType::TK_TO => Some("TO"),
TokenType::TK_TRANSACTION => Some("TRANSACTION"),
TokenType::TK_TRIGGER => Some("TRIGGER"),
TokenType::TK_UNBOUNDED => Some("UNBOUNDED"),
TokenType::TK_UNION => Some("UNION"),
TokenType::TK_UNIQUE => Some("UNIQUE"),
TokenType::TK_UPDATE => Some("UPDATE"),
TokenType::TK_USING => Some("USING"),
TokenType::TK_VACUUM => Some("VACUUM"),
TokenType::TK_VALUES => Some("VALUES"),
TokenType::TK_VIEW => Some("VIEW"),
TokenType::TK_VIRTUAL => Some("VIRTUAL"),
TokenType::TK_WHEN => Some("WHEN"),
TokenType::TK_WHERE => Some("WHERE"),
TokenType::TK_WINDOW => Some("WINDOW"),
TokenType::TK_WITH => Some("WITH"),
TokenType::TK_WITHOUT => Some("WITHOUT"),
TokenType::TK_BITAND => Some("&"),
TokenType::TK_BITNOT => Some("~"),
TokenType::TK_BITOR => Some("|"),
TokenType::TK_COMMA => Some(","),
TokenType::TK_CONCAT => Some("||"),
TokenType::TK_DOT => Some("."),
TokenType::TK_EQ => Some("="), // or ==
TokenType::TK_GT => Some(">"),
TokenType::TK_GE => Some(">="),
TokenType::TK_LP => Some("("),
TokenType::TK_LSHIFT => Some("<<"),
TokenType::TK_LE => Some("<="),
TokenType::TK_LT => Some("<"),
TokenType::TK_MINUS => Some("-"),
TokenType::TK_NE => Some("!="), // or <>
TokenType::TK_PLUS => Some("+"),
TokenType::TK_REM => Some("%"),
TokenType::TK_RP => Some(")"),
TokenType::TK_RSHIFT => Some(">>"),
TokenType::TK_SEMI => Some(";"),
TokenType::TK_SLASH => Some("/"),
TokenType::TK_STAR => Some("*"),
_ => None,
}
}
}
impl Display for TokenType {
// for debugging purposes
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use TokenType::*;
let s = match self {
TK_EOF => "TK_EOF",
TK_SEMI => "TK_SEMI",
TK_EXPLAIN => "TK_EXPLAIN",
TK_QUERY => "TK_QUERY",
TK_PLAN => "TK_PLAN",
TK_BEGIN => "TK_BEGIN",
TK_TRANSACTION => "TK_TRANSACTION",
TK_DEFERRED => "TK_DEFERRED",
TK_IMMEDIATE => "TK_IMMEDIATE",
TK_EXCLUSIVE => "TK_EXCLUSIVE",
TK_CONCURRENT => "TK_CONCURRENT",
TK_COMMIT => "TK_COMMIT",
TK_END => "TK_END",
TK_ROLLBACK => "TK_ROLLBACK",
TK_SAVEPOINT => "TK_SAVEPOINT",
TK_RELEASE => "TK_RELEASE",
TK_TO => "TK_TO",
TK_TABLE => "TK_TABLE",
TK_CREATE => "TK_CREATE",
TK_IF => "TK_IF",
TK_NOT => "TK_NOT",
TK_EXISTS => "TK_EXISTS",
TK_TEMP => "TK_TEMP",
TK_LP => "TK_LP",
TK_RP => "TK_RP",
TK_AS => "TK_AS",
TK_COMMA => "TK_COMMA",
TK_WITHOUT => "TK_WITHOUT",
TK_ABORT => "TK_ABORT",
TK_ACTION => "TK_ACTION",
TK_AFTER => "TK_AFTER",
TK_ANALYZE => "TK_ANALYZE",
TK_ASC => "TK_ASC",
TK_ATTACH => "TK_ATTACH",
TK_BEFORE => "TK_BEFORE",
TK_BY => "TK_BY",
TK_CASCADE => "TK_CASCADE",
TK_CAST => "TK_CAST",
TK_CONFLICT => "TK_CONFLICT",
TK_DATABASE => "TK_DATABASE",
TK_DESC => "TK_DESC",
TK_DETACH => "TK_DETACH",
TK_EACH => "TK_EACH",
TK_FAIL => "TK_FAIL",
TK_OR => "TK_OR",
TK_AND => "TK_AND",
TK_IS => "TK_IS",
TK_ISNOT => "TK_ISNOT",
TK_MATCH => "TK_MATCH",
TK_LIKE_KW => "TK_LIKE_KW",
TK_BETWEEN => "TK_BETWEEN",
TK_IN => "TK_IN",
TK_ISNULL => "TK_ISNULL",
TK_NOTNULL => "TK_NOTNULL",
TK_NE => "TK_NE",
TK_EQ => "TK_EQ",
TK_GT => "TK_GT",
TK_LE => "TK_LE",
TK_LT => "TK_LT",
TK_GE => "TK_GE",
TK_ESCAPE => "TK_ESCAPE",
TK_ID => "TK_ID",
TK_COLUMNKW => "TK_COLUMNKW",
TK_DO => "TK_DO",
TK_FOR => "TK_FOR",
TK_IGNORE => "TK_IGNORE",
TK_INITIALLY => "TK_INITIALLY",
TK_INSTEAD => "TK_INSTEAD",
TK_NO => "TK_NO",
TK_KEY => "TK_KEY",
TK_OF => "TK_OF",
TK_OFFSET => "TK_OFFSET",
TK_PRAGMA => "TK_PRAGMA",
TK_RAISE => "TK_RAISE",
TK_RECURSIVE => "TK_RECURSIVE",
TK_REPLACE => "TK_REPLACE",
TK_RESTRICT => "TK_RESTRICT",
TK_ROW => "TK_ROW",
TK_ROWS => "TK_ROWS",
TK_TRIGGER => "TK_TRIGGER",
TK_VACUUM => "TK_VACUUM",
TK_VIEW => "TK_VIEW",
TK_VIRTUAL => "TK_VIRTUAL",
TK_WITH => "TK_WITH",
TK_NULLS => "TK_NULLS",
TK_FIRST => "TK_FIRST",
TK_LAST => "TK_LAST",
TK_CURRENT => "TK_CURRENT",
TK_FOLLOWING => "TK_FOLLOWING",
TK_PARTITION => "TK_PARTITION",
TK_PRECEDING => "TK_PRECEDING",
TK_RANGE => "TK_RANGE",
TK_UNBOUNDED => "TK_UNBOUNDED",
TK_EXCLUDE => "TK_EXCLUDE",
TK_GROUPS => "TK_GROUPS",
TK_OTHERS => "TK_OTHERS",
TK_TIES => "TK_TIES",
TK_GENERATED => "TK_GENERATED",
TK_ALWAYS => "TK_ALWAYS",
TK_MATERIALIZED => "TK_MATERIALIZED",
TK_REINDEX => "TK_REINDEX",
TK_RENAME => "TK_RENAME",
TK_CTIME_KW => "TK_CTIME_KW",
TK_ANY => "TK_ANY",
TK_BITAND => "TK_BITAND",
TK_BITOR => "TK_BITOR",
TK_LSHIFT => "TK_LSHIFT",
TK_RSHIFT => "TK_RSHIFT",
TK_PLUS => "TK_PLUS",
TK_MINUS => "TK_MINUS",
TK_STAR => "TK_STAR",
TK_SLASH => "TK_SLASH",
TK_REM => "TK_REM",
TK_CONCAT => "TK_CONCAT",
TK_PTR => "TK_PTR",
TK_COLLATE => "TK_COLLATE",
TK_BITNOT => "TK_BITNOT",
TK_ON => "TK_ON",
TK_INDEXED => "TK_INDEXED",
TK_STRING => "TK_STRING",
TK_JOIN_KW => "TK_JOIN_KW",
TK_CONSTRAINT => "TK_CONSTRAINT",
TK_DEFAULT => "TK_DEFAULT",
TK_NULL => "TK_NULL",
TK_PRIMARY => "TK_PRIMARY",
TK_UNIQUE => "TK_UNIQUE",
TK_CHECK => "TK_CHECK",
TK_REFERENCES => "TK_REFERENCES",
TK_AUTOINCR => "TK_AUTOINCR",
TK_INSERT => "TK_INSERT",
TK_DELETE => "TK_DELETE",
TK_UPDATE => "TK_UPDATE",
TK_SET => "TK_SET",
TK_DEFERRABLE => "TK_DEFERRABLE",
TK_FOREIGN => "TK_FOREIGN",
TK_DROP => "TK_DROP",
TK_UNION => "TK_UNION",
TK_ALL => "TK_ALL",
TK_EXCEPT => "TK_EXCEPT",
TK_INTERSECT => "TK_INTERSECT",
TK_SELECT => "TK_SELECT",
TK_VALUES => "TK_VALUES",
TK_DISTINCT => "TK_DISTINCT",
TK_DOT => "TK_DOT",
TK_FROM => "TK_FROM",
TK_JOIN => "TK_JOIN",
TK_USING => "TK_USING",
TK_ORDER => "TK_ORDER",
TK_GROUP => "TK_GROUP",
TK_HAVING => "TK_HAVING",
TK_LIMIT => "TK_LIMIT",
TK_WHERE => "TK_WHERE",
TK_RETURNING => "TK_RETURNING",
TK_INTO => "TK_INTO",
TK_NOTHING => "TK_NOTHING",
TK_BLOB => "TK_BLOB",
TK_FLOAT => "TK_FLOAT",
TK_INTEGER => "TK_INTEGER",
TK_VARIABLE => "TK_VARIABLE",
TK_CASE => "TK_CASE",
TK_WHEN => "TK_WHEN",
TK_THEN => "TK_THEN",
TK_ELSE => "TK_ELSE",
TK_INDEX => "TK_INDEX",
TK_ALTER => "TK_ALTER",
TK_ADD => "TK_ADD",
TK_WINDOW => "TK_WINDOW",
TK_OVER => "TK_OVER",
TK_FILTER => "TK_FILTER",
TK_ILLEGAL => "TK_ILLEGAL",
};
write!(f, "{s}")
}
}
impl TokenType {
/// if your parsing process expects next token to be TK_ID, remember to call this function !!!
#[inline(always)]
pub fn fallback_id_if_ok(self) -> Self {
use TokenType::*;
match self {
TK_ABORT | TK_ACTION | TK_AFTER | TK_ANALYZE | TK_ASC | TK_ATTACH | TK_BEFORE
| TK_BEGIN | TK_BY | TK_CASCADE | TK_CAST | TK_CONFLICT | TK_DATABASE | TK_DEFERRED
| TK_DESC | TK_DETACH | TK_DO | TK_EACH | TK_END | TK_EXCLUSIVE | TK_CONCURRENT
| TK_EXPLAIN | TK_FAIL | TK_FOR | TK_IGNORE | TK_IMMEDIATE | TK_INITIALLY
| TK_INSTEAD | TK_LIKE_KW | TK_MATCH | TK_NO | TK_PLAN | TK_QUERY | TK_KEY | TK_OF
| TK_OFFSET | TK_PRAGMA | TK_RAISE | TK_RECURSIVE | TK_RELEASE | TK_REPLACE
| TK_RESTRICT | TK_ROW | TK_ROWS | TK_ROLLBACK | TK_SAVEPOINT | TK_TEMP
| TK_TRIGGER | TK_VACUUM | TK_VIEW | TK_VIRTUAL | TK_WITH | TK_NULLS | TK_FIRST
| TK_LAST | TK_CURRENT | TK_FOLLOWING | TK_PARTITION | TK_PRECEDING | TK_RANGE
| TK_UNBOUNDED | TK_EXCLUDE | TK_GROUPS | TK_OTHERS | TK_TIES | TK_ALWAYS
| TK_MATERIALIZED | TK_REINDEX | TK_RENAME | TK_CTIME_KW | TK_IF => TK_ID,
// | TK_COLUMNKW | TK_UNION | TK_EXCEPT | TK_INTERSECT | TK_GENERATED | TK_WITHOUT
// see comments in `next_token` of parser
_ => self,
}
}
}