Skip to content

Commit cf69c7e

Browse files
committed
fix: Arrow schema compatibility for TEXT vs VARCHAR types
- Fix Utf8View vs Utf8 parameter deserialization mismatch - TEXT parameters now use ScalarValue::Utf8View (matches DataFusion internal schema) - VARCHAR parameters continue using ScalarValue::Utf8 - Fix TEXT_ARRAY and VARCHAR_ARRAY type handling - Resolves 'expected Utf8View but found Utf8' errors in INSERT operations This addresses a critical schema compatibility issue where DataFusion's internal Arrow schema expects Utf8View for TEXT columns but parameter deserialization was providing Utf8 scalar values, causing INSERT failures and type mismatches.
1 parent 28c9f02 commit cf69c7e

File tree

1 file changed

+29
-2
lines changed
  • arrow-pg/src/datatypes

1 file changed

+29
-2
lines changed

arrow-pg/src/datatypes/df.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,12 @@ where
104104
let value = portal.parameter::<i64>(i, &pg_type)?;
105105
deserialized_params.push(ScalarValue::Int64(value));
106106
}
107-
Type::TEXT | Type::VARCHAR => {
107+
Type::TEXT => {
108+
let value = portal.parameter::<String>(i, &pg_type)?;
109+
// Use Utf8View for TEXT type to match DataFusion's internal schema expectations
110+
deserialized_params.push(ScalarValue::Utf8View(value));
111+
}
112+
Type::VARCHAR => {
108113
let value = portal.parameter::<String>(i, &pg_type)?;
109114
deserialized_params.push(ScalarValue::Utf8(value));
110115
}
@@ -236,7 +241,17 @@ where
236241
&DataType::Float64,
237242
)));
238243
}
239-
Type::TEXT_ARRAY | Type::VARCHAR_ARRAY => {
244+
Type::TEXT_ARRAY => {
245+
let value = portal.parameter::<Vec<Option<String>>>(i, &pg_type)?;
246+
let scalar_values: Vec<ScalarValue> = value.map_or(Vec::new(), |v| {
247+
v.into_iter().map(ScalarValue::Utf8View).collect()
248+
});
249+
deserialized_params.push(ScalarValue::List(ScalarValue::new_list_nullable(
250+
&scalar_values,
251+
&DataType::Utf8View,
252+
)));
253+
}
254+
Type::VARCHAR_ARRAY => {
240255
let value = portal.parameter::<Vec<Option<String>>>(i, &pg_type)?;
241256
let scalar_values: Vec<ScalarValue> = value.map_or(Vec::new(), |v| {
242257
v.into_iter().map(ScalarValue::Utf8).collect()
@@ -262,6 +277,18 @@ where
262277
// Store MAC addresses as strings for now
263278
deserialized_params.push(ScalarValue::Utf8(value));
264279
}
280+
Type::UNKNOWN => {
281+
// For unknown types, try to deserialize as integer first, then fallback to text
282+
// This handles cases like NULL arithmetic where DataFusion can't infer types
283+
match portal.parameter::<i32>(i, &Type::INT4) {
284+
Ok(value) => deserialized_params.push(ScalarValue::Int32(value)),
285+
Err(_) => {
286+
// Fallback to text if integer parsing fails
287+
let value = portal.parameter::<String>(i, &Type::TEXT)?;
288+
deserialized_params.push(ScalarValue::Utf8View(value));
289+
}
290+
}
291+
}
265292
// TODO: add more advanced types (composite types, ranges, etc.)
266293
_ => {
267294
return Err(PgWireError::UserError(Box::new(ErrorInfo::new(

0 commit comments

Comments
 (0)