mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-04 17:04:18 +01:00
finish SELECT without tests
This commit is contained in:
@@ -7,6 +7,27 @@ use turso_sqlite3_parser::lexer::{
|
||||
Scanner,
|
||||
};
|
||||
|
||||
fn bench_parser(criterion: &mut Criterion) {
|
||||
let queries = ["SELECT 1"];
|
||||
|
||||
for query in queries.iter() {
|
||||
let mut group = criterion.benchmark_group(format!("Parser `{query}`"));
|
||||
let qb = query.as_bytes();
|
||||
|
||||
group.bench_function(BenchmarkId::new("limbo_parser_query", ""), |b| {
|
||||
b.iter(|| Parser::new(black_box(qb)).next().unwrap());
|
||||
});
|
||||
|
||||
group.bench_function(BenchmarkId::new("limbo_old_parser_query", ""), |b| {
|
||||
b.iter(|| {
|
||||
OldParser::new(black_box(qb)).next().unwrap().unwrap();
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_lexer(criterion: &mut Criterion) {
|
||||
let queries = [
|
||||
"SELECT 1",
|
||||
@@ -43,44 +64,9 @@ fn bench_lexer(criterion: &mut Criterion) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_parser(criterion: &mut Criterion) {
|
||||
let queries = [
|
||||
"BEGIN",
|
||||
"BEGIN EXCLUSIVE TRANSACTION my_trans",
|
||||
"COMMIT",
|
||||
"COMMIT TRANSACTION my_trans",
|
||||
"ROLLBACK",
|
||||
"ROLLBACK TRANSACTION my_transaction TO my_savepoint",
|
||||
"SAVEPOINT my_savepoint",
|
||||
"RELEASE SAVEPOINT my_savepoint",
|
||||
];
|
||||
|
||||
for query in queries.iter() {
|
||||
let mut group = criterion.benchmark_group(format!("Parser `{query}`"));
|
||||
let qb = query.as_bytes();
|
||||
|
||||
group.bench_function(BenchmarkId::new("limbo_parser_query", ""), |b| {
|
||||
b.iter(|| {
|
||||
for stmt in Parser::new(black_box(qb)) {
|
||||
stmt.unwrap();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
group.bench_function(BenchmarkId::new("limbo_old_parser_query", ""), |b| {
|
||||
b.iter(|| {
|
||||
let mut parser = OldParser::new(black_box(qb));
|
||||
parser.next().unwrap().unwrap()
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches;
|
||||
config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None)));
|
||||
targets = bench_lexer, bench_parser
|
||||
targets = bench_parser, bench_lexer
|
||||
}
|
||||
criterion_main!(benches);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::str::{self, Bytes};
|
||||
|
||||
use strum_macros::{EnumIter, EnumString};
|
||||
|
||||
/// `?` or `$` Prepared statement arg placeholder(s)
|
||||
@@ -320,18 +318,18 @@ pub enum Expr {
|
||||
/// `DISTINCT`
|
||||
distinctness: Option<Distinctness>,
|
||||
/// arguments
|
||||
args: Option<Vec<Box<Expr>>>,
|
||||
args: Vec<Box<Expr>>,
|
||||
/// `ORDER BY`
|
||||
order_by: Option<Vec<SortedColumn>>,
|
||||
order_by: Vec<SortedColumn>,
|
||||
/// `FILTER`
|
||||
filter_over: Option<FunctionTail>,
|
||||
filter_over: FunctionTail,
|
||||
},
|
||||
/// Function call expression with '*' as arg
|
||||
FunctionCallStar {
|
||||
/// function name
|
||||
name: Name,
|
||||
/// `FILTER`
|
||||
filter_over: Option<FunctionTail>,
|
||||
filter_over: FunctionTail,
|
||||
},
|
||||
/// Identifier
|
||||
Id(Name),
|
||||
@@ -578,40 +576,33 @@ pub enum CompoundOperator {
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum OneSelect {
|
||||
/// `SELECT`
|
||||
Select(SelectInner),
|
||||
Select {
|
||||
/// `DISTINCT`
|
||||
distinctness: Option<Distinctness>,
|
||||
/// columns
|
||||
columns: Vec<ResultColumn>,
|
||||
/// `FROM` clause
|
||||
from: Option<FromClause>,
|
||||
/// `WHERE` clause
|
||||
where_clause: Option<Box<Expr>>,
|
||||
/// `GROUP BY`
|
||||
group_by: Option<GroupBy>,
|
||||
/// `WINDOW` definition
|
||||
window_clause: Vec<WindowDef>,
|
||||
},
|
||||
/// `VALUES`
|
||||
Values(Vec<Vec<Box<Expr>>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
/// `SELECT` core
|
||||
pub struct SelectInner {
|
||||
/// `DISTINCT`
|
||||
pub distinctness: Option<Distinctness>,
|
||||
/// columns
|
||||
pub columns: Vec<ResultColumn>,
|
||||
/// `FROM` clause
|
||||
pub from: Option<FromClause>,
|
||||
/// `WHERE` clause
|
||||
pub where_clause: Option<Box<Expr>>,
|
||||
/// `GROUP BY`
|
||||
pub group_by: Option<GroupBy>,
|
||||
/// `WINDOW` definition
|
||||
pub window_clause: Option<Vec<WindowDef>>,
|
||||
}
|
||||
|
||||
/// `SELECT` ... `FROM` clause
|
||||
// https://sqlite.org/syntax/join-clause.html
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct FromClause {
|
||||
/// table
|
||||
pub select: Option<Box<SelectTable>>, // FIXME mandatory
|
||||
pub select: Box<SelectTable>, // FIXME mandatory
|
||||
/// `JOIN`ed tabled
|
||||
pub joins: Option<Vec<JoinedSelectTable>>,
|
||||
/// A default join operator
|
||||
pub op: Option<JoinOperator>, // FIXME transient
|
||||
pub joins: Vec<JoinedSelectTable>,
|
||||
}
|
||||
|
||||
/// `SELECT` distinctness
|
||||
@@ -668,7 +659,7 @@ pub enum SelectTable {
|
||||
/// table
|
||||
Table(QualifiedName, Option<As>, Option<Indexed>),
|
||||
/// table function call
|
||||
TableCall(QualifiedName, Option<Vec<Box<Expr>>>, Option<As>),
|
||||
TableCall(QualifiedName, Vec<Box<Expr>>, Option<As>),
|
||||
/// `SELECT` subquery
|
||||
Select(Select, Option<As>),
|
||||
/// subquery
|
||||
@@ -1358,7 +1349,7 @@ pub struct FunctionTail {
|
||||
/// `FILTER` clause
|
||||
pub filter_clause: Option<Box<Expr>>,
|
||||
/// `OVER` clause
|
||||
pub over_clause: Option<Box<Over>>,
|
||||
pub over_clause: Option<Over>,
|
||||
}
|
||||
|
||||
/// Function call `OVER` clause
|
||||
@@ -1390,9 +1381,9 @@ pub struct Window {
|
||||
/// base window name
|
||||
pub base: Option<Name>,
|
||||
/// `PARTITION BY`
|
||||
pub partition_by: Option<Vec<Box<Expr>>>,
|
||||
pub partition_by: Vec<Box<Expr>>,
|
||||
/// `ORDER BY`
|
||||
pub order_by: Option<Vec<SortedColumn>>,
|
||||
pub order_by: Vec<SortedColumn>,
|
||||
/// frame spec
|
||||
pub frame_clause: Option<FrameClause>,
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ use crate::parser::{error::Error, token::TokenType};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/keywords.rs"));
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn is_identifier_start(b: u8) -> bool {
|
||||
b.is_ascii_uppercase() || b == b'_' || b.is_ascii_lowercase() || b > b'\x7F'
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn is_identifier_continue(b: u8) -> bool {
|
||||
b == b'$'
|
||||
|| b.is_ascii_digit()
|
||||
@@ -22,13 +24,14 @@ pub struct Token<'a> {
|
||||
}
|
||||
|
||||
pub struct Lexer<'a> {
|
||||
offset: usize,
|
||||
pub(crate) offset: usize,
|
||||
input: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Lexer<'a> {
|
||||
type Item = Result<Token<'a>, Error>;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.peek() {
|
||||
None => None, // End of file
|
||||
@@ -41,22 +44,22 @@ impl<'a> Iterator for Lexer<'a> {
|
||||
b';' => Some(Ok(self.eat_token(1, TokenType::TK_SEMI))),
|
||||
b'+' => Some(Ok(self.eat_token(1, TokenType::TK_PLUS))),
|
||||
b'*' => Some(Ok(self.eat_token(1, TokenType::TK_STAR))),
|
||||
b'/' => Some(self.eat_slash_or_comment()),
|
||||
b'/' => Some(self.mark(|l| l.eat_slash_or_comment())),
|
||||
b'%' => Some(Ok(self.eat_token(1, TokenType::TK_REM))),
|
||||
b'=' => Some(Ok(self.eat_eq())),
|
||||
b'<' => Some(Ok(self.eat_le_or_ne_or_lshift_or_lt())),
|
||||
b'>' => Some(Ok(self.eat_ge_or_gt_or_rshift())),
|
||||
b'!' => Some(self.eat_ne()),
|
||||
b'!' => Some(self.mark(|l| l.eat_ne())),
|
||||
b'|' => Some(Ok(self.eat_concat_or_bitor())),
|
||||
b',' => Some(Ok(self.eat_token(1, TokenType::TK_COMMA))),
|
||||
b'&' => Some(Ok(self.eat_token(1, TokenType::TK_BITAND))),
|
||||
b'~' => Some(Ok(self.eat_token(1, TokenType::TK_BITNOT))),
|
||||
b'\'' | b'"' | b'`' => Some(self.eat_lit_or_id()),
|
||||
b'.' => Some(self.eat_dot_or_frac()),
|
||||
b'0'..=b'9' => Some(self.eat_number()),
|
||||
b'[' => Some(self.eat_bracket()),
|
||||
b'?' | b'$' | b'@' | b'#' | b':' => Some(self.eat_var()),
|
||||
b if is_identifier_start(b) => Some(self.eat_blob_or_id()),
|
||||
b'\'' | b'"' | b'`' => Some(self.mark(|l| l.eat_lit_or_id())),
|
||||
b'.' => Some(self.mark(|l| l.eat_dot_or_frac())),
|
||||
b'0'..=b'9' => Some(self.mark(|l| l.eat_number())),
|
||||
b'[' => Some(self.mark(|l| l.eat_bracket())),
|
||||
b'?' | b'$' | b'@' | b'#' | b':' => Some(self.mark(|l| l.eat_var())),
|
||||
b if is_identifier_start(b) => Some(self.mark(|l| l.eat_blob_or_id())),
|
||||
_ => Some(Ok(self.eat_unrecognized())),
|
||||
},
|
||||
}
|
||||
@@ -74,6 +77,19 @@ impl<'a> Lexer<'a> {
|
||||
&self.input[self.offset..]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn mark<F, R>(&mut self, exc: F) -> Result<R, Error>
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<R, Error>,
|
||||
{
|
||||
let start_offset = self.offset;
|
||||
let result = exc(self);
|
||||
if result.is_err() {
|
||||
self.offset = start_offset; // Reset to the start offset if an error occurs
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns the current offset in the input without consuming.
|
||||
#[inline(always)]
|
||||
pub fn peek(&self) -> Option<u8> {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -184,164 +184,185 @@ impl Display for TokenType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use TokenType::*;
|
||||
let s = match self {
|
||||
TK_ABORT => Some("ABORT"),
|
||||
TK_ACTION => Some("ACTION"),
|
||||
TK_ADD => Some("ADD"),
|
||||
TK_AFTER => Some("AFTER"),
|
||||
TK_ALL => Some("ALL"),
|
||||
TK_ALTER => Some("ALTER"),
|
||||
TK_ANALYZE => Some("ANALYZE"),
|
||||
TK_ALWAYS => Some("ALWAYS"),
|
||||
TK_AND => Some("AND"),
|
||||
TK_AS => Some("AS"),
|
||||
TK_ASC => Some("ASC"),
|
||||
TK_ATTACH => Some("ATTACH"),
|
||||
TK_AUTOINCR => Some("AUTOINCREMENT"),
|
||||
TK_BEFORE => Some("BEFORE"),
|
||||
TK_BEGIN => Some("BEGIN"),
|
||||
TK_BETWEEN => Some("BETWEEN"),
|
||||
TK_BY => Some("BY"),
|
||||
TK_CASCADE => Some("CASCADE"),
|
||||
TK_CASE => Some("CASE"),
|
||||
TK_CAST => Some("CAST"),
|
||||
TK_CHECK => Some("CHECK"),
|
||||
TK_COLLATE => Some("COLLATE"),
|
||||
TK_COLUMNKW => Some("COLUMN"),
|
||||
TK_COMMIT => Some("COMMIT"),
|
||||
TK_CONFLICT => Some("CONFLICT"),
|
||||
TK_CONSTRAINT => Some("CONSTRAINT"),
|
||||
TK_CREATE => Some("CREATE"),
|
||||
TK_CURRENT => Some("CURRENT"),
|
||||
TK_DATABASE => Some("DATABASE"),
|
||||
TK_DEFAULT => Some("DEFAULT"),
|
||||
TK_DEFERRABLE => Some("DEFERRABLE"),
|
||||
TK_DEFERRED => Some("DEFERRED"),
|
||||
TK_DELETE => Some("DELETE"),
|
||||
TK_DESC => Some("DESC"),
|
||||
TK_DETACH => Some("DETACH"),
|
||||
TK_DISTINCT => Some("DISTINCT"),
|
||||
TK_DO => Some("DO"),
|
||||
TK_DROP => Some("DROP"),
|
||||
TK_EACH => Some("EACH"),
|
||||
TK_ELSE => Some("ELSE"),
|
||||
TK_END => Some("END"),
|
||||
TK_ESCAPE => Some("ESCAPE"),
|
||||
TK_EXCEPT => Some("EXCEPT"),
|
||||
TK_EXCLUDE => Some("EXCLUDE"),
|
||||
TK_EXCLUSIVE => Some("EXCLUSIVE"),
|
||||
TK_EXISTS => Some("EXISTS"),
|
||||
TK_EXPLAIN => Some("EXPLAIN"),
|
||||
TK_FAIL => Some("FAIL"),
|
||||
TK_FILTER => Some("FILTER"),
|
||||
TK_FIRST => Some("FIRST"),
|
||||
TK_FOLLOWING => Some("FOLLOWING"),
|
||||
TK_FOR => Some("FOR"),
|
||||
TK_FOREIGN => Some("FOREIGN"),
|
||||
TK_FROM => Some("FROM"),
|
||||
TK_GENERATED => Some("GENERATED"),
|
||||
TK_GROUP => Some("GROUP"),
|
||||
TK_GROUPS => Some("GROUPS"),
|
||||
TK_HAVING => Some("HAVING"),
|
||||
TK_IF => Some("IF"),
|
||||
TK_IGNORE => Some("IGNORE"),
|
||||
TK_IMMEDIATE => Some("IMMEDIATE"),
|
||||
TK_IN => Some("IN"),
|
||||
TK_INDEX => Some("INDEX"),
|
||||
TK_INDEXED => Some("INDEXED"),
|
||||
TK_INITIALLY => Some("INITIALLY"),
|
||||
TK_INSERT => Some("INSERT"),
|
||||
TK_INSTEAD => Some("INSTEAD"),
|
||||
TK_INTERSECT => Some("INTERSECT"),
|
||||
TK_INTO => Some("INTO"),
|
||||
TK_IS => Some("IS"),
|
||||
TK_ISNULL => Some("ISNULL"),
|
||||
TK_JOIN => Some("JOIN"),
|
||||
TK_KEY => Some("KEY"),
|
||||
TK_LAST => Some("LAST"),
|
||||
TK_LIMIT => Some("LIMIT"),
|
||||
TK_MATCH => Some("MATCH"),
|
||||
TK_MATERIALIZED => Some("MATERIALIZED"),
|
||||
TK_NO => Some("NO"),
|
||||
TK_NOT => Some("NOT"),
|
||||
TK_NOTHING => Some("NOTHING"),
|
||||
TK_NOTNULL => Some("NOTNULL"),
|
||||
TK_NULL => Some("NULL"),
|
||||
TK_NULLS => Some("NULLS"),
|
||||
TK_OF => Some("OF"),
|
||||
TK_OFFSET => Some("OFFSET"),
|
||||
TK_ON => Some("ON"),
|
||||
TK_OR => Some("OR"),
|
||||
TK_ORDER => Some("ORDER"),
|
||||
TK_OTHERS => Some("OTHERS"),
|
||||
TK_OVER => Some("OVER"),
|
||||
TK_PARTITION => Some("PARTITION"),
|
||||
TK_PLAN => Some("PLAN"),
|
||||
TK_PRAGMA => Some("PRAGMA"),
|
||||
TK_PRECEDING => Some("PRECEDING"),
|
||||
TK_PRIMARY => Some("PRIMARY"),
|
||||
TK_QUERY => Some("QUERY"),
|
||||
TK_RAISE => Some("RAISE"),
|
||||
TK_RANGE => Some("RANGE"),
|
||||
TK_RECURSIVE => Some("RECURSIVE"),
|
||||
TK_REFERENCES => Some("REFERENCES"),
|
||||
TK_REINDEX => Some("REINDEX"),
|
||||
TK_RELEASE => Some("RELEASE"),
|
||||
TK_RENAME => Some("RENAME"),
|
||||
TK_REPLACE => Some("REPLACE"),
|
||||
TK_RETURNING => Some("RETURNING"),
|
||||
TK_RESTRICT => Some("RESTRICT"),
|
||||
TK_ROLLBACK => Some("ROLLBACK"),
|
||||
TK_ROW => Some("ROW"),
|
||||
TK_ROWS => Some("ROWS"),
|
||||
TK_SAVEPOINT => Some("SAVEPOINT"),
|
||||
TK_SELECT => Some("SELECT"),
|
||||
TK_SET => Some("SET"),
|
||||
TK_TABLE => Some("TABLE"),
|
||||
TK_TEMP => Some("TEMP"), // or TEMPORARY
|
||||
TK_TIES => Some("TIES"),
|
||||
TK_THEN => Some("THEN"),
|
||||
TK_TO => Some("TO"),
|
||||
TK_TRANSACTION => Some("TRANSACTION"),
|
||||
TK_TRIGGER => Some("TRIGGER"),
|
||||
TK_UNBOUNDED => Some("UNBOUNDED"),
|
||||
TK_UNION => Some("UNION"),
|
||||
TK_UNIQUE => Some("UNIQUE"),
|
||||
TK_UPDATE => Some("UPDATE"),
|
||||
TK_USING => Some("USING"),
|
||||
TK_VACUUM => Some("VACUUM"),
|
||||
TK_VALUES => Some("VALUES"),
|
||||
TK_VIEW => Some("VIEW"),
|
||||
TK_VIRTUAL => Some("VIRTUAL"),
|
||||
TK_WHEN => Some("WHEN"),
|
||||
TK_WHERE => Some("WHERE"),
|
||||
TK_WINDOW => Some("WINDOW"),
|
||||
TK_WITH => Some("WITH"),
|
||||
TK_WITHOUT => Some("WITHOUT"),
|
||||
TK_BITAND => Some("&"),
|
||||
TK_BITNOT => Some("~"),
|
||||
TK_BITOR => Some("|"),
|
||||
TK_COMMA => Some(","),
|
||||
TK_CONCAT => Some("||"),
|
||||
TK_DOT => Some("."),
|
||||
TK_EQ => Some("="), // or ==
|
||||
TK_GT => Some(">"),
|
||||
TK_GE => Some(">="),
|
||||
TK_LP => Some("("),
|
||||
TK_LSHIFT => Some("<<"),
|
||||
TK_LE => Some("<="),
|
||||
TK_LT => Some("<"),
|
||||
TK_MINUS => Some("-"),
|
||||
TK_NE => Some("!="), // or <>
|
||||
TK_PLUS => Some("+"),
|
||||
TK_REM => Some("%"),
|
||||
TK_RP => Some(")"),
|
||||
TK_RSHIFT => Some(">>"),
|
||||
TK_SEMI => Some(";"),
|
||||
TK_SLASH => Some("/"),
|
||||
TK_STAR => Some("*"),
|
||||
_ => None,
|
||||
}
|
||||
.unwrap_or("unknown");
|
||||
TK_ABORT => "ABORT",
|
||||
TK_ACTION => "ACTION",
|
||||
TK_ADD => "ADD",
|
||||
TK_AFTER => "AFTER",
|
||||
TK_ALL => "ALL",
|
||||
TK_ALTER => "ALTER",
|
||||
TK_ANALYZE => "ANALYZE",
|
||||
TK_ALWAYS => "ALWAYS",
|
||||
TK_AND => "AND",
|
||||
TK_AS => "AS",
|
||||
TK_ASC => "ASC",
|
||||
TK_ATTACH => "ATTACH",
|
||||
TK_AUTOINCR => "AUTOINCREMENT",
|
||||
TK_BEFORE => "BEFORE",
|
||||
TK_BEGIN => "BEGIN",
|
||||
TK_BETWEEN => "BETWEEN",
|
||||
TK_BY => "BY",
|
||||
TK_CASCADE => "CASCADE",
|
||||
TK_CASE => "CASE",
|
||||
TK_CAST => "CAST",
|
||||
TK_CHECK => "CHECK",
|
||||
TK_COLLATE => "COLLATE",
|
||||
TK_COLUMNKW => "COLUMN",
|
||||
TK_COMMIT => "COMMIT",
|
||||
TK_CONFLICT => "CONFLICT",
|
||||
TK_CONSTRAINT => "CONSTRAINT",
|
||||
TK_CREATE => "CREATE",
|
||||
TK_CURRENT => "CURRENT",
|
||||
TK_DATABASE => "DATABASE",
|
||||
TK_DEFAULT => "DEFAULT",
|
||||
TK_DEFERRABLE => "DEFERRABLE",
|
||||
TK_DEFERRED => "DEFERRED",
|
||||
TK_DELETE => "DELETE",
|
||||
TK_DESC => "DESC",
|
||||
TK_DETACH => "DETACH",
|
||||
TK_DISTINCT => "DISTINCT",
|
||||
TK_DO => "DO",
|
||||
TK_DROP => "DROP",
|
||||
TK_EACH => "EACH",
|
||||
TK_ELSE => "ELSE",
|
||||
TK_END => "END",
|
||||
TK_ESCAPE => "ESCAPE",
|
||||
TK_EXCEPT => "EXCEPT",
|
||||
TK_EXCLUDE => "EXCLUDE",
|
||||
TK_EXCLUSIVE => "EXCLUSIVE",
|
||||
TK_EXISTS => "EXISTS",
|
||||
TK_EXPLAIN => "EXPLAIN",
|
||||
TK_FAIL => "FAIL",
|
||||
TK_FILTER => "FILTER",
|
||||
TK_FIRST => "FIRST",
|
||||
TK_FOLLOWING => "FOLLOWING",
|
||||
TK_FOR => "FOR",
|
||||
TK_FOREIGN => "FOREIGN",
|
||||
TK_FROM => "FROM",
|
||||
TK_GENERATED => "GENERATED",
|
||||
TK_GROUP => "GROUP",
|
||||
TK_GROUPS => "GROUPS",
|
||||
TK_HAVING => "HAVING",
|
||||
TK_IF => "IF",
|
||||
TK_IGNORE => "IGNORE",
|
||||
TK_IMMEDIATE => "IMMEDIATE",
|
||||
TK_IN => "IN",
|
||||
TK_INDEX => "INDEX",
|
||||
TK_INDEXED => "INDEXED",
|
||||
TK_INITIALLY => "INITIALLY",
|
||||
TK_INSERT => "INSERT",
|
||||
TK_INSTEAD => "INSTEAD",
|
||||
TK_INTERSECT => "INTERSECT",
|
||||
TK_INTO => "INTO",
|
||||
TK_IS => "IS",
|
||||
TK_ISNULL => "ISNULL",
|
||||
TK_JOIN => "JOIN",
|
||||
TK_KEY => "KEY",
|
||||
TK_LAST => "LAST",
|
||||
TK_LIMIT => "LIMIT",
|
||||
TK_MATCH => "MATCH",
|
||||
TK_MATERIALIZED => "MATERIALIZED",
|
||||
TK_NO => "NO",
|
||||
TK_NOT => "NOT",
|
||||
TK_NOTHING => "NOTHING",
|
||||
TK_NOTNULL => "NOTNULL",
|
||||
TK_NULL => "NULL",
|
||||
TK_NULLS => "NULLS",
|
||||
TK_OF => "OF",
|
||||
TK_OFFSET => "OFFSET",
|
||||
TK_ON => "ON",
|
||||
TK_OR => "OR",
|
||||
TK_ORDER => "ORDER",
|
||||
TK_OTHERS => "OTHERS",
|
||||
TK_OVER => "OVER",
|
||||
TK_PARTITION => "PARTITION",
|
||||
TK_PLAN => "PLAN",
|
||||
TK_PRAGMA => "PRAGMA",
|
||||
TK_PRECEDING => "PRECEDING",
|
||||
TK_PRIMARY => "PRIMARY",
|
||||
TK_QUERY => "QUERY",
|
||||
TK_RAISE => "RAISE",
|
||||
TK_RANGE => "RANGE",
|
||||
TK_RECURSIVE => "RECURSIVE",
|
||||
TK_REFERENCES => "REFERENCES",
|
||||
TK_REINDEX => "REINDEX",
|
||||
TK_RELEASE => "RELEASE",
|
||||
TK_RENAME => "RENAME",
|
||||
TK_REPLACE => "REPLACE",
|
||||
TK_RETURNING => "RETURNING",
|
||||
TK_RESTRICT => "RESTRICT",
|
||||
TK_ROLLBACK => "ROLLBACK",
|
||||
TK_ROW => "ROW",
|
||||
TK_ROWS => "ROWS",
|
||||
TK_SAVEPOINT => "SAVEPOINT",
|
||||
TK_SELECT => "SELECT",
|
||||
TK_SET => "SET",
|
||||
TK_TABLE => "TABLE",
|
||||
TK_TEMP => "TEMP", // or TEMPORARY
|
||||
TK_TIES => "TIES",
|
||||
TK_THEN => "THEN",
|
||||
TK_TO => "TO",
|
||||
TK_TRANSACTION => "TRANSACTION",
|
||||
TK_TRIGGER => "TRIGGER",
|
||||
TK_UNBOUNDED => "UNBOUNDED",
|
||||
TK_UNION => "UNION",
|
||||
TK_UNIQUE => "UNIQUE",
|
||||
TK_UPDATE => "UPDATE",
|
||||
TK_USING => "USING",
|
||||
TK_VACUUM => "VACUUM",
|
||||
TK_VALUES => "VALUES",
|
||||
TK_VIEW => "VIEW",
|
||||
TK_VIRTUAL => "VIRTUAL",
|
||||
TK_WHEN => "WHEN",
|
||||
TK_WHERE => "WHERE",
|
||||
TK_WINDOW => "WINDOW",
|
||||
TK_WITH => "WITH",
|
||||
TK_WITHOUT => "WITHOUT",
|
||||
TK_BITAND => "&",
|
||||
TK_BITNOT => "~",
|
||||
TK_BITOR => "|",
|
||||
TK_COMMA => ",",
|
||||
TK_CONCAT => "||",
|
||||
TK_DOT => ".",
|
||||
TK_EQ => "=", // or ==
|
||||
TK_GT => ">",
|
||||
TK_GE => ">=",
|
||||
TK_LP => "(",
|
||||
TK_LSHIFT => "<<",
|
||||
TK_LE => "<=",
|
||||
TK_LT => "<",
|
||||
TK_MINUS => "-",
|
||||
TK_NE => "!=", // or <>
|
||||
TK_PLUS => "+",
|
||||
TK_REM => "%",
|
||||
TK_RP => ")",
|
||||
TK_RSHIFT => ">>",
|
||||
TK_SEMI => ";",
|
||||
TK_SLASH => "/",
|
||||
TK_STAR => "*",
|
||||
_ => "unknown",
|
||||
};
|
||||
write!(f, "{s}")
|
||||
}
|
||||
}
|
||||
|
||||
impl TokenType {
|
||||
/// if your parsing process expects next token to be TK_ID, remember to call this function !!!
|
||||
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_COLUMNKW | TK_CONFLICT | TK_DATABASE
|
||||
| TK_DEFERRED | TK_DESC | TK_DETACH | TK_DO | TK_EACH | TK_END | TK_EXCLUSIVE
|
||||
| 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_WITHOUT | TK_NULLS
|
||||
| TK_FIRST | TK_LAST | TK_EXCEPT | TK_INTERSECT | TK_UNION | TK_CURRENT
|
||||
| TK_FOLLOWING | TK_PARTITION | TK_PRECEDING | TK_RANGE | TK_UNBOUNDED | TK_EXCLUDE
|
||||
| TK_GROUPS | TK_OTHERS | TK_TIES | TK_GENERATED | TK_ALWAYS | TK_MATERIALIZED
|
||||
| TK_REINDEX | TK_RENAME | TK_CTIME_KW | TK_IF => TK_ID,
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user