diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 9c4b7820d7..d278d4481f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,7 +32,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@6ac9fc7e8e290bda8fac86290b68e176def71959 # v2.25.8 + uses: github/codeql-action/upload-sarif@a073c66b2accf653a511d88537804dcafa07812e # v2.25.10 with: sarif_file: results.sarif diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index 79451bab18..ee2d3db7a6 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -17,7 +17,7 @@ jobs: # repository .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.31.0 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.32.0 with: # java-bigquery does not produce a BOM. Fortunately the root pom.xml # defines google-cloud-bigquery in dependencyManagement section. So diff --git a/.kokoro/continuous/graalvm-native-17.cfg b/.kokoro/continuous/graalvm-native-17.cfg index b2d351e09d..91d2c3bc7d 100644 --- a/.kokoro/continuous/graalvm-native-17.cfg +++ b/.kokoro/continuous/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.31.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.32.0" } env_vars: { diff --git a/.kokoro/continuous/graalvm-native.cfg b/.kokoro/continuous/graalvm-native.cfg index 8a5d647570..3f34dd7532 100644 --- a/.kokoro/continuous/graalvm-native.cfg +++ b/.kokoro/continuous/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.31.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.32.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index e94d7bcd66..e4416de916 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.31.0"" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.32.0"" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index 047ec1b678..519c2e3ce3 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.31.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.32.0" } env_vars: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 74c10885b2..e962971e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [2.41.0](https://github.com/googleapis/java-bigquery/compare/v2.40.3...v2.41.0) (2024-06-25) + + +### Features + +* Add columnNameCharacterMap to LoadJobConfiguration ([#3356](https://github.com/googleapis/java-bigquery/issues/3356)) ([2f3cbe3](https://github.com/googleapis/java-bigquery/commit/2f3cbe39619bcc93cb7d504417accd84b418dd41)) +* Add MetadataCacheMode to ExternalTableDefinition ([#3351](https://github.com/googleapis/java-bigquery/issues/3351)) ([2814dc4](https://github.com/googleapis/java-bigquery/commit/2814dc49dfdd5671257b6a9933a5dd381d889dd1)) + + +### Bug Fixes + +* Add clustering value to ListTables result ([#3359](https://github.com/googleapis/java-bigquery/issues/3359)) ([5d52bc9](https://github.com/googleapis/java-bigquery/commit/5d52bc9f4ef93f84200335685901c6ac0256b769)) + + +### Dependencies + +* Update actions/checkout action to v4.1.7 ([#3349](https://github.com/googleapis/java-bigquery/issues/3349)) ([0857234](https://github.com/googleapis/java-bigquery/commit/085723491e4aca58d670c313bc18b0c044cfdca8)) +* Update dependency com.google.apis:google-api-services-bigquery to v2-rev20240602-2.0.0 ([#3273](https://github.com/googleapis/java-bigquery/issues/3273)) ([7b7e52b](https://github.com/googleapis/java-bigquery/commit/7b7e52b339f57af752c573a222df68196f1808f5)) +* Update dependency com.google.cloud:sdk-platform-java-config to v3.32.0 ([#3360](https://github.com/googleapis/java-bigquery/issues/3360)) ([4420996](https://github.com/googleapis/java-bigquery/commit/4420996e89fef49270771bb4f01ffa4e871e7885)) +* Update github/codeql-action action to v2.25.10 ([#3348](https://github.com/googleapis/java-bigquery/issues/3348)) ([8b6feff](https://github.com/googleapis/java-bigquery/commit/8b6feffa0e8add73a7587ce1762989713c2af38b)) + ## [2.40.3](https://github.com/googleapis/java-bigquery/compare/v2.40.2...v2.40.3) (2024-06-12) diff --git a/README.md b/README.md index f8cebcd7eb..3a77fbac98 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ If you are using Maven without the BOM, add this to your dependencies: com.google.cloud google-cloud-bigquery - 2.40.2 + 2.40.3 ``` @@ -53,20 +53,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.40.0') +implementation platform('com.google.cloud:libraries-bom:26.42.0') implementation 'com.google.cloud:google-cloud-bigquery' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-bigquery:2.40.2' +implementation 'com.google.cloud:google-cloud-bigquery:2.40.3' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.40.2" +libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.40.3" ``` @@ -351,7 +351,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-bigquery/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-bigquery.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigquery/2.40.2 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigquery/2.40.3 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 34936aa4b3..7bc7e664f8 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -6,7 +6,7 @@ google-cloud-bigquery-parent com.google.cloud - 2.40.3 + 2.41.0 diff --git a/google-cloud-bigquery-bom/pom.xml b/google-cloud-bigquery-bom/pom.xml index 62c3d4efca..02d85f13fc 100644 --- a/google-cloud-bigquery-bom/pom.xml +++ b/google-cloud-bigquery-bom/pom.xml @@ -3,12 +3,12 @@ 4.0.0 com.google.cloud google-cloud-bigquery-bom - 2.40.3 + 2.41.0 pom com.google.cloud sdk-platform-java-config - 3.31.0 + 3.32.0 @@ -54,7 +54,7 @@ com.google.cloud google-cloud-bigquery - 2.40.3 + 2.41.0 diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 7c4aeb0b2a..3a4fa4af07 100644 --- a/google-cloud-bigquery/pom.xml +++ b/google-cloud-bigquery/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigquery - 2.40.3 + 2.41.0 jar BigQuery https://github.com/googleapis/java-bigquery @@ -11,7 +11,7 @@ com.google.cloud google-cloud-bigquery-parent - 2.40.3 + 2.41.0 google-cloud-bigquery diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java index 9f8aa40124..363f9507e1 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java @@ -186,6 +186,20 @@ public Builder setObjectMetadata(String objectMetadata) { abstract Builder setObjectMetadataInner(String objectMetadata); + /** + * [Optional] Metadata Cache Mode for the table. Set this to enable caching of metadata from + * external data source. + * + * @see + * MetadataCacheMode + */ + public Builder setMetadataCacheMode(String metadataCacheMode) { + return setMetadataCacheModeInner(metadataCacheMode); + } + + abstract Builder setMetadataCacheModeInner(String metadataCacheMode); + /** Creates an {@code ExternalTableDefinition} object. */ @Override public abstract ExternalTableDefinition build(); @@ -276,6 +290,21 @@ public String getObjectMetadata() { @Nullable abstract String getObjectMetadataInner(); + /** + * Returns the metadata cache mode. + * + * @see + * MetadataCacheMode + */ + @Nullable + public String getMetadataCacheMode() { + return getMetadataCacheModeInner(); + } + + @Nullable + abstract String getMetadataCacheModeInner(); + /** * Returns the source format, and possibly some parsing options, of the external data. Supported * formats are {@code CSV} and {@code NEWLINE_DELIMITED_JSON}. @@ -387,6 +416,10 @@ com.google.api.services.bigquery.model.ExternalDataConfiguration toExternalDataC externalConfigurationPb.setObjectMetadata(getObjectMetadata()); } + if (getMetadataCacheMode() != null) { + externalConfigurationPb.setMetadataCacheMode(getMetadataCacheMode()); + } + return externalConfigurationPb; } @@ -580,6 +613,9 @@ static ExternalTableDefinition fromPb(Table tablePb) { if (externalDataConfiguration.getObjectMetadata() != null) { builder.setObjectMetadata(externalDataConfiguration.getObjectMetadata()); } + if (externalDataConfiguration.getMetadataCacheMode() != null) { + builder.setMetadataCacheMode(externalDataConfiguration.getMetadataCacheMode()); + } } return builder.build(); } @@ -647,6 +683,10 @@ static ExternalTableDefinition fromExternalDataConfiguration( builder.setObjectMetadata(externalDataConfiguration.getObjectMetadata()); } + if (externalDataConfiguration.getMetadataCacheMode() != null) { + builder.setMetadataCacheMode(externalDataConfiguration.getMetadataCacheMode()); + } + return builder.build(); } } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java index fefff3409f..2d348f0d45 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java @@ -39,6 +39,7 @@ public final class LoadJobConfiguration extends JobConfiguration implements Load private final List sourceUris; private final String fileSetSpecType; + private final String columnNameCharacterMap; private final TableId destinationTable; private final List decimalTargetTypes; private final EncryptionConfiguration destinationEncryptionConfiguration; @@ -69,6 +70,8 @@ public static final class Builder extends JobConfiguration.Builder sourceUris; private String fileSetSpecType; + private String columnNameCharacterMap; + private TableId destinationTable; private List decimalTargetTypes; private EncryptionConfiguration destinationEncryptionConfiguration; @@ -110,6 +113,7 @@ private Builder(LoadJobConfiguration loadConfiguration) { this.ignoreUnknownValues = loadConfiguration.ignoreUnknownValues; this.sourceUris = loadConfiguration.sourceUris; this.fileSetSpecType = loadConfiguration.fileSetSpecType; + this.columnNameCharacterMap = loadConfiguration.columnNameCharacterMap; this.schemaUpdateOptions = loadConfiguration.schemaUpdateOptions; this.autodetect = loadConfiguration.autodetect; this.destinationEncryptionConfiguration = @@ -181,6 +185,9 @@ private Builder(com.google.api.services.bigquery.model.JobConfiguration configur if (loadConfigurationPb.getFileSetSpecType() != null) { this.fileSetSpecType = loadConfigurationPb.getFileSetSpecType(); } + if (loadConfigurationPb.getColumnNameCharacterMap() != null) { + this.columnNameCharacterMap = loadConfigurationPb.getColumnNameCharacterMap(); + } if (loadConfigurationPb.getSchemaUpdateOptions() != null) { ImmutableList.Builder schemaUpdateOptionsBuilder = new ImmutableList.Builder<>(); @@ -323,6 +330,20 @@ public Builder setFileSetSpecType(String fileSetSpecType) { return this; } + /** + * [Optional] Character map supported for column names in CSV/Parquet loads. Defaults to STRICT + * and can be overridden by Project Config Service. Using this option with unsupporting load + * formats will result in an error. + * + * @see + * ColumnNameCharacterMap + */ + public Builder setColumnNameCharacterMap(String columnNameCharacterMap) { + this.columnNameCharacterMap = columnNameCharacterMap; + return this; + } + /** * Defines the list of possible SQL data types to which the source decimal values are converted. * This list and the precision and the scale parameters of the decimal field determine the @@ -421,6 +442,7 @@ private LoadJobConfiguration(Builder builder) { super(builder); this.sourceUris = builder.sourceUris; this.fileSetSpecType = builder.fileSetSpecType; + this.columnNameCharacterMap = builder.columnNameCharacterMap; this.destinationTable = builder.destinationTable; this.decimalTargetTypes = builder.decimalTargetTypes; this.createDisposition = builder.createDisposition; @@ -519,6 +541,17 @@ public String getFileSetSpecType() { return fileSetSpecType; } + /** + * Returns the column name character map used in CSV/Parquet loads. + * + * @see + * ColumnNameCharacterMap + */ + public String getColumnNameCharacterMap() { + return columnNameCharacterMap; + } + public List getDecimalTargetTypes() { return decimalTargetTypes; } @@ -598,6 +631,7 @@ ToStringHelper toStringHelper() { .add("ignoreUnknownValue", ignoreUnknownValues) .add("sourceUris", sourceUris) .add("fileSetSpecType", fileSetSpecType) + .add("columnNameCharacterMap", columnNameCharacterMap) .add("schemaUpdateOptions", schemaUpdateOptions) .add("autodetect", autodetect) .add("timePartitioning", timePartitioning) @@ -681,6 +715,9 @@ com.google.api.services.bigquery.model.JobConfiguration toPb() { if (fileSetSpecType != null) { loadConfigurationPb.setFileSetSpecType(fileSetSpecType); } + if (columnNameCharacterMap != null) { + loadConfigurationPb.setColumnNameCharacterMap(columnNameCharacterMap); + } if (decimalTargetTypes != null) { loadConfigurationPb.setDecimalTargetTypes(ImmutableList.copyOf(decimalTargetTypes)); } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java index 5dd39eaed9..93337d8cac 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java @@ -364,7 +364,8 @@ public Table apply(TableList.Tables tablePb) { .setType(tablePb.getType()) .setCreationTime(tablePb.getCreationTime()) .setTimePartitioning(tablePb.getTimePartitioning()) - .setRangePartitioning(tablePb.getRangePartitioning()); + .setRangePartitioning(tablePb.getRangePartitioning()) + .setClustering(tablePb.getClustering()); } })); } catch (IOException ex) { diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java index ed56598916..2562e1763c 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java @@ -59,6 +59,8 @@ public class ExternalTableDefinitionTest { .setSourceUriPrefix(SOURCE_URIS.get(0)) .build(); private static final String OBJECT_METADATA = "SIMPLE"; + + private static final String METADATA_CACHE_MODE = "AUTOMATIC"; private static final ExternalTableDefinition EXTERNAL_TABLE_DEFINITION = ExternalTableDefinition.newBuilder(SOURCE_URIS, TABLE_SCHEMA, CSV_OPTIONS) .setFileSetSpecType("FILE_SET_SPEC_TYPE_FILE_SYSTEM_MATCH") @@ -70,6 +72,7 @@ public class ExternalTableDefinitionTest { .setAutodetect(AUTODETECT) .setHivePartitioningOptions(HIVE_PARTITIONING_OPTIONS) .setObjectMetadata(OBJECT_METADATA) + .setMetadataCacheMode(METADATA_CACHE_MODE) .build(); private static final ExternalTableDefinition EXTERNAL_TABLE_DEFINITION_AVRO = @@ -170,5 +173,6 @@ private void compareExternalTableDefinition( assertEquals(expected.getAutodetect(), value.getAutodetect()); assertEquals(expected.getHivePartitioningOptions(), value.getHivePartitioningOptions()); assertEquals(expected.getObjectMetadata(), value.getObjectMetadata()); + assertEquals(expected.getMetadataCacheMode(), value.getMetadataCacheMode()); } } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java index 563a3f34a1..85709a74a2 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java @@ -92,6 +92,7 @@ public class LoadJobConfigurationTest { .setWriteDisposition(WRITE_DISPOSITION) .setFormatOptions(CSV_OPTIONS) .setFileSetSpecType("FILE_SET_SPEC_TYPE_FILE_SYSTEM_MATCH") + .setColumnNameCharacterMap("STRICT") .setIgnoreUnknownValues(IGNORE_UNKNOWN_VALUES) .setMaxBadRecords(MAX_BAD_RECORDS) .setSchema(TABLE_SCHEMA) @@ -242,6 +243,7 @@ private void compareLoadJobConfiguration( assertEquals(expected, value); assertEquals(expected.hashCode(), value.hashCode()); assertEquals(expected.getFileSetSpecType(), value.getFileSetSpecType()); + assertEquals(expected.getColumnNameCharacterMap(), value.getColumnNameCharacterMap()); assertEquals(expected.toString(), value.toString()); assertEquals(expected.getDestinationTable(), value.getDestinationTable()); assertEquals(expected.getDecimalTargetTypes(), value.getDecimalTargetTypes()); 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 e67c9486fc..6a7a4e26bd 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 @@ -586,6 +586,8 @@ public class ITBigQueryTest { RangePartitioning.newBuilder().setField("IntegerField").setRange(RANGE).build(); private static final String LOAD_FILE = "load.csv"; private static final String LOAD_FILE_LARGE = "load_large.csv"; + + private static final String LOAD_FILE_FLEXIBLE_COLUMN_NAME = "load_flexible_column_name.csv"; private static final String JSON_LOAD_FILE = "load.json"; private static final String JSON_LOAD_FILE_BQ_RESULTSET = "load_bq_resultset.json"; private static final String JSON_LOAD_FILE_SIMPLE = "load_simple.json"; @@ -601,6 +603,7 @@ public class ITBigQueryTest { private static final TableId TABLE_ID_FASTQUERY_BQ_RESULTSET = TableId.of(DATASET, "fastquery_testing_bq_resultset"); private static final String CSV_CONTENT = "StringValue1\nStringValue2\n"; + private static final String CSV_CONTENT_FLEXIBLE_COLUMN = "name,&ersand\nrow_name,1"; private static final String JSON_CONTENT = "{" @@ -1019,6 +1022,11 @@ public static void beforeClass() throws InterruptedException, IOException { storage.create( BlobInfo.newBuilder(BUCKET, LOAD_FILE).setContentType("text/plain").build(), CSV_CONTENT.getBytes(StandardCharsets.UTF_8)); + storage.create( + BlobInfo.newBuilder(BUCKET, LOAD_FILE_FLEXIBLE_COLUMN_NAME) + .setContentType("text/plain") + .build(), + CSV_CONTENT_FLEXIBLE_COLUMN.getBytes(StandardCharsets.UTF_8)); storage.create( BlobInfo.newBuilder(BUCKET, JSON_LOAD_FILE).setContentType("application/json").build(), JSON_CONTENT.getBytes(StandardCharsets.UTF_8)); @@ -1895,6 +1903,41 @@ public void testCreateAndGetTable() { assertTrue(remoteTable.delete()); } + @Test + public void testCreateAndListTable() { + String tableName = "test_create_and_list_table"; + TableId tableId = TableId.of(DATASET, tableName); + TimePartitioning partitioning = TimePartitioning.of(Type.DAY); + Clustering clustering = + Clustering.newBuilder().setFields(ImmutableList.of(STRING_FIELD_SCHEMA.getName())).build(); + StandardTableDefinition tableDefinition = + StandardTableDefinition.newBuilder() + .setSchema(TABLE_SCHEMA) + .setTimePartitioning(partitioning) + .setClustering(clustering) + .build(); + Table createdTable = bigquery.create(TableInfo.of(tableId, tableDefinition)); + assertNotNull(createdTable); + assertEquals(DATASET, createdTable.getTableId().getDataset()); + assertEquals(tableName, createdTable.getTableId().getTable()); + + Page tables = bigquery.listTables(DATASET); + boolean found = false; + Iterator
tableIterator = tables.getValues().iterator(); + // Find createdTable and validate the table definition. + while (tableIterator.hasNext() && !found) { + Table table = tableIterator.next(); + if (table.getTableId().equals(createdTable.getTableId())) { + StandardTableDefinition definition = table.getDefinition(); + assertThat(definition.getClustering()).isNotNull(); + assertThat(definition.getTimePartitioning()).isNotNull(); + found = true; + } + } + assertTrue(found); + assertTrue(createdTable.delete()); + } + @Test public void testCreateAndGetTableWithBasicTableMetadataView() { String tableName = "test_create_and_get_table_with_basic_metadata_view"; @@ -6832,6 +6875,32 @@ public void testExternalTableMetadataCachingNotEnable() throws InterruptedExcept assertTrue(remoteTable.delete()); } + @Test + public void testExternalMetadataCacheModeFailForNonBiglake() { + // Validate that MetadataCacheMode is passed to the backend. + // TODO: Enhance this test after BigLake testing infrastructure is inplace. + String tableName = "test_metadata_cache_mode_fail_for_non_biglake"; + TableId tableId = TableId.of(DATASET, tableName); + ExternalTableDefinition externalTableDefinition = + ExternalTableDefinition.newBuilder( + "gs://" + BUCKET + "/" + JSON_LOAD_FILE, TABLE_SCHEMA, FormatOptions.json()) + .setMetadataCacheMode("AUTOMATIC") + .build(); + TableInfo tableInfo = TableInfo.of(tableId, externalTableDefinition); + + try { + bigquery.create(tableInfo); + fail("BigQueryException was expected"); + } catch (BigQueryException e) { + BigQueryError error = e.getError(); + assertNotNull(error); + assertEquals("invalid", error.getReason()); + assertThat( + e.getMessage().contains("metadataCacheMode provided for non BigLake external table")) + .isTrue(); + } + } + @Test public void testObjectTable() throws InterruptedException { String tableName = "test_object_table"; @@ -6908,4 +6977,60 @@ public void testQueryExportStatistics() throws InterruptedException { assertEquals(1L, queryStatistics.getExportDataStats().getFileCount().longValue()); assertEquals(3L, queryStatistics.getExportDataStats().getRowCount().longValue()); } + + @Test + public void testLoadConfigurationFlexibleColumnName() throws InterruptedException { + // See https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#columnnamecharactermap for + // mapping. + + // Test v1 mapping. + String v1TableName = "flexible_column_name_data_testing_table_v1"; + TableId v1TableId = TableId.of(DATASET, v1TableName); + try { + LoadJobConfiguration loadJobConfigurationV1 = + LoadJobConfiguration.newBuilder( + v1TableId, + "gs://" + BUCKET + "/" + LOAD_FILE_FLEXIBLE_COLUMN_NAME, + FormatOptions.csv()) + .setCreateDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED) + .setAutodetect(true) + .setColumnNameCharacterMap("V1") + .build(); + Job jobV1 = bigquery.create(JobInfo.of(loadJobConfigurationV1)); + jobV1 = jobV1.waitFor(); + assertNull(jobV1.getStatus().getError()); + + Table remoteTableV1 = bigquery.getTable(DATASET, v1TableName); + assertNotNull(remoteTableV1); + assertEquals( + "_ampersand", remoteTableV1.getDefinition().getSchema().getFields().get(1).getName()); + } finally { + bigquery.delete(v1TableId); + } + + // Test v2 mapping. + String v2TableName = "flexible_column_name_data_testing_table_v2"; + TableId v2TableId = TableId.of(DATASET, v2TableName); + try { + LoadJobConfiguration loadJobConfigurationV2 = + LoadJobConfiguration.newBuilder( + v2TableId, + "gs://" + BUCKET + "/" + LOAD_FILE_FLEXIBLE_COLUMN_NAME, + FormatOptions.csv()) + .setCreateDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED) + .setAutodetect(true) + .setColumnNameCharacterMap("V2") + .build(); + Job jobV2 = bigquery.create(JobInfo.of(loadJobConfigurationV2)); + jobV2 = jobV2.waitFor(); + assertNull(jobV2.getStatus().getError()); + + Table remoteTableV2 = bigquery.getTable(DATASET, v2TableName); + assertNotNull(remoteTableV2); + assertEquals( + "&ersand", remoteTableV2.getDefinition().getSchema().getFields().get(1).getName()); + } finally { + bigquery.delete(v2TableId); + } + } } diff --git a/pom.xml b/pom.xml index 076fac5219..bdbd671348 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloudgoogle-cloud-bigquery-parentpom - 2.40.3 + 2.41.0BigQuery Parenthttps://github.com/googleapis/java-bigquery @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.31.0 + 3.32.0 @@ -54,7 +54,7 @@ UTF-8 github google-cloud-bigquery-parent - v2-rev20240323-2.0.0 + v2-rev20240602-2.0.0 @@ -71,7 +71,7 @@ com.google.cloud google-cloud-bigquerystorage-bom - 3.6.0 + 3.6.1 pom import @@ -93,7 +93,7 @@ com.google.cloud google-cloud-bigquery - 2.40.3 + 2.41.0 @@ -180,7 +180,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.5.0 + 3.6.0 diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 89db86a583..3a8f8d9976 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -45,7 +45,7 @@ com.google.cloud google-cloud-bigquery - 2.40.2 + 2.40.3 diff --git a/samples/native-image-sample/pom.xml b/samples/native-image-sample/pom.xml index cb49561656..db3ce2f184 100644 --- a/samples/native-image-sample/pom.xml +++ b/samples/native-image-sample/pom.xml @@ -111,7 +111,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.5 + 3.3.0 **/*IT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 673234c1dd..a37cbe6f3a 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -44,7 +44,7 @@ com.google.cloud google-cloud-bigquery - 2.40.3 + 2.41.0 diff --git a/versions.txt b/versions.txt index 77a4710e89..5534bc5ee6 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-bigquery:2.40.3:2.40.3 \ No newline at end of file +google-cloud-bigquery:2.41.0:2.41.0 \ No newline at end of file