Conversation
## Versions - [x] dev - [ ] 4.x - [ ] 3.x - [ ] 2.1 ## Languages - [x] Chinese - [x] English ## Docs Checklist - [ ] Checked by AI - [ ] Test Cases Built ## Summary Document the `gamma` scalar function, which is being added to the Doris frontend and backend: - `docs/sql-manual/sql-functions/scalar-functions/numeric-functions/gamma.md` (English) - `i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-functions/scalar-functions/numeric-functions/gamma.md` (Chinese) - the `numeric-functions/gamma` entry in `sidebars.ts` The page covers the definition (`gamma(n)` is `(n - 1)!` for a positive integer `n`, `gamma(0.5)` is `sqrt(pi)`), the special values the implementation produces (NULL at `0`, at every negative integer and at negative infinity; NaN for a NaN input; Infinity for positive infinity and above the double overflow threshold), and nine examples in both languages. Every example block is the real output of the function, taken from a build of the dev branch, so the values match what a reader gets, including the double-precision representation `24.000000000000004` for `gamma(5)`. Related Doris PR: added once the Doris pull request is opened; that pull request links back to this documentation PR.
12 tasks
RH211-sys
added a commit
to RH211-sys/doris
that referenced
this pull request
Sep 21, 2026
### What problem does this PR solve? Related issue: [apache#48203](apache#48203) Problem Summary: The FE folded `gamma(<literal>)` through commons-math3 while the BE computes it with `std::tgamma`. The two are independent implementations that cannot be kept aligned, so a folded constant could differ from the value the BE produces. Measured on the Doris build environment: - `gamma(-1000.5)` is NaN from the FE and -0.0 from the BE, a different classification; - `gamma(-150.5)` is 0.0 from the FE and -4.4784476581511713e-264 from the BE; - `gamma(10)` is 362879.9999999998 from the FE and 362880.00000000047 from the BE, about 11 ulp. `gamma` feeds neither partition nor bucket pruning, so the folding buys nothing. Remove it (`NumericArithmetic.gamma` and the commons-math3 import it needed) and let the BE stay the only implementation. There is then a single evaluation path: the default session, a session with `debug_skip_fold_constant=true`, a session with `enable_fold_constant_by_be=true` and a query that reads `gamma` of a table column all return identical values for the boundary inputs below (0, -0.0, negative integers, +/-infinity, NaN, 165/170/171/171.5/171.8/172/1e308, the smallest subnormal and the smallest normal, 1e-300, and large negative non-integers). Also in this commit: - The negative-zero row of the regression suite was written as the integer `-0`, which is stored as +0.0 and silently duplicated the row holding 0.0. It now uses `cast('-0.0' as double)` and is guarded by a `signbit` assertion, so a wrong test value fails instead of being recorded in the generated .out file. The suite also gains the boundary classes it was missing: inputs whose reciprocal overflows (1e-300, 5e-324, 2.2250738585072014e-308), the overflow onset (171.5 is finite, 171.8 is Infinity) and large negative non-integers that underflow to -0.0 (-1000.5) or to a subnormal (-171.5). - `math.cpp` cited a MySQL `gamma` anchor, but MySQL has no `gamma` function. The comment now states the convention actually followed: a domain error such as a pole returns NULL, as `sqrt(-1)` and `ln(0)` do, and only overflow returns Infinity. - The BE unit test also pins -0.0 as a pole. - The new FE statements are covered by `GammaTest`, which exercises the signature, the nullability, the implicit cast of the argument and the visitor dispatch through `withChildren`. This is what `check_coverage_fe` reports as uncovered. ### Release note None ### Check List (For Author) - Test - [x] Regression test - [x] Unit Test - [x] Manual test (the boundary matrix described above) - [ ] No need to test or manual test. Explain why: - Behavior changed: - [x] Yes: `gamma(<literal>)` is no longer constant folded in the FE, it is computed by the BE like every other invocation. The values returned to the client are unchanged. - Does this need documentation? - [x] Yes: apache/doris-website#4140
RH211-sys
added a commit
to RH211-sys/doris
that referenced
this pull request
Sep 21, 2026
### What problem does this PR solve? Related issue: [apache#48203](apache#48203) Problem Summary: The FE folded `gamma(<literal>)` through commons-math3 while the BE computes it with `std::tgamma`. The two are independent implementations that cannot be kept aligned, so a folded constant could differ from the value the BE produces. Measured on the Doris build environment: - `gamma(-1000.5)` is NaN from the FE and -0.0 from the BE, a different classification; - `gamma(-150.5)` is 0.0 from the FE and -4.4784476581511713e-264 from the BE; - `gamma(10)` is 362879.9999999998 from the FE and 362880.00000000047 from the BE, about 11 ulp. `gamma` feeds neither partition nor bucket pruning, so the folding buys nothing. Remove it (`NumericArithmetic.gamma` and the commons-math3 import it needed) and let the BE stay the only implementation. There is then a single evaluation path: the default session, a session with `debug_skip_fold_constant=true`, a session with `enable_fold_constant_by_be=true` and a query that reads `gamma` of a table column all return identical values for the boundary inputs below (0, -0.0, negative integers, +/-infinity, NaN, 165/170/171/171.5/171.8/172/1e308, the smallest subnormal and the smallest normal, 1e-300, and large negative non-integers). Also in this commit: - The negative-zero row of the regression suite was written as the integer `-0`, which is stored as +0.0 and silently duplicated the row holding 0.0. It now uses `cast('-0.0' as double)` and is guarded by a `signbit` assertion, so a wrong test value fails instead of being recorded in the generated .out file. The suite also gains the boundary classes it was missing: inputs whose reciprocal overflows (1e-300, 5e-324, 2.2250738585072014e-308), the overflow onset (171.5 is finite, 171.8 is Infinity) and large negative non-integers that underflow to -0.0 (-1000.5) or to a subnormal (-171.5). - The near-zero rows hold what libm's tgamma returns, about 1e-14 relative away from the correctly rounded value, which is inside the 1e-8 relative tolerance the framework applies to DOUBLE cells. The two properties that tolerance cannot see are asserted directly: the sign of a result that underflows to zero, and a subnormal result that must not collapse to zero. - `testFoldConst` passes by construction now that nothing is folded, so it is kept as a guard for a folding that might come back, and its last two columns are BOOLEAN (`signbit(gamma(-1000.5))`, `gamma(-171.5) > 0`). checkCell compares BOOLEAN cells exactly, while its double path would not notice a folding that flipped the sign of an underflowed zero (0.0 against -0.0 divides by a zero magnitude) or let a subnormal collapse to zero (the decimal-place fallback accepts it). - `math.cpp` cited a MySQL `gamma` anchor, but MySQL has no `gamma` function. The comment now states the convention actually followed: a domain error such as a pole returns NULL, as `sqrt(-1)` and `ln(0)` do, and only overflow returns Infinity. - The BE unit test also pins -0.0 as a pole. - The new FE statements are covered by `GammaTest`, which exercises the signature, the nullability, the implicit cast of the argument and the visitor dispatch through `withChildren`. This is what `check_coverage_fe` reports as uncovered. ### Release note None ### Check List (For Author) - Test - [x] Regression test - [x] Unit Test - [x] Manual test (the boundary matrix described above) - [ ] No need to test or manual test. Explain why: - Behavior changed: - [x] Yes: `gamma(<literal>)` is no longer constant folded in the FE, it is computed by the BE like every other invocation. The values returned to the client are unchanged. - Does this need documentation? - [x] Yes: apache/doris-website#4140
- gamma(-2.5) returns -0.9453087204829418, not -0.9453087204829419. - The pole case covers -0.0 as well. - Document the two remaining boundary classes: a very small positive argument, where gamma(a) is about 1 / a, overflows to Infinity, and a large negative non-integer can underflow to a signed zero. Checked against the engine on the pull request build: gamma(-2.5) is -0.9453087204829418, signbit(gamma(-1000.5)) is true, and gamma(5e-324) and gamma(1e-320) are Infinity.
This branch has not been deployed
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.
Versions
gammais a new function on the master branch only, so there is no released version to document yet.Languages
Docs Checklist
Every example block on the page is the real output of the function, captured from a build of the dev
branch, and both language versions are added in this PR, so no counterpart sync is outstanding. The
function itself is covered by the regression test and the BE unit test in the Doris PR.
Summary
Document the
gammascalar function, which is being added to the Doris frontend and backend:docs/sql-manual/sql-functions/scalar-functions/numeric-functions/gamma.md(English)i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-functions/scalar-functions/numeric-functions/gamma.md(Chinese)numeric-functions/gammaentry insidebars.tsThe page covers the definition (
gamma(n)is(n - 1)!for a positive integern,gamma(0.5)issqrt(pi)), the special values the implementation produces (NULL at0, at every negative integerand at negative infinity; NaN for a NaN input; Infinity for positive infinity and above the double
overflow threshold), and nine examples in both languages. Every example block is the real output of
the function, taken from a build of the dev branch, so the values match what a reader gets,
including the double-precision representation
24.000000000000004forgamma(5).