Skip to content

Commit d732480

Browse files
committed
Change DATE type encoding to integer (#2491)
# Conflicts: # core/src/test/java/com/scalar/db/storage/jdbc/JdbcAdminTestBase.java
1 parent ff01cea commit d732480

10 files changed

+62
-27
lines changed

core/src/main/java/com/scalar/db/storage/cosmos/ResultInterpreter.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ private Column<?> convert(@Nullable Object recordValue, String name, DataType da
9898
return recordValue == null
9999
? DateColumn.ofNull(name)
100100
: DateColumn.of(
101-
name,
102-
TimeRelatedColumnEncodingUtils.decodeDate(((Number) recordValue).longValue()));
101+
name, TimeRelatedColumnEncodingUtils.decodeDate(((Number) recordValue).intValue()));
103102
case TIME:
104103
return recordValue == null
105104
? TimeColumn.ofNull(name)

core/src/main/java/com/scalar/db/storage/dynamo/ResultInterpreter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private Column<?> convert(@Nullable AttributeValue itemValue, String name, DataT
8181
return isNull
8282
? DateColumn.ofNull(name)
8383
: DateColumn.of(
84-
name, TimeRelatedColumnEncodingUtils.decodeDate(Long.parseLong(itemValue.n())));
84+
name, TimeRelatedColumnEncodingUtils.decodeDate(Integer.parseInt(itemValue.n())));
8585
case TIME:
8686
return isNull
8787
? TimeColumn.ofNull(name)

core/src/main/java/com/scalar/db/storage/dynamo/bytes/BytesUtils.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ public static byte[] toBytes(ByteBuffer src) {
112112
}
113113

114114
static void encodeLong(long value, Order order, ByteBuffer dst) {
115-
dst.put(
116-
mask((byte) ((value >> 56) ^ 0x80), order)); // Flip a sign bit to make it binary comparable
115+
// Flip a sign bit to make it binary comparable
116+
dst.put(mask((byte) ((value >> 56) ^ 0x80), order));
117117
dst.put(mask((byte) (value >> 48), order));
118118
dst.put(mask((byte) (value >> 40), order));
119119
dst.put(mask((byte) (value >> 32), order));
@@ -122,4 +122,12 @@ static void encodeLong(long value, Order order, ByteBuffer dst) {
122122
dst.put(mask((byte) (value >> 8), order));
123123
dst.put(mask((byte) value, order));
124124
}
125+
126+
static void encodeInt(int value, Order order, ByteBuffer dst) {
127+
// Flip a sign bit to make it binary comparable
128+
dst.put(mask((byte) ((value >> 24) ^ 0x80), order));
129+
dst.put(mask((byte) (value >> 16), order));
130+
dst.put(mask((byte) (value >> 8), order));
131+
dst.put(mask((byte) value, order));
132+
}
125133
}

core/src/main/java/com/scalar/db/storage/dynamo/bytes/DateBytesEncoder.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.scalar.db.storage.dynamo.bytes;
22

3-
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.encodeLong;
3+
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.encodeInt;
44

55
import com.scalar.db.api.Scan.Ordering.Order;
66
import com.scalar.db.io.DateColumn;
@@ -17,14 +17,14 @@ public class DateBytesEncoder implements BytesEncoder<DateColumn> {
1717
public int encodedLength(DateColumn column, Order order) {
1818
assert column.getValue().isPresent();
1919

20-
return 8;
20+
return 4;
2121
}
2222

2323
@Override
2424
public void encode(DateColumn column, Order order, ByteBuffer dst) {
2525
assert column.getValue().isPresent();
2626

27-
long value = TimeRelatedColumnEncodingUtils.encode(column);
28-
encodeLong(value, order, dst);
27+
int value = TimeRelatedColumnEncodingUtils.encode(column);
28+
encodeInt(value, order, dst);
2929
}
3030
}

core/src/main/java/com/scalar/db/storage/dynamo/bytes/IntBytesEncoder.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.scalar.db.storage.dynamo.bytes;
22

3-
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;
3+
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.encodeInt;
44

55
import com.scalar.db.api.Scan.Ordering.Order;
66
import com.scalar.db.io.IntColumn;
@@ -22,9 +22,6 @@ public void encode(IntColumn column, Order order, ByteBuffer dst) {
2222
assert !column.hasNullValue();
2323

2424
int v = column.getIntValue();
25-
dst.put(mask((byte) ((v >> 24) ^ 0x80), order)); // Flip a sign bit to make it binary comparable
26-
dst.put(mask((byte) (v >> 16), order));
27-
dst.put(mask((byte) (v >> 8), order));
28-
dst.put(mask((byte) v, order));
25+
encodeInt(v, order, dst);
2926
}
3027
}

core/src/main/java/com/scalar/db/storage/jdbc/RdbEngineSqlite.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ public String getDataTypeForEngine(DataType scalarDbDataType) {
8989
case BOOLEAN:
9090
return "BOOLEAN";
9191
case INT:
92+
case DATE:
9293
return "INT";
9394
case BIGINT:
94-
case DATE:
9595
case TIME:
9696
case TIMESTAMP:
9797
case TIMESTAMPTZ:
@@ -120,8 +120,8 @@ public int getSqlTypes(DataType dataType) {
120120
case BOOLEAN:
121121
return Types.BOOLEAN;
122122
case INT:
123-
return Types.INTEGER;
124123
case DATE:
124+
return Types.INTEGER;
125125
case TIME:
126126
case TIMESTAMP:
127127
case TIMESTAMPTZ:
@@ -306,7 +306,7 @@ public String getEscape(LikeExpression likeExpression) {
306306
@Override
307307
public DateColumn parseDateColumn(ResultSet resultSet, String columnName) throws SQLException {
308308
return DateColumn.of(
309-
columnName, TimeRelatedColumnEncodingUtils.decodeDate(resultSet.getLong(columnName)));
309+
columnName, TimeRelatedColumnEncodingUtils.decodeDate(resultSet.getInt(columnName)));
310310
}
311311

312312
@Override
@@ -331,7 +331,7 @@ public TimestampTZColumn parseTimestampTZColumn(ResultSet resultSet, String colu
331331
}
332332

333333
@Override
334-
public RdbEngineTimeTypeStrategy<Long, Long, Long, Long> getTimeTypeStrategy() {
334+
public RdbEngineTimeTypeStrategy<Integer, Long, Long, Long> getTimeTypeStrategy() {
335335
return timeTypeEngine;
336336
}
337337
}

core/src/main/java/com/scalar/db/storage/jdbc/RdbEngineTimeTypeSqlite.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import java.time.LocalTime;
77
import java.time.OffsetDateTime;
88

9-
public class RdbEngineTimeTypeSqlite implements RdbEngineTimeTypeStrategy<Long, Long, Long, Long> {
9+
public class RdbEngineTimeTypeSqlite
10+
implements RdbEngineTimeTypeStrategy<Integer, Long, Long, Long> {
1011

1112
@Override
12-
public Long convert(LocalDate date) {
13+
public Integer convert(LocalDate date) {
1314
return TimeRelatedColumnEncodingUtils.encode(date);
1415
}
1516

core/src/main/java/com/scalar/db/util/TimeRelatedColumnEncodingUtils.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
public final class TimeRelatedColumnEncodingUtils {
1818
private TimeRelatedColumnEncodingUtils() {}
1919

20-
public static long encode(DateColumn column) {
20+
public static int encode(DateColumn column) {
2121
assert column.getDateValue() != null;
2222
return encode(column.getDateValue());
2323
}
2424

25-
public static long encode(LocalDate date) {
26-
return date.toEpochDay();
25+
public static int encode(LocalDate date) {
26+
return Math.toIntExact(date.toEpochDay());
2727
}
2828

29-
public static LocalDate decodeDate(long epochDay) {
29+
public static LocalDate decodeDate(int epochDay) {
3030
return LocalDate.ofEpochDay(epochDay);
3131
}
3232

core/src/test/java/com/scalar/db/storage/TimeRelatedColumnEncodingUtilsTest.java

+32-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,27 @@ public void encodeDate_ShouldWorkProperly() {
2626
DateColumn column = DateColumn.of("date", LocalDate.of(2023, 10, 1));
2727

2828
// Act
29-
long encoded = TimeRelatedColumnEncodingUtils.encode(column);
29+
int encoded = TimeRelatedColumnEncodingUtils.encode(column);
3030

3131
// Assert
3232
assertThat(encoded).isEqualTo(LocalDate.of(2023, 10, 1).toEpochDay());
3333
}
3434

35+
@Test
36+
public void encodeThenDecodeDate_ShouldPreserveDataIntegrity() {
37+
// Arrange
38+
DateColumn min = DateColumn.of("date", DateColumn.MIN_VALUE);
39+
DateColumn max = DateColumn.of("date", DateColumn.MAX_VALUE);
40+
41+
// Act Assert
42+
assertThat(
43+
TimeRelatedColumnEncodingUtils.decodeDate(TimeRelatedColumnEncodingUtils.encode(min)))
44+
.isEqualTo(min.getDateValue());
45+
assertThat(
46+
TimeRelatedColumnEncodingUtils.decodeDate(TimeRelatedColumnEncodingUtils.encode(max)))
47+
.isEqualTo(max.getDateValue());
48+
}
49+
3550
@Test
3651
public void encodeTime_ShouldWorkProperly() {
3752
// Arrange
@@ -44,6 +59,21 @@ public void encodeTime_ShouldWorkProperly() {
4459
assertThat(encoded).isEqualTo(LocalTime.of(12, 34, 56, 123_456_000).toNanoOfDay());
4560
}
4661

62+
@Test
63+
public void encodeThenDecodeTime_ShouldPreserveDataIntegrity() {
64+
// Arrange
65+
TimeColumn min = TimeColumn.of("time", TimeColumn.MIN_VALUE);
66+
TimeColumn max = TimeColumn.of("time", TimeColumn.MAX_VALUE);
67+
68+
// Act Assert
69+
assertThat(
70+
TimeRelatedColumnEncodingUtils.decodeTime(TimeRelatedColumnEncodingUtils.encode(min)))
71+
.isEqualTo(min.getTimeValue());
72+
assertThat(
73+
TimeRelatedColumnEncodingUtils.decodeTime(TimeRelatedColumnEncodingUtils.encode(max)))
74+
.isEqualTo(max.getTimeValue());
75+
}
76+
4777
@Test
4878
public void encodeTimestamp_ShouldWorkProperly() {
4979
// Arrange
@@ -124,7 +154,7 @@ public void encodeTimestampTZ_ShouldWorkProperly() {
124154
public void decodeDate_ShouldWorkProperly() {
125155
// Arrange Act
126156
LocalDate date =
127-
TimeRelatedColumnEncodingUtils.decodeDate(LocalDate.of(2023, 10, 1).toEpochDay());
157+
TimeRelatedColumnEncodingUtils.decodeDate((int) LocalDate.of(2023, 10, 1).toEpochDay());
128158

129159
// Assert
130160
assertThat(date).isEqualTo(LocalDate.of(2023, 10, 1));

core/src/test/java/com/scalar/db/storage/jdbc/JdbcAdminTestBase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ public void createTable_WithClusteringOrderForSqlite_shouldExecuteCreateTableSta
967967
+ "\"indexed\" BOOLEAN NOT NULL,"
968968
+ "\"ordinal_position\" INTEGER NOT NULL,"
969969
+ "PRIMARY KEY (\"full_table_name\", \"column_name\"))",
970-
"CREATE TABLE \"my_ns$foo_table\"(\"c3\" BOOLEAN,\"c1\" TEXT,\"c4\" BLOB,\"c2\" BIGINT,\"c5\" INT,\"c6\" DOUBLE,\"c7\" FLOAT,\"c8\" BIGINT,\"c9\" BIGINT,\"c10\" BIGINT,\"c11\" BIGINT, PRIMARY KEY (\"c3\",\"c1\",\"c4\"))",
970+
"CREATE TABLE \"my_ns$foo_table\"(\"c3\" BOOLEAN,\"c1\" TEXT,\"c4\" BLOB,\"c2\" BIGINT,\"c5\" INT,\"c6\" DOUBLE,\"c7\" FLOAT,\"c8\" INT,\"c9\" BIGINT,\"c10\" BIGINT,\"c11\" BIGINT, PRIMARY KEY (\"c3\",\"c1\",\"c4\"))",
971971
"CREATE INDEX \"index_my_ns_foo_table_c4\" ON \"my_ns$foo_table\" (\"c4\")",
972972
"CREATE INDEX \"index_my_ns_foo_table_c1\" ON \"my_ns$foo_table\" (\"c1\")",
973973
"INSERT INTO \""

0 commit comments

Comments
 (0)