Skip to content

Commit

Permalink
Updated tests for Int32, Int64, Time, Date and Timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
alex268 committed Aug 23, 2024
1 parent d3e5863 commit 3584e69
Show file tree
Hide file tree
Showing 4 changed files with 416 additions and 88 deletions.
2 changes: 1 addition & 1 deletion jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} -Duser.timezone=GMT-04</argLine>
<environmentVariables>
<TESTCONTAINERS_REUSE_ENABLE>true</TESTCONTAINERS_REUSE_ENABLE>
<YDB_DOCKER_IMAGE>cr.yandex/yc/yandex-docker-local-ydb:trunk</YDB_DOCKER_IMAGE>
</environmentVariables>
<systemPropertyVariables>
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
</systemPropertyVariables>

<!--
Enable support of test's custom display names
https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html#surefire-extensions-and-reports-configuration-for-displayname
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ private String upsertSql(String column, String type) {
.replaceAll("#tableName", TEST_TABLE_NAME);
}

private YdbPreparedStatement prepareUpsert(YdbPrepareMode mode,String column, String type)
throws SQLException {
return jdbc.connection().unwrap(YdbConnection.class).prepareStatement(upsertSql(column, type), mode);
}

private PreparedStatement prepareSimpleSelect(String column) throws SQLException {
String sql = SIMPLE_SELECT_SQL
.replaceAll("#column", column)
Expand Down
260 changes: 253 additions & 7 deletions jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.TimeZone;

import org.junit.Assert;
import org.junit.jupiter.api.AfterAll;
Expand Down Expand Up @@ -52,12 +53,6 @@ public class YdbPreparedStatementTest {
*/
private static final Instant TEST_TS = Instant.ofEpochSecond(1583288311l, 123456789);

@BeforeAll
public static void setupTimeZone() throws SQLException {
// Set non UTC timezone to test different cases
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4))));
}

@BeforeAll
public static void createTable() throws SQLException {
try (Statement statement = jdbc.connection().createStatement();) {
Expand Down Expand Up @@ -341,6 +336,257 @@ public void batchUpsertAllTest(SqlQueries.JdbcQuery query) throws SQLException {
}
};

@ParameterizedTest(name = "with {0}")
@EnumSource(SqlQueries.JdbcQuery.class)
public void int32Test(SqlQueries.JdbcQuery query) throws SQLException {
String upsert = TEST_TABLE.upsertOne(query, "c_Int32", "Int32");
boolean castingSupported = query != SqlQueries.JdbcQuery.IN_MEMORY;
int ydbSqlType = YdbConst.SQL_KIND_PRIMITIVE + PrimitiveType.Int32.ordinal();

try (PreparedStatement ps = jdbc.connection().prepareStatement(upsert)) {
ps.setInt(1, 1);
ps.setByte(2, (byte) -120);
ps.execute();

ps.setInt(1, 2);
ps.setShort(2, (short) 1234);
ps.execute();

ps.setInt(1, 3);
ps.setInt(2, 1234567);
ps.execute();

ps.setInt(1, 4);
ps.setTime(2, Time.valueOf(LocalTime.of(11, 23, 59))); // will be stored as 11 * 3600 + 23 * 60 + 59
ps.execute();

ps.setInt(1, 5);
ps.setTime(2, new Time(TEST_TS.toEpochMilli())); // will be stored local time of timestamp
ps.execute();

if (castingSupported) {
ps.setInt(1, 6);
ps.setBoolean(2, true);
ps.execute();

ps.setInt(1, 7);
ps.setDate(2, Date.valueOf(LocalDate.of(2020, Month.MARCH, 3))); // will be store as day of epoch
ps.execute();

ps.setInt(1, 8);
ps.setDate(2, new Date(TEST_TS.toEpochMilli())); // will be store as day of the year
ps.execute();

ps.setInt(1, 9);
ps.setTimestamp(2, new Timestamp(TEST_TS.toEpochMilli()));
ps.execute();
} else {
ps.setInt(1, 6);
ps.setObject(2, Boolean.TRUE, ydbSqlType);
ps.execute();

ps.setInt(1, 7);
ps.setObject(2, Date.valueOf(LocalDate.of(2020, Month.MARCH, 3)), ydbSqlType);
ps.execute();

ps.setInt(1, 8);
ps.setObject(2, new Date(TEST_TS.toEpochMilli()), ydbSqlType);
ps.execute();

ps.setInt(1, 9);
ps.setObject(2, new Timestamp(TEST_TS.toEpochMilli()), ydbSqlType);
ps.execute();
}
}

try (Statement statement = jdbc.connection().createStatement()) {
try (ResultSet rs = statement.executeQuery(TEST_TABLE.selectColumn("c_Int32"))) {
assertNextInt32(rs, 1, -120);
assertNextInt32(rs, 2, 1234);
assertNextInt32(rs, 3, 1234567);
assertNextInt32(rs, 4, 11 * 3600 + 23 * 60 + 59);
assertNextInt32(rs, 5, TEST_TS.atZone(ZoneId.systemDefault()).toLocalTime().toSecondOfDay());

assertNextInt32(rs, 6, 1);
assertNextInt32(rs, 7, (int) LocalDate.of(2020, Month.MARCH, 3).toEpochDay());
assertNextInt32(rs, 8, (int) TEST_TS.atZone(ZoneId.systemDefault()).toLocalDate().toEpochDay());
assertNextInt32(rs, 9, (int) TEST_TS.toEpochMilli());

Assert.assertFalse(rs.next());
}
}
};

private void assertNextInt32(ResultSet rs, int key, Integer value) throws SQLException {
Assert.assertTrue(rs.next());
Assert.assertEquals(key, rs.getInt("key"));

Object obj = rs.getObject("c_Int32");
Assert.assertTrue(obj instanceof Integer);
Assert.assertEquals(value, obj);

if (value.byteValue() == value.intValue()) {
Assert.assertEquals(value.intValue(), rs.getByte("c_Int32"));
} else {
String msg = String.format("Cannot cast [Int32] with value [%s] to [byte]", value);
ExceptionAssert.sqlException(msg, () -> rs.getByte("c_Int32"));
}

if (value.shortValue() == value.intValue()) {
Assert.assertEquals(value.intValue(), rs.getShort("c_Int32"));
} else {
String msg = String.format("Cannot cast [Int32] with value [%s] to [short]", value);
ExceptionAssert.sqlException(msg, () -> rs.getShort("c_Int32"));
}

Assert.assertEquals(value.intValue(), rs.getInt("c_Int32"));
Assert.assertEquals(value.longValue(), rs.getLong("c_Int32"));

if (value >= 0 && value < 24 * 3600) {
Assert.assertEquals(Time.valueOf(LocalTime.ofSecondOfDay(value)), rs.getTime("c_Int32"));
} else {
String msg = String.format("Cannot cast [Int32] with value [%s] to [class java.sql.Time]", value);
ExceptionAssert.sqlException(msg, () -> rs.getTime("c_Int32"));
}

Assert.assertEquals(Date.valueOf(LocalDate.ofEpochDay(value)), rs.getDate("c_Int32"));
Assert.assertEquals(new Timestamp(value), rs.getTimestamp("c_Int32"));
}

@ParameterizedTest(name = "with {0}")
@EnumSource(SqlQueries.JdbcQuery.class)
public void int64Test(SqlQueries.JdbcQuery query) throws SQLException {
String upsert = TEST_TABLE.upsertOne(query, "c_Int64", "Int64");
boolean castingSupported = query != SqlQueries.JdbcQuery.IN_MEMORY;
int ydbSqlType = YdbConst.SQL_KIND_PRIMITIVE + PrimitiveType.Int64.ordinal();

try (PreparedStatement ps = jdbc.connection().prepareStatement(upsert)) {
ps.setInt(1, 1);
ps.setByte(2, (byte) -120);
ps.execute();

ps.setInt(1, 2);
ps.setShort(2, (short) 1234);
ps.execute();

ps.setInt(1, 3);
ps.setInt(2, 1234567);
ps.execute();

ps.setInt(1, 4);
ps.setLong(2, 54211234567l);
ps.execute();

ps.setInt(1, 5);
ps.setTime(2, Time.valueOf(LocalTime.of(11, 23, 59))); // will be stored as 11 * 3600 + 23 * 60 + 59
ps.execute();

ps.setInt(1, 6);
ps.setTime(2, new Time(TEST_TS.toEpochMilli())); // will be stored local time of timestamp
ps.execute();

if (castingSupported) {
ps.setInt(1, 7);
ps.setBoolean(2, true);
ps.execute();

ps.setInt(1, 8);
ps.setDate(2, Date.valueOf(LocalDate.of(2020, Month.MARCH, 3))); // will be store as day of epoch
ps.execute();

ps.setInt(1, 9);
ps.setDate(2, new Date(TEST_TS.toEpochMilli())); // will be store as day of the year
ps.execute();

ps.setInt(1, 10);
ps.setTimestamp(2, new Timestamp(TEST_TS.toEpochMilli()));
ps.execute();
} else {
ps.setInt(1, 7);
ps.setObject(2, Boolean.TRUE, ydbSqlType);
ps.execute();

ps.setInt(1, 8);
ps.setObject(2, Date.valueOf(LocalDate.of(2020, Month.MARCH, 3)), ydbSqlType);
ps.execute();

ps.setInt(1, 9);
ps.setObject(2, new Date(TEST_TS.toEpochMilli()), ydbSqlType);
ps.execute();

ps.setInt(1, 10);
ps.setObject(2, new Timestamp(TEST_TS.toEpochMilli()), ydbSqlType);
ps.execute();
}
}

try (Statement statement = jdbc.connection().createStatement()) {
try (ResultSet rs = statement.executeQuery(TEST_TABLE.selectColumn("c_Int64"))) {
assertNextInt64(rs, 1, -120l);
assertNextInt64(rs, 2, 1234l);
assertNextInt64(rs, 3, 1234567l);
assertNextInt64(rs, 4, 54211234567l);
assertNextInt64(rs, 5, 11 * 3600l + 23 * 60 + 59);
assertNextInt64(rs, 6, Long.valueOf(TEST_TS.atZone(ZoneId.systemDefault()).toLocalTime().toSecondOfDay()));

assertNextInt64(rs, 7, 1l);
assertNextInt64(rs, 8, LocalDate.of(2020, Month.MARCH, 3).toEpochDay());
assertNextInt64(rs, 9, TEST_TS.atZone(ZoneId.systemDefault()).toLocalDate().toEpochDay());
assertNextInt64(rs, 10, TEST_TS.toEpochMilli());

Assert.assertFalse(rs.next());
}
}
};

private void assertNextInt64(ResultSet rs, int key, Long value) throws SQLException {
Assert.assertTrue(rs.next());
Assert.assertEquals(key, rs.getInt("key"));

Object obj = rs.getObject("c_Int64");
Assert.assertTrue(obj instanceof Long);
Assert.assertEquals(value, obj);

if (value.byteValue() == value.intValue()) {
Assert.assertEquals(value.intValue(), rs.getByte("c_Int64"));
} else {
String msg = String.format("Cannot cast [Int64] with value [%s] to [byte]", value);
ExceptionAssert.sqlException(msg, () -> rs.getByte("c_Int64"));
}

if (value.shortValue() == value.intValue()) {
Assert.assertEquals(value.intValue(), rs.getShort("c_Int64"));
} else {
String msg = String.format("Cannot cast [Int64] with value [%s] to [short]", value);
ExceptionAssert.sqlException(msg, () -> rs.getShort("c_Int64"));
}

if (value.intValue() == value.longValue()) {
Assert.assertEquals(value.intValue(), rs.getInt("c_Int64"));
} else {
String msg = String.format("Cannot cast [Int64] with value [%s] to [int]", value);
ExceptionAssert.sqlException(msg, () -> rs.getInt("c_Int64"));
}

Assert.assertEquals(value.longValue(), rs.getLong("c_Int64"));

if (value >= 0 && value < 24 * 3600) {
Assert.assertEquals(Time.valueOf(LocalTime.ofSecondOfDay(value)), rs.getTime("c_Int64"));
} else {
String msg = String.format("Cannot cast [Int64] with value [%s] to [class java.sql.Time]", value);
ExceptionAssert.sqlException(msg, () -> rs.getTime("c_Int64"));
}

if (ChronoField.EPOCH_DAY.range().isValidValue(value)) {
Assert.assertEquals(Date.valueOf(LocalDate.ofEpochDay(value)), rs.getDate("c_Int64"));
} else {
String msg = String.format("Cannot cast [Int64] with value [%s] to [class java.sql.Date]", value);
ExceptionAssert.sqlException(msg, () -> rs.getDate("c_Int64"));
}

Assert.assertEquals(new Timestamp(value), rs.getTimestamp("c_Int64"));
}

@ParameterizedTest(name = "with {0}")
@EnumSource(SqlQueries.JdbcQuery.class)
public void timestampTest(SqlQueries.JdbcQuery query) throws SQLException {
Expand Down
Loading

0 comments on commit 3584e69

Please sign in to comment.