hematite-db 0.1.0

A small embeddable SQL database.
Documentation
use crate::catalog::Value;
use crate::parser::ast::{
    ComparisonOperator, Condition, Expression, LogicalOperator, SelectStatement, WhereClause,
};
use crate::query::lowering::lower_literal_value;
use std::collections::HashMap;

pub(crate) fn extract_literal_equalities(
    where_clause: &WhereClause,
) -> Option<HashMap<String, Value>> {
    let mut equalities = HashMap::new();
    for condition in &where_clause.conditions {
        collect_literal_equalities(condition, &mut equalities)?;
    }
    Some(equalities)
}

fn collect_literal_equalities(
    condition: &Condition,
    equalities: &mut HashMap<String, Value>,
) -> Option<()> {
    match condition {
        Condition::Comparison {
            left,
            operator: ComparisonOperator::Equal,
            right,
        } => {
            let (column_name, value) = match (left, right) {
                (Expression::Column(column_name), Expression::Literal(value)) => (
                    SelectStatement::column_reference_name(column_name),
                    lower_literal_value(value),
                ),
                (Expression::Literal(value), Expression::Column(column_name)) => (
                    SelectStatement::column_reference_name(column_name),
                    lower_literal_value(value),
                ),
                _ => return None,
            };

            match equalities.get(column_name) {
                Some(existing) if existing != &value => None,
                _ => {
                    equalities.insert(column_name.to_string(), value);
                    Some(())
                }
            }
        }
        Condition::Logical {
            left,
            operator: LogicalOperator::And,
            right,
        } => {
            collect_literal_equalities(left, equalities)?;
            collect_literal_equalities(right, equalities)
        }
        _ => None,
    }
}