matdb 0.1.0

An experimental embedded SQL-like DBMS
Documentation
use crate::ast::{SelectStatement, Statement};

use super::{lexer::Token, rename_default_table, Parser, ParserError};

impl<'a> Parser<'a> {
    pub fn try_consume_int(&mut self) -> Result<u64, ParserError> {
        match self.peek()? {
            Token::Int(i) => {
                let _ = self.lexer.next().unwrap();
                Ok(i.parse().unwrap())
            }
            token => Err(ParserError::Unexpected(token)),
        }
    }

    pub fn try_consume_mapping(&mut self) -> Result<(String, String), ParserError> {
        let table = self.try_consume_symbol()?;

        Ok((
            if let Ok(()) = self.try_consume_keyword("AS") {
                self.try_consume_symbol()?.to_string()
            } else {
                table.to_string()
            },
            table.to_string(),
        ))
    }

    fn parse_table_list(&mut self) -> Result<Vec<(String, String)>, ParserError> {
        self.make_parse_list(Self::try_consume_mapping)
    }

    pub(crate) fn parse_select_statement(&mut self) -> Result<Statement, ParserError> {
        let explain = self.try_consume_keyword("EXPLAIN").is_ok();

        self.try_consume_keyword("SELECT")?;

        let exprs = self.parse_expr_list()?;

        self.try_consume_keyword("FROM")?;

        let table_mappings = self.parse_table_list()?;

        let cond = if let Ok(_) = self.try_consume_keyword("WHERE") {
            Some(rename_default_table(
                &self.parse_expr()?,
                &table_mappings[0].0,
            ))
        } else {
            None
        };

        let version = if let Ok(_) = self.try_consume_keyword("VERSION") {
            Some(self.try_consume_int()?)
        } else {
            None
        };

        self.try_consume_semi()?;

        Ok(Statement::Select(SelectStatement {
            explain,
            expr: exprs
                .into_iter()
                .map(|e| rename_default_table(&e, &table_mappings[0].0))
                .collect(),
            cond,
            table_mappings,
            version,
        }))
    }
}