Skip to content

[EPIC] Support Decimal for User Defined Functions #18889

Description

@theirix

Is your feature request related to a problem or challenge?

Math UDFs in the datafusion-functions crate support integer and floating types, but not Decimals. This epic is dedicated to adding and improving decimal support for UDFs. It is a follow-up epic to adding Decimal support to the DataFusion core #3523.

So far, it is implemented for log, power binary UDFs; round, ceil unary UDF. Turns out, more code should be moved into helper functions to make UDFs leaner and abstracted from details (e.g., scalar vs. array cases, casting, etc).

Latest state (as for Aug 25)

Legend:

  • ✅ - all good, implemented
  • ❌ - not supported or not applicable
  • ⬜ - DataFusion implementation conforms to possible support, nothing to follow-up
UDF Is implemented Could Support Decimal Comments
abs Native support, #17808
any_value Native support by design
approx_distinct Native support, #23190
approx_median Coerce to floats as with majority of DBs, #21074
approx_percentile_cont See approx_median
approx_percentile_cont_with_weight See approx_median
array_agg Native support by design
avg Native support, #22713
bit_and / bit_or / bit_xor N/A, bit domain
bool_and / bool_or N/A, boolean domain
ceil Native support, #18979
corr Coerced. Native support is hard. #3572 , #3481, #19463
count / count_distinct N/A, integer domain
covar_samp / covar_pop See corr
degrees,radians,cot N/A, float domain, coerced to float
exp N/A, float domain, coerced to float
factorial N/A, integer domain
first_value / last_value Native support, #17501
floor Native support, #18979
gcd Native support, #22655
greatest Native support by design
isnan Native support, #20093
iszero Native support, #20093
least Native support by design
lcm Native support, #22655
median Native support, #24419
log Partial support, #17023, #17555
ln,log2,log10 N/A, float domain
min / max Native support, #17501
nanvl N/A, decimals are not nans
nth_value Native support by design
percentile_cont Native support, #24419
pi, random N/A, float domain
power / pow Decimals removed due to complexity, now coerced to floats. #18032
regr_* (e.g. slope) See corr
round Native support, #17054,
signum N/A, returns integer
sqrt,cbrt N/A, float domain, coerced to float
stddev / stddev_pop Coerced. Native support is hard. #3572 , #21926
sum Native support, #17591
trunc Native support, #23320
variance / var_pop See stddev
trigonometric functions N/A, float domain, coerced to float

Describe the solution you'd like

There are the following primary directions:

  1. Adding support for well-known Decimal128 and Decimal256 to existing functions
  2. Adding support for new Decimal32 and Decimal64, which are not yet fully supported
  3. Refining coercion rules to work with mixtures of floats/decimals
  4. Ensuring it would work properly with the new parse_float_as_decimal flag, forcing floats to be decimals after SQL parsing
  5. Improving tests to validate correct behaviour for floats/decimals and corner cases
  6. Moving some core support to the Arrow libraries

I welcome thoughts and discussions about these directions.

Describe alternatives you've considered

The approach of coercing decimals to floats could work, but it loses precision and data and doesn't match the behaviour of existing SQL engines (Postgres, Spark). Decimals should be first-class citizens.

Additional context

Related tickets:

Function support:

Core support:

Coercion and type issues:

Related but excluded from this epic:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    EPICA larger project, actively underway, with sub tasksenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions