|
1 | 1 | package tech.ydb.jdbc.impl; |
2 | 2 |
|
3 | 3 | import java.math.BigDecimal; |
| 4 | +import java.math.BigInteger; |
4 | 5 | import java.sql.Date; |
5 | 6 | import java.sql.PreparedStatement; |
6 | 7 | import java.sql.ResultSet; |
@@ -982,4 +983,74 @@ private void assertNextDate(ResultSet rs, int key, LocalDate ld) throws SQLExcep |
982 | 983 | Assertions.assertEquals(ld.atStartOfDay(), rs.getObject("c_Date", LocalDateTime.class)); |
983 | 984 | Assertions.assertEquals(ld.atStartOfDay(ZoneId.systemDefault()).toInstant(), rs.getObject("c_Date", Instant.class)); |
984 | 985 | } |
| 986 | + |
| 987 | + @ParameterizedTest(name = "with {0}") |
| 988 | + @EnumSource(SqlQueries.JdbcQuery.class) |
| 989 | + public void decimalTest(SqlQueries.JdbcQuery query) throws SQLException { |
| 990 | + String upsert = TEST_TABLE.upsertOne(query, "c_Decimal", "Decimal(22, 9)"); |
| 991 | + |
| 992 | + // YDB partially ignores Decimal(22, 9) limit, but have hard limit to 35 digits |
| 993 | + String maxValue = "9999999999" + "9999999999" + "9999999999" + "99999"; |
| 994 | + BigDecimal closeToInf = new BigDecimal(new BigInteger(maxValue), 9); |
| 995 | + BigDecimal closeToNegInf = new BigDecimal(new BigInteger(maxValue).negate(), 9); |
| 996 | + try (PreparedStatement ps = jdbc.connection().prepareStatement(upsert)) { |
| 997 | + ps.setInt(1, 1); |
| 998 | + ps.setBigDecimal(2, BigDecimal.valueOf(1.5d)); |
| 999 | + ps.execute(); |
| 1000 | + |
| 1001 | + ps.setInt(1, 2); |
| 1002 | + ps.setBigDecimal(2, BigDecimal.valueOf(-12345, 10)); // will be rounded to -0.000001234 |
| 1003 | + ps.execute(); |
| 1004 | + |
| 1005 | + ps.setInt(1, 3); |
| 1006 | + ps.setBigDecimal(2, closeToInf); |
| 1007 | + ps.execute(); |
| 1008 | + |
| 1009 | + ps.setInt(1, 4); |
| 1010 | + ps.setBigDecimal(2, closeToNegInf); |
| 1011 | + ps.execute(); |
| 1012 | + |
| 1013 | + ps.setInt(1, 5); |
| 1014 | + ExceptionAssert.sqlException("" |
| 1015 | + + "Cannot cast to decimal type Decimal(22, 9): " |
| 1016 | + + "[class java.math.BigDecimal: 100000000000000000000000000.000000000] is Infinite", |
| 1017 | + () -> ps.setBigDecimal(2, closeToInf.add(BigDecimal.valueOf(1, 9))) |
| 1018 | + ); |
| 1019 | + |
| 1020 | + ExceptionAssert.sqlException("" |
| 1021 | + + "Cannot cast to decimal type Decimal(22, 9): " |
| 1022 | + + "[class java.math.BigDecimal: -100000000000000000000000000.000000000] is -Infinite", |
| 1023 | + () -> ps.setBigDecimal(2, closeToNegInf.subtract(BigDecimal.valueOf(1, 9))) |
| 1024 | + ); |
| 1025 | + |
| 1026 | + ExceptionAssert.sqlException("" |
| 1027 | + + "Cannot cast to decimal type Decimal(22, 9): " |
| 1028 | + + "[class java.math.BigDecimal: 100000000000000000000000000.000000001] is NaN", |
| 1029 | + () -> ps.setBigDecimal(2, closeToInf.add(BigDecimal.valueOf(2, 9))) |
| 1030 | + ); |
| 1031 | + } |
| 1032 | + |
| 1033 | + try (Statement st = jdbc.connection().createStatement()) { |
| 1034 | + try (ResultSet rs = st.executeQuery(TEST_TABLE.selectColumn("c_Decimal"))) { |
| 1035 | + assertNextDecimal(rs, 1, BigDecimal.valueOf(1.5d).setScale(9)); |
| 1036 | + assertNextDecimal(rs, 2, BigDecimal.valueOf(-1234, 9)); |
| 1037 | + assertNextDecimal(rs, 3, closeToInf); |
| 1038 | + assertNextDecimal(rs, 4, closeToNegInf); |
| 1039 | + |
| 1040 | + Assertions.assertFalse(rs.next()); |
| 1041 | + } |
| 1042 | + } |
| 1043 | + }; |
| 1044 | + |
| 1045 | + private void assertNextDecimal(ResultSet rs, int key, BigDecimal bg) throws SQLException { |
| 1046 | + Assertions.assertTrue(rs.next()); |
| 1047 | + Assertions.assertEquals(key, rs.getInt("key")); |
| 1048 | + |
| 1049 | + Object obj = rs.getObject("c_Decimal"); |
| 1050 | + Assertions.assertTrue(obj instanceof BigDecimal); |
| 1051 | + Assertions.assertEquals(bg, obj); |
| 1052 | + |
| 1053 | + BigDecimal decimal = rs.getBigDecimal("c_Decimal"); |
| 1054 | + Assertions.assertEquals(bg, decimal); |
| 1055 | + } |
985 | 1056 | } |
0 commit comments