You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] format_string prints the unscaled value for %s of a DECIMAL and strips trailing zeros for %g #39
Spark's format_string hands its arguments to Java's java.util.Formatter (stringExpressions.scala#L2045). Two behaviors of datafusion-spark differ from that:
%s with a DECIMAL argument prints the unscaled integer. Spark prints the decimal with its scale.
%g and %G drop trailing zeros like C does. Java keeps the full precision, which is six significant digits by default.
A literal such as 1234.5 is a DECIMAL in Spark and makes %g throw (see below), so the examples use 1234.5D.
DataFusion, existing tests:
format_string.slt#L1623 expects String: 123456 for %s of arrow_cast(123.456, 'Decimal128(10, 3)'). The %S test at #L1628 and the Decimal256 test at #L1649 show the same.
%f, %e and %g with a DECIMAL argument throw in Spark (IllegalFormatConversionException: f != org.apache.spark.sql.types.Decimal) but DataFusion formats them, for example format_string.slt#L609 expects Decimal: 123.456000. DataFusion is more permissive there, so this is informational.
Additional context
Found by running the queries in datafusion/sqllogictest/test_files/spark on a local Spark and comparing the results with the expected values in the files, which is the kind of check proposed in #7. Spark results come from Apple's build of Spark 4.0.0 (4.0.0.65-apple) with a UTC session and spark.sql.ansi.enabled=false unless stated. The Spark source links point at the v4.0.0 tag. DataFusion results are the sqllogictest expectations at 9dec77584, which CI enforces. Anything marked as not run was derived from reading the code.
Running format_string.slt on Spark 4.2.0 with the runner in apache/datafusion#27165 found these queries, which raise an error in DataFusion and return a value in Spark:
Java's %b prints true for any non-null argument that is not a boolean, and %h prints the argument's hash code, here the hash of Spark's internal UTF8String.
It also happens the other way round. Spark passes its internal values to java.util.Formatter (stringExpressions.scala#L2086), so %f, %e, %g and %a fail for a DECIMAL argument with f != org.apache.spark.sql.types.Decimal. The tests pass literals such as 1.5, which are DECIMAL in Spark and DOUBLE in DataFusion (#27185), so 61 of them raise this error in Spark.
Every Spark version from 3.4 to 4.2 passes internal values to java.util.Formatter the same way, so none of this, nor the %t behavior in #14, depends on the Spark version.
Activity
andygrove commentedon Nov 6, 2026
Running
format_string.slton Spark 4.2.0 with the runner in apache/datafusion#27165 found these queries, which raise an error in DataFusion and return a value in Spark:Java's
%bprintstruefor any non-null argument that is not a boolean, and%hprints the argument's hash code, here the hash of Spark's internalUTF8String.It also happens the other way round. Spark passes its internal values to
java.util.Formatter(stringExpressions.scala#L2086), so%f,%e,%gand%afail for aDECIMALargument withf != org.apache.spark.sql.types.Decimal. The tests pass literals such as1.5, which areDECIMALin Spark andDOUBLEin DataFusion (#27185), so 61 of them raise this error in Spark.Every Spark version from 3.4 to 4.2 passes internal values to
java.util.Formatterthe same way, so none of this, nor the%tbehavior in #14, depends on the Spark version.