use fsqlite_ast::Span;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
pub line: u32,
pub col: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TokenKind {
Integer(i64),
OversizedInt(String),
Float(f64),
String(String),
Blob(Vec<u8>),
Id(Arc<str>),
QuotedId(Arc<str>, bool),
Question,
QuestionNum(u32),
ColonParam(String),
AtParam(String),
DollarParam(String),
Plus,
Minus,
Star,
Slash,
Percent,
Ampersand,
Pipe,
Tilde,
ShiftLeft,
ShiftRight,
Eq, EqEq, Ne, LtGt, Lt,
Le,
Gt,
Ge,
Concat, Arrow, DoubleArrow,
Dot,
Comma,
Semicolon,
LeftParen,
RightParen,
KwAbort,
KwAction,
KwAdd,
KwAfter,
KwAll,
KwAlter,
KwAlways,
KwAnalyze,
KwAnd,
KwAs,
KwAsc,
KwAttach,
KwAutoincrement,
KwBefore,
KwBegin,
KwBetween,
KwBy,
KwCascade,
KwCase,
KwCast,
KwCheck,
KwCollate,
KwColumn,
KwCommit,
KwCommitseq,
KwConcurrent,
KwConflict,
KwConstraint,
KwCreate,
KwCross,
KwCurrentDate,
KwCurrentTime,
KwCurrentTimestamp,
KwDatabase,
KwDefault,
KwDeferrable,
KwDeferred,
KwDelete,
KwDesc,
KwDetach,
KwDistinct,
KwDo,
KwDrop,
KwEach,
KwElse,
KwEnd,
KwEscape,
KwExcept,
KwExclude,
KwExclusive,
KwExists,
KwExplain,
KwFail,
KwFilter,
KwFirst,
KwFollowing,
KwFor,
KwForeign,
KwFrom,
KwFull,
KwGenerated,
KwGlob,
KwGroup,
KwGroups,
KwHaving,
KwIf,
KwIgnore,
KwImmediate,
KwIn,
KwIndex,
KwIndexed,
KwInitially,
KwInner,
KwInsert,
KwInstead,
KwIntersect,
KwInto,
KwIs,
KwIsnull,
KwJoin,
KwKey,
KwLast,
KwLeft,
KwLike,
KwLimit,
KwMatch,
KwMaterialized,
KwNatural,
KwNo,
KwNot,
KwNothing,
KwNotnull,
KwNull,
KwNulls,
KwOf,
KwOffset,
KwOn,
KwOr,
KwOrder,
KwOthers,
KwOuter,
KwOver,
KwPartition,
KwPlan,
KwPragma,
KwPreceding,
KwPrimary,
KwQuery,
KwRaise,
KwRange,
KwRecursive,
KwReferences,
KwRegexp,
KwReindex,
KwRelease,
KwRename,
KwReplace,
KwRestrict,
KwReturning,
KwRight,
KwRollback,
KwRow,
KwRows,
KwSavepoint,
KwSelect,
KwSet,
KwStored,
KwStrict,
KwTable,
KwTemp,
KwTemporary,
KwThen,
KwTies,
KwTo,
KwTransaction,
KwTrigger,
KwTrue,
KwFalse,
KwUnbounded,
KwUnion,
KwUnique,
KwUpdate,
KwUsing,
KwVacuum,
KwValues,
KwView,
KwVirtual,
KwWhen,
KwWhere,
KwWindow,
KwWith,
KwWithout,
Eof,
Error(String),
}
impl TokenKind {
const MAX_KEYWORD_LEN: usize = "CURRENT_TIMESTAMP".len();
#[must_use]
pub(crate) fn lookup_common_keyword_bytes(s: &[u8]) -> Option<Self> {
match s.len() {
2 => {
if s.eq_ignore_ascii_case(b"AS") {
Some(Self::KwAs)
} else if s.eq_ignore_ascii_case(b"BY") {
Some(Self::KwBy)
} else if s.eq_ignore_ascii_case(b"DO") {
Some(Self::KwDo)
} else if s.eq_ignore_ascii_case(b"IF") {
Some(Self::KwIf)
} else if s.eq_ignore_ascii_case(b"IN") {
Some(Self::KwIn)
} else if s.eq_ignore_ascii_case(b"IS") {
Some(Self::KwIs)
} else if s.eq_ignore_ascii_case(b"NO") {
Some(Self::KwNo)
} else if s.eq_ignore_ascii_case(b"OF") {
Some(Self::KwOf)
} else if s.eq_ignore_ascii_case(b"ON") {
Some(Self::KwOn)
} else if s.eq_ignore_ascii_case(b"OR") {
Some(Self::KwOr)
} else if s.eq_ignore_ascii_case(b"TO") {
Some(Self::KwTo)
} else {
None
}
}
3 => {
if s.eq_ignore_ascii_case(b"AND") {
Some(Self::KwAnd)
} else if s.eq_ignore_ascii_case(b"ASC") {
Some(Self::KwAsc)
} else if s.eq_ignore_ascii_case(b"END") {
Some(Self::KwEnd)
} else if s.eq_ignore_ascii_case(b"FOR") {
Some(Self::KwFor)
} else if s.eq_ignore_ascii_case(b"KEY") {
Some(Self::KwKey)
} else if s.eq_ignore_ascii_case(b"NOT") {
Some(Self::KwNot)
} else if s.eq_ignore_ascii_case(b"SET") {
Some(Self::KwSet)
} else {
None
}
}
4 => {
if s.eq_ignore_ascii_case(b"FROM") {
Some(Self::KwFrom)
} else if s.eq_ignore_ascii_case(b"INTO") {
Some(Self::KwInto)
} else if s.eq_ignore_ascii_case(b"JOIN") {
Some(Self::KwJoin)
} else if s.eq_ignore_ascii_case(b"LEFT") {
Some(Self::KwLeft)
} else if s.eq_ignore_ascii_case(b"LIKE") {
Some(Self::KwLike)
} else if s.eq_ignore_ascii_case(b"NULL") {
Some(Self::KwNull)
} else if s.eq_ignore_ascii_case(b"THEN") {
Some(Self::KwThen)
} else if s.eq_ignore_ascii_case(b"WHEN") {
Some(Self::KwWhen)
} else {
None
}
}
5 => {
if s.eq_ignore_ascii_case(b"BEGIN") {
Some(Self::KwBegin)
} else if s.eq_ignore_ascii_case(b"CROSS") {
Some(Self::KwCross)
} else if s.eq_ignore_ascii_case(b"GROUP") {
Some(Self::KwGroup)
} else if s.eq_ignore_ascii_case(b"INNER") {
Some(Self::KwInner)
} else if s.eq_ignore_ascii_case(b"LIMIT") {
Some(Self::KwLimit)
} else if s.eq_ignore_ascii_case(b"ORDER") {
Some(Self::KwOrder)
} else if s.eq_ignore_ascii_case(b"TABLE") {
Some(Self::KwTable)
} else if s.eq_ignore_ascii_case(b"WHERE") {
Some(Self::KwWhere)
} else {
None
}
}
6 => {
if s.eq_ignore_ascii_case(b"COMMIT") {
Some(Self::KwCommit)
} else if s.eq_ignore_ascii_case(b"CREATE") {
Some(Self::KwCreate)
} else if s.eq_ignore_ascii_case(b"DELETE") {
Some(Self::KwDelete)
} else if s.eq_ignore_ascii_case(b"EXISTS") {
Some(Self::KwExists)
} else if s.eq_ignore_ascii_case(b"INSERT") {
Some(Self::KwInsert)
} else if s.eq_ignore_ascii_case(b"OFFSET") {
Some(Self::KwOffset)
} else if s.eq_ignore_ascii_case(b"SELECT") {
Some(Self::KwSelect)
} else if s.eq_ignore_ascii_case(b"UPDATE") {
Some(Self::KwUpdate)
} else if s.eq_ignore_ascii_case(b"VALUES") {
Some(Self::KwValues)
} else {
None
}
}
7 => {
if s.eq_ignore_ascii_case(b"BETWEEN") {
Some(Self::KwBetween)
} else if s.eq_ignore_ascii_case(b"DEFAULT") {
Some(Self::KwDefault)
} else if s.eq_ignore_ascii_case(b"HAVING") {
Some(Self::KwHaving)
} else if s.eq_ignore_ascii_case(b"INDEXED") {
Some(Self::KwIndexed)
} else if s.eq_ignore_ascii_case(b"PRIMARY") {
Some(Self::KwPrimary)
} else {
None
}
}
8 => {
if s.eq_ignore_ascii_case(b"DISTINCT") {
Some(Self::KwDistinct)
} else {
None
}
}
9 => {
if s.eq_ignore_ascii_case(b"RETURNING") {
Some(Self::KwReturning)
} else {
None
}
}
10 => {
if s.eq_ignore_ascii_case(b"CONCURRENT") {
Some(Self::KwConcurrent)
} else {
None
}
}
11 => {
if s.eq_ignore_ascii_case(b"TRANSACTION") {
Some(Self::KwTransaction)
} else {
None
}
}
_ => None,
}
}
#[must_use]
#[allow(clippy::too_many_lines)]
pub(crate) fn lookup_keyword_bytes(s: &[u8]) -> Option<Self> {
if let Some(keyword) = Self::lookup_common_keyword_bytes(s) {
return Some(keyword);
}
if s.is_empty() || s.len() > Self::MAX_KEYWORD_LEN || !s.is_ascii() {
return None;
}
let mut upper = [0_u8; Self::MAX_KEYWORD_LEN];
for (dst, src) in upper.iter_mut().zip(s.iter().copied()) {
*dst = src.to_ascii_uppercase();
}
match &upper[..s.len()] {
b"ABORT" => Some(Self::KwAbort),
b"ACTION" => Some(Self::KwAction),
b"ADD" => Some(Self::KwAdd),
b"AFTER" => Some(Self::KwAfter),
b"ALL" => Some(Self::KwAll),
b"ALTER" => Some(Self::KwAlter),
b"ALWAYS" => Some(Self::KwAlways),
b"ANALYZE" => Some(Self::KwAnalyze),
b"AND" => Some(Self::KwAnd),
b"AS" => Some(Self::KwAs),
b"ASC" => Some(Self::KwAsc),
b"ATTACH" => Some(Self::KwAttach),
b"AUTOINCREMENT" => Some(Self::KwAutoincrement),
b"BEFORE" => Some(Self::KwBefore),
b"BEGIN" => Some(Self::KwBegin),
b"BETWEEN" => Some(Self::KwBetween),
b"BY" => Some(Self::KwBy),
b"CASCADE" => Some(Self::KwCascade),
b"CASE" => Some(Self::KwCase),
b"CAST" => Some(Self::KwCast),
b"CHECK" => Some(Self::KwCheck),
b"COLLATE" => Some(Self::KwCollate),
b"COLUMN" => Some(Self::KwColumn),
b"COMMIT" => Some(Self::KwCommit),
b"COMMITSEQ" => Some(Self::KwCommitseq),
b"CONCURRENT" => Some(Self::KwConcurrent),
b"CONFLICT" => Some(Self::KwConflict),
b"CONSTRAINT" => Some(Self::KwConstraint),
b"CREATE" => Some(Self::KwCreate),
b"CROSS" => Some(Self::KwCross),
b"CURRENT_DATE" => Some(Self::KwCurrentDate),
b"CURRENT_TIME" => Some(Self::KwCurrentTime),
b"CURRENT_TIMESTAMP" => Some(Self::KwCurrentTimestamp),
b"DATABASE" => Some(Self::KwDatabase),
b"DEFAULT" => Some(Self::KwDefault),
b"DEFERRABLE" => Some(Self::KwDeferrable),
b"DEFERRED" => Some(Self::KwDeferred),
b"DELETE" => Some(Self::KwDelete),
b"DESC" => Some(Self::KwDesc),
b"DETACH" => Some(Self::KwDetach),
b"DISTINCT" => Some(Self::KwDistinct),
b"DO" => Some(Self::KwDo),
b"DROP" => Some(Self::KwDrop),
b"EACH" => Some(Self::KwEach),
b"ELSE" => Some(Self::KwElse),
b"END" => Some(Self::KwEnd),
b"ESCAPE" => Some(Self::KwEscape),
b"EXCEPT" => Some(Self::KwExcept),
b"EXCLUDE" => Some(Self::KwExclude),
b"EXCLUSIVE" => Some(Self::KwExclusive),
b"EXISTS" => Some(Self::KwExists),
b"EXPLAIN" => Some(Self::KwExplain),
b"FAIL" => Some(Self::KwFail),
b"FILTER" => Some(Self::KwFilter),
b"FIRST" => Some(Self::KwFirst),
b"FOLLOWING" => Some(Self::KwFollowing),
b"FOR" => Some(Self::KwFor),
b"FOREIGN" => Some(Self::KwForeign),
b"FROM" => Some(Self::KwFrom),
b"FULL" => Some(Self::KwFull),
b"GENERATED" => Some(Self::KwGenerated),
b"GLOB" => Some(Self::KwGlob),
b"GROUP" => Some(Self::KwGroup),
b"GROUPS" => Some(Self::KwGroups),
b"HAVING" => Some(Self::KwHaving),
b"IF" => Some(Self::KwIf),
b"IGNORE" => Some(Self::KwIgnore),
b"IMMEDIATE" => Some(Self::KwImmediate),
b"IN" => Some(Self::KwIn),
b"INDEX" => Some(Self::KwIndex),
b"INDEXED" => Some(Self::KwIndexed),
b"INITIALLY" => Some(Self::KwInitially),
b"INNER" => Some(Self::KwInner),
b"INSERT" => Some(Self::KwInsert),
b"INSTEAD" => Some(Self::KwInstead),
b"INTERSECT" => Some(Self::KwIntersect),
b"INTO" => Some(Self::KwInto),
b"IS" => Some(Self::KwIs),
b"ISNULL" => Some(Self::KwIsnull),
b"JOIN" => Some(Self::KwJoin),
b"KEY" => Some(Self::KwKey),
b"LAST" => Some(Self::KwLast),
b"LEFT" => Some(Self::KwLeft),
b"LIKE" => Some(Self::KwLike),
b"LIMIT" => Some(Self::KwLimit),
b"MATCH" => Some(Self::KwMatch),
b"MATERIALIZED" => Some(Self::KwMaterialized),
b"NATURAL" => Some(Self::KwNatural),
b"NO" => Some(Self::KwNo),
b"NOT" => Some(Self::KwNot),
b"NOTHING" => Some(Self::KwNothing),
b"NOTNULL" => Some(Self::KwNotnull),
b"NULL" => Some(Self::KwNull),
b"NULLS" => Some(Self::KwNulls),
b"OF" => Some(Self::KwOf),
b"OFFSET" => Some(Self::KwOffset),
b"ON" => Some(Self::KwOn),
b"OR" => Some(Self::KwOr),
b"ORDER" => Some(Self::KwOrder),
b"OTHERS" => Some(Self::KwOthers),
b"OUTER" => Some(Self::KwOuter),
b"OVER" => Some(Self::KwOver),
b"PARTITION" => Some(Self::KwPartition),
b"PLAN" => Some(Self::KwPlan),
b"PRAGMA" => Some(Self::KwPragma),
b"PRECEDING" => Some(Self::KwPreceding),
b"PRIMARY" => Some(Self::KwPrimary),
b"QUERY" => Some(Self::KwQuery),
b"RAISE" => Some(Self::KwRaise),
b"RANGE" => Some(Self::KwRange),
b"RECURSIVE" => Some(Self::KwRecursive),
b"REFERENCES" => Some(Self::KwReferences),
b"REGEXP" => Some(Self::KwRegexp),
b"REINDEX" => Some(Self::KwReindex),
b"RELEASE" => Some(Self::KwRelease),
b"RENAME" => Some(Self::KwRename),
b"REPLACE" => Some(Self::KwReplace),
b"RESTRICT" => Some(Self::KwRestrict),
b"RETURNING" => Some(Self::KwReturning),
b"RIGHT" => Some(Self::KwRight),
b"ROLLBACK" => Some(Self::KwRollback),
b"ROW" => Some(Self::KwRow),
b"ROWS" => Some(Self::KwRows),
b"SAVEPOINT" => Some(Self::KwSavepoint),
b"SELECT" => Some(Self::KwSelect),
b"SET" => Some(Self::KwSet),
b"STORED" => Some(Self::KwStored),
b"STRICT" => Some(Self::KwStrict),
b"TABLE" => Some(Self::KwTable),
b"TEMP" => Some(Self::KwTemp),
b"TEMPORARY" => Some(Self::KwTemporary),
b"THEN" => Some(Self::KwThen),
b"TIES" => Some(Self::KwTies),
b"TO" => Some(Self::KwTo),
b"TRANSACTION" => Some(Self::KwTransaction),
b"TRIGGER" => Some(Self::KwTrigger),
b"TRUE" => Some(Self::KwTrue),
b"FALSE" => Some(Self::KwFalse),
b"UNBOUNDED" => Some(Self::KwUnbounded),
b"UNION" => Some(Self::KwUnion),
b"UNIQUE" => Some(Self::KwUnique),
b"UPDATE" => Some(Self::KwUpdate),
b"USING" => Some(Self::KwUsing),
b"VACUUM" => Some(Self::KwVacuum),
b"VALUES" => Some(Self::KwValues),
b"VIEW" => Some(Self::KwView),
b"VIRTUAL" => Some(Self::KwVirtual),
b"WHEN" => Some(Self::KwWhen),
b"WHERE" => Some(Self::KwWhere),
b"WINDOW" => Some(Self::KwWindow),
b"WITH" => Some(Self::KwWith),
b"WITHOUT" => Some(Self::KwWithout),
_ => None,
}
}
#[must_use]
pub fn lookup_keyword(s: &str) -> Option<Self> {
Self::lookup_keyword_bytes(s.as_bytes())
}
#[must_use]
pub fn is_statement_start(&self) -> bool {
matches!(
self,
Self::KwSelect
| Self::KwValues
| Self::KwInsert
| Self::KwUpdate
| Self::KwDelete
| Self::KwCreate
| Self::KwDrop
| Self::KwAlter
| Self::KwBegin
| Self::KwCommit
| Self::KwEnd
| Self::KwRollback
| Self::KwSavepoint
| Self::KwRelease
| Self::KwAttach
| Self::KwDetach
| Self::KwPragma
| Self::KwVacuum
| Self::KwReindex
| Self::KwAnalyze
| Self::KwExplain
| Self::KwWith
| Self::KwReplace
)
}
#[must_use]
#[allow(clippy::too_many_lines)]
pub fn to_sql(&self) -> String {
match self {
Self::Integer(i) => i.to_string(),
Self::OversizedInt(s) | Self::Error(s) => s.clone(),
Self::Id(s) => s.to_string(),
Self::Float(f) => format!("{f}"),
Self::String(s) => format!("'{}'", s.replace('\'', "''")),
Self::Blob(b) => {
use std::fmt::Write;
let mut hex = std::string::String::with_capacity(3 + b.len() * 2);
hex.push_str("X'");
for byte in b {
let _ = write!(hex, "{byte:02X}");
}
hex.push('\'');
hex
}
Self::QuotedId(s, _) => format!("\"{}\"", s.replace('"', "\"\"")),
Self::Question => "?".to_owned(),
Self::QuestionNum(n) => format!("?{n}"),
Self::ColonParam(s) => format!(":{s}"),
Self::AtParam(s) => format!("@{s}"),
Self::DollarParam(s) => format!("${s}"),
Self::Plus => "+".to_owned(),
Self::Minus => "-".to_owned(),
Self::Star => "*".to_owned(),
Self::Slash => "/".to_owned(),
Self::Percent => "%".to_owned(),
Self::Ampersand => "&".to_owned(),
Self::Pipe => "|".to_owned(),
Self::Tilde => "~".to_owned(),
Self::ShiftLeft => "<<".to_owned(),
Self::ShiftRight => ">>".to_owned(),
Self::Eq => "=".to_owned(),
Self::EqEq => "==".to_owned(),
Self::Ne => "!=".to_owned(),
Self::LtGt => "<>".to_owned(),
Self::Lt => "<".to_owned(),
Self::Le => "<=".to_owned(),
Self::Gt => ">".to_owned(),
Self::Ge => ">=".to_owned(),
Self::Concat => "||".to_owned(),
Self::Arrow => "->".to_owned(),
Self::DoubleArrow => "->>".to_owned(),
Self::Dot => ".".to_owned(),
Self::Comma => ",".to_owned(),
Self::Semicolon => ";".to_owned(),
Self::LeftParen => "(".to_owned(),
Self::RightParen => ")".to_owned(),
Self::Eof => String::new(),
kw => kw.keyword_str().unwrap_or_default().to_owned(),
}
}
#[must_use]
#[allow(clippy::too_many_lines)]
pub const fn keyword_str(&self) -> Option<&'static str> {
match self {
Self::KwAbort => Some("ABORT"),
Self::KwAction => Some("ACTION"),
Self::KwAdd => Some("ADD"),
Self::KwAfter => Some("AFTER"),
Self::KwAll => Some("ALL"),
Self::KwAlter => Some("ALTER"),
Self::KwAlways => Some("ALWAYS"),
Self::KwAnalyze => Some("ANALYZE"),
Self::KwAnd => Some("AND"),
Self::KwAs => Some("AS"),
Self::KwAsc => Some("ASC"),
Self::KwAttach => Some("ATTACH"),
Self::KwAutoincrement => Some("AUTOINCREMENT"),
Self::KwBefore => Some("BEFORE"),
Self::KwBegin => Some("BEGIN"),
Self::KwBetween => Some("BETWEEN"),
Self::KwBy => Some("BY"),
Self::KwCascade => Some("CASCADE"),
Self::KwCase => Some("CASE"),
Self::KwCast => Some("CAST"),
Self::KwCheck => Some("CHECK"),
Self::KwCollate => Some("COLLATE"),
Self::KwColumn => Some("COLUMN"),
Self::KwCommit => Some("COMMIT"),
Self::KwCommitseq => Some("COMMITSEQ"),
Self::KwConcurrent => Some("CONCURRENT"),
Self::KwConflict => Some("CONFLICT"),
Self::KwConstraint => Some("CONSTRAINT"),
Self::KwCreate => Some("CREATE"),
Self::KwCross => Some("CROSS"),
Self::KwCurrentDate => Some("CURRENT_DATE"),
Self::KwCurrentTime => Some("CURRENT_TIME"),
Self::KwCurrentTimestamp => Some("CURRENT_TIMESTAMP"),
Self::KwDatabase => Some("DATABASE"),
Self::KwDefault => Some("DEFAULT"),
Self::KwDeferrable => Some("DEFERRABLE"),
Self::KwDeferred => Some("DEFERRED"),
Self::KwDelete => Some("DELETE"),
Self::KwDesc => Some("DESC"),
Self::KwDetach => Some("DETACH"),
Self::KwDistinct => Some("DISTINCT"),
Self::KwDo => Some("DO"),
Self::KwDrop => Some("DROP"),
Self::KwEach => Some("EACH"),
Self::KwElse => Some("ELSE"),
Self::KwEnd => Some("END"),
Self::KwEscape => Some("ESCAPE"),
Self::KwExcept => Some("EXCEPT"),
Self::KwExclude => Some("EXCLUDE"),
Self::KwExclusive => Some("EXCLUSIVE"),
Self::KwExists => Some("EXISTS"),
Self::KwExplain => Some("EXPLAIN"),
Self::KwFail => Some("FAIL"),
Self::KwFilter => Some("FILTER"),
Self::KwFirst => Some("FIRST"),
Self::KwFollowing => Some("FOLLOWING"),
Self::KwFor => Some("FOR"),
Self::KwForeign => Some("FOREIGN"),
Self::KwFrom => Some("FROM"),
Self::KwFull => Some("FULL"),
Self::KwGenerated => Some("GENERATED"),
Self::KwGlob => Some("GLOB"),
Self::KwGroup => Some("GROUP"),
Self::KwGroups => Some("GROUPS"),
Self::KwHaving => Some("HAVING"),
Self::KwIf => Some("IF"),
Self::KwIgnore => Some("IGNORE"),
Self::KwImmediate => Some("IMMEDIATE"),
Self::KwIn => Some("IN"),
Self::KwIndex => Some("INDEX"),
Self::KwIndexed => Some("INDEXED"),
Self::KwInitially => Some("INITIALLY"),
Self::KwInner => Some("INNER"),
Self::KwInsert => Some("INSERT"),
Self::KwInstead => Some("INSTEAD"),
Self::KwIntersect => Some("INTERSECT"),
Self::KwInto => Some("INTO"),
Self::KwIs => Some("IS"),
Self::KwIsnull => Some("ISNULL"),
Self::KwJoin => Some("JOIN"),
Self::KwKey => Some("KEY"),
Self::KwLast => Some("LAST"),
Self::KwLeft => Some("LEFT"),
Self::KwLike => Some("LIKE"),
Self::KwLimit => Some("LIMIT"),
Self::KwMatch => Some("MATCH"),
Self::KwMaterialized => Some("MATERIALIZED"),
Self::KwNatural => Some("NATURAL"),
Self::KwNo => Some("NO"),
Self::KwNot => Some("NOT"),
Self::KwNothing => Some("NOTHING"),
Self::KwNotnull => Some("NOTNULL"),
Self::KwNull => Some("NULL"),
Self::KwNulls => Some("NULLS"),
Self::KwOf => Some("OF"),
Self::KwOffset => Some("OFFSET"),
Self::KwOn => Some("ON"),
Self::KwOr => Some("OR"),
Self::KwOrder => Some("ORDER"),
Self::KwOthers => Some("OTHERS"),
Self::KwOuter => Some("OUTER"),
Self::KwOver => Some("OVER"),
Self::KwPartition => Some("PARTITION"),
Self::KwPlan => Some("PLAN"),
Self::KwPragma => Some("PRAGMA"),
Self::KwPreceding => Some("PRECEDING"),
Self::KwPrimary => Some("PRIMARY"),
Self::KwQuery => Some("QUERY"),
Self::KwRaise => Some("RAISE"),
Self::KwRange => Some("RANGE"),
Self::KwRecursive => Some("RECURSIVE"),
Self::KwReferences => Some("REFERENCES"),
Self::KwRegexp => Some("REGEXP"),
Self::KwReindex => Some("REINDEX"),
Self::KwRelease => Some("RELEASE"),
Self::KwRename => Some("RENAME"),
Self::KwReplace => Some("REPLACE"),
Self::KwRestrict => Some("RESTRICT"),
Self::KwReturning => Some("RETURNING"),
Self::KwRight => Some("RIGHT"),
Self::KwRollback => Some("ROLLBACK"),
Self::KwRow => Some("ROW"),
Self::KwRows => Some("ROWS"),
Self::KwSavepoint => Some("SAVEPOINT"),
Self::KwSelect => Some("SELECT"),
Self::KwSet => Some("SET"),
Self::KwStored => Some("STORED"),
Self::KwStrict => Some("STRICT"),
Self::KwTable => Some("TABLE"),
Self::KwTemp => Some("TEMP"),
Self::KwTemporary => Some("TEMPORARY"),
Self::KwThen => Some("THEN"),
Self::KwTies => Some("TIES"),
Self::KwTo => Some("TO"),
Self::KwTransaction => Some("TRANSACTION"),
Self::KwTrigger => Some("TRIGGER"),
Self::KwTrue => Some("TRUE"),
Self::KwFalse => Some("FALSE"),
Self::KwUnbounded => Some("UNBOUNDED"),
Self::KwUnion => Some("UNION"),
Self::KwUnique => Some("UNIQUE"),
Self::KwUpdate => Some("UPDATE"),
Self::KwUsing => Some("USING"),
Self::KwVacuum => Some("VACUUM"),
Self::KwValues => Some("VALUES"),
Self::KwView => Some("VIEW"),
Self::KwVirtual => Some("VIRTUAL"),
Self::KwWhen => Some("WHEN"),
Self::KwWhere => Some("WHERE"),
Self::KwWindow => Some("WINDOW"),
Self::KwWith => Some("WITH"),
Self::KwWithout => Some("WITHOUT"),
_ => None,
}
}
}