motedb 0.8.0

AI-native embedded multimodal database for embodied intelligence (robots, AR glasses, industrial arms).
Documentation
/// Token types for SQL lexer
use phf::phf_map;

// 🚀 P1.3: Perfect hash map for O(1) keyword lookup
static KEYWORDS: phf::Map<&'static str, TokenType> = phf_map! {
    "select" => TokenType::Select,
    "from" => TokenType::From,
    "where" => TokenType::Where,
    "insert" => TokenType::Insert,
    "into" => TokenType::Into,
    "values" => TokenType::Values,
    "update" => TokenType::Update,
    "set" => TokenType::Set,
    "delete" => TokenType::Delete,
    "create" => TokenType::Create,
    "table" => TokenType::Table,
    "index" => TokenType::Index,
    "drop" => TokenType::Drop,
    "and" => TokenType::And,
    "or" => TokenType::Or,
    "not" => TokenType::Not,
    "like" => TokenType::Like,
    "in" => TokenType::In,
    "between" => TokenType::Between,
    "is" => TokenType::Is,
    "null" => TokenType::Null,
    "as" => TokenType::As,
    "order" => TokenType::Order,
    "by" => TokenType::By,
    "asc" => TokenType::Asc,
    "desc" => TokenType::Desc,
    "limit" => TokenType::Limit,
    "offset" => TokenType::Offset,
    "latest" => TokenType::Latest,
    "distinct" => TokenType::Distinct,
    "group" => TokenType::Group,
    "having" => TokenType::Having,
    "join" => TokenType::Join,
    "left" => TokenType::Left,
    "right" => TokenType::Right,
    "inner" => TokenType::Inner,
    "outer" => TokenType::Outer,
    "full" => TokenType::Full,
    "on" => TokenType::On,
    "primary" => TokenType::Primary,
    "key" => TokenType::Key,
    "using" => TokenType::Using,
    "array" => TokenType::Array,
    "show" => TokenType::Show,
    "describe" => TokenType::Describe,
    "tables" => TokenType::Tables,
    "alter" => TokenType::Alter,
    "integer" => TokenType::Integer,
    "int" => TokenType::Integer,
    "bigint" => TokenType::BigInt,
    "float" => TokenType::Float,
    "real" => TokenType::Float,
    "double" => TokenType::Float,
    "text" => TokenType::Text,
    "varchar" => TokenType::Text,
    "string" => TokenType::Text,
    "timestamp" => TokenType::Timestamp,
    "datetime" => TokenType::Timestamp,
    "vector" => TokenType::Vector,
    "geometry" => TokenType::Geometry,
    "geom" => TokenType::Geometry,
    "boolean" => TokenType::Boolean,
    "bool" => TokenType::Boolean,
    "true" => TokenType::True,
    "false" => TokenType::False,
    "auto_increment" => TokenType::AutoIncrement,
    "timeseries" => TokenType::Timeseries,
    "ttl" => TokenType::Ttl,
    "begin" => TokenType::Begin,
    "commit" => TokenType::Commit,
    "rollback" => TokenType::Rollback,
    "case" => TokenType::Case,
    "when" => TokenType::When,
    "then" => TokenType::Then,
    "else" => TokenType::Else,
    "end" => TokenType::End,
    "union" => TokenType::Union,
    "intersect" => TokenType::Intersect,
    "except" => TokenType::Except,
    "all" => TokenType::All,
    "add" => TokenType::Add,
    "default" => TokenType::Default,
    "with" => TokenType::With,
    "recursive" => TokenType::Recursive,
    "over" => TokenType::Over,
    "partition" => TokenType::Partition,
};

#[derive(Debug, Clone, PartialEq)]
pub enum TokenType {
    // Keywords
    Select,
    From,
    Where,
    Insert,
    Into,
    Values,
    Update,
    Set,
    Delete,
    Create,
    Table,
    Index,
    Drop,
    And,
    Or,
    Not,
    Like,
    In,
    Between,
    Is,
    Null,
    As,
    Order,
    By,
    Asc,
    Desc,
    Limit,
    Offset,
    Latest,   // LATEST (for LATEST BY)
    Distinct, // DISTINCT
    Group,
    Having,
    Join,
    Left,
    Right,
    Inner,
    Full,
    Outer,
    On,
    Primary,       // PRIMARY
    Key,           // KEY
    Using,         // USING (for CREATE INDEX ... USING type)
    Array,         // ARRAY (for array literals)
    Show,          // SHOW
    Describe,      // DESCRIBE or DESC
    Tables,        // TABLES
    Alter,         // ALTER
    AutoIncrement, // AUTO_INCREMENT
    Timeseries,    // TIMESERIES
    Ttl,           // TTL
    Begin,         // BEGIN
    Commit,        // COMMIT
    Rollback,      // ROLLBACK
    Case,          // CASE
    When,          // WHEN
    Then,          // THEN
    Else,          // ELSE
    End,           // END
    Union,         // UNION
    Intersect,     // INTERSECT
    Except,        // EXCEPT
    Over,          // OVER (window functions)
    Partition,     // PARTITION (window functions)
    All,           // ALL
    Add,           // ADD (ALTER TABLE ADD COLUMN)
    Default,       // DEFAULT (column default value)
    With,          // WITH (CTE)
    Recursive,     // RECURSIVE (recursive CTE marker; v1 accepts but rejects self-reference)

    // Data types
    Integer,
    BigInt, // 🚀 Phase 4: BIGINT type (i64)
    Float,
    Text,
    Timestamp,
    Vector,
    Geometry,
    Boolean,

    // Operators
    Eq,      // =
    Ne,      // != or <>
    Lt,      // <
    Gt,      // >
    Le,      // <=
    Ge,      // >=
    Plus,    // +
    Minus,   // -
    Star,    // *
    Slash,   // /
    Percent, // %
    /// String concatenation operator `||` (SQL standard).
    DoublePipe,

    // E-SQL Vector Distance Operators
    L2Distance,     // <-> (Euclidean distance)
    CosineDistance, // <=> (Cosine distance)
    DotProduct,     // <#> (Inner product)

    // Delimiters
    LParen,    // (
    RParen,    // )
    LBracket,  // [
    RBracket,  // ]
    Comma,     // ,
    Semicolon, // ;
    Dot,       // .

    // Literals
    Number(f64),
    /// A pure integer literal that fits in i64 (e.g. 42, -7).
    /// Distinct from Number to preserve Integer type for type-sensitive
    /// operations (7/2 = Integer(3) vs 7.0/2 = Float(3.5)).
    PureInteger(i64),
    /// A pure integer literal that overflows i64 (e.g. 9223372036854775808 = 2^63).
    /// Kept as i128 to preserve exact value distinction that f64 loses.
    /// Without this, `-9223372036854775808` (i64::MIN) parsed as f64 and
    /// collapsed to i64::MAX+1 incorrectly.
    OverflowInteger(i128),
    String(String),
    Identifier(String),
    True,
    False,

    // Special
    Parameter(usize), // ? or ?1, ?2, ... (bind variable)
    Eof,
}

#[derive(Debug, Clone)]
pub struct Token {
    pub token_type: TokenType,
    pub line: usize,
    pub column: usize,
}

impl Token {
    pub fn new(token_type: TokenType, line: usize, column: usize) -> Self {
        Self {
            token_type,
            line,
            column,
        }
    }
}

impl TokenType {
    /// Check if this token is a keyword — zero-allocation lookup.
    /// Lowercases into a stack buffer (all keywords are ASCII, max 14 chars).
    pub fn from_keyword(s: &str) -> Option<Self> {
        let len = s.len();
        if len > 14 || len == 0 {
            return None;
        }
        let mut buf = [0u8; 16];
        let bytes = s.as_bytes();
        for i in 0..len {
            buf[i] = bytes[i].to_ascii_lowercase();
        }
        // Safety: buf[..len] is valid ASCII after to_ascii_lowercase
        let lower = unsafe { std::str::from_utf8_unchecked(&buf[..len]) };
        KEYWORDS.get(lower).cloned()
    }
}