[SPARK-40945][SQL][PYTHON] Add truncate function#57476
Open
SreeramaYeshwanthGowd wants to merge 1 commit into
Open
[SPARK-40945][SQL][PYTHON] Add truncate function#57476SreeramaYeshwanthGowd wants to merge 1 commit into
SreeramaYeshwanthGowd wants to merge 1 commit into
Conversation
truncate function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
Add a built in
truncate(expr[, scale])scalar function that truncates a numeric value toward zero toscaledecimal places.scaledefaults to 0, and a negativescaletruncates digits to the left of the decimal point.API surface added:
truncate(expr)andtruncate(expr, scale)functions.truncate(col),functions.truncate(col, scale)pyspark.sql.functions.truncate(col, scale=None)Implementation notes:
Truncateis a smallRoundBasesubclass usingRoundingMode.DOWN, mirroring the existingRound(HALF_UP) andBRound(HALF_EVEN). It reuses the same input types, result type derivation, and constant scale handling.RoundBaseroutesDecimalTypethroughDecimal.changePrecision, which previously supported only the FLOOR, CEILING, HALF_UP, and HALF_EVEN modes. This addsDecimal.ROUND_DOWNand the corresponding branches so the DOWN mode is supported. The branches are trivial: on the compact (long backed) path, integer division already truncates toward zero, so no adjustment is needed; the BigDecimal path already usessetScale(scale, roundMode), which supports DOWN natively.On naming: this adds a new function named
truncaterather than overloading the existingtrunc. Spark'struncis date only (trunc(date, fmt)), and both the date form and a numerictrunc(numeric, scale)take two arguments, so they cannot be distinguished by arity the wayceil/flooroverload their scale argument. Introducing a numeric overload oftruncwould require type based dispatch at parse time, which is a larger and more error prone change. The nametruncatematches MySQL and Trino, and the behavior (truncation toward zero) matches PostgreSQLtrunc, BigQueryTRUNC, Oracle, and Snowflake.Why are the changes needed?
Truncation toward zero to a given number of decimal places is a common numeric operation that Spark cannot express directly today.
floorandceilwith a scale round toward negative and positive infinity, which is wrong for negative values, andround/broundround to nearest. The function is requested in SPARK-40945 and is provided by PostgreSQL, BigQuery, MySQL, Oracle, Snowflake, and Trino, so it also improves parity with the engines Spark users migrate from.Does this PR introduce any user-facing change?
Yes. It adds a new built in SQL function
truncateand the corresponding Scala and PySpark DataFrame API entries. No existing behavior changes; theDecimalchange only adds support for a new rounding mode and does not alter the existing modes.Example:
How was this patch tested?
Added catalyst unit tests in
MathExpressionsSuitecovering decimal (both long backed and BigDecimal backed), double, and integral inputs, positive and negative values, positive and negative scale, the default scale, and null propagation. ExtendedDecimalSuiteso its existing "respect rounding mode" test also exercisesROUND_DOWNby comparingDecimal.changePrecisionagainstBigDecimal.setScalefor the DOWN mode. Added a DataFrame API test inMathFunctionsSuite, PySpark doctests, and regeneratedsql-expression-schema.md.Was this patch authored or co-authored using generative AI tooling? No