Summary
In src/activities/execute_sql.rs, when the f64 decode arm is taken, serde_json::Number::from_f64(val) returns None for NaN and ±Infinity (since JSON has no representation for these values). The current code simply skips the insert — the column disappears from the row object entirely rather than being stored as null.
} else if let Ok(val) = row.try_get::<f64, _>(col_name) {
if let Some(n) = serde_json::Number::from_f64(val) {
row_obj.insert(col_name.to_string(), serde_json::Value::Number(n));
}
// <- no else: column is silently dropped
}
Severity
Low — edge case, but causes confusing downstream failures: $result.nan_col is left unsubstituted because the column does not exist in the JSON.
Repro
SELECT df.start(
$$SELECT 'NaN'::float8 AS nan_col, 'Infinity'::float8 AS inf_col, 1 AS normal$$ |=> 'x'
~> 'SELECT $x.nan_col AS got_nan, $x.inf_col AS got_inf, $x.normal AS got_normal',
'bug12-nan-inf'
);
-- nan_col and inf_col are MISSING from the JSON; $x.nan_col is left as-is
Fix
Add an else branch to insert serde_json::Value::Null when from_f64 returns None:
} else if let Ok(val) = row.try_get::<f64, _>(col_name) {
if let Some(n) = serde_json::Number::from_f64(val) {
row_obj.insert(col_name.to_string(), serde_json::Value::Number(n));
} else {
row_obj.insert(col_name.to_string(), serde_json::Value::Null);
}
}
Summary
In
src/activities/execute_sql.rs, when thef64decode arm is taken,serde_json::Number::from_f64(val)returnsNoneforNaNand±Infinity(since JSON has no representation for these values). The current code simply skips the insert — the column disappears from the row object entirely rather than being stored asnull.Severity
Low — edge case, but causes confusing downstream failures:
$result.nan_colis left unsubstituted because the column does not exist in the JSON.Repro
Fix
Add an
elsebranch to insertserde_json::Value::Nullwhenfrom_f64returnsNone: