use sqlparser::ast;
use crate::error::{Result, SqlError};
use crate::resolver::expr::convert_value;
use crate::types::*;
pub(crate) fn convert_value_rows(
columns: &[String],
rows: &[ast::Parens<Vec<ast::Expr>>],
) -> Result<Vec<Vec<(String, SqlValue)>>> {
rows.iter()
.map(|row| {
row.iter()
.enumerate()
.map(|(i, expr)| {
let col = columns.get(i).cloned().unwrap_or_else(|| format!("col{i}"));
let val = expr_to_sql_value(expr)?;
Ok((col, val))
})
.collect::<Result<Vec<_>>>()
})
.collect()
}
pub(crate) fn expr_to_sql_value(expr: &ast::Expr) -> Result<SqlValue> {
match expr {
ast::Expr::Value(v) => convert_value(&v.value),
ast::Expr::Array(ast::Array { elem, .. }) => {
let vals = elem.iter().map(expr_to_sql_value).collect::<Result<_>>()?;
Ok(SqlValue::Array(vals))
}
ast::Expr::Function(func) => {
match crate::planner::geometry_expr::fold_geometry_function(func) {
Some(result) => result,
None => fold_constant_value(expr),
}
}
_ => fold_constant_value(expr),
}
}
fn fold_constant_value(expr: &ast::Expr) -> Result<SqlValue> {
let sql_expr =
crate::resolver::expr::convert_expr(expr, &crate::resolver::ColumnScope::Unchecked)?;
crate::planner::const_fold::fold_constant_default(&sql_expr)?.ok_or_else(|| {
SqlError::Unsupported {
detail: format!("value expression: {expr}"),
}
})
}