@@ -74,6 +74,146 @@ Y_UNIT_TEST_SUITE(KqpQuery) {
74
74
UNIT_ASSERT_VALUES_EQUAL (counters.RecompileRequestGet ()->Val (), 1 );
75
75
}
76
76
77
+ Y_UNIT_TEST_TWIN (DecimalOutOfPrecisionBulk, EnableParameterizedDecimal) {
78
+ TKikimrSettings serverSettings;
79
+ serverSettings.FeatureFlags .SetEnableParameterizedDecimal (EnableParameterizedDecimal);
80
+ serverSettings.WithSampleTables = false ;
81
+
82
+ TKikimrRunner kikimr (serverSettings);
83
+ auto client = kikimr.GetQueryClient ();
84
+
85
+ {
86
+ auto ddlResult = client.ExecuteQuery (R"(
87
+ CREATE TABLE DecTest (
88
+ Key Int32 NOT NULL,
89
+ Value Decimal(22, 9) NOT NULL,
90
+ PRIMARY KEY (Key)
91
+ );
92
+ )" , NYdb::NQuery::TTxControl::NoTx ()).ExtractValueSync ();
93
+ UNIT_ASSERT_C (ddlResult.IsSuccess (), ddlResult.GetIssues ().ToString ());
94
+ }
95
+
96
+ // 10000000000000 in Decimal(35, 9), invalid for Decimal(22, 9)
97
+ Ydb::Value value;
98
+ value.set_low_128 (1864712049423024128 );
99
+ value.set_high_128 (542 );
100
+ auto invalidValue = TDecimalValue (value, NYdb::TDecimalType (22 , 9 ));
101
+
102
+ {
103
+ auto db = kikimr.GetTableClient ();
104
+ auto session = db.CreateSession ().GetValueSync ().GetSession ();
105
+
106
+ NYdb::TValueBuilder rows;
107
+ rows.BeginList ();
108
+ rows.AddListItem ()
109
+ .BeginStruct ()
110
+ .AddMember (" Key" ).Int32 (1 )
111
+ .AddMember (" Value" ).Decimal (TDecimalValue (" 10" , 22 , 9 ))
112
+ .EndStruct ();
113
+ rows.AddListItem ()
114
+ .BeginStruct ()
115
+ .AddMember (" Key" ).Int32 (2 )
116
+ .AddMember (" Value" ).Decimal (invalidValue)
117
+ .EndStruct ();
118
+ rows.AddListItem ()
119
+ .BeginStruct ()
120
+ .AddMember (" Key" ).Int32 (3 )
121
+ .AddMember (" Value" ).Decimal (TDecimalValue (" 10000000000000" , 22 , 9 ))
122
+ .EndStruct ();
123
+ rows.EndList ();
124
+
125
+ auto resultUpsert = db.BulkUpsert (" /Root/DecTest" , rows.Build ()).GetValueSync ();
126
+ // TODO: Plan A, upsert should fail as provided value is invalid for given type.
127
+ UNIT_ASSERT_C (!resultUpsert.IsSuccess (), resultUpsert.GetIssues ().ToString ());
128
+
129
+ auto tableYson = ReadTableToYson (session, " /Root/DecTest" );
130
+ // TODO: Plan B, value for key 2 should be inf, as provided value is out of range
131
+ // for given type.
132
+ CompareYson (R"( [])" , tableYson);
133
+ }
134
+ }
135
+
136
+ Y_UNIT_TEST_QUAD (DecimalOutOfPrecision, UseOltpSink, EnableParameterizedDecimal) {
137
+ TKikimrSettings serverSettings;
138
+ serverSettings.AppConfig .MutableTableServiceConfig ()->SetEnableOltpSink (UseOltpSink);
139
+ serverSettings.FeatureFlags .SetEnableParameterizedDecimal (EnableParameterizedDecimal);
140
+ serverSettings.WithSampleTables = false ;
141
+
142
+ TKikimrRunner kikimr (serverSettings);
143
+ auto client = kikimr.GetQueryClient ();
144
+
145
+ {
146
+ auto ddlResult = client.ExecuteQuery (Sprintf (R"(
147
+ CREATE TABLE DecTest (
148
+ Key Int32 NOT NULL,
149
+ Value Decimal(22, 9),
150
+ %s
151
+ PRIMARY KEY (Key)
152
+ );
153
+ )" , EnableParameterizedDecimal ? " ValueLarge Decimal(35, 9), " : " " ), NYdb::NQuery::TTxControl::NoTx ()).ExtractValueSync ();
154
+ UNIT_ASSERT_C (ddlResult.IsSuccess (), ddlResult.GetIssues ().ToString ());
155
+ }
156
+
157
+ // 10000000000000 in Decimal(35, 9), invalid for Decimal(22, 9)
158
+ Ydb::Value value;
159
+ value.set_low_128 (1864712049423024128 );
160
+ value.set_high_128 (542 );
161
+ auto invalidValue = TDecimalValue (value, NYdb::TDecimalType (22 , 9 ));
162
+
163
+ auto validValue = TDecimalValue (value, NYdb::TDecimalType (35 , 9 ));
164
+
165
+ {
166
+ auto params = TParamsBuilder ()
167
+ .AddParam (" $value" ).Decimal (invalidValue).Build ()
168
+ .Build ();
169
+
170
+ auto writeResult = client.ExecuteQuery (R"(
171
+ UPSERT INTO DecTest (Key, Value) VALUES
172
+ (1, CAST(10 AS Decimal(22,9))),
173
+ (2, $value),
174
+ (3, $value - CAST(1 AS Decimal(22,9)));
175
+ )" , NYdb::NQuery::TTxControl::BeginTx ().CommitTx (), params).ExtractValueSync ();
176
+
177
+ // TODO: Plan A, query should fail as provided value is invalid for given type.
178
+ UNIT_ASSERT_C (!writeResult.IsSuccess (), writeResult.GetIssues ().ToString ());
179
+ UNIT_ASSERT_EQUAL_C (writeResult.GetStatus (), EStatus::BAD_REQUEST, writeResult.GetIssues ().ToString ());
180
+
181
+ // TODO: Plan B, value for key 2 should be inf, as provided value is out of range
182
+ // for given type.
183
+ auto session = kikimr.GetTableClient ().CreateSession ().GetValueSync ().GetSession ();
184
+ auto tableYson = ReadTableToYson (session, " /Root/DecTest" );
185
+ CompareYson (R"( [])" , tableYson);
186
+
187
+ if (EnableParameterizedDecimal)
188
+ {
189
+ auto paramsValid = TParamsBuilder ()
190
+ .AddParam (" $value" ).Decimal (validValue).Build ()
191
+ .Build ();
192
+ auto writeResult = client.ExecuteQuery (R"(
193
+ UPSERT INTO DecTest (Key, ValueLarge) VALUES
194
+ (2, $value);
195
+ )" , NYdb::NQuery::TTxControl::BeginTx ().CommitTx (), paramsValid).ExtractValueSync ();
196
+
197
+ // TODO: Plan A, query should fail as provided value is invalid for given type.
198
+ UNIT_ASSERT_C (writeResult.IsSuccess (), writeResult.GetIssues ().ToString ());
199
+ UNIT_ASSERT_EQUAL_C (writeResult.GetStatus (), EStatus::SUCCESS, writeResult.GetIssues ().ToString ());
200
+
201
+ auto tableYson = ReadTableToYson (session, " /Root/DecTest" );
202
+ CompareYson (R"( [[[2];#;["10000000000000"]]])" , tableYson);
203
+ }
204
+
205
+ if (EnableParameterizedDecimal)
206
+ {
207
+ auto writeResult = client.ExecuteQuery (R"(
208
+ UPSERT INTO DecTest (Key, Value) SELECT Key, ValueLarge as Value FROM DecTest;
209
+ )" , NYdb::NQuery::TTxControl::BeginTx ().CommitTx ()).ExtractValueSync ();
210
+ // TODO: Plan A, query should fail as provided value is invalid for given type.
211
+ UNIT_ASSERT_C (!writeResult.IsSuccess (), writeResult.GetIssues ().ToString ());
212
+ UNIT_ASSERT_EQUAL_C (writeResult.GetStatus (), EStatus::GENERIC_ERROR, writeResult.GetIssues ().ToString ());
213
+ }
214
+ }
215
+ }
216
+
77
217
Y_UNIT_TEST (QueryCache) {
78
218
TKikimrRunner kikimr;
79
219
auto db = kikimr.GetTableClient ();
0 commit comments