@@ -148,44 +148,138 @@ public async Task Date_WhenSetDateOnly_ReturnDateTime()
148148 [ Theory ]
149149 [ InlineData ( "12345" , "12345.0000000000" , 22 , 9 ) ]
150150 [ InlineData ( "54321" , "54321" , 5 , 0 ) ]
151- [ InlineData ( "493235.4" , "493235.40" , 7 , 2 ) ]
151+ [ InlineData ( "493235.4" , "493235.40" , 8 , 2 ) ]
152152 [ InlineData ( "123.46" , "123.46" , 5 , 2 ) ]
153+ [ InlineData ( "0.46" , "0.46" , 2 , 2 ) ]
153154 [ InlineData ( "-184467434073.70911616" , "-184467434073.7091161600" , 35 , 10 ) ]
154155 [ InlineData ( "-18446744074" , "-18446744074" , 12 , 0 ) ]
155156 [ InlineData ( "-184467440730709551616" , "-184467440730709551616" , 21 , 0 ) ]
156157 [ InlineData ( "-218446744073.709551616" , "-218446744073.7095516160" , 22 , 10 ) ]
158+ [ InlineData ( "79228162514264337593543950335" , "79228162514264337593543950335" , 29 , 0 ) ]
159+ [ InlineData ( "79228162514264337593543950.335" , "79228162514264337593543950.335" , 29 , 3 ) ]
160+ [ InlineData ( "-79228162514264337593543950335" , "-79228162514264337593543950335" , 29 , 0 ) ]
161+ [ InlineData ( "-79228162514264337593543950.335" , "-79228162514264337593543950.335" , 29 , 3 ) ]
157162 [ InlineData ( null , null , 22 , 9 ) ]
158163 [ InlineData ( null , null , 35 , 9 ) ]
159164 [ InlineData ( null , null , 35 , 0 ) ]
160165 public async Task Decimal_WhenDecimalIsScaleAndPrecision_ReturnDecimal ( string ? value , string ? expected ,
161166 byte precision , byte scale )
162167 {
163168 await using var ydbConnection = await CreateOpenConnectionAsync ( ) ;
164- var decimalTableName = $ "DecimalTable_{ Random . Shared . Next ( ) } ";
169+ var tableName = $ "DecimalTable_{ Random . Shared . Next ( ) } ";
165170 var decimalValue = value == null ? ( decimal ? ) null : decimal . Parse ( value , CultureInfo . InvariantCulture ) ;
166171 await new YdbCommand ( ydbConnection )
167- {
168- CommandText = $ """
169- CREATE TABLE { decimalTableName } (
170- DecimalField Decimal({ precision } , { scale } ),
171- PRIMARY KEY (DecimalField)
172- )
173- """
174- } . ExecuteNonQueryAsync ( ) ;
172+ { CommandText = $ "CREATE TABLE { tableName } (d Decimal({ precision } , { scale } ), PRIMARY KEY (d))" }
173+ . ExecuteNonQueryAsync ( ) ;
175174 await new YdbCommand ( ydbConnection )
176175 {
177- CommandText = $ "INSERT INTO { decimalTableName } (DecimalField ) VALUES (@DecimalField );",
176+ CommandText = $ "INSERT INTO { tableName } (d ) VALUES (@d );",
178177 Parameters =
179- {
180- new YdbParameter ( "DecimalField" , DbType . Decimal , decimalValue ) { Precision = precision , Scale = scale }
181- }
178+ { new YdbParameter ( "d" , DbType . Decimal , decimalValue ) { Precision = precision , Scale = scale } }
182179 } . ExecuteNonQueryAsync ( ) ;
183180
184181 Assert . Equal ( expected == null ? DBNull . Value : decimal . Parse ( expected , CultureInfo . InvariantCulture ) ,
185- await new YdbCommand ( ydbConnection ) { CommandText = $ "SELECT DecimalField FROM { decimalTableName } ;" }
182+ await new YdbCommand ( ydbConnection ) { CommandText = $ "SELECT d FROM { tableName } ;" }
186183 . ExecuteScalarAsync ( ) ) ;
187184
188- await new YdbCommand ( ydbConnection ) { CommandText = $ "DROP TABLE { decimalTableName } ;" } . ExecuteNonQueryAsync ( ) ;
185+ await new YdbCommand ( ydbConnection ) { CommandText = $ "DROP TABLE { tableName } ;" } . ExecuteNonQueryAsync ( ) ;
186+ }
187+
188+ [ Theory ]
189+ [ InlineData ( "123.456" , 5 , 2 ) ]
190+ [ InlineData ( "1.46" , 2 , 2 ) ]
191+ [ InlineData ( "654321" , 5 , 0 ) ]
192+ [ InlineData ( "493235.4" , 7 , 2 ) ]
193+ [ InlineData ( "10.46" , 3 , 2 ) ]
194+ [ InlineData ( "99.999" , 5 , 2 ) ]
195+ [ InlineData ( "0.001" , 3 , 2 ) ]
196+ [ InlineData ( "-12.345" , 5 , 2 ) ]
197+ [ InlineData ( "7.001" , 4 , 2 ) ]
198+ [ InlineData ( "1.0001" , 5 , 3 ) ]
199+ [ InlineData ( "1000.00" , 5 , 2 ) ]
200+ [ InlineData ( "123456.7" , 6 , 1 ) ]
201+ [ InlineData ( "999.99" , 5 , 4 ) ]
202+ [ InlineData ( "-100" , 2 , 0 ) ]
203+ [ InlineData ( "-0.12" , 2 , 1 ) ]
204+ [ InlineData ( "10.0" , 2 , 0 ) ]
205+ [ InlineData ( "-0.1" , 1 , 0 ) ]
206+ [ InlineData ( "10000" , 4 , 0 ) ]
207+ [ InlineData ( "12345" , 4 , 0 ) ]
208+ [ InlineData ( "12.3456" , 6 , 3 ) ]
209+ [ InlineData ( "123.45" , 4 , 1 ) ]
210+ [ InlineData ( "9999.9" , 5 , 0 ) ]
211+ [ InlineData ( "-1234.56" , 5 , 1 ) ]
212+ [ InlineData ( "-1000" , 3 , 0 ) ]
213+ [ InlineData ( "0.0001" , 4 , 3 ) ]
214+ [ InlineData ( "99999" , 4 , 0 ) ]
215+ [ InlineData ( "9.999" , 3 , 2 ) ]
216+ [ InlineData ( "123.4" , 3 , 0 ) ]
217+ [ InlineData ( "1.234" , 4 , 2 ) ]
218+ [ InlineData ( "-98.765" , 5 , 2 ) ]
219+ [ InlineData ( "100.01" , 5 , 1 ) ]
220+ [ InlineData ( "100000" , 5 , 0 ) ]
221+ public async Task Decimal_WhenNotRepresentableBySystemDecimal_ThrowsOverflowException ( string value , byte precision ,
222+ byte scale )
223+ {
224+ await using var ydbConnection = await CreateOpenConnectionAsync ( ) ;
225+ var tableName = $ "DecimalOverflowTable__{ Random . Shared . Next ( ) } ";
226+ var decimalValue = decimal . Parse ( value , CultureInfo . InvariantCulture ) ;
227+ await new YdbCommand ( ydbConnection )
228+ { CommandText = $ "CREATE TABLE { tableName } (d Decimal(5,2), PRIMARY KEY(d))" }
229+ . ExecuteNonQueryAsync ( ) ;
230+
231+ Assert . Equal ( $ "Value { decimalValue } does not fit Decimal({ precision } , { scale } )",
232+ ( await Assert . ThrowsAsync < OverflowException > ( ( ) => new YdbCommand ( ydbConnection )
233+ {
234+ CommandText = $ "INSERT INTO { tableName } (d) VALUES (@d);",
235+ Parameters =
236+ {
237+ new YdbParameter ( "d" , DbType . Decimal , 123.456m )
238+ { Value = decimalValue , Precision = precision , Scale = scale }
239+ }
240+ } . ExecuteNonQueryAsync ( ) ) ) . Message ) ;
241+
242+ Assert . Equal ( 0ul ,
243+ ( ulong ) ( await new YdbCommand ( ydbConnection ) { CommandText = $ "SELECT COUNT(*) FROM { tableName } ;" }
244+ . ExecuteScalarAsync ( ) ) !
245+ ) ;
246+
247+ await new YdbCommand ( ydbConnection ) { CommandText = $ "DROP TABLE { tableName } ;" } . ExecuteNonQueryAsync ( ) ;
248+ }
249+
250+
251+ [ Fact ]
252+ public void Decimal_WhenScaleGreaterThanPrecision_ThrowsArgumentOutOfRangeException ( ) =>
253+ Assert . Throws < ArgumentOutOfRangeException > ( ( ) =>
254+ new YdbParameter ( "d" , DbType . Decimal , 0.0m ) { Precision = 1 , Scale = 2 } . TypedValue ) ;
255+
256+ [ Theory ]
257+ [ InlineData ( "10000000000000000000000000000000000" , 35 , 0 ) ]
258+ [ InlineData ( "1000000000000000000000000.0000000000" , 35 , 10 ) ]
259+ [ InlineData ( "1000000000000000000000000000000000" , 34 , 0 ) ]
260+ [ InlineData ( "100000000000000000000000.0000000000" , 34 , 10 ) ]
261+ [ InlineData ( "100000000000000000000000000000000" , 33 , 0 ) ]
262+ [ InlineData ( "10000000000000000000000.0000000000" , 33 , 10 ) ]
263+ [ InlineData ( "-10000000000000000000000000000000" , 32 , 0 ) ]
264+ [ InlineData ( "-1000000000000000000000.0000000000" , 32 , 10 ) ]
265+ [ InlineData ( "-1000000000000000000000000000000" , 31 , 0 ) ]
266+ [ InlineData ( "-100000000000000000000.0000000000" , 31 , 10 ) ]
267+ [ InlineData ( "1000000000000000000000000000000" , 30 , 0 ) ]
268+ [ InlineData ( "100000000000000000000.0000000000" , 30 , 10 ) ]
269+ [ InlineData ( "79228162514264337593543950336" , 29 , 0 ) ]
270+ [ InlineData ( "79228162514264337593543950.336" , 29 , 3 ) ]
271+ [ InlineData ( "-79228162514264337593543950336" , 29 , 0 ) ]
272+ [ InlineData ( "-79228162514264337593543950.336" , 29 , 3 ) ]
273+ [ InlineData ( "100000" , 4 , 0 ) ] // inf
274+ public async Task Decimal_WhenYdbReturnsDecimalWithPrecisionGreaterThan28_ThrowsOverflowException ( string value ,
275+ int precision , int scale )
276+ {
277+ await using var ydbConnection = await CreateOpenConnectionAsync ( ) ;
278+ Assert . Equal ( "Value does not fit into decimal" , ( await Assert . ThrowsAsync < OverflowException > ( ( ) =>
279+ new YdbCommand ( ydbConnection )
280+ { CommandText = $ "SELECT (CAST('{ value } ' AS Decimal({ precision } , { scale } )));" }
281+ . ExecuteScalarAsync ( ) )
282+ ) . Message ) ;
189283 }
190284
191285 [ Fact ]
0 commit comments