diff --git a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java index 388878649f..56edc4b488 100644 --- a/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java +++ b/google-cloud-bigquerystorage/src/main/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessage.java @@ -502,6 +502,11 @@ private static void fillRepeatedField( try { jsonArray = json.getJSONArray(exactJsonKeyName); } catch (JSONException e) { + java.lang.Object val = json.get(exactJsonKeyName); + // It is OK for repeated field to be null. + if (val == JSONObject.NULL) { + return; + } throw new IllegalArgumentException( "JSONObject does not have a array field at " + currentScope + "."); } diff --git a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessageTest.java b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessageTest.java index 6f6b0c43a0..e69e8f1bb0 100644 --- a/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessageTest.java +++ b/google-cloud-bigquerystorage/src/test/java/com/google/cloud/bigquery/storage/v1/JsonToProtoMessageTest.java @@ -1275,4 +1275,40 @@ public void testBadJsonFieldIntRepeated() throws Exception { assertEquals(ex.getMessage(), "Text 'blah' could not be parsed at index 0"); } } + + @Test + public void testNullRepeatedField() throws Exception { + TableSchema ts = + TableSchema.newBuilder() + .addFields( + 0, + TableFieldSchema.newBuilder() + .setName("test_repeated") + .setType(TableFieldSchema.Type.DATE) + .setMode(TableFieldSchema.Mode.REPEATED) + .build()) + .addFields( + 1, + TableFieldSchema.newBuilder() + .setName("test_non_repeated") + .setType(TableFieldSchema.Type.DATE) + .setMode(TableFieldSchema.Mode.NULLABLE) + .build()) + .build(); + JSONObject json = new JSONObject(); + // Null repeated field. + json.put("test_repeated", JSONObject.NULL); + + DynamicMessage protoMsg = + JsonToProtoMessage.convertJsonToProtoMessage(RepeatedInt32.getDescriptor(), ts, json); + assertTrue(protoMsg.getAllFields().isEmpty()); + + // Missing repeated field. + json = new JSONObject(); + json.put("test_non_repeated", JSONObject.NULL); + + protoMsg = + JsonToProtoMessage.convertJsonToProtoMessage(RepeatedInt32.getDescriptor(), ts, json); + assertTrue(protoMsg.getAllFields().isEmpty()); + } } diff --git a/google-cloud-bigquerystorage/src/test/proto/jsonTest.proto b/google-cloud-bigquerystorage/src/test/proto/jsonTest.proto index 4eca3d901b..0b9292e03a 100644 --- a/google-cloud-bigquerystorage/src/test/proto/jsonTest.proto +++ b/google-cloud-bigquerystorage/src/test/proto/jsonTest.proto @@ -89,6 +89,7 @@ message RepeatedInt64 { message RepeatedInt32 { repeated int32 test_repeated = 1; + optional int32 test_non_repeated = 2; } message RepeatedDouble {