From b410b7cddc5bedb41a90d55862a34e3a1824c417 Mon Sep 17 00:00:00 2001 From: stephwang Date: Tue, 18 Jan 2022 13:40:59 -0500 Subject: [PATCH 1/6] feat: add JSON type support --- .../cloud/bigquery/LegacySQLTypeName.java | 3 ++ .../cloud/bigquery/QueryParameterValue.java | 15 ++++++ .../cloud/bigquery/StandardSQLTypeName.java | 4 +- .../bigquery/QueryParameterValueTest.java | 11 ++++ .../cloud/bigquery/it/ITBigQueryTest.java | 54 +++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java index 56d66cb1a..1c2a3d884 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LegacySQLTypeName.java @@ -93,6 +93,9 @@ public LegacySQLTypeName apply(String constant) { /** A record type with a nested schema. */ public static final LegacySQLTypeName RECORD = type.createAndRegister("RECORD").setStandardType(StandardSQLTypeName.STRUCT); + /** Represents JSON data */ + public static final LegacySQLTypeName JSON = + type.createAndRegister("JSON").setStandardType(StandardSQLTypeName.JSON); private static Map standardToLegacyMap = new HashMap<>(); diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java index 76e521d56..d44fefe4a 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java @@ -61,6 +61,7 @@ *
  • Float: StandardSQLTypeName.FLOAT64 *
  • BigDecimal: StandardSQLTypeName.NUMERIC *
  • BigNumeric: StandardSQLTypeName.BIGNUMERIC + *
  • JSON: StandardSQLTypeName.JSON * * *

    No other types are supported through that entry point. The other types can be created by @@ -254,6 +255,14 @@ public static QueryParameterValue string(String value) { return of(value, StandardSQLTypeName.STRING); } + /** + * Creates a {@code QueryParameterValue} object with a type of JSON. This is only supported in + * INSERT, not in query as a filter + */ + public static QueryParameterValue json(String value) { + return of(value, StandardSQLTypeName.JSON); + } + /** Creates a {@code QueryParameterValue} object with a type of BYTES. */ public static QueryParameterValue bytes(byte[] value) { return of(value, StandardSQLTypeName.BYTES); @@ -347,6 +356,8 @@ private static StandardSQLTypeName classToType(Class type) { return StandardSQLTypeName.NUMERIC; } else if (Date.class.isAssignableFrom(type)) { return StandardSQLTypeName.DATE; + } else if (String.class.isAssignableFrom(type)) { + return StandardSQLTypeName.JSON; } throw new IllegalArgumentException("Unsupported object type for QueryParameter: " + type); } @@ -384,6 +395,10 @@ private static String valueToStringOrNull(T value, StandardSQLTypeName type) break; case STRING: return value.toString(); + case JSON: + if (value instanceof String) { + return value.toString(); + } case STRUCT: throw new IllegalArgumentException("Cannot convert STRUCT to String value"); case ARRAY: diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java index d618b7656..57152a2a6 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardSQLTypeName.java @@ -56,5 +56,7 @@ public enum StandardSQLTypeName { /** Represents a year, month, day, hour, minute, second, and subsecond (microsecond precision). */ DATETIME, /** Represents a set of geographic points, represented as a Well Known Text (WKT) string. */ - GEOGRAPHY + GEOGRAPHY, + /** Represents JSON data */ + JSON } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java index b643ae580..6dad95dcc 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java @@ -193,6 +193,17 @@ public void testString() { assertThat(value.getArrayValues()).isNull(); } + @Test + public void testJson() { + QueryParameterValue value = + QueryParameterValue.json("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); + assertThat(value.getValue()) + .isEqualTo("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); + assertThat(value.getType()).isEqualTo(StandardSQLTypeName.JSON); + assertThat(value.getArrayType()).isNull(); + assertThat(value.getArrayValues()).isNull(); + } + @Test public void testBytes() { QueryParameterValue value = QueryParameterValue.bytes(new byte[] {1, 3}); diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 479a80e89..7a00220b6 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -707,6 +707,60 @@ public void testCreateTableWithRangePartitioning() { } } + @Test + public void testJsonType() throws InterruptedException { + String tableName = "test_create_table_jsontype"; + TableId tableId = TableId.of(DATASET, tableName); + Schema schema = Schema.of(Field.of("jsonField", StandardSQLTypeName.JSON)); + StandardTableDefinition standardTableDefinition = StandardTableDefinition.of(schema); + try { + // Create a table with a JSON column + Table createdTable = bigquery.create(TableInfo.of(tableId, standardTableDefinition)); + assertNotNull(createdTable); + + // Insert data into JSON column + Map jsonRow = new HashMap<>(); + jsonRow.put("jsonField", "{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); + InsertAllRequest request = InsertAllRequest.newBuilder(tableId).addRow(jsonRow).build(); + InsertAllResponse response = bigquery.insertAll(request); + assertFalse(response.hasErrors()); + assertEquals(0, response.getInsertErrors().size()); + + // Query the JSON column with string positional query parameter + String sql = + "SELECT JSON_VALUE(jsonField, \"$.class.students[0].name\") FROM " + + tableId.getTable() + + " WHERE JSON_VALUE(jsonField, \"$.class.students[0].name\") = ? "; + QueryParameterValue stringParameter = QueryParameterValue.string("Jane"); + QueryJobConfiguration queryJobConfiguration = + QueryJobConfiguration.newBuilder(sql) + .setDefaultDataset(DatasetId.of(DATASET)) + .setUseLegacySql(false) + .addPositionalParameter(stringParameter) + .build(); + TableResult result = bigquery.query(queryJobConfiguration); + for (FieldValueList values : result.iterateAll()) { + assertEquals("Jane", values.get(0).getValue()); + } + + // Add a new JSON row with json positional query parameter + String dml = "INSERT INTO " + tableId.getTable() + " (jsonField) VALUES(?)"; + QueryParameterValue jsonParameter = + QueryParameterValue.json("{\"class\" : {\"students\" : [{\"name\" : \"Joy\"}]}}"); + QueryJobConfiguration dmlQueryJobConfiguration = + QueryJobConfiguration.newBuilder(dml) + .setDefaultDataset(DatasetId.of(DATASET)) + .setUseLegacySql(false) + .addPositionalParameter(jsonParameter) + .build(); + bigquery.query(dmlQueryJobConfiguration); + Page rows = bigquery.listTableData(tableId); + assertEquals(2, Iterables.size(rows.getValues())); + } finally { + assertTrue(bigquery.delete(tableId)); + } + } + @Test public void testCreateTableWithConstraints() { String tableName = "test_create_table_with_constraints"; From 3f502dd433847e6213b0247840479023c10dc29d Mon Sep 17 00:00:00 2001 From: stephwang Date: Wed, 26 Jan 2022 18:02:43 -0500 Subject: [PATCH 2/6] add support for JSONObject --- google-cloud-bigquery/pom.xml | 4 ++ .../cloud/bigquery/QueryParameterValue.java | 22 +++++++-- .../bigquery/QueryParameterValueTest.java | 7 +++ .../cloud/bigquery/it/ITBigQueryTest.java | 49 +++++++++++++++---- pom.xml | 6 +++ 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 6796b91c8..6892f35f4 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -81,6 +81,10 @@ org.threeten threetenbp + + org.json + json + diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java index d44fefe4a..6db7db3e3 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; +import org.json.JSONObject; import org.threeten.bp.Instant; import org.threeten.bp.ZoneOffset; import org.threeten.bp.format.DateTimeFormatter; @@ -256,13 +257,21 @@ public static QueryParameterValue string(String value) { } /** - * Creates a {@code QueryParameterValue} object with a type of JSON. This is only supported in - * INSERT, not in query as a filter + * Creates a {@code QueryParameterValue} object with a type of JSON. Currently, this is only + * supported in INSERT, not in query as a filter */ public static QueryParameterValue json(String value) { return of(value, StandardSQLTypeName.JSON); } + /** + * Creates a {@code QueryParameterValue} object with a type of JSON. Currently, this is only + * supported in INSERT, not in query as a filter + */ + public static QueryParameterValue json(JSONObject value) { + return of(value, StandardSQLTypeName.JSON); + } + /** Creates a {@code QueryParameterValue} object with a type of BYTES. */ public static QueryParameterValue bytes(byte[] value) { return of(value, StandardSQLTypeName.BYTES); @@ -358,6 +367,10 @@ private static StandardSQLTypeName classToType(Class type) { return StandardSQLTypeName.DATE; } else if (String.class.isAssignableFrom(type)) { return StandardSQLTypeName.JSON; + } else if (JSONObject.class.isAssignableFrom(type)) { + return StandardSQLTypeName.JSON; + } else if (Map.class.isAssignableFrom(type)) { + return StandardSQLTypeName.JSON; } throw new IllegalArgumentException("Unsupported object type for QueryParameter: " + type); } @@ -396,9 +409,8 @@ private static String valueToStringOrNull(T value, StandardSQLTypeName type) case STRING: return value.toString(); case JSON: - if (value instanceof String) { - return value.toString(); - } + if (value instanceof String || value instanceof JSONObject) return value.toString(); + break; case STRUCT: throw new IllegalArgumentException("Cannot convert STRUCT to String value"); case ARRAY: diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java index 6dad95dcc..13c0261b4 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; import org.threeten.bp.Instant; @@ -197,11 +198,17 @@ public void testString() { public void testJson() { QueryParameterValue value = QueryParameterValue.json("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); + JSONObject jsonObject = new JSONObject().put("class", "student"); + QueryParameterValue value1 = QueryParameterValue.json(jsonObject); assertThat(value.getValue()) .isEqualTo("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); + assertThat(value1.getValue()).isEqualTo("{\"class\":\"student\"}"); assertThat(value.getType()).isEqualTo(StandardSQLTypeName.JSON); + assertThat(value1.getType()).isEqualTo(StandardSQLTypeName.JSON); assertThat(value.getArrayType()).isNull(); + assertThat(value1.getArrayType()).isNull(); assertThat(value.getArrayValues()).isNull(); + assertThat(value1.getArrayType()).isNull(); } @Test diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 7a00220b6..e6ef70b81 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -143,6 +143,7 @@ import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; +import org.json.JSONObject; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; @@ -718,19 +719,34 @@ public void testJsonType() throws InterruptedException { Table createdTable = bigquery.create(TableInfo.of(tableId, standardTableDefinition)); assertNotNull(createdTable); - // Insert data into JSON column - Map jsonRow = new HashMap<>(); - jsonRow.put("jsonField", "{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); - InsertAllRequest request = InsertAllRequest.newBuilder(tableId).addRow(jsonRow).build(); + // Insert 4 rows of JSON data into the JSON column + Map jsonRow1 = + Collections.singletonMap( + "jsonField", "{\"student\" : {\"name\" : \"Jane\", \"id\": 10}}"); + Map jsonRow2 = + Collections.singletonMap("jsonField", "{\"student\" : {\"name\" : \"Joy\", \"id\": 11}}"); + Map jsonRow3 = + Collections.singletonMap( + "jsonField", "{\"student\" : {\"name\" : \"Alice\", \"id\": 12}}"); + Map jsonRow4 = + Collections.singletonMap( + "jsonField", "{\"student\" : {\"name\" : \"Bijoy\", \"id\": 14}}"); + InsertAllRequest request = + InsertAllRequest.newBuilder(tableId) + .addRow(jsonRow1) + .addRow(jsonRow2) + .addRow(jsonRow3) + .addRow(jsonRow4) + .build(); InsertAllResponse response = bigquery.insertAll(request); assertFalse(response.hasErrors()); assertEquals(0, response.getInsertErrors().size()); // Query the JSON column with string positional query parameter String sql = - "SELECT JSON_VALUE(jsonField, \"$.class.students[0].name\") FROM " + "SELECT jsonField.class.student.id FROM " + tableId.getTable() - + " WHERE JSON_VALUE(jsonField, \"$.class.students[0].name\") = ? "; + + " WHERE JSON_VALUE(jsonField, \"$.class.student.name\") = ? "; QueryParameterValue stringParameter = QueryParameterValue.string("Jane"); QueryJobConfiguration queryJobConfiguration = QueryJobConfiguration.newBuilder(sql) @@ -740,13 +756,13 @@ public void testJsonType() throws InterruptedException { .build(); TableResult result = bigquery.query(queryJobConfiguration); for (FieldValueList values : result.iterateAll()) { - assertEquals("Jane", values.get(0).getValue()); + assertEquals("10", values.get(0).getValue()); } - // Add a new JSON row with json positional query parameter + // Insert another JSON row parsed from a String with json positional query parameter String dml = "INSERT INTO " + tableId.getTable() + " (jsonField) VALUES(?)"; QueryParameterValue jsonParameter = - QueryParameterValue.json("{\"class\" : {\"students\" : [{\"name\" : \"Joy\"}]}}"); + QueryParameterValue.json("{\"class\" : {\"student\" : [{\"name\" : \"Amy\"}]}}"); QueryJobConfiguration dmlQueryJobConfiguration = QueryJobConfiguration.newBuilder(dml) .setDefaultDataset(DatasetId.of(DATASET)) @@ -755,7 +771,20 @@ public void testJsonType() throws InterruptedException { .build(); bigquery.query(dmlQueryJobConfiguration); Page rows = bigquery.listTableData(tableId); - assertEquals(2, Iterables.size(rows.getValues())); + assertEquals(5, Iterables.size(rows.getValues())); + + // Insert another JSON row parsed from a JsonObject with json positional query parameter + JSONObject jsonObject = new JSONObject().put("class", "student"); + QueryParameterValue jsonParameter1 = QueryParameterValue.json(jsonObject); + QueryJobConfiguration dmlQueryJobConfiguration1 = + QueryJobConfiguration.newBuilder(dml) + .setDefaultDataset(DatasetId.of(DATASET)) + .setUseLegacySql(false) + .addPositionalParameter(jsonParameter1) + .build(); + bigquery.query(dmlQueryJobConfiguration1); + Page rows1 = bigquery.listTableData(tableId); + assertEquals(6, Iterables.size(rows1.getValues())); } finally { assertTrue(bigquery.delete(tableId)); } diff --git a/pom.xml b/pom.xml index 30898a62d..5d228edd3 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,12 @@ ${google-api-services-bigquery.version} + + org.json + json + 20200518 + + junit From ddd973bcec5f236602a6bdb17d495e68b543444a Mon Sep 17 00:00:00 2001 From: stephwang Date: Wed, 26 Jan 2022 18:32:01 -0500 Subject: [PATCH 3/6] clean up --- .../java/com/google/cloud/bigquery/QueryParameterValue.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java index 6db7db3e3..c919d34c5 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java @@ -369,8 +369,6 @@ private static StandardSQLTypeName classToType(Class type) { return StandardSQLTypeName.JSON; } else if (JSONObject.class.isAssignableFrom(type)) { return StandardSQLTypeName.JSON; - } else if (Map.class.isAssignableFrom(type)) { - return StandardSQLTypeName.JSON; } throw new IllegalArgumentException("Unsupported object type for QueryParameter: " + type); } From dcbc075ff2d0b65014a5cf6e2914b56f290a6850 Mon Sep 17 00:00:00 2001 From: stephwang Date: Thu, 27 Jan 2022 11:59:05 -0500 Subject: [PATCH 4/6] address feedback --- google-cloud-bigquery/pom.xml | 4 --- .../cloud/bigquery/QueryParameterValue.java | 8 ++--- .../bigquery/QueryParameterValueTest.java | 5 ++-- .../cloud/bigquery/it/ITBigQueryTest.java | 29 +++++++++++++++++-- pom.xml | 6 ---- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 6892f35f4..6796b91c8 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -81,10 +81,6 @@ org.threeten threetenbp - - org.json - json - diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java index c919d34c5..f7f7e384f 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryParameterValue.java @@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.io.BaseEncoding; +import com.google.gson.JsonObject; import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; @@ -37,7 +38,6 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; -import org.json.JSONObject; import org.threeten.bp.Instant; import org.threeten.bp.ZoneOffset; import org.threeten.bp.format.DateTimeFormatter; @@ -268,7 +268,7 @@ public static QueryParameterValue json(String value) { * Creates a {@code QueryParameterValue} object with a type of JSON. Currently, this is only * supported in INSERT, not in query as a filter */ - public static QueryParameterValue json(JSONObject value) { + public static QueryParameterValue json(JsonObject value) { return of(value, StandardSQLTypeName.JSON); } @@ -367,7 +367,7 @@ private static StandardSQLTypeName classToType(Class type) { return StandardSQLTypeName.DATE; } else if (String.class.isAssignableFrom(type)) { return StandardSQLTypeName.JSON; - } else if (JSONObject.class.isAssignableFrom(type)) { + } else if (JsonObject.class.isAssignableFrom(type)) { return StandardSQLTypeName.JSON; } throw new IllegalArgumentException("Unsupported object type for QueryParameter: " + type); @@ -407,7 +407,7 @@ private static String valueToStringOrNull(T value, StandardSQLTypeName type) case STRING: return value.toString(); case JSON: - if (value instanceof String || value instanceof JSONObject) return value.toString(); + if (value instanceof String || value instanceof JsonObject) return value.toString(); break; case STRUCT: throw new IllegalArgumentException("Cannot convert STRUCT to String value"); diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java index 13c0261b4..679b6ec5c 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryParameterValueTest.java @@ -24,13 +24,13 @@ import com.google.api.services.bigquery.model.QueryParameterType; import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonObject; import java.math.BigDecimal; import java.text.ParseException; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; import org.threeten.bp.Instant; @@ -198,7 +198,8 @@ public void testString() { public void testJson() { QueryParameterValue value = QueryParameterValue.json("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); - JSONObject jsonObject = new JSONObject().put("class", "student"); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("class", "student"); QueryParameterValue value1 = QueryParameterValue.json(jsonObject); assertThat(value.getValue()) .isEqualTo("{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"); diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index e6ef70b81..ad6618625 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -122,6 +122,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.common.io.BaseEncoding; +import com.google.gson.JsonObject; import java.io.IOException; import java.math.BigDecimal; import java.nio.ByteBuffer; @@ -143,7 +144,6 @@ import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; -import org.json.JSONObject; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; @@ -774,7 +774,8 @@ public void testJsonType() throws InterruptedException { assertEquals(5, Iterables.size(rows.getValues())); // Insert another JSON row parsed from a JsonObject with json positional query parameter - JSONObject jsonObject = new JSONObject().put("class", "student"); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("class", "student"); QueryParameterValue jsonParameter1 = QueryParameterValue.json(jsonObject); QueryJobConfiguration dmlQueryJobConfiguration1 = QueryJobConfiguration.newBuilder(dml) @@ -785,6 +786,30 @@ public void testJsonType() throws InterruptedException { bigquery.query(dmlQueryJobConfiguration1); Page rows1 = bigquery.listTableData(tableId); assertEquals(6, Iterables.size(rows1.getValues())); + int rowCount = 0; + for (FieldValueList row : rows1.iterateAll()) { + FieldValue jsonCell = row.get(0); + if (rowCount == 1) assertEquals("{\"class\":\"student\"}", jsonCell.getStringValue()); + rowCount++; + } + + // Try inserting a malformed JSON + QueryParameterValue badJsonParameter = + QueryParameterValue.json("{\"class\" : {\"student\" : [{\"name\" : \"BadBoy\"}}"); + QueryJobConfiguration dmlQueryJobConfiguration2 = + QueryJobConfiguration.newBuilder(dml) + .setDefaultDataset(DatasetId.of(DATASET)) + .setUseLegacySql(false) + .addPositionalParameter(badJsonParameter) + .build(); + try { + bigquery.query(dmlQueryJobConfiguration2); + fail("Quering with malformed JSON shouldn't work"); + } catch (BigQueryException e) { + BigQueryError error = e.getError(); + assertNotNull(error); + assertEquals("invalidQuery", error.getReason()); + } } finally { assertTrue(bigquery.delete(tableId)); } diff --git a/pom.xml b/pom.xml index 5d228edd3..30898a62d 100644 --- a/pom.xml +++ b/pom.xml @@ -93,12 +93,6 @@ ${google-api-services-bigquery.version} - - org.json - json - 20200518 - - junit From 29328036c0061caf396d7a6593490cc120f61d4b Mon Sep 17 00:00:00 2001 From: stephwang Date: Thu, 27 Jan 2022 12:01:26 -0500 Subject: [PATCH 5/6] fix typo --- .../test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index ad6618625..09c9b7a7b 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -804,7 +804,7 @@ public void testJsonType() throws InterruptedException { .build(); try { bigquery.query(dmlQueryJobConfiguration2); - fail("Quering with malformed JSON shouldn't work"); + fail("Querying with malformed JSON shouldn't work"); } catch (BigQueryException e) { BigQueryError error = e.getError(); assertNotNull(error); From 497517857dfbbd0a5f982d7837a12cc1c9330366 Mon Sep 17 00:00:00 2001 From: stephwang Date: Thu, 27 Jan 2022 15:18:36 -0500 Subject: [PATCH 6/6] add gson as a dependency --- google-cloud-bigquery/pom.xml | 4 ++++ pom.xml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 6796b91c8..1c3f4a9ba 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -81,6 +81,10 @@ org.threeten threetenbp + + com.google.code.gson + gson + diff --git a/pom.xml b/pom.xml index 30898a62d..8a55b2ed6 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,12 @@ ${google-api-services-bigquery.version} + + com.google.code.gson + gson + 2.8.9 + + junit