Is your feature request related to a problem or challenge?
Scalar UDFs using the default evaluate_bounds return an unbounded Null interval. During physical property analysis, this loses the output type even though ScalarFunctionExpr already stores the resolved return_field. Parent expressions that inspect range.data_type() may therefore retain redundant sorts.
#25575 addresses this for date_bin and from_unixtime with individual typed-bounds overrides. A central fallback could preserve type information for other built-in and user-defined scalar functions without requiring each function to implement evaluate_bounds solely for this purpose.
Describe the solution you'd like
Add a fallback in ScalarFunctionExpr::get_properties that uses the resolved return type to construct a typed unbounded interval when the UDF returns an unbounded Null interval.
As discussed during review of #25575:
- Replace only an unbounded
Null result; preserve any bounds the UDF provides.
- If
Interval::make_unbounded(return_type) fails, retain the original Null interval rather than failing query planning. Errors from the UDF's own bounds evaluation should continue to propagate.
- Leave
PhysicalExpr::evaluate_bounds and its constraint-solver path unchanged.
- Once equivalent behavior is covered, remove the type-only
evaluate_bounds overrides added for date_bin and from_unixtime.
Preserving a type does not itself establish ordering; existing expression-specific ordering rules must still apply.
Validation should cover successful type recovery, preservation of existing bounds, unsupported interval types, and unchanged constraint-solver behavior. Retain positive plan tests for safe timezone-free compositions, and add negative plan tests showing that required sorts remain for named-timezone function outputs and time-of-day arithmetic with intervals through a function, including midnight wraparound.
Describe alternatives you've considered
- Continue adding typed-bounds overrides to individual UDFs.
- Store
DataType independently in ExprProperties. This would require a separate design discussion because it affects the public API, consumers, and FFI compatibility.
Additional context
Follow-up to #25575 and its review discussion.
The initial local prototype also observed redundant sort removal for CAST(signum(c) AS REAL) and CAST(trunc(c) AS REAL) over sorted inputs. These provide additional compositions to validate beyond the two datetime functions.
Is your feature request related to a problem or challenge?
Scalar UDFs using the default
evaluate_boundsreturn an unboundedNullinterval. During physical property analysis, this loses the output type even thoughScalarFunctionExpralready stores the resolvedreturn_field. Parent expressions that inspectrange.data_type()may therefore retain redundant sorts.#25575 addresses this for
date_binandfrom_unixtimewith individual typed-bounds overrides. A central fallback could preserve type information for other built-in and user-defined scalar functions without requiring each function to implementevaluate_boundssolely for this purpose.Describe the solution you'd like
Add a fallback in
ScalarFunctionExpr::get_propertiesthat uses the resolved return type to construct a typed unbounded interval when the UDF returns an unboundedNullinterval.As discussed during review of #25575:
Nullresult; preserve any bounds the UDF provides.Interval::make_unbounded(return_type)fails, retain the originalNullinterval rather than failing query planning. Errors from the UDF's own bounds evaluation should continue to propagate.PhysicalExpr::evaluate_boundsand its constraint-solver path unchanged.evaluate_boundsoverrides added fordate_binandfrom_unixtime.Preserving a type does not itself establish ordering; existing expression-specific ordering rules must still apply.
Validation should cover successful type recovery, preservation of existing bounds, unsupported interval types, and unchanged constraint-solver behavior. Retain positive plan tests for safe timezone-free compositions, and add negative plan tests showing that required sorts remain for named-timezone function outputs and time-of-day arithmetic with intervals through a function, including midnight wraparound.
Describe alternatives you've considered
DataTypeindependently inExprProperties. This would require a separate design discussion because it affects the public API, consumers, and FFI compatibility.Additional context
Follow-up to #25575 and its review discussion.
The initial local prototype also observed redundant sort removal for
CAST(signum(c) AS REAL)andCAST(trunc(c) AS REAL)over sorted inputs. These provide additional compositions to validate beyond the two datetime functions.