|
122 | 122 | import com.google.common.collect.Iterables; |
123 | 123 | import com.google.common.collect.Sets; |
124 | 124 | import com.google.common.io.BaseEncoding; |
| 125 | +import com.google.gson.JsonObject; |
125 | 126 | import java.io.IOException; |
126 | 127 | import java.math.BigDecimal; |
127 | 128 | import java.nio.ByteBuffer; |
@@ -707,6 +708,113 @@ public void testCreateTableWithRangePartitioning() { |
707 | 708 | } |
708 | 709 | } |
709 | 710 |
|
| 711 | + @Test |
| 712 | + public void testJsonType() throws InterruptedException { |
| 713 | + String tableName = "test_create_table_jsontype"; |
| 714 | + TableId tableId = TableId.of(DATASET, tableName); |
| 715 | + Schema schema = Schema.of(Field.of("jsonField", StandardSQLTypeName.JSON)); |
| 716 | + StandardTableDefinition standardTableDefinition = StandardTableDefinition.of(schema); |
| 717 | + try { |
| 718 | + // Create a table with a JSON column |
| 719 | + Table createdTable = bigquery.create(TableInfo.of(tableId, standardTableDefinition)); |
| 720 | + assertNotNull(createdTable); |
| 721 | + |
| 722 | + // Insert 4 rows of JSON data into the JSON column |
| 723 | + Map<String, Object> jsonRow1 = |
| 724 | + Collections.singletonMap( |
| 725 | + "jsonField", "{\"student\" : {\"name\" : \"Jane\", \"id\": 10}}"); |
| 726 | + Map<String, Object> jsonRow2 = |
| 727 | + Collections.singletonMap("jsonField", "{\"student\" : {\"name\" : \"Joy\", \"id\": 11}}"); |
| 728 | + Map<String, Object> jsonRow3 = |
| 729 | + Collections.singletonMap( |
| 730 | + "jsonField", "{\"student\" : {\"name\" : \"Alice\", \"id\": 12}}"); |
| 731 | + Map<String, Object> jsonRow4 = |
| 732 | + Collections.singletonMap( |
| 733 | + "jsonField", "{\"student\" : {\"name\" : \"Bijoy\", \"id\": 14}}"); |
| 734 | + InsertAllRequest request = |
| 735 | + InsertAllRequest.newBuilder(tableId) |
| 736 | + .addRow(jsonRow1) |
| 737 | + .addRow(jsonRow2) |
| 738 | + .addRow(jsonRow3) |
| 739 | + .addRow(jsonRow4) |
| 740 | + .build(); |
| 741 | + InsertAllResponse response = bigquery.insertAll(request); |
| 742 | + assertFalse(response.hasErrors()); |
| 743 | + assertEquals(0, response.getInsertErrors().size()); |
| 744 | + |
| 745 | + // Query the JSON column with string positional query parameter |
| 746 | + String sql = |
| 747 | + "SELECT jsonField.class.student.id FROM " |
| 748 | + + tableId.getTable() |
| 749 | + + " WHERE JSON_VALUE(jsonField, \"$.class.student.name\") = ? "; |
| 750 | + QueryParameterValue stringParameter = QueryParameterValue.string("Jane"); |
| 751 | + QueryJobConfiguration queryJobConfiguration = |
| 752 | + QueryJobConfiguration.newBuilder(sql) |
| 753 | + .setDefaultDataset(DatasetId.of(DATASET)) |
| 754 | + .setUseLegacySql(false) |
| 755 | + .addPositionalParameter(stringParameter) |
| 756 | + .build(); |
| 757 | + TableResult result = bigquery.query(queryJobConfiguration); |
| 758 | + for (FieldValueList values : result.iterateAll()) { |
| 759 | + assertEquals("10", values.get(0).getValue()); |
| 760 | + } |
| 761 | + |
| 762 | + // Insert another JSON row parsed from a String with json positional query parameter |
| 763 | + String dml = "INSERT INTO " + tableId.getTable() + " (jsonField) VALUES(?)"; |
| 764 | + QueryParameterValue jsonParameter = |
| 765 | + QueryParameterValue.json("{\"class\" : {\"student\" : [{\"name\" : \"Amy\"}]}}"); |
| 766 | + QueryJobConfiguration dmlQueryJobConfiguration = |
| 767 | + QueryJobConfiguration.newBuilder(dml) |
| 768 | + .setDefaultDataset(DatasetId.of(DATASET)) |
| 769 | + .setUseLegacySql(false) |
| 770 | + .addPositionalParameter(jsonParameter) |
| 771 | + .build(); |
| 772 | + bigquery.query(dmlQueryJobConfiguration); |
| 773 | + Page<FieldValueList> rows = bigquery.listTableData(tableId); |
| 774 | + assertEquals(5, Iterables.size(rows.getValues())); |
| 775 | + |
| 776 | + // Insert another JSON row parsed from a JsonObject with json positional query parameter |
| 777 | + JsonObject jsonObject = new JsonObject(); |
| 778 | + jsonObject.addProperty("class", "student"); |
| 779 | + QueryParameterValue jsonParameter1 = QueryParameterValue.json(jsonObject); |
| 780 | + QueryJobConfiguration dmlQueryJobConfiguration1 = |
| 781 | + QueryJobConfiguration.newBuilder(dml) |
| 782 | + .setDefaultDataset(DatasetId.of(DATASET)) |
| 783 | + .setUseLegacySql(false) |
| 784 | + .addPositionalParameter(jsonParameter1) |
| 785 | + .build(); |
| 786 | + bigquery.query(dmlQueryJobConfiguration1); |
| 787 | + Page<FieldValueList> rows1 = bigquery.listTableData(tableId); |
| 788 | + assertEquals(6, Iterables.size(rows1.getValues())); |
| 789 | + int rowCount = 0; |
| 790 | + for (FieldValueList row : rows1.iterateAll()) { |
| 791 | + FieldValue jsonCell = row.get(0); |
| 792 | + if (rowCount == 1) assertEquals("{\"class\":\"student\"}", jsonCell.getStringValue()); |
| 793 | + rowCount++; |
| 794 | + } |
| 795 | + |
| 796 | + // Try inserting a malformed JSON |
| 797 | + QueryParameterValue badJsonParameter = |
| 798 | + QueryParameterValue.json("{\"class\" : {\"student\" : [{\"name\" : \"BadBoy\"}}"); |
| 799 | + QueryJobConfiguration dmlQueryJobConfiguration2 = |
| 800 | + QueryJobConfiguration.newBuilder(dml) |
| 801 | + .setDefaultDataset(DatasetId.of(DATASET)) |
| 802 | + .setUseLegacySql(false) |
| 803 | + .addPositionalParameter(badJsonParameter) |
| 804 | + .build(); |
| 805 | + try { |
| 806 | + bigquery.query(dmlQueryJobConfiguration2); |
| 807 | + fail("Querying with malformed JSON shouldn't work"); |
| 808 | + } catch (BigQueryException e) { |
| 809 | + BigQueryError error = e.getError(); |
| 810 | + assertNotNull(error); |
| 811 | + assertEquals("invalidQuery", error.getReason()); |
| 812 | + } |
| 813 | + } finally { |
| 814 | + assertTrue(bigquery.delete(tableId)); |
| 815 | + } |
| 816 | + } |
| 817 | + |
710 | 818 | @Test |
711 | 819 | public void testCreateTableWithConstraints() { |
712 | 820 | String tableName = "test_create_table_with_constraints"; |
|
0 commit comments