mrhhsg opened a new pull request, #69056:
URL: https://github.com/apache/doris/pull/69056
### What problem does this PR solve?
Issue Number: None
Problem Summary:
When `enable_decimal256` is off (decimal128 mode), `+`, `-` and `%` fail with
`ERROR 1105 ... IllegalArgumentException: scale should not smaller than 0,
but real scale is -28`
whenever one DecimalV3 operand's integral part (`precision - scale`) is
wider than 38 digits, for
example a `decimal(76, x)` column, or the output of a view whose
`sum`/`sum_map`/`avg_map` was
analyzed while `enable_decimal256` was on (the view's output slot type is
persisted at create time
and carried into a later decimal128-mode query against that view).
Root cause: `TypeCoercionUtils.processDecimalV3BinaryArithmetic` converts
both operands of
`Add`/`Subtract`/`Mod` to `DecimalV3Type` and calls
`getDataTypeForDecimalV3` directly, without
accounting for an operand that is already wider than decimal128 while the
current session is in
128-bit mode. `BinaryArithmetic.processDecimalV3OverFlow` then computes
`scale = 38 - maxIntegralPart` for decimal128 mode; when `maxIntegralPart >
38` (e.g. the range of
`decimal(76,10)` is 66) that scale is negative, and
`DecimalV3Type.createDecimalV3Type`'s `Preconditions.checkArgument(scale >=
0, ...)` throws.
The fix narrows an operand whose integral part alone exceeds 38 digits to
decimal128 (keeping as
much scale as possible) before deriving the result type, the same
lossy-narrowing rule the codebase
already applies to `sum`/`sum_map` arguments, `Multiply`/`Divide`, and
`widerDecimalV3Type` when
`enable_decimal256` is off. The new
`DecimalV3Type.narrowToDecimal128IfDisabled` helper is shared by
`ComputePrecisionForSum` and `SumMap.sumDecimalArgumentType`, which
previously inlined the same
formula. `SumMap`/`AvgMap` also now implement `NeedSessionVarGuard`,
aligning them with
`Sum`/`Avg`/`Sum0` so their view output stays guarded by the session
variables in effect when the
view was created.
Only the path that previously always threw is affected: when every operand's
integral part already
fits within 38 digits, the derived type and child casts are unchanged
(covered by existing
regression `test_view_var_persist`). In decimal256 mode nothing changes.
When an operand's actual
value has more than 28 integral digits (for scale 10), the narrowing cast
can overflow in BE
(`NULL` under the default `enable_strict_cast=false`, or an error when it is
`true`) — the same
behavior already observed today for `sum(decimal256 column)` in 128-bit mode.
### Release note
In decimal128 mode (`enable_decimal256=false`), arithmetic (`+`, `-`, `%`)
on a decimal operand
whose integral part is wider than decimal128 (e.g. a decimal256 column, or
the output of a view
created while `enable_decimal256` was on) no longer fails with an FE error;
the operand is narrowed
to decimal128 first, which may yield `NULL` instead of an exact result when
the actual value's
integral part does not fit in 38 digits.
### Check List (For Author)
- Test:
- Unit Test: `TypeCoercionUtilsTest`, `ViewDecimal256OperandTest`,
`VariablePersistTest` (54 cases,
all pass; reverting the main-code change reproduces the original `-28`
scale error / guard
assertion failure)
- Regression test: new `query_p0/variables_persist/test_map_agg_view`;
also re-ran
`test_view_var_persist`, `test_array_agg_view`,
`datatype_p0/decimalv3/test_arithmetic_expressions`
to confirm no behavior change
- Behavior changed: Yes (see Release note)
- 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]