Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 46 additions & 8 deletions datafusion/catalog/src/information_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ impl InformationSchemaConfig {
);
}
if let Some(return_type) = return_type {
// OUT-only rows still need to retain overload arity (for example, COUNT()).
builder.add_parameter(
catalog_name,
schema_name,
Expand All @@ -384,7 +385,7 @@ impl InformationSchemaConfig {
None::<&str>,
return_type.as_str(),
None::<&str>,
false,
is_variadic,
rid,
);
}
Expand Down Expand Up @@ -447,13 +448,34 @@ impl InformationSchemaConfig {
}

fn is_variadic(signature: &Signature) -> bool {
matches!(
signature.type_signature,
TypeSignature::Variadic(_) | TypeSignature::VariadicAny
)
fn contains_variadic(signature: &TypeSignature) -> bool {
match signature {
TypeSignature::Variadic(_) | TypeSignature::VariadicAny => true,
TypeSignature::OneOf(signatures) => {
signatures.iter().any(contains_variadic)
}
_ => false,
}
}

contains_variadic(&signature.type_signature)
}
}

fn get_nullary_return_type(
signature: &Signature,
return_field: impl FnOnce() -> Result<FieldRef>,
) -> Option<String> {
signature
.type_signature
.supports_zero_argument()
.then(return_field)
.and_then(Result::ok)
.map(|field| {
remove_native_type_prefix(&NativeType::from(field.data_type().clone()))
})
}

/// get the arguments and return types of a UDF
/// returns a tuple of (arg_types, return_type)
fn get_udf_args_and_return_types(
Expand All @@ -462,7 +484,15 @@ fn get_udf_args_and_return_types(
let signature = udf.signature();
let arg_types = signature.type_signature.get_example_types();
if arg_types.is_empty() {
Ok(vec![(vec![], None)].into_iter().collect::<BTreeSet<_>>())
let return_type = get_nullary_return_type(signature, || {
udf.return_field_from_args(ReturnFieldArgs {
arg_fields: &[],
scalar_arguments: &[],
})
});
Ok(vec![(vec![], return_type)]
.into_iter()
.collect::<BTreeSet<_>>())
} else {
Ok(arg_types
.into_iter()
Expand Down Expand Up @@ -502,7 +532,10 @@ fn get_udaf_args_and_return_types(
let signature = udaf.signature();
let arg_types = signature.type_signature.get_example_types();
if arg_types.is_empty() {
Ok(vec![(vec![], None)].into_iter().collect::<BTreeSet<_>>())
let return_type = get_nullary_return_type(signature, || udaf.return_field(&[]));
Ok(vec![(vec![], return_type)]
.into_iter()
.collect::<BTreeSet<_>>())
} else {
Ok(arg_types
.into_iter()
Expand Down Expand Up @@ -538,7 +571,12 @@ fn get_udwf_args_and_return_types(
let signature = udwf.signature();
let arg_types = signature.type_signature.get_example_types();
if arg_types.is_empty() {
Ok(vec![(vec![], None)].into_iter().collect::<BTreeSet<_>>())
let return_type = get_nullary_return_type(signature, || {
udwf.field(WindowUDFFieldArgs::new(&[], udwf.name()))
});
Ok(vec![(vec![], return_type)]
.into_iter()
.collect::<BTreeSet<_>>())
} else {
Ok(arg_types
.into_iter()
Expand Down
18 changes: 17 additions & 1 deletion datafusion/sqllogictest/test_files/information_schema.slt
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ datafusion public date_trunc datafusion public date_trunc FUNCTION true String S
datafusion public date_trunc datafusion public date_trunc FUNCTION true Time(ns) SCALAR Truncates a timestamp or time value to a specified precision. date_trunc(precision, expression)
datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(ns) SCALAR Truncates a timestamp or time value to a specified precision. date_trunc(precision, expression)
datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(ns, "+TZ") SCALAR Truncates a timestamp or time value to a specified precision. date_trunc(precision, expression)
datafusion public rank datafusion public rank FUNCTION true NULL WINDOW Returns the rank of the current row within its partition, allowing gaps between ranks. This function provides a ranking similar to `row_number`, but skips ranks for identical values. rank()
datafusion public rank datafusion public rank FUNCTION true UInt64 WINDOW Returns the rank of the current row within its partition, allowing gaps between ranks. This function provides a ranking similar to `row_number`, but skips ranks for identical values. rank()
datafusion public string_agg datafusion public string_agg FUNCTION true String AGGREGATE Concatenates the values of string expressions and places separator values between them. If ordering is required, strings are concatenated in the specified order. This aggregation function can only mix DISTINCT and ORDER BY if the ordering expression is exactly the same as the first argument expression. string_agg([DISTINCT] expression, delimiter [ORDER BY expression])

query B
Expand All @@ -887,6 +887,7 @@ datafusion public date_trunc 1 OUT NULL Timestamp(ns) NULL false 3
datafusion public date_trunc 1 IN precision String NULL false 4
datafusion public date_trunc 2 IN expression Timestamp(ns, "+TZ") NULL false 4
datafusion public date_trunc 1 OUT NULL Timestamp(ns, "+TZ") NULL false 4
datafusion public rank 1 OUT NULL UInt64 NULL false 0
datafusion public string_agg 2 IN delimiter Null NULL false 0
datafusion public string_agg 1 IN expression String NULL false 0
datafusion public string_agg 1 OUT NULL String NULL false 0
Expand All @@ -902,6 +903,21 @@ repeat Int64 2 IN 0
repeat String 1 IN 0
repeat String 1 OUT 0

# Nullary functions retain their OUT metadata, and OneOf signatures retain a
# nested variadic marker even when no representative input type is available.
query TTTB rowsort
select specific_name, data_type, parameter_mode, is_variadic
from information_schema.parameters
where specific_name in ('count', 'current_date');
----
count Int64 OUT true
current_date Date OUT false

query TT??TTT
show functions like 'count';
----
count Int64 [NULL] [NULL] AGGREGATE Returns the number of non-null values in the specified column. To include null values in the total count, use `count(*)`. count(expression)

query TT??TTT rowsort
show functions like 'date_trunc';
----
Expand Down
Loading