Skip to content

Commit ed2058c

Browse files
committed
fix(defaults): evaluate arbitrary DEFAULT expressions via const-fold
The DEFAULT resolver previously only handled a small set of hard-coded keywords (NOW, UUID, etc.) and returned None for everything else. Add a fallback path that parses the DEFAULT string through sqlparser-rs and runs it through the planner's constant-folding evaluator, enabling DEFAULT values like upper('hello'), 1 + 2, or concat('a', 'b') to resolve at insert time without a Data Plane round-trip. Also replace wrapping integer arithmetic in the const-folder with checked variants to prevent silent overflow on constant expressions.
1 parent 3e11ca2 commit ed2058c

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

nodedb-sql/src/planner/const_fold.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ pub fn fold_constant(expr: &SqlExpr, registry: &FunctionRegistry) -> Option<SqlV
6464

6565
fn fold_binary(l: SqlValue, op: BinaryOp, r: SqlValue) -> Option<SqlValue> {
6666
Some(match (l, op, r) {
67-
(SqlValue::Int(a), BinaryOp::Add, SqlValue::Int(b)) => SqlValue::Int(a + b),
68-
(SqlValue::Int(a), BinaryOp::Sub, SqlValue::Int(b)) => SqlValue::Int(a - b),
69-
(SqlValue::Int(a), BinaryOp::Mul, SqlValue::Int(b)) => SqlValue::Int(a * b),
67+
(SqlValue::Int(a), BinaryOp::Add, SqlValue::Int(b)) => SqlValue::Int(a.checked_add(b)?),
68+
(SqlValue::Int(a), BinaryOp::Sub, SqlValue::Int(b)) => SqlValue::Int(a.checked_sub(b)?),
69+
(SqlValue::Int(a), BinaryOp::Mul, SqlValue::Int(b)) => SqlValue::Int(a.checked_mul(b)?),
7070
(SqlValue::Float(a), BinaryOp::Add, SqlValue::Float(b)) => SqlValue::Float(a + b),
7171
(SqlValue::Float(a), BinaryOp::Sub, SqlValue::Float(b)) => SqlValue::Float(a - b),
7272
(SqlValue::Float(a), BinaryOp::Mul, SqlValue::Float(b)) => SqlValue::Float(a * b),

nodedb/src/control/planner/sql_plan_convert/value/defaults.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,30 @@ fn parse_parametric_or_literal(expr: &str, upper: &str) -> Option<nodedb_types::
6767
trimmed[1..trimmed.len() - 1].to_string(),
6868
));
6969
}
70-
None
70+
71+
// Fallback: try the plan-time const-folder for arbitrary expressions
72+
// (e.g. `upper('x')`, `1 + 2`, `concat('a', 'b')`).
73+
try_const_fold_default(expr)
74+
}
75+
76+
/// Attempt to parse the DEFAULT expression as SQL, then const-fold it.
77+
fn try_const_fold_default(expr: &str) -> Option<nodedb_types::Value> {
78+
let sql_expr = nodedb_sql::parse_expr_string(expr).ok()?;
79+
let folded = nodedb_sql::planner::const_fold::fold_constant_default(&sql_expr)?;
80+
Some(sql_value_to_ndb(folded))
81+
}
82+
83+
fn sql_value_to_ndb(v: nodedb_sql::types::SqlValue) -> nodedb_types::Value {
84+
use nodedb_sql::types::SqlValue;
85+
match v {
86+
SqlValue::Null => nodedb_types::Value::Null,
87+
SqlValue::Bool(b) => nodedb_types::Value::Bool(b),
88+
SqlValue::Int(i) => nodedb_types::Value::Integer(i),
89+
SqlValue::Float(f) => nodedb_types::Value::Float(f),
90+
SqlValue::String(s) => nodedb_types::Value::String(s),
91+
SqlValue::Bytes(b) => nodedb_types::Value::Bytes(b),
92+
SqlValue::Array(a) => {
93+
nodedb_types::Value::Array(a.into_iter().map(sql_value_to_ndb).collect())
94+
}
95+
}
7196
}

0 commit comments

Comments
 (0)