mrhhsg opened a new pull request, #68503:
URL: https://github.com/apache/doris/pull/68503

   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: #58200
   
   Problem Summary:
   
   `ntile(1 + 1) OVER (ORDER BY k)` was rejected at analysis time, although
   the bucket is a constant expression that folds to `2`:
   
   ```
   mysql> SELECT ntile(1 + 1) OVER (ORDER BY k) AS bucket
       -> FROM (SELECT 1 AS k UNION ALL SELECT 2 UNION ALL SELECT 3) t;
   ERROR 1105 (HY000): errCode = 2, detailMessage = The bucket parameter of 
NTILE
   must be a constant positive integer: ntile((1 + 1))
   ```
   
   LAG/LEAD (#58200) and NTH_VALUE already accept such expressions, because
   their literal checks run after constant folding.
   
   Root cause: `Ntile.checkLegalityBeforeTypeCoercion` runs while the function
   is being bound in the analyzer, before `FoldConstant` has turned `1 + 1`
   into a literal, and it required the argument to already be a `Literal`.
   Every non-literal constant expression therefore failed the check.
   
   Fix: keep the integral-type, LARGEINT and constant checks as they are, then
   fold the bucket with `FoldConstantRuleOnFE.evaluateWithoutContext` (the
   pattern already used by `Stack`) and require the folded value to be an
   integer literal greater than zero. Constant expressions such as `1 + 1`,
   `cast(5 - 2 as bigint)` or `abs(-3)` are now accepted, while `0`, `1 - 1`,
   `1 - 2`, a NULL result such as `cast('abc' as int)`, a non-constant column
   and a LARGEINT bucket are still rejected with the existing error messages.
   The backend registers `ntile` only for a non-nullable integer argument and
   reads the bucket count from the argument column, so the bucket must still be
   a literal when the plan is translated. A `checkLegalityAfterRewrite` is added
   that requires a positive integer literal after rewrite (the same approach LAG
   and LEAD use). When constant folding is skipped with
   `debug_skip_fold_constant=true`, an unfolded expression such as
   `cast('3' as int)` is now rejected with the NTILE message instead of failing
   in the backend with `Agg Function ntile(int) is not implemented`.
   
   After the fix the query above returns `1, 1, 2`.
   
   ### Release note
   
   None
   
   ### Check List (For Author)
   
   - Test:
       - Unit Test: `NtileBucketTest` covers a literal bucket, foldable
         constant expressions, expressions folded to zero/negative/NULL,
         non-constant, non-integral and LARGEINT buckets, and the
         after-rewrite check for literal and unfolded buckets.
       - Regression test: `test_ntile_function` adds `ntile(1 + 1)`,
         `ntile(cast(5 - 2 as bigint))`, `ntile(abs(-3))` with generated
         output, error cases for `ntile(1 - 1)`, `ntile(1 - 2)` and
         `ntile(cast('abc' as int))`, and cases with
         `debug_skip_fold_constant=true`.
   - Behavior changed: Yes (NTILE now accepts a constant bucket expression
     that folds to a positive integer; such queries previously failed)
   - Does this need documentation: No
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to