diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/IndexUnusedReason.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/IndexUnusedReason.java new file mode 100644 index 0000000000..120e42e03d --- /dev/null +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/IndexUnusedReason.java @@ -0,0 +1,114 @@ +/* + * 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.api.services.bigquery.model.TableReference; +import com.google.auto.value.AutoValue; +import java.io.Serializable; +import javax.annotation.Nullable; + +@AutoValue +public abstract class IndexUnusedReason implements Serializable { + + @AutoValue.Builder + public abstract static class Builder { + + /** + * Specifies the name of the unused search index, if available. + * + * @param indexName + */ + public abstract Builder setIndexName(String indexName); + + /** + * Specifies the high-level reason for the scenario when no search index was used. + * + * @param code + */ + public abstract Builder setCode(String code); + + /** + * Free form human-readable reason for the scenario when no search index was used. + * + * @param message + */ + public abstract Builder setMessage(String message); + + /** + * Specifies the base table involved in the reason that no search index was used. + * + * @param tableReference + */ + public abstract Builder setBaseTable(TableReference tableReference); + + public abstract IndexUnusedReason build(); + } + + public abstract Builder toBuilder(); + + public static Builder newBuilder() { + return new AutoValue_IndexUnusedReason.Builder(); + } + + @Nullable + public abstract TableReference getBaseTable(); + + @Nullable + public abstract String getIndexName(); + + @Nullable + public abstract String getCode(); + + @Nullable + public abstract String getMessage(); + + com.google.api.services.bigquery.model.IndexUnusedReason toPb() { + com.google.api.services.bigquery.model.IndexUnusedReason indexUnusedReason = + new com.google.api.services.bigquery.model.IndexUnusedReason(); + if (getIndexName() != null) { + indexUnusedReason.setIndexName(indexUnusedReason.getIndexName()); + } + if (getCode() != null) { + indexUnusedReason.setCode(indexUnusedReason.getCode()); + } + if (getMessage() != null) { + indexUnusedReason.setMessage(indexUnusedReason.getMessage()); + } + if (getBaseTable() != null) { + indexUnusedReason.setBaseTable(indexUnusedReason.getBaseTable()); + } + return indexUnusedReason; + } + + static IndexUnusedReason fromPb( + com.google.api.services.bigquery.model.IndexUnusedReason indexUnusedReason) { + Builder builder = newBuilder(); + if (indexUnusedReason.getIndexName() != null) { + builder.setIndexName(indexUnusedReason.getIndexName()); + } + if (indexUnusedReason.getCode() != null) { + builder.setCode(indexUnusedReason.getCode()); + } + if (indexUnusedReason.getMessage() != null) { + builder.setMessage(indexUnusedReason.getMessage()); + } + if (indexUnusedReason.getBaseTable() != null) { + builder.setBaseTable(indexUnusedReason.getBaseTable()); + } + return builder.build(); + } +} diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java index 0ef1d1f947..e5d62c3d6f 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java @@ -340,6 +340,7 @@ public static class QueryStatistics extends JobStatistics { private final List queryPlan; private final List timeline; private final Schema schema; + private final SearchStats searchStats; private final List queryParameters; /** @@ -424,6 +425,7 @@ static final class Builder extends JobStatistics.Builder timeline; private Schema schema; private List queryParameters; + private SearchStats searchStats; private Builder() {} @@ -471,6 +473,9 @@ private Builder(com.google.api.services.bigquery.model.JobStatistics statisticsP if (statisticsPb.getQuery().getSchema() != null) { this.schema = Schema.fromPb(statisticsPb.getQuery().getSchema()); } + if (statisticsPb.getQuery().getSearchStatistics() != null) { + this.searchStats = SearchStats.fromPb(statisticsPb.getQuery().getSearchStatistics()); + } if (statisticsPb.getQuery().getDmlStats() != null) { this.dmlStats = DmlStats.fromPb(statisticsPb.getQuery().getDmlStats()); } @@ -572,6 +577,11 @@ Builder setSchema(Schema schema) { return self(); } + Builder setSearchStats(SearchStats searchStats) { + this.searchStats = searchStats; + return self(); + } + Builder setQueryParameters(List queryParameters) { this.queryParameters = queryParameters; return self(); @@ -603,6 +613,7 @@ private QueryStatistics(Builder builder) { this.queryPlan = builder.queryPlan; this.timeline = builder.timeline; this.schema = builder.schema; + this.searchStats = builder.searchStats; this.queryParameters = builder.queryParameters; } @@ -724,6 +735,10 @@ public Schema getSchema() { return schema; } + public SearchStats getSearchStats() { + return searchStats; + } + /** * Standard SQL only: Returns a list of undeclared query parameters detected during a dry run * validation. @@ -743,6 +758,7 @@ ToStringHelper toStringHelper() { .add("queryPlan", queryPlan) .add("timeline", timeline) .add("schema", schema) + .add("searchStats", searchStats) .add("queryParameters", queryParameters); } @@ -765,6 +781,7 @@ public final int hashCode() { totalBytesProcessed, queryPlan, schema, + searchStats, queryParameters); } @@ -807,6 +824,9 @@ com.google.api.services.bigquery.model.JobStatistics toPb() { if (schema != null) { queryStatisticsPb.setSchema(schema.toPb()); } + if (searchStats != null) { + queryStatisticsPb.setSearchStatistics(searchStats.toPb()); + } if (queryParameters != null) { queryStatisticsPb.setUndeclaredQueryParameters(queryParameters); } diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/SearchStats.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/SearchStats.java new file mode 100644 index 0000000000..c5329c8690 --- /dev/null +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/SearchStats.java @@ -0,0 +1,90 @@ +/* + * 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.api.services.bigquery.model.SearchStatistics; +import com.google.auto.value.AutoValue; +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +@AutoValue +public abstract class SearchStats implements Serializable { + + @AutoValue.Builder + public abstract static class Builder { + + /** + * Specifies index usage mode for the query. + * + * @param indexUsageMode, has three modes UNUSED, PARTIALLY_USED, and FULLY_USED + */ + public abstract Builder setIndexUsageMode(String indexUsageMode); + + /** + * When index_usage_mode is UNUSED or PARTIALLY_USED, this field explains why index was not used + * in all or part of the search query. If index_usage_mode is FULLY_USED, this field is not + * populated. + * + * @param indexUnusedReasons + */ + public abstract Builder setIndexUnusedReasons(List indexUnusedReasons); + + public abstract SearchStats build(); + } + + public abstract Builder toBuilder(); + + public static Builder newBuilder() { + return new AutoValue_SearchStats.Builder(); + } + + @Nullable + public abstract String getIndexUsageMode(); + + @Nullable + public abstract List getIndexUnusedReasons(); + + SearchStatistics toPb() { + SearchStatistics searchStatistics = new SearchStatistics(); + if (getIndexUsageMode() != null) { + searchStatistics.setIndexUsageMode(getIndexUsageMode()); + } + if (getIndexUnusedReasons() != null) { + searchStatistics.setIndexUnusedReason( + getIndexUnusedReasons().stream() + .map(IndexUnusedReason::toPb) + .collect(Collectors.toList())); + } + return searchStatistics; + } + + static SearchStats fromPb(SearchStatistics searchStatistics) { + Builder builder = newBuilder(); + if (searchStatistics.getIndexUsageMode() != null) { + builder.setIndexUsageMode(searchStatistics.getIndexUsageMode()); + } + if (searchStatistics.getIndexUnusedReason() != null) { + builder.setIndexUnusedReasons( + searchStatistics.getIndexUnusedReason().stream() + .map(IndexUnusedReason::fromPb) + .collect(Collectors.toList())); + } + return builder.build(); + } +}