| 3122 | }; |
| 3123 | |
| 3124 | void TestScaleBy() { |
| 3125 | // IMPALA-6429: There is a shortcut in the decimal division. If we estimate that the |
| 3126 | // dividend requires more than 255 bits after scaling up, we overflow right away. This |
| 3127 | // test proves that it is correct to do this and no other checks are needed. |
| 3128 | for (int scale_by = 0; scale_by < 38 * 2 + 1; ++scale_by) { |
| 3129 | for (int num_bits = 1; num_bits < 128; ++num_bits) { |
| 3130 | // We set the dividend to be the smallest number that requires a certain number of |
| 3131 | // bits. |
| 3132 | int128_t dividend = 1; |
| 3133 | dividend <<= num_bits - 1; |
| 3134 | int256_t scaled_up_dividend = DecimalUtil::MultiplyByScale<int256_t>( |
| 3135 | ConvertToInt256(dividend), scale_by, true); |
| 3136 | int256_t scale_multiplier = DecimalUtil::GetScaleMultiplier<int256_t>(scale_by); |
| 3137 | if (detail::MaxBitsRequiredAfterScaling(dividend, scale_by) <= 255) { |
| 3138 | // If we estimate that the scaled up dividend requires 255 bits or less, verify |
| 3139 | // that we do not overflow when scaling up. |
| 3140 | EXPECT_TRUE(scaled_up_dividend / scale_multiplier == ConvertToInt256(dividend)); |
| 3141 | EXPECT_TRUE( |
| 3142 | (-scaled_up_dividend) / scale_multiplier == ConvertToInt256(-dividend)); |
| 3143 | } else { |
| 3144 | // If we estimate that scaled up dividend requres more than 255 bits, we want to |
| 3145 | // verify that it is safe to set the result of the division to overflow. |
| 3146 | if (scaled_up_dividend / scale_multiplier == ConvertToInt256(dividend)) { |
| 3147 | // In this case, scaling up did not overflow. Verify that the scaled up |
| 3148 | // dividend is too large. Even if we divide it by the largest possible divisor |
| 3149 | // the result is larger than MAX_UNSCALED_DECIMAL16, which means the division |
| 3150 | // overflows in all cases. |
| 3151 | EXPECT_TRUE((-scaled_up_dividend) / scale_multiplier == |
| 3152 | ConvertToInt256(-dividend)); |
| 3153 | int256_t max_divisor = ConvertToInt256(MAX_UNSCALED_DECIMAL16); |
| 3154 | EXPECT_TRUE(scaled_up_dividend / max_divisor > max_divisor); |
| 3155 | EXPECT_TRUE((-scaled_up_dividend) / max_divisor < -max_divisor); |
| 3156 | } else { |
| 3157 | // There was an overflow when scaling up. |
| 3158 | EXPECT_TRUE((-scaled_up_dividend) / scale_multiplier != |
| 3159 | ConvertToInt256(-dividend)); |
| 3160 | } |
| 3161 | } |
| 3162 | } |
| 3163 | } |
| 3164 | } |
| 3165 | |
| 3166 | TEST_P(ExprTest, DecimalArithmeticExprs) { |
| 3167 | // Test with both decimal_v2={false, true} |
no test coverage detected