|
11 | 11 | #include <yql/essentials/ast/yql_ast.h> |
12 | 12 | #include <yql/essentials/ast/yql_expr.h> |
13 | 13 | #include <yql/essentials/core/yql_expr_optimize.h> |
| 14 | +#include <yql/essentials/public/udf/udf_data_type.h> |
14 | 15 |
|
15 | 16 | #include <library/cpp/json/json_reader.h> |
16 | 17 |
|
@@ -74,6 +75,115 @@ Y_UNIT_TEST_SUITE(KqpQuery) { |
74 | 75 | UNIT_ASSERT_VALUES_EQUAL(counters.RecompileRequestGet()->Val(), 1); |
75 | 76 | } |
76 | 77 |
|
| 78 | + Y_UNIT_TEST_TWIN(ExtendedTimeOutOfBounds, BulkUpsert) { |
| 79 | + auto settings = TKikimrSettings().SetWithSampleTables(false); |
| 80 | + TKikimrRunner kikimr(settings); |
| 81 | + |
| 82 | + auto queryClient = kikimr.GetQueryClient(); |
| 83 | + auto tableClient = kikimr.GetTableClient(); |
| 84 | + |
| 85 | + { |
| 86 | + const std::string query = R"( |
| 87 | + CREATE TABLE `/Root/TimeTable` ( |
| 88 | + Key UInt32 NOT NULL, |
| 89 | + V_Date32 Date32, |
| 90 | + V_Datetime64 Datetime64, |
| 91 | + V_Timestamp64 Timestamp64, |
| 92 | + V_Interval64 Interval64, |
| 93 | + PRIMARY KEY (Key) |
| 94 | + ); |
| 95 | + )"; |
| 96 | + auto result = queryClient.ExecuteQuery(query, NQuery::TTxControl::NoTx()).ExtractValueSync(); |
| 97 | + UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString()); |
| 98 | + } |
| 99 | + |
| 100 | + auto fUpsertAndCheck = [&]<typename T>(ui32 key, T value, bool success) { |
| 101 | + std::string colName; |
| 102 | + if (BulkUpsert) { |
| 103 | + TValueBuilder rows; |
| 104 | + rows.BeginList(); |
| 105 | + rows.AddListItem().BeginStruct().AddMember("Key").Uint32(key); |
| 106 | + if constexpr (std::is_same_v<T, TWideDays>) { |
| 107 | + rows.AddMember("V_Date32").Date32(std::chrono::sys_time<TWideDays>(TWideDays(value))); |
| 108 | + colName = "V_Date32"; |
| 109 | + } else if constexpr (std::is_same_v<T, TWideSeconds>) { |
| 110 | + rows.AddMember("V_Datetime64").Datetime64(std::chrono::sys_time<TWideSeconds>(TWideSeconds(value))); |
| 111 | + colName = "V_Datetime64"; |
| 112 | + } else if constexpr (std::is_same_v<T, TWideMicroseconds>) { |
| 113 | + rows.AddMember("V_Timestamp64").Timestamp64(std::chrono::sys_time<TWideMicroseconds>(TWideMicroseconds(value))); |
| 114 | + colName = "V_Timestamp64"; |
| 115 | + } else if constexpr (std::is_same_v<T, i64>) { |
| 116 | + rows.AddMember("V_Interval64").Interval64(TWideMicroseconds(value)); |
| 117 | + colName = "V_Interval64"; |
| 118 | + } else { |
| 119 | + UNIT_ASSERT_C(false, "Unsupported type"); |
| 120 | + } |
| 121 | + rows.EndStruct().EndList(); |
| 122 | + |
| 123 | + auto result = tableClient.BulkUpsert("/Root/TimeTable", rows.Build()).GetValueSync(); |
| 124 | + UNIT_ASSERT_VALUES_EQUAL_C(result.IsSuccess(), success, result.GetIssues().ToString()); |
| 125 | + } else { |
| 126 | + auto params = std::move(TParamsBuilder().AddParam("$key").Uint32(key).Build()); |
| 127 | + if constexpr (std::is_same_v<T, TWideDays>) { |
| 128 | + params.AddParam("$param").Date32(std::chrono::sys_time<TWideDays>(TWideDays(value))).Build(); |
| 129 | + colName = "V_Date32"; |
| 130 | + } else if constexpr (std::is_same_v<T, TWideSeconds>) { |
| 131 | + params.AddParam("$param").Datetime64(std::chrono::sys_time<TWideSeconds>(TWideSeconds(value))).Build(); |
| 132 | + colName = "V_Datetime64"; |
| 133 | + } else if constexpr (std::is_same_v<T, TWideMicroseconds>) { |
| 134 | + params.AddParam("$param").Timestamp64(std::chrono::sys_time<TWideMicroseconds>(TWideMicroseconds(value))).Build(); |
| 135 | + colName = "V_Timestamp64"; |
| 136 | + } else if constexpr (std::is_same_v<T, i64>) { |
| 137 | + params.AddParam("$param").Interval64(TWideMicroseconds(value)).Build(); |
| 138 | + colName = "V_Interval64"; |
| 139 | + } else { |
| 140 | + UNIT_ASSERT_C(false, "Unsupported type"); |
| 141 | + } |
| 142 | + |
| 143 | + auto result = queryClient.ExecuteQuery(Sprintf(R"( |
| 144 | + UPSERT INTO `/Root/TimeTable` (Key, %s) VALUES ($key, $param); |
| 145 | + )", colName.c_str()), NQuery::TTxControl::NoTx(), params.Build()).ExtractValueSync(); |
| 146 | + UNIT_ASSERT_VALUES_EQUAL_C(result.IsSuccess(), success, result.GetIssues().ToString()); |
| 147 | + } |
| 148 | + }; |
| 149 | + |
| 150 | + { |
| 151 | + // Date32 |
| 152 | + fUpsertAndCheck(1, TWideDays(0), /* success */ true); // Basic |
| 153 | + fUpsertAndCheck(2, TWideDays(NYql::NUdf::MIN_DATE32), /* success */ true); // Min is inclusive |
| 154 | + fUpsertAndCheck(3, TWideDays(NYql::NUdf::MAX_DATE32), /* success */ true); // Max is inclusive |
| 155 | + fUpsertAndCheck(4, TWideDays(NYql::NUdf::MIN_DATE32 - 1), /* success */ false); // Out of bounds |
| 156 | + fUpsertAndCheck(5, TWideDays(NYql::NUdf::MAX_DATE32 + 1), /* success */ false); // Out of bounds |
| 157 | + } |
| 158 | + |
| 159 | + { |
| 160 | + // Datetime64 |
| 161 | + fUpsertAndCheck(11, TWideSeconds(0), /* success */ true); // Basic |
| 162 | + fUpsertAndCheck(12, TWideSeconds(NYql::NUdf::MIN_DATETIME64), /* success */ true); // Min is inclusive |
| 163 | + fUpsertAndCheck(13, TWideSeconds(NYql::NUdf::MAX_DATETIME64), /* success */ true); // Max is inclusive |
| 164 | + fUpsertAndCheck(14, TWideSeconds(NYql::NUdf::MIN_DATETIME64 - 1), /* success */ false); // Out of bounds |
| 165 | + fUpsertAndCheck(15, TWideSeconds(NYql::NUdf::MAX_DATETIME64 + 1), /* success */ false); // Out of bounds |
| 166 | + } |
| 167 | + |
| 168 | + { |
| 169 | + // Timestamp64 |
| 170 | + fUpsertAndCheck(21, TWideMicroseconds(0), /* success */ true); // Basic |
| 171 | + fUpsertAndCheck(22, TWideMicroseconds(NYql::NUdf::MIN_TIMESTAMP64), /* success */ true); // Min is inclusive |
| 172 | + fUpsertAndCheck(23, TWideMicroseconds(NYql::NUdf::MAX_TIMESTAMP64), /* success */ true); // Max is inclusive |
| 173 | + fUpsertAndCheck(24, TWideMicroseconds(NYql::NUdf::MIN_TIMESTAMP64 - 1), /* success */ false); // Out of bounds |
| 174 | + fUpsertAndCheck(25, TWideMicroseconds(NYql::NUdf::MAX_TIMESTAMP64 + 1), /* success */ false); // Out of bounds |
| 175 | + } |
| 176 | + |
| 177 | + { |
| 178 | + // Interval64 |
| 179 | + fUpsertAndCheck(31, static_cast<i64>(0), /* success */ true); // Basic |
| 180 | + fUpsertAndCheck(32, NYql::NUdf::MAX_INTERVAL64, /* success */ true); // Max is inclusive |
| 181 | + fUpsertAndCheck(33, -NYql::NUdf::MAX_INTERVAL64, /* success */ true); // -Max is inclusive |
| 182 | + fUpsertAndCheck(34, NYql::NUdf::MAX_INTERVAL64 + 1, /* success */ false); // Out of bounds |
| 183 | + fUpsertAndCheck(35, -(NYql::NUdf::MAX_INTERVAL64 + 1), /* success */ false); // Out of bounds |
| 184 | + } |
| 185 | + } |
| 186 | + |
77 | 187 | Y_UNIT_TEST_TWIN(DecimalOutOfPrecisionBulk, EnableParameterizedDecimal) { |
78 | 188 | TKikimrSettings serverSettings; |
79 | 189 | serverSettings.FeatureFlags.SetEnableParameterizedDecimal(EnableParameterizedDecimal); |
|
0 commit comments