{"record":{"id":"70e92a4b06da69bf","repo":"risingwavelabs/risingwave","slug":"eval-row-in-iceberg-transform-is-not-supported-yet","errorCode":null,"errorMessage":"eval_row in iceberg_transform is not supported yet","messagePattern":"eval_row in iceberg_transform is not supported yet","errorType":"error_code","errorClass":"Internal","httpStatus":null,"severity":"error","filePath":"src/expr/impl/src/scalar/external/iceberg.rs","lineNumber":73,"sourceCode":"    }\n}\n\nimpl SyncExpression for IcebergTransform {\n    fn eval(&self, data_chunk: &DataChunk) -> Result<ArrayRef> {\n        let array = self.child.eval(data_chunk)?;\n        // Convert to arrow array\n        let arrow_array = IcebergArrowConvert.to_arrow_array(&self.input_arrow_type, &array)?;\n        // Transform\n        let res_array = self.transform.transform(arrow_array).unwrap();\n        // Convert back to array ref and return it\n        Ok(Arc::new(IcebergArrowConvert.array_from_arrow_array(\n            &self.output_arrow_field,\n            &res_array,\n        )?))\n    }\n\n    fn eval_row(&self, _row: &OwnedRow) -> Result<Datum> {\n        Err(ExprError::Internal(anyhow!(\n            \"eval_row in iceberg_transform is not supported yet\"\n        )))\n    }\n}\n\n#[build_function(\"iceberg_transform(varchar, any) -> any\", type_infer = \"unreachable\")]\nfn build(return_type: DataType, mut children: Vec<BoxedExpression>) -> Result<BoxedExpression> {\n    let transform_type = {\n        let datum = children[0].eval_const()?.unwrap();\n        let str = datum.as_utf8();\n        Transform::from_str(str).map_err(|_| ExprError::InvalidParam {\n            name: \"transform type in iceberg_transform\",\n            reason: format!(\"Fail to parse {str} as iceberg transform type\").into(),\n        })?\n    };\n\n    // For Identity and Void transform, we will use `InputRef` and const null in frontend,\n    // so it should not reach here.","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/impl/src/scalar/external/iceberg.rs#L55-L91","documentation":"The iceberg_transform expression only implements row-batch (array) evaluation; its eval_row path is deliberately unimplemented and always returns this internal error. Row-at-a-time evaluation of Iceberg partition transforms is not supported.","triggerScenarios":"Evaluating an iceberg_transform expression through the sync/row evaluation path — e.g. code that calls ExprVisitor::eval_row or evaluates the expression against a single OwnedRow instead of an array.","commonSituations":"New executor or tooling code path that evaluates expressions per-row rather than per-batch; using iceberg_transform in a context (e.g. some UDF wrappers or row-based joins) that requires eval_row.","solutions":["Evaluate the expression via the array/batch path (eval) instead of eval_row.","If you must evaluate row-wise, wrap the row in a single-row array and call eval.","If this is a legitimate need, file/await upstream support for eval_row in iceberg_transform."],"exampleFix":"// before\nlet datum = expr.eval_row(&row)?;\n// after\nlet array = expr.eval(&single_row_array)?;\nlet datum = array.value_at(0).to_owned_datum();","handlingStrategy":"fallback","validationCode":"// Avoid row-wise evaluation of iceberg_transform; use batch eval:\n// let array = expr.eval(&input_array)?;","typeGuard":null,"tryCatchPattern":"match expr.eval_row(row) {\n    Ok(d) => d,\n    Err(e) if e.to_string().contains(\"not supported\") => {\n        // fall back to batch evaluation\n        let arr = expr.eval(&single_row_array)?;\n        arr.value_at(0).to_owned_datum()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never call eval_row on external/iceberg_transform expressions.","Route iceberg_transform through batch (array) evaluation paths only.","Check expression kind before choosing row vs array evaluation in generic executor code."],"tags":["iceberg","expression","unimplemented"],"backgroundTag":"method-not-implemented","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}