diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 52eaa54d82..8058621d83 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:88ba8dcc5c2c7792e1c3511381f4ab329002a1c42c512f66ca87ced572dfbf9f -# created: 2023-09-05T18:54:42.225408832Z + digest: sha256:4875b2142cb4325542ba4f3175a81921c4b2b8256db012b220e3ca9637b34154 +# created: 2023-10-24T01:51:42.863726766Z diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 71db8036bb..1518a20e22 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,12 +32,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0 + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 with: results_file: results.sarif results_format: sarif @@ -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@fdcae64e1484d349b3366718cdfef3d404390e85 # v2.22.1 + uses: github/codeql-action/upload-sarif@49abf0ba24d0b7953cb586944e918a0b92074c80 # v2.22.4 with: sarif_file: results.sarif diff --git a/.kokoro/nightly/integration.cfg b/.kokoro/nightly/integration.cfg index a2907a257b..24b9cf6345 100644 --- a/.kokoro/nightly/integration.cfg +++ b/.kokoro/nightly/integration.cfg @@ -13,12 +13,12 @@ env_vars: { # TODO: remove this after we've migrated all tests and scripts env_vars: { key: "GCLOUD_PROJECT" - value: "java-docs-samples-testing" + value: "gcloud-devel" } env_vars: { key: "GOOGLE_CLOUD_PROJECT" - value: "java-docs-samples-testing" + value: "gcloud-devel" } env_vars: { @@ -35,3 +35,4 @@ env_vars: { key: "SECRET_MANAGER_KEYS" value: "java-it-service-account" } + diff --git a/.kokoro/nightly/java11-integration.cfg b/.kokoro/nightly/java11-integration.cfg index 58049cc38f..6a6ef94eff 100644 --- a/.kokoro/nightly/java11-integration.cfg +++ b/.kokoro/nightly/java11-integration.cfg @@ -35,3 +35,4 @@ env_vars: { key: "SECRET_MANAGER_KEYS" value: "java-it-service-account" } + diff --git a/.kokoro/presubmit/integration.cfg b/.kokoro/presubmit/integration.cfg index dded67a9d5..5864c603e5 100644 --- a/.kokoro/presubmit/integration.cfg +++ b/.kokoro/presubmit/integration.cfg @@ -31,3 +31,4 @@ env_vars: { key: "SECRET_MANAGER_KEYS" value: "java-it-service-account" } + diff --git a/.kokoro/requirements.txt b/.kokoro/requirements.txt index a73256ab80..c5c11bbe79 100644 --- a/.kokoro/requirements.txt +++ b/.kokoro/requirements.txt @@ -418,6 +418,7 @@ protobuf==3.20.3 \ # gcp-docuploader # gcp-releasetool # google-api-core + # googleapis-common-protos pyasn1==0.5.0 \ --hash=sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57 \ --hash=sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde @@ -469,9 +470,9 @@ typing-extensions==4.7.1 \ --hash=sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36 \ --hash=sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2 # via -r requirements.in -urllib3==1.26.16 \ - --hash=sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f \ - --hash=sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14 +urllib3==1.26.18 \ + --hash=sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07 \ + --hash=sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0 # via # google-auth # requests @@ -485,5 +486,6 @@ zipp==3.16.1 \ # via importlib-metadata # WARNING: The following packages were not pinned, but pip requires them to be -# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. +# pinned when the requirements file includes hashes and the requirement is not +# satisfied by a package already installed. Consider using the --allow-unsafe flag. # setuptools diff --git a/CHANGELOG.md b/CHANGELOG.md index 07d11f8888..a8d56e8910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## [2.34.0](https://github.com/googleapis/java-bigquery/compare/v2.33.2...v2.34.0) (2023-10-26) + + +### Features + +* Add BigLakeConfiguration Property in StandardTableDefinition.java ([#2916](https://github.com/googleapis/java-bigquery/issues/2916)) ([1d660fa](https://github.com/googleapis/java-bigquery/commit/1d660fa19f0d82c2b6ec2ea9590881e513274c25)) +* Add support for Dataset property storageBillingModel ([#2913](https://github.com/googleapis/java-bigquery/issues/2913)) ([f452cf4](https://github.com/googleapis/java-bigquery/commit/f452cf4e100b6cc211681a840ddbd0be5108d01e)) +* Add support for preview features ([#2923](https://github.com/googleapis/java-bigquery/issues/2923)) ([113b8f2](https://github.com/googleapis/java-bigquery/commit/113b8f27419365c7277c6a300c5f07cea954cca1)) + + +### Dependencies + +* Update actions/checkout action to v4.1.1 ([#2950](https://github.com/googleapis/java-bigquery/issues/2950)) ([c556c18](https://github.com/googleapis/java-bigquery/commit/c556c1837baf0d53245452d6a152910df7883262)) +* Update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.30.0 ([#2942](https://github.com/googleapis/java-bigquery/issues/2942)) ([e760fca](https://github.com/googleapis/java-bigquery/commit/e760fcae98b23ff4e7fc3ae25f2437be220e9df9)) +* Update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.31.0 ([#2967](https://github.com/googleapis/java-bigquery/issues/2967)) ([7ed55b5](https://github.com/googleapis/java-bigquery/commit/7ed55b5c075dbac827c6201d0398ff87d8240b38)) +* Update dependency com.google.apis:google-api-services-bigquery to v2-rev20231008-2.0.0 ([#2946](https://github.com/googleapis/java-bigquery/issues/2946)) ([3d0da5b](https://github.com/googleapis/java-bigquery/commit/3d0da5b5a20f49721477afbed10ea3fff43652bb)) +* Update dependency com.google.cloud:google-cloud-datacatalog-bom to v1.34.0 ([#2943](https://github.com/googleapis/java-bigquery/issues/2943)) ([18162c3](https://github.com/googleapis/java-bigquery/commit/18162c37c97eff6387e0f58d211f2c1725a9c8d3)) +* Update dependency com.google.cloud:google-cloud-datacatalog-bom to v1.35.0 ([#2968](https://github.com/googleapis/java-bigquery/issues/2968)) ([219db2c](https://github.com/googleapis/java-bigquery/commit/219db2c0023610d2adcba4889a9b785df2113893)) +* Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.18.0 ([#2955](https://github.com/googleapis/java-bigquery/issues/2955)) ([1ee18eb](https://github.com/googleapis/java-bigquery/commit/1ee18ebeb90adeb371ef04cbfc7b18be2c24d1e8)) +* Update dependency org.graalvm.buildtools:junit-platform-native to v0.9.28 ([#2956](https://github.com/googleapis/java-bigquery/issues/2956)) ([b03effd](https://github.com/googleapis/java-bigquery/commit/b03effd3b5f5fd6365de9a6267a1a8ace46d7718)) +* Update dependency org.graalvm.buildtools:native-maven-plugin to v0.9.28 ([#2957](https://github.com/googleapis/java-bigquery/issues/2957)) ([6465e41](https://github.com/googleapis/java-bigquery/commit/6465e413c93e01069f86c80fc424715d46f9067b)) +* Update github/codeql-action action to v2.22.2 ([#2944](https://github.com/googleapis/java-bigquery/issues/2944)) ([f584e59](https://github.com/googleapis/java-bigquery/commit/f584e59571f0c7918d2d83a19b00d49bd5b558c4)) +* Update github/codeql-action action to v2.22.3 ([#2954](https://github.com/googleapis/java-bigquery/issues/2954)) ([1b2bc18](https://github.com/googleapis/java-bigquery/commit/1b2bc18bf49d06e1ccd29745be649108dd28cfa5)) +* Update github/codeql-action action to v2.22.4 ([#2958](https://github.com/googleapis/java-bigquery/issues/2958)) ([de9bcee](https://github.com/googleapis/java-bigquery/commit/de9bcee50ba682ffa93aae063191a8880741507d)) +* Update ossf/scorecard-action action to v2.3.1 ([#2960](https://github.com/googleapis/java-bigquery/issues/2960)) ([855e698](https://github.com/googleapis/java-bigquery/commit/855e69889f68592608c8a56070ffdafdf8365f57)) + ## [2.33.2](https://github.com/googleapis/java-bigquery/compare/v2.33.1...v2.33.2) (2023-10-11) diff --git a/README.md b/README.md index 2a30c8073a..6eb5a01fa5 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.33.1 + 2.33.2 ``` @@ -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.24.0') +implementation platform('com.google.cloud:libraries-bom:26.25.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.33.1' +implementation 'com.google.cloud:google-cloud-bigquery:2.33.2' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.33.1" +libraryDependencies += "com.google.cloud" % "google-cloud-bigquery" % "2.33.2" ``` @@ -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.33.1 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigquery/2.33.2 [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 cd086b1116..15cd025ff6 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -6,7 +6,7 @@ google-cloud-bigquery-parent com.google.cloud - 2.33.2 + 2.34.0 diff --git a/google-cloud-bigquery/clirr-ignored-differences.xml b/google-cloud-bigquery/clirr-ignored-differences.xml index eaeeded132..c22579a795 100644 --- a/google-cloud-bigquery/clirr-ignored-differences.xml +++ b/google-cloud-bigquery/clirr-ignored-differences.xml @@ -109,4 +109,14 @@ com/google/cloud/bigquery/DatasetInfo* *setExternalDatasetReference(*) + + 7013 + com/google/cloud/bigquery/DatasetInfo* + *setStorageBillingModel(*) + + + 7013 + com/google/cloud/bigquery/StandardTableDefinition* + *BigLakeConfiguration(*) + \ No newline at end of file diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml index 53bd43904f..d98743b7e7 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.33.2 + 2.34.0 jar BigQuery https://github.com/googleapis/java-bigquery @@ -11,7 +11,7 @@ com.google.cloud google-cloud-bigquery-parent - 2.33.2 + 2.34.0 google-cloud-bigquery diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigLakeConfiguration.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigLakeConfiguration.java new file mode 100644 index 0000000000..76b3f55d94 --- /dev/null +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigLakeConfiguration.java @@ -0,0 +1,120 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.bigquery; + +import com.google.auto.value.AutoValue; +import java.io.Serializable; + +@AutoValue +public abstract class BigLakeConfiguration implements Serializable { + + private static final long serialVersionUID = -5951589238459622025L; + + /** + * Credential reference for accessing external storage system. Normalized as + * project_id.location_id.connection_id. + * + * @return value or {@code null} for none + */ + public abstract String getConnectionId(); + + /** + * Open source file format that the table data is stored in. Currently only PARQUET is supported. + * + * @return value or {@code null} for none + */ + public abstract String getFileFormat(); + + /** + * Fully qualified location prefix of the external folder where data is stored. Starts with + * "gs://" ends with "/". Does not contain "*". + * + * @return value or {@code null} for none + */ + public abstract String getStorageUri(); + + /** + * Open source file format that the table data is stored in. Currently only PARQUET is supported. + * + * @return value or {@code null} for none + */ + public abstract String getTableFormat(); + + public static Builder newBuilder() { + return new AutoValue_BigLakeConfiguration.Builder(); + } + + public abstract Builder toBuilder(); + + @AutoValue.Builder + public abstract static class Builder { + /** + * [Required] Required and immutable. Credential reference for accessing external storage + * system. Normalized as project_id.location_id.connection_id. + * + * @param connectionId connectionId or {@code null} for none + */ + public abstract Builder setConnectionId(String connectionId); + + /** + * [Required] Required and immutable. Open source file format that the table data is stored in. + * Currently only PARQUET is supported. + * + * @param fileFormat fileFormat or {@code null} for none + */ + public abstract Builder setFileFormat(String fileFormat); + + /** + * [Required] Required and immutable. Fully qualified location prefix of the external folder + * where data is stored. Starts with "gs://" and ends with "/". Does not contain "*". + * + * @param storageUri storageUri or {@code null} for none + */ + public abstract Builder setStorageUri(String storageUri); + + /** + * [Required] Required and immutable. Open source file format that the table data is stored in. + * Currently only PARQUET is supported. + * + * @param tableFormat tableFormat or {@code null} for none + */ + public abstract Builder setTableFormat(String tableFormat); + + public abstract BigLakeConfiguration build(); + } + + com.google.api.services.bigquery.model.BigLakeConfiguration toPb() { + com.google.api.services.bigquery.model.BigLakeConfiguration biglakeConfiguration = + new com.google.api.services.bigquery.model.BigLakeConfiguration(); + biglakeConfiguration.setConnectionId(getConnectionId()); + biglakeConfiguration.setFileFormat(getFileFormat()); + biglakeConfiguration.setStorageUri(getStorageUri()); + biglakeConfiguration.setTableFormat(getTableFormat()); + + return biglakeConfiguration; + } + + static BigLakeConfiguration fromPb( + com.google.api.services.bigquery.model.BigLakeConfiguration biglakeConfigurationPb) { + return newBuilder() + .setConnectionId(biglakeConfigurationPb.getConnectionId()) + .setFileFormat(biglakeConfigurationPb.getFileFormat()) + .setStorageUri(biglakeConfigurationPb.getStorageUri()) + .setTableFormat(biglakeConfigurationPb.getTableFormat()) + .build(); + } +} diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java index ac6262e69d..80fd6618dc 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java @@ -1596,6 +1596,16 @@ TableResult listTableData( * } * * + * This method supports query-related preview features via environmental variables (enabled by + * setting the {@code QUERY_PREVIEW_ENABLED} environment variable to "TRUE"). Specifically, this + * method supports: + * + * + * + * The behaviour of these preview features is controlled by the bigquery service as well + * * @throws BigQueryException upon failure * @throws InterruptedException if the current thread gets interrupted while waiting for the query * to complete diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java index ef7e8cb8b8..0d5842724b 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java @@ -41,6 +41,7 @@ import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.Tuple; import com.google.cloud.bigquery.InsertAllRequest.RowToInsert; +import com.google.cloud.bigquery.QueryJobConfiguration.JobCreationMode; import com.google.cloud.bigquery.spi.v2.BigQueryRpc; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -1324,6 +1325,14 @@ public TableResult query(QueryJobConfiguration configuration, JobOption... optio throws InterruptedException, JobException { Job.checkNotDryRun(configuration, "query"); + if (getOptions().isQueryPreviewEnabled()) { + configuration = + configuration + .toBuilder() + .setJobCreationMode(JobCreationMode.JOB_CREATION_OPTIONAL) + .build(); + } + // If all parameters passed in configuration are supported by the query() method on the backend, // put on fast path QueryRequestInfo requestInfo = new QueryRequestInfo(configuration); @@ -1416,6 +1425,7 @@ public com.google.api.services.bigquery.model.QueryResponse call() { public TableResult query(QueryJobConfiguration configuration, JobId jobId, JobOption... options) throws InterruptedException, JobException { Job.checkNotDryRun(configuration, "query"); + // If all parameters passed in configuration are supported by the query() method on the backend, // put on fast path QueryRequestInfo requestInfo = new QueryRequestInfo(configuration); diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java index 2e22ba9224..e53439f023 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java @@ -24,6 +24,7 @@ import com.google.cloud.bigquery.spi.v2.BigQueryRpc; import com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc; import com.google.cloud.http.HttpTransportOptions; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import java.util.Set; @@ -37,6 +38,7 @@ public class BigQueryOptions extends ServiceOptions { private final String location; // set the option ThrowNotFound when you want to throw the exception when the value not found private boolean setThrowNotFound; + private String queryPreviewEnabled = System.getenv("QUERY_PREVIEW_ENABLED"); public static class DefaultBigQueryFactory implements BigQueryFactory { @@ -130,10 +132,19 @@ public String getLocation() { return location; } + public boolean isQueryPreviewEnabled() { + return queryPreviewEnabled != null && queryPreviewEnabled.equalsIgnoreCase("TRUE"); + } + public void setThrowNotFound(boolean setThrowNotFound) { this.setThrowNotFound = setThrowNotFound; } + @VisibleForTesting + public void setQueryPreviewEnabled(String queryPreviewEnabled) { + this.queryPreviewEnabled = queryPreviewEnabled; + } + public boolean getThrowNotFound() { return setThrowNotFound; } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java index 3ed4b89287..daadb9a857 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java @@ -158,6 +158,12 @@ public Builder setExternalDatasetReference(ExternalDatasetReference externalData return this; } + @Override + public Builder setStorageBillingModel(String storageBillingModel) { + infoBuilder.setStorageBillingModel(storageBillingModel); + return this; + } + @Override public Dataset build() { return new Dataset(bigquery, infoBuilder); diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java index 44583e0c85..0dddc0e86f 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java @@ -74,6 +74,7 @@ public Dataset apply(DatasetInfo datasetInfo) { private final Long defaultPartitionExpirationMs; private final String defaultCollation; private final ExternalDatasetReference externalDatasetReference; + private final String storageBillingModel; /** A builder for {@code DatasetInfo} objects. */ public abstract static class Builder { @@ -135,6 +136,12 @@ public abstract static class Builder { public abstract Builder setExternalDatasetReference( ExternalDatasetReference externalDatasetReference); + /** + * Optional. Storage billing model to be used for all tables in the dataset. Can be set to + * PHYSICAL. Default is LOGICAL. + */ + public abstract Builder setStorageBillingModel(String storageBillingModel); + /** * The default encryption key for all tables in the dataset. Once this property is set, all * newly-created partitioned tables in the dataset will have encryption key set to this value, @@ -192,6 +199,7 @@ static final class BuilderImpl extends Builder { private Long defaultPartitionExpirationMs; private String defaultCollation; private ExternalDatasetReference externalDatasetReference; + private String storageBillingModel; BuilderImpl() {} @@ -212,6 +220,7 @@ static final class BuilderImpl extends Builder { this.defaultPartitionExpirationMs = datasetInfo.defaultPartitionExpirationMs; this.defaultCollation = datasetInfo.defaultCollation; this.externalDatasetReference = datasetInfo.externalDatasetReference; + this.storageBillingModel = datasetInfo.storageBillingModel; } BuilderImpl(com.google.api.services.bigquery.model.Dataset datasetPb) { @@ -250,6 +259,7 @@ public Acl apply(Dataset.Access accessPb) { this.externalDatasetReference = ExternalDatasetReference.fromPb(datasetPb.getExternalDatasetReference()); } + this.storageBillingModel = datasetPb.getStorageBillingModel(); } @Override @@ -356,6 +366,12 @@ public Builder setExternalDatasetReference(ExternalDatasetReference externalData return this; } + @Override + public Builder setStorageBillingModel(String storageBillingModel) { + this.storageBillingModel = storageBillingModel; + return this; + } + @Override public DatasetInfo build() { return new DatasetInfo(this); @@ -379,6 +395,7 @@ public DatasetInfo build() { defaultPartitionExpirationMs = builder.defaultPartitionExpirationMs; defaultCollation = builder.defaultCollation; externalDatasetReference = builder.externalDatasetReference; + storageBillingModel = builder.storageBillingModel; } /** Returns the dataset identity. */ @@ -508,6 +525,10 @@ public String getDefaultCollation() { return defaultCollation; } + public String getStorageBillingModel() { + return storageBillingModel; + } + /** * Returns information about the external metadata storage where the dataset is defined. Filled * out when the dataset type is EXTERNAL. @@ -540,6 +561,7 @@ public String toString() { .add("defaultPartitionExpirationMs", defaultPartitionExpirationMs) .add("defaultCollation", defaultCollation) .add("externalDatasetReference", externalDatasetReference) + .add("storageBillingModel", storageBillingModel) .toString(); } @@ -621,6 +643,9 @@ public Dataset.Access apply(Acl acl) { if (externalDatasetReference != null) { datasetPb.setExternalDatasetReference(externalDatasetReference.toPb()); } + if (storageBillingModel != null) { + datasetPb.setStorageBillingModel(storageBillingModel); + } return datasetPb; } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java index cc726bdd15..0ad85137b2 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java @@ -73,6 +73,7 @@ public final class QueryJobConfiguration extends JobConfiguration { private final List connectionProperties; // maxResults is only used for fast query path private final Long maxResults; + private final JobCreationMode jobCreationMode; /** * Priority levels for a query. If not specified the priority is assumed to be {@link @@ -94,6 +95,21 @@ public enum Priority { BATCH } + /** Job Creation Mode provides different options on job creation. */ + enum JobCreationMode { + /** Unspecified JobCreationMode, defaults to JOB_CREATION_REQUIRED. */ + JOB_CREATION_MODE_UNSPECIFIED, + /** Default. Job creation is always required. */ + JOB_CREATION_REQUIRED, + /** + * Job creation is optional. Returning immediate results is prioritized. BigQuery will + * automatically determine if a Job needs to be created. The conditions under which BigQuery can + * decide to not create a Job are subject to change. If Job creation is required, + * JOB_CREATION_REQUIRED mode should be used, which is the default. + */ + JOB_CREATION_OPTIONAL, + } + public static final class Builder extends JobConfiguration.Builder { @@ -125,6 +141,7 @@ public static final class Builder private RangePartitioning rangePartitioning; private List connectionProperties; private Long maxResults; + private JobCreationMode jobCreationMode; private Builder() { super(Type.QUERY); @@ -160,6 +177,7 @@ private Builder(QueryJobConfiguration jobConfiguration) { this.rangePartitioning = jobConfiguration.rangePartitioning; this.connectionProperties = jobConfiguration.connectionProperties; this.maxResults = jobConfiguration.maxResults; + this.jobCreationMode = jobConfiguration.jobCreationMode; } private Builder(com.google.api.services.bigquery.model.JobConfiguration configurationPb) { @@ -655,6 +673,15 @@ public Builder setMaxResults(Long maxResults) { return this; } + /** + * Provides different options on job creation. If not specified the job creation mode is assumed + * to be {@link JobCreationMode#JOB_CREATION_REQUIRED}. + */ + Builder setJobCreationMode(JobCreationMode jobCreationMode) { + this.jobCreationMode = jobCreationMode; + return this; + } + public QueryJobConfiguration build() { return new QueryJobConfiguration(this); } @@ -699,6 +726,7 @@ private QueryJobConfiguration(Builder builder) { this.rangePartitioning = builder.rangePartitioning; this.connectionProperties = builder.connectionProperties; this.maxResults = builder.maxResults; + this.jobCreationMode = builder.jobCreationMode; } /** @@ -910,6 +938,11 @@ public Long getMaxResults() { return maxResults; } + /** Returns the job creation mode. */ + JobCreationMode getJobCreationMode() { + return jobCreationMode; + } + @Override public Builder toBuilder() { return new Builder(this); @@ -944,7 +977,8 @@ ToStringHelper toStringHelper() { .add("jobTimeoutMs", jobTimeoutMs) .add("labels", labels) .add("rangePartitioning", rangePartitioning) - .add("connectionProperties", connectionProperties); + .add("connectionProperties", connectionProperties) + .add("jobCreationMode", jobCreationMode); } @Override diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequestInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequestInfo.java index 00a8983636..00a11f723b 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequestInfo.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequestInfo.java @@ -18,6 +18,7 @@ import com.google.api.services.bigquery.model.QueryParameter; import com.google.api.services.bigquery.model.QueryRequest; +import com.google.cloud.bigquery.QueryJobConfiguration.JobCreationMode; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import com.google.common.collect.Lists; @@ -40,6 +41,7 @@ final class QueryRequestInfo { private final Boolean createSession; private final Boolean useQueryCache; private final Boolean useLegacySql; + private final JobCreationMode jobCreationMode; QueryRequestInfo(QueryJobConfiguration config) { this.config = config; @@ -55,6 +57,7 @@ final class QueryRequestInfo { this.createSession = config.createSession(); this.useLegacySql = config.useLegacySql(); this.useQueryCache = config.useQueryCache(); + this.jobCreationMode = config.getJobCreationMode(); } boolean isFastQuerySupported(JobId jobId) { @@ -116,6 +119,9 @@ QueryRequest toPb() { if (useQueryCache != null) { request.setUseQueryCache(useQueryCache); } + if (jobCreationMode != null) { + request.setJobCreationMode(jobCreationMode.toString()); + } return request; } @@ -134,6 +140,7 @@ public String toString() { .add("createSession", createSession) .add("useQueryCache", useQueryCache) .add("useLegacySql", useLegacySql) + .add("jobCreationMode", jobCreationMode) .toString(); } @@ -151,7 +158,8 @@ public int hashCode() { requestId, createSession, useQueryCache, - useLegacySql); + useLegacySql, + jobCreationMode); } @Override diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java index f4459d734a..0319a6a4dd 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java @@ -177,6 +177,12 @@ public abstract static class Builder public abstract Builder setTableConstraints(TableConstraints tableConstraints); + /** + * Set the configuration of a BigLake managed table. If not set, the table is not a BigLake + * managed table. + */ + public abstract Builder setBigLakeConfiguration(BigLakeConfiguration biglakeConfiguration); + /** Creates a {@code StandardTableDefinition} object. */ public abstract StandardTableDefinition build(); } @@ -300,6 +306,13 @@ public abstract static class Builder @Nullable public abstract TableConstraints getTableConstraints(); + /** + * [Optional] Specifies the configuration of a BigLake managed table. The value may be {@code + * null}. + */ + @Nullable + public abstract BigLakeConfiguration getBigLakeConfiguration(); + /** Returns a builder for a BigQuery standard table definition. */ public static Builder newBuilder() { return new AutoValue_StandardTableDefinition.Builder().setType(Type.TABLE); @@ -348,6 +361,9 @@ Table toPb() { if (getTableConstraints() != null) { tablePb.setTableConstraints(getTableConstraints().toPb()); } + if (getBigLakeConfiguration() != null) { + tablePb.setBiglakeConfiguration(getBigLakeConfiguration().toPb()); + } return tablePb; } @@ -409,6 +425,11 @@ static StandardTableDefinition fromPb(Table tablePb) { if (tablePb.getTableConstraints() != null) { builder.setTableConstraints(TableConstraints.fromPb(tablePb.getTableConstraints())); } + if (tablePb.getBiglakeConfiguration() != null) { + builder.setBigLakeConfiguration( + BigLakeConfiguration.fromPb(tablePb.getBiglakeConfiguration())); + } + return builder.setNumBytes(tablePb.getNumBytes()).setLocation(tablePb.getLocation()).build(); } } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigLakeConfigurationTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigLakeConfigurationTest.java new file mode 100644 index 0000000000..afb2b5b10a --- /dev/null +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/BigLakeConfigurationTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.bigquery; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BigLakeConfigurationTest { + + private static final String STORAGE_URI = "gs://storage-uri"; + private static final String FILE_FORMAT = "PARQUET"; + private static final String TABLE_FORMAT = "ICEBERG"; + private static final String CONNECTION_ID = "us.test-connection"; + + private static final BigLakeConfiguration BIG_LAKE_CONFIGURATION = + BigLakeConfiguration.newBuilder() + .setStorageUri(STORAGE_URI) + .setFileFormat(FILE_FORMAT) + .setTableFormat(TABLE_FORMAT) + .setConnectionId(CONNECTION_ID) + .build(); + private static final com.google.api.services.bigquery.model.BigLakeConfiguration + BIG_LAKE_CONFIGURATION_PB = + new com.google.api.services.bigquery.model.BigLakeConfiguration() + .setStorageUri(STORAGE_URI) + .setFileFormat(FILE_FORMAT) + .setTableFormat(TABLE_FORMAT) + .setConnectionId(CONNECTION_ID); + + @Test + public void testToBuilder() { + assertEquals(STORAGE_URI, BIG_LAKE_CONFIGURATION.getStorageUri()); + assertEquals(FILE_FORMAT, BIG_LAKE_CONFIGURATION.getFileFormat()); + assertEquals(TABLE_FORMAT, BIG_LAKE_CONFIGURATION.getTableFormat()); + assertEquals(CONNECTION_ID, BIG_LAKE_CONFIGURATION.getConnectionId()); + } + + @Test + public void testToPb() { + assertBigLakeConfiguration(BIG_LAKE_CONFIGURATION_PB, BIG_LAKE_CONFIGURATION.toPb()); + } + + @Test + public void testFromPb() { + assertBigLakeConfiguration( + BIG_LAKE_CONFIGURATION, BigLakeConfiguration.fromPb(BIG_LAKE_CONFIGURATION_PB)); + } + + private static void assertBigLakeConfiguration( + BigLakeConfiguration expected, BigLakeConfiguration actual) { + assertEquals(expected.getConnectionId(), actual.getConnectionId()); + assertEquals(expected.getTableFormat(), actual.getTableFormat()); + assertEquals(expected.getStorageUri(), actual.getStorageUri()); + assertEquals(expected.getFileFormat(), actual.getFileFormat()); + } + + private static void assertBigLakeConfiguration( + com.google.api.services.bigquery.model.BigLakeConfiguration expected, + com.google.api.services.bigquery.model.BigLakeConfiguration actual) { + assertEquals(expected.getConnectionId(), actual.getConnectionId()); + assertEquals(expected.getTableFormat(), actual.getTableFormat()); + assertEquals(expected.getStorageUri(), actual.getStorageUri()); + assertEquals(expected.getFileFormat(), actual.getFileFormat()); + } +} diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java index c91cbc2f30..df62b7dac8 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java @@ -58,6 +58,7 @@ public class DatasetInfoTest { private static final DatasetId DATASET_ID_COMPLETE = DatasetId.of("project", "dataset"); private static final EncryptionConfiguration DATASET_ENCRYPTION_CONFIGURATION = EncryptionConfiguration.newBuilder().setKmsKeyName("KMS_KEY_1").build(); + private static final String STORAGE_BILLING_MODEL = "LOGICAL"; private static final ExternalDatasetReference EXTERNAL_DATASET_REFERENCE = ExternalDatasetReference.newBuilder() @@ -79,6 +80,7 @@ public class DatasetInfoTest { .setLabels(LABELS) .setDefaultEncryptionConfiguration(DATASET_ENCRYPTION_CONFIGURATION) .setDefaultPartitionExpirationMs(DEFAULT_PARTITION__EXPIRATION) + .setStorageBillingModel(STORAGE_BILLING_MODEL) .build(); private static final DatasetInfo DATASET_INFO_COMPLETE = DATASET_INFO @@ -170,6 +172,7 @@ public void testBuilder() { assertEquals( EXTERNAL_DATASET_REFERENCE, DATASET_INFO_COMPLETE_WITH_EXTERNAL_DATASET_REFERENCE.getExternalDatasetReference()); + assertEquals(STORAGE_BILLING_MODEL, DATASET_INFO_COMPLETE.getStorageBillingModel()); } @Test @@ -190,6 +193,7 @@ public void testOf() { assertNull(datasetInfo.getDefaultPartitionExpirationMs()); assertTrue(datasetInfo.getLabels().isEmpty()); assertNull(datasetInfo.getExternalDatasetReference()); + assertNull(datasetInfo.getStorageBillingModel()); datasetInfo = DatasetInfo.of(DATASET_ID); assertEquals(DATASET_ID, datasetInfo.getDatasetId()); @@ -207,6 +211,7 @@ public void testOf() { assertNull(datasetInfo.getDefaultPartitionExpirationMs()); assertTrue(datasetInfo.getLabels().isEmpty()); assertNull(datasetInfo.getExternalDatasetReference()); + assertNull(datasetInfo.getStorageBillingModel()); } @Test @@ -243,5 +248,6 @@ private void compareDatasets(DatasetInfo expected, DatasetInfo value) { assertEquals( expected.getDefaultPartitionExpirationMs(), value.getDefaultPartitionExpirationMs()); assertEquals(expected.getExternalDatasetReference(), value.getExternalDatasetReference()); + assertEquals(expected.getStorageBillingModel(), value.getStorageBillingModel()); } } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java index b244cf2606..bc42976b23 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java @@ -66,6 +66,7 @@ public class DatasetTest { private static final String SELF_LINK = "http://bigquery/p/d"; private static final DatasetInfo DATASET_INFO = DatasetInfo.newBuilder(DATASET_ID).build(); private static final Field FIELD = Field.of("FieldName", LegacySQLTypeName.INTEGER); + private static final String STORAGE_BILLING_MODEL = "LOGICAL"; private static final StandardTableDefinition TABLE_DEFINITION = StandardTableDefinition.of(Schema.of(FIELD)); private static final ViewDefinition VIEW_DEFINITION = ViewDefinition.of("QUERY"); @@ -120,6 +121,7 @@ public void testBuilder() { .setLocation(LOCATION) .setSelfLink(SELF_LINK) .setLabels(LABELS) + .setStorageBillingModel(STORAGE_BILLING_MODEL) .build(); assertEquals(DATASET_ID, builtDataset.getDatasetId()); assertEquals(ACCESS_RULES, builtDataset.getAcl()); @@ -133,6 +135,7 @@ public void testBuilder() { assertEquals(LOCATION, builtDataset.getLocation()); assertEquals(SELF_LINK, builtDataset.getSelfLink()); assertEquals(LABELS, builtDataset.getLabels()); + assertEquals(STORAGE_BILLING_MODEL, builtDataset.getStorageBillingModel()); } @Test @@ -340,6 +343,7 @@ public void testExternalDatasetReference() { .setSelfLink(SELF_LINK) .setLabels(LABELS) .setExternalDatasetReference(EXTERNAL_DATASET_REFERENCE) + .setStorageBillingModel(STORAGE_BILLING_MODEL) .build(); assertEquals( EXTERNAL_DATASET_REFERENCE, @@ -369,5 +373,6 @@ private void compareDatasetInfo(DatasetInfo expected, DatasetInfo value) { assertEquals(expected.getDefaultTableLifetime(), value.getDefaultTableLifetime()); assertEquals(expected.getLastModified(), value.getLastModified()); assertEquals(expected.getExternalDatasetReference(), value.getExternalDatasetReference()); + assertEquals(expected.getStorageBillingModel(), value.getStorageBillingModel()); } } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java index 9a20219d66..f71e152e62 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java @@ -23,6 +23,7 @@ import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.QueryJobConfiguration.JobCreationMode; import com.google.cloud.bigquery.QueryJobConfiguration.Priority; import com.google.cloud.bigquery.TimePartitioning.Type; import com.google.common.collect.ImmutableList; @@ -110,6 +111,7 @@ public class QueryJobConfigurationTest { private static final Map NAME_PARAMETER = ImmutableMap.of("string", STRING_PARAMETER, "timestamp", TIMESTAMP_PARAMETER); private static final String PARAMETER_MODE = "POSITIONAL"; + private static final JobCreationMode JOB_CREATION_MODE = JobCreationMode.JOB_CREATION_OPTIONAL; private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION = QueryJobConfiguration.newBuilder(QUERY) .setUseQueryCache(USE_QUERY_CACHE) @@ -150,6 +152,8 @@ public class QueryJobConfigurationTest { .setPositionalParameters(ImmutableList.of()) .setNamedParameters(NAME_PARAMETER) .build(); + private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION_SET_JOB_CREATION_MODE = + QUERY_JOB_CONFIGURATION.toBuilder().setJobCreationMode(JOB_CREATION_MODE).build(); @Test public void testToBuilder() { @@ -230,6 +234,13 @@ public void testNamedParameter() { QUERY_JOB_CONFIGURATION_SET_NAME_PARAMETER.toBuilder().build()); } + @Test + public void testJobCreationMode() { + compareQueryJobConfiguration( + QUERY_JOB_CONFIGURATION_SET_JOB_CREATION_MODE, + QUERY_JOB_CONFIGURATION_SET_JOB_CREATION_MODE.toBuilder().build()); + } + private void compareQueryJobConfiguration( QueryJobConfiguration expected, QueryJobConfiguration value) { assertEquals(expected, value); diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestInfoTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestInfoTest.java index 456475597e..0d9464c768 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestInfoTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestInfoTest.java @@ -23,6 +23,7 @@ import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.SchemaUpdateOption; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.QueryJobConfiguration.JobCreationMode; import com.google.cloud.bigquery.QueryJobConfiguration.Priority; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -105,6 +106,8 @@ public class QueryRequestInfoTest { ImmutableList.of(STRING_PARAMETER, TIMESTAMP_PARAMETER); private static final Map NAME_PARAMETER = ImmutableMap.of("string", STRING_PARAMETER, "timestamp", TIMESTAMP_PARAMETER); + private static final JobCreationMode jobCreationModeRequired = + JobCreationMode.JOB_CREATION_REQUIRED; private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION = QueryJobConfiguration.newBuilder(QUERY) .setUseQueryCache(USE_QUERY_CACHE) @@ -131,6 +134,7 @@ public class QueryRequestInfoTest { .setConnectionProperties(CONNECTION_PROPERTIES) .setPositionalParameters(POSITIONAL_PARAMETER) .setMaxResults(100L) + .setJobCreationMode(jobCreationModeRequired) .build(); QueryRequestInfo REQUEST_INFO = new QueryRequestInfo(QUERY_JOB_CONFIGURATION); private static final QueryJobConfiguration QUERY_JOB_CONFIGURATION_SUPPORTED = @@ -194,5 +198,6 @@ private void compareQueryRequestInfo(QueryRequestInfo expected, QueryRequestInfo assertEquals(expectedQueryReq.getCreateSession(), actualQueryReq.getCreateSession()); assertEquals(expectedQueryReq.getUseQueryCache(), actualQueryReq.getUseQueryCache()); assertEquals(expectedQueryReq.getUseLegacySql(), actualQueryReq.getUseLegacySql()); + assertEquals(expectedQueryReq.get("jobCreationMode"), actualQueryReq.get("jobCreationMode")); } } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/StandardTableDefinitionTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/StandardTableDefinitionTest.java index df0e5d79b0..8fbe3cefe7 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/StandardTableDefinitionTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/StandardTableDefinitionTest.java @@ -65,6 +65,13 @@ public class StandardTableDefinitionTest { TimePartitioning.of(TimePartitioning.Type.DAY, 42); private static final Clustering CLUSTERING = Clustering.newBuilder().setFields(ImmutableList.of("Foo", "Bar")).build(); + private static final BigLakeConfiguration BIG_LAKE_CONFIGURATION = + BigLakeConfiguration.newBuilder() + .setConnectionId("us.connection-test") + .setTableFormat("ICEBERG") + .setFileFormat("PARQUET") + .setStorageUri("gs://java-bigquery-test/standard-table-def") + .build(); private static final StandardTableDefinition TABLE_DEFINITION = StandardTableDefinition.newBuilder() .setLocation(LOCATION) @@ -82,6 +89,7 @@ public class StandardTableDefinitionTest { .setSchema(TABLE_SCHEMA) .setTimePartitioning(TIME_PARTITIONING) .setClustering(CLUSTERING) + .setBigLakeConfiguration(BIG_LAKE_CONFIGURATION) .build(); @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 1ff8597455..8cada3e084 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 @@ -202,6 +202,7 @@ public class ITBigQueryTest { private static final String ROUTINE_DATASET = RemoteBigQueryHelper.generateDatasetName(); private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId(); private static final String RANDOM_ID = UUID.randomUUID().toString().substring(0, 8); + private static final String STORAGE_BILLING_MODEL = "LOGICAL"; private static final String CLOUD_SAMPLES_DATA = Optional.fromNullable(System.getenv("CLOUD_SAMPLES_DATA_BUCKET")).or("cloud-samples-data"); private static final Map LABELS = @@ -965,6 +966,7 @@ public void testGetDatasetWithSelectedFields() { assertNull(dataset.getLastModified()); assertNull(dataset.getLocation()); assertNull(dataset.getSelfLink()); + assertNull(dataset.getStorageBillingModel()); } @Test @@ -980,6 +982,7 @@ public void testUpdateDataset() { assertThat(dataset.getDatasetId().getDataset()).isEqualTo(OTHER_DATASET); assertThat(dataset.getDescription()).isEqualTo("Some Description"); assertThat(dataset.getLabels()).containsExactly("a", "b"); + assertThat(dataset.getStorageBillingModel()).isNull(); Map updateLabels = new HashMap<>(); updateLabels.put("x", "y"); @@ -990,9 +993,11 @@ public void testUpdateDataset() { .toBuilder() .setDescription("Updated Description") .setLabels(updateLabels) + .setStorageBillingModel("LOGICAL") .build()); assertThat(updatedDataset.getDescription()).isEqualTo("Updated Description"); assertThat(updatedDataset.getLabels()).containsExactly("x", "y"); + assertThat(updatedDataset.getStorageBillingModel()).isEqualTo("LOGICAL"); updatedDataset = bigquery.update(updatedDataset.toBuilder().setLabels(null).build()); assertThat(updatedDataset.getLabels()).isEmpty(); @@ -1022,6 +1027,7 @@ public void testUpdateDatasetWithSelectedFields() { assertNull(updatedDataset.getLastModified()); assertNull(updatedDataset.getLocation()); assertNull(updatedDataset.getSelfLink()); + assertNull(updatedDataset.getStorageBillingModel()); assertTrue(dataset.delete()); } @@ -1283,6 +1289,23 @@ public void testCreateTableWithConstraints() { bigquery.delete(tableId); } + @Test + public void testCreateDatasetWithSpecifiedStorageBillingModel() { + String billingModelDataset = RemoteBigQueryHelper.generateDatasetName(); + DatasetInfo info = + DatasetInfo.newBuilder(billingModelDataset) + .setDescription(DESCRIPTION) + .setStorageBillingModel(STORAGE_BILLING_MODEL) + .setLabels(LABELS) + .build(); + bigquery.create(info); + + Dataset dataset = bigquery.getDataset(DatasetId.of(billingModelDataset)); + assertEquals(STORAGE_BILLING_MODEL, dataset.getStorageBillingModel()); + + RemoteBigQueryHelper.forceDelete(bigquery, billingModelDataset); + } + @Test public void testCreateDatasetWithDefaultCollation() { String collationDataset = RemoteBigQueryHelper.generateDatasetName(); @@ -6165,4 +6188,30 @@ public void testAlreadyExistJobExceptionHandling() throws InterruptedException { } } } + + @Test + public void testStatelessQueries() throws InterruptedException { + // simulate setting the QUERY_PREVIEW_ENABLED environment variable + bigquery.getOptions().setQueryPreviewEnabled("TRUE"); + assertNull(executeSimpleQuery().getJobId()); + + // the flag should be case-insensitive + bigquery.getOptions().setQueryPreviewEnabled("tRuE"); + assertNull(executeSimpleQuery().getJobId()); + + // any other values won't enable optional job creation mode + bigquery.getOptions().setQueryPreviewEnabled("test_value"); + assertNotNull(executeSimpleQuery().getJobId()); + + // reset the flag + bigquery.getOptions().setQueryPreviewEnabled(null); + assertNotNull(executeSimpleQuery().getJobId()); + } + + private TableResult executeSimpleQuery() throws InterruptedException { + String query = "SELECT 1 as one"; + QueryJobConfiguration config = QueryJobConfiguration.newBuilder(query).build(); + TableResult result = bigquery.query(config); + return result; + } } diff --git a/owlbot.py b/owlbot.py index bf1878a29c..7a89db8ff2 100644 --- a/owlbot.py +++ b/owlbot.py @@ -18,6 +18,7 @@ java.common_templates(excludes=[ '.kokoro/nightly/samples.cfg', + '.kokoro/nightly/integration.cfg', '.kokoro/presubmit/samples.cfg', 'codecov.yaml', 'renovate.json', diff --git a/pom.xml b/pom.xml index 9def71c132..da800e6f2a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-bigquery-parent pom - 2.33.2 + 2.34.0 BigQuery Parent https://github.com/googleapis/java-bigquery @@ -14,7 +14,7 @@ com.google.cloud google-cloud-shared-config - 1.5.8 + 1.6.0 @@ -54,8 +54,8 @@ UTF-8 github google-cloud-bigquery-parent - v2-rev20230925-2.0.0 - 3.17.0 + v2-rev20231008-2.0.0 + 3.18.0 12.0.1 @@ -73,7 +73,7 @@ com.google.cloud google-cloud-bigquerystorage-bom - 2.44.0 + 2.44.1 pom import @@ -97,7 +97,7 @@ com.google.cloud google-cloud-datacatalog-bom - 1.33.0 + 1.35.0 pom import @@ -111,7 +111,7 @@ com.google.cloud google-cloud-bigquery - 2.33.2 + 2.34.0 @@ -155,19 +155,19 @@ com.google.cloud google-cloud-storage - 2.27.1 + 2.29.0 test com.google.cloud google-cloud-bigqueryconnection - 2.29.0 + 2.31.0 test com.google.api.grpc proto-google-cloud-bigqueryconnection-v1 - 2.29.0 + 2.31.0 test diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 0648fec10d..5f7509ff63 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.33.1 + 2.33.2 @@ -63,13 +63,13 @@ com.google.cloud google-cloud-bigtable - 2.27.4 + 2.29.0 test com.google.cloud google-cloud-bigqueryconnection - 2.29.0 + 2.31.0 test diff --git a/samples/native-image-sample/pom.xml b/samples/native-image-sample/pom.xml index 1f18d2c067..e5c84a3045 100644 --- a/samples/native-image-sample/pom.xml +++ b/samples/native-image-sample/pom.xml @@ -99,7 +99,7 @@ org.graalvm.buildtools junit-platform-native - 0.9.27 + 0.9.28 test @@ -111,7 +111,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.2 + 3.2.1 **/*IT @@ -121,7 +121,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.27 + 0.9.28 true com.example.bigquery.NativeImageBigquerySample diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 53288c26ee..caa1d2d20e 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -44,7 +44,7 @@ com.google.cloud google-cloud-bigquery - 2.33.2 + 2.34.0 @@ -61,13 +61,13 @@ com.google.cloud google-cloud-bigtable - 2.27.4 + 2.29.0 test com.google.cloud google-cloud-bigqueryconnection - 2.29.0 + 2.31.0 test diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 352e86adab..5a828edced 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -79,13 +79,13 @@ com.google.cloud google-cloud-bigtable - 2.27.4 + 2.29.0 test com.google.cloud google-cloud-bigqueryconnection - 2.29.0 + 2.31.0 test diff --git a/versions.txt b/versions.txt index 004398030c..d14c19ff96 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,4 @@ # Format: # module:released-version:current-version -google-cloud-bigquery:2.33.2:2.33.2 \ No newline at end of file +google-cloud-bigquery:2.34.0:2.34.0 \ No newline at end of file