Skip to content

Commit 085768b

Browse files
authored
fix: Numerics cast from strings (#1588)
Signed-off-by: dark0dave <dark0dave@mykolab.com>
1 parent 0c62c85 commit 085768b

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import com.google.api.pathtemplate.ValidationException;
1919
import com.google.common.base.Preconditions;
2020
import com.google.common.collect.ImmutableMap;
21+
import com.google.common.primitives.Doubles;
22+
import com.google.common.primitives.Ints;
23+
import com.google.common.primitives.Longs;
2124
import com.google.protobuf.ByteString;
2225
import com.google.protobuf.Descriptors.Descriptor;
2326
import com.google.protobuf.Descriptors.FieldDescriptor;
@@ -226,6 +229,12 @@ private static void fillField(
226229
protoMsg.setField(fieldDescriptor, (Boolean) val);
227230
return;
228231
}
232+
if (val instanceof String
233+
&& ("true".equals(((String) val).toLowerCase())
234+
|| "false".equals(((String) val).toLowerCase()))) {
235+
protoMsg.setField(fieldDescriptor, Boolean.parseBoolean((String) val));
236+
return;
237+
}
229238
break;
230239
case BYTES:
231240
if (fieldSchema != null) {
@@ -312,6 +321,13 @@ private static void fillField(
312321
protoMsg.setField(fieldDescriptor, (Long) val);
313322
return;
314323
}
324+
if (val instanceof String) {
325+
Long parsed = Longs.tryParse((String) val);
326+
if (parsed != null) {
327+
protoMsg.setField(fieldDescriptor, parsed);
328+
return;
329+
}
330+
}
315331
break;
316332
case INT32:
317333
if (fieldSchema != null && fieldSchema.getType() == TableFieldSchema.Type.DATE) {
@@ -327,6 +343,13 @@ private static void fillField(
327343
protoMsg.setField(fieldDescriptor, (Integer) val);
328344
return;
329345
}
346+
if (val instanceof String) {
347+
Integer parsed = Ints.tryParse((String) val);
348+
if (parsed != null) {
349+
protoMsg.setField(fieldDescriptor, parsed);
350+
return;
351+
}
352+
}
330353
break;
331354
case STRING:
332355
if (val instanceof String) {
@@ -339,6 +362,13 @@ private static void fillField(
339362
protoMsg.setField(fieldDescriptor, ((Number) val).doubleValue());
340363
return;
341364
}
365+
if (val instanceof String) {
366+
Double parsed = Doubles.tryParse((String) val);
367+
if (parsed != null) {
368+
protoMsg.setField(fieldDescriptor, parsed);
369+
return;
370+
}
371+
}
342372
break;
343373
case MESSAGE:
344374
if (val instanceof JSONObject) {
@@ -400,6 +430,10 @@ private static void fillRepeatedField(
400430
case BOOL:
401431
if (val instanceof Boolean) {
402432
protoMsg.addRepeatedField(fieldDescriptor, (Boolean) val);
433+
} else if (val instanceof String
434+
&& ("true".equals(((String) val).toLowerCase())
435+
|| "false".equals(((String) val).toLowerCase()))) {
436+
protoMsg.addRepeatedField(fieldDescriptor, Boolean.parseBoolean((String) val));
403437
} else {
404438
fail = true;
405439
}
@@ -491,6 +525,13 @@ private static void fillRepeatedField(
491525
protoMsg.addRepeatedField(fieldDescriptor, new Long((Integer) val));
492526
} else if (val instanceof Long) {
493527
protoMsg.addRepeatedField(fieldDescriptor, (Long) val);
528+
} else if (val instanceof String) {
529+
Long parsed = Longs.tryParse((String) val);
530+
if (parsed != null) {
531+
protoMsg.addRepeatedField(fieldDescriptor, parsed);
532+
} else {
533+
fail = true;
534+
}
494535
} else {
495536
fail = true;
496537
}
@@ -507,6 +548,13 @@ private static void fillRepeatedField(
507548
}
508549
} else if (val instanceof Integer) {
509550
protoMsg.addRepeatedField(fieldDescriptor, (Integer) val);
551+
} else if (val instanceof String) {
552+
Integer parsed = Ints.tryParse((String) val);
553+
if (parsed != null) {
554+
protoMsg.addRepeatedField(fieldDescriptor, parsed);
555+
} else {
556+
fail = true;
557+
}
510558
} else {
511559
fail = true;
512560
}
@@ -521,6 +569,13 @@ private static void fillRepeatedField(
521569
case DOUBLE:
522570
if (val instanceof Number) {
523571
protoMsg.addRepeatedField(fieldDescriptor, ((Number) val).doubleValue());
572+
} else if (val instanceof String) {
573+
Double parsed = Doubles.tryParse((String) val);
574+
if (parsed != null) {
575+
protoMsg.addRepeatedField(fieldDescriptor, parsed);
576+
} else {
577+
fail = true;
578+
}
524579
} else {
525580
fail = true;
526581
}

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,27 +473,43 @@ public void testDifferentNameCasing() throws Exception {
473473
assertEquals(expectedProto, protoMsg);
474474
}
475475

476+
@Test
477+
public void testBool() throws Exception {
478+
TestBool expectedProto =
479+
TestBool.newBuilder().setBool(true).setUppercase(true).setLowercase(false).build();
480+
JSONObject json = new JSONObject();
481+
json.put("bool", true);
482+
json.put("uppercase", "TRUE");
483+
json.put("lowercase", "false");
484+
DynamicMessage protoMsg =
485+
JsonToProtoMessage.convertJsonToProtoMessage(TestBool.getDescriptor(), json);
486+
assertEquals(expectedProto, protoMsg);
487+
}
488+
476489
@Test
477490
public void testInt64() throws Exception {
478491
TestInt64 expectedProto =
479-
TestInt64.newBuilder().setByte(1).setShort(1).setInt(1).setLong(1).build();
492+
TestInt64.newBuilder().setByte(1).setShort(1).setInt(1).setLong(1).setString(1).build();
480493
JSONObject json = new JSONObject();
481494
json.put("byte", (byte) 1);
482495
json.put("short", (short) 1);
483496
json.put("int", 1);
484497
json.put("long", 1L);
498+
json.put("string", "1");
485499
DynamicMessage protoMsg =
486500
JsonToProtoMessage.convertJsonToProtoMessage(TestInt64.getDescriptor(), json);
487501
assertEquals(expectedProto, protoMsg);
488502
}
489503

490504
@Test
491505
public void testInt32() throws Exception {
492-
TestInt32 expectedProto = TestInt32.newBuilder().setByte(1).setShort(1).setInt(1).build();
506+
TestInt32 expectedProto =
507+
TestInt32.newBuilder().setByte(1).setShort(1).setInt(1).setString(1).build();
493508
JSONObject json = new JSONObject();
494509
json.put("byte", (byte) 1);
495510
json.put("short", (short) 1);
496511
json.put("int", 1);
512+
json.put("string", 1);
497513
DynamicMessage protoMsg =
498514
JsonToProtoMessage.convertJsonToProtoMessage(TestInt32.getDescriptor(), json);
499515
assertEquals(expectedProto, protoMsg);
@@ -625,6 +641,7 @@ public void testDouble() throws Exception {
625641
.setShort(6)
626642
.setInt(7)
627643
.setLong(8)
644+
.setString(9.1)
628645
.build();
629646
JSONObject json = new JSONObject();
630647
json.put("double", 1.2);
@@ -633,6 +650,7 @@ public void testDouble() throws Exception {
633650
json.put("short", new Short((short) 6));
634651
json.put("int", 7);
635652
json.put("long", 8L);
653+
json.put("string", "9.1");
636654
DynamicMessage protoMsg =
637655
JsonToProtoMessage.convertJsonToProtoMessage(TestDouble.getDescriptor(), json);
638656
assertEquals(expectedProto, protoMsg);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,25 @@ message RepeatedObject {
103103
repeated ComplexLvl2 test_repeated = 1;
104104
}
105105

106+
message TestBool {
107+
optional bool bool = 1;
108+
optional bool lowercase = 2;
109+
optional bool uppercase = 3;
110+
}
111+
106112
message TestInt64 {
107113
optional int64 byte = 1;
108114
optional int64 short = 2;
109115
optional int64 int = 3;
110116
optional int64 long = 4;
117+
optional int64 string = 5;
111118
}
112119

113120
message TestInt32 {
114121
optional int32 byte = 1;
115122
optional int32 short = 2;
116123
optional int32 int = 3;
124+
optional int32 string = 4;
117125
}
118126

119127
message TestDouble {
@@ -123,6 +131,7 @@ message TestDouble {
123131
optional double short = 4;
124132
optional double int = 5;
125133
optional double long = 6;
134+
optional double string = 7;
126135
}
127136

128137
message TestDate {

0 commit comments

Comments
 (0)