From f32be5506ae8814cb70b977b0766b521aa836e55 Mon Sep 17 00:00:00 2001 From: Pablo Paglilla Date: Tue, 7 May 2024 11:00:43 -0300 Subject: [PATCH] Configure google-java-format through the Spotless plugin (#39) * Configure google-java-format with spotless plugin * Apply google-java-format codebase-wide * Reformat poms --- pom.xml | 414 +++++----- zetasql-toolkit-bigquery/pom.xml | 4 + .../bigquery/BigQueryAPIResourceProvider.java | 3 +- .../catalog/bigquery/BigQueryBuiltIns.java | 7 +- .../catalog/bigquery/BigQueryCatalog.java | 131 +-- .../catalog/bigquery/BigQueryReference.java | 1 - .../catalog/bigquery/BigQueryService.java | 3 +- .../LocalBigQueryResourceProvider.java | 171 ++-- .../options/BigQueryLanguageOptions.java | 292 +++---- .../BigQueryAPIResourceProviderTest.java | 15 +- .../catalog/bigquery/BigQueryCatalogTest.java | 68 +- zetasql-toolkit-core/pom.xml | 334 ++++---- .../com/google/zetasql/SimpleCatalogUtil.java | 23 +- .../zetasql/toolkit/AnalysisException.java | 5 +- .../zetasql/toolkit/AnalyzedStatement.java | 1 - .../zetasql/toolkit/AnalyzerExtensions.java | 14 +- .../com/google/zetasql/toolkit/Coercer.java | 693 +++++++++------- .../zetasql/toolkit/StatementRewriter.java | 750 +++++++++--------- .../toolkit/ZetaSQLToolkitAnalyzer.java | 182 +++-- .../toolkit/catalog/CatalogOperations.java | 103 ++- .../zetasql/toolkit/catalog/FunctionInfo.java | 3 +- .../toolkit/catalog/ProcedureInfo.java | 1 - .../catalog/basic/BasicCatalogWrapper.java | 13 +- .../CatalogResourceDoesNotExist.java | 1 - .../toolkit/catalog/io/CatalogResources.java | 9 +- .../catalog/io/JsonCatalogDeserializer.java | 362 +++++---- .../catalog/typeparser/ZetaSQLTypeParser.java | 10 +- .../toolkit/tools/lineage/ColumnEntity.java | 3 +- .../toolkit/tools/lineage/ColumnLineage.java | 3 +- .../tools/lineage/ColumnLineageExtractor.java | 140 ++-- .../tools/lineage/ExpressionParentFinder.java | 67 +- .../tools/lineage/ParentColumnFinder.java | 78 +- .../toolkit/tools/patch/ZetaSQLPatcher.java | 61 +- .../zetasql/toolkit/usage/UsageTracking.java | 3 +- .../toolkit/AnalyzerExtensionsTest.java | 17 +- .../toolkit/CatalogUpdaterVisitorTest.java | 22 +- .../google/zetasql/toolkit/CoercerTest.java | 52 +- .../zetasql/toolkit/ZetaSQLToolkitTest.java | 13 +- .../catalog/CatalogOperationsTest.java | 54 +- .../tools/patch/ZetaSQLPatcherTest.java | 15 +- .../toolkit/usage/UsageTrackingTest.java | 4 +- zetasql-toolkit-examples/pom.xml | 94 ++- .../AddResourcesToBigQueryCatalog.java | 6 +- .../AddResourcesToSpannerCatalog.java | 3 +- .../toolkit/examples/AnalyzeBigQuery.java | 19 +- .../toolkit/examples/AnalyzeCloudSpanner.java | 9 +- .../examples/AnalyzeWithoutCatalog.java | 8 +- .../examples/AnalyzingCreateStatements.java | 5 +- .../examples/ExtractColumnLevelLineage.java | 91 ++- .../examples/LoadTablesUsedInQuery.java | 5 +- zetasql-toolkit-spanner/pom.xml | 4 + .../spanner/LocalSpannerResourceProvider.java | 8 +- .../catalog/spanner/SpannerCatalog.java | 19 +- .../catalog/spanner/SpannerCatalogTest.java | 16 +- .../SpannerResourceProviderImplTest.java | 3 +- 55 files changed, 2298 insertions(+), 2137 deletions(-) diff --git a/pom.xml b/pom.xml index b97818f..86f481e 100644 --- a/pom.xml +++ b/pom.xml @@ -16,198 +16,230 @@ limitations under the License. --> - - 4.0.0 - - com.google.zetasql.toolkit - zetasql-toolkit - 0.5.0 - pom - - ${project.groupId}:${project.artifactId} - https://github.com/GoogleCloudPlatform/zetasql-toolkit - - The ZetaSQL Toolkit is a library that helps users use ZetaSQL Java API - to perform SQL analysis for multiple query engines, including - BigQuery and Cloud Spanner. - - - - scm:git:git@github.com:GoogleCloudPlatform/zetasql-toolkit.git - scm:git:git@github.com:GoogleCloudPlatform/zetasql-toolkit.git - git@github.com:GoogleCloudPlatform/zetasql-toolkit.git - HEAD + + 4.0.0 + + com.google.zetasql.toolkit + zetasql-toolkit + 0.5.0 + pom + + ${project.groupId}:${project.artifactId} + https://github.com/GoogleCloudPlatform/zetasql-toolkit + + The ZetaSQL Toolkit is a library that helps users use ZetaSQL Java API + to perform SQL analysis for multiple query engines, including + BigQuery and Cloud Spanner. + + + + zetasql-toolkit-core + zetasql-toolkit-bigquery + zetasql-toolkit-spanner + zetasql-toolkit-examples + + + + scm:git:git@github.com:GoogleCloudPlatform/zetasql-toolkit.git + + + scm:git:git@github.com:GoogleCloudPlatform/zetasql-toolkit.git + + git@github.com:GoogleCloudPlatform/zetasql-toolkit.git + HEAD - - - The Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - ppaglilla - Pablo Paglilla - ppaglilla@google.com - Google - http://www.google.com - - - - - 8 - 8 - UTF-8 - false - true - - 2024.03.1 - 26.37.0 - - 5.10.2 - 4.11.0 - - 3.3.0 - 3.5.0 - 3.1.0 - 3.1.0 - - - - zetasql-toolkit-core - zetasql-toolkit-bigquery - zetasql-toolkit-spanner - zetasql-toolkit-examples - - - - - - com.google.cloud - libraries-bom - ${google.cloud.libraries.version} - pom - import - - - org.junit - junit-bom - ${junit.version} - pom - import - - - com.google.zetasql - zetasql-client - ${zetasql.version} - - - com.google.zetasql - zetasql-types - ${zetasql.version} - - - com.google.zetasql - zetasql-jni-channel - ${zetasql.version} - - - org.mockito - mockito-core - ${mockito.version} - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - - - - - - - - - org.apache.maven.plugins - maven-gpg-plugin - - - - - - org.apache.maven.plugins - maven-source-plugin - ${maven.source.plugin.version} - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.version} - - - - - - - - sonatype-nexus-staging - Sonatype Nexus Staging - https://oss.sonatype.org/service/local/staging/deploy/maven2 - - - sonatype-nexus-snapshots - Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots - - - - - - default - - true - - - - release - - + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + ppaglilla + Pablo Paglilla + ppaglilla@google.com + Google + http://www.google.com + + + + + 8 + 8 + UTF-8 + false + true + + 2024.03.1 + 26.37.0 + + 5.10.2 + 4.11.0 + + 3.3.0 + 3.5.0 + 3.1.0 + 3.1.0 + 2.30.0 + + + + + + com.google.cloud + libraries-bom + ${google.cloud.libraries.version} + pom + import + + + org.junit + junit-bom + ${junit.version} + pom + import + + + com.google.zetasql + zetasql-client + ${zetasql.version} + + + com.google.zetasql + zetasql-types + ${zetasql.version} + + + com.google.zetasql + zetasql-jni-channel + ${zetasql.version} + + + org.mockito + mockito-core + ${mockito.version} + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + + + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.version} + + + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + + + + check + apply + + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + + + 1.7 + + + + + + + + + + + + + sonatype-nexus-staging + Sonatype Nexus Staging + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots + + + + + + default + + true + + + + release + + diff --git a/zetasql-toolkit-bigquery/pom.xml b/zetasql-toolkit-bigquery/pom.xml index dc2d9b0..3a592ac 100644 --- a/zetasql-toolkit-bigquery/pom.xml +++ b/zetasql-toolkit-bigquery/pom.xml @@ -146,6 +146,10 @@ org.apache.maven.plugins maven-gpg-plugin + + com.diffplug.spotless + spotless-maven-plugin + diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProvider.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProvider.java index 6186506..e0af58b 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProvider.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProvider.java @@ -202,7 +202,8 @@ private List extractColumnsFromBigQueryTable(Table table) { if (table.getDefinition().getSchema() == null) { // BigQuery tables can have no columns, in which case the schema is null - // One such table is bigquery-public-data.america_health_rankings.america_health_rankings + // One such table is + // bigquery-public-data.america_health_rankings.america_health_rankings return ImmutableList.of(); } diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryBuiltIns.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryBuiltIns.java index 4643c28..540e125 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryBuiltIns.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryBuiltIns.java @@ -199,9 +199,10 @@ class BigQueryBuiltIns { public static void addToCatalog(SimpleCatalog catalog) { TYPE_ALIASES.forEach(catalog::addType); FUNCTIONS.forEach(catalog::addFunction); - PROCEDURES.forEach(procedure -> - CatalogOperations.createProcedureInCatalog( - catalog, procedure.getFullName(), procedure, CreateMode.CREATE_DEFAULT)); + PROCEDURES.forEach( + procedure -> + CatalogOperations.createProcedureInCatalog( + catalog, procedure.getFullName(), procedure, CreateMode.CREATE_DEFAULT)); } private BigQueryBuiltIns() {} diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalog.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalog.java index db10976..6907d28 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalog.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalog.java @@ -57,7 +57,6 @@ public class BigQueryCatalog implements CatalogWrapper { * default credentials. * * @deprecated Use {@link BigQueryCatalog#usingBigQueryAPI(String)} - * * @param defaultProjectId The BigQuery default project id, queries are assumed to be running on * this project */ @@ -71,7 +70,6 @@ public BigQueryCatalog(String defaultProjectId) { * BigQuery Client. * * @deprecated Use {@link BigQueryCatalog#usingBigQueryAPI(String, BigQuery)} - * * @param defaultProjectId The BigQuery default project id, queries are assumed to be running on * this project * @param bigQueryClient The BigQuery client to use for accessing the API @@ -144,8 +142,8 @@ public static BigQueryCatalog usingBigQueryAPI(String defaultProjectId, BigQuery } /** - * Constructs a BigQueryCatalog that can use the resources in the provided - * {@link CatalogResources} object. + * Constructs a BigQueryCatalog that can use the resources in the provided {@link + * CatalogResources} object. * * @param defaultProjectId The BigQuery default project id, queries are assumed to be running on * this project @@ -159,8 +157,7 @@ public static BigQueryCatalog usingResources(String defaultProjectId, CatalogRes } /** - * Returns whether the table referenced by the provided reference exists - * in the catalog. + * Returns whether the table referenced by the provided reference exists in the catalog. * * @param reference The reference to check (e.g. "project.dataset.table") * @return Whether there's a table in the catalog referenced by the reference @@ -170,8 +167,7 @@ private boolean tableExistsInCatalog(String reference) { } /** - * Returns whether the function referenced by the provided reference exists - * in the catalog. + * Returns whether the function referenced by the provided reference exists in the catalog. * * @param reference The reference to check (e.g. "project.dataset.function") * @return Whether there's a function in the catalog referenced by the reference @@ -186,8 +182,7 @@ private boolean functionExistsInCatalog(String reference) { } /** - * Returns whether the TVF referenced by the provided reference exists - * in the catalog. + * Returns whether the TVF referenced by the provided reference exists in the catalog. * * @param reference The reference to check (e.g. "project.dataset.tvf") * @return Whether there's a TVF in the catalog referenced by the reference @@ -197,8 +192,7 @@ private boolean tvfExistsInCatalog(String reference) { } /** - * Returns whether the procedure referenced by the provided reference exists - * in the catalog. + * Returns whether the procedure referenced by the provided reference exists in the catalog. * * @param reference The reference to check (e.g. "project.dataset.procedure") * @return Whether there's a procedure in the catalog referenced by the reference @@ -275,14 +269,14 @@ private void validateNamePathForCreation( * Returns the names a resource referenced by the provided string should have in the underlying * {@link SimpleCatalog}. * - *

If the reference is qualified, its complete name in the catalog will be in the form of - * "project.dataset.resource". If the resource is in the default project, an additional name - * in the form of "dataset.resource" will be returned. + *

If the reference is qualified, its complete name in the catalog will be in the form of + * "project.dataset.resource". If the resource is in the default project, an additional name in + * the form of "dataset.resource" will be returned. * - *

For unqualified resource (e.g. temporary tables), the name will be used as-is. + *

For unqualified resource (e.g. temporary tables), the name will be used as-is. * * @param reference The string used to reference the resource (e.g. "project.dataset.table", - * "dataset.function", "tableName") + * "dataset.function", "tableName") * @return The list of names the resource should have in the underlying {@link SimpleCatalog} */ private List buildCatalogNamesForResource(String reference) { @@ -292,8 +286,7 @@ private List buildCatalogNamesForResource(String reference) { return ImmutableList.of(reference); } - BigQueryReference parsedReference = - BigQueryReference.from(this.defaultProjectId, reference); + BigQueryReference parsedReference = BigQueryReference.from(this.defaultProjectId, reference); boolean isInDefaultProject = parsedReference.getProjectId().equalsIgnoreCase(this.defaultProjectId); @@ -319,9 +312,9 @@ private CatalogResourceAlreadyExists addCaseInsensitivityWarning( /** * {@inheritDoc} * - *

If the table is not temporary and is in the catalog's default project, it will be - * registered twice. Once as "project.dataset.table" and once as "dataset.table". That way, - * queries that omit the project when referencing the table can be analyzed. + *

If the table is not temporary and is in the catalog's default project, it will be registered + * twice. Once as "project.dataset.table" and once as "dataset.table". That way, queries that omit + * the project when referencing the table can be analyzed. * * @throws BigQueryCreateError if a pre-create validation fails * @throws CatalogResourceAlreadyExists if the table already exists and CreateMode != @@ -334,14 +327,14 @@ public void register(SimpleTable table, CreateMode createMode, CreateScope creat ImmutableList.of(CreateScope.CREATE_DEFAULT_SCOPE, CreateScope.CREATE_TEMP), table.getFullName(), "table"); - this.validateNamePathForCreation( - ImmutableList.of(table.getFullName()), createScope, "table"); + this.validateNamePathForCreation(ImmutableList.of(table.getFullName()), createScope, "table"); List catalogNamesForTable = buildCatalogNamesForResource(table.getFullName()); try { - catalogNamesForTable.forEach(catalogName -> - CatalogOperations.createTableInCatalog(catalog, catalogName, table, createMode)); + catalogNamesForTable.forEach( + catalogName -> + CatalogOperations.createTableInCatalog(catalog, catalogName, table, createMode)); } catch (CatalogResourceAlreadyExists alreadyExists) { throw this.addCaseInsensitivityWarning(alreadyExists); } @@ -350,7 +343,7 @@ public void register(SimpleTable table, CreateMode createMode, CreateScope creat /** * {@inheritDoc} * - *

If the function is not temporary and is in the catalog's default project, it will be + *

If the function is not temporary and is in the catalog's default project, it will be * registered twice. Once as "project.dataset.function" and once as "dataset.function". That way, * queries that omit the project when referencing the table can be analyzed. * @@ -383,9 +376,10 @@ public void register(FunctionInfo function, CreateMode createMode, CreateScope c List catalogNamesForFunction = buildCatalogNamesForResource(fullName); try { - catalogNamesForFunction.forEach(catalogName -> - CatalogOperations.createFunctionInCatalog( - catalog, catalogName, resolvedFunction, createMode)); + catalogNamesForFunction.forEach( + catalogName -> + CatalogOperations.createFunctionInCatalog( + catalog, catalogName, resolvedFunction, createMode)); } catch (CatalogResourceAlreadyExists alreadyExists) { throw this.addCaseInsensitivityWarning(alreadyExists); } @@ -394,7 +388,7 @@ public void register(FunctionInfo function, CreateMode createMode, CreateScope c /** * {@inheritDoc} * - *

If the function in the catalog's default project, it will be registered twice. Once as + *

If the function in the catalog's default project, it will be registered twice. Once as * "project.dataset.function" and once as "dataset.function". That way, queries that omit the * project when referencing the table can be analyzed. * @@ -417,8 +411,10 @@ public void register(TVFInfo tvfInfo, CreateMode createMode, CreateScope createS List catalogNamesForFunction = buildCatalogNamesForResource(fullName); try { - catalogNamesForFunction.forEach(catalogName -> - CatalogOperations.createTVFInCatalog(catalog, catalogName, resolvedTvfInfo, createMode)); + catalogNamesForFunction.forEach( + catalogName -> + CatalogOperations.createTVFInCatalog( + catalog, catalogName, resolvedTvfInfo, createMode)); } catch (CatalogResourceAlreadyExists alreadyExists) { throw this.addCaseInsensitivityWarning(alreadyExists); } @@ -427,7 +423,7 @@ public void register(TVFInfo tvfInfo, CreateMode createMode, CreateScope createS /** * {@inheritDoc} * - *

If the procedure in the catalog's default project, it will be registered twice. Once as + *

If the procedure in the catalog's default project, it will be registered twice. Once as * "project.dataset.procedure" and once as "dataset.procedure". That way, queries that omit the * project when referencing the table can be analyzed. * @@ -447,9 +443,10 @@ public void register( List catalogNamesForProcedure = buildCatalogNamesForResource(fullName); try { - catalogNamesForProcedure.forEach(catalogName -> - CatalogOperations.createProcedureInCatalog( - catalog, catalogName, procedureInfo, createMode)); + catalogNamesForProcedure.forEach( + catalogName -> + CatalogOperations.createProcedureInCatalog( + catalog, catalogName, procedureInfo, createMode)); } catch (CatalogResourceAlreadyExists alreadyExists) { throw this.addCaseInsensitivityWarning(alreadyExists); } @@ -470,13 +467,13 @@ public void register(Constant constant) { "BigQuery constants cannot be qualified, was: " + fullName); } - boolean constantExists = this.catalog.getConstantList() - .stream() - .anyMatch(existingConstant -> existingConstant.getFullName().equalsIgnoreCase(fullName)); + boolean constantExists = + this.catalog.getConstantList().stream() + .anyMatch( + existingConstant -> existingConstant.getFullName().equalsIgnoreCase(fullName)); if (constantExists) { - throw new CatalogResourceAlreadyExists( - fullName, "Constant " + fullName + "already exists"); + throw new CatalogResourceAlreadyExists(fullName, "Constant " + fullName + "already exists"); } this.catalog.addConstant(constant); @@ -486,32 +483,32 @@ public void register(Constant constant) { public void removeTable(String tableReference) { List catalogNamesForTable = buildCatalogNamesForResource(tableReference); - catalogNamesForTable.forEach(catalogName -> - CatalogOperations.deleteTableFromCatalog(catalog, catalogName)); + catalogNamesForTable.forEach( + catalogName -> CatalogOperations.deleteTableFromCatalog(catalog, catalogName)); } @Override public void removeFunction(String functionReference) { List catalogNamesForFunction = buildCatalogNamesForResource(functionReference); - catalogNamesForFunction.forEach(catalogName -> - CatalogOperations.deleteFunctionFromCatalog(catalog, catalogName)); + catalogNamesForFunction.forEach( + catalogName -> CatalogOperations.deleteFunctionFromCatalog(catalog, catalogName)); } @Override public void removeTVF(String functionReference) { List catalogNamesForFunction = buildCatalogNamesForResource(functionReference); - catalogNamesForFunction.forEach(catalogName -> - CatalogOperations.deleteTVFFromCatalog(catalog, catalogName)); + catalogNamesForFunction.forEach( + catalogName -> CatalogOperations.deleteTVFFromCatalog(catalog, catalogName)); } @Override public void removeProcedure(String procedureReference) { List catalogNamesForProcedure = buildCatalogNamesForResource(procedureReference); - catalogNamesForProcedure.forEach(catalogName -> - CatalogOperations.deleteProcedureFromCatalog(catalog, catalogName)); + catalogNamesForProcedure.forEach( + catalogName -> CatalogOperations.deleteProcedureFromCatalog(catalog, catalogName)); } /** @@ -521,9 +518,10 @@ public void removeProcedure(String procedureReference) { */ @Override public void addTables(List tableReferences) { - List tablesNotInCatalog = tableReferences.stream() - .filter(tableRef -> !this.tableExistsInCatalog(tableRef)) - .collect(Collectors.toList()); + List tablesNotInCatalog = + tableReferences.stream() + .filter(tableRef -> !this.tableExistsInCatalog(tableRef)) + .collect(Collectors.toList()); this.bigQueryResourceProvider .getTables(this.defaultProjectId, tablesNotInCatalog) @@ -592,9 +590,10 @@ public void addAllTablesUsedInQuery(String query, AnalyzerOptions options) { */ @Override public void addFunctions(List functionReferences) { - List functionsNotInCatalog = functionReferences.stream() - .filter(functionRef -> !this.functionExistsInCatalog(functionRef)) - .collect(Collectors.toList()); + List functionsNotInCatalog = + functionReferences.stream() + .filter(functionRef -> !this.functionExistsInCatalog(functionRef)) + .collect(Collectors.toList()); this.bigQueryResourceProvider .getFunctions(this.defaultProjectId, functionsNotInCatalog) @@ -683,9 +682,10 @@ public void addAllFunctionsUsedInQuery(String query) { */ @Override public void addTVFs(List functionReferences) { - List functionsNotInCatalog = functionReferences.stream() - .filter(functionRef -> !this.tvfExistsInCatalog(functionRef)) - .collect(Collectors.toList()); + List functionsNotInCatalog = + functionReferences.stream() + .filter(functionRef -> !this.tvfExistsInCatalog(functionRef)) + .collect(Collectors.toList()); this.bigQueryResourceProvider .getTVFs(this.defaultProjectId, functionsNotInCatalog) @@ -770,9 +770,10 @@ public void addAllTVFsUsedInQuery(String query) { */ @Override public void addProcedures(List procedureReferences) { - List proceduresNotInCatalog = procedureReferences.stream() - .filter(procedureRef -> !this.procedureExistsInCatalog(procedureRef)) - .collect(Collectors.toList()); + List proceduresNotInCatalog = + procedureReferences.stream() + .filter(procedureRef -> !this.procedureExistsInCatalog(procedureRef)) + .collect(Collectors.toList()); this.bigQueryResourceProvider .getProcedures(this.defaultProjectId, proceduresNotInCatalog) @@ -834,9 +835,9 @@ public void addAllProceduresUsedInQuery(String query) { * Adds all the resources used in the provided query to this catalog. Includes tables, functions, * TVFs and procedures. * - *

It calls {@link #addAllTablesUsedInQuery(String, AnalyzerOptions)}, - * {@link #addAllFunctionsUsedInQuery(String)}, {@link #addAllTVFsUsedInQuery(String)} - * and {@link #addAllProceduresUsedInQuery(String)}. + *

It calls {@link #addAllTablesUsedInQuery(String, AnalyzerOptions)}, {@link + * #addAllFunctionsUsedInQuery(String)}, {@link #addAllTVFsUsedInQuery(String)} and {@link + * #addAllProceduresUsedInQuery(String)}. * * @param query The SQL query from which to get the resources that should be added to the catalog * @param options The ZetaSQL AnalyzerOptions to use when extracting the resource names from the diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryReference.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryReference.java index 90c3ea3..563aa03 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryReference.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryReference.java @@ -143,5 +143,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(projectId.toLowerCase(), datasetId, resourceName); } - } diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryService.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryService.java index 8ec0e08..d2d6520 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryService.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryService.java @@ -173,8 +173,7 @@ private Table fetchTableFromAPI(BigQueryReference reference) { * Fetches a BigQuery Table from the API. Results are cached indefinitely. * * @param projectId The default BigQuery project id - * @param tableReference The String referencing the table, - * e.g. "project.dataset.table" + * @param tableReference The String referencing the table, e.g. "project.dataset.table" * @return A Result<Table> containing the fetched Table */ public Result fetchTable(String projectId, String tableReference) { diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/LocalBigQueryResourceProvider.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/LocalBigQueryResourceProvider.java index 47b1b01..f4fdb39 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/LocalBigQueryResourceProvider.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/catalog/bigquery/LocalBigQueryResourceProvider.java @@ -48,35 +48,35 @@ private Set parseBigQueryReferences( public List getTables(String projectId, List tableReferences) { Set references = parseBigQueryReferences(projectId, tableReferences); - return catalogResources.getTables() - .stream() - .filter(table -> { - BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); - return references.contains(tableReference); - }) + return catalogResources.getTables().stream() + .filter( + table -> { + BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); + return references.contains(tableReference); + }) .collect(Collectors.toList()); } @Override public List getAllTablesInDataset(String projectId, String datasetName) { - return catalogResources.getTables() - .stream() - .filter(table -> { - BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); - return tableReference.getProjectId().equalsIgnoreCase(projectId) - && tableReference.getDatasetId().equals(datasetName); - }) + return catalogResources.getTables().stream() + .filter( + table -> { + BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); + return tableReference.getProjectId().equalsIgnoreCase(projectId) + && tableReference.getDatasetId().equals(datasetName); + }) .collect(Collectors.toList()); } @Override public List getAllTablesInProject(String projectId) { - return catalogResources.getTables() - .stream() - .filter(table -> { - BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); - return tableReference.getProjectId().equalsIgnoreCase(projectId); - }) + return catalogResources.getTables().stream() + .filter( + table -> { + BigQueryReference tableReference = BigQueryReference.from(projectId, table.getName()); + return tableReference.getProjectId().equalsIgnoreCase(projectId); + }) .collect(Collectors.toList()); } @@ -84,38 +84,38 @@ public List getAllTablesInProject(String projectId) { public List getFunctions(String projectId, List functionReferences) { Set references = parseBigQueryReferences(projectId, functionReferences); - return catalogResources.getFunctions() - .stream() - .filter(function -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, function.getFullName()); - return references.contains(functionReference); - }) + return catalogResources.getFunctions().stream() + .filter( + function -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, function.getFullName()); + return references.contains(functionReference); + }) .collect(Collectors.toList()); } @Override public List getAllFunctionsInDataset(String projectId, String datasetName) { - return catalogResources.getFunctions() - .stream() - .filter(function -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, function.getFullName()); - return functionReference.getProjectId().equalsIgnoreCase(projectId) - && functionReference.getDatasetId().equals(datasetName); - }) + return catalogResources.getFunctions().stream() + .filter( + function -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, function.getFullName()); + return functionReference.getProjectId().equalsIgnoreCase(projectId) + && functionReference.getDatasetId().equals(datasetName); + }) .collect(Collectors.toList()); } @Override public List getAllFunctionsInProject(String projectId) { - return catalogResources.getFunctions() - .stream() - .filter(function -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, function.getFullName()); - return functionReference.getProjectId().equalsIgnoreCase(projectId); - }) + return catalogResources.getFunctions().stream() + .filter( + function -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, function.getFullName()); + return functionReference.getProjectId().equalsIgnoreCase(projectId); + }) .collect(Collectors.toList()); } @@ -123,38 +123,38 @@ public List getAllFunctionsInProject(String projectId) { public List getTVFs(String projectId, List functionReferences) { Set references = parseBigQueryReferences(projectId, functionReferences); - return catalogResources.getTVFs() - .stream() - .filter(tvf -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, tvf.getFullName()); - return references.contains(functionReference); - }) + return catalogResources.getTVFs().stream() + .filter( + tvf -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, tvf.getFullName()); + return references.contains(functionReference); + }) .collect(Collectors.toList()); } @Override public List getAllTVFsInDataset(String projectId, String datasetName) { - return catalogResources.getTVFs() - .stream() - .filter(tvf -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, tvf.getFullName()); - return functionReference.getProjectId().equalsIgnoreCase(projectId) - && functionReference.getDatasetId().equals(datasetName); - }) + return catalogResources.getTVFs().stream() + .filter( + tvf -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, tvf.getFullName()); + return functionReference.getProjectId().equalsIgnoreCase(projectId) + && functionReference.getDatasetId().equals(datasetName); + }) .collect(Collectors.toList()); } @Override public List getAllTVFsInProject(String projectId) { - return catalogResources.getTVFs() - .stream() - .filter(tvf -> { - BigQueryReference functionReference = - BigQueryReference.from(projectId, tvf.getFullName()); - return functionReference.getProjectId().equalsIgnoreCase(projectId); - }) + return catalogResources.getTVFs().stream() + .filter( + tvf -> { + BigQueryReference functionReference = + BigQueryReference.from(projectId, tvf.getFullName()); + return functionReference.getProjectId().equalsIgnoreCase(projectId); + }) .collect(Collectors.toList()); } @@ -162,39 +162,38 @@ public List getAllTVFsInProject(String projectId) { public List getProcedures(String projectId, List procedureReferences) { Set references = parseBigQueryReferences(projectId, procedureReferences); - return catalogResources.getProcedures() - .stream() - .filter(procedure -> { - BigQueryReference procedureReference = - BigQueryReference.from(projectId, procedure.getFullName()); - return references.contains(procedureReference); - }) + return catalogResources.getProcedures().stream() + .filter( + procedure -> { + BigQueryReference procedureReference = + BigQueryReference.from(projectId, procedure.getFullName()); + return references.contains(procedureReference); + }) .collect(Collectors.toList()); } @Override public List getAllProceduresInDataset(String projectId, String datasetName) { - return catalogResources.getProcedures() - .stream() - .filter(procedure -> { - BigQueryReference procedureReference = - BigQueryReference.from(projectId, procedure.getFullName()); - return procedureReference.getProjectId().equalsIgnoreCase(projectId) - && procedureReference.getDatasetId().equals(datasetName); - }) + return catalogResources.getProcedures().stream() + .filter( + procedure -> { + BigQueryReference procedureReference = + BigQueryReference.from(projectId, procedure.getFullName()); + return procedureReference.getProjectId().equalsIgnoreCase(projectId) + && procedureReference.getDatasetId().equals(datasetName); + }) .collect(Collectors.toList()); } @Override public List getAllProceduresInProject(String projectId) { - return catalogResources.getProcedures() - .stream() - .filter(procedure -> { - BigQueryReference procedureReference = - BigQueryReference.from(projectId, procedure.getFullName()); - return procedureReference.getProjectId().equalsIgnoreCase(projectId); - }) + return catalogResources.getProcedures().stream() + .filter( + procedure -> { + BigQueryReference procedureReference = + BigQueryReference.from(projectId, procedure.getFullName()); + return procedureReference.getProjectId().equalsIgnoreCase(projectId); + }) .collect(Collectors.toList()); } - } diff --git a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/options/BigQueryLanguageOptions.java b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/options/BigQueryLanguageOptions.java index 061bb40..d50c830 100644 --- a/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/options/BigQueryLanguageOptions.java +++ b/zetasql-toolkit-bigquery/src/main/java/com/google/zetasql/toolkit/options/BigQueryLanguageOptions.java @@ -25,155 +25,155 @@ public class BigQueryLanguageOptions { - private static final LanguageOptions languageOptions = new LanguageOptions(); + private static final LanguageOptions languageOptions = new LanguageOptions(); - static { - languageOptions.setNameResolutionMode(NameResolutionMode.NAME_RESOLUTION_DEFAULT); - languageOptions.setProductMode(ProductMode.PRODUCT_EXTERNAL); + static { + languageOptions.setNameResolutionMode(NameResolutionMode.NAME_RESOLUTION_DEFAULT); + languageOptions.setProductMode(ProductMode.PRODUCT_EXTERNAL); - languageOptions.setEnabledLanguageFeatures( - ImmutableSet.of( - LanguageFeature.FEATURE_ALLOW_MISSING_PATH_EXPRESSION_IN_ALTER_DDL, - LanguageFeature.FEATURE_ALTER_COLUMN_SET_DATA_TYPE, - LanguageFeature.FEATURE_ALTER_TABLE_RENAME_COLUMN, - LanguageFeature.FEATURE_ANALYTIC_FUNCTIONS, - LanguageFeature.FEATURE_ANONYMIZATION, - LanguageFeature.FEATURE_BIGNUMERIC_TYPE, - LanguageFeature.FEATURE_CBRT_FUNCTIONS, - LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_CONNECTION, - LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_PARTITION_COLUMNS, - LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_TABLE_ELEMENT_LIST, - LanguageFeature.FEATURE_CREATE_MATERIALIZED_VIEW_CLUSTER_BY, - LanguageFeature.FEATURE_CREATE_MATERIALIZED_VIEW_PARTITION_BY, - LanguageFeature.FEATURE_CREATE_SNAPSHOT_TABLE, - LanguageFeature.FEATURE_CREATE_TABLE_AS_SELECT_COLUMN_LIST, - LanguageFeature.FEATURE_CREATE_TABLE_CLONE, - LanguageFeature.FEATURE_CREATE_TABLE_CLUSTER_BY, - LanguageFeature.FEATURE_CREATE_TABLE_COPY, - LanguageFeature.FEATURE_CREATE_TABLE_FIELD_ANNOTATIONS, - LanguageFeature.FEATURE_CREATE_TABLE_FUNCTION, - LanguageFeature.FEATURE_CREATE_TABLE_LIKE, - LanguageFeature.FEATURE_CREATE_TABLE_NOT_NULL, - LanguageFeature.FEATURE_CREATE_TABLE_PARTITION_BY, - LanguageFeature.FEATURE_CREATE_VIEW_WITH_COLUMN_LIST, - LanguageFeature.FEATURE_DML_UPDATE_WITH_JOIN, - LanguageFeature.FEATURE_ENCRYPTION, - LanguageFeature.FEATURE_FOREIGN_KEYS, - LanguageFeature.FEATURE_GEOGRAPHY, - LanguageFeature.FEATURE_GROUP_BY_ROLLUP, - LanguageFeature.FEATURE_INTERVAL_TYPE, - LanguageFeature.FEATURE_INVERSE_TRIG_FUNCTIONS, - LanguageFeature.FEATURE_JSON_ARRAY_FUNCTIONS, - LanguageFeature.FEATURE_JSON_TYPE, - LanguageFeature.FEATURE_JSON_VALUE_EXTRACTION_FUNCTIONS, - LanguageFeature.FEATURE_NAMED_ARGUMENTS, - LanguageFeature.FEATURE_NUMERIC_TYPE, - LanguageFeature.FEATURE_PARAMETERIZED_TYPES, - LanguageFeature.FEATURE_PARAMETERS_IN_GRANTEE_LIST, - LanguageFeature.FEATURE_ROUND_WITH_ROUNDING_MODE, - LanguageFeature.FEATURE_TABLESAMPLE, - LanguageFeature.FEATURE_TABLE_VALUED_FUNCTIONS, - LanguageFeature.FEATURE_TEMPLATE_FUNCTIONS, - LanguageFeature.FEATURE_TIMESTAMP_NANOS, - LanguageFeature.FEATURE_TIME_BUCKET_FUNCTIONS, - LanguageFeature.FEATURE_UNENFORCED_PRIMARY_KEYS, - LanguageFeature.FEATURE_V_1_1_HAVING_IN_AGGREGATE, - LanguageFeature.FEATURE_V_1_1_LIMIT_IN_AGGREGATE, - LanguageFeature.FEATURE_V_1_1_NULL_HANDLING_MODIFIER_IN_AGGREGATE, - LanguageFeature.FEATURE_V_1_1_NULL_HANDLING_MODIFIER_IN_ANALYTIC, - LanguageFeature.FEATURE_V_1_1_ORDER_BY_IN_AGGREGATE, - LanguageFeature.FEATURE_V_1_1_SELECT_STAR_EXCEPT_REPLACE, - LanguageFeature.FEATURE_V_1_1_WITH_ON_SUBQUERY, - LanguageFeature.FEATURE_V_1_2_CIVIL_TIME, - LanguageFeature.FEATURE_V_1_2_SAFE_FUNCTION_CALL, - LanguageFeature.FEATURE_V_1_2_WEEK_WITH_WEEKDAY, - LanguageFeature.FEATURE_V_1_3_ADDITIONAL_STRING_FUNCTIONS, - LanguageFeature.FEATURE_V_1_3_ALLOW_DASHES_IN_TABLE_NAME, - LanguageFeature.FEATURE_V_1_3_ALLOW_REGEXP_EXTRACT_OPTIONALS, - LanguageFeature.FEATURE_V_1_3_ANNOTATION_FRAMEWORK, - LanguageFeature.FEATURE_V_1_3_CASE_STMT, - LanguageFeature.FEATURE_V_1_3_COLLATION_SUPPORT, - LanguageFeature.FEATURE_V_1_3_COLUMN_DEFAULT_VALUE, - LanguageFeature.FEATURE_V_1_3_CONCAT_MIXED_TYPES, - LanguageFeature.FEATURE_V_1_3_DATE_ARITHMETICS, - LanguageFeature.FEATURE_V_1_3_DATE_TIME_CONSTRUCTORS, - LanguageFeature.FEATURE_V_1_3_DECIMAL_ALIAS, - LanguageFeature.FEATURE_V_1_3_EXTENDED_DATE_TIME_SIGNATURES, - LanguageFeature.FEATURE_V_1_3_EXTENDED_GEOGRAPHY_PARSERS, - LanguageFeature.FEATURE_V_1_3_FORMAT_IN_CAST, - LanguageFeature.FEATURE_V_1_3_FOR_IN, - LanguageFeature.FEATURE_V_1_3_IS_DISTINCT, - LanguageFeature.FEATURE_V_1_3_LIKE_ANY_SOME_ALL, - LanguageFeature.FEATURE_V_1_3_NULLS_FIRST_LAST_IN_ORDER_BY, - LanguageFeature.FEATURE_V_1_3_OMIT_INSERT_COLUMN_LIST, - LanguageFeature.FEATURE_V_1_3_PIVOT, - LanguageFeature.FEATURE_V_1_3_QUALIFY, - LanguageFeature.FEATURE_V_1_3_REMOTE_FUNCTION, - LanguageFeature.FEATURE_V_1_3_REPEAT, - LanguageFeature.FEATURE_V_1_3_SCRIPT_LABEL, - LanguageFeature.FEATURE_V_1_3_UNNEST_AND_FLATTEN_ARRAYS, - LanguageFeature.FEATURE_V_1_3_UNPIVOT, - LanguageFeature.FEATURE_V_1_3_WITH_GROUP_ROWS, - LanguageFeature.FEATURE_V_1_3_WITH_RECURSIVE, - LanguageFeature.FEATURE_V_1_4_ARRAY_AGGREGATION_FUNCTIONS, - LanguageFeature.FEATURE_V_1_4_REMOTE_MODEL, - LanguageFeature.FEATURE_V_1_4_GROUPING_BUILTIN, - LanguageFeature.FEATURE_V_1_4_GROUPING_SETS, - LanguageFeature.FEATURE_V_1_4_GROUP_BY_ALL)); + languageOptions.setEnabledLanguageFeatures( + ImmutableSet.of( + LanguageFeature.FEATURE_ALLOW_MISSING_PATH_EXPRESSION_IN_ALTER_DDL, + LanguageFeature.FEATURE_ALTER_COLUMN_SET_DATA_TYPE, + LanguageFeature.FEATURE_ALTER_TABLE_RENAME_COLUMN, + LanguageFeature.FEATURE_ANALYTIC_FUNCTIONS, + LanguageFeature.FEATURE_ANONYMIZATION, + LanguageFeature.FEATURE_BIGNUMERIC_TYPE, + LanguageFeature.FEATURE_CBRT_FUNCTIONS, + LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_CONNECTION, + LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_PARTITION_COLUMNS, + LanguageFeature.FEATURE_CREATE_EXTERNAL_TABLE_WITH_TABLE_ELEMENT_LIST, + LanguageFeature.FEATURE_CREATE_MATERIALIZED_VIEW_CLUSTER_BY, + LanguageFeature.FEATURE_CREATE_MATERIALIZED_VIEW_PARTITION_BY, + LanguageFeature.FEATURE_CREATE_SNAPSHOT_TABLE, + LanguageFeature.FEATURE_CREATE_TABLE_AS_SELECT_COLUMN_LIST, + LanguageFeature.FEATURE_CREATE_TABLE_CLONE, + LanguageFeature.FEATURE_CREATE_TABLE_CLUSTER_BY, + LanguageFeature.FEATURE_CREATE_TABLE_COPY, + LanguageFeature.FEATURE_CREATE_TABLE_FIELD_ANNOTATIONS, + LanguageFeature.FEATURE_CREATE_TABLE_FUNCTION, + LanguageFeature.FEATURE_CREATE_TABLE_LIKE, + LanguageFeature.FEATURE_CREATE_TABLE_NOT_NULL, + LanguageFeature.FEATURE_CREATE_TABLE_PARTITION_BY, + LanguageFeature.FEATURE_CREATE_VIEW_WITH_COLUMN_LIST, + LanguageFeature.FEATURE_DML_UPDATE_WITH_JOIN, + LanguageFeature.FEATURE_ENCRYPTION, + LanguageFeature.FEATURE_FOREIGN_KEYS, + LanguageFeature.FEATURE_GEOGRAPHY, + LanguageFeature.FEATURE_GROUP_BY_ROLLUP, + LanguageFeature.FEATURE_INTERVAL_TYPE, + LanguageFeature.FEATURE_INVERSE_TRIG_FUNCTIONS, + LanguageFeature.FEATURE_JSON_ARRAY_FUNCTIONS, + LanguageFeature.FEATURE_JSON_TYPE, + LanguageFeature.FEATURE_JSON_VALUE_EXTRACTION_FUNCTIONS, + LanguageFeature.FEATURE_NAMED_ARGUMENTS, + LanguageFeature.FEATURE_NUMERIC_TYPE, + LanguageFeature.FEATURE_PARAMETERIZED_TYPES, + LanguageFeature.FEATURE_PARAMETERS_IN_GRANTEE_LIST, + LanguageFeature.FEATURE_ROUND_WITH_ROUNDING_MODE, + LanguageFeature.FEATURE_TABLESAMPLE, + LanguageFeature.FEATURE_TABLE_VALUED_FUNCTIONS, + LanguageFeature.FEATURE_TEMPLATE_FUNCTIONS, + LanguageFeature.FEATURE_TIMESTAMP_NANOS, + LanguageFeature.FEATURE_TIME_BUCKET_FUNCTIONS, + LanguageFeature.FEATURE_UNENFORCED_PRIMARY_KEYS, + LanguageFeature.FEATURE_V_1_1_HAVING_IN_AGGREGATE, + LanguageFeature.FEATURE_V_1_1_LIMIT_IN_AGGREGATE, + LanguageFeature.FEATURE_V_1_1_NULL_HANDLING_MODIFIER_IN_AGGREGATE, + LanguageFeature.FEATURE_V_1_1_NULL_HANDLING_MODIFIER_IN_ANALYTIC, + LanguageFeature.FEATURE_V_1_1_ORDER_BY_IN_AGGREGATE, + LanguageFeature.FEATURE_V_1_1_SELECT_STAR_EXCEPT_REPLACE, + LanguageFeature.FEATURE_V_1_1_WITH_ON_SUBQUERY, + LanguageFeature.FEATURE_V_1_2_CIVIL_TIME, + LanguageFeature.FEATURE_V_1_2_SAFE_FUNCTION_CALL, + LanguageFeature.FEATURE_V_1_2_WEEK_WITH_WEEKDAY, + LanguageFeature.FEATURE_V_1_3_ADDITIONAL_STRING_FUNCTIONS, + LanguageFeature.FEATURE_V_1_3_ALLOW_DASHES_IN_TABLE_NAME, + LanguageFeature.FEATURE_V_1_3_ALLOW_REGEXP_EXTRACT_OPTIONALS, + LanguageFeature.FEATURE_V_1_3_ANNOTATION_FRAMEWORK, + LanguageFeature.FEATURE_V_1_3_CASE_STMT, + LanguageFeature.FEATURE_V_1_3_COLLATION_SUPPORT, + LanguageFeature.FEATURE_V_1_3_COLUMN_DEFAULT_VALUE, + LanguageFeature.FEATURE_V_1_3_CONCAT_MIXED_TYPES, + LanguageFeature.FEATURE_V_1_3_DATE_ARITHMETICS, + LanguageFeature.FEATURE_V_1_3_DATE_TIME_CONSTRUCTORS, + LanguageFeature.FEATURE_V_1_3_DECIMAL_ALIAS, + LanguageFeature.FEATURE_V_1_3_EXTENDED_DATE_TIME_SIGNATURES, + LanguageFeature.FEATURE_V_1_3_EXTENDED_GEOGRAPHY_PARSERS, + LanguageFeature.FEATURE_V_1_3_FORMAT_IN_CAST, + LanguageFeature.FEATURE_V_1_3_FOR_IN, + LanguageFeature.FEATURE_V_1_3_IS_DISTINCT, + LanguageFeature.FEATURE_V_1_3_LIKE_ANY_SOME_ALL, + LanguageFeature.FEATURE_V_1_3_NULLS_FIRST_LAST_IN_ORDER_BY, + LanguageFeature.FEATURE_V_1_3_OMIT_INSERT_COLUMN_LIST, + LanguageFeature.FEATURE_V_1_3_PIVOT, + LanguageFeature.FEATURE_V_1_3_QUALIFY, + LanguageFeature.FEATURE_V_1_3_REMOTE_FUNCTION, + LanguageFeature.FEATURE_V_1_3_REPEAT, + LanguageFeature.FEATURE_V_1_3_SCRIPT_LABEL, + LanguageFeature.FEATURE_V_1_3_UNNEST_AND_FLATTEN_ARRAYS, + LanguageFeature.FEATURE_V_1_3_UNPIVOT, + LanguageFeature.FEATURE_V_1_3_WITH_GROUP_ROWS, + LanguageFeature.FEATURE_V_1_3_WITH_RECURSIVE, + LanguageFeature.FEATURE_V_1_4_ARRAY_AGGREGATION_FUNCTIONS, + LanguageFeature.FEATURE_V_1_4_REMOTE_MODEL, + LanguageFeature.FEATURE_V_1_4_GROUPING_BUILTIN, + LanguageFeature.FEATURE_V_1_4_GROUPING_SETS, + LanguageFeature.FEATURE_V_1_4_GROUP_BY_ALL)); - languageOptions.setSupportedStatementKinds( - ImmutableSet.of( - ResolvedNodeKind.RESOLVED_ADD_CONSTRAINT_ACTION, - ResolvedNodeKind.RESOLVED_ALTER_ENTITY_STMT, - ResolvedNodeKind.RESOLVED_ALTER_MATERIALIZED_VIEW_STMT, - ResolvedNodeKind.RESOLVED_ALTER_MODEL_STMT, - ResolvedNodeKind.RESOLVED_ALTER_SCHEMA_STMT, - ResolvedNodeKind.RESOLVED_ALTER_TABLE_STMT, - ResolvedNodeKind.RESOLVED_ALTER_VIEW_STMT, - ResolvedNodeKind.RESOLVED_ASSERT_STMT, - ResolvedNodeKind.RESOLVED_ASSIGNMENT_STMT, - ResolvedNodeKind.RESOLVED_AUX_LOAD_DATA_STMT, - ResolvedNodeKind.RESOLVED_BEGIN_STMT, - ResolvedNodeKind.RESOLVED_CALL_STMT, - ResolvedNodeKind.RESOLVED_COMMIT_STMT, - ResolvedNodeKind.RESOLVED_CREATE_ENTITY_STMT, - ResolvedNodeKind.RESOLVED_CREATE_EXTERNAL_TABLE_STMT, - ResolvedNodeKind.RESOLVED_CREATE_FUNCTION_STMT, - ResolvedNodeKind.RESOLVED_CREATE_INDEX_STMT, - ResolvedNodeKind.RESOLVED_CREATE_MATERIALIZED_VIEW_STMT, - ResolvedNodeKind.RESOLVED_CREATE_MODEL_STMT, - ResolvedNodeKind.RESOLVED_CREATE_PROCEDURE_STMT, - ResolvedNodeKind.RESOLVED_CREATE_ROW_ACCESS_POLICY_STMT, - ResolvedNodeKind.RESOLVED_CREATE_SCHEMA_STMT, - ResolvedNodeKind.RESOLVED_CREATE_SNAPSHOT_TABLE_STMT, - ResolvedNodeKind.RESOLVED_CREATE_TABLE_AS_SELECT_STMT, - ResolvedNodeKind.RESOLVED_CREATE_TABLE_FUNCTION_STMT, - ResolvedNodeKind.RESOLVED_CREATE_TABLE_STMT, - ResolvedNodeKind.RESOLVED_CREATE_VIEW_STMT, - ResolvedNodeKind.RESOLVED_DELETE_STMT, - ResolvedNodeKind.RESOLVED_DROP_CONSTRAINT_ACTION, - ResolvedNodeKind.RESOLVED_DROP_FUNCTION_STMT, - ResolvedNodeKind.RESOLVED_DROP_MATERIALIZED_VIEW_STMT, - ResolvedNodeKind.RESOLVED_DROP_ROW_ACCESS_POLICY_STMT, - ResolvedNodeKind.RESOLVED_DROP_SNAPSHOT_TABLE_STMT, - ResolvedNodeKind.RESOLVED_DROP_STMT, - ResolvedNodeKind.RESOLVED_DROP_TABLE_FUNCTION_STMT, - ResolvedNodeKind.RESOLVED_EXECUTE_IMMEDIATE_STMT, - ResolvedNodeKind.RESOLVED_EXPORT_DATA_STMT, - ResolvedNodeKind.RESOLVED_EXPORT_MODEL_STMT, - ResolvedNodeKind.RESOLVED_GRANT_STMT, - ResolvedNodeKind.RESOLVED_INSERT_STMT, - ResolvedNodeKind.RESOLVED_MERGE_STMT, - ResolvedNodeKind.RESOLVED_QUERY_STMT, - ResolvedNodeKind.RESOLVED_REVOKE_STMT, - ResolvedNodeKind.RESOLVED_ROLLBACK_STMT, - ResolvedNodeKind.RESOLVED_TRUNCATE_STMT, - ResolvedNodeKind.RESOLVED_UPDATE_STMT)); + languageOptions.setSupportedStatementKinds( + ImmutableSet.of( + ResolvedNodeKind.RESOLVED_ADD_CONSTRAINT_ACTION, + ResolvedNodeKind.RESOLVED_ALTER_ENTITY_STMT, + ResolvedNodeKind.RESOLVED_ALTER_MATERIALIZED_VIEW_STMT, + ResolvedNodeKind.RESOLVED_ALTER_MODEL_STMT, + ResolvedNodeKind.RESOLVED_ALTER_SCHEMA_STMT, + ResolvedNodeKind.RESOLVED_ALTER_TABLE_STMT, + ResolvedNodeKind.RESOLVED_ALTER_VIEW_STMT, + ResolvedNodeKind.RESOLVED_ASSERT_STMT, + ResolvedNodeKind.RESOLVED_ASSIGNMENT_STMT, + ResolvedNodeKind.RESOLVED_AUX_LOAD_DATA_STMT, + ResolvedNodeKind.RESOLVED_BEGIN_STMT, + ResolvedNodeKind.RESOLVED_CALL_STMT, + ResolvedNodeKind.RESOLVED_COMMIT_STMT, + ResolvedNodeKind.RESOLVED_CREATE_ENTITY_STMT, + ResolvedNodeKind.RESOLVED_CREATE_EXTERNAL_TABLE_STMT, + ResolvedNodeKind.RESOLVED_CREATE_FUNCTION_STMT, + ResolvedNodeKind.RESOLVED_CREATE_INDEX_STMT, + ResolvedNodeKind.RESOLVED_CREATE_MATERIALIZED_VIEW_STMT, + ResolvedNodeKind.RESOLVED_CREATE_MODEL_STMT, + ResolvedNodeKind.RESOLVED_CREATE_PROCEDURE_STMT, + ResolvedNodeKind.RESOLVED_CREATE_ROW_ACCESS_POLICY_STMT, + ResolvedNodeKind.RESOLVED_CREATE_SCHEMA_STMT, + ResolvedNodeKind.RESOLVED_CREATE_SNAPSHOT_TABLE_STMT, + ResolvedNodeKind.RESOLVED_CREATE_TABLE_AS_SELECT_STMT, + ResolvedNodeKind.RESOLVED_CREATE_TABLE_FUNCTION_STMT, + ResolvedNodeKind.RESOLVED_CREATE_TABLE_STMT, + ResolvedNodeKind.RESOLVED_CREATE_VIEW_STMT, + ResolvedNodeKind.RESOLVED_DELETE_STMT, + ResolvedNodeKind.RESOLVED_DROP_CONSTRAINT_ACTION, + ResolvedNodeKind.RESOLVED_DROP_FUNCTION_STMT, + ResolvedNodeKind.RESOLVED_DROP_MATERIALIZED_VIEW_STMT, + ResolvedNodeKind.RESOLVED_DROP_ROW_ACCESS_POLICY_STMT, + ResolvedNodeKind.RESOLVED_DROP_SNAPSHOT_TABLE_STMT, + ResolvedNodeKind.RESOLVED_DROP_STMT, + ResolvedNodeKind.RESOLVED_DROP_TABLE_FUNCTION_STMT, + ResolvedNodeKind.RESOLVED_EXECUTE_IMMEDIATE_STMT, + ResolvedNodeKind.RESOLVED_EXPORT_DATA_STMT, + ResolvedNodeKind.RESOLVED_EXPORT_MODEL_STMT, + ResolvedNodeKind.RESOLVED_GRANT_STMT, + ResolvedNodeKind.RESOLVED_INSERT_STMT, + ResolvedNodeKind.RESOLVED_MERGE_STMT, + ResolvedNodeKind.RESOLVED_QUERY_STMT, + ResolvedNodeKind.RESOLVED_REVOKE_STMT, + ResolvedNodeKind.RESOLVED_ROLLBACK_STMT, + ResolvedNodeKind.RESOLVED_TRUNCATE_STMT, + ResolvedNodeKind.RESOLVED_UPDATE_STMT)); - languageOptions.enableReservableKeyword("QUALIFY"); - } + languageOptions.enableReservableKeyword("QUALIFY"); + } - public static LanguageOptions get() { - return languageOptions; - } + public static LanguageOptions get() { + return languageOptions; + } } diff --git a/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProviderTest.java b/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProviderTest.java index 7e124bf..2392e72 100644 --- a/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProviderTest.java +++ b/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryAPIResourceProviderTest.java @@ -65,8 +65,7 @@ Table createMockTable(boolean timePartitioned) { Field.of("col1", StandardSQLTypeName.INT64), Field.newBuilder("col2", StandardSQLTypeName.STRING).setMode(Mode.REPEATED).build(), Field.of( - "col3", StandardSQLTypeName.STRUCT, - Field.of("field1", StandardSQLTypeName.INT64))); + "col3", StandardSQLTypeName.STRUCT, Field.of("field1", StandardSQLTypeName.INT64))); StandardTableDefinition.Builder tableDefinitionBuilder = StandardTableDefinition.newBuilder(); tableDefinitionBuilder.setSchema(Schema.of(fields)); @@ -74,7 +73,8 @@ Table createMockTable(boolean timePartitioned) { if (timePartitioned) { TimePartitioning timePartitioning = TimePartitioning.newBuilder(TimePartitioning.Type.DAY) - .setField(null) // A null field means the table in ingestion-time partitioned + .setField(null) // A null field means the table in ingestion-time + // partitioned .build(); tableDefinitionBuilder.setTimePartitioning(timePartitioning); } @@ -110,7 +110,8 @@ void testGetTables() { List expectedSchemaForMockTable = expectedColumnsForMockTable(); - List tables = bigqueryResourceProvider.getTables("project", ImmutableList.of("reference")); + List tables = + bigqueryResourceProvider.getTables("project", ImmutableList.of("reference")); assertEquals(1, tables.size()); assertTrue( @@ -124,7 +125,8 @@ void testGetTimePartitionedTable() { when(bigQueryServiceMock.fetchTable(anyString(), anyString())) .thenReturn(Result.success(mockTable)); - List tables = bigqueryResourceProvider.getTables("project", ImmutableList.of("reference")); + List tables = + bigqueryResourceProvider.getTables("project", ImmutableList.of("reference")); assertEquals(1, tables.size()); @@ -308,7 +310,8 @@ void testGetTVFs() { FunctionSignature expectedSignatureForMockTVF = expectedSignatureForMockTVF(); TVFRelation expectedOutputSchemaForMockTVF = expectedOutputSchemaForMockTVF(); - List functions = bigqueryResourceProvider.getTVFs("project", ImmutableList.of("reference")); + List functions = + bigqueryResourceProvider.getTVFs("project", ImmutableList.of("reference")); assertEquals(1, functions.size()); assertTrue( diff --git a/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalogTest.java b/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalogTest.java index 7906bf9..059e6ec 100644 --- a/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalogTest.java +++ b/zetasql-toolkit-bigquery/src/test/java/com/google/zetasql/toolkit/catalog/bigquery/BigQueryCatalogTest.java @@ -43,7 +43,6 @@ import com.google.zetasql.toolkit.catalog.TVFInfo; import com.google.zetasql.toolkit.catalog.bigquery.exceptions.InvalidBigQueryReference; import com.google.zetasql.toolkit.catalog.exceptions.CatalogResourceAlreadyExists; -import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -63,7 +62,9 @@ public class BigQueryCatalogTest { .setNamePath(ImmutableList.of(testProjectId, "dataset", "exampletvf")) .setSignature( new FunctionSignature( - new FunctionArgumentType(SignatureArgumentKind.ARG_TYPE_RELATION), ImmutableList.of(), -1)) + new FunctionArgumentType(SignatureArgumentKind.ARG_TYPE_RELATION), + ImmutableList.of(), + -1)) .setOutputSchema( TVFRelation.createValueTableBased(TypeFactory.createSimpleType(TypeKind.TYPE_STRING))) .build(); @@ -83,13 +84,12 @@ void init() { } private SimpleTable buildExampleTable(String tableRef) { - SimpleTable table = new SimpleTable( - tableRef, - ImmutableList.of( - new SimpleColumn( - tableRef, - "col1", - TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); + SimpleTable table = + new SimpleTable( + tableRef, + ImmutableList.of( + new SimpleColumn( + tableRef, "col1", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); table.setFullName(tableRef); return table; } @@ -117,8 +117,7 @@ private Table assertTableExists(BigQueryCatalog catalog, String tableRef) { assertDoesNotThrow( () -> underlyingCatalog.findTable(tablePath), - String.format( - "Expected table %s to exist", tableRef)); + String.format("Expected table %s to exist", tableRef)); try { return underlyingCatalog.findTable(tablePath); @@ -187,14 +186,12 @@ void testRegisterInvalidTableName() { @Test void testRegisterTableFromDefaultProject() { - SimpleTable table = + SimpleTable table = new SimpleTable( "example", ImmutableList.of( new SimpleColumn( - "example", - "col1", - TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); + "example", "col1", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); table.setFullName(String.format("%s.dataset.example", this.testProjectId)); this.bigQueryCatalog.register( @@ -210,14 +207,12 @@ void testRegisterTableFromDefaultProject() { @Test void testRegisterTableFromNonDefaultProject() { - SimpleTable table = + SimpleTable table = new SimpleTable( "example", ImmutableList.of( new SimpleColumn( - "example", - "col1", - TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); + "example", "col1", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); table.setFullName("another-project-id.dataset.example"); this.bigQueryCatalog.register( @@ -232,8 +227,7 @@ void testRemoveTable() { String tableRef = String.format("%s.dataset.example", testProjectId); SimpleTable table = buildExampleTable(tableRef); - bigQueryCatalog.register( - table, CreateMode.CREATE_DEFAULT, CreateScope.CREATE_DEFAULT_SCOPE); + bigQueryCatalog.register(table, CreateMode.CREATE_DEFAULT, CreateScope.CREATE_DEFAULT_SCOPE); assertTableExists(bigQueryCatalog, tableRef); assertTableExists(bigQueryCatalog, "dataset.example"); @@ -249,18 +243,18 @@ void testReplaceTable() { String tableRef = String.format("%s.dataset.example", testProjectId); SimpleTable table = buildExampleTable(tableRef); - SimpleTable replacement = new SimpleTable(tableRef, ImmutableList.of( - new SimpleColumn(tableRef, "newCol", - TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); + SimpleTable replacement = + new SimpleTable( + tableRef, + ImmutableList.of( + new SimpleColumn( + tableRef, "newCol", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); - bigQueryCatalog.register( - table, CreateMode.CREATE_DEFAULT, CreateScope.CREATE_DEFAULT_SCOPE); + bigQueryCatalog.register(table, CreateMode.CREATE_DEFAULT, CreateScope.CREATE_DEFAULT_SCOPE); // Replace the table and validate it has been replaced bigQueryCatalog.register( - replacement, - CreateMode.CREATE_OR_REPLACE, - CreateScope.CREATE_DEFAULT_SCOPE); + replacement, CreateMode.CREATE_OR_REPLACE, CreateScope.CREATE_DEFAULT_SCOPE); Table foundTable = assertTableExists(this.bigQueryCatalog, tableRef); @@ -282,9 +276,7 @@ void testTableAlreadyExists() { CatalogResourceAlreadyExists.class, () -> this.bigQueryCatalog.register( - table, - CreateMode.CREATE_DEFAULT, - CreateScope.CREATE_DEFAULT_SCOPE), + table, CreateMode.CREATE_DEFAULT, CreateScope.CREATE_DEFAULT_SCOPE), "Expected fail creating table that already exists"); } @@ -301,8 +293,7 @@ void testAddTablesByName() { bigQueryCatalog.addTables(ImmutableList.of(table.getFullName())); // Verify the BigQueryCatalog got the tables from the BigQueryResourceProvider - verify(bigQueryResourceProviderMock, times(1)) - .getTables(anyString(), anyList()); + verify(bigQueryResourceProviderMock, times(1)).getTables(anyString(), anyList()); // Verify the test table was added to the catalog assertTableExists(bigQueryCatalog, tableRef); @@ -318,8 +309,7 @@ void testAddAllTablesInDataset() { bigQueryCatalog.addAllTablesInDataset(testProjectId, "dataset"); - verify(bigQueryResourceProviderMock, times(1)) - .getAllTablesInDataset(anyString(), anyString()); + verify(bigQueryResourceProviderMock, times(1)).getAllTablesInDataset(anyString(), anyString()); assertTableExists(bigQueryCatalog, tableRef); } @@ -334,8 +324,7 @@ void testAddAllTablesInProject() { bigQueryCatalog.addAllTablesInProject(testProjectId); - verify(bigQueryResourceProviderMock, times(1)) - .getAllTablesInProject(anyString()); + verify(bigQueryResourceProviderMock, times(1)).getAllTablesInProject(anyString()); assertTableExists(bigQueryCatalog, tableRef); } @@ -352,8 +341,7 @@ void testRegisterFunction() { assertDoesNotThrow( () -> underlyingCatalog.findFunction(function.getNamePath()), String.format( - "Expected function to exist at path %s", - String.join(".", function.getNamePath()))); + "Expected function to exist at path %s", String.join(".", function.getNamePath()))); } @Test diff --git a/zetasql-toolkit-core/pom.xml b/zetasql-toolkit-core/pom.xml index 63e5ca1..6d62146 100644 --- a/zetasql-toolkit-core/pom.xml +++ b/zetasql-toolkit-core/pom.xml @@ -16,173 +16,181 @@ limitations under the License. --> - - 4.0.0 + + 4.0.0 - - com.google.zetasql.toolkit - zetasql-toolkit - 0.5.0 - ../pom.xml - - - zetasql-toolkit-core + + com.google.zetasql.toolkit + zetasql-toolkit 0.5.0 - ${project.groupId}:${project.artifactId} + ../pom.xml + + + zetasql-toolkit-core + 0.5.0 + ${project.groupId}:${project.artifactId} - - ${project.version} - UTF-8 - false - 4.9.3 - 1.1.0 - 3.3.0 - + + ${project.version} + UTF-8 + false + 4.9.3 + 1.1.0 + 3.3.0 + - - - com.google.zetasql - zetasql-client - - - com.google.protobuf - protobuf-javalite - - - io.grpc - grpc-stub - - - io.grpc - grpc-context - - - io.grpc - grpc-core - - - io.grpc - grpc-api - - - - - com.google.zetasql - zetasql-types - - - com.google.zetasql - zetasql-jni-channel - - - com.google.protobuf - protobuf-javalite - - - io.grpc - grpc-stub - - - io.grpc - grpc-context - - - io.grpc - grpc-core - - - io.grpc - grpc-api - - - - - org.antlr - antlr4-runtime - ${antlr4.version} - - - com.google.cloud - google-cloud-spanner - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-core - test - - - org.mockito - mockito-junit-jupiter - test - - + + + com.google.zetasql + zetasql-client + + + com.google.protobuf + protobuf-javalite + + + io.grpc + grpc-stub + + + io.grpc + grpc-context + + + io.grpc + grpc-core + + + io.grpc + grpc-api + + + + + com.google.zetasql + zetasql-types + + + com.google.zetasql + zetasql-jni-channel + + + com.google.protobuf + protobuf-javalite + + + io.grpc + grpc-stub + + + io.grpc + grpc-context + + + io.grpc + grpc-core + + + io.grpc + grpc-api + + + + + org.antlr + antlr4-runtime + ${antlr4.version} + + + com.google.cloud + google-cloud-spanner + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + + - - - - org.antlr - antlr4-maven-plugin - ${antlr4.version} - - - - antlr4 - - antlr - - - - - org.codehaus.mojo - properties-maven-plugin - ${properties.maven.plugin.version} - - - generate-resources - - write-project-properties - - - ${project.build.outputDirectory}/zetasql-toolkit-core.properties - - - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven.jar.plugin.version} - - - test - - test-jar - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - org.apache.maven.plugins - maven-source-plugin - - - org.apache.maven.plugins - maven-javadoc-plugin - - - org.apache.maven.plugins - maven-gpg-plugin - - - + + + + org.antlr + antlr4-maven-plugin + ${antlr4.version} + + + + antlr4 + + antlr + + + + + org.codehaus.mojo + properties-maven-plugin + ${properties.maven.plugin.version} + + + generate-resources + + write-project-properties + + + + ${project.build.outputDirectory}/zetasql-toolkit-core.properties + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + test + + test-jar + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + com.diffplug.spotless + spotless-maven-plugin + + + \ No newline at end of file diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/SimpleCatalogUtil.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/SimpleCatalogUtil.java index 15eefe1..aa26a7c 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/SimpleCatalogUtil.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/SimpleCatalogUtil.java @@ -16,17 +16,16 @@ package com.google.zetasql; -/** - * Only public to make it possible to copy the SimpleCatalog - */ +/** Only public to make it possible to copy the SimpleCatalog */ public class SimpleCatalogUtil { - public static SimpleCatalog copyCatalog(SimpleCatalog sourceCatalog) { - // Simply serializes and deserializes the source catalog to create a copy. - // This is the most reliable way of creating a copy of a SimpleCatalog, - // as the SimpleCatalog's public interface does not expose enough of the internal - // structures to create an accurate copy. - FileDescriptorSetsBuilder fileDescriptorSetsBuilder = new FileDescriptorSetsBuilder(); - SimpleCatalogProtos.SimpleCatalogProto serialized = sourceCatalog.serialize(fileDescriptorSetsBuilder); - return SimpleCatalog.deserialize(serialized, fileDescriptorSetsBuilder.getDescriptorPools()); - } + public static SimpleCatalog copyCatalog(SimpleCatalog sourceCatalog) { + // Simply serializes and deserializes the source catalog to create a copy. + // This is the most reliable way of creating a copy of a SimpleCatalog, + // as the SimpleCatalog's public interface does not expose enough of the internal + // structures to create an accurate copy. + FileDescriptorSetsBuilder fileDescriptorSetsBuilder = new FileDescriptorSetsBuilder(); + SimpleCatalogProtos.SimpleCatalogProto serialized = + sourceCatalog.serialize(fileDescriptorSetsBuilder); + return SimpleCatalog.deserialize(serialized, fileDescriptorSetsBuilder.getDescriptorPools()); + } } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalysisException.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalysisException.java index 293585d..1257403 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalysisException.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalysisException.java @@ -18,9 +18,7 @@ import com.google.zetasql.SqlException; -/** - * Exception thrown by the {@link ZetaSQLToolkitAnalyzer} when analysis fails. - */ +/** Exception thrown by the {@link ZetaSQLToolkitAnalyzer} when analysis fails. */ public class AnalysisException extends RuntimeException { public AnalysisException(String message) { @@ -30,5 +28,4 @@ public AnalysisException(String message) { public AnalysisException(SqlException cause) { super(cause.getMessage(), cause); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzedStatement.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzedStatement.java index 63f3a53..b2a897d 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzedStatement.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzedStatement.java @@ -38,5 +38,4 @@ public ASTStatement getParsedStatement() { public Optional getResolvedStatement() { return resolvedStatement; } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzerExtensions.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzerExtensions.java index 59c06b8..0f8cc26 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzerExtensions.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/AnalyzerExtensions.java @@ -276,21 +276,19 @@ public void visit(ASTCallStatement procedureCall) { * @param options The {@link AnalyzerOptions} to use for analysis * @param catalog The {@link SimpleCatalog} to use for analysis * @return The {@link ResolvedExpr} resulting from the analysis - * * @throws SqlException if the analysis fails * @throws IllegalArgumentException if the expression's parse location exceeds the SQL string - * length. It will not happen if the SQL string is the query the expression was parsed from. + * length. It will not happen if the SQL string is the query the expression was parsed from. */ public static ResolvedExpr analyzeExpression( - String sql, ASTExpression expression, - AnalyzerOptions options, SimpleCatalog catalog - ) { + String sql, ASTExpression expression, AnalyzerOptions options, SimpleCatalog catalog) { ParseLocationRange expressionRange = expression.getParseLocationRange(); if (expressionRange.end() > sql.length()) { - String message = String.format( - "Expression parse location %d exceeds SQL query length of %d", - expressionRange.end(), sql.length()); + String message = + String.format( + "Expression parse location %d exceeds SQL query length of %d", + expressionRange.end(), sql.length()); throw new IllegalArgumentException(message); } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/Coercer.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/Coercer.java index 9eac516..0bfb058 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/Coercer.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/Coercer.java @@ -26,12 +26,12 @@ import java.util.Optional; /** - * Basic (and not complete) implementation of a type coercer for ZetaSQL, based on the - * C++ Coercer + * Basic (and not complete) implementation of a type coercer for ZetaSQL, based on the C++ Coercer * - *

This is not a complete implementation for ZetaSQL; since it doesn't properly implement - * coercion for protos, enums and other complex types. However, it should suffice for the - * SQL engines the ZetaSQL toolkit is targeting (primarily BigQuery and Cloud Spanner). + *

This is not a complete implementation for ZetaSQL; since it doesn't properly implement + * coercion for protos, enums and other complex types. However, it should suffice for the SQL + * engines the ZetaSQL toolkit is targeting (primarily BigQuery and Cloud Spanner). */ class Coercer { @@ -44,262 +44,399 @@ public Coercer(LanguageOptions languageOptions) { /** * List of supported type coercions in ZetaSQL. * - *

Each {@link TypeCoercion} specifies a supported type coercion from one type - * (the "from" type) to another (the "to" type). Each coercion has a {@link CoercionMode} - * associated to it. + *

Each {@link TypeCoercion} specifies a supported type coercion from one type (the "from" + * type) to another (the "to" type). Each coercion has a {@link CoercionMode} associated to it. * - *

For example: + *

For example: * *

    - *
  • BOOL implicitly coerces to BOOL (any type coerces implicitly to itself) - *
  • INT32 implicitly coerces to INT64 and DOUBLE - *
  • INT32 explicitly coerces to STRING (it needs to be casted) + *
  • BOOL implicitly coerces to BOOL (any type coerces implicitly to itself) + *
  • INT32 implicitly coerces to INT64 and DOUBLE + *
  • INT32 explicitly coerces to STRING (it needs to be casted) *
*/ - private static final ImmutableList supportedTypeCoercions = ImmutableList.of( - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BOOL, /*to=*/TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_INT32, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_INT64, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_ENUM, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT32, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_INT64, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_ENUM, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INT64, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_ENUM, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT32, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_ENUM, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_UINT64, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_NUMERIC, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BIGNUMERIC, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_FLOAT, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_FLOAT, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_DOUBLE, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.EXPLICIT_OR_LITERAL), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_INT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_INT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_UINT32, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_UINT64, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_FLOAT, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_DOUBLE, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_BYTES, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_DATE, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_TIMESTAMP, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_TIME, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_DATETIME, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_INTERVAL, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_ENUM, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_PROTO, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_NUMERIC, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_BIGNUMERIC, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_STRING, /*to=*/TypeKind.TYPE_RANGE, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BYTES, /*to=*/TypeKind.TYPE_BYTES, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BYTES, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_BYTES, /*to=*/TypeKind.TYPE_PROTO, - CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATE, /*to=*/TypeKind.TYPE_DATE, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATE, /*to=*/TypeKind.TYPE_DATETIME, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATE, /*to=*/TypeKind.TYPE_TIMESTAMP, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATE, /*to=*/TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIMESTAMP, /*to=*/TypeKind.TYPE_DATE, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIMESTAMP, /*to=*/TypeKind.TYPE_DATETIME, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIMESTAMP, /*to=*/TypeKind.TYPE_TIME, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIMESTAMP, /*to=*/TypeKind.TYPE_TIMESTAMP, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIMESTAMP, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIME, /*to=*/TypeKind.TYPE_TIME, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_TIME, /*to=*/TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATETIME, /*to=*/TypeKind.TYPE_DATE, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATETIME, /*to=*/TypeKind.TYPE_DATETIME, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATETIME, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATETIME, /*to=*/TypeKind.TYPE_TIME, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_DATETIME, /*to=*/TypeKind.TYPE_TIMESTAMP, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INTERVAL, /*to=*/TypeKind.TYPE_INTERVAL, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_INTERVAL, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_GEOGRAPHY, /*to=*/TypeKind.TYPE_GEOGRAPHY, - CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_JSON, /*to=*/TypeKind.TYPE_JSON, CoercionMode.IMPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_ENUM, /*to=*/TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_ENUM, /*to=*/TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_ENUM, /*to=*/TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_ENUM, /*to=*/TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_ENUM, /*to=*/TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_PROTO, /*to=*/TypeKind.TYPE_STRING, - CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_PROTO, /*to=*/TypeKind.TYPE_BYTES, CoercionMode.EXPLICIT), - new TypeCoercion(/*from=*/TypeKind.TYPE_RANGE, /*to=*/TypeKind.TYPE_STRING, CoercionMode.EXPLICIT) - ); + private static final ImmutableList supportedTypeCoercions = + ImmutableList.of( + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BOOL, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, + /*to=*/ TypeKind.TYPE_UINT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, + /*to=*/ TypeKind.TYPE_UINT64, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, + /*to=*/ TypeKind.TYPE_ENUM, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT32, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_INT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_UINT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_UINT64, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_ENUM, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INT64, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, + /*to=*/ TypeKind.TYPE_INT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, + /*to=*/ TypeKind.TYPE_ENUM, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT32, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_INT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_INT64, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_UINT32, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_ENUM, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_UINT64, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_FLOAT, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, + /*to=*/ TypeKind.TYPE_NUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_NUMERIC, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_INT32, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_INT64, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_UINT32, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_UINT64, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_DOUBLE, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_STRING, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_NUMERIC, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BIGNUMERIC, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_FLOAT, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_FLOAT, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, + /*to=*/ TypeKind.TYPE_FLOAT, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, + /*to=*/ TypeKind.TYPE_NUMERIC, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DOUBLE, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.EXPLICIT_OR_LITERAL), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_FLOAT, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_DOUBLE, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_BYTES, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_DATE, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_TIMESTAMP, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_TIME, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_DATETIME, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_INTERVAL, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_ENUM, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_PROTO, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_BOOL, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_NUMERIC, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, + /*to=*/ TypeKind.TYPE_BIGNUMERIC, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_STRING, /*to=*/ TypeKind.TYPE_RANGE, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BYTES, /*to=*/ TypeKind.TYPE_BYTES, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BYTES, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_BYTES, + /*to=*/ TypeKind.TYPE_PROTO, + CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATE, /*to=*/ TypeKind.TYPE_DATE, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATE, /*to=*/ TypeKind.TYPE_DATETIME, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATE, /*to=*/ TypeKind.TYPE_TIMESTAMP, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATE, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIMESTAMP, /*to=*/ TypeKind.TYPE_DATE, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIMESTAMP, + /*to=*/ TypeKind.TYPE_DATETIME, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIMESTAMP, /*to=*/ TypeKind.TYPE_TIME, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIMESTAMP, + /*to=*/ TypeKind.TYPE_TIMESTAMP, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIMESTAMP, + /*to=*/ TypeKind.TYPE_STRING, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIME, /*to=*/ TypeKind.TYPE_TIME, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_TIME, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATETIME, /*to=*/ TypeKind.TYPE_DATE, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATETIME, + /*to=*/ TypeKind.TYPE_DATETIME, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATETIME, + /*to=*/ TypeKind.TYPE_STRING, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATETIME, /*to=*/ TypeKind.TYPE_TIME, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_DATETIME, + /*to=*/ TypeKind.TYPE_TIMESTAMP, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INTERVAL, + /*to=*/ TypeKind.TYPE_INTERVAL, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_INTERVAL, + /*to=*/ TypeKind.TYPE_STRING, + CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_GEOGRAPHY, + /*to=*/ TypeKind.TYPE_GEOGRAPHY, + CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_JSON, /*to=*/ TypeKind.TYPE_JSON, CoercionMode.IMPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_ENUM, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_ENUM, /*to=*/ TypeKind.TYPE_INT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_ENUM, /*to=*/ TypeKind.TYPE_INT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_ENUM, /*to=*/ TypeKind.TYPE_UINT32, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_ENUM, /*to=*/ TypeKind.TYPE_UINT64, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_PROTO, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_PROTO, /*to=*/ TypeKind.TYPE_BYTES, CoercionMode.EXPLICIT), + new TypeCoercion( + /*from=*/ TypeKind.TYPE_RANGE, /*to=*/ TypeKind.TYPE_STRING, CoercionMode.EXPLICIT)); private enum CoercionMode { IMPLICIT, @@ -323,18 +460,14 @@ public TypeCoercion(TypeKind fromKind, TypeKind toKind, CoercionMode coercionMod /** * Returns whether fromType can coerce to toType - * + * * @param fromType The type to coerce from * @param toType The type to coerce to * @param isLiteral Whether the expression that's being coerced is a literal * @param isParameter Whether the expression that's being coerced is a parameter - * * @return Whether fromType can coerce to toType */ - public boolean coercesTo( - Type fromType, Type toType, - boolean isLiteral, boolean isParameter - ) { + public boolean coercesTo(Type fromType, Type toType, boolean isLiteral, boolean isParameter) { if (fromType.isStruct()) { return structCoercesTo((StructType) fromType, toType, isLiteral, isParameter); } @@ -350,13 +483,15 @@ public boolean coercesTo( TypeKind fromKind = fromType.getKind(); TypeKind toKind = toType.getKind(); - Optional maybeCoercionMode = supportedTypeCoercions.stream() - .filter(typeCoercion -> - typeCoercion.fromKind.equals(fromKind) && typeCoercion.toKind.equals(toKind)) - .map(typeCoercion -> typeCoercion.coercionMode) - .findFirst(); + Optional maybeCoercionMode = + supportedTypeCoercions.stream() + .filter( + typeCoercion -> + typeCoercion.fromKind.equals(fromKind) && typeCoercion.toKind.equals(toKind)) + .map(typeCoercion -> typeCoercion.coercionMode) + .findFirst(); - if(!maybeCoercionMode.isPresent()) { + if (!maybeCoercionMode.isPresent()) { return false; } @@ -373,13 +508,9 @@ public boolean coercesTo( return supportsImplicitCoercion(coercionMode); } - /** - * @see Coercer#coercesTo(Type, Type, boolean, boolean) - */ + /** @see Coercer#coercesTo(Type, Type, boolean, boolean) */ public boolean structCoercesTo( - StructType fromType, Type toType, - boolean isLiteral, boolean isParameter - ) { + StructType fromType, Type toType, boolean isLiteral, boolean isParameter) { if (!toType.isStruct() || toType.asStruct().getFieldCount() != fromType.getFieldCount()) { return false; } @@ -397,13 +528,9 @@ public boolean structCoercesTo( return true; } - /** - * @see Coercer#coercesTo(Type, Type, boolean, boolean) - */ + /** @see Coercer#coercesTo(Type, Type, boolean, boolean) */ public boolean arrayCoercesTo( - ArrayType fromType, Type toType, - boolean isLiteral, boolean isParameter - ) { + ArrayType fromType, Type toType, boolean isLiteral, boolean isParameter) { if (fromType.equivalent(toType)) { return true; } @@ -419,10 +546,7 @@ public boolean arrayCoercesTo( if (isLiteral || isParameter) { return coercesTo( - fromType.getElementType(), - toType.asArray().getElementType(), - isLiteral, - isParameter); + fromType.getElementType(), toType.asArray().getElementType(), isLiteral, isParameter); } return false; @@ -442,5 +566,4 @@ public boolean supportsParameterCoercion(CoercionMode mode) { return mode.equals(CoercionMode.IMPLICIT) || mode.equals(CoercionMode.EXPLICIT_OR_LITERAL_OR_PARAMETER); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/StatementRewriter.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/StatementRewriter.java index 2d66780..25432be 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/StatementRewriter.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/StatementRewriter.java @@ -99,8 +99,8 @@ * Implements query-level rewrites based on the parsed tree. It allows modifying the query text * after parsing but before analyzing. * - *

These rewrites are done at the query level because the parsed tree is immutable and can't - * be modified itself. + *

These rewrites are done at the query level because the parsed tree is immutable and can't be + * modified itself. */ class StatementRewriter { @@ -109,9 +109,9 @@ class StatementRewriter { * said query are quoted entirely. For example, it rewrites "FROM project.dataset.table" to "FROM * `project.dataset.table`". * - *

To do so; it finds all {@link ASTPathExpression} nodes in the parse tree refer to a - * resource (i.e. tables, functions, etc.), builds their fully quoted representation and replaces - * their original text in the query with their quoted representation. + *

To do so; it finds all {@link ASTPathExpression} nodes in the parse tree refer to a resource + * (i.e. tables, functions, etc.), builds their fully quoted representation and replaces their + * original text in the query with their quoted representation. * * @param query The original query text the statement was parsed from * @param parsedStatement The parsed statement for which to rewrite name paths @@ -147,21 +147,20 @@ public static String quoteNamePaths(String query, ASTStatement parsedStatement) /** * Returns the fully quoted string representation of an {@link ASTPathExpression}. * - * @param pathExpression The path expression for which to build the fully quoted - * representation + * @param pathExpression The path expression for which to build the fully quoted representation * @return The fully quoted representation of the path expression */ private static String buildQuotedNamePath(ASTPathExpression pathExpression) { - String fullName = pathExpression.getNames() - .stream() - .map(ASTIdentifier::getIdString) - .collect(Collectors.joining(".")); + String fullName = + pathExpression.getNames().stream() + .map(ASTIdentifier::getIdString) + .collect(Collectors.joining(".")); return "`" + fullName + "`"; } /** - * Extracts all {@link ASTPathExpression} nodes that refer to a resource - * (i.e. tables, functions, etc.) from a parse tree + * Extracts all {@link ASTPathExpression} nodes that refer to a resource (i.e. tables, functions, + * etc.) from a parse tree * * @param tree The parse tree * @return The list of all {@link ASTPathExpression} in the tree that refer to a resource @@ -169,370 +168,369 @@ private static String buildQuotedNamePath(ASTPathExpression pathExpression) { private static List getResourcePathExpressionFromParseTree(ASTNode tree) { ArrayList result = new ArrayList<>(); - tree.accept(new ParseTreeVisitor() { - - public void visit(ASTTablePathExpression node) { - result.add(node.getPathExpr()); - } - - public void visit(ASTFunctionCall node) { - result.add(node.getFunction()); - super.visit(node); - } - - public void visit(ASTSequenceArg node) { - result.add(node.getSequencePath()); - } - - public void visit(ASTDescribeStatement node) { - result.add(node.getName()); - if (node.getOptionalFromName() != null) { - result.add(node.getOptionalFromName()); - } - super.visit(node); - } - - public void visit(ASTShowStatement node) { - result.add(node.getOptionalName()); - super.visit(node); - } - - public void visit(ASTDropEntityStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropFunctionStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropTableFunctionStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropAllRowAccessPoliciesStatement node) { - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTDropMaterializedViewStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropSnapshotTableStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropSearchIndexStatement node) { - result.add(node.getName()); - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTDropVectorIndexStatement node) { - result.add(node.getName()); - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTRenameStatement node) { - result.add(node.getOldName()); - result.add(node.getNewName()); - super.visit(node); - } - - public void visit(ASTImportStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTModuleStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTSystemVariableExpr node) { - result.add(node.getPath()); - } - - public void visit(ASTFunctionDeclaration node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTTVF node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTTableClause node) { - result.add(node.getTablePath()); - super.visit(node); - } - - public void visit(ASTModelClause node) { - result.add(node.getModelPath()); - } - - public void visit(ASTConnectionClause node) { - result.add(node.getConnectionPath()); - } - - public void visit(ASTCloneDataSource node) { - result.add(node.getPathExpr()); - super.visit(node); - } - - public void visit(ASTCopyDataSource node) { - result.add(node.getPathExpr()); - super.visit(node); - } - - public void visit(ASTCloneDataStatement node) { - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTCreateConstantStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateDatabaseStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateProcedureStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateSchemaStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateModelStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateIndexStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTExportModelStatement node) { - result.add(node.getModelNamePath()); - super.visit(node); - } - - public void visit(ASTExportMetadataStatement node) { - result.add(node.getNamePath()); - super.visit(node); - } - - public void visit(ASTCallStatement node) { - result.add(node.getProcedureName()); - super.visit(node); - } - - public void visit(ASTDefineTableStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateSnapshotStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateSnapshotTableStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTTableAndColumnInfo node) { - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTTruncateStatement node) { - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTMergeStatement node) { - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTGrantStatement node) { - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTRevokeStatement node) { - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTRenameToClause node) { - result.add(node.getNewName()); - super.visit(node); - } - - public void visit(ASTAlterAllRowAccessPoliciesStatement node) { - result.add(node.getTableNamePath()); - super.visit(node); - } - - public void visit(ASTForeignKeyReference node) { - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTCreateEntityStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTDropPrivilegeRestrictionStatement node) { - result.add(node.getNamePath()); - super.visit(node); - } - - public void visit(ASTDropRowAccessPolicyStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreatePrivilegeRestrictionStatement node) { - result.add(node.getNamePath()); - super.visit(node); - } - - public void visit(ASTCreateRowAccessPolicyStatement node) { - result.add(node.getName()); - result.add(node.getTargetPath()); - super.visit(node); - } - - public void visit(ASTDropStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateTableStatement node) { - result.add(node.getName()); - if (node.getLikeTableName() != null) { - result.add(node.getLikeTableName()); - } - super.visit(node); - } - - public void visit(ASTCreateExternalTableStatement node) { - result.add(node.getName()); - if (node.getLikeTableName() != null) { - result.add(node.getLikeTableName()); - } - super.visit(node); - } - - public void visit(ASTAuxLoadDataStatement node) { - result.add(node.getName()); - if (node.getLikeTableName() != null) { - result.add(node.getLikeTableName()); - } - super.visit(node); - } - - public void visit(ASTCreateViewStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateApproxViewStatement node) { - result.add(node.getName()); - super.visit(node); - } - - public void visit(ASTCreateMaterializedViewStatement node) { - result.add(node.getName()); - if (node.getReplicaSource() != null) { - result.add(node.getReplicaSource()); - } - super.visit(node); - } - - public void visit(ASTAlterDatabaseStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterSchemaStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterTableStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterViewStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterMaterializedViewStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterApproxViewStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterModelStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterPrivilegeRestrictionStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterRowAccessPolicyStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTAlterEntityStatement node) { - result.add(node.getPath()); - super.visit(node); - } - - public void visit(ASTSpannerInterleaveClause node) { - result.add(node.getTableName()); - super.visit(node); - } - - public void visit(ASTUndropStatement node) { - result.add(node.getName()); - super.visit(node); - } - - }); + tree.accept( + new ParseTreeVisitor() { + + public void visit(ASTTablePathExpression node) { + result.add(node.getPathExpr()); + } + + public void visit(ASTFunctionCall node) { + result.add(node.getFunction()); + super.visit(node); + } + + public void visit(ASTSequenceArg node) { + result.add(node.getSequencePath()); + } + + public void visit(ASTDescribeStatement node) { + result.add(node.getName()); + if (node.getOptionalFromName() != null) { + result.add(node.getOptionalFromName()); + } + super.visit(node); + } + + public void visit(ASTShowStatement node) { + result.add(node.getOptionalName()); + super.visit(node); + } + + public void visit(ASTDropEntityStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropFunctionStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropTableFunctionStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropAllRowAccessPoliciesStatement node) { + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTDropMaterializedViewStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropSnapshotTableStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropSearchIndexStatement node) { + result.add(node.getName()); + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTDropVectorIndexStatement node) { + result.add(node.getName()); + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTRenameStatement node) { + result.add(node.getOldName()); + result.add(node.getNewName()); + super.visit(node); + } + + public void visit(ASTImportStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTModuleStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTSystemVariableExpr node) { + result.add(node.getPath()); + } + + public void visit(ASTFunctionDeclaration node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTTVF node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTTableClause node) { + result.add(node.getTablePath()); + super.visit(node); + } + + public void visit(ASTModelClause node) { + result.add(node.getModelPath()); + } + + public void visit(ASTConnectionClause node) { + result.add(node.getConnectionPath()); + } + + public void visit(ASTCloneDataSource node) { + result.add(node.getPathExpr()); + super.visit(node); + } + + public void visit(ASTCopyDataSource node) { + result.add(node.getPathExpr()); + super.visit(node); + } + + public void visit(ASTCloneDataStatement node) { + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTCreateConstantStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateDatabaseStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateProcedureStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateSchemaStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateModelStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateIndexStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTExportModelStatement node) { + result.add(node.getModelNamePath()); + super.visit(node); + } + + public void visit(ASTExportMetadataStatement node) { + result.add(node.getNamePath()); + super.visit(node); + } + + public void visit(ASTCallStatement node) { + result.add(node.getProcedureName()); + super.visit(node); + } + + public void visit(ASTDefineTableStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateSnapshotStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateSnapshotTableStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTTableAndColumnInfo node) { + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTTruncateStatement node) { + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTMergeStatement node) { + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTGrantStatement node) { + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTRevokeStatement node) { + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTRenameToClause node) { + result.add(node.getNewName()); + super.visit(node); + } + + public void visit(ASTAlterAllRowAccessPoliciesStatement node) { + result.add(node.getTableNamePath()); + super.visit(node); + } + + public void visit(ASTForeignKeyReference node) { + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTCreateEntityStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTDropPrivilegeRestrictionStatement node) { + result.add(node.getNamePath()); + super.visit(node); + } + + public void visit(ASTDropRowAccessPolicyStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreatePrivilegeRestrictionStatement node) { + result.add(node.getNamePath()); + super.visit(node); + } + + public void visit(ASTCreateRowAccessPolicyStatement node) { + result.add(node.getName()); + result.add(node.getTargetPath()); + super.visit(node); + } + + public void visit(ASTDropStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateTableStatement node) { + result.add(node.getName()); + if (node.getLikeTableName() != null) { + result.add(node.getLikeTableName()); + } + super.visit(node); + } + + public void visit(ASTCreateExternalTableStatement node) { + result.add(node.getName()); + if (node.getLikeTableName() != null) { + result.add(node.getLikeTableName()); + } + super.visit(node); + } + + public void visit(ASTAuxLoadDataStatement node) { + result.add(node.getName()); + if (node.getLikeTableName() != null) { + result.add(node.getLikeTableName()); + } + super.visit(node); + } + + public void visit(ASTCreateViewStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateApproxViewStatement node) { + result.add(node.getName()); + super.visit(node); + } + + public void visit(ASTCreateMaterializedViewStatement node) { + result.add(node.getName()); + if (node.getReplicaSource() != null) { + result.add(node.getReplicaSource()); + } + super.visit(node); + } + + public void visit(ASTAlterDatabaseStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterSchemaStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterTableStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterViewStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterMaterializedViewStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterApproxViewStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterModelStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterPrivilegeRestrictionStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterRowAccessPolicyStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTAlterEntityStatement node) { + result.add(node.getPath()); + super.visit(node); + } + + public void visit(ASTSpannerInterleaveClause node) { + result.add(node.getTableName()); + super.visit(node); + } + + public void visit(ASTUndropStatement node) { + result.add(node.getName()); + super.visit(node); + } + }); return result; } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/ZetaSQLToolkitAnalyzer.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/ZetaSQLToolkitAnalyzer.java index b6b95aa..9c116a6 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/ZetaSQLToolkitAnalyzer.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/ZetaSQLToolkitAnalyzer.java @@ -103,12 +103,11 @@ public Iterator analyzeStatements(String query, CatalogWrappe } /** - * Analyze a SQL query or script, using the provided {@link CatalogWrapper} to manage the - * catalog. + * Analyze a SQL query or script, using the provided {@link CatalogWrapper} to manage the catalog. * - *

This toolkit includes two implementations, the BigQueryCatalog and the SpannerCatalog; - * which can be used to run the analyzer following BigQuery or Spanner catalog semantics - * respectively. For other use-cases, you can provide your own CatalogWrapper implementation. + *

This toolkit includes two implementations, the BigQueryCatalog and the SpannerCatalog; which + * can be used to run the analyzer following BigQuery or Spanner catalog semantics respectively. + * For other use-cases, you can provide your own CatalogWrapper implementation. * * @param query The SQL query or script to analyze * @param catalog The CatalogWrapper implementation to use when managing the catalog @@ -129,21 +128,22 @@ public Iterator analyzeStatements( * ZetaSQL Toolkit. It implements Iterator<{@link AnalyzedStatement}>, and consuming the * iterator will lazily perform SQL analysis statement by statement. * - *

For each statement in the query, it will: + *

For each statement in the query, it will: + * *

    - *
  1. Parse the statement using the {@link Parser} - *
  2. If it is a variable declaration or an assignment, validate it and update the catalog - *
  3. Resolve the statement if possible, using the {@link Analyzer} - *
  4. Return the corresponding {@link AnalyzedStatement} object; containing the parsed - * {@link ASTStatement} and, optionally, the resolved {@link ResolvedStatement} + *
  5. Parse the statement using the {@link Parser} + *
  6. If it is a variable declaration or an assignment, validate it and update the catalog + *
  7. Resolve the statement if possible, using the {@link Analyzer} + *
  8. Return the corresponding {@link AnalyzedStatement} object; containing the parsed {@link + * ASTStatement} and, optionally, the resolved {@link ResolvedStatement} *
* - *

Resolution will only happen for a statement if it is supported by the Analyzer (i.e. - * it is not a script statement). If a complex script statement is encountered (e.g. IFs, LOOPs), + *

Resolution will only happen for a statement if it is supported by the Analyzer (i.e. it is + * not a script statement). If a complex script statement is encountered (e.g. IFs, LOOPs), * statement resolution will stop altogether and not be performed for the rest of this query. * - *

If parsing, resolution or validations fail while analyzing a statement, - * an {@link AnalysisException} will be thrown. + *

If parsing, resolution or validations fail while analyzing a statement, an {@link + * AnalysisException} will be thrown. */ private static class StatementAnalyzer implements Iterator { @@ -155,8 +155,8 @@ private static class StatementAnalyzer implements Iterator { private final ParseResumeLocation parseResumeLocation; private boolean reachedComplexScriptStatement = false; - public StatementAnalyzer(String query, CatalogWrapper catalog, - AnalyzerOptions analyzerOptions) { + public StatementAnalyzer( + String query, CatalogWrapper catalog, AnalyzerOptions analyzerOptions) { this.query = query; this.catalog = catalog; this.analyzerOptions = analyzerOptions; @@ -176,9 +176,9 @@ public boolean hasNext() { * Analyze the next statement in the query, following the steps outlined in this class's * javadoc. * - * @return An {@link AnalyzedStatement} for the next statement of the query. It will include - * the parsed statement and, optionally, the resolved statement. See this class's javadoc - * to know when a statement is resolved. + * @return An {@link AnalyzedStatement} for the next statement of the query. It will include the + * parsed statement and, optionally, the resolved statement. See this class's javadoc to + * know when a statement is resolved. */ @Override public AnalyzedStatement next() { @@ -189,7 +189,8 @@ public AnalyzedStatement next() { this.reachedComplexScriptStatement = this.reachedComplexScriptStatement || isComplexScriptStatement(parsedStatement); - // If the statement is a variable declaration, we need to validate it and create a Constant + // If the statement is a variable declaration, we need to validate it and create a + // Constant // in the catalog if (parsedStatement instanceof ASTVariableDeclaration) { this.applyVariableDeclaration((ASTVariableDeclaration) parsedStatement); @@ -206,8 +207,7 @@ public AnalyzedStatement next() { return new AnalyzedStatement(parsedStatement, Optional.empty()); } - String rewrittenQuery = - StatementRewriter.quoteNamePaths(query, parsedStatement); + String rewrittenQuery = StatementRewriter.quoteNamePaths(query, parsedStatement); ParseResumeLocation analysisParseResumeLocation = new ParseResumeLocation(rewrittenQuery); analysisParseResumeLocation.setBytePosition(startPosition); @@ -249,23 +249,17 @@ private boolean isComplexScriptStatement(ASTStatement parsedStatement) { } private Type parseASTType(ASTType astType) { - String typeString = query.substring( - astType.getParseLocationRange().start(), - astType.getParseLocationRange().end() - ); + String typeString = + query.substring( + astType.getParseLocationRange().start(), astType.getParseLocationRange().end()); return ZetaSQLTypeParser.parse(typeString); } private Constant buildConstant(String name, Type type) { - SimpleConstantProto proto = SimpleConstantProto.newBuilder() - .addNamePath(name) - .setType(type.serialize()) - .build(); - - return Constant.deserialize( - proto, - ImmutableList.of(), - TypeFactory.nonUniqueNames()); + SimpleConstantProto proto = + SimpleConstantProto.newBuilder().addNamePath(name).setType(type.serialize()).build(); + + return Constant.deserialize(proto, ImmutableList.of(), TypeFactory.nonUniqueNames()); } private void coerceExpressionToType(Type type, ResolvedExpr resolvedExpr) { @@ -276,20 +270,22 @@ private void coerceExpressionToType(Type type, ResolvedExpr resolvedExpr) { boolean coerces = this.coercer.coercesTo(expressionType, type, isLiteral, isParameter); if (!coerces) { - String message = String.format( - "Cannot coerce expression of type %s to type %s", - type, expressionType); + String message = + String.format("Cannot coerce expression of type %s to type %s", type, expressionType); throw new AnalysisException(message); } } private void applyVariableDeclaration(ASTVariableDeclaration declaration) { - Optional explicitType = Optional.ofNullable(declaration.getType()) - .map(this::parseASTType); + Optional explicitType = + Optional.ofNullable(declaration.getType()).map(this::parseASTType); - Optional defaultValueExpr = Optional.ofNullable(declaration.getDefaultValue()) - .map(expression -> AnalyzerExtensions.analyzeExpression( - query, expression, analyzerOptions, catalog.getZetaSQLCatalog())); + Optional defaultValueExpr = + Optional.ofNullable(declaration.getDefaultValue()) + .map( + expression -> + AnalyzerExtensions.analyzeExpression( + query, expression, analyzerOptions, catalog.getZetaSQLCatalog())); if (!explicitType.isPresent() && !defaultValueExpr.isPresent()) { // Should not happen, since this is enforced by the parser @@ -303,9 +299,7 @@ private void applyVariableDeclaration(ASTVariableDeclaration declaration) { Type variableType = explicitType.orElseGet(() -> defaultValueExpr.get().getType()); - declaration.getVariableList() - .getIdentifierList() - .stream() + declaration.getVariableList().getIdentifierList().stream() .map(ASTIdentifier::getIdString) .map(variableName -> this.buildConstant(variableName, variableType)) .forEach(catalog::register); @@ -315,11 +309,13 @@ private void validateSingleAssignment(ASTSingleAssignment singleAssignment) { String assignmentTarget = singleAssignment.getVariable().getIdString(); ASTExpression expression = singleAssignment.getExpression(); - ResolvedExpr analyzedExpression = AnalyzerExtensions.analyzeExpression( - query, expression, analyzerOptions, catalog.getZetaSQLCatalog()); + ResolvedExpr analyzedExpression = + AnalyzerExtensions.analyzeExpression( + query, expression, analyzerOptions, catalog.getZetaSQLCatalog()); try { - Constant constant = catalog.getZetaSQLCatalog().findConstant(ImmutableList.of(assignmentTarget)); + Constant constant = + catalog.getZetaSQLCatalog().findConstant(ImmutableList.of(assignmentTarget)); this.coerceExpressionToType(constant.getType(), analyzedExpression); } catch (NotFoundException e) { throw new AnalysisException("Undeclared variable: " + assignmentTarget); @@ -331,48 +327,50 @@ private void applyCatalogMutation(ResolvedStatement statement) { } private void validateProcedureAndTVFReferences(ASTStatement parsedStatement) { - parsedStatement.accept(new ParseTreeVisitor() { - - public void visit(ASTCallStatement callStatement) { - List procedureNames = callStatement.getProcedureName().getNames() - .stream() - .map(ASTIdentifier::getIdString) - .collect(Collectors.toList()); - - if (procedureNames.size() > 1) { - String foundProcedureName = procedureNames.stream() - .map(name -> "`" + name + "`") - .collect(Collectors.joining(".")); - String expectedProcedureName = "`" + String.join(".", procedureNames) + "`"; - - String message = String.format( - "Procedures in CALL statements should be fully quoted. Expected %s, found %s.", - expectedProcedureName, foundProcedureName); - throw new AnalysisException(message); - } - } - - public void visit(ASTTVF astTvf) { - List tvfNames = astTvf.getName().getNames() - .stream() - .map(ASTIdentifier::getIdString) - .collect(Collectors.toList()); - if (tvfNames.size() > 1) { - String foundTvfName = tvfNames.stream() - .map(name -> "`" + name + "`") - .collect(Collectors.joining(".")); - String expectedTvfName = "`" + String.join(".", tvfNames) + "`"; - - String message = String.format( - "TVF calls should be fully quoted. Expected %s, found %s.", - expectedTvfName, foundTvfName); - throw new AnalysisException(message); - } - } - - }); + parsedStatement.accept( + new ParseTreeVisitor() { + + public void visit(ASTCallStatement callStatement) { + List procedureNames = + callStatement.getProcedureName().getNames().stream() + .map(ASTIdentifier::getIdString) + .collect(Collectors.toList()); + + if (procedureNames.size() > 1) { + String foundProcedureName = + procedureNames.stream() + .map(name -> "`" + name + "`") + .collect(Collectors.joining(".")); + String expectedProcedureName = "`" + String.join(".", procedureNames) + "`"; + + String message = + String.format( + "Procedures in CALL statements should be fully quoted. Expected %s, found %s.", + expectedProcedureName, foundProcedureName); + throw new AnalysisException(message); + } + } + + public void visit(ASTTVF astTvf) { + List tvfNames = + astTvf.getName().getNames().stream() + .map(ASTIdentifier::getIdString) + .collect(Collectors.toList()); + if (tvfNames.size() > 1) { + String foundTvfName = + tvfNames.stream() + .map(name -> "`" + name + "`") + .collect(Collectors.joining(".")); + String expectedTvfName = "`" + String.join(".", tvfNames) + "`"; + + String message = + String.format( + "TVF calls should be fully quoted. Expected %s, found %s.", + expectedTvfName, foundTvfName); + throw new AnalysisException(message); + } + } + }); } - } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/CatalogOperations.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/CatalogOperations.java index ba8afc3..bf1ae6f 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/CatalogOperations.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/CatalogOperations.java @@ -19,7 +19,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.zetasql.*; -import com.google.zetasql.SimpleCatalogProtos.SimpleCatalogProto; import com.google.zetasql.TableValuedFunction.FixedOutputSchemaTVF; import com.google.zetasql.resolvedast.ResolvedCreateStatementEnums.CreateMode; import com.google.zetasql.toolkit.catalog.exceptions.CatalogResourceAlreadyExists; @@ -143,9 +142,12 @@ private static SimpleCatalog getSubCatalogForResource( * @param deleter A Runnable that will delete the resource from the catalog if run */ private static void createResource( - String nameInCatalog, CreateMode createMode, String resourceType, - boolean alreadyExists, Runnable creator, Runnable deleter - ) { + String nameInCatalog, + CreateMode createMode, + String resourceType, + boolean alreadyExists, + Runnable creator, + Runnable deleter) { if (createMode.equals(CreateMode.CREATE_IF_NOT_EXISTS) && alreadyExists) { return; } @@ -156,8 +158,7 @@ private static void createResource( if (createMode.equals(CreateMode.CREATE_DEFAULT) && alreadyExists) { String errorMessage = - String.format( - "%s %s already exists in catalog", resourceType, nameInCatalog); + String.format("%s %s already exists in catalog", resourceType, nameInCatalog); throw new CatalogResourceAlreadyExists(nameInCatalog, errorMessage); } @@ -181,8 +182,8 @@ public static void deleteTableFromCatalog(SimpleCatalog catalog, String name) { } /** - * Creates a table in a {@link SimpleCatalog} using the provided paths and complying with - * the provided CreateMode. + * Creates a table in a {@link SimpleCatalog} using the provided paths and complying with the + * provided CreateMode. * * @param catalog The catalog in which to create the table * @param nameInCatalog The name under which the table will be registered in the catalog @@ -192,10 +193,7 @@ public static void deleteTableFromCatalog(SimpleCatalog catalog, String name) { * and CreateMode != CREATE_OR_REPLACE. */ public static void createTableInCatalog( - SimpleCatalog catalog, - String nameInCatalog, - SimpleTable table, - CreateMode createMode) { + SimpleCatalog catalog, String nameInCatalog, SimpleTable table, CreateMode createMode) { boolean alreadyExists = tableExists(catalog, nameInCatalog); @@ -205,8 +203,7 @@ public static void createTableInCatalog( "Table", alreadyExists, /*creator=*/ () -> catalog.addSimpleTable(nameInCatalog, table), - /*deleter=*/ () -> deleteTableFromCatalog(catalog, nameInCatalog) - ); + /*deleter=*/ () -> deleteTableFromCatalog(catalog, nameInCatalog)); } /** @@ -222,15 +219,14 @@ public static void deleteFunctionFromCatalog(SimpleCatalog catalog, String fullN Optional fullNameToDelete = catalog.getFunctionNameList().stream() .filter( - name -> - removeGroupFromFunctionName(name).equalsIgnoreCase(fullNameWithoutGroup)) + name -> removeGroupFromFunctionName(name).equalsIgnoreCase(fullNameWithoutGroup)) .findFirst(); if (fullNameToDelete.isPresent()) { catalog.removeFunction(fullNameToDelete.get()); } else { - String errorMessage = String.format( - "Tried to delete function which does not exist: %s", fullName); + String errorMessage = + String.format("Tried to delete function which does not exist: %s", fullName); throw new CatalogResourceDoesNotExist(fullName, errorMessage); } } @@ -241,8 +237,8 @@ public static void deleteFunctionFromCatalog(SimpleCatalog catalog, String fullN * * @param catalog The catalog in which to create the function * @param nameInCatalog The name under which the function will be registered in the catalog - * @param functionInfo The {@link FunctionInfo} object representing the function that - * should be created + * @param functionInfo The {@link FunctionInfo} object representing the function that should be + * created * @param createMode The CreateMode to use * @throws CatalogResourceAlreadyExists if the function already exists at any of the provided * paths and CreateMode != CREATE_OR_REPLACE. @@ -268,8 +264,7 @@ public static void createFunctionInCatalog( "Function", alreadyExists, /*creator=*/ () -> catalog.addFunction(function), - /*deleter=*/ () -> deleteFunctionFromCatalog(catalog, nameInCatalog) - ); + /*deleter=*/ () -> deleteFunctionFromCatalog(catalog, nameInCatalog)); } /** @@ -296,17 +291,13 @@ public static void deleteTVFFromCatalog(SimpleCatalog catalog, String fullName) * @param nameInCatalog The name under which the TVF will be registered in the catalog * @param tvfInfo The {@link TVFInfo} object representing the TVF that should be created * @param createMode The CreateMode to use - * @throws CatalogResourceAlreadyExists if the TVF already exists at any of the provided - * paths and CreateMode != CREATE_OR_REPLACE. + * @throws CatalogResourceAlreadyExists if the TVF already exists at any of the provided paths and + * CreateMode != CREATE_OR_REPLACE. */ public static void createTVFInCatalog( - SimpleCatalog catalog, - String nameInCatalog, - TVFInfo tvfInfo, - CreateMode createMode) { + SimpleCatalog catalog, String nameInCatalog, TVFInfo tvfInfo, CreateMode createMode) { Preconditions.checkArgument( - tvfInfo.getOutputSchema().isPresent(), - "Cannot create a a TVF without an output schema"); + tvfInfo.getOutputSchema().isPresent(), "Cannot create a a TVF without an output schema"); boolean alreadyExists = tvfExists(catalog, nameInCatalog); @@ -321,15 +312,14 @@ public static void createTVFInCatalog( createMode, "TVF", alreadyExists, - /*creator=*/() -> catalog.addTableValuedFunction(tvf), - /*deleter=*/() -> deleteTVFFromCatalog(catalog, nameInCatalog) - ); + /*creator=*/ () -> catalog.addTableValuedFunction(tvf), + /*deleter=*/ () -> deleteTVFFromCatalog(catalog, nameInCatalog)); } private static void deleteProcedureFromCatalogImpl(SimpleCatalog catalog, String fullName) { if (!procedureExists(catalog, fullName)) { - String errorMessage = String.format( - "Tried to delete procedure which does not exist: %s", fullName); + String errorMessage = + String.format("Tried to delete procedure which does not exist: %s", fullName); throw new CatalogResourceDoesNotExist(fullName, errorMessage); } @@ -339,8 +329,8 @@ private static void deleteProcedureFromCatalogImpl(SimpleCatalog catalog, String /** * Deletes a procedure with the provided name from the {@link SimpleCatalog} * - *

Qualified procedures need to be registered two times in the catalog for analysis to - * work as expected. This method takes care of deleting both copies of the procedure if necessary. + *

Qualified procedures need to be registered two times in the catalog for analysis to work as + * expected. This method takes care of deleting both copies of the procedure if necessary. * * @param catalog The catalog from which to delete the procedure * @param fullName The full name of the procedure in the catalog @@ -358,10 +348,10 @@ public static void deleteProcedureFromCatalog(SimpleCatalog catalog, String full } /** - * Creates a procedure in a {@link SimpleCatalog} using the provided name and complying with - * the provided CreateMode. + * Creates a procedure in a {@link SimpleCatalog} using the provided name and complying with the + * provided CreateMode. * - *

Qualified procedures will be registered two times in the catalog for analysis to work as + *

Qualified procedures will be registered two times in the catalog for analysis to work as * expected. A procedure with name "project.dataset.table" will be registered at name paths: * ["project.dataset.table"] and ["project", "dataset", "table"]. * @@ -380,20 +370,21 @@ public static void createProcedureInCatalog( boolean alreadyExists = procedureExists(catalog, nameInCatalog); - Runnable creatorFunction = () -> { - Procedure procedure = - new Procedure(ImmutableList.of(nameInCatalog), procedureInfo.getSignature()); - catalog.addProcedure(procedure); - - if (nameInCatalog.contains(".")) { - List nameComponents = Arrays.asList(nameInCatalog.split("\\.")); - String nestedName = nameComponents.get(nameComponents.size() - 1); - SimpleCatalog nestedCatalog = getSubCatalogForResource(catalog, nameComponents); - Procedure nestedProcedure = - new Procedure(ImmutableList.of(nestedName), procedureInfo.getSignature()); - nestedCatalog.addProcedure(nestedProcedure); - } - }; + Runnable creatorFunction = + () -> { + Procedure procedure = + new Procedure(ImmutableList.of(nameInCatalog), procedureInfo.getSignature()); + catalog.addProcedure(procedure); + + if (nameInCatalog.contains(".")) { + List nameComponents = Arrays.asList(nameInCatalog.split("\\.")); + String nestedName = nameComponents.get(nameComponents.size() - 1); + SimpleCatalog nestedCatalog = getSubCatalogForResource(catalog, nameComponents); + Procedure nestedProcedure = + new Procedure(ImmutableList.of(nestedName), procedureInfo.getSignature()); + nestedCatalog.addProcedure(nestedProcedure); + } + }; createResource( nameInCatalog, @@ -401,9 +392,7 @@ public static void createProcedureInCatalog( "Procedure", alreadyExists, /*creator=*/ creatorFunction, - /*deleter=*/ () -> deleteProcedureFromCatalog(catalog, nameInCatalog) - ); - + /*deleter=*/ () -> deleteProcedureFromCatalog(catalog, nameInCatalog)); } /** diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/FunctionInfo.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/FunctionInfo.java index e791bf8..169426b 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/FunctionInfo.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/FunctionInfo.java @@ -25,7 +25,8 @@ public class FunctionInfo { public enum Language { - LANGUAGE_UNSPECIFIED, SQL; + LANGUAGE_UNSPECIFIED, + SQL; public static Language valueOfOrUnspecified(String name) { try { diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/ProcedureInfo.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/ProcedureInfo.java index 4716282..9664bc7 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/ProcedureInfo.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/ProcedureInfo.java @@ -50,5 +50,4 @@ public FunctionSignature getSignature() { public String getFullName() { return String.join(".", namePath); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/basic/BasicCatalogWrapper.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/basic/BasicCatalogWrapper.java index f04ffe7..22ffaa8 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/basic/BasicCatalogWrapper.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/basic/BasicCatalogWrapper.java @@ -77,8 +77,7 @@ public void register(FunctionInfo function, CreateMode createMode, CreateScope c @Override public void register(TVFInfo tvfInfo, CreateMode createMode, CreateScope createScope) { - CatalogOperations.createTVFInCatalog( - this.catalog, tvfInfo.getFullName(), tvfInfo, createMode); + CatalogOperations.createTVFInCatalog(this.catalog, tvfInfo.getFullName(), tvfInfo, createMode); } /** @@ -102,13 +101,13 @@ public void register( public void register(Constant constant) { String fullName = constant.getFullName(); - boolean constantExists = this.catalog.getConstantList() - .stream() - .anyMatch(existingConstant -> existingConstant.getFullName().equalsIgnoreCase(fullName)); + boolean constantExists = + this.catalog.getConstantList().stream() + .anyMatch( + existingConstant -> existingConstant.getFullName().equalsIgnoreCase(fullName)); if (constantExists) { - throw new CatalogResourceAlreadyExists( - fullName, "Constant " + fullName + "already exists"); + throw new CatalogResourceAlreadyExists(fullName, "Constant " + fullName + "already exists"); } this.catalog.addConstant(constant); diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/exceptions/CatalogResourceDoesNotExist.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/exceptions/CatalogResourceDoesNotExist.java index e9f84cf..a331c31 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/exceptions/CatalogResourceDoesNotExist.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/exceptions/CatalogResourceDoesNotExist.java @@ -22,5 +22,4 @@ public CatalogResourceDoesNotExist(String resourceName, String message, Throwabl public String getResourceName() { return resourceName; } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/CatalogResources.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/CatalogResources.java index e894933..f141189 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/CatalogResources.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/CatalogResources.java @@ -24,9 +24,7 @@ import com.google.zetasql.toolkit.catalog.TVFInfo; import java.util.List; -/** - * Dataclass containing the resources of a Catalog - */ +/** Dataclass containing the resources of a Catalog */ public class CatalogResources { private final List tables; @@ -62,7 +60,7 @@ public List getProcedures() { } /** - * Deserializes a JSON object representing a Catalog into a {@link CatalogResources} instance. + * Deserializes a JSON object representing a Catalog into a {@link CatalogResources} instance. * JSON objects representing catalogs support tables, scalar functions, TVFs and procedures. * *

@@ -112,7 +110,7 @@ public List getProcedures() {
    *   ]
    * }
    * 
- * + * * @param json The JSON string for the object to deserialize into {@link CatalogResources} * @return The resulting {@link CatalogResources} instance * @throws JsonParseException when parsing the JSON catalog fails @@ -120,5 +118,4 @@ public List getProcedures() { public static CatalogResources fromJson(String json) { return JsonCatalogDeserializer.readJsonCatalog(json); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/JsonCatalogDeserializer.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/JsonCatalogDeserializer.java index f4a4abc..d80c490 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/JsonCatalogDeserializer.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/io/JsonCatalogDeserializer.java @@ -100,7 +100,6 @@ * ] * } * - * */ class JsonCatalogDeserializer { @@ -108,14 +107,15 @@ class JsonCatalogDeserializer { * {@link Gson} instance used when deserializing. Registers all custom deserializers defined in * this class. */ - private static final Gson gson = new GsonBuilder() - .registerTypeAdapter(SimpleTable.class, new TableDeserializer()) - .registerTypeAdapter(FunctionInfo.class, new FunctionDeserializer()) - .registerTypeAdapter(FunctionSignature.class, new FunctionSignatureDeserializer()) - .registerTypeAdapter(FunctionArgumentType.class, new FunctionArgumentTypeDeserializer()) - .registerTypeAdapter(TVFInfo.class, new TVFDeserializer()) - .registerTypeAdapter(ProcedureInfo.class, new ProcedureDeserializer()) - .create(); + private static final Gson gson = + new GsonBuilder() + .registerTypeAdapter(SimpleTable.class, new TableDeserializer()) + .registerTypeAdapter(FunctionInfo.class, new FunctionDeserializer()) + .registerTypeAdapter(FunctionSignature.class, new FunctionSignatureDeserializer()) + .registerTypeAdapter(FunctionArgumentType.class, new FunctionArgumentTypeDeserializer()) + .registerTypeAdapter(TVFInfo.class, new TVFDeserializer()) + .registerTypeAdapter(ProcedureInfo.class, new ProcedureDeserializer()) + .create(); /** * Deserializes the {@link CatalogResources} represented by the provided JSON object @@ -166,8 +166,9 @@ private static boolean getFieldAsBoolean( } JsonPrimitive primitive = field.getAsJsonPrimitive(); - boolean isTrueOrFalseString = primitive.isString() - && ImmutableList.of("true", "false").contains(primitive.getAsString().toLowerCase()); + boolean isTrueOrFalseString = + primitive.isString() + && ImmutableList.of("true", "false").contains(primitive.getAsString().toLowerCase()); if (!primitive.isBoolean() && !isTrueOrFalseString) { throw new JsonParseException(errorMessage); @@ -185,18 +186,25 @@ private static Type parseType(String type) { } private static SimpleColumn deserializeSimpleColumn(String tableName, JsonObject jsonColumn) { - String columnName = getFieldAsString( - jsonColumn, "name", - "Invalid JSON column " + jsonColumn + ". Field name should be string"); - String columnType = getFieldAsString( - jsonColumn, "type", - "Invalid JSON column " + jsonColumn + ". Field type should be string"); + String columnName = + getFieldAsString( + jsonColumn, + "name", + "Invalid JSON column " + jsonColumn + ". Field name should be string"); + String columnType = + getFieldAsString( + jsonColumn, + "type", + "Invalid JSON column " + jsonColumn + ". Field type should be string"); Type parsedType = parseType(columnType); - boolean isPseudoColumn = jsonColumn.has("isPseudoColumn") - && getFieldAsBoolean(jsonColumn, "isPseudoColumn", - "Invalid JSON column " + jsonColumn + ". Field isPseudoColumn should be bool"); + boolean isPseudoColumn = + jsonColumn.has("isPseudoColumn") + && getFieldAsBoolean( + jsonColumn, + "isPseudoColumn", + "Invalid JSON column " + jsonColumn + ". Field isPseudoColumn should be bool"); boolean isWriteableColumn = !isPseudoColumn; @@ -206,70 +214,72 @@ && getFieldAsBoolean(jsonColumn, "isPseudoColumn", private static TVFRelation.Column deserializeTVFOutputColumn(JsonObject jsonColumn) { SimpleColumn deserializedSimpleColumn = deserializeSimpleColumn("", jsonColumn); return TVFRelation.Column.create( - deserializedSimpleColumn.getName(), - deserializedSimpleColumn.getType()); + deserializedSimpleColumn.getName(), deserializedSimpleColumn.getType()); } - /** - * Gson deserializer for {@link SimpleTable} - */ + /** Gson deserializer for {@link SimpleTable} */ private static class TableDeserializer implements JsonDeserializer { @Override public SimpleTable deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON table: " + jsonElement + ". Tables should be objects."); - - String tableName = getFieldAsString( - jsonObject, "name", - "Invalid JSON table: " + jsonElement + ". Field name should be string."); - - JsonArray columns = getFieldAsJsonArray( - jsonObject, "columns", - "Invalid JSON table: " + jsonElement + ". Field columns should be array of columns."); - - List parsedColumns = columns - .asList() - .stream() - .map(jsonColumn -> - getAsJsonObject(jsonColumn, - "Invalid JSON column " + jsonColumn + ". Should be JSON object.")) - .map(jsonColumn -> deserializeSimpleColumn(tableName, jsonColumn)) - .collect(Collectors.toList()); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, "Invalid JSON table: " + jsonElement + ". Tables should be objects."); + + String tableName = + getFieldAsString( + jsonObject, + "name", + "Invalid JSON table: " + jsonElement + ". Field name should be string."); + + JsonArray columns = + getFieldAsJsonArray( + jsonObject, + "columns", + "Invalid JSON table: " + jsonElement + ". Field columns should be array of columns."); + + List parsedColumns = + columns.asList().stream() + .map( + jsonColumn -> + getAsJsonObject( + jsonColumn, + "Invalid JSON column " + jsonColumn + ". Should be JSON object.")) + .map(jsonColumn -> deserializeSimpleColumn(tableName, jsonColumn)) + .collect(Collectors.toList()); return new SimpleTable(tableName, parsedColumns); } } - /** - * Gson deserializer for {@link FunctionInfo} - */ + /** Gson deserializer for {@link FunctionInfo} */ private static class FunctionDeserializer implements JsonDeserializer { @Override public FunctionInfo deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON function: " + jsonElement + ". Functions should be objects."); - - String functionName = getFieldAsString( - jsonObject, "name", - "Invalid JSON function: " + jsonElement + ". Field name should be string."); - - FunctionSignature[] signatures = Optional.ofNullable(jsonObject.get("signatures")) - .map(jsonSignatures -> context.deserialize(jsonSignatures, FunctionSignature[].class)) - .map(FunctionSignature[].class::cast) - .orElseThrow(() -> new JsonParseException( - "Invalid JSON function: " + jsonElement + ". Signatures missing.")); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, + "Invalid JSON function: " + jsonElement + ". Functions should be objects."); + + String functionName = + getFieldAsString( + jsonObject, + "name", + "Invalid JSON function: " + jsonElement + ". Field name should be string."); + + FunctionSignature[] signatures = + Optional.ofNullable(jsonObject.get("signatures")) + .map(jsonSignatures -> context.deserialize(jsonSignatures, FunctionSignature[].class)) + .map(FunctionSignature[].class::cast) + .orElseThrow( + () -> + new JsonParseException( + "Invalid JSON function: " + jsonElement + ". Signatures missing.")); return FunctionInfo.newBuilder() .setNamePath(ImmutableList.of(functionName)) @@ -280,65 +290,70 @@ public FunctionInfo deserialize( } } - /** - * Gson deserializer for {@link FunctionSignature} - */ - private static class FunctionSignatureDeserializer implements JsonDeserializer { + /** Gson deserializer for {@link FunctionSignature} */ + private static class FunctionSignatureDeserializer + implements JsonDeserializer { @Override public FunctionSignature deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON function signature: " + jsonElement + ". Should be object."); - - String returnType = getFieldAsString( - jsonObject, "returnType", - "Invalid JSON function signature: " + jsonElement - + ". Field returnType should be string."); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, + "Invalid JSON function signature: " + jsonElement + ". Should be object."); + + String returnType = + getFieldAsString( + jsonObject, + "returnType", + "Invalid JSON function signature: " + + jsonElement + + ". Field returnType should be string."); Type parsedReturnType = parseType(returnType); - FunctionArgumentType[] arguments = Optional.ofNullable(jsonObject.get("arguments")) - .map(jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) - .map(FunctionArgumentType[].class::cast) - .orElseThrow(() -> new JsonParseException( - "Invalid JSON function signature: " + jsonElement + ". Arguments missing.")); + FunctionArgumentType[] arguments = + Optional.ofNullable(jsonObject.get("arguments")) + .map( + jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) + .map(FunctionArgumentType[].class::cast) + .orElseThrow( + () -> + new JsonParseException( + "Invalid JSON function signature: " + + jsonElement + + ". Arguments missing.")); return new FunctionSignature( - new FunctionArgumentType(parsedReturnType), - Arrays.asList(arguments), - -1); - + new FunctionArgumentType(parsedReturnType), Arrays.asList(arguments), -1); } } - /** - * Gson deserializer for {@link FunctionArgumentType} - */ + /** Gson deserializer for {@link FunctionArgumentType} */ private static class FunctionArgumentTypeDeserializer implements JsonDeserializer { @Override public FunctionArgumentType deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON function argument: " + jsonElement + ". Should be object."); - - String argumentName = getFieldAsString( - jsonObject, "name", - "Invalid JSON function argument: " + jsonElement + ". Field name should be string."); - - String argumentType = getFieldAsString( - jsonObject, "type", - "Invalid JSON function argument: " + jsonElement + ". Field type should be string."); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, + "Invalid JSON function argument: " + jsonElement + ". Should be object."); + + String argumentName = + getFieldAsString( + jsonObject, + "name", + "Invalid JSON function argument: " + jsonElement + ". Field name should be string."); + + String argumentType = + getFieldAsString( + jsonObject, + "type", + "Invalid JSON function argument: " + jsonElement + ". Field type should be string."); Type parsedArgumentType = parseType(argumentType); @@ -347,48 +362,54 @@ public FunctionArgumentType deserialize( FunctionArgumentTypeOptions.builder() .setArgumentName(argumentName, NamedArgumentKind.POSITIONAL_OR_NAMED) .build(), - 1 - ); + 1); } } - /** - * Gson deserializer for {@link TVFInfo} - */ + /** Gson deserializer for {@link TVFInfo} */ private static class TVFDeserializer implements JsonDeserializer { @Override public TVFInfo deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON TVF: " + jsonElement + ". TVFs should be objects."); - - String functionName = getFieldAsString( - jsonObject, "name", - "Invalid JSON TVF: " + jsonElement + ". Field name should be string."); - - FunctionArgumentType[] arguments = Optional.ofNullable(jsonObject.get("arguments")) - .map(jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) - .map(FunctionArgumentType[].class::cast) - .orElseThrow(() -> new JsonParseException( - "Invalid JSON TVF: " + jsonElement + ". Arguments missing.")); - - JsonArray outputColumns = getFieldAsJsonArray( - jsonObject, "outputColumns", - "Invalid JSON TVF: " + jsonElement + ". Field outputColumns should be array of columns."); - - List parsedOutputColumns = outputColumns - .asList() - .stream() - .map(jsonColumn -> - getAsJsonObject(jsonColumn, - "Invalid JSON column " + jsonColumn + ". Should be JSON object.")) - .map(JsonCatalogDeserializer::deserializeTVFOutputColumn) - .collect(Collectors.toList()); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, "Invalid JSON TVF: " + jsonElement + ". TVFs should be objects."); + + String functionName = + getFieldAsString( + jsonObject, + "name", + "Invalid JSON TVF: " + jsonElement + ". Field name should be string."); + + FunctionArgumentType[] arguments = + Optional.ofNullable(jsonObject.get("arguments")) + .map( + jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) + .map(FunctionArgumentType[].class::cast) + .orElseThrow( + () -> + new JsonParseException( + "Invalid JSON TVF: " + jsonElement + ". Arguments missing.")); + + JsonArray outputColumns = + getFieldAsJsonArray( + jsonObject, + "outputColumns", + "Invalid JSON TVF: " + + jsonElement + + ". Field outputColumns should be array of columns."); + + List parsedOutputColumns = + outputColumns.asList().stream() + .map( + jsonColumn -> + getAsJsonObject( + jsonColumn, + "Invalid JSON column " + jsonColumn + ". Should be JSON object.")) + .map(JsonCatalogDeserializer::deserializeTVFOutputColumn) + .collect(Collectors.toList()); FunctionArgumentType returnType = new FunctionArgumentType( @@ -404,39 +425,40 @@ public TVFInfo deserialize( } } - /** - * Gson deserializer for {@link ProcedureInfo} - */ + /** Gson deserializer for {@link ProcedureInfo} */ private static class ProcedureDeserializer implements JsonDeserializer { @Override public ProcedureInfo deserialize( - JsonElement jsonElement, - java.lang.reflect.Type type, - JsonDeserializationContext context - ) throws JsonParseException { - JsonObject jsonObject = getAsJsonObject( - jsonElement, - "Invalid JSON procedure: " + jsonElement + ". Preceduress should be objects."); - - String procedureName = getFieldAsString( - jsonObject, "name", - "Invalid JSON procedure: " + jsonElement + ". Field name should be string."); - - FunctionArgumentType[] arguments = Optional.ofNullable(jsonObject.get("arguments")) - .map(jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) - .map(FunctionArgumentType[].class::cast) - .orElseThrow(() -> new JsonParseException( - "Invalid JSON procedure: " + jsonElement + ". Arguments missing.")); + JsonElement jsonElement, java.lang.reflect.Type type, JsonDeserializationContext context) + throws JsonParseException { + JsonObject jsonObject = + getAsJsonObject( + jsonElement, + "Invalid JSON procedure: " + jsonElement + ". Preceduress should be objects."); + + String procedureName = + getFieldAsString( + jsonObject, + "name", + "Invalid JSON procedure: " + jsonElement + ". Field name should be string."); + + FunctionArgumentType[] arguments = + Optional.ofNullable(jsonObject.get("arguments")) + .map( + jsonArguments -> context.deserialize(jsonArguments, FunctionArgumentType[].class)) + .map(FunctionArgumentType[].class::cast) + .orElseThrow( + () -> + new JsonParseException( + "Invalid JSON procedure: " + jsonElement + ". Arguments missing.")); FunctionArgumentType returnType = new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_STRING)); - FunctionSignature signature = new FunctionSignature( - returnType, Arrays.asList(arguments), -1); + FunctionSignature signature = new FunctionSignature(returnType, Arrays.asList(arguments), -1); return new ProcedureInfo(ImmutableList.of(procedureName), signature); } } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/typeparser/ZetaSQLTypeParser.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/typeparser/ZetaSQLTypeParser.java index 32f408f..5e5cfcf 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/typeparser/ZetaSQLTypeParser.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/catalog/typeparser/ZetaSQLTypeParser.java @@ -38,8 +38,8 @@ * Parser for ZetaSQL types. * *

Allows parsing string representations of SQL types to their corresponding Type objects. For - * example; it can parse type strings such as "STRING", "ARRAY<INT64>" - * and "STRUCT<f DECIMAL>". + * example; it can parse type strings such as "STRING", "ARRAY<INT64>" and "STRUCT<f + * DECIMAL>". * *

Uses an ANTLR4 based parser. */ @@ -73,10 +73,8 @@ public static Type parse(String type) { return listener.getResult(); } catch (ParseCancellationException err) { - throw new ZetaSQLTypeParseError( - String.format("Invalid SQL type: %s", type), err); + throw new ZetaSQLTypeParseError(String.format("Invalid SQL type: %s", type), err); } - } /** @@ -87,7 +85,7 @@ private static class ZetaSQLTypeParserListener extends ZetaSQLTypeGrammarBaseLis private static final Map simpleTypeMapping = new HashMap<>(); private final Stack typeStack = new Stack<>(); private final Stack> structFieldStack = new Stack<>(); - + static { simpleTypeMapping.put("STRING", TypeKind.TYPE_STRING); simpleTypeMapping.put("BYTES", TypeKind.TYPE_BYTES); diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnEntity.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnEntity.java index cd7812d..168eb02 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnEntity.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnEntity.java @@ -44,8 +44,7 @@ public boolean equals(Object o) { } ColumnEntity other = (ColumnEntity) o; - return table.equals(other.table) - && name.equalsIgnoreCase(other.name); + return table.equals(other.table) && name.equalsIgnoreCase(other.name); } @Override diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineage.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineage.java index 1d69878..1cb0ac5 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineage.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineage.java @@ -40,8 +40,7 @@ public boolean equals(Object o) { } ColumnLineage other = (ColumnLineage) o; - return target.equals(other.target) - && parents.equals(other.parents); + return target.equals(other.target) && parents.equals(other.parents); } @Override diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineageExtractor.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineageExtractor.java index 4c3f4b3..4aeb025 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineageExtractor.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ColumnLineageExtractor.java @@ -21,7 +21,6 @@ import com.google.zetasql.Table; import com.google.zetasql.Type; import com.google.zetasql.resolvedast.ResolvedColumn; -import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedQueryStmt; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedColumnRef; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedCreateTableAsSelectStmt; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedCreateViewBase; @@ -32,6 +31,7 @@ import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedMergeStmt; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedMergeWhen; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedOutputColumn; +import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedQueryStmt; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedScan; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedStatement; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedUpdateItem; @@ -47,15 +47,16 @@ import java.util.stream.IntStream; /** - * Implements extraction of column-level lineage from ZetaSQL {@link ResolvedStatement}s. - * Supported statements: + * Implements extraction of column-level lineage from ZetaSQL {@link ResolvedStatement}s. Supported + * statements: + * *

    - *
  • SELECT - *
  • CREATE TABLE AS SELECT - *
  • CREATE [MATERIALIZED] VIEW AS SELECT - *
  • INSERT - *
  • UPDATE - *
  • MERGE + *
  • SELECT + *
  • CREATE TABLE AS SELECT + *
  • CREATE [MATERIALIZED] VIEW AS SELECT + *
  • INSERT + *
  • UPDATE + *
  • MERGE *
*/ public class ColumnLineageExtractor { @@ -63,10 +64,8 @@ public class ColumnLineageExtractor { private static ColumnLineage buildColumnLineage( String targetTableName, String targetColumnName, Collection parentColumns) { ColumnEntity target = new ColumnEntity(targetTableName, targetColumnName); - Set parents = parentColumns - .stream() - .map(ColumnEntity::forResolvedColumn) - .collect(Collectors.toSet()); + Set parents = + parentColumns.stream().map(ColumnEntity::forResolvedColumn).collect(Collectors.toSet()); return new ColumnLineage(target, parents); } @@ -75,8 +74,7 @@ private static List expandColumn(ResolvedColumn column) { Type type = column.getType(); if (type.isStruct()) { - return type.asStruct().getFieldList() - .stream() + return type.asStruct().getFieldList().stream() .map(field -> buildColumnSubfield(column, field.getName(), field.getType())) .map(ColumnLineageExtractor::expandColumn) .flatMap(List::stream) @@ -87,8 +85,8 @@ private static List expandColumn(ResolvedColumn column) { } /** - * Extracts the column-level lineage entries for a set of {@link ResolvedOutputColumn}s, - * given the {@link ResolvedStatement} they belong to. + * Extracts the column-level lineage entries for a set of {@link ResolvedOutputColumn}s, given the + * {@link ResolvedStatement} they belong to. * * @param targetTableName The name of the table the output columns write to * @param outputColumns The output columns to find lineage for @@ -115,7 +113,6 @@ private static Set extractColumnLevelLineageForOutputColumns( } return result; - } /** @@ -147,8 +144,7 @@ public static Set extractColumnLevelLineage( List outputColumns = createViewBase.getOutputColumnList(); - return extractColumnLevelLineageForOutputColumns( - fullViewName, outputColumns, createViewBase); + return extractColumnLevelLineageForOutputColumns(fullViewName, outputColumns, createViewBase); } /** @@ -179,23 +175,28 @@ public static Set extractColumnLevelLineage(ResolvedInsertStmt in Table targetTable = insertStmt.getTableScan().getTable(); ResolvedScan query = insertStmt.getQuery(); - List insertedColumns = insertStmt.getInsertColumnList() - .stream() - .map(ColumnLineageExtractor::expandColumn) - .flatMap(List::stream) - .collect(Collectors.toList()); - List matchingColumnsInQuery = query.getColumnList() - .stream() - .map(ColumnLineageExtractor::expandColumn) - .flatMap(List::stream) - .collect(Collectors.toList()); + List insertedColumns = + insertStmt.getInsertColumnList().stream() + .map(ColumnLineageExtractor::expandColumn) + .flatMap(List::stream) + .collect(Collectors.toList()); + List matchingColumnsInQuery = + query.getColumnList().stream() + .map(ColumnLineageExtractor::expandColumn) + .flatMap(List::stream) + .collect(Collectors.toList()); return IntStream.range(0, insertedColumns.size()) - .mapToObj(index -> new SimpleEntry<>( - insertedColumns.get(index), - ParentColumnFinder.findParentsForColumn(insertStmt, matchingColumnsInQuery.get(index)))) - .map(entry -> buildColumnLineage( - targetTable.getFullName(), entry.getKey().getName(), entry.getValue())) + .mapToObj( + index -> + new SimpleEntry<>( + insertedColumns.get(index), + ParentColumnFinder.findParentsForColumn( + insertStmt, matchingColumnsInQuery.get(index)))) + .map( + entry -> + buildColumnLineage( + targetTable.getFullName(), entry.getKey().getName(), entry.getValue())) .collect(Collectors.toSet()); } @@ -203,10 +204,7 @@ public static Set extractColumnLevelLineage(ResolvedInsertStmt in private static ResolvedColumn buildColumnSubfield( ResolvedColumn column, String fieldName, Type fieldType) { return new ResolvedColumn( - column.getId(), - column.getTableName(), - column.getName() + "." + fieldName, - fieldType); + column.getId(), column.getTableName(), column.getName() + "." + fieldName, fieldType); } private static Optional resolveUpdateItemTarget(ResolvedExpr updateTarget) { @@ -216,11 +214,8 @@ private static Optional resolveUpdateItemTarget(ResolvedExpr upd } else if (updateTarget instanceof ResolvedGetStructField) { ResolvedGetStructField getStructField = (ResolvedGetStructField) updateTarget; int structFieldIdx = (int) getStructField.getFieldIdx(); - String fieldName = getStructField.getExpr() - .getType() - .asStruct() - .getField(structFieldIdx) - .getName(); + String fieldName = + getStructField.getExpr().getType().asStruct().getField(structFieldIdx).getName(); return resolveUpdateItemTarget(getStructField.getExpr()) .map(target -> buildColumnSubfield(target, fieldName, getStructField.getType())); } @@ -234,15 +229,13 @@ private static Optional resolveUpdateItemTarget(ResolvedExpr upd * * @param targetTable The {@link Table} this update item writes to * @param updateItem The ResolvedUpdateItem to return lineage for - * @param originalStatement The {@link ResolvedStatement} the update item belongs to. Used - * * to resolve the parent columns of the update expression. + * @param originalStatement The {@link ResolvedStatement} the update item belongs to. Used * to + * resolve the parent columns of the update expression. * @return An optional instance of {@link ColumnLineage}, empty if the update item assigns to - * something other than a column directly. + * something other than a column directly. */ private static Optional extractColumnLevelLineageForUpdateItem( - Table targetTable, - ResolvedUpdateItem updateItem, - ResolvedStatement originalStatement) { + Table targetTable, ResolvedUpdateItem updateItem, ResolvedStatement originalStatement) { ResolvedExpr targetExpression = updateItem.getTarget(); ResolvedExpr updateExpression = updateItem.getSetValue().getValue(); @@ -258,8 +251,8 @@ private static Optional extractColumnLevelLineageForUpdateItem( List parents = ParentColumnFinder.findParentsForExpression(originalStatement, updateExpression); - ColumnLineage result = buildColumnLineage( - targetTable.getFullName(), targetColumn.getName(), parents); + ColumnLineage result = + buildColumnLineage(targetTable.getFullName(), targetColumn.getName(), parents); return Optional.of(result); } @@ -275,8 +268,9 @@ public static Set extractColumnLevelLineage(ResolvedUpdateStmt up List updateItems = updateStmt.getUpdateItemList(); return updateItems.stream() - .map(updateItem -> - extractColumnLevelLineageForUpdateItem(targetTable, updateItem, updateStmt)) + .map( + updateItem -> + extractColumnLevelLineageForUpdateItem(targetTable, updateItem, updateStmt)) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toSet()); @@ -289,13 +283,11 @@ public static Set extractColumnLevelLineage(ResolvedUpdateStmt up * @param targetTable The {@link Table} this merge statement item writes to. * @param mergeWhen The ResolvedMergeWhen to return lineage for. * @param originalStatement The {@link ResolvedMergeStmt} the ResolvedMergeWhen belongs to. Used - * to resolve the lineage of the INSERT/UPDATE operations the ResolvedMergeWhen contains. + * to resolve the lineage of the INSERT/UPDATE operations the ResolvedMergeWhen contains. * @return The set of resulting {@link ColumnLineage} objects. */ private static Set extractColumnLevelLineage( - Table targetTable, - ResolvedMergeWhen mergeWhen, - ResolvedMergeStmt originalStatement) { + Table targetTable, ResolvedMergeWhen mergeWhen, ResolvedMergeStmt originalStatement) { List insertedColumns = mergeWhen.getInsertColumnList(); ResolvedInsertRow insertRow = mergeWhen.getInsertRow(); @@ -304,20 +296,28 @@ private static Set extractColumnLevelLineage( if (Objects.nonNull(insertRow)) { // WHEN ... THEN INSERT return IntStream.range(0, insertedColumns.size()) - .mapToObj(index -> new SimpleEntry<>( - insertedColumns.get(index), - insertRow.getValueList().get(index).getValue())) - .map(entry -> new SimpleEntry<>( - entry.getKey(), - ParentColumnFinder.findParentsForExpression(originalStatement, entry.getValue()))) - .map(entry -> buildColumnLineage( - targetTable.getFullName(), entry.getKey().getName(), entry.getValue())) + .mapToObj( + index -> + new SimpleEntry<>( + insertedColumns.get(index), insertRow.getValueList().get(index).getValue())) + .map( + entry -> + new SimpleEntry<>( + entry.getKey(), + ParentColumnFinder.findParentsForExpression( + originalStatement, entry.getValue()))) + .map( + entry -> + buildColumnLineage( + targetTable.getFullName(), entry.getKey().getName(), entry.getValue())) .collect(Collectors.toSet()); } else if (Objects.nonNull(updateItems)) { // WHEN ... THEN UPDATE return updateItems.stream() - .map(updateItem -> - extractColumnLevelLineageForUpdateItem(targetTable, updateItem, originalStatement)) + .map( + updateItem -> + extractColumnLevelLineageForUpdateItem( + targetTable, updateItem, originalStatement)) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toSet()); @@ -335,11 +335,9 @@ private static Set extractColumnLevelLineage( public static Set extractColumnLevelLineage(ResolvedMergeStmt mergeStmt) { Table targetTable = mergeStmt.getTableScan().getTable(); - return mergeStmt.getWhenClauseList() - .stream() + return mergeStmt.getWhenClauseList().stream() .map(mergeWhen -> extractColumnLevelLineage(targetTable, mergeWhen, mergeStmt)) .flatMap(Set::stream) .collect(Collectors.toSet()); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ExpressionParentFinder.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ExpressionParentFinder.java index 984e179..539bf9b 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ExpressionParentFinder.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ExpressionParentFinder.java @@ -39,11 +39,10 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -/** - * Implements finding the direct {@link ResolvedColumn} parent of a {@link ResolvedExpr}. - */ +/** Implements finding the direct {@link ResolvedColumn} parent of a {@link ResolvedExpr}. */ class ExpressionParentFinder extends Visitor { private final Stack result = new Stack<>(); + public static List findDirectParentsForExpression(ResolvedExpr expression) { ExpressionParentFinder extractor = new ExpressionParentFinder(); expression.accept(extractor); @@ -76,19 +75,23 @@ public void visitResolvedFunctionCallBase(ResolvedFunctionCallBase functionCallB switch (function.getName().toLowerCase()) { case "$case_no_value": - // Must keep all odd arguments (the WHEN expressions), plus the last one (the ELSE expr) - expressionsToVisit = IntStream.range(0, numberOfArguments) - .filter(i -> i % 2 == 1 || i == numberOfArguments - 1) - .mapToObj(arguments::get) - .collect(Collectors.toList()); + // Must keep all odd arguments (the WHEN expressions), plus the last one (the ELSE + // expr) + expressionsToVisit = + IntStream.range(0, numberOfArguments) + .filter(i -> i % 2 == 1 || i == numberOfArguments - 1) + .mapToObj(arguments::get) + .collect(Collectors.toList()); break; case "$case_with_value": - // Must keep all even arguments (the WHEN expressions) but the first one (the CASE value), + // Must keep all even arguments (the WHEN expressions) but the first one (the CASE + // value), // plus the last one (the ELSE expr) - expressionsToVisit = IntStream.range(0, numberOfArguments) - .filter(i -> (i != 0 && i % 2 == 0) || i == numberOfArguments - 1) - .mapToObj(arguments::get) - .collect(Collectors.toList()); + expressionsToVisit = + IntStream.range(0, numberOfArguments) + .filter(i -> (i != 0 && i % 2 == 0) || i == numberOfArguments - 1) + .mapToObj(arguments::get) + .collect(Collectors.toList()); break; case "if": // Remove the first argument (the condition) @@ -128,32 +131,41 @@ public void visit(ResolvedGetStructField getStructField) { String accessedFieldName = structExpressionType.getField(accessedFieldIndex).getName(); if (structExpression instanceof ResolvedMakeStruct) { - // If the user made a STRUCT and immediately accessed a field in it, only consider the parent + // If the user made a STRUCT and immediately accessed a field in it, only consider the + // parent // columns of the corresponding field. ResolvedMakeStruct makeStructExpression = (ResolvedMakeStruct) structExpression; StructType makeStructExpressionType = makeStructExpression.getType().asStruct(); int numberOfFields = makeStructExpressionType.getFieldCount(); - int fieldIndex = IntStream.range(0, numberOfFields) - .filter(index -> - makeStructExpressionType.getField(index).getName().equals(accessedFieldName)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException( - "Field " + accessedFieldName + " does not exist in STRUCT of type: " - + makeStructExpressionType)); + int fieldIndex = + IntStream.range(0, numberOfFields) + .filter( + index -> + makeStructExpressionType.getField(index).getName().equals(accessedFieldName)) + .findFirst() + .orElseThrow( + () -> + new IllegalArgumentException( + "Field " + + accessedFieldName + + " does not exist in STRUCT of type: " + + makeStructExpressionType)); ResolvedExpr fieldExpression = makeStructExpression.getFieldList().get(fieldIndex); - List parentColumns = ExpressionParentFinder.findDirectParentsForExpression(fieldExpression); + List parentColumns = + ExpressionParentFinder.findDirectParentsForExpression(fieldExpression); parentColumns.forEach(result::push); } else { structExpression.accept(this); ResolvedColumn structColumn = result.pop(); - ResolvedColumn parentColumn = new ResolvedColumn( - structColumn.getId(), - structColumn.getTableName(), - structColumn.getName() + "." + accessedFieldName, - getStructField.getType()); + ResolvedColumn parentColumn = + new ResolvedColumn( + structColumn.getId(), + structColumn.getTableName(), + structColumn.getName() + "." + accessedFieldName, + getStructField.getType()); this.result.push(parentColumn); } } @@ -163,5 +175,4 @@ public void visit(ResolvedCast cast) { } private ExpressionParentFinder() {} - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ParentColumnFinder.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ParentColumnFinder.java index 7410862..c1b5c8b 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ParentColumnFinder.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/lineage/ParentColumnFinder.java @@ -21,7 +21,6 @@ import com.google.zetasql.Type; import com.google.zetasql.resolvedast.ResolvedColumn; import com.google.zetasql.resolvedast.ResolvedNode; -import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedAnalyticScan; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedArrayScan; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedComputedColumn; import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedExpr; @@ -51,27 +50,27 @@ * statement. Only "terminal" columns are considered to be parents, meaning columns that read * directly from a table. Intermediate computed columns in the statement are not considered. * - *

Column A being a parent of column B means the content of A is (either directly or indirectly) - * used to write to B. For example: "SELECT A AS B", "UPDATE ... SET B = UPPER(A)", - * "INSERT INTO t(B) SELECT something FROM (SELECT A AS something)", etc. + *

Column A being a parent of column B means the content of A is (either directly or indirectly) + * used to write to B. For example: "SELECT A AS B", "UPDATE ... SET B = UPPER(A)", "INSERT INTO + * t(B) SELECT something FROM (SELECT A AS something)", etc. * - *

The parent columns of an expression E are the terminal parents of all the columns E uses - * as output. For example, the parents of expression E = "UPPER(A, B)" are A and B. If A or B happen - * to not be terminal columns, the parents of E are the terminal parents of A and B themselves. - * Another example; the parents for "IF(condition, trueCase, falseCase)" are all the parents from - * the trueCase and the falseCase, but not the parents from the condition since the condition - * is not used as output. + *

The parent columns of an expression E are the terminal parents of all the columns E uses as + * output. For example, the parents of expression E = "UPPER(A, B)" are A and B. If A or B happen to + * not be terminal columns, the parents of E are the terminal parents of A and B themselves. Another + * example; the parents for "IF(condition, trueCase, falseCase)" are all the parents from the + * trueCase and the falseCase, but not the parents from the condition since the condition is not + * used as output. * - *

Finding parent columns is implemented by traversing the statement the column or expression + *

Finding parent columns is implemented by traversing the statement the column or expression * belongs to. When a {@link ResolvedComputedColumn} node is found; it is registered in the - * columnsToParents Map, together with its direct parents. After traversal, the columnsToParents - * map is used to find all terminal parents for the column or expression in question. + * columnsToParents Map, together with its direct parents. After traversal, the columnsToParents map + * is used to find all terminal parents for the column or expression in question. * - *

There's a special case for WITH statements, since each reference to a WITH entry creates - * a new unique set of {@link ResolvedColumn}s instead of referencing the ones created in the WITH - * subquery. While traversing the statement, this visitor maintains a stack of the - * {@link ResolvedWithEntry}s in scope. When visiting a {@link ResolvedWithRefScan} it uses - * those scopes to correlate the ResolvedWithRefScan columns to their parents in the corresponding + *

There's a special case for WITH statements, since each reference to a WITH entry creates a new + * unique set of {@link ResolvedColumn}s instead of referencing the ones created in the WITH + * subquery. While traversing the statement, this visitor maintains a stack of the {@link + * ResolvedWithEntry}s in scope. When visiting a {@link ResolvedWithRefScan} it uses those scopes to + * correlate the ResolvedWithRefScan columns to their parents in the corresponding * ResolvedWithEntry. */ public class ParentColumnFinder extends Visitor { @@ -115,7 +114,8 @@ public static List findParentsForExpression( public List findImpl(ResolvedNode containerNode, ResolvedColumn column) { // 1. Traverse the containerNode. - // This will populate this.columnsToParents with the ResolvedColumns in the containerNode and + // This will populate this.columnsToParents with the ResolvedColumns in the containerNode + // and // the direct parents for each of them. // columnsToParents can be thought of as a tree where the root node is the original // ResolvedColumn and the leaves are its terminal parents. @@ -162,10 +162,7 @@ private void addParentToColumn(ResolvedColumn column, ResolvedColumn newParent) private ResolvedColumn buildColumnSubfield( ResolvedColumn column, String fieldName, Type fieldType) { return new ResolvedColumn( - column.getId(), - column.getTableName(), - column.getName() + "." + fieldName, - fieldType); + column.getId(), column.getTableName(), column.getName() + "." + fieldName, fieldType); } private List expandColumn(ResolvedColumn column) { @@ -175,8 +172,7 @@ private List expandColumn(ResolvedColumn column) { Type type = column.getType(); if (type.isStruct()) { - type.asStruct().getFieldList() - .stream() + type.asStruct().getFieldList().stream() .map(field -> buildColumnSubfield(column, field.getName(), field.getType())) .flatMap(subColumn -> expandColumn(subColumn).stream()) .forEachOrdered(result::add); @@ -197,9 +193,10 @@ public void visit(ResolvedComputedColumn computedColumn) { if (expression instanceof ResolvedMakeStruct) { expandMakeStruct(column, (ResolvedMakeStruct) expression); } else { - List expressionParents = ExpressionParentFinder.findDirectParentsForExpression(expression); - columnsBeingComputed.forEach(columnBeingComputed -> - addParentsToColumn(columnBeingComputed, expressionParents)); + List expressionParents = + ExpressionParentFinder.findDirectParentsForExpression(expression); + columnsBeingComputed.forEach( + columnBeingComputed -> addParentsToColumn(columnBeingComputed, expressionParents)); } columnsBeingComputed.pop(); @@ -218,8 +215,8 @@ public void expandMakeStruct(ResolvedColumn targetColumn, ResolvedMakeStruct mak columnsBeingComputed.push(fieldColumn); List expressionParents = ExpressionParentFinder.findDirectParentsForExpression(fieldExpression); - columnsBeingComputed.forEach(columnBeingComputed -> - addParentsToColumn(columnBeingComputed, expressionParents)); + columnsBeingComputed.forEach( + columnBeingComputed -> addParentsToColumn(columnBeingComputed, expressionParents)); columnsBeingComputed.pop(); if (fieldExpression instanceof ResolvedMakeStruct) { @@ -262,9 +259,10 @@ private Optional findInScopeWithEntryByName(String name) { for (int i = withEntryScopes.size() - 1; i >= 0; i--) { List inScopeWithEntries = withEntryScopes.get(i); - maybeWithEntry = inScopeWithEntries.stream() - .filter(withEntry -> withEntry.getWithQueryName().equalsIgnoreCase(name)) - .findFirst(); + maybeWithEntry = + inScopeWithEntries.stream() + .filter(withEntry -> withEntry.getWithQueryName().equalsIgnoreCase(name)) + .findFirst(); if (maybeWithEntry.isPresent()) { break; @@ -303,9 +301,7 @@ public void visit(ResolvedWithRefScan withRefScan) { for (int j = 0; j < expandedRefScanColumn.size(); j++) { addParentToColumn(expandedRefScanColumn.get(j), expandedMatchingWithEntryColumn.get(j)); } - } - } public void visit(ResolvedArrayScan arrayScan) { @@ -326,16 +322,16 @@ public void visit(ResolvedSetOperationScan setOperationScan) { for (int i = 0; i < generatedColumns.size(); i++) { int columnIndex = i; ResolvedColumn generatedColumn = generatedColumns.get(columnIndex); - List parentColumns = setOperationItems.stream() - .map(ResolvedSetOperationItem::getOutputColumnList) - .map(outputColumnList -> outputColumnList.get(columnIndex)) - .collect(Collectors.toList()); + List parentColumns = + setOperationItems.stream() + .map(ResolvedSetOperationItem::getOutputColumnList) + .map(outputColumnList -> outputColumnList.get(columnIndex)) + .collect(Collectors.toList()); addParentsToColumn(generatedColumn, parentColumns); } setOperationItems.stream() .map(ResolvedSetOperationItem::getScan) - .forEach(innerScan -> innerScan.accept(this)); + .forEach(innerScan -> innerScan.accept(this)); } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcher.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcher.java index 2a0ce55..a964c6c 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcher.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcher.java @@ -31,33 +31,32 @@ import java.lang.reflect.Field; /** - * Implements some reflection-based patches to ZetaSQL. The only patch currently available is - * {@link #patchMaxProtobufNestingDepth(int)}. + * Implements some reflection-based patches to ZetaSQL. The only patch currently available is {@link + * #patchMaxProtobufNestingDepth(int)}. * - *

These reflection-based patches are brittle by design and should be avoided whenever possible. + *

These reflection-based patches are brittle by design and should be avoided whenever possible. */ public class ZetaSQLPatcher { /** * Patches the maximum protobuf nesting depth allowed when accessing the ZetaSQL local service - * through GRPC. This patch should be applied when working with large SQL statements that - * hit GRPC's default nesting limit of 100. + * through GRPC. This patch should be applied when working with large SQL statements that hit + * GRPC's default nesting limit of 100. * - *

This new max depth is only set for three key RPCs, which result in a lot of nesting when + *

This new max depth is only set for three key RPCs, which result in a lot of nesting when * working with large SQL statements. These RPCs are Parse, Analyze and BuildSql. * - *

This patch should be considered experimental; as it relies on - * {@link ProtoUtils#marshallerWithRecursionLimit(Message, int)} from grpc-java, which is - * experimental itself. + *

This patch should be considered experimental; as it relies on {@link + * ProtoUtils#marshallerWithRecursionLimit(Message, int)} from grpc-java, which is experimental + * itself. * - * @param maxDepth the maximum nesting depth to set for RPCs to the ZetaSQL local service. - * Should be greater than 100. + * @param maxDepth the maximum nesting depth to set for RPCs to the ZetaSQL local service. Should + * be greater than 100. * @throws IllegalAccessException if any reflective access performed by this patch produces an - * illegal access. + * illegal access. */ @ExperimentalApi - public static void patchMaxProtobufNestingDepth(int maxDepth) - throws IllegalAccessException { + public static void patchMaxProtobufNestingDepth(int maxDepth) throws IllegalAccessException { if (!(maxDepth > 100)) { throw new IllegalArgumentException( "Invalid max nesting depth for patching protobuf. Should be at least 100, but got: " @@ -79,14 +78,13 @@ private static Field getLocalServiceField(String name) { } } - private static void patchMaxNestingDepthForAnalyze(int maxDepth) - throws IllegalAccessException { + private static void patchMaxNestingDepthForAnalyze(int maxDepth) throws IllegalAccessException { Field getAnalyzeMethod = getLocalServiceField("getAnalyzeMethod"); - Marshaller requestMarshaller = ProtoUtils.marshallerWithRecursionLimit( - AnalyzeRequest.getDefaultInstance(), maxDepth); - Marshaller responseMarshaller = ProtoUtils.marshallerWithRecursionLimit( - AnalyzeResponse.getDefaultInstance(), maxDepth); + Marshaller requestMarshaller = + ProtoUtils.marshallerWithRecursionLimit(AnalyzeRequest.getDefaultInstance(), maxDepth); + Marshaller responseMarshaller = + ProtoUtils.marshallerWithRecursionLimit(AnalyzeResponse.getDefaultInstance(), maxDepth); MethodDescriptor newMethodDescriptor = ZetaSqlLocalServiceGrpc.getAnalyzeMethod() @@ -99,14 +97,13 @@ private static void patchMaxNestingDepthForAnalyze(int maxDepth) } } - private static void patchMaxNestingDepthForParse(int maxDepth) - throws IllegalAccessException { + private static void patchMaxNestingDepthForParse(int maxDepth) throws IllegalAccessException { Field getParseMethod = getLocalServiceField("getParseMethod"); - Marshaller requestMarshaller = ProtoUtils.marshallerWithRecursionLimit( - ParseRequest.getDefaultInstance(), maxDepth); - Marshaller responseMarshaller = ProtoUtils.marshallerWithRecursionLimit( - ParseResponse.getDefaultInstance(), maxDepth); + Marshaller requestMarshaller = + ProtoUtils.marshallerWithRecursionLimit(ParseRequest.getDefaultInstance(), maxDepth); + Marshaller responseMarshaller = + ProtoUtils.marshallerWithRecursionLimit(ParseResponse.getDefaultInstance(), maxDepth); MethodDescriptor newMethodDescriptor = ZetaSqlLocalServiceGrpc.getParseMethod() @@ -119,14 +116,13 @@ private static void patchMaxNestingDepthForParse(int maxDepth) } } - private static void patchMaxNestingDepthForBuildSql(int maxDepth) - throws IllegalAccessException { + private static void patchMaxNestingDepthForBuildSql(int maxDepth) throws IllegalAccessException { Field getBuildSqlMethod = getLocalServiceField("getBuildSqlMethod"); - Marshaller requestMarshaller = ProtoUtils.marshallerWithRecursionLimit( - BuildSqlRequest.getDefaultInstance(), maxDepth); - Marshaller responseMarshaller = ProtoUtils.marshallerWithRecursionLimit( - BuildSqlResponse.getDefaultInstance(), maxDepth); + Marshaller requestMarshaller = + ProtoUtils.marshallerWithRecursionLimit(BuildSqlRequest.getDefaultInstance(), maxDepth); + Marshaller responseMarshaller = + ProtoUtils.marshallerWithRecursionLimit(BuildSqlResponse.getDefaultInstance(), maxDepth); MethodDescriptor newMethodDescriptor = ZetaSqlLocalServiceGrpc.getBuildSqlMethod() @@ -138,5 +134,4 @@ private static void patchMaxNestingDepthForBuildSql(int maxDepth) getBuildSqlMethod.set(null, newMethodDescriptor); } } - } diff --git a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/usage/UsageTracking.java b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/usage/UsageTracking.java index 61f79ed..e98f158 100644 --- a/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/usage/UsageTracking.java +++ b/zetasql-toolkit-core/src/main/java/com/google/zetasql/toolkit/usage/UsageTracking.java @@ -41,7 +41,8 @@ public class UsageTracking { properties.load(propertiesInputStream); revision = properties.getProperty("zetasql.toolkit.version", "UNSET"); } - } catch (IOException ignored) {} + } catch (IOException ignored) { + } CURRENT_REVISION = revision; USER_AGENT_VALUE = String.format("google-pso-tool/zetasql-helper/%s", revision); diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/AnalyzerExtensionsTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/AnalyzerExtensionsTest.java index 77d6d29..55458bb 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/AnalyzerExtensionsTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/AnalyzerExtensionsTest.java @@ -37,7 +37,9 @@ public class AnalyzerExtensionsTest { void testExtractFunctionNamesFromStatement() { String query = "SELECT f1(), c.f2(), `c.f3`();"; - List> expected = ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2"), ImmutableList.of("c.f3")); + List> expected = + ImmutableList.of( + ImmutableList.of("f1"), ImmutableList.of("c", "f2"), ImmutableList.of("c.f3")); List> extractedFunctions = AnalyzerExtensions.extractFunctionNamesFromStatement(query, languageOptions); @@ -49,7 +51,8 @@ void testExtractFunctionNamesFromStatement() { void testExtractFunctionNamesFromScript() { String script = "INSERT INTO t(column) VALUES (f1(1));\n" + "SELECT c.f2(column) FROM t;\n"; - List> expected = ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2")); + List> expected = + ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2")); List> extractedFunctions = AnalyzerExtensions.extractFunctionNamesFromScript(script, languageOptions); @@ -76,7 +79,9 @@ void testExtractFunctionNamesFromNextStatement() { void testExtractTVFNamesFromStatement() { String query = "SELECT * FROM f1(), c.f2(), `c.f3`();"; - List> expected = ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2"), ImmutableList.of("c.f3")); + List> expected = + ImmutableList.of( + ImmutableList.of("f1"), ImmutableList.of("c", "f2"), ImmutableList.of("c.f3")); List> extractedFunctions = AnalyzerExtensions.extractTVFNamesFromStatement(query, languageOptions); @@ -89,7 +94,8 @@ void testExtractTVFNamesFromScript() { String script = "INSERT INTO t(column) SELECT column FROM f1(1);\n" + "SELECT * FROM c.f2(column);\n"; - List> expected = ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2")); + List> expected = + ImmutableList.of(ImmutableList.of("f1"), ImmutableList.of("c", "f2")); List> extractedFunctions = AnalyzerExtensions.extractTVFNamesFromScript(script, languageOptions); @@ -128,7 +134,8 @@ void testExtractProcedureNamesFromStatement() { void testExtractProcedureNamesFromScript() { String script = "CALL c.p1(); CALL `c.p2`();"; - List> expected = ImmutableList.of(ImmutableList.of("c", "p1"), ImmutableList.of("c.p2")); + List> expected = + ImmutableList.of(ImmutableList.of("c", "p1"), ImmutableList.of("c.p2")); List> extractedProcedures = AnalyzerExtensions.extractProcedureNamesFromScript(script, languageOptions); diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CatalogUpdaterVisitorTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CatalogUpdaterVisitorTest.java index f380e9b..d6f492a 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CatalogUpdaterVisitorTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CatalogUpdaterVisitorTest.java @@ -35,7 +35,6 @@ import com.google.zetasql.toolkit.catalog.CatalogWrapper; import com.google.zetasql.toolkit.catalog.FunctionInfo; import com.google.zetasql.toolkit.catalog.TVFInfo; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -119,7 +118,9 @@ void testCreateTableAsSelectStmt() { .build())) .setOutputColumnList(ImmutableList.of(resolvedOutputColumn)) .setQuery( - ResolvedSingleRowScan.builder().setColumnList(ImmutableList.of(resolvedColumn)).build()) + ResolvedSingleRowScan.builder() + .setColumnList(ImmutableList.of(resolvedColumn)) + .build()) .setIsValueTable(false) .build(); @@ -175,7 +176,9 @@ void testCreateViewStmt() { .setCreateMode(CreateMode.CREATE_DEFAULT) .setOutputColumnList(ImmutableList.of(resolvedOutputColumn)) .setQuery( - ResolvedSingleRowScan.builder().setColumnList(ImmutableList.of(resolvedColumn)).build()) + ResolvedSingleRowScan.builder() + .setColumnList(ImmutableList.of(resolvedColumn)) + .build()) .setIsValueTable(false) .setHasExplicitColumns(true) .setRecursive(false) @@ -206,7 +209,9 @@ void testCreateMaterializedViewStmt() { .setCreateMode(CreateMode.CREATE_DEFAULT) .setOutputColumnList(ImmutableList.of(resolvedOutputColumn)) .setQuery( - ResolvedSingleRowScan.builder().setColumnList(ImmutableList.of(resolvedColumn)).build()) + ResolvedSingleRowScan.builder() + .setColumnList(ImmutableList.of(resolvedColumn)) + .build()) .setIsValueTable(false) .setHasExplicitColumns(true) .setRecursive(false) @@ -227,7 +232,8 @@ void testCreateFunction() { FunctionSignature signature = new FunctionSignature( new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_STRING)), - ImmutableList.of(new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_INT64))), + ImmutableList.of( + new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_INT64))), -1); Function expectedFunction = @@ -269,12 +275,14 @@ void testCreateTVF() { FunctionSignature signature = new FunctionSignature( new FunctionArgumentType(SignatureArgumentKind.ARG_TYPE_RELATION), - ImmutableList.of(new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_INT64))), + ImmutableList.of( + new FunctionArgumentType(TypeFactory.createSimpleType(TypeKind.TYPE_INT64))), -1); TVFRelation tvfOutputSchema = TVFRelation.createColumnBased( - ImmutableList.of(Column.create("output", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); + ImmutableList.of( + Column.create("output", TypeFactory.createSimpleType(TypeKind.TYPE_STRING)))); TVFInfo expectedFunction = TVFInfo.newBuilder() diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CoercerTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CoercerTest.java index 40caff2..e0efd95 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CoercerTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/CoercerTest.java @@ -43,11 +43,9 @@ void testBasicCoercions() { Coercer coercer = new Coercer(languageOptions); assertTrue( - coercer.coercesTo(int32Type, int64Type, false, false), - "Expect INT32 to coerce to INT64"); + coercer.coercesTo(int32Type, int64Type, false, false), "Expect INT32 to coerce to INT64"); assertTrue( - coercer.coercesTo(int32Type, doubleType, false, false), - "Expect INT32 to coerce to DOUBLE"); + coercer.coercesTo(int32Type, doubleType, false, false), "Expect INT32 to coerce to DOUBLE"); assertFalse( coercer.coercesTo(int32Type, stringType, false, false), "Expect INT32 to not coerce to STRING"); @@ -70,12 +68,10 @@ void testBasicCoercions() { @Test void testArrayCoercions() { - Type int32Array = TypeFactory.createArrayType( - TypeFactory.createSimpleType(TypeKind.TYPE_INT32) - ); - Type int64Array = TypeFactory.createArrayType( - TypeFactory.createSimpleType(TypeKind.TYPE_INT64) - ); + Type int32Array = + TypeFactory.createArrayType(TypeFactory.createSimpleType(TypeKind.TYPE_INT32)); + Type int64Array = + TypeFactory.createArrayType(TypeFactory.createSimpleType(TypeKind.TYPE_INT64)); LanguageOptions languageOptions = new LanguageOptions(); @@ -100,12 +96,14 @@ void testArrayCoercions() { @Test void testStructCoercions() { - Type structWithInt32Field = TypeFactory.createStructType(ImmutableList.of( - new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT32)) - )); - Type structWithInt64Field = TypeFactory.createStructType(ImmutableList.of( - new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT64)) - )); + Type structWithInt32Field = + TypeFactory.createStructType( + ImmutableList.of( + new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT32)))); + Type structWithInt64Field = + TypeFactory.createStructType( + ImmutableList.of( + new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT64)))); LanguageOptions languageOptions = new LanguageOptions(); languageOptions.enableMaximumLanguageFeatures(); @@ -119,16 +117,16 @@ void testStructCoercions() { @Test void testComplexCoercions() { - Type int32StructArray = TypeFactory.createArrayType( - TypeFactory.createStructType(ImmutableList.of( - new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT32)) - )) - ); - Type int64StructArray = TypeFactory.createArrayType( - TypeFactory.createStructType(ImmutableList.of( - new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT64)) - )) - ); + Type int32StructArray = + TypeFactory.createArrayType( + TypeFactory.createStructType( + ImmutableList.of( + new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT32))))); + Type int64StructArray = + TypeFactory.createArrayType( + TypeFactory.createStructType( + ImmutableList.of( + new StructField("field", TypeFactory.createSimpleType(TypeKind.TYPE_INT64))))); LanguageOptions languageOptions = new LanguageOptions(); languageOptions.enableMaximumLanguageFeatures(); @@ -138,7 +136,5 @@ void testComplexCoercions() { assertTrue( coercer.coercesTo(int32StructArray, int64StructArray, true, false), "Expect compatible ARRAY> literals to coerce to one another"); - } - } diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/ZetaSQLToolkitTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/ZetaSQLToolkitTest.java index 356713f..acd50d2 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/ZetaSQLToolkitTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/ZetaSQLToolkitTest.java @@ -68,8 +68,7 @@ void testSimpleSelectStmt() { @Test void testTableDDL() { - String query = "CREATE TEMP TABLE t AS (SELECT 1 AS column);\n" - + "SELECT * FROM t;"; + String query = "CREATE TEMP TABLE t AS (SELECT 1 AS column);\n" + "SELECT * FROM t;"; SimpleCatalog catalog = new SimpleCatalog("catalog"); Iterator statementIterator = @@ -83,8 +82,7 @@ void testTableDDL() { assertAll( () -> assertEquals("t", table.getName()), () -> assertEquals(1, table.getColumnList().size()), - () -> assertEquals("column", table.getColumnList().get(0).getName()) - ); + () -> assertEquals("column", table.getColumnList().get(0).getName())); // Just check that the second statement was analyzed successfully AnalyzedStatement second = statementIterator.next(); @@ -94,8 +92,7 @@ void testTableDDL() { @Test void testVariableDeclaration() { - String query = "DECLARE x INT64 DEFAULT 1;\n" - + "SELECT x;"; + String query = "DECLARE x INT64 DEFAULT 1;\n" + "SELECT x;"; SimpleCatalog catalog = new SimpleCatalog("catalog"); Iterator statementIterator = @@ -131,11 +128,9 @@ void testTypeCoercion() { assertThrows(AnalysisException.class, statementIterator::next); // Invalid type for SET statement - query = "DECLARE x INT64;\n" - + "SET x = 'ASD';"; + query = "DECLARE x INT64;\n" + "SET x = 'ASD';"; statementIterator = this.analyzer.analyzeStatements(query); statementIterator.next(); assertThrows(AnalysisException.class, statementIterator::next); } - } diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/catalog/CatalogOperationsTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/catalog/CatalogOperationsTest.java index d00ac40..15bdb61 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/catalog/CatalogOperationsTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/catalog/CatalogOperationsTest.java @@ -74,7 +74,10 @@ void testCreateTableInCatalog() { CatalogOperations.createTableInCatalog( this.testCatalog, newTable.getFullName(), newTable, CreateMode.CREATE_DEFAULT); - assertTableExists(this.testCatalog, ImmutableList.of("qualified.newTable"), "Expected created table to exist"); + assertTableExists( + this.testCatalog, + ImmutableList.of("qualified.newTable"), + "Expected created table to exist"); } @Test @@ -83,9 +86,7 @@ void testDeleteTableFromCatalog() { CatalogOperations.deleteTableFromCatalog(this.testCatalog, "sample"); assertTableDoesNotExist( - this.testCatalog, ImmutableList.of("sample"), - "Expected table to have been deleted"); - + this.testCatalog, ImmutableList.of("sample"), "Expected table to have been deleted"); } @Test @@ -115,12 +116,12 @@ void testReplaceTable() { new SimpleColumn( tableName, "column", TypeFactory.createSimpleType(TypeKind.TYPE_INT64)))); - CatalogOperations.createTableInCatalog( this.testCatalog, newTable.getFullName(), newTable, CreateMode.CREATE_OR_REPLACE); - Table foundTable = assertTableExists( - this.testCatalog, ImmutableList.of("sample"), "Expected replaced table to exist"); + Table foundTable = + assertTableExists( + this.testCatalog, ImmutableList.of("sample"), "Expected replaced table to exist"); assertEquals( foundTable.getColumn(0).getType(), @@ -171,9 +172,7 @@ void testCreateTableIfNotExists_NewTable() { this.testCatalog, newTable.getFullName(), newTable, CreateMode.CREATE_IF_NOT_EXISTS); assertTableExists( - this.testCatalog, - ImmutableList.of("newTable"), - "Expected table to have been created"); + this.testCatalog, ImmutableList.of("newTable"), "Expected table to have been created"); } private Function assertFunctionExists(SimpleCatalog catalog, String fullName, String message) { @@ -209,7 +208,6 @@ void testCreateFunctionInCatalog() { assertFunctionExists( this.testCatalog, "UDF:qualified.newFunction", "Expected created function to exist"); - } @Test @@ -233,10 +231,7 @@ void testDeleteFunctionFromCatalog() { CatalogOperations.deleteFunctionFromCatalog(this.testCatalog, "qualified.newFunction"); assertFunctionDoesNotExist( - this.testCatalog, - "UDF:qualified.newFunction", - "Expected function to have been deleted"); - + this.testCatalog, "UDF:qualified.newFunction", "Expected function to have been deleted"); } private TableValuedFunction assertTVFExists(SimpleCatalog catalog, String name, String message) { @@ -275,18 +270,19 @@ void testCreateTVFInCatalog() { @Test void testDeleteTVFFromCatalog() { - TVFInfo tvf = TVFInfo.newBuilder() - .setNamePath(ImmutableList.of("qualified.newTVF")) - .setSignature( - new FunctionSignature( - new FunctionArgumentType( - ZetaSQLFunctions.SignatureArgumentKind.ARG_TYPE_RELATION), - ImmutableList.of(), - -1)) - .setOutputSchema( - TVFRelation.createValueTableBased( - TypeFactory.createSimpleType(TypeKind.TYPE_STRING))) - .build(); + TVFInfo tvf = + TVFInfo.newBuilder() + .setNamePath(ImmutableList.of("qualified.newTVF")) + .setSignature( + new FunctionSignature( + new FunctionArgumentType( + ZetaSQLFunctions.SignatureArgumentKind.ARG_TYPE_RELATION), + ImmutableList.of(), + -1)) + .setOutputSchema( + TVFRelation.createValueTableBased( + TypeFactory.createSimpleType(TypeKind.TYPE_STRING))) + .build(); CatalogOperations.createTVFInCatalog( this.testCatalog, "qualified.newTVF", tvf, CreateMode.CREATE_DEFAULT); @@ -355,9 +351,7 @@ void testDeleteProcedureFromCatalog() { this.testCatalog, procedurePath1, "Expected procedure to have been deleted"), () -> assertProcedureDoesNotExist( - this.testCatalog, - procedurePath2, - "Expected procedure to have been deleted")); + this.testCatalog, procedurePath2, "Expected procedure to have been deleted")); } @Test diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcherTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcherTest.java index 01fff8c..f8db74a 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcherTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/tools/patch/ZetaSQLPatcherTest.java @@ -19,7 +19,6 @@ import static org.junit.jupiter.api.Assertions.*; import com.google.zetasql.AnalyzerOptions; -import com.google.zetasql.Parser; import com.google.zetasql.toolkit.ZetaSQLToolkitAnalyzer; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeEach; @@ -45,6 +44,7 @@ public static String generateNestedSelectStatement(int times) { return String.format("SELECT 1 FROM (%s)", generateNestedSelectStatement(times - 1)); } + @Test void testMaxNestingDepthPatch() { // The query is a SELECT statement nested 100 times. Parsing or analyzing @@ -56,13 +56,14 @@ void testMaxNestingDepthPatch() { try { ZetaSQLPatcher.patchMaxProtobufNestingDepth(1000); } catch (IllegalAccessException err) { - Assumptions.abort("Aborting test because the patch was not applied successfully due to " - + "disallowed reflective access."); + Assumptions.abort( + "Aborting test because the patch was not applied successfully due to " + + "disallowed reflective access."); } - assertDoesNotThrow(() -> { - this.analyzer.analyzeStatements(query).next(); - }); + assertDoesNotThrow( + () -> { + this.analyzer.analyzeStatements(query).next(); + }); } - } diff --git a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/usage/UsageTrackingTest.java b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/usage/UsageTrackingTest.java index 2310d03..bfb5ac9 100644 --- a/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/usage/UsageTrackingTest.java +++ b/zetasql-toolkit-core/src/test/java/com/google/zetasql/toolkit/usage/UsageTrackingTest.java @@ -10,8 +10,7 @@ public class UsageTrackingTest { @Test public void testRevisionIsSet() { assertNotNull(UsageTracking.CURRENT_REVISION, "Project revision not set"); - assertNotEquals( - "UNSET", UsageTracking.CURRENT_REVISION, "Project revision not set"); + assertNotEquals("UNSET", UsageTracking.CURRENT_REVISION, "Project revision not set"); } @Test @@ -20,5 +19,4 @@ public void testUserAgentIsSet() { String userAgentValue = headerProvider.getHeaders().get("user-agent"); assertNotNull(userAgentValue, "User agent for API calls not set"); } - } diff --git a/zetasql-toolkit-examples/pom.xml b/zetasql-toolkit-examples/pom.xml index 0c9433c..29c68ce 100644 --- a/zetasql-toolkit-examples/pom.xml +++ b/zetasql-toolkit-examples/pom.xml @@ -16,54 +16,60 @@ limitations under the License. --> - - 4.0.0 + + 4.0.0 - - com.google.zetasql.toolkit - zetasql-toolkit - 0.5.0 - ../pom.xml - - - zetasql-toolkit-examples + + com.google.zetasql.toolkit + zetasql-toolkit 0.5.0 - ${project.groupId}:${project.artifactId} + ../pom.xml + + + zetasql-toolkit-examples + 0.5.0 + ${project.groupId}:${project.artifactId} - - ${project.version} - UTF-8 - true - 3.3.2 - - + + ${project.version} + UTF-8 + true + 3.3.2 + + - - - zetasql-toolkit-bigquery - com.google.zetasql.toolkit - ${zetasql.toolkit.version} - - - zetasql-toolkit-spanner - com.google.zetasql.toolkit - ${zetasql.toolkit.version} - - + + + zetasql-toolkit-bigquery + com.google.zetasql.toolkit + ${zetasql.toolkit.version} + + + zetasql-toolkit-spanner + com.google.zetasql.toolkit + ${zetasql.toolkit.version} + + - - - - com.google.cloud.tools - jib-maven-plugin - ${google.cloud.jib.version} - - - ${container.mainClass} - - - - - + + + + com.google.cloud.tools + jib-maven-plugin + ${google.cloud.jib.version} + + + ${container.mainClass} + + + + + com.diffplug.spotless + spotless-maven-plugin + + + \ No newline at end of file diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToBigQueryCatalog.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToBigQueryCatalog.java index 6932c07..8fcd456 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToBigQueryCatalog.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToBigQueryCatalog.java @@ -41,7 +41,8 @@ public static void main(String[] args) { // For the time being, functions must have an explicit return type (i.e. creating with // a RETURNS clause); otherwise adding them will fail. catalog.addFunction("project.dataset.function"); - catalog.addFunctions(ImmutableList.of("project.dataset.function2", "project.dataset.function3")); + catalog.addFunctions( + ImmutableList.of("project.dataset.function2", "project.dataset.function3")); // Add all functions in a dataset or project // For the time being, functions without an explicit return type are silently ignored @@ -61,7 +62,8 @@ public static void main(String[] args) { // Add a procedure or a set of procedures by name catalog.addProcedure("project.dataset.procedure"); - catalog.addProcedures(ImmutableList.of("project.dataset.procedure1", "project.dataset.procedure2")); + catalog.addProcedures( + ImmutableList.of("project.dataset.procedure1", "project.dataset.procedure2")); // Add all procedures in a dataset or project catalog.addAllProceduresInDataset("projectId", "datasetName"); diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToSpannerCatalog.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToSpannerCatalog.java index 67e2036..5786b08 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToSpannerCatalog.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AddResourcesToSpannerCatalog.java @@ -22,8 +22,7 @@ public class AddResourcesToSpannerCatalog { public static void main(String[] args) { - SpannerCatalog catalog = SpannerCatalog.usingSpannerClient( - "projectId", "instance", "database"); + SpannerCatalog catalog = SpannerCatalog.usingSpannerClient("projectId", "instance", "database"); // Add a table or a set of tables by name // Views are considered tables as well, so they can be added this way to the catalog diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeBigQuery.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeBigQuery.java index 974ab79..8a92649 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeBigQuery.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeBigQuery.java @@ -32,13 +32,14 @@ public class AnalyzeBigQuery { public static void main(String[] args) { // Analyzing a query that uses bigquery-public-data tables String query = - "DECLARE x STRING DEFAULT 'ASD';" + - "SET x = 'ASD2';" + - "INSERT INTO `bigquery-public-data.samples.wikipedia` (title) VALUES ('random title');\n" + "DECLARE x STRING DEFAULT 'ASD';" + + "SET x = 'ASD2';" + + "INSERT INTO `bigquery-public-data.samples.wikipedia` (title) VALUES ('random title');\n" + "SELECT title, language FROM `bigquery-public-data.samples.wikipedia` WHERE title = 'random title';"; // Step 1: Create a BigQueryCatalog - // In this case, we provide the project id where queries are assumed to be running. The catalog + // In this case, we provide the project id where queries are assumed to be running. The + // catalog // will connect to the BigQuery API using application-default credentials to access BigQuery // resources. // You can also provide your own BigQuery API client or a custom implementation of @@ -48,13 +49,15 @@ public static void main(String[] args) { // Step 2: Add tables to the catalog before analyzing // BigQueryCatalog.addTable will fetch the table metadata and // create the table in the catalog. - // Just as we can add tables and views; we can also add UDFs, TVFs and Procedures from BigQuery. + // Just as we can add tables and views; we can also add UDFs, TVFs and Procedures from + // BigQuery. // See also: BigQueryCatalog.addAllTablesInDataset and BigQueryCatalog.addAllTablesInProject catalog.addTable("bigquery-public-data.samples.wikipedia"); // Step 3: Define the LanguageOptions and AnalyzerOptions to configure the ZetaSQL analyzer - // LanguageOptions are ZetaSQL's way of customizing the SQL dialect the analyzer accepts. This + // LanguageOptions are ZetaSQL's way of customizing the SQL dialect the analyzer accepts. + // This // toolkit // includes properly configured LanguageOptions for BigQuery. @@ -71,7 +74,7 @@ public static void main(String[] args) { Iterator statementIterator = analyzer.analyzeStatements(query, catalog); // Step 5: Consume the previous iterator and use the ResolvedStatements however you need - statementIterator.forEachRemaining(statement -> - statement.getResolvedStatement().ifPresent(System.out::println)); + statementIterator.forEachRemaining( + statement -> statement.getResolvedStatement().ifPresent(System.out::println)); } } diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeCloudSpanner.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeCloudSpanner.java index 7cec381..a084599 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeCloudSpanner.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeCloudSpanner.java @@ -39,8 +39,9 @@ public static void main(String[] args) { // This will use application default credentials to create a Spanner DatabaseClient. // You can also provide your own DatabaseClient or a custom implementation // of SpannerResourceProvider. - SpannerCatalog catalog = SpannerCatalog.usingSpannerClient( - spannerProjectId, spannerInstanceName, spannerDatabaseName); + SpannerCatalog catalog = + SpannerCatalog.usingSpannerClient( + spannerProjectId, spannerInstanceName, spannerDatabaseName); // Step 3: Add your tables to the catalog // In this case, we add all the tables in the database. @@ -61,7 +62,7 @@ public static void main(String[] args) { ZetaSQLToolkitAnalyzer analyzer = new ZetaSQLToolkitAnalyzer(options); analyzer .analyzeStatements(query, catalog) - .forEachRemaining(statement -> - statement.getResolvedStatement().ifPresent(System.out::println)); + .forEachRemaining( + statement -> statement.getResolvedStatement().ifPresent(System.out::println)); } } diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeWithoutCatalog.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeWithoutCatalog.java index e851c7d..f1b1b3c 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeWithoutCatalog.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzeWithoutCatalog.java @@ -18,7 +18,6 @@ import com.google.zetasql.AnalyzerOptions; import com.google.zetasql.LanguageOptions; -import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedStatement; import com.google.zetasql.toolkit.AnalyzedStatement; import com.google.zetasql.toolkit.ZetaSQLToolkitAnalyzer; import java.util.Iterator; @@ -36,7 +35,8 @@ public static void main(String[] args) { // LanguageOptions are ZetaSQL's way of customizing the SQL dialect the analyzer accepts. // Using LanguageOptions, we can: // * enable or disable language features, such as whether TVFs are accepted - // * enable or disable statement kinds, for example, whether ALTER TABLE statements are allowed + // * enable or disable statement kinds, for example, whether ALTER TABLE statements are + // allowed // This toolkit includes properly configured LanguageOptions for BigQuery and Cloud Spanner LanguageOptions languageOptions = new LanguageOptions().enableMaximumLanguageFeatures(); languageOptions.setSupportsAllStatementKinds(); @@ -54,7 +54,7 @@ public static void main(String[] args) { Iterator statementIterator = analyzer.analyzeStatements(query); // Step 3: Consume the previous iterator and use the ResolvedStatements however you need - statementIterator.forEachRemaining(statement -> - statement.getResolvedStatement().ifPresent(System.out::println)); + statementIterator.forEachRemaining( + statement -> statement.getResolvedStatement().ifPresent(System.out::println)); } } diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzingCreateStatements.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzingCreateStatements.java index 4e62fdc..723a06e 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzingCreateStatements.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/AnalyzingCreateStatements.java @@ -17,7 +17,6 @@ package com.google.zetasql.toolkit.examples; import com.google.zetasql.AnalyzerOptions; -import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedStatement; import com.google.zetasql.toolkit.AnalyzedStatement; import com.google.zetasql.toolkit.ZetaSQLToolkitAnalyzer; import com.google.zetasql.toolkit.catalog.bigquery.BigQueryCatalog; @@ -48,7 +47,7 @@ public static void main(String[] args) { ZetaSQLToolkitAnalyzer analyzer = new ZetaSQLToolkitAnalyzer(options); Iterator statementIterator = analyzer.analyzeStatements(query, catalog); - statementIterator.forEachRemaining(statement -> - statement.getResolvedStatement().ifPresent(System.out::println)); + statementIterator.forEachRemaining( + statement -> statement.getResolvedStatement().ifPresent(System.out::println)); } } diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/ExtractColumnLevelLineage.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/ExtractColumnLevelLineage.java index 43355b7..270282b 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/ExtractColumnLevelLineage.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/ExtractColumnLevelLineage.java @@ -27,9 +27,9 @@ import com.google.zetasql.toolkit.ZetaSQLToolkitAnalyzer; import com.google.zetasql.toolkit.catalog.bigquery.BigQueryCatalog; import com.google.zetasql.toolkit.options.BigQueryLanguageOptions; -import com.google.zetasql.toolkit.tools.lineage.ColumnLineageExtractor; import com.google.zetasql.toolkit.tools.lineage.ColumnEntity; import com.google.zetasql.toolkit.tools.lineage.ColumnLineage; +import com.google.zetasql.toolkit.tools.lineage.ColumnLineageExtractor; import java.util.Iterator; import java.util.Set; @@ -39,28 +39,30 @@ private static void outputLineage(String query, Set lineageEntrie System.out.println("\nQuery:"); System.out.println(query); System.out.println("\nLineage:"); - lineageEntries.forEach(lineage -> { - System.out.printf("%s.%s\n", lineage.target.table, lineage.target.name); - for (ColumnEntity parent : lineage.parents) { - System.out.printf("\t\t<- %s.%s\n", parent.table, parent.name); - } - }); + lineageEntries.forEach( + lineage -> { + System.out.printf("%s.%s\n", lineage.target.table, lineage.target.name); + for (ColumnEntity parent : lineage.parents) { + System.out.printf("\t\t<- %s.%s\n", parent.table, parent.name); + } + }); System.out.println(); System.out.println(); } private static void lineageForCreateTableAsSelectStatement( BigQueryCatalog catalog, ZetaSQLToolkitAnalyzer analyzer) { - String query = "CREATE TABLE `project.dataset.table` AS\n" - + "SELECT\n" - + " concatted AS column_alias\n" - + "FROM\n" - + " (\n" - + " SELECT \n" - + " UPPER(CONCAT(title, comment)) AS concatted\n" - + " FROM `bigquery-public-data`.samples.wikipedia\n" - + " )\n" - + "GROUP BY 1;"; + String query = + "CREATE TABLE `project.dataset.table` AS\n" + + "SELECT\n" + + " concatted AS column_alias\n" + + "FROM\n" + + " (\n" + + " SELECT \n" + + " UPPER(CONCAT(title, comment)) AS concatted\n" + + " FROM `bigquery-public-data`.samples.wikipedia\n" + + " )\n" + + "GROUP BY 1;"; Iterator statementIterator = analyzer.analyzeStatements(query, catalog); ResolvedStatement statement = statementIterator.next().getResolvedStatement().get(); @@ -76,17 +78,18 @@ private static void lineageForCreateTableAsSelectStatement( private static void lineageForInsertStatement( BigQueryCatalog catalog, ZetaSQLToolkitAnalyzer analyzer) { - String query = "INSERT INTO `bigquery-public-data.samples.wikipedia`(title, comment)\n" - + "SELECT\n" - + " LOWER(upper_corpus) AS titleaaaaaa,\n" - + " UPPER(lower_word) AS comment\n" - + "FROM (\n" - + " SELECT\n" - + " UPPER(corpus) AS upper_corpus,\n" - + " LOWER(word) AS lower_word\n" - + " FROM `bigquery-public-data.samples.shakespeare`\n" - + " WHERE word_count > 10\n" - + " );"; + String query = + "INSERT INTO `bigquery-public-data.samples.wikipedia`(title, comment)\n" + + "SELECT\n" + + " LOWER(upper_corpus) AS titleaaaaaa,\n" + + " UPPER(lower_word) AS comment\n" + + "FROM (\n" + + " SELECT\n" + + " UPPER(corpus) AS upper_corpus,\n" + + " LOWER(word) AS lower_word\n" + + " FROM `bigquery-public-data.samples.shakespeare`\n" + + " WHERE word_count > 10\n" + + " );"; Iterator statementIterator = analyzer.analyzeStatements(query, catalog); @@ -102,10 +105,11 @@ private static void lineageForInsertStatement( private static void lineageForUpdateStatement( BigQueryCatalog catalog, ZetaSQLToolkitAnalyzer analyzer) { - String query = "UPDATE `bigquery-public-data.samples.wikipedia` W\n" - + " SET title = S.corpus, comment = S.word\n" - + "FROM (SELECT corpus, UPPER(word) AS word FROM `bigquery-public-data.samples.shakespeare`) S\n" - + "WHERE W.title = S.corpus;"; + String query = + "UPDATE `bigquery-public-data.samples.wikipedia` W\n" + + " SET title = S.corpus, comment = S.word\n" + + "FROM (SELECT corpus, UPPER(word) AS word FROM `bigquery-public-data.samples.shakespeare`) S\n" + + "WHERE W.title = S.corpus;"; Iterator statementIterator = analyzer.analyzeStatements(query, catalog); @@ -121,13 +125,14 @@ private static void lineageForUpdateStatement( private static void lineageForMergeStatement( BigQueryCatalog catalog, ZetaSQLToolkitAnalyzer analyzer) { - String query = "MERGE `bigquery-public-data.samples.wikipedia` W\n" - + "USING (SELECT corpus, UPPER(word) AS word FROM `bigquery-public-data.samples.shakespeare`) S\n" - + "ON W.title = S.corpus\n" - + "WHEN MATCHED THEN\n" - + " UPDATE SET comment = S.word\n" - + "WHEN NOT MATCHED THEN\n" - + " INSERT(title) VALUES (UPPER(corpus));"; + String query = + "MERGE `bigquery-public-data.samples.wikipedia` W\n" + + "USING (SELECT corpus, UPPER(word) AS word FROM `bigquery-public-data.samples.shakespeare`) S\n" + + "ON W.title = S.corpus\n" + + "WHEN MATCHED THEN\n" + + " UPDATE SET comment = S.word\n" + + "WHEN NOT MATCHED THEN\n" + + " INSERT(title) VALUES (UPPER(corpus));"; Iterator statementIterator = analyzer.analyzeStatements(query, catalog); @@ -142,10 +147,9 @@ private static void lineageForMergeStatement( public static void main(String[] args) { BigQueryCatalog catalog = BigQueryCatalog.usingBigQueryAPI("bigquery-public-data"); - catalog.addTables(ImmutableList.of( - "bigquery-public-data.samples.wikipedia", - "bigquery-public-data.samples.shakespeare" - )); + catalog.addTables( + ImmutableList.of( + "bigquery-public-data.samples.wikipedia", "bigquery-public-data.samples.shakespeare")); AnalyzerOptions options = new AnalyzerOptions(); options.setLanguageOptions(BigQueryLanguageOptions.get()); @@ -160,5 +164,4 @@ public static void main(String[] args) { System.out.println("-----------------------------------"); lineageForMergeStatement(catalog, analyzer); } - } diff --git a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/LoadTablesUsedInQuery.java b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/LoadTablesUsedInQuery.java index e169539..eaf3a29 100644 --- a/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/LoadTablesUsedInQuery.java +++ b/zetasql-toolkit-examples/src/main/java/com/google/zetasql/toolkit/examples/LoadTablesUsedInQuery.java @@ -17,7 +17,6 @@ package com.google.zetasql.toolkit.examples; import com.google.zetasql.AnalyzerOptions; -import com.google.zetasql.resolvedast.ResolvedNodes.ResolvedStatement; import com.google.zetasql.toolkit.AnalyzedStatement; import com.google.zetasql.toolkit.ZetaSQLToolkitAnalyzer; import com.google.zetasql.toolkit.catalog.bigquery.BigQueryCatalog; @@ -46,7 +45,7 @@ public static void main(String[] args) { ZetaSQLToolkitAnalyzer analyzer = new ZetaSQLToolkitAnalyzer(options); Iterator statementIterator = analyzer.analyzeStatements(query, catalog); - statementIterator.forEachRemaining(statement -> - statement.getResolvedStatement().ifPresent(System.out::println)); + statementIterator.forEachRemaining( + statement -> statement.getResolvedStatement().ifPresent(System.out::println)); } } diff --git a/zetasql-toolkit-spanner/pom.xml b/zetasql-toolkit-spanner/pom.xml index 40f73f6..a8b354d 100644 --- a/zetasql-toolkit-spanner/pom.xml +++ b/zetasql-toolkit-spanner/pom.xml @@ -122,6 +122,10 @@ org.apache.maven.plugins maven-gpg-plugin + + com.diffplug.spotless + spotless-maven-plugin + diff --git a/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/LocalSpannerResourceProvider.java b/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/LocalSpannerResourceProvider.java index 878021a..5cdbb06 100644 --- a/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/LocalSpannerResourceProvider.java +++ b/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/LocalSpannerResourceProvider.java @@ -6,8 +6,8 @@ import java.util.stream.Collectors; /** - * {@link SpannerResourceProvider} implementation that fetches tables from a local - * {@link CatalogResources} object. + * {@link SpannerResourceProvider} implementation that fetches tables from a local {@link + * CatalogResources} object. */ public class LocalSpannerResourceProvider implements SpannerResourceProvider { @@ -19,8 +19,7 @@ public LocalSpannerResourceProvider(CatalogResources catalogResources) { @Override public List getTables(List tableNames) { - return catalogResources.getTables() - .stream() + return catalogResources.getTables().stream() .filter(table -> tableNames.contains(table.getName())) .collect(Collectors.toList()); } @@ -29,5 +28,4 @@ public List getTables(List tableNames) { public List getAllTablesInDatabase() { return catalogResources.getTables(); } - } diff --git a/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalog.java b/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalog.java index 27edc5d..457949d 100644 --- a/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalog.java +++ b/zetasql-toolkit-spanner/src/main/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalog.java @@ -66,7 +66,6 @@ public SpannerCatalog(SpannerResourceProvider spannerResourceProvider) { * DatabaseClient} with application default credentials to access Spanner. * * @deprecated Use {@link SpannerCatalog#usingSpannerClient(String, String, String)} - * * @param projectId The Spanner project id * @param instance The Spanner instance name * @param database The Spanner database name @@ -81,7 +80,6 @@ public SpannerCatalog(String projectId, String instance, String database) { * Spanner. * * @deprecated Use {@link SpannerCatalog#usingSpannerClient(String, String, String, Spanner)} - * * @param projectId The Spanner project id * @param instance The Spanner instance name * @param database The Spanner database name @@ -94,8 +92,7 @@ public SpannerCatalog(String projectId, String instance, String database, Spanne /** Private constructor used for implementing {@link #copy()} */ private SpannerCatalog( - SpannerResourceProvider spannerResourceProvider, - SimpleCatalog internalCatalog) { + SpannerResourceProvider spannerResourceProvider, SimpleCatalog internalCatalog) { this.spannerResourceProvider = spannerResourceProvider; this.catalog = internalCatalog; } @@ -134,8 +131,8 @@ public static SpannerCatalog usingSpannerClient( } /** - * Constructs a SpannerCatalog that can use the tables in the provided - * {@link CatalogResources} object. + * Constructs a SpannerCatalog that can use the tables in the provided {@link CatalogResources} + * object. * * @param resources The {@link CatalogResources} object from which this catalog will get tables * @return the new SpannerCatalog instance @@ -228,9 +225,10 @@ private void validateSpannerTableNames(List tableNames) { public void addTables(List tableNames) { this.validateSpannerTableNames(tableNames); - List tablesNotInCatalog = tableNames.stream() - .filter(tableName -> Objects.isNull(this.catalog.getTable(tableName, null))) - .collect(Collectors.toList()); + List tablesNotInCatalog = + tableNames.stream() + .filter(tableName -> Objects.isNull(this.catalog.getTable(tableName, null))) + .collect(Collectors.toList()); this.spannerResourceProvider .getTables(tablesNotInCatalog) @@ -287,8 +285,7 @@ public void addProcedures(List procedures) { @Override public SpannerCatalog copy() { return new SpannerCatalog( - this.spannerResourceProvider, - CatalogOperations.copyCatalog(this.catalog)); + this.spannerResourceProvider, CatalogOperations.copyCatalog(this.catalog)); } @Override diff --git a/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalogTest.java b/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalogTest.java index 2dc5b72..028104d 100644 --- a/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalogTest.java +++ b/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerCatalogTest.java @@ -27,7 +27,6 @@ import com.google.zetasql.toolkit.catalog.CatalogTestUtils; import com.google.zetasql.toolkit.catalog.exceptions.CatalogResourceAlreadyExists; import com.google.zetasql.toolkit.catalog.spanner.exceptions.InvalidSpannerTableName; -import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -40,8 +39,7 @@ public class SpannerCatalogTest { SpannerCatalog spannerCatalog; - @Mock - SpannerResourceProvider spannerResourceProviderMock; + @Mock SpannerResourceProvider spannerResourceProviderMock; SimpleTable exampleTable = new SimpleTable( @@ -61,8 +59,7 @@ public class SpannerCatalogTest { @BeforeEach void init() { - this.spannerCatalog = - new SpannerCatalog(spannerResourceProviderMock); + this.spannerCatalog = new SpannerCatalog(spannerResourceProviderMock); } private Table assertTableExistsInCatalog(SpannerCatalog catalog, SimpleTable table) { @@ -74,7 +71,8 @@ private Table assertTableExistsInCatalog(SpannerCatalog catalog, SimpleTable tab private void assertTableDoesNotExistInCatalog(SpannerCatalog catalog, String tableName) { SimpleCatalog underlyingCatalog = catalog.getZetaSQLCatalog(); - assertThrows(NotFoundException.class, () -> underlyingCatalog.findTable(ImmutableList.of(tableName))); + assertThrows( + NotFoundException.class, () -> underlyingCatalog.findTable(ImmutableList.of(tableName))); } @Test @@ -151,7 +149,8 @@ void testTableAlreadyExists() { @Test void testAddTablesByName() { // When SpannerResourceProvider.getTables() is called, return the test table - when(spannerResourceProviderMock.getTables(anyList())).thenReturn(ImmutableList.of(exampleTable)); + when(spannerResourceProviderMock.getTables(anyList())) + .thenReturn(ImmutableList.of(exampleTable)); // Add the tables by name spannerCatalog.addTables(ImmutableList.of(exampleTable.getName())); @@ -170,7 +169,8 @@ void testAddTablesByName() { @Test void testAddAllTablesInDatabase() { // When SpannerResourceProvider.getAllTablesInDatabase() is called, return the test table - when(spannerResourceProviderMock.getAllTablesInDatabase()).thenReturn(ImmutableList.of(exampleTable)); + when(spannerResourceProviderMock.getAllTablesInDatabase()) + .thenReturn(ImmutableList.of(exampleTable)); // Add the tables by name spannerCatalog.addAllTablesInDatabase(); diff --git a/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerResourceProviderImplTest.java b/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerResourceProviderImplTest.java index 1dd1373..ab66e3f 100644 --- a/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerResourceProviderImplTest.java +++ b/zetasql-toolkit-spanner/src/test/java/com/google/zetasql/toolkit/catalog/spanner/SpannerResourceProviderImplTest.java @@ -88,6 +88,7 @@ void testTableNotFound() { when(dbClient.singleUse().executeQuery(any())).thenReturn(resultSet); assertThrows( - SpannerTablesNotFound.class, () -> spannerResourceProvider.getTables(ImmutableList.of("table"))); + SpannerTablesNotFound.class, + () -> spannerResourceProvider.getTables(ImmutableList.of("table"))); } }