1use fsqlite_ast::Span;
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct Token {
11 pub kind: TokenKind,
13 pub span: Span,
15 pub line: u32,
17 pub col: u32,
19}
20
21#[derive(Debug, Clone, PartialEq)]
26pub enum TokenKind {
27 Integer(i64),
30 Float(f64),
32 String(String),
34 Blob(Vec<u8>),
36
37 Id(String),
40 QuotedId(String, bool),
43
44 Question,
47 QuestionNum(u32),
49 ColonParam(String),
51 AtParam(String),
53 DollarParam(String),
55
56 Plus,
58 Minus,
59 Star,
60 Slash,
61 Percent,
62 Ampersand,
63 Pipe,
64 Tilde,
65 ShiftLeft,
66 ShiftRight,
67 Eq, EqEq, Ne, LtGt, Lt,
72 Le,
73 Gt,
74 Ge,
75 Concat, Arrow, DoubleArrow, Dot,
81 Comma,
82 Semicolon,
83 LeftParen,
84 RightParen,
85
86 KwAbort,
88 KwAction,
89 KwAdd,
90 KwAfter,
91 KwAll,
92 KwAlter,
93 KwAlways,
94 KwAnalyze,
95 KwAnd,
96 KwAs,
97 KwAsc,
98 KwAttach,
99 KwAutoincrement,
100 KwBefore,
101 KwBegin,
102 KwBetween,
103 KwBy,
104 KwCascade,
105 KwCase,
106 KwCast,
107 KwCheck,
108 KwCollate,
109 KwColumn,
110 KwCommit,
111 KwConcurrent,
112 KwConflict,
113 KwConstraint,
114 KwCreate,
115 KwCross,
116 KwCurrentDate,
117 KwCurrentTime,
118 KwCurrentTimestamp,
119 KwDatabase,
120 KwDefault,
121 KwDeferrable,
122 KwDeferred,
123 KwDelete,
124 KwDesc,
125 KwDetach,
126 KwDistinct,
127 KwDo,
128 KwDrop,
129 KwEach,
130 KwElse,
131 KwEnd,
132 KwEscape,
133 KwExcept,
134 KwExclude,
135 KwExclusive,
136 KwExists,
137 KwExplain,
138 KwFail,
139 KwFilter,
140 KwFirst,
141 KwFollowing,
142 KwFor,
143 KwForeign,
144 KwFrom,
145 KwFull,
146 KwGenerated,
147 KwGlob,
148 KwGroup,
149 KwGroups,
150 KwHaving,
151 KwIf,
152 KwIgnore,
153 KwImmediate,
154 KwIn,
155 KwIndex,
156 KwIndexed,
157 KwInitially,
158 KwInner,
159 KwInsert,
160 KwInstead,
161 KwIntersect,
162 KwInto,
163 KwIs,
164 KwIsnull,
165 KwJoin,
166 KwKey,
167 KwLast,
168 KwLeft,
169 KwLike,
170 KwLimit,
171 KwMatch,
172 KwMaterialized,
173 KwNatural,
174 KwNo,
175 KwNot,
176 KwNothing,
177 KwNotnull,
178 KwNull,
179 KwNulls,
180 KwOf,
181 KwOffset,
182 KwOn,
183 KwOr,
184 KwOrder,
185 KwOthers,
186 KwOuter,
187 KwOver,
188 KwPartition,
189 KwPlan,
190 KwPragma,
191 KwPreceding,
192 KwPrimary,
193 KwQuery,
194 KwRaise,
195 KwRange,
196 KwRecursive,
197 KwReferences,
198 KwRegexp,
199 KwReindex,
200 KwRelease,
201 KwRename,
202 KwReplace,
203 KwRestrict,
204 KwReturning,
205 KwRight,
206 KwRollback,
207 KwRow,
208 KwRows,
209 KwSavepoint,
210 KwSelect,
211 KwSet,
212 KwStored,
213 KwStrict,
214 KwTable,
215 KwTemp,
216 KwTemporary,
217 KwThen,
218 KwTies,
219 KwTo,
220 KwTransaction,
221 KwTrigger,
222 KwTrue,
223 KwFalse,
224 KwUnbounded,
225 KwUnion,
226 KwUnique,
227 KwUpdate,
228 KwUsing,
229 KwVacuum,
230 KwValues,
231 KwView,
232 KwVirtual,
233 KwWhen,
234 KwWhere,
235 KwWindow,
236 KwWith,
237 KwWithout,
238
239 Eof,
242 Error(String),
244}
245
246impl TokenKind {
247 #[must_use]
250 #[allow(clippy::too_many_lines)]
251 pub fn lookup_keyword(s: &str) -> Option<Self> {
252 match s.to_ascii_uppercase().as_str() {
255 "ABORT" => Some(Self::KwAbort),
256 "ACTION" => Some(Self::KwAction),
257 "ADD" => Some(Self::KwAdd),
258 "AFTER" => Some(Self::KwAfter),
259 "ALL" => Some(Self::KwAll),
260 "ALTER" => Some(Self::KwAlter),
261 "ALWAYS" => Some(Self::KwAlways),
262 "ANALYZE" => Some(Self::KwAnalyze),
263 "AND" => Some(Self::KwAnd),
264 "AS" => Some(Self::KwAs),
265 "ASC" => Some(Self::KwAsc),
266 "ATTACH" => Some(Self::KwAttach),
267 "AUTOINCREMENT" => Some(Self::KwAutoincrement),
268 "BEFORE" => Some(Self::KwBefore),
269 "BEGIN" => Some(Self::KwBegin),
270 "BETWEEN" => Some(Self::KwBetween),
271 "BY" => Some(Self::KwBy),
272 "CASCADE" => Some(Self::KwCascade),
273 "CASE" => Some(Self::KwCase),
274 "CAST" => Some(Self::KwCast),
275 "CHECK" => Some(Self::KwCheck),
276 "COLLATE" => Some(Self::KwCollate),
277 "COLUMN" => Some(Self::KwColumn),
278 "COMMIT" => Some(Self::KwCommit),
279 "CONCURRENT" => Some(Self::KwConcurrent),
280 "CONFLICT" => Some(Self::KwConflict),
281 "CONSTRAINT" => Some(Self::KwConstraint),
282 "CREATE" => Some(Self::KwCreate),
283 "CROSS" => Some(Self::KwCross),
284 "CURRENT_DATE" => Some(Self::KwCurrentDate),
285 "CURRENT_TIME" => Some(Self::KwCurrentTime),
286 "CURRENT_TIMESTAMP" => Some(Self::KwCurrentTimestamp),
287 "DATABASE" => Some(Self::KwDatabase),
288 "DEFAULT" => Some(Self::KwDefault),
289 "DEFERRABLE" => Some(Self::KwDeferrable),
290 "DEFERRED" => Some(Self::KwDeferred),
291 "DELETE" => Some(Self::KwDelete),
292 "DESC" => Some(Self::KwDesc),
293 "DETACH" => Some(Self::KwDetach),
294 "DISTINCT" => Some(Self::KwDistinct),
295 "DO" => Some(Self::KwDo),
296 "DROP" => Some(Self::KwDrop),
297 "EACH" => Some(Self::KwEach),
298 "ELSE" => Some(Self::KwElse),
299 "END" => Some(Self::KwEnd),
300 "ESCAPE" => Some(Self::KwEscape),
301 "EXCEPT" => Some(Self::KwExcept),
302 "EXCLUDE" => Some(Self::KwExclude),
303 "EXCLUSIVE" => Some(Self::KwExclusive),
304 "EXISTS" => Some(Self::KwExists),
305 "EXPLAIN" => Some(Self::KwExplain),
306 "FAIL" => Some(Self::KwFail),
307 "FILTER" => Some(Self::KwFilter),
308 "FIRST" => Some(Self::KwFirst),
309 "FOLLOWING" => Some(Self::KwFollowing),
310 "FOR" => Some(Self::KwFor),
311 "FOREIGN" => Some(Self::KwForeign),
312 "FROM" => Some(Self::KwFrom),
313 "FULL" => Some(Self::KwFull),
314 "GENERATED" => Some(Self::KwGenerated),
315 "GLOB" => Some(Self::KwGlob),
316 "GROUP" => Some(Self::KwGroup),
317 "GROUPS" => Some(Self::KwGroups),
318 "HAVING" => Some(Self::KwHaving),
319 "IF" => Some(Self::KwIf),
320 "IGNORE" => Some(Self::KwIgnore),
321 "IMMEDIATE" => Some(Self::KwImmediate),
322 "IN" => Some(Self::KwIn),
323 "INDEX" => Some(Self::KwIndex),
324 "INDEXED" => Some(Self::KwIndexed),
325 "INITIALLY" => Some(Self::KwInitially),
326 "INNER" => Some(Self::KwInner),
327 "INSERT" => Some(Self::KwInsert),
328 "INSTEAD" => Some(Self::KwInstead),
329 "INTERSECT" => Some(Self::KwIntersect),
330 "INTO" => Some(Self::KwInto),
331 "IS" => Some(Self::KwIs),
332 "ISNULL" => Some(Self::KwIsnull),
333 "JOIN" => Some(Self::KwJoin),
334 "KEY" => Some(Self::KwKey),
335 "LAST" => Some(Self::KwLast),
336 "LEFT" => Some(Self::KwLeft),
337 "LIKE" => Some(Self::KwLike),
338 "LIMIT" => Some(Self::KwLimit),
339 "MATCH" => Some(Self::KwMatch),
340 "MATERIALIZED" => Some(Self::KwMaterialized),
341 "NATURAL" => Some(Self::KwNatural),
342 "NO" => Some(Self::KwNo),
343 "NOT" => Some(Self::KwNot),
344 "NOTHING" => Some(Self::KwNothing),
345 "NOTNULL" => Some(Self::KwNotnull),
346 "NULL" => Some(Self::KwNull),
347 "NULLS" => Some(Self::KwNulls),
348 "OF" => Some(Self::KwOf),
349 "OFFSET" => Some(Self::KwOffset),
350 "ON" => Some(Self::KwOn),
351 "OR" => Some(Self::KwOr),
352 "ORDER" => Some(Self::KwOrder),
353 "OTHERS" => Some(Self::KwOthers),
354 "OUTER" => Some(Self::KwOuter),
355 "OVER" => Some(Self::KwOver),
356 "PARTITION" => Some(Self::KwPartition),
357 "PLAN" => Some(Self::KwPlan),
358 "PRAGMA" => Some(Self::KwPragma),
359 "PRECEDING" => Some(Self::KwPreceding),
360 "PRIMARY" => Some(Self::KwPrimary),
361 "QUERY" => Some(Self::KwQuery),
362 "RAISE" => Some(Self::KwRaise),
363 "RANGE" => Some(Self::KwRange),
364 "RECURSIVE" => Some(Self::KwRecursive),
365 "REFERENCES" => Some(Self::KwReferences),
366 "REGEXP" => Some(Self::KwRegexp),
367 "REINDEX" => Some(Self::KwReindex),
368 "RELEASE" => Some(Self::KwRelease),
369 "RENAME" => Some(Self::KwRename),
370 "REPLACE" => Some(Self::KwReplace),
371 "RESTRICT" => Some(Self::KwRestrict),
372 "RETURNING" => Some(Self::KwReturning),
373 "RIGHT" => Some(Self::KwRight),
374 "ROLLBACK" => Some(Self::KwRollback),
375 "ROW" => Some(Self::KwRow),
376 "ROWS" => Some(Self::KwRows),
377 "SAVEPOINT" => Some(Self::KwSavepoint),
378 "SELECT" => Some(Self::KwSelect),
379 "SET" => Some(Self::KwSet),
380 "STORED" => Some(Self::KwStored),
381 "STRICT" => Some(Self::KwStrict),
382 "TABLE" => Some(Self::KwTable),
383 "TEMP" => Some(Self::KwTemp),
384 "TEMPORARY" => Some(Self::KwTemporary),
385 "THEN" => Some(Self::KwThen),
386 "TIES" => Some(Self::KwTies),
387 "TO" => Some(Self::KwTo),
388 "TRANSACTION" => Some(Self::KwTransaction),
389 "TRIGGER" => Some(Self::KwTrigger),
390 "TRUE" => Some(Self::KwTrue),
391 "FALSE" => Some(Self::KwFalse),
392 "UNBOUNDED" => Some(Self::KwUnbounded),
393 "UNION" => Some(Self::KwUnion),
394 "UNIQUE" => Some(Self::KwUnique),
395 "UPDATE" => Some(Self::KwUpdate),
396 "USING" => Some(Self::KwUsing),
397 "VACUUM" => Some(Self::KwVacuum),
398 "VALUES" => Some(Self::KwValues),
399 "VIEW" => Some(Self::KwView),
400 "VIRTUAL" => Some(Self::KwVirtual),
401 "WHEN" => Some(Self::KwWhen),
402 "WHERE" => Some(Self::KwWhere),
403 "WINDOW" => Some(Self::KwWindow),
404 "WITH" => Some(Self::KwWith),
405 "WITHOUT" => Some(Self::KwWithout),
406 _ => None,
407 }
408 }
409
410 #[must_use]
413 pub fn is_statement_start(&self) -> bool {
414 matches!(
415 self,
416 Self::KwSelect
417 | Self::KwInsert
418 | Self::KwUpdate
419 | Self::KwDelete
420 | Self::KwCreate
421 | Self::KwDrop
422 | Self::KwAlter
423 | Self::KwBegin
424 | Self::KwCommit
425 | Self::KwRollback
426 | Self::KwSavepoint
427 | Self::KwRelease
428 | Self::KwAttach
429 | Self::KwDetach
430 | Self::KwPragma
431 | Self::KwVacuum
432 | Self::KwReindex
433 | Self::KwAnalyze
434 | Self::KwExplain
435 | Self::KwWith
436 | Self::KwReplace
437 )
438 }
439
440 #[must_use]
445 #[allow(clippy::too_many_lines)]
446 pub fn to_sql(&self) -> String {
447 match self {
448 Self::Integer(i) => i.to_string(),
449 Self::Float(f) => format!("{f}"),
450 Self::String(s) => format!("'{}'", s.replace('\'', "''")),
451 Self::Blob(b) => {
452 use std::fmt::Write;
453 let mut hex = std::string::String::with_capacity(3 + b.len() * 2);
454 hex.push_str("X'");
455 for byte in b {
456 let _ = write!(hex, "{byte:02X}");
457 }
458 hex.push('\'');
459 hex
460 }
461 Self::Id(s) | Self::Error(s) => s.clone(),
462 Self::QuotedId(s, _) => format!("\"{s}\""),
463 Self::Question => "?".to_owned(),
464 Self::QuestionNum(n) => format!("?{n}"),
465 Self::ColonParam(s) => format!(":{s}"),
466 Self::AtParam(s) => format!("@{s}"),
467 Self::DollarParam(s) => format!("${s}"),
468 Self::Plus => "+".to_owned(),
469 Self::Minus => "-".to_owned(),
470 Self::Star => "*".to_owned(),
471 Self::Slash => "/".to_owned(),
472 Self::Percent => "%".to_owned(),
473 Self::Ampersand => "&".to_owned(),
474 Self::Pipe => "|".to_owned(),
475 Self::Tilde => "~".to_owned(),
476 Self::ShiftLeft => "<<".to_owned(),
477 Self::ShiftRight => ">>".to_owned(),
478 Self::Eq => "=".to_owned(),
479 Self::EqEq => "==".to_owned(),
480 Self::Ne => "!=".to_owned(),
481 Self::LtGt => "<>".to_owned(),
482 Self::Lt => "<".to_owned(),
483 Self::Le => "<=".to_owned(),
484 Self::Gt => ">".to_owned(),
485 Self::Ge => ">=".to_owned(),
486 Self::Concat => "||".to_owned(),
487 Self::Arrow => "->".to_owned(),
488 Self::DoubleArrow => "->>".to_owned(),
489 Self::Dot => ".".to_owned(),
490 Self::Comma => ",".to_owned(),
491 Self::Semicolon => ";".to_owned(),
492 Self::LeftParen => "(".to_owned(),
493 Self::RightParen => ")".to_owned(),
494 Self::Eof => String::new(),
495 kw => kw.keyword_str().unwrap_or_default().to_owned(),
497 }
498 }
499
500 #[must_use]
502 #[allow(clippy::too_many_lines)]
503 pub const fn keyword_str(&self) -> Option<&'static str> {
504 match self {
505 Self::KwAbort => Some("ABORT"),
506 Self::KwAction => Some("ACTION"),
507 Self::KwAdd => Some("ADD"),
508 Self::KwAfter => Some("AFTER"),
509 Self::KwAll => Some("ALL"),
510 Self::KwAlter => Some("ALTER"),
511 Self::KwAlways => Some("ALWAYS"),
512 Self::KwAnalyze => Some("ANALYZE"),
513 Self::KwAnd => Some("AND"),
514 Self::KwAs => Some("AS"),
515 Self::KwAsc => Some("ASC"),
516 Self::KwAttach => Some("ATTACH"),
517 Self::KwAutoincrement => Some("AUTOINCREMENT"),
518 Self::KwBefore => Some("BEFORE"),
519 Self::KwBegin => Some("BEGIN"),
520 Self::KwBetween => Some("BETWEEN"),
521 Self::KwBy => Some("BY"),
522 Self::KwCascade => Some("CASCADE"),
523 Self::KwCase => Some("CASE"),
524 Self::KwCast => Some("CAST"),
525 Self::KwCheck => Some("CHECK"),
526 Self::KwCollate => Some("COLLATE"),
527 Self::KwColumn => Some("COLUMN"),
528 Self::KwCommit => Some("COMMIT"),
529 Self::KwConcurrent => Some("CONCURRENT"),
530 Self::KwConflict => Some("CONFLICT"),
531 Self::KwConstraint => Some("CONSTRAINT"),
532 Self::KwCreate => Some("CREATE"),
533 Self::KwCross => Some("CROSS"),
534 Self::KwCurrentDate => Some("CURRENT_DATE"),
535 Self::KwCurrentTime => Some("CURRENT_TIME"),
536 Self::KwCurrentTimestamp => Some("CURRENT_TIMESTAMP"),
537 Self::KwDatabase => Some("DATABASE"),
538 Self::KwDefault => Some("DEFAULT"),
539 Self::KwDeferrable => Some("DEFERRABLE"),
540 Self::KwDeferred => Some("DEFERRED"),
541 Self::KwDelete => Some("DELETE"),
542 Self::KwDesc => Some("DESC"),
543 Self::KwDetach => Some("DETACH"),
544 Self::KwDistinct => Some("DISTINCT"),
545 Self::KwDo => Some("DO"),
546 Self::KwDrop => Some("DROP"),
547 Self::KwEach => Some("EACH"),
548 Self::KwElse => Some("ELSE"),
549 Self::KwEnd => Some("END"),
550 Self::KwEscape => Some("ESCAPE"),
551 Self::KwExcept => Some("EXCEPT"),
552 Self::KwExclude => Some("EXCLUDE"),
553 Self::KwExclusive => Some("EXCLUSIVE"),
554 Self::KwExists => Some("EXISTS"),
555 Self::KwExplain => Some("EXPLAIN"),
556 Self::KwFail => Some("FAIL"),
557 Self::KwFilter => Some("FILTER"),
558 Self::KwFirst => Some("FIRST"),
559 Self::KwFollowing => Some("FOLLOWING"),
560 Self::KwFor => Some("FOR"),
561 Self::KwForeign => Some("FOREIGN"),
562 Self::KwFrom => Some("FROM"),
563 Self::KwFull => Some("FULL"),
564 Self::KwGenerated => Some("GENERATED"),
565 Self::KwGlob => Some("GLOB"),
566 Self::KwGroup => Some("GROUP"),
567 Self::KwGroups => Some("GROUPS"),
568 Self::KwHaving => Some("HAVING"),
569 Self::KwIf => Some("IF"),
570 Self::KwIgnore => Some("IGNORE"),
571 Self::KwImmediate => Some("IMMEDIATE"),
572 Self::KwIn => Some("IN"),
573 Self::KwIndex => Some("INDEX"),
574 Self::KwIndexed => Some("INDEXED"),
575 Self::KwInitially => Some("INITIALLY"),
576 Self::KwInner => Some("INNER"),
577 Self::KwInsert => Some("INSERT"),
578 Self::KwInstead => Some("INSTEAD"),
579 Self::KwIntersect => Some("INTERSECT"),
580 Self::KwInto => Some("INTO"),
581 Self::KwIs => Some("IS"),
582 Self::KwIsnull => Some("ISNULL"),
583 Self::KwJoin => Some("JOIN"),
584 Self::KwKey => Some("KEY"),
585 Self::KwLast => Some("LAST"),
586 Self::KwLeft => Some("LEFT"),
587 Self::KwLike => Some("LIKE"),
588 Self::KwLimit => Some("LIMIT"),
589 Self::KwMatch => Some("MATCH"),
590 Self::KwMaterialized => Some("MATERIALIZED"),
591 Self::KwNatural => Some("NATURAL"),
592 Self::KwNo => Some("NO"),
593 Self::KwNot => Some("NOT"),
594 Self::KwNothing => Some("NOTHING"),
595 Self::KwNotnull => Some("NOTNULL"),
596 Self::KwNull => Some("NULL"),
597 Self::KwNulls => Some("NULLS"),
598 Self::KwOf => Some("OF"),
599 Self::KwOffset => Some("OFFSET"),
600 Self::KwOn => Some("ON"),
601 Self::KwOr => Some("OR"),
602 Self::KwOrder => Some("ORDER"),
603 Self::KwOthers => Some("OTHERS"),
604 Self::KwOuter => Some("OUTER"),
605 Self::KwOver => Some("OVER"),
606 Self::KwPartition => Some("PARTITION"),
607 Self::KwPlan => Some("PLAN"),
608 Self::KwPragma => Some("PRAGMA"),
609 Self::KwPreceding => Some("PRECEDING"),
610 Self::KwPrimary => Some("PRIMARY"),
611 Self::KwQuery => Some("QUERY"),
612 Self::KwRaise => Some("RAISE"),
613 Self::KwRange => Some("RANGE"),
614 Self::KwRecursive => Some("RECURSIVE"),
615 Self::KwReferences => Some("REFERENCES"),
616 Self::KwRegexp => Some("REGEXP"),
617 Self::KwReindex => Some("REINDEX"),
618 Self::KwRelease => Some("RELEASE"),
619 Self::KwRename => Some("RENAME"),
620 Self::KwReplace => Some("REPLACE"),
621 Self::KwRestrict => Some("RESTRICT"),
622 Self::KwReturning => Some("RETURNING"),
623 Self::KwRight => Some("RIGHT"),
624 Self::KwRollback => Some("ROLLBACK"),
625 Self::KwRow => Some("ROW"),
626 Self::KwRows => Some("ROWS"),
627 Self::KwSavepoint => Some("SAVEPOINT"),
628 Self::KwSelect => Some("SELECT"),
629 Self::KwSet => Some("SET"),
630 Self::KwStored => Some("STORED"),
631 Self::KwStrict => Some("STRICT"),
632 Self::KwTable => Some("TABLE"),
633 Self::KwTemp => Some("TEMP"),
634 Self::KwTemporary => Some("TEMPORARY"),
635 Self::KwThen => Some("THEN"),
636 Self::KwTies => Some("TIES"),
637 Self::KwTo => Some("TO"),
638 Self::KwTransaction => Some("TRANSACTION"),
639 Self::KwTrigger => Some("TRIGGER"),
640 Self::KwTrue => Some("TRUE"),
641 Self::KwFalse => Some("FALSE"),
642 Self::KwUnbounded => Some("UNBOUNDED"),
643 Self::KwUnion => Some("UNION"),
644 Self::KwUnique => Some("UNIQUE"),
645 Self::KwUpdate => Some("UPDATE"),
646 Self::KwUsing => Some("USING"),
647 Self::KwVacuum => Some("VACUUM"),
648 Self::KwValues => Some("VALUES"),
649 Self::KwView => Some("VIEW"),
650 Self::KwVirtual => Some("VIRTUAL"),
651 Self::KwWhen => Some("WHEN"),
652 Self::KwWhere => Some("WHERE"),
653 Self::KwWindow => Some("WINDOW"),
654 Self::KwWith => Some("WITH"),
655 Self::KwWithout => Some("WITHOUT"),
656 _ => None,
657 }
658 }
659}