Skip to content

Commit e5bb5d0

Browse files
fix: interpret Integer and Float values for TIMESTAMP as microseconds (#2175)
1 parent 494ce85 commit e5bb5d0

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ private void fillField(
442442
if (val instanceof String) {
443443
Double parsed = Doubles.tryParse((String) val);
444444
if (parsed != null) {
445-
protoMsg.setField(fieldDescriptor, parsed.longValue() * 10000000);
445+
protoMsg.setField(fieldDescriptor, parsed.longValue());
446446
return;
447447
}
448448
TemporalAccessor parsedTime = TIMESTAMP_FORMATTER.parse((String) val);
@@ -455,7 +455,7 @@ private void fillField(
455455
protoMsg.setField(fieldDescriptor, val);
456456
return;
457457
} else if (val instanceof Integer) {
458-
protoMsg.setField(fieldDescriptor, Long.valueOf((Integer) val) * 10000000);
458+
protoMsg.setField(fieldDescriptor, Long.valueOf((Integer) val));
459459
return;
460460
}
461461
}
@@ -705,7 +705,7 @@ private void fillRepeatedField(
705705
if (val instanceof String) {
706706
Double parsed = Doubles.tryParse((String) val);
707707
if (parsed != null) {
708-
protoMsg.addRepeatedField(fieldDescriptor, parsed.longValue() * 10000000);
708+
protoMsg.addRepeatedField(fieldDescriptor, parsed.longValue());
709709
} else {
710710
TemporalAccessor parsedTime = TIMESTAMP_FORMATTER.parse((String) val);
711711
protoMsg.addRepeatedField(
@@ -716,7 +716,7 @@ private void fillRepeatedField(
716716
} else if (val instanceof Long) {
717717
protoMsg.addRepeatedField(fieldDescriptor, val);
718718
} else if (val instanceof Integer) {
719-
protoMsg.addRepeatedField(fieldDescriptor, ((Integer) val) * 10000000);
719+
protoMsg.addRepeatedField(fieldDescriptor, Long.valueOf((Integer) val));
720720
} else {
721721
throwWrongFieldType(fieldDescriptor, currentScope, index);
722722
}

google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessageTest.java

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,12 @@ public class JsonToProtoMessageTest {
393393
.setMode(TableFieldSchema.Mode.NULLABLE)
394394
.setName("test_timestamp")
395395
.build();
396+
private final TableFieldSchema TEST_TIMESTAMP_REPEATED =
397+
TableFieldSchema.newBuilder()
398+
.setType(TableFieldSchema.Type.TIMESTAMP)
399+
.setMode(TableFieldSchema.Mode.REPEATED)
400+
.setName("test_timestamp_repeated")
401+
.build();
396402
private final TableFieldSchema TEST_TIME =
397403
TableFieldSchema.newBuilder()
398404
.setType(TableFieldSchema.Type.TIME)
@@ -787,17 +793,17 @@ public void testTimestamp() throws Exception {
787793
TestTimestamp.newBuilder()
788794
.setTestString(10L)
789795
.setTestStringTZ(1648493279010000L)
790-
.setTestLong(0L)
791-
.setTestInt(1534806950000000L)
792-
.setTestFloat(1534680695000000000L)
796+
.setTestLong(1687984085000000L)
797+
.setTestInt(153480695L)
798+
.setTestFloat(153468069500L)
793799
.setTestOffset(1649135171000000L)
794800
.setTestTimezone(1649174771000000L)
795801
.setTestSaformat(1534680660000000L)
796802
.build();
797803
JSONObject json = new JSONObject();
798804
json.put("test_string", "1970-01-01 00:00:00.000010");
799805
json.put("test_string_T_Z", "2022-03-28T18:47:59.01Z");
800-
json.put("test_long", 0L);
806+
json.put("test_long", 1687984085000000L);
801807
json.put("test_int", 153480695);
802808
json.put("test_float", "1.534680695e11");
803809
json.put("test_offset", "2022-04-05T09:06:11+04:00");
@@ -809,6 +815,69 @@ public void testTimestamp() throws Exception {
809815
assertEquals(expectedProto, protoMsg);
810816
}
811817

818+
@Test
819+
public void testTimestampRepeated() throws Exception {
820+
TableSchema tableSchema =
821+
TableSchema.newBuilder()
822+
.addFields(
823+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
824+
.setName("test_string_repeated")
825+
.build())
826+
.addFields(
827+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
828+
.setName("test_string_T_Z_repeated")
829+
.build())
830+
.addFields(
831+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
832+
.setName("test_long_repeated")
833+
.build())
834+
.addFields(
835+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
836+
.setName("test_int_repeated")
837+
.build())
838+
.addFields(
839+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
840+
.setName("test_float_repeated")
841+
.build())
842+
.addFields(
843+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
844+
.setName("test_offset_repeated")
845+
.build())
846+
.addFields(
847+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
848+
.setName("test_timezone_repeated")
849+
.build())
850+
.addFields(
851+
TableFieldSchema.newBuilder(TEST_TIMESTAMP_REPEATED)
852+
.setName("test_saformat_repeated")
853+
.build())
854+
.build();
855+
TestRepeatedTimestamp expectedProto =
856+
TestRepeatedTimestamp.newBuilder()
857+
.addTestStringRepeated(10L)
858+
.addTestStringTZRepeated(1648493279010000L)
859+
.addTestLongRepeated(1687984085000000L)
860+
.addTestIntRepeated(153480695L)
861+
.addTestFloatRepeated(153468069500L)
862+
.addTestOffsetRepeated(1649135171000000L)
863+
.addTestTimezoneRepeated(1649174771000000L)
864+
.addTestSaformatRepeated(1534680660000000L)
865+
.build();
866+
JSONObject json = new JSONObject();
867+
json.put("test_string_repeated", new JSONArray(new String[] {"1970-01-01 00:00:00.000010"}));
868+
json.put("test_string_T_Z_repeated", new JSONArray(new String[] {"2022-03-28T18:47:59.01Z"}));
869+
json.put("test_long_repeated", new JSONArray(new Long[] {1687984085000000L}));
870+
json.put("test_int_repeated", new JSONArray(new Integer[] {153480695}));
871+
json.put("test_float_repeated", new JSONArray(new String[] {"1.534680695e11"}));
872+
json.put("test_offset_repeated", new JSONArray(new String[] {"2022-04-05T09:06:11+04:00"}));
873+
json.put("test_timezone_repeated", new JSONArray(new String[] {"2022-04-05 09:06:11 PST"}));
874+
json.put("test_saformat_repeated", new JSONArray(new String[] {"2018/08/19 12:11"}));
875+
DynamicMessage protoMsg =
876+
JsonToProtoMessage.INSTANCE.convertToProtoMessage(
877+
TestRepeatedTimestamp.getDescriptor(), tableSchema, json);
878+
assertEquals(expectedProto, protoMsg);
879+
}
880+
812881
@Test
813882
public void testDate() throws Exception {
814883
TableSchema tableSchema =
@@ -993,7 +1062,7 @@ public void testStructComplex() throws Exception {
9931062
.setTestNumeric(
9941063
BigDecimalByteStringEncoder.encodeToNumericByteString(new BigDecimal("1.23456")))
9951064
.setTestGeo("POINT(1,1)")
996-
.setTestTimestamp(123456780000000L)
1065+
.setTestTimestamp(12345678L)
9971066
.setTestTime(CivilTimeEncoder.encodePacked64TimeMicros(LocalTime.of(1, 0, 1)))
9981067
.setTestTimeStr(89332507144L)
9991068
.addTestNumericRepeated(

google-cloud-bigquerystorage/src/test/proto/jsonTest.proto

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ message TestTimestamp {
156156
optional int64 test_saformat = 8;
157157
}
158158

159+
message TestRepeatedTimestamp {
160+
repeated int64 test_string_repeated = 1;
161+
repeated int64 test_string_t_z_repeated = 2;
162+
repeated int64 test_long_repeated = 3;
163+
repeated int64 test_int_repeated = 4;
164+
repeated int64 test_float_repeated = 5;
165+
repeated int64 test_offset_repeated = 6;
166+
repeated int64 test_timezone_repeated = 7;
167+
repeated int64 test_saformat_repeated = 8;
168+
}
169+
159170
message TestDate {
160171
optional int32 test_string = 1;
161172
optional int32 test_long = 2;

0 commit comments

Comments
 (0)