Skip to content

fix: log(0.0::float8) should error, not return -inf - #24399

Open
shinzoxD wants to merge 1 commit into
apache:mainfrom
shinzoxD:fix/log-zero-domain-error
Open

fix: log(0.0::float8) should error, not return -inf#24399
shinzoxD wants to merge 1 commit into
apache:mainfrom
shinzoxD:fix/log-zero-domain-error

Conversation

@shinzoxD

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

SELECT log(0.0::float8) currently returns -inf. PostgreSQL raises ERROR: cannot take logarithm of zero.

This is the same class of domain error already accepted for sqrt of a negative number (#22260 / #22308), power(0, negative) (#22272), and factorial of a negative number (#22270). IEEE 754 would yield -inf; PostgreSQL treats it as undefined.

A previous attempt (#22564) grew into a log-function refactor (simplification rewrites, log(1, 64), etc.) and was closed. This PR stays scoped to the issue: reject a zero value at evaluation time.

What changes are included in this PR?

  • log now returns cannot take logarithm of zero when the number being logged is zero (including -0.0, float32/float64, and decimal zeros).
  • A zero base (log(0, 64)) and log(1, 64) are unchanged. Those are separate compatibility cases.
  • Existing log simplifications (log(a, 1) => 0, log(a, a) => 1, log(a, power(a, b)) => b) are unchanged.
  • User-guide note updated: it still claimed log(0) returns -inf and sqrt(-1) returns NaN, both of which are now domain errors.

Are these changes tested?

Yes.

  • Unit tests in datafusion/functions/src/math/log.rs cover unary/binary float64, float32, -0.0, array input, decimal128, and decimal256.
  • math.slt adds the issue query plus two-arg, negative-zero, column, and decimal cases, matching the style of the power(0, -1) tests.
  • scalar.slt updates the previous log(0) => -Infinity expectation to the domain error, and keeps log(1, 64) => Infinity.

Ran:

  • cargo test -p datafusion-functions --lib math::log
  • cargo clippy -p datafusion-functions --lib -- -D warnings
  • cargo test -p datafusion-sqllogictest --test sqllogictests -- math.slt
  • cargo test -p datafusion-sqllogictest --test sqllogictests -- scalar.slt (log cases pass; later failures are missing testing submodule testdata for aggregate_test_100, unrelated)

Are there any user-facing changes?

Yes. log(0), log(0.0::float8), and other zero values now fail the query with cannot take logarithm of zero instead of returning -inf. Queries that relied on the IEEE result need to filter zeros first.

PostgreSQL treats log(0.0::float8) as a domain error. DataFusion
previously returned -inf via IEEE 754. Match the same class of
domain error already used for sqrt(negative), power(0, negative),
and factorial(negative).

Only the logged value is checked. A zero base (log(0, x)) and
log(1, 64) are left unchanged so this stays scoped to apache#22261.
Copilot AI lite review requested due to automatic review settings August 15, 2026 20:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added documentation Improvements or additions to documentation sqllogictest SQL Logic Tests (.slt) functions Changes to functions implementation labels Aug 15, 2026
@kosiew

kosiew commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

hi @shinzoxD
Can you fix the CI errors?

@kosiew kosiew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shinzoxD,

Thanks for working on this. The new PostgreSQL-compatible domain error handling and the additional coverage look useful overall.

I found one simplification path that can still bypass the new zero-value invariant, so I think that needs to be addressed before merging. I also left a small testing suggestion for the additional physical types touched by this change.

Ok(ExprSimplifyResult::Simplified(b))
}
number => {
if number == base && !base_nullable {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this simplification can bypass the new invariant. log(a, a) is simplified directly to 1, so the logged value is never evaluated. For example, SELECT log(0.0::float8, 0.0::float8) returns 1.0 on this commit instead of the expected domain error.

The similar log(a, power(a, b)) rewrite around lines 405-412 can also bypass the check when the power result is zero.

Could we guard these rewrites so they only apply when the domain-error preconditions are known to hold? It would also be good to add planner-level regression cases for these zero-valued forms.


#[test]
fn test_log_zero_decimal128_errors() {
let err = invoke_log(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see the new coverage for Float32/64 and Decimal128/256. Since this change also touches the separate Float16, Decimal32, and Decimal64 branches, could we add a small table-driven unit test that exercises every changed physical type?
That should help catch branch-specific regressions in the future.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.82609% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.19%. Comparing base (e7e037d) to head (3e6d538).
⚠️ Report is 18 commits behind head on main.

Files with missing lines Patch % Lines
datafusion/functions/src/math/log.rs 97.82% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main   #24399    +/-   ##
========================================
  Coverage   81.18%   81.19%            
========================================
  Files        1110     1110            
  Lines      388906   389029   +123     
  Branches   388906   389029   +123     
========================================
+ Hits       315733   315854   +121     
- Misses      54576    54577     +1     
- Partials    18597    18598     +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

documentation Improvements or additions to documentation functions Changes to functions implementation sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PostgreSQL compatibility: log(0.0::float8) should error, not return -inf

4 participants