mockgres 0.0.25

An in-memory database that replicates a reasonable subset of Postgres functionality to make unit tests that rely on a database to run.
Documentation
use crate::catalog::TableMeta;
use crate::engine::{
    Column, EvalContext, EvalMode, ScalarExpr, Value, cast_value_to_type,
    eval_scalar_expr_with_mode,
};

use super::sql_err;

pub(crate) fn eval_column_default(
    expr: &ScalarExpr,
    col: &Column,
    idx: usize,
    meta: &TableMeta,
    ctx: &EvalContext,
) -> anyhow::Result<Value> {
    let value = eval_scalar_expr_with_mode(&[], expr, &[], ctx, EvalMode::ColumnDefault)
        .map_err(|e| sql_err("XX000", e.to_string()))?;
    coerce_value_for_column(value, col, idx, meta, ctx)
}

pub(crate) fn coerce_value_for_column(
    val: Value,
    col: &Column,
    idx: usize,
    meta: &TableMeta,
    ctx: &EvalContext,
) -> anyhow::Result<Value> {
    if let Value::Null = val {
        if !col.nullable {
            return Err(sql_err("23502", format!("column {} is not null", col.name)));
        }
        if let Some(pk) = &meta.primary_key
            && pk.columns.contains(&idx)
        {
            return Err(sql_err(
                "23502",
                format!("primary key column {} cannot be null", col.name),
            ));
        }
        return Ok(Value::Null);
    }
    let coerced = cast_value_to_type(val, &col.data_type, &ctx.time_zone).map_err(|e| {
        sql_err(
            e.code,
            format!("column {} (index {}): {}", col.name, idx, e.message),
        )
    })?;
    Ok(coerced)
}