diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp index 59729c4afaad..b00789a3064e 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp @@ -40,22 +40,23 @@ struct TNumMulInterval { const auto lv = static_cast(left.template Get()); const auto rv = static_cast(right.template Get()); const auto ret = lv * rv; - if (ret == 0) { + if (rv == 0 || lv == 0) { return NUdf::TUnboxedValuePod(ret); } + i64 i64Max = std::numeric_limits::max(); if constexpr (std::is_same_v) { - if (left.Get() > static_cast(std::numeric_limits::max())) { + if (left.Get() >= static_cast(i64Max)) { return NUdf::TUnboxedValuePod(); } } if constexpr (std::is_same_v) { - if (right.Get() > static_cast(std::numeric_limits::max())) { + if (right.Get() >= static_cast(i64Max)) { return NUdf::TUnboxedValuePod(); } } - i64 lvAbs = (lv > 0) ? lv : -lv; - i64 rvAbs = (rv > 0) ? rv : -rv; - if (rvAbs != 0 && (std::numeric_limits::max() / rvAbs < lvAbs)) { + auto div = i64Max / rv; + auto divAbs = (div >= 0) ? div : -div; + if ((lv >= 0) ? (lv > divAbs) : (lv < -divAbs)) { return NUdf::TUnboxedValuePod(); } return IsBadInterval(ret) ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(ret); @@ -68,7 +69,7 @@ struct TNumMulInterval { const auto bbMain = BasicBlock::Create(context, "bbMain", ctx.Func); const auto bbDone = BasicBlock::Create(context, "bbDone", ctx.Func); const auto resultType = Type::getInt128Ty(context); - const auto result = PHINode::Create(resultType, 3, "result", bbDone); + const auto result = PHINode::Create(resultType, 2, "result", bbDone); const auto lv = GetterFor(left, context, block); const auto lhs = StaticCast(lv, context, block); @@ -76,31 +77,35 @@ struct TNumMulInterval { const auto rhs = StaticCast(rv, context, block); const auto mul = BinaryOperator::CreateMul(lhs, rhs, "mul", block); const auto zero = ConstantInt::get(Type::getInt64Ty(context), 0); - const auto mulZero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, mul, zero, "mulZero", block); + const auto lhsZero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lhs, zero, "lhsZero", block); + const auto rhsZero = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rhs, zero, "rhsZero", block); const auto res = SetterFor(mul, context, block); - BranchInst::Create(bbDone, bbMain, mulZero, block); + BranchInst::Create(bbDone, bbMain, BinaryOperator::CreateOr(lhsZero, rhsZero, "mulZero", block), block); result->addIncoming(res, block); block = bbMain; - const auto lhsAbs = SelectInst::Create( - CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, lhs, zero, "lhsPos", block), - lhs, - BinaryOperator::CreateNeg(lhs, "lhsNeg", block), - "lhsAbs", block); - const auto rhsAbs = SelectInst::Create( - CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, rhs, zero, "rhsPos", block), - rhs, - BinaryOperator::CreateNeg(rhs, "rhsNeg", block), - "rhsAbs", block); const auto i64Max = ConstantInt::get(Type::getInt64Ty(context), std::numeric_limits::max()); - const auto div = BinaryOperator::CreateSDiv(i64Max, rhsAbs, "div", block); - const auto mulOverflow = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, lhsAbs, div, "mulOverflow", block); + const auto div = BinaryOperator::CreateSDiv(i64Max, rhs, "div", block); + const auto divAbs = SelectInst::Create( + CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, div, zero, "divPos", block), + div, + BinaryOperator::CreateNeg(div, "divNeg", block), + "divAbs", block); + const auto divAbsNeg = BinaryOperator::CreateNeg(divAbs, "divAbsNeg", block); + + const auto mulOverflow = SelectInst::Create( + CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, lhs, zero, "lhsPos", block), + CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, lhs, divAbs, "lhsDiv", block), + CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, lhs, divAbsNeg, "lhsDivAbsNeg", block), + "mulOverflow", block); + const auto i64Overflow = BinaryOperator::CreateOr( GenIsInt64Overflow(lv, context, block), GenIsInt64Overflow(rv, context, block), "i64Overflow", block); + const auto bad = BinaryOperator::CreateOr( BinaryOperator::CreateOr(i64Overflow, mulOverflow, "overflow", block), GenIsBadInterval(mul, context, block), diff --git a/ydb/library/yql/tests/sql/dq_file/part16/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part16/canondata/result.json index 29149206adcf..ceef9a4dd35b 100644 --- a/ydb/library/yql/tests/sql/dq_file/part16/canondata/result.json +++ b/ydb/library/yql/tests/sql/dq_file/part16/canondata/result.json @@ -405,9 +405,9 @@ ], "test.test[bigdate-arithmetic-default.txt-Debug]": [ { - "checksum": "968be71411b4f41aa78165913bd74333", - "size": 8688, - "uri": "https://{canondata_backend}/1937367/518bbcf510ad7a43c5e77746bafd21ed0e3fdc6e/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql_patched" + "checksum": "1a5cecc5f3f3d734d4eef23e12f6725b", + "size": 8887, + "uri": "https://{canondata_backend}/1899731/2ec8224db091f2a7362c5e4ce595bc50329b8311/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-arithmetic-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json index c8f7a0839ef4..9b0c4994646e 100644 --- a/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json +++ b/ydb/library/yql/tests/sql/dq_file/part4/canondata/result.json @@ -531,9 +531,9 @@ ], "test.test[bigdate-table_int_cast-default.txt-Debug]": [ { - "checksum": "1d672f23cc038dc42d14175121554c71", + "checksum": "0f242de0900368c56d1b937487ced6cb", "size": 8617, - "uri": "https://{canondata_backend}/1924537/907e79379e1e72f9d09545e57f65dee63f42dbfe/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql_patched" + "uri": "https://{canondata_backend}/1809005/df0d5940a3b3a38ba468a035aba7ce54440f0891/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-table_int_cast-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/dq_file/part6/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part6/canondata/result.json index 775d223dcbb0..7b874be0f413 100644 --- a/ydb/library/yql/tests/sql/dq_file/part6/canondata/result.json +++ b/ydb/library/yql/tests/sql/dq_file/part6/canondata/result.json @@ -457,9 +457,9 @@ ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Debug]": [ { - "checksum": "7d3363f2bc50bd3ecf9097b47926a9e4", + "checksum": "11e7ab9520da2bde231d70dbb834e16a", "size": 9840, - "uri": "https://{canondata_backend}/1936842/e2f5b27b418549665a04de58de4b4e487f33c292/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql_patched" + "uri": "https://{canondata_backend}/1937424/022b4c4aaf443124c76bb3e388177d9b3de00044/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/hybrid_file/part2/canondata/result.json b/ydb/library/yql/tests/sql/hybrid_file/part2/canondata/result.json index cf93466360ee..d2011a6fc441 100644 --- a/ydb/library/yql/tests/sql/hybrid_file/part2/canondata/result.json +++ b/ydb/library/yql/tests/sql/hybrid_file/part2/canondata/result.json @@ -435,9 +435,9 @@ ], "test.test[bigdate-table_int_cast-default.txt-Debug]": [ { - "checksum": "1041a100c9cdb8f46d004a635dfdc1c1", + "checksum": "2255e5c0c361ed4e31289580bb6a402c", "size": 18588, - "uri": "https://{canondata_backend}/1809005/ad7c074711ee8d1675aebabbf8025a2c8bd317d8/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql_patched" + "uri": "https://{canondata_backend}/1775059/b57c9040709a7b012953cf170d04a292adc8d3d3/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-table_int_cast-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json b/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json index c5adba636ea0..25d7d7fd11e5 100644 --- a/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json +++ b/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json @@ -477,9 +477,9 @@ ], "test.test[bigdate-arithmetic-default.txt-Debug]": [ { - "checksum": "74f20089d55fea37e0e7cdee17f0cbd8", - "size": 8687, - "uri": "https://{canondata_backend}/1784117/3885f0a76b64a32a48487f8866602d3fff1e416a/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql_patched" + "checksum": "c1939c3925f1c9e2d27b33692637bc61", + "size": 8886, + "uri": "https://{canondata_backend}/1889210/e26b9c7fc72b580fe82c1126f535456e73306c2c/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-arithmetic-default.txt-Plan]": [ @@ -519,9 +519,9 @@ ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Debug]": [ { - "checksum": "d4d5d49978ce482aebef2f3eb7048d9e", - "size": 28197, - "uri": "https://{canondata_backend}/1809005/7478904042df2a3888a84b6a917dd7cf55a05d66/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql_patched" + "checksum": "7f460bd132529e2aee95b0bcb5b608b7", + "size": 28216, + "uri": "https://{canondata_backend}/1817427/46729b354b9b15ea89f67bf14fefd2face8b402b/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql_patched" } ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Plan]": [ diff --git a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json index 9507f982a2a8..bbb3949a072b 100644 --- a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json +++ b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json @@ -2738,9 +2738,9 @@ ], "test_sql2yql.test[bigdate-arithmetic]": [ { - "checksum": "10d3641741062fdda397c48868d0bd18", - "size": 54577, - "uri": "https://{canondata_backend}/1784117/d56ae82ad9d30397a41490647be1bd2124718f98/resource.tar.gz#test_sql2yql.test_bigdate-arithmetic_/sql.yql" + "checksum": "dd71cf80379fd120f899f51a8d4185e0", + "size": 55200, + "uri": "https://{canondata_backend}/1784117/72de9d096244671bdc282e3e67e222f7d47084f5/resource.tar.gz#test_sql2yql.test_bigdate-arithmetic_/sql.yql" } ], "test_sql2yql.test[bigdate-bitcast_date32]": [ @@ -22296,9 +22296,9 @@ ], "test_sql_format.test[bigdate-arithmetic]": [ { - "checksum": "74aed1e3957af10f2b714b9961faaa61", - "size": 7211, - "uri": "https://{canondata_backend}/1775319/65663ceaccc952bb64364e6408bfc54197bb33e2/resource.tar.gz#test_sql_format.test_bigdate-arithmetic_/formatted.sql" + "checksum": "9733896aaffd0f29c69369ba53a83908", + "size": 7322, + "uri": "https://{canondata_backend}/1784117/72de9d096244671bdc282e3e67e222f7d47084f5/resource.tar.gz#test_sql_format.test_bigdate-arithmetic_/formatted.sql" } ], "test_sql_format.test[bigdate-bitcast_date32]": [ diff --git a/ydb/library/yql/tests/sql/suites/bigdate/Signed.txt b/ydb/library/yql/tests/sql/suites/bigdate/Signed.txt index ed2f24449366..3a6634c9869e 100644 --- a/ydb/library/yql/tests/sql/suites/bigdate/Signed.txt +++ b/ydb/library/yql/tests/sql/suites/bigdate/Signed.txt @@ -1,3 +1,4 @@ +{ "row"=-8; "i8"=-16; "i16"=-256; "i32"=-65536; "i64"=-4294967296; }; { "row"=-7; "i8"=-128; "i16"=-32768; "i32"=-2147483648; "i64"=-9223372036854775808; }; { "row"=-6; "i8"=-128; "i16"=-32768; "i32"=-2147483648; "i64"=-9223339708799999999; }; { "row"=-5; "i8"=-128; "i16"=-32768; "i32"=-2147483648; "i64"=-4611669897600000001; }; @@ -13,3 +14,4 @@ { "row"=5; "i8"=127; "i16"=32767; "i32"=2147483647; "i64"=4611669811200000000; }; { "row"=6; "i8"=127; "i16"=32767; "i32"=2147483647; "i64"=9223339708799999999; }; { "row"=7; "i8"=127; "i16"=32767; "i32"=2147483647; "i64"=9223372036854775807; }; +{ "row"=8; "i8"=16; "i16"=256; "i32"=65536; "i64"=4294967296; }; diff --git a/ydb/library/yql/tests/sql/suites/bigdate/arithmetic.sql b/ydb/library/yql/tests/sql/suites/bigdate/arithmetic.sql index 65993823df16..5e72aa0c0634 100644 --- a/ydb/library/yql/tests/sql/suites/bigdate/arithmetic.sql +++ b/ydb/library/yql/tests/sql/suites/bigdate/arithmetic.sql @@ -99,4 +99,5 @@ select 0, -$interval64_max, -$interval64_min, -$interval64_zero , 8, $interval64_zero/$ui64_max, $interval64_zero/$i64_max, $interval64_plus1/$ui64_max, $interval64_plus1/$i64_max, $interval64_minus1/$ui64_max, $interval64_minus1/$i64_max , 9, $interval64_max/cast($interval64_max as int64), $interval64_min/cast($interval64_min as int64) , 10, abs($interval64_max), abs($interval64_min), abs($interval64_zero) +, 11, cast(4294967296l as interval64) * 4294967296l, 4294967296ul * cast(4294967296l as interval64) ; diff --git a/ydb/library/yql/tests/sql/yt_native_file/part16/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part16/canondata/result.json index 53ecf9637db1..1b62115c688a 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part16/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part16/canondata/result.json @@ -353,9 +353,9 @@ ], "test.test[bigdate-arithmetic-default.txt-Debug]": [ { - "checksum": "2559cb39ee0ad016c2eeba0175d90372", - "size": 8617, - "uri": "https://{canondata_backend}/1130705/85e00e1809c16d7a062c55ddef958687d825adb0/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql" + "checksum": "a8db511c5581bd3dac3da50a14581438", + "size": 8816, + "uri": "https://{canondata_backend}/1937424/bcd047e5237d8754d97b84f73ec58e1dfd3f242e/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Debug_/opt.yql" } ], "test.test[bigdate-arithmetic-default.txt-Plan]": [ @@ -367,9 +367,9 @@ ], "test.test[bigdate-arithmetic-default.txt-Results]": [ { - "checksum": "78b14e7c48f2837c128e3175ccbdecb8", - "size": 78678, - "uri": "https://{canondata_backend}/1775059/3537a7096af92f6c747d78f769fafb259258445e/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Results_/results.txt" + "checksum": "5c7490438490b2bc79701426ebfaa41a", + "size": 79839, + "uri": "https://{canondata_backend}/1937424/bcd047e5237d8754d97b84f73ec58e1dfd3f242e/resource.tar.gz#test.test_bigdate-arithmetic-default.txt-Results_/results.txt" } ], "test.test[bigdate-compare_big_big-default.txt-Debug]": [ diff --git a/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json index 68d31144a329..d3d96f9e4e29 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part4/canondata/result.json @@ -441,9 +441,9 @@ ], "test.test[bigdate-table_int_cast-default.txt-Debug]": [ { - "checksum": "51e140cf0893afa5a725df8cc2c01834", + "checksum": "66aa7125c203486f28ed2c642c5741f0", "size": 13465, - "uri": "https://{canondata_backend}/1936842/bca567d011b535ed157a29d116aa0c03a876f699/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql" + "uri": "https://{canondata_backend}/1946324/97f79e67e2ba571def52794d35b33cdebe8c85ed/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Debug_/opt.yql" } ], "test.test[bigdate-table_int_cast-default.txt-Plan]": [ @@ -455,9 +455,9 @@ ], "test.test[bigdate-table_int_cast-default.txt-Results]": [ { - "checksum": "1791e9dfc14aa122ae1f383b5651a4af", - "size": 97973, - "uri": "https://{canondata_backend}/1936997/9b8859f70925a58b024145127cca3e8e612258c0/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Results_/results.txt" + "checksum": "ec0c795efb2cb5df83406d85a55783b7", + "size": 99849, + "uri": "https://{canondata_backend}/1946324/97f79e67e2ba571def52794d35b33cdebe8c85ed/resource.tar.gz#test.test_bigdate-table_int_cast-default.txt-Results_/results.txt" } ], "test.test[bigdate-tzstrliterals-default.txt-Debug]": [ diff --git a/ydb/library/yql/tests/sql/yt_native_file/part6/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part6/canondata/result.json index f2e5ab3ea280..a63ac6d5af2c 100644 --- a/ydb/library/yql/tests/sql/yt_native_file/part6/canondata/result.json +++ b/ydb/library/yql/tests/sql/yt_native_file/part6/canondata/result.json @@ -421,9 +421,9 @@ ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Debug]": [ { - "checksum": "7c0763701065ca8b3138feca9672ace3", - "size": 24381, - "uri": "https://{canondata_backend}/1925821/1cd5a00cb1561c8bd6ad6a05b5a3985def6ab335/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql" + "checksum": "428a68b06c3b405e0087538758ca7e4c", + "size": 24400, + "uri": "https://{canondata_backend}/1917492/30b5bc2d6861ed60772eb6885e2fd9071a8898c0/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Debug_/opt.yql" } ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Plan]": [ @@ -435,9 +435,9 @@ ], "test.test[bigdate-table_arithmetic_mul_div-default.txt-Results]": [ { - "checksum": "af13590e677929ae5e2008ba94e8e3d5", - "size": 662899, - "uri": "https://{canondata_backend}/1924537/2f28b0eebe4156125fa9fe084e0ede26fda21bd7/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Results_/results.txt" + "checksum": "785fb2e27cc00e47a21316d75d79a7b5", + "size": 662203, + "uri": "https://{canondata_backend}/1917492/30b5bc2d6861ed60772eb6885e2fd9071a8898c0/resource.tar.gz#test.test_bigdate-table_arithmetic_mul_div-default.txt-Results_/results.txt" } ], "test.test[bigdate-table_arithmetic_narrow-default.txt-Debug]": [