Fix nullable query parameters: accept omission and null for ? params

Parameters declared with `?` (e.g. `$changelogUrl: String?`) now correctly
accept omission or explicit null in JSON input instead of requiring empty
strings as a workaround. Adds `Literal::Null` variant and threads it through
parameter parsing, type-checking, and Arrow array conversion.

https://claude.ai/code/session_014oGFKL7EVg1b2cyPgt9Gne
This commit is contained in:
Claude 2026-04-13 08:43:48 +00:00
parent c5a88cacb5
commit 37b7a94eb7
No known key found for this signature in database
6 changed files with 135 additions and 13 deletions

View file

@ -26,6 +26,7 @@ fn literal_to_typed_array(
num_rows: usize,
) -> Result<ArrayRef> {
Ok(match (lit, data_type) {
(Literal::Null, _) => arrow_array::new_null_array(data_type, num_rows),
(Literal::String(s), DataType::Utf8) => {
Arc::new(StringArray::from(vec![s.as_str(); num_rows])) as ArrayRef
}

View file

@ -74,6 +74,7 @@ fn evaluate_expr(batch: &RecordBatch, expr: &IRExpr, params: &ParamMap) -> Resul
/// Create a constant array from a literal value.
fn literal_to_array(lit: &Literal, num_rows: usize) -> Result<ArrayRef> {
Ok(match lit {
Literal::Null => arrow_array::new_null_array(&DataType::Utf8, num_rows),
Literal::String(s) => Arc::new(StringArray::from(vec![s.as_str(); num_rows])) as ArrayRef,
Literal::Integer(n) => {
// Try to match the most common integer types
@ -283,6 +284,7 @@ fn list_scalar_type(items: &[Literal]) -> Result<ScalarType> {
fn literal_scalar_type(lit: &Literal) -> Result<ScalarType> {
match lit {
Literal::Null => Ok(ScalarType::String),
Literal::String(_) => Ok(ScalarType::String),
Literal::Integer(_) => Ok(ScalarType::I64),
Literal::Float(_) => Ok(ScalarType::F64),

View file

@ -1225,6 +1225,7 @@ fn ir_expr_to_sql(expr: &IRExpr, params: &ParamMap) -> Option<String> {
pub(super) fn literal_to_sql(lit: &Literal) -> String {
match lit {
Literal::Null => "NULL".to_string(),
Literal::String(s) => format!("'{}'", s.replace('\'', "''")),
Literal::Integer(n) => n.to_string(),
Literal::Float(f) => f.to_string(),