jayzhan211 commented on code in PR #21737:
URL: https://github.com/apache/datafusion/pull/21737#discussion_r4093491057
##########
datafusion/catalog/src/information_schema.rs:
##########
@@ -454,26 +454,35 @@ impl InformationSchemaConfig {
}
}
+/// Build the argument field for `information_schema` to provide a return type
+fn resolve_informational_field(idx: usize, t: &NativeType) -> Result<FieldRef>
{
+ // Since a native type maps to several physical types, resolve it against
`Null` data type
+ // to get the canonical `DataType` for the native type
+ let data_type = t.default_cast_for(&DataType::Null)?;
+ Ok(Arc::new(Field::new(format!("arg_{idx}"), data_type, true)))
+}
+
/// get the arguments and return types of a UDF
/// returns a tuple of (arg_types, return_type)
fn get_udf_args_and_return_types(
udf: &Arc<ScalarUDF>,
) -> Result<BTreeSet<(Vec<String>, Option<String>)>> {
let signature = udf.signature();
- let arg_types = signature.type_signature.get_example_types();
+ let arg_types = signature.type_signature.get_representative_types();
if arg_types.is_empty() {
Ok(vec![(vec![], None)].into_iter().collect::<BTreeSet<_>>())
} else {
- Ok(arg_types
+ arg_types
.into_iter()
.map(|arg_types| {
- let arg_fields: Vec<FieldRef> = arg_types
+ let mut arg_fields = arg_types
.iter()
.enumerate()
- .map(|(i, t)| {
- Arc::new(Field::new(format!("arg_{i}"), t.clone(),
true))
- })
- .collect();
+ .map(|(i, t)| resolve_informational_field(i, t))
+ .collect::<Result<Vec<FieldRef>>>()?;
+ // Even with collecting results into a set, drop duplicates
early
+ arg_fields.sort();
+ arg_fields.dedup();
Review Comment:
`Field`'s `Ord` compares `name` first, and every field is named `arg_{i}`,
so `dedup()` never removes anything. `sort()` is a no-op up to 10 args, but
from 11 args it reorders them lexicographically (`arg_0, arg_1, arg_10, arg_2,
…`). The return type is then computed from permuted argument types, while the
`arg_types` shown keep the original order.
Repro: a UDF with `Signature::exact(vec![DataType::Int32; 10] +
[DataType::Utf8])` whose `return_type` returns the last arg.
`get_udf_args_and_return_types` reports args `[Int32 ×10, String]` with return
type `Some("Int32")` instead of `Some("String")`.
The `BTreeSet` collect already dedups rows, so drop both lines:
```diff
- let mut arg_fields = arg_types
+ let arg_fields = arg_types
.iter()
.enumerate()
.map(|(i, t)| resolve_informational_field(i, t))
.collect::<Result<Vec<FieldRef>>>()?;
- // Even with collecting results into a set, drop duplicates
early
- arg_fields.sort();
- arg_fields.dedup();
```
Please add a test with more than 10 heterogeneous args.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]