Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
### What problem does this PR solve? Related issue: [apache#48203](apache#48203) Problem Summary: Add the `gamma` scalar function, which generalizes the factorial to real numbers: `gamma(n)` is `(n - 1)!` for a positive integer `n`, and `gamma(0.5)` is `sqrt(pi)`. - BE: `gamma` is registered in `be/src/exprs/function/math.cpp` on top of `std::tgamma`. The poles are mapped to NULL instead of the value the C library produces: `gamma(0)` and every negative integer return NULL, and so does negative infinity, which the BE classifies as a negative integer pole. A NaN argument returns NaN, and positive infinity or an argument large enough to overflow a double (`gamma(172)` and above) returns Infinity. - FE: `Gamma` (unary, `ExplicitlyCastableSignature`, `AlwaysNullable`, `PropagateNullLiteral`), the Nereids visitor entry, and the builtin scalar function registration. - FE constant folding: `NumericArithmetic.gamma`, so that a folded `gamma(<literal>)` produces the same value as the BE. commons-math3's `Gamma.gamma` saturates to Infinity at 165, where `std::tgamma` still returns a finite 3.29e293 (it stays finite up to 171), so positive inputs are evaluated as `exp(logGamma(x))`. Negative non-integers have no overflow problem and use `Gamma.gamma`. ### Release note Add the `gamma` scalar function. `gamma(n)` is `(n - 1)!` for a positive integer `n`; `gamma(0)` and the negative integers return NULL. ### Check List (For Author) - Test - [x] Regression test - [x] Unit Test - [x] Manual test (add detailed scripts or steps below) - [ ] No need to test or manual test. Explain why: - Behavior changed: - [x] No. - [ ] Yes. <!-- Explain the behavior change --> - Does this need documentation? - [ ] No. - [x] Yes. <!-- REPLACE THIS WITH THE DOCS PR LINK, e.g. https://github.com/apache/doris-website/pull/XXXX --> ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label Manual test: - `select gamma(5), gamma(0.5), gamma(-1.5), gamma(0), gamma(-1), gamma(-3);` returns `24.000000000000004, 1.772453850905516, 2.3632718012073544, NULL, NULL, NULL`, and the same values are returned with `set debug_skip_fold_constant=true`, i.e. constant folding and BE execution agree. - `gamma(cast('nan' as double))` is NaN, `gamma(cast('inf' as double))` is Infinity, `gamma(cast('-inf' as double))` is NULL, `gamma(165)` is 3.287218585534318E293, `gamma(171)` is 7.257415615308056E306 and `gamma(172)` is Infinity. - `explain select gamma(v) from t where gamma(v) > 10;` still plans an olap scan with the predicate and the projection applied.
7cb9056 to
6ef21f0
Compare
|
Friendly ping @morrySnow @924060929 @englefly @starocean999 (Code Owners of This PR adds the Local validation: full Docs PR: apache/doris-website#4140 Thanks! |
What problem does this PR solve?
Related issue: #48203
Related PR: #51576, #60111 — earlier attempts at the same function, both closed without merging.
This one additionally implements FE constant folding that agrees with the BE at the poles and above
the commons-math3 overflow point, ships a regression suite covering the same case classes as
test_template_one_arg.groovy, and links a documentation PR.Problem Summary:
Add the
gammascalar function, which generalizes the factorial to real numbers:gamma(n)is(n - 1)!for a positive integern, andgamma(0.5)issqrt(pi).gammais registered inbe/src/exprs/function/math.cppon top ofstd::tgamma. The polesare mapped to NULL instead of the value the C library produces:
gamma(0)and every negativeinteger return NULL, and so does negative infinity, which the BE classifies as a negative
integer pole. A NaN argument returns NaN, and positive infinity or an argument large enough to
overflow a double (
gamma(172)and above) returns Infinity.Gamma(unary,ExplicitlyCastableSignature,AlwaysNullable,PropagateNullLiteral),the Nereids visitor entry, and the builtin scalar function registration.
NumericArithmetic.gamma, so that a foldedgamma(<literal>)produces thesame value as the BE. commons-math3's
Gamma.gammasaturates to Infinity at 165, wherestd::tgammastill returns a finite 3.29e293 (it stays finite up to 171), so positive inputs areevaluated as
exp(logGamma(x)). Negative non-integers have no overflow problem and useGamma.gamma.Release note
Add the
gammascalar function.gamma(n)is(n - 1)!for a positive integern;gamma(0)and the negative integers return NULL.
Check List (For Author)
Check List (For Reviewer who merge this PR)
Manual test:
select gamma(5), gamma(0.5), gamma(-1.5), gamma(0), gamma(-1), gamma(-3);returns24.000000000000004, 1.772453850905516, 2.3632718012073544, NULL, NULL, NULL, and the samevalues are returned with
set debug_skip_fold_constant=true, i.e. constant folding and BEexecution agree.
gamma(cast('nan' as double))is NaN,gamma(cast('inf' as double))is Infinity,gamma(cast('-inf' as double))is NULL,gamma(165)is 3.287218585534318E293,gamma(171)is 7.257415615308056E306 andgamma(172)is Infinity.explain select gamma(v) from t where gamma(v) > 10;still plans an olap scan with thepredicate and the projection applied.