-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
Fully Compatible
-
ALL
-
v6.0
-
-
QO 2022-02-07, QO 2022-02-21
-
149
Currently, arithmetic aggregation expressions like $multiply are marked as associative and commutative which allows the constant folding optimization to rearrange constants to combine as many of them as possible during optimization.
There are three reasons this is not a valid optimization in general:
1. For integers, this is not a safe optimization due to overflow. For example, 1073741824*-1*2 == -2147483648, but 1073741824*2*-1 overflows.
2. Floating point arithmetic is not generally associative. See this paper, specifically:
Due to roundoff errors, the associative laws of algebra do not necessarily hold for floating-point numbers. For example, the expression (x+y)z has a totally different answer than x(y+z) when x = 1030, y = -1030 and z = 1 (it is 1 in the former case, 0 in the latter). The importance of preserving parentheses cannot be overemphasized.
3. Type coercions occur when performing an operation on multiple types. For example, 1 + 0.5 + 2 will convert 1 from an integer to a float before adding it to 0.5. These type coercions are dependent on the order of operations and could change the result. See the "steps to reproduce" section for an example with `NumberDecimal`.
Because we can't know if a fieldpath will resolve to a specific number type or a value within a specific range, we cannot rule out any kind of overflow or type coercion.
After investigation, this only applies to ExpressionAdd and ExpressionMultiply.
As part of the fix for this ticket, we'll implement a left-to-right constant folding optimization that respects the order of operations during query execution while folding as many constants as is safe. For example, [c1, c2, c3, "$v", c5, c6] will be folded to [c', "$v", c5, c6].
- causes
-
SERVER-67011 $const folding in $add expression in $bucketAuto groupBy changes number of buckets
- Closed
- depends on
-
SERVER-65735 $add operator should not use DoubleDoubleSummation in the classic engine
- Closed
- is duplicated by
-
SERVER-66969 The $add aggregation expression is not always commutative
- Closed
- is related to
-
SERVER-65735 $add operator should not use DoubleDoubleSummation in the classic engine
- Closed
- related to
-
SERVER-63018 Have ExpressionAdd::evaluate() return intermediate result for pipeline optimization constant folding
- Closed