diff --git a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java index 3fadc7b88704..59722d4625bc 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java +++ b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java @@ -840,7 +840,7 @@ public void createSchema(Session session, CatalogSchemaName schema, Map parts = schema.get().getParts(); @@ -174,8 +177,10 @@ public static CatalogSchemaName createCatalogSchemaName(Session session, Node no } if (parts.size() == 2) { catalogName = parts.get(0); + isCatalogDelimited = schema.get().isDelimitedPart(0); } schemaName = schema.get().getSuffix(); + isSchemaDelimited = schema.get().isDelimitedSuffix(); } if (catalogName == null) { @@ -185,7 +190,9 @@ public static CatalogSchemaName createCatalogSchemaName(Session session, Node no throw semanticException(MISSING_SCHEMA_NAME, node, "Schema must be specified when session schema is not set"); } - return new CatalogSchemaName(catalogName, schemaName); + return new CatalogSchemaName( + new ConnectorIdentifier(catalogName, isCatalogDelimited), + new ConnectorIdentifier(schemaName, isSchemaDelimited)); } public static QualifiedObjectName createQualifiedObjectName(Session session, Node node, QualifiedName name) diff --git a/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java b/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java index b68b974debb3..a7d1f189d6f6 100644 --- a/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java +++ b/core/trino-main/src/main/java/io/trino/tracing/TracingConnectorMetadata.java @@ -26,6 +26,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeTableHandle; @@ -351,6 +352,15 @@ public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + { + Span span = startSpan("createSchema", schema.getValue()); + try (var _ = scopedSpan(span)) { + delegate.createSchema(session, schema, properties, owner); + } + } + @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) { @@ -362,9 +372,28 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc } @Override - public void renameSchema(ConnectorSession session, String source, String target) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) + { + Span span = startSpan("dropSchema", schema.getValue()) + .setAttribute(TrinoAttributes.CASCADE, cascade); + try (var _ = scopedSpan(span)) { + delegate.dropSchema(session, schema, cascade); + } + } + + @Override + public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + { + Span span = startSpan("renameSchema", schemaName); + try (var _ = scopedSpan(span)) { + delegate.renameSchema(session, schemaName, newSchemaName); + } + } + + @Override + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { - Span span = startSpan("renameSchema", source); + Span span = startSpan("renameSchema", source.getValue()); try (var _ = scopedSpan(span)) { delegate.renameSchema(session, source, target); } diff --git a/core/trino-main/src/test/java/io/trino/connector/MockConnector.java b/core/trino-main/src/test/java/io/trino/connector/MockConnector.java index 724d8127754a..f56750aac4c0 100644 --- a/core/trino-main/src/test/java/io/trino/connector/MockConnector.java +++ b/core/trino-main/src/test/java/io/trino/connector/MockConnector.java @@ -37,6 +37,7 @@ import io.trino.spi.connector.Connector; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorCapabilities; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeSink; @@ -529,16 +530,16 @@ public List listSchemaNames(ConnectorSession session) } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) {} + public void createSchema(ConnectorSession session, ConnectorIdentifier schemaName, Map properties, TrinoPrincipal owner) {} @Override - public void renameSchema(ConnectorSession session, String source, String target) {} + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) {} @Override public void setSchemaAuthorization(ConnectorSession session, String schemaName, TrinoPrincipal principal) {} @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) {} + public void dropSchema(ConnectorSession session, ConnectorIdentifier schemaName, boolean cascade) {} @Override public ConnectorTableHandle getTableHandle(ConnectorSession session, SchemaTableName tableName, Optional startVersion, Optional endVersion) diff --git a/core/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java b/core/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java index c197123f2f4e..c02d6637a46e 100644 --- a/core/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java +++ b/core/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java @@ -88,6 +88,22 @@ public List getParts() return parts; } + public boolean isDelimitedPart(int part) + { + if (part >= 0 && part < originalParts.size()) { + return originalParts.get(part).isDelimited(); + } + return false; + } + + public boolean isDelimitedSuffix() + { + if (!originalParts.isEmpty()) { + return originalParts.getFirst().isDelimited(); + } + return false; + } + public List getOriginalParts() { return originalParts; diff --git a/core/trino-spi/pom.xml b/core/trino-spi/pom.xml index 636b19e641f0..b4d98e4f86dd 100644 --- a/core/trino-spi/pom.xml +++ b/core/trino-spi/pom.xml @@ -914,6 +914,30 @@ method io.trino.spi.function.FunctionMetadata io.trino.spi.function.FunctionMetadata::fromJson(io.trino.spi.function.FunctionId, io.trino.spi.function.Signature, java.lang.String, java.util.Set<java.lang.String>, io.trino.spi.function.FunctionNullability, boolean, boolean, boolean, java.lang.String, io.trino.spi.function.FunctionKind, boolean) Function declares whether it never fails + + true + java.annotation.removed + method void io.trino.spi.connector.CatalogSchemaName::<init>(java.lang.String, java.lang.String) + method void io.trino.spi.connector.CatalogSchemaName::<init>(java.lang.String, java.lang.String) + @com.fasterxml.jackson.annotation.JsonCreator + Use of ConnectorIdentifier + + + true + java.annotation.removed + parameter void io.trino.spi.connector.CatalogSchemaName::<init>(===java.lang.String===, java.lang.String) + parameter void io.trino.spi.connector.CatalogSchemaName::<init>(===java.lang.String===, java.lang.String) + @com.fasterxml.jackson.annotation.JsonProperty("catalogName") + Use of ConnectorIdentifier + + + true + java.annotation.removed + parameter void io.trino.spi.connector.CatalogSchemaName::<init>(java.lang.String, ===java.lang.String===) + parameter void io.trino.spi.connector.CatalogSchemaName::<init>(java.lang.String, ===java.lang.String===) + @com.fasterxml.jackson.annotation.JsonProperty("schemaName") + Use of ConnectorIdentifier + diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/CatalogSchemaName.java b/core/trino-spi/src/main/java/io/trino/spi/connector/CatalogSchemaName.java index b450ec4fc22e..9fc7a20e6273 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/CatalogSchemaName.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/CatalogSchemaName.java @@ -18,32 +18,52 @@ import java.util.Objects; -import static java.util.Locale.ENGLISH; +import static java.util.Objects.requireNonNull; public final class CatalogSchemaName { - private final String catalogName; - private final String schemaName; + private final ConnectorIdentifier catalog; + private final ConnectorIdentifier schema; @JsonCreator public CatalogSchemaName( - @JsonProperty("catalogName") String catalogName, - @JsonProperty("schemaName") String schemaName) + @JsonProperty("catalog") ConnectorIdentifier catalog, + @JsonProperty("schema") ConnectorIdentifier schema) { - this.catalogName = catalogName.toLowerCase(ENGLISH); - this.schemaName = schemaName.toLowerCase(ENGLISH); + this.catalog = requireNonNull(catalog, "catalog is null"); + this.schema = requireNonNull(schema, "schema is null"); + } + + public CatalogSchemaName( + String catalog, + String schema) + { + this.catalog = new ConnectorIdentifier(catalog, false); + this.schema = new ConnectorIdentifier(schema, false); + } + + @JsonProperty + public ConnectorIdentifier getCatalog() + { + return catalog; + } + + @JsonProperty + public ConnectorIdentifier getSchema() + { + return schema; } @JsonProperty public String getCatalogName() { - return catalogName; + return catalog.getValue(); } @JsonProperty public String getSchemaName() { - return schemaName; + return schema.getValue(); } @Override @@ -56,19 +76,19 @@ public boolean equals(Object obj) return false; } CatalogSchemaName that = (CatalogSchemaName) obj; - return Objects.equals(catalogName, that.catalogName) && - Objects.equals(schemaName, that.schemaName); + return Objects.equals(catalog, that.catalog) && + Objects.equals(schema, that.schema); } @Override public int hashCode() { - return Objects.hash(catalogName, schemaName); + return Objects.hash(catalog, schema); } @Override public String toString() { - return catalogName + '.' + schemaName; + return catalog.getValue() + '.' + schema.getValue(); } } diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorIdentifier.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorIdentifier.java new file mode 100644 index 000000000000..82286fda1882 --- /dev/null +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorIdentifier.java @@ -0,0 +1,77 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.trino.spi.connector; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Objects; + +import static java.util.Locale.ENGLISH; +import static java.util.Objects.requireNonNull; + +public class ConnectorIdentifier +{ + private final String value; + private final boolean delimited; + + @JsonCreator + public ConnectorIdentifier(String value, boolean delimited) + { + this.value = requireNonNull(value, "value is null"); + this.delimited = delimited; + } + + @JsonProperty + public String getValue() + { + return delimited ? value : canonicalize(); + } + + @JsonProperty + public boolean isDelimited() + { + return delimited; + } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConnectorIdentifier that = (ConnectorIdentifier) o; + return Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() + { + return Objects.hash(value, delimited); + } + + @Override + public String toString() + { + return value; + } + + private String canonicalize() + { + return value.toLowerCase(ENGLISH); + } +} diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java index 7303c13e437d..128ffeecf329 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMetadata.java @@ -444,6 +444,14 @@ default TableStatistics getTableStatistics(ConnectorSession session, ConnectorTa * Creates a schema. */ default void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + { + createSchema(session, new ConnectorIdentifier(schemaName, true), properties, owner); + } + + /** + * Creates a schema. + */ + default void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating schemas"); } @@ -454,6 +462,16 @@ default void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { try (ThreadContextClassLoader _ = new ThreadContextClassLoader(classLoader)) { - delegate.createSchema(session, schemaName, properties, owner); + delegate.createSchema(session, schema, properties, owner); } } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { try (ThreadContextClassLoader _ = new ThreadContextClassLoader(classLoader)) { - delegate.dropSchema(session, schemaName, cascade); + delegate.dropSchema(session, schema, cascade); } } @Override - public void renameSchema(ConnectorSession session, String source, String target) + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { try (ThreadContextClassLoader _ = new ThreadContextClassLoader(classLoader)) { delegate.renameSchema(session, source, target); diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java index ee7b875513d9..c9afb3641029 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/BaseJdbcClient.java @@ -32,6 +32,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableHandle; @@ -1550,71 +1551,70 @@ public TableStatistics getTableStatistics(ConnectorSession session, JdbcTableHan } @Override - public void createSchema(ConnectorSession session, String schemaName) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) { - ConnectorIdentity identity = session.getIdentity(); try (Connection connection = connectionFactory.openConnection(session)) { verify(connection.getAutoCommit()); - schemaName = identifierMapping.toRemoteSchemaName(getRemoteIdentifiers(connection), identity, schemaName); - verifySchemaName(connection.getMetaData(), schemaName); - createSchema(session, connection, schemaName); + verifySchemaName(connection.getMetaData(), schema); + System.out.println("BaseJdbcClient.createSchema() schema: " + schema.getValue()); + createSchema(session, connection, schema); } catch (SQLException e) { throw new TrinoException(JDBC_ERROR, e); } } - protected void createSchema(ConnectorSession session, Connection connection, String remoteSchemaName) + protected void createSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema) throws SQLException { - execute(session, connection, "CREATE SCHEMA " + quoted(remoteSchemaName)); + String createSchema = "CREATE SCHEMA " + quoted(schema); + System.out.println("BaseJdbcClient.createSchema() query: " + createSchema); + execute(session, connection, createSchema); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { ConnectorIdentity identity = session.getIdentity(); try (Connection connection = connectionFactory.openConnection(session)) { verify(connection.getAutoCommit()); - schemaName = identifierMapping.toRemoteSchemaName(getRemoteIdentifiers(connection), identity, schemaName); - dropSchema(session, connection, schemaName, cascade); + System.out.println("BaseJdbcClient.dropSchema() schema: " + schema.getValue()); + dropSchema(session, connection, schema, cascade); } catch (SQLException e) { throw new TrinoException(JDBC_ERROR, e); } } - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { - String dropSchema = "DROP SCHEMA " + quoted(remoteSchemaName); + String dropSchema = "DROP SCHEMA " + quoted(schema); if (cascade) { dropSchema += " CASCADE"; } + System.out.println("BaseJdbcClient.dropSchema() query: " + dropSchema); execute(session, connection, dropSchema); } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { ConnectorIdentity identity = session.getIdentity(); try (Connection connection = connectionFactory.openConnection(session)) { verify(connection.getAutoCommit()); - RemoteIdentifiers remoteIdentifiers = getRemoteIdentifiers(connection); - String remoteSchemaName = identifierMapping.toRemoteSchemaName(remoteIdentifiers, identity, schemaName); - String newRemoteSchemaName = identifierMapping.toRemoteSchemaName(remoteIdentifiers, identity, newSchemaName); - verifySchemaName(connection.getMetaData(), newRemoteSchemaName); - renameSchema(session, connection, remoteSchemaName, newRemoteSchemaName); + verifySchemaName(connection.getMetaData(), newSchema); + renameSchema(session, connection, schema, newSchema); } catch (SQLException e) { throw new TrinoException(JDBC_ERROR, e); } } - protected void renameSchema(ConnectorSession session, Connection connection, String remoteSchemaName, String newRemoteSchemaName) + protected void renameSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, ConnectorIdentifier newSchema) throws SQLException { - execute(session, connection, "ALTER SCHEMA " + quoted(remoteSchemaName) + " RENAME TO " + quoted(newRemoteSchemaName)); + execute(session, connection, "ALTER SCHEMA " + quoted(schema) + " RENAME TO " + quoted(newSchema)); } @Override @@ -1828,6 +1828,12 @@ protected OptionalInt getMaxColumnNameLengthFromDatabaseMetaData(ConnectorSessio } } + protected void verifySchemaName(DatabaseMetaData databaseMetadata, ConnectorIdentifier schema) + throws SQLException + { + // expect remote databases throw an exception for unsupported schema names + } + protected void verifySchemaName(DatabaseMetaData databaseMetadata, String schemaName) throws SQLException { diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java index 94df9f4cfd20..24e120c4aa2e 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/CachingJdbcClient.java @@ -33,6 +33,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; @@ -507,6 +508,13 @@ public void createSchema(ConnectorSession session, String schemaName) invalidateSchemasCache(); } + @Override + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) + { + delegate.createSchema(session, schema); + invalidateSchemasCache(); + } + @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) { @@ -514,6 +522,13 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc invalidateSchemasCache(); } + @Override + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) + { + delegate.dropSchema(session, schema, cascade); + invalidateSchemasCache(); + } + @Override public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) { @@ -521,6 +536,13 @@ public void renameSchema(ConnectorSession session, String schemaName, String new invalidateSchemasCache(); } + @Override + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) + { + delegate.renameSchema(session, schema, newSchema); + invalidateSchemasCache(); + } + @Override public Optional getTableComment(ResultSet resultSet) throws SQLException @@ -611,6 +633,12 @@ public Optional getSystemTable(ConnectorSession session, SchemaTabl return delegate.getSystemTable(session, tableName); } + @Override + public String quoted(ConnectorIdentifier identifier) + { + return delegate.quoted(identifier); + } + @Override public String quoted(String name) { diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/DefaultJdbcMetadata.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/DefaultJdbcMetadata.java index ff5a1991cf28..c272d521d358 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/DefaultJdbcMetadata.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/DefaultJdbcMetadata.java @@ -32,6 +32,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMergeTableHandle; import io.trino.spi.connector.ConnectorOutputMetadata; @@ -1488,21 +1489,21 @@ public TableStatistics getTableStatistics(ConnectorSession session, ConnectorTab } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { - jdbcClient.createSchema(session, schemaName); + jdbcClient.createSchema(session, schema); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { - jdbcClient.dropSchema(session, schemaName, cascade); + jdbcClient.dropSchema(session, schema, cascade); } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { - jdbcClient.renameSchema(session, schemaName, newSchemaName); + jdbcClient.renameSchema(session, schema, newSchema); } @Override diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/ForwardingJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/ForwardingJdbcClient.java index 3d65c818e7fe..0a5b9fb47597 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/ForwardingJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/ForwardingJdbcClient.java @@ -19,6 +19,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; @@ -459,24 +460,48 @@ public void createSchema(ConnectorSession session, String schemaName) delegate().createSchema(session, schemaName); } + @Override + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) + { + delegate().createSchema(session, schema); + } + @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) { delegate().dropSchema(session, schemaName, cascade); } + @Override + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) + { + delegate().dropSchema(session, schema, cascade); + } + @Override public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) { delegate().renameSchema(session, schemaName, newSchemaName); } + @Override + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) + { + delegate().renameSchema(session, schema, newSchema); + } + @Override public Optional getSystemTable(ConnectorSession session, SchemaTableName tableName) { return delegate().getSystemTable(session, tableName); } + @Override + public String quoted(ConnectorIdentifier identifier) + { + return delegate().quoted(identifier); + } + @Override public String quoted(String name) { diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java index 1af104aa909e..a348b711f894 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/JdbcClient.java @@ -20,6 +20,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; @@ -252,17 +253,37 @@ PreparedStatement getPreparedStatement(Connection connection, String sql, Option TableStatistics getTableStatistics(ConnectorSession session, JdbcTableHandle handle); - void createSchema(ConnectorSession session, String schemaName); + default void createSchema(ConnectorSession session, String schemaName) + { + createSchema(session, new ConnectorIdentifier(schemaName, false)); + } + + void createSchema(ConnectorSession session, ConnectorIdentifier schema); + + default void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + { + dropSchema(session, new ConnectorIdentifier(schemaName, false), cascade); + } - void dropSchema(ConnectorSession session, String schemaName, boolean cascade); + void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade); - void renameSchema(ConnectorSession session, String schemaName, String newSchemaName); + default void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + { + renameSchema(session, new ConnectorIdentifier(schemaName, false), new ConnectorIdentifier(newSchemaName, false)); + } + + void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema); default Optional getSystemTable(ConnectorSession session, SchemaTableName tableName) { return Optional.empty(); } + default String quoted(ConnectorIdentifier identifier) + { + return identifier.isDelimited() ? quoted(identifier.getValue()) : identifier.getValue(); + } + String quoted(String name); String quoted(RemoteTableName remoteTableName); diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/RetryingJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/RetryingJdbcClient.java index cac6675626f8..873be75b171c 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/RetryingJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/RetryingJdbcClient.java @@ -21,6 +21,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; @@ -479,6 +480,13 @@ public void createSchema(ConnectorSession session, String schemaName) delegate.createSchema(session, schemaName); } + @Override + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) + { + // no retrying as it could be not idempotent operation + delegate.createSchema(session, schema); + } + @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) { @@ -486,6 +494,13 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc delegate.dropSchema(session, schemaName, cascade); } + @Override + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) + { + // no retrying as it could be not idempotent operation + delegate.dropSchema(session, schema, cascade); + } + @Override public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) { @@ -493,6 +508,13 @@ public void renameSchema(ConnectorSession session, String schemaName, String new delegate.renameSchema(session, schemaName, newSchemaName); } + @Override + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) + { + // no retrying as it could be not idempotent operation + delegate.renameSchema(session, schema, newSchema); + } + @Override public Optional getSystemTable(ConnectorSession session, SchemaTableName tableName) { @@ -500,6 +522,12 @@ public Optional getSystemTable(ConnectorSession session, SchemaTabl return delegate.getSystemTable(session, tableName); } + @Override + public String quoted(ConnectorIdentifier identifier) + { + return delegate.quoted(identifier); + } + @Override public String quoted(String name) { diff --git a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/jmx/StatisticsAwareJdbcClient.java b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/jmx/StatisticsAwareJdbcClient.java index c08bb1361bf9..c5bb1298f11d 100644 --- a/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/jmx/StatisticsAwareJdbcClient.java +++ b/plugin/trino-base-jdbc/src/main/java/io/trino/plugin/jdbc/jmx/StatisticsAwareJdbcClient.java @@ -35,6 +35,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorSplitSource; import io.trino.spi.connector.ConnectorTableMetadata; @@ -480,24 +481,48 @@ public void createSchema(ConnectorSession session, String schemaName) stats.getCreateSchema().wrap(() -> delegate().createSchema(session, schemaName)); } + @Override + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) + { + stats.getCreateSchema().wrap(() -> delegate().createSchema(session, schema)); + } + @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) { stats.getDropSchema().wrap(() -> delegate().dropSchema(session, schemaName, cascade)); } + @Override + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) + { + stats.getDropSchema().wrap(() -> delegate().dropSchema(session, schema, cascade)); + } + @Override public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) { stats.getRenameSchema().wrap(() -> delegate().renameSchema(session, schemaName, newSchemaName)); } + @Override + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) + { + stats.getRenameSchema().wrap(() -> delegate().renameSchema(session, schema, newSchema)); + } + @Override public Optional getSystemTable(ConnectorSession session, SchemaTableName tableName) { return delegate().getSystemTable(session, tableName); } + @Override + public String quoted(ConnectorIdentifier identifier) + { + return delegate().quoted(identifier); + } + @Override public String quoted(String name) { diff --git a/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/BaseJdbcConnectorTest.java b/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/BaseJdbcConnectorTest.java index cbb944eb1367..6be61afef3d4 100644 --- a/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/BaseJdbcConnectorTest.java +++ b/plugin/trino-base-jdbc/src/test/java/io/trino/plugin/jdbc/BaseJdbcConnectorTest.java @@ -1420,7 +1420,7 @@ public void testBulkColumnListingOptions() { if (hasBehavior(SUPPORTS_CREATE_SCHEMA)) { String schemaName = "test_columns_listing_" + randomNameSuffix(); - assertUpdate("CREATE SCHEMA " + schemaName); + assertUpdate(createSchemaSql(schemaName)); try { try (TestTable newNation = newTrinoTable( schemaName + ".nation", @@ -1437,7 +1437,7 @@ public void testBulkColumnListingOptions() } } finally { - assertUpdate("DROP SCHEMA " + schemaName); + assertUpdate(dropSchemaSql(schemaName)); } return; } diff --git a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java index 4ef823ce1fbe..6023e5ed89c3 100644 --- a/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java +++ b/plugin/trino-bigquery/src/main/java/io/trino/plugin/bigquery/BigQueryMetadata.java @@ -53,6 +53,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeTableHandle; @@ -505,19 +506,19 @@ protected Stream processInParallel(List list, Function functi } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { BigQueryClient client = bigQueryClientFactory.create(session); checkArgument(properties.isEmpty(), "Can't have properties for schema creation"); - DatasetInfo datasetInfo = DatasetInfo.newBuilder(client.toDatasetId(schemaName)).build(); + DatasetInfo datasetInfo = DatasetInfo.newBuilder(client.toDatasetId(schema.getValue())).build(); client.createSchema(datasetInfo); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { BigQueryClient client = bigQueryClientFactory.create(session); - DatasetId localDatasetId = client.toDatasetId(schemaName); + DatasetId localDatasetId = client.toDatasetId(schema.getValue()); String remoteSchemaName = getRemoteSchemaName(client, localDatasetId.getProject(), localDatasetId.getDataset()); client.dropSchema(DatasetId.of(localDatasetId.getProject(), remoteSchemaName), cascade); } diff --git a/plugin/trino-blackhole/src/main/java/io/trino/plugin/blackhole/BlackHoleMetadata.java b/plugin/trino-blackhole/src/main/java/io/trino/plugin/blackhole/BlackHoleMetadata.java index 3125e154e7e3..4a7ca579d3e6 100644 --- a/plugin/trino-blackhole/src/main/java/io/trino/plugin/blackhole/BlackHoleMetadata.java +++ b/plugin/trino-blackhole/src/main/java/io/trino/plugin/blackhole/BlackHoleMetadata.java @@ -24,6 +24,7 @@ import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMergeTableHandle; import io.trino.spi.connector.ConnectorMetadata; @@ -111,12 +112,12 @@ public List listSchemaNames(ConnectorSession session) } @Override - public synchronized void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public synchronized void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { - if (schemas.contains(schemaName)) { - throw new TrinoException(ALREADY_EXISTS, format("Schema [%s] already exists", schemaName)); + if (schemas.contains(schema.getValue())) { + throw new TrinoException(ALREADY_EXISTS, format("Schema [%s] already exists", schema.getValue())); } - schemas.add(schemaName); + schemas.add(schema.getValue()); } @Override diff --git a/plugin/trino-clickhouse/src/main/java/io/trino/plugin/clickhouse/ClickHouseClient.java b/plugin/trino-clickhouse/src/main/java/io/trino/plugin/clickhouse/ClickHouseClient.java index 54b7fb20e033..0647cdf2b333 100644 --- a/plugin/trino-clickhouse/src/main/java/io/trino/plugin/clickhouse/ClickHouseClient.java +++ b/plugin/trino-clickhouse/src/main/java/io/trino/plugin/clickhouse/ClickHouseClient.java @@ -66,6 +66,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.expression.ConnectorExpression; @@ -491,32 +492,32 @@ protected String getColumnDefinitionSql(ConnectorSession session, ColumnMetadata } @Override - protected void createSchema(ConnectorSession session, Connection connection, String remoteSchemaName) + protected void createSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema) throws SQLException { - execute(session, connection, "CREATE DATABASE " + quoted(remoteSchemaName)); + execute(session, connection, "CREATE DATABASE " + quoted(schema)); } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { // ClickHouse always deletes all tables inside the database https://clickhouse.com/docs/en/sql-reference/statements/drop if (!cascade) { - try (ResultSet tables = getTables(connection, Optional.of(remoteSchemaName), Optional.empty())) { + try (ResultSet tables = getTables(connection, Optional.of(schema.getValue()), Optional.empty())) { if (tables.next()) { - throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(remoteSchemaName)); + throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(schema.getValue())); } } } - execute(session, connection, "DROP DATABASE " + quoted(remoteSchemaName)); + execute(session, connection, "DROP DATABASE " + quoted(schema)); } @Override - protected void renameSchema(ConnectorSession session, Connection connection, String remoteSchemaName, String newRemoteSchemaName) + protected void renameSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, ConnectorIdentifier newSchema) throws SQLException { - execute(session, connection, "RENAME DATABASE " + quoted(remoteSchemaName) + " TO " + quoted(newRemoteSchemaName)); + execute(session, connection, "RENAME DATABASE " + quoted(schema) + " TO " + quoted(newSchema)); } @Override diff --git a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakeMetadata.java b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakeMetadata.java index cf74170893f5..d03ac9a77e26 100644 --- a/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakeMetadata.java +++ b/plugin/trino-delta-lake/src/main/java/io/trino/plugin/deltalake/DeltaLakeMetadata.java @@ -103,6 +103,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeTableHandle; @@ -1192,7 +1193,7 @@ public TableStatistics getTableStatistics(ConnectorSession session, ConnectorTab } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { Optional location = DeltaLakeSchemaProperties.getLocation(properties).map(locationUri -> { try { @@ -1207,7 +1208,7 @@ public void createSchema(ConnectorSession session, String schemaName, Map location = metastore.getDatabase(schemaName) - .orElseThrow(() -> new SchemaNotFoundException(schemaName)) + Optional location = metastore.getDatabase(schema.getValue()) + .orElseThrow(() -> new SchemaNotFoundException(schema.getValue())) .getLocation(); // If we see files in the schema location, don't delete it. @@ -1266,7 +1267,7 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc } }).orElse(deleteSchemaLocationsFallback); - metastore.dropDatabase(schemaName, deleteData); + metastore.dropDatabase(schema.getValue(), deleteData); } @Override diff --git a/plugin/trino-druid/src/main/java/io/trino/plugin/druid/DruidJdbcClient.java b/plugin/trino-druid/src/main/java/io/trino/plugin/druid/DruidJdbcClient.java index 51023a151dbe..5a8fdb882c78 100644 --- a/plugin/trino-druid/src/main/java/io/trino/plugin/druid/DruidJdbcClient.java +++ b/plugin/trino-druid/src/main/java/io/trino/plugin/druid/DruidJdbcClient.java @@ -41,6 +41,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.predicate.Range; import io.trino.spi.security.ConnectorIdentity; @@ -555,19 +556,19 @@ public String buildInsertSql(JdbcOutputTableHandle handle, List c } @Override - public void createSchema(ConnectorSession session, String schemaName) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating schemas"); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas"); } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-duckdb/src/main/java/io/trino/plugin/duckdb/DuckDbClient.java b/plugin/trino-duckdb/src/main/java/io/trino/plugin/duckdb/DuckDbClient.java index efb4df9ffe19..6baee5dec2a2 100644 --- a/plugin/trino-duckdb/src/main/java/io/trino/plugin/duckdb/DuckDbClient.java +++ b/plugin/trino-duckdb/src/main/java/io/trino/plugin/duckdb/DuckDbClient.java @@ -31,6 +31,7 @@ import io.trino.spi.TrinoException; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.type.CharType; @@ -114,7 +115,7 @@ public Connection getConnection(ConnectorSession session) } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java b/plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java index 915b7c58e72a..91ac82db0a69 100644 --- a/plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java +++ b/plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java @@ -43,6 +43,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.type.Type; import java.sql.Connection; @@ -172,19 +173,19 @@ public String buildInsertSql(JdbcOutputTableHandle handle, List c } @Override - public void createSchema(ConnectorSession session, String schemaName) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating schemas"); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas"); } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-faker/src/main/java/io/trino/plugin/faker/FakerMetadata.java b/plugin/trino-faker/src/main/java/io/trino/plugin/faker/FakerMetadata.java index 7109de2f21b0..57fed2a17b70 100644 --- a/plugin/trino-faker/src/main/java/io/trino/plugin/faker/FakerMetadata.java +++ b/plugin/trino-faker/src/main/java/io/trino/plugin/faker/FakerMetadata.java @@ -23,6 +23,7 @@ import io.trino.spi.block.Block; import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorMetadata; import io.trino.spi.connector.ConnectorOutputMetadata; import io.trino.spi.connector.ConnectorOutputTableHandle; @@ -167,18 +168,18 @@ public synchronized List listSchemaNames(ConnectorSession connectorSessi } @Override - public synchronized void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public synchronized void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { - if (schemas.stream().anyMatch(schema -> schema.name().equals(schemaName))) { - throw new TrinoException(SCHEMA_ALREADY_EXISTS, format("Schema '%s' already exists", schemaName)); + if (schemas.stream().anyMatch(info -> info.name().equals(schema.getValue()))) { + throw new TrinoException(SCHEMA_ALREADY_EXISTS, format("Schema '%s' already exists", schema.getValue())); } - schemas.add(new SchemaInfo(schemaName, properties)); + schemas.add(new SchemaInfo(schema.getValue(), properties)); } @Override - public synchronized void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public synchronized void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { - verify(schemas.remove(getSchema(schemaName))); + verify(schemas.remove(getSchema(schema.getValue()))); } private synchronized SchemaInfo getSchema(String name) diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java index 51eed0171b3b..ec78609b4dee 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMetadata.java @@ -80,6 +80,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMergeTableHandle; import io.trino.spi.connector.ConnectorOutputMetadata; @@ -991,7 +992,7 @@ public ColumnMetadata getColumnMetadata(ConnectorSession session, ConnectorTable } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { Optional location = HiveSchemaProperties.getLocation(properties).map(locationUri -> { try { @@ -1004,7 +1005,7 @@ public void createSchema(ConnectorSession session, String schemaName, Map views = listViews(session, Optional.of(schemaName)); - List tables = listTables(session, Optional.of(schemaName)).stream() + List views = listViews(session, Optional.of(schema.getValue())); + List tables = listTables(session, Optional.of(schema.getValue())).stream() .filter(table -> !views.contains(table)) .collect(toImmutableList()); @@ -1039,18 +1040,18 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc // Commit and then drop the database with raw metastore because exclusive operation after dropping object is disallowed in SemiTransactionalHiveMetastore metastore.commit(); - boolean deleteData = metastore.shouldDeleteDatabaseData(session, schemaName); - metastore.unsafeGetRawHiveMetastore().dropDatabase(schemaName, deleteData); + boolean deleteData = metastore.shouldDeleteDatabaseData(session, schema.getValue()); + metastore.unsafeGetRawHiveMetastore().dropDatabase(schema.getValue(), deleteData); } else { - metastore.dropDatabase(session, schemaName); + metastore.dropDatabase(session, schema.getValue()); } } @Override - public void renameSchema(ConnectorSession session, String source, String target) + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { - metastore.renameDatabase(source, target); + metastore.renameDatabase(source.getValue(), target.getValue()); } @Override diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java index 77273db01d19..f788dbc6fd20 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java @@ -86,6 +86,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeTableHandle; @@ -1231,29 +1232,29 @@ public Iterator streamRelationComments(ConnectorSession } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { - catalog.createNamespace(session, schemaName, properties, owner); + catalog.createNamespace(session, schema.getValue(), properties, owner); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { if (cascade) { - List nestedNamespaces = getChildNamespaces(session, schemaName); + List nestedNamespaces = getChildNamespaces(session, schema.getValue()); if (!nestedNamespaces.isEmpty()) { throw new TrinoException( ICEBERG_CATALOG_ERROR, - format("Cannot drop non-empty schema: %s, contains %s nested schema(s)", schemaName, Joiner.on(", ").join(nestedNamespaces))); + format("Cannot drop non-empty schema: %s, contains %s nested schema(s)", schema.getValue(), Joiner.on(", ").join(nestedNamespaces))); } - for (SchemaTableName materializedView : listMaterializedViews(session, Optional.of(schemaName))) { + for (SchemaTableName materializedView : listMaterializedViews(session, Optional.of(schema.getValue()))) { dropMaterializedView(session, materializedView); } - for (SchemaTableName viewName : listViews(session, Optional.of(schemaName))) { + for (SchemaTableName viewName : listViews(session, Optional.of(schema.getValue()))) { dropView(session, viewName); } - for (SchemaTableName tableName : listTables(session, Optional.of(schemaName))) { + for (SchemaTableName tableName : listTables(session, Optional.of(schema.getValue()))) { ConnectorTableHandle tableHandle = getTableHandle(session, tableName, Optional.empty(), Optional.empty()); if (tableHandle != null) { // getTableHandle method returns null if the table is dropped concurrently @@ -1261,13 +1262,13 @@ public void dropSchema(ConnectorSession session, String schemaName, boolean casc } } } - catalog.dropNamespace(session, schemaName); + catalog.dropNamespace(session, schema.getValue()); } @Override - public void renameSchema(ConnectorSession session, String source, String target) + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { - catalog.renameNamespace(session, source, target); + catalog.renameNamespace(session, source.getValue(), target.getValue()); } @Override diff --git a/plugin/trino-ignite/src/main/java/io/trino/plugin/ignite/IgniteClient.java b/plugin/trino-ignite/src/main/java/io/trino/plugin/ignite/IgniteClient.java index 4598438d9ca2..87a91c756ec4 100644 --- a/plugin/trino-ignite/src/main/java/io/trino/plugin/ignite/IgniteClient.java +++ b/plugin/trino-ignite/src/main/java/io/trino/plugin/ignite/IgniteClient.java @@ -55,6 +55,7 @@ import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.JoinStatistics; import io.trino.spi.connector.JoinType; import io.trino.spi.connector.SchemaNotFoundException; @@ -643,13 +644,13 @@ protected boolean isSupportedJoinCondition(ConnectorSession session, JdbcJoinCon } @Override - public void createSchema(ConnectorSession session, String schemaName) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating schemas"); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas"); } @@ -673,7 +674,7 @@ public void renameTable(ConnectorSession session, JdbcTableHandle handle, Schema } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-lakehouse/src/main/java/io/trino/plugin/lakehouse/LakehouseMetadata.java b/plugin/trino-lakehouse/src/main/java/io/trino/plugin/lakehouse/LakehouseMetadata.java index 0b439bb46679..23d271c6c4a5 100644 --- a/plugin/trino-lakehouse/src/main/java/io/trino/plugin/lakehouse/LakehouseMetadata.java +++ b/plugin/trino-lakehouse/src/main/java/io/trino/plugin/lakehouse/LakehouseMetadata.java @@ -48,6 +48,7 @@ import io.trino.spi.connector.ColumnPosition; import io.trino.spi.connector.ConnectorAccessControl; import io.trino.spi.connector.ConnectorAnalyzeMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; import io.trino.spi.connector.ConnectorMergeTableHandle; @@ -338,20 +339,38 @@ public TableStatistics getTableStatistics(ConnectorSession session, ConnectorTab @Override public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) { - hiveMetadata.createSchema(session, schemaName, properties, owner); + createSchema(session, new ConnectorIdentifier(schemaName, true), properties, owner); + } + + @Override + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) + { + hiveMetadata.createSchema(session, schema.getValue(), properties, owner); } @Override public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + { + dropSchema(session, new ConnectorIdentifier(schemaName, true), cascade); + } + + @Override + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { // use Iceberg to allow dropping materialized views - icebergMetadata.dropSchema(session, schemaName, cascade); + icebergMetadata.dropSchema(session, schema.getValue(), cascade); + } + + @Override + public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + { + renameSchema(session, new ConnectorIdentifier(schemaName, true), new ConnectorIdentifier(newSchemaName, true)); } @Override - public void renameSchema(ConnectorSession session, String source, String target) + public void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { - hiveMetadata.renameSchema(session, source, target); + hiveMetadata.renameSchema(session, source.getValue(), target.getValue()); } @Override diff --git a/plugin/trino-mariadb/src/main/java/io/trino/plugin/mariadb/MariaDbClient.java b/plugin/trino-mariadb/src/main/java/io/trino/plugin/mariadb/MariaDbClient.java index 12044f3e5a61..a11916f57234 100644 --- a/plugin/trino-mariadb/src/main/java/io/trino/plugin/mariadb/MariaDbClient.java +++ b/plugin/trino-mariadb/src/main/java/io/trino/plugin/mariadb/MariaDbClient.java @@ -57,6 +57,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.JoinCondition; @@ -279,24 +280,24 @@ protected boolean filterRemoteSchema(String schemaName) } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { // MariaDB always deletes all tables inside the database https://mariadb.com/kb/en/drop-database/ if (!cascade) { - try (ResultSet tables = getTables(connection, Optional.of(remoteSchemaName), Optional.empty())) { + try (ResultSet tables = getTables(connection, Optional.of(schema.getValue()), Optional.empty())) { if (tables.next()) { - throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(remoteSchemaName)); + throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(schema.getValue())); } } } - execute(session, connection, "DROP SCHEMA " + quoted(remoteSchemaName)); + execute(session, connection, "DROP SCHEMA " + quoted(schema)); } @Override diff --git a/plugin/trino-memory/src/main/java/io/trino/plugin/memory/MemoryMetadata.java b/plugin/trino-memory/src/main/java/io/trino/plugin/memory/MemoryMetadata.java index f3efbec7246e..a7d8ce049bcb 100644 --- a/plugin/trino-memory/src/main/java/io/trino/plugin/memory/MemoryMetadata.java +++ b/plugin/trino-memory/src/main/java/io/trino/plugin/memory/MemoryMetadata.java @@ -30,6 +30,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMetadata; import io.trino.spi.connector.ConnectorOutputMetadata; @@ -123,62 +124,62 @@ public synchronized List listSchemaNames(ConnectorSession session) } @Override - public synchronized void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public synchronized void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { - if (schemas.contains(schemaName)) { - throw new TrinoException(ALREADY_EXISTS, format("Schema [%s] already exists", schemaName)); + if (schemas.contains(schema.getValue())) { + throw new TrinoException(ALREADY_EXISTS, format("Schema [%s] already exists", schema.getValue())); } - schemas.add(schemaName); + schemas.add(schema.getValue()); } @Override - public synchronized void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public synchronized void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { - if (!schemas.contains(schemaName)) { - throw new TrinoException(NOT_FOUND, format("Schema [%s] does not exist", schemaName)); + if (!schemas.contains(schema.getValue())) { + throw new TrinoException(NOT_FOUND, format("Schema [%s] does not exist", schema.getValue())); } if (cascade) { Set viewNames = views.keySet().stream() - .filter(view -> view.getSchemaName().equals(schemaName)) + .filter(view -> view.getSchemaName().equals(schema.getValue())) .collect(toImmutableSet()); viewNames.forEach(viewName -> dropView(session, viewName)); Set tableNames = tables.values().stream() - .filter(table -> table.schemaName().equals(schemaName)) + .filter(table -> table.schemaName().equals(schema.getValue())) .map(TableInfo::getSchemaTableName) .collect(toImmutableSet()); tableNames.forEach(tableName -> dropTable(session, getTableHandle(session, tableName, Optional.empty(), Optional.empty()))); } // DropSchemaTask has the same logic, but needs to check in connector side considering concurrent operations - if (!isSchemaEmpty(schemaName)) { - throw new TrinoException(SCHEMA_NOT_EMPTY, "Schema not empty: " + schemaName); + if (!isSchemaEmpty(schema.getValue())) { + throw new TrinoException(SCHEMA_NOT_EMPTY, "Schema not empty: " + schema); } - verify(schemas.remove(schemaName)); + verify(schemas.remove(schema.getValue())); } @Override - public synchronized void renameSchema(ConnectorSession session, String source, String target) + public synchronized void renameSchema(ConnectorSession session, ConnectorIdentifier source, ConnectorIdentifier target) { - if (!schemas.remove(source)) { - throw new SchemaNotFoundException(source); + if (!schemas.remove(source.getValue())) { + throw new SchemaNotFoundException(source.getValue()); } - schemas.add(target); + schemas.add(target.getValue()); Map newTableIds = new HashMap<>(); for (Iterator> iterator = tableIds.entrySet().iterator(); iterator.hasNext(); ) { Entry table = iterator.next(); if (table.getKey().getSchemaName().equals(source)) { iterator.remove(); - newTableIds.put(new SchemaTableName(target, table.getKey().getTableName()), table.getValue()); + newTableIds.put(new SchemaTableName(target.getValue(), table.getKey().getTableName()), table.getValue()); } } tableIds.putAll(newTableIds); tables.replaceAll((tableId, table) -> - table.schemaName().equals(source) - ? new TableInfo(tableId, target, table.tableName(), table.columns(), table.truncated(), table.dataFragments(), table.comment()) + table.schemaName().equals(source.getValue()) + ? new TableInfo(tableId, target.getValue(), table.tableName(), table.columns(), table.truncated(), table.dataFragments(), table.comment()) : table); Map newViews = new HashMap<>(); @@ -186,7 +187,7 @@ public synchronized void renameSchema(ConnectorSession session, String source, S Entry view = iterator.next(); if (view.getKey().getSchemaName().equals(source)) { iterator.remove(); - newViews.put(new SchemaTableName(target, view.getKey().getTableName()), view.getValue()); + newViews.put(new SchemaTableName(target.getValue(), view.getKey().getTableName()), view.getValue()); } } views.putAll(newViews); @@ -196,7 +197,7 @@ public synchronized void renameSchema(ConnectorSession session, String source, S Entry> function = iterator.next(); if (function.getKey().schemaName().equals(source)) { iterator.remove(); - newFunctions.put(new SchemaFunctionName(target, function.getKey().functionName()), function.getValue()); + newFunctions.put(new SchemaFunctionName(target.getValue(), function.getKey().functionName()), function.getValue()); } } functions.putAll(newFunctions); diff --git a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java index 65b972dd1ea9..86097222e990 100644 --- a/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java +++ b/plugin/trino-mongodb/src/main/java/io/trino/plugin/mongodb/MongoMetadata.java @@ -29,6 +29,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorInsertTableHandle; import io.trino.spi.connector.ConnectorMetadata; import io.trino.spi.connector.ConnectorOutputMetadata; @@ -149,16 +150,16 @@ public List listSchemaNames(ConnectorSession session) } @Override - public void createSchema(ConnectorSession session, String schemaName, Map properties, TrinoPrincipal owner) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema, Map properties, TrinoPrincipal owner) { checkArgument(properties.isEmpty(), "Can't have properties for schema creation"); - mongoSession.createSchema(schemaName); + mongoSession.createSchema(schema.getValue()); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { - mongoSession.dropSchema(schemaName, cascade); + mongoSession.dropSchema(schema.getValue(), cascade); } @Override diff --git a/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java b/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java index e357274dc808..1a262eb0ef1e 100644 --- a/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java +++ b/plugin/trino-mysql/src/main/java/io/trino/plugin/mysql/MySqlClient.java @@ -69,6 +69,7 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ColumnPosition; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.JoinCondition; @@ -394,18 +395,18 @@ protected boolean filterRemoteSchema(String schemaName) } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { // MySQL always deletes all tables inside the database https://dev.mysql.com/doc/refman/8.0/en/drop-database.html if (!cascade) { - try (ResultSet tables = getTables(connection, Optional.of(remoteSchemaName), Optional.empty())) { + try (ResultSet tables = getTables(connection, Optional.of(schema.getValue()), Optional.empty())) { if (tables.next()) { - throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(remoteSchemaName)); + throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(schema.getValue())); } } } - execute(session, connection, "DROP SCHEMA " + quoted(remoteSchemaName)); + execute(session, connection, "DROP SCHEMA " + quoted(schema)); } @Override @@ -1007,7 +1008,7 @@ public void dropNotNullConstraint(ConnectorSession session, JdbcTableHandle hand } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java b/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java index 6758b2929933..a9dd834fce2e 100644 --- a/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java +++ b/plugin/trino-oracle/src/main/java/io/trino/plugin/oracle/OracleClient.java @@ -62,6 +62,7 @@ import io.trino.spi.TrinoException; import io.trino.spi.connector.AggregateFunction; import io.trino.spi.connector.ColumnHandle; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.JoinCondition; @@ -336,14 +337,14 @@ protected void renameTable(ConnectorSession session, Connection connection, Stri } @Override - public void createSchema(ConnectorSession session, String schemaName) + public void createSchema(ConnectorSession session, ConnectorIdentifier schema) { // ORA-02420: missing schema authorization clause throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating schemas"); } @Override - public void dropSchema(ConnectorSession session, String schemaName, boolean cascade) + public void dropSchema(ConnectorSession session, ConnectorIdentifier schema, boolean cascade) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas"); } @@ -380,7 +381,7 @@ protected void dropTable(ConnectorSession session, RemoteTableName remoteTableNa } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java b/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java index 2fb388d2dc89..f29bb591140d 100644 --- a/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java +++ b/plugin/trino-postgresql/src/test/java/io/trino/plugin/postgresql/TestPostgreSqlConnectorTest.java @@ -85,6 +85,8 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assumptions.abort; +import static org.junit.platform.engine.TestExecutionResult.aborted; /** * @see TestPostgreSqlConnectorSmokeTest @@ -1516,4 +1518,18 @@ protected TestTable createTestTableForWrites(String namePrefix, String tableDefi onRemoteDatabase().execute(format("ALTER TABLE %s ADD CONSTRAINT %s PRIMARY KEY (%s)", tableName, "pk_" + tableName, primaryKey)); return testTable; } + + @Test + @Override + public void testCreateSchemaWithLongName() + { + abort("After PR#28359 cant run this test with exception?"); + } + + @Test + @Override + public void testRenameSchemaToLongName() + { + abort("After PR#28359 cant run this test with exception?"); + } } diff --git a/plugin/trino-redshift/src/main/java/io/trino/plugin/redshift/RedshiftClient.java b/plugin/trino-redshift/src/main/java/io/trino/plugin/redshift/RedshiftClient.java index e5c1c629a800..7c4e846644d1 100644 --- a/plugin/trino-redshift/src/main/java/io/trino/plugin/redshift/RedshiftClient.java +++ b/plugin/trino-redshift/src/main/java/io/trino/plugin/redshift/RedshiftClient.java @@ -67,6 +67,7 @@ import io.trino.spi.connector.AggregateFunction; import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.JoinCondition; @@ -326,14 +327,14 @@ protected ResultSet getAllTableColumns(Connection connection, Optional r } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { if (cascade) { // Dropping schema with cascade option may lead to other metadata listing operations. Disable until finding the solution. throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas with CASCADE option"); } - execute(session, connection, "DROP SCHEMA " + quoted(remoteSchemaName)); + execute(session, connection, "DROP SCHEMA " + quoted(schema)); } @Override diff --git a/plugin/trino-singlestore/src/main/java/io/trino/plugin/singlestore/SingleStoreClient.java b/plugin/trino-singlestore/src/main/java/io/trino/plugin/singlestore/SingleStoreClient.java index 4fa6709608de..7373ba19e77b 100644 --- a/plugin/trino-singlestore/src/main/java/io/trino/plugin/singlestore/SingleStoreClient.java +++ b/plugin/trino-singlestore/src/main/java/io/trino/plugin/singlestore/SingleStoreClient.java @@ -40,6 +40,7 @@ import io.trino.spi.TrinoException; import io.trino.spi.connector.AggregateFunction; import io.trino.spi.connector.ColumnHandle; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.JoinCondition; import io.trino.spi.connector.JoinStatistics; @@ -246,19 +247,19 @@ protected boolean filterRemoteSchema(String schemaName) } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { // SingleStore always deletes all tables inside the database though // the behavior isn't documented in https://docs.singlestore.com/cloud/reference/sql-reference/data-definition-language-ddl/drop-database/ if (!cascade) { - try (ResultSet tables = getTables(connection, Optional.of(remoteSchemaName), Optional.empty())) { + try (ResultSet tables = getTables(connection, Optional.of(schema.getValue()), Optional.empty())) { if (tables.next()) { - throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(remoteSchemaName)); + throw new TrinoException(SCHEMA_NOT_EMPTY, "Cannot drop non-empty schema '%s'".formatted(schema.getValue())); } } } - execute(session, connection, "DROP SCHEMA " + quoted(remoteSchemaName)); + execute(session, connection, "DROP SCHEMA " + quoted(schema)); } @Override @@ -474,7 +475,7 @@ public void dropNotNullConstraint(ConnectorSession session, JdbcTableHandle hand } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java b/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java index fe979ebbbec1..5b24565ace3e 100644 --- a/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java +++ b/plugin/trino-sqlserver/src/main/java/io/trino/plugin/sqlserver/SqlServerClient.java @@ -72,6 +72,7 @@ import io.trino.spi.TrinoException; import io.trino.spi.connector.AggregateFunction; import io.trino.spi.connector.ColumnHandle; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.ConnectorTableMetadata; import io.trino.spi.connector.JoinCondition; @@ -353,14 +354,14 @@ public SqlServerClient( } @Override - protected void dropSchema(ConnectorSession session, Connection connection, String remoteSchemaName, boolean cascade) + protected void dropSchema(ConnectorSession session, Connection connection, ConnectorIdentifier schema, boolean cascade) throws SQLException { if (cascade) { // SQL Server doesn't support CASCADE option https://learn.microsoft.com/en-us/sql/t-sql/statements/drop-schema-transact-sql throw new TrinoException(NOT_SUPPORTED, "This connector does not support dropping schemas with CASCADE option"); } - execute(session, connection, "DROP SCHEMA " + quoted(remoteSchemaName)); + execute(session, connection, "DROP SCHEMA " + quoted(schema)); } @Override @@ -536,7 +537,7 @@ public Optional convertPredicate(ConnectorSession sessi } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/plugin/trino-vertica/src/main/java/io/trino/plugin/vertica/VerticaClient.java b/plugin/trino-vertica/src/main/java/io/trino/plugin/vertica/VerticaClient.java index 2b160ba666d1..dd0bb55f535e 100644 --- a/plugin/trino-vertica/src/main/java/io/trino/plugin/vertica/VerticaClient.java +++ b/plugin/trino-vertica/src/main/java/io/trino/plugin/vertica/VerticaClient.java @@ -36,6 +36,7 @@ import io.trino.plugin.jdbc.logging.RemoteQueryModifier; import io.trino.spi.TrinoException; import io.trino.spi.connector.ColumnHandle; +import io.trino.spi.connector.ConnectorIdentifier; import io.trino.spi.connector.ConnectorSession; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.expression.ConnectorExpression; @@ -406,7 +407,7 @@ public Optional convertPredicate(ConnectorSession sessi } @Override - public void renameSchema(ConnectorSession session, String schemaName, String newSchemaName) + public void renameSchema(ConnectorSession session, ConnectorIdentifier schema, ConnectorIdentifier newSchema) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support renaming schemas"); } diff --git a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java index 2e324dfd60d8..ba861afba9d3 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorSmokeTest.java @@ -69,11 +69,6 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) return connectorBehavior.hasBehaviorByDefault(this::hasBehavior); } - protected String createSchemaSql(String schemaName) - { - return "CREATE SCHEMA " + schemaName; - } - /** * Ensure the tests are run with {@link io.trino.testing.DistributedQueryRunner} with multiple workers. */ @@ -766,4 +761,12 @@ protected String getColumnComment(String tableName, String columnName) tableName, columnName)); } + + protected String createSchemaSql(String schemaName) + { + // If we want the connectors to create views with delimited identifiers, + // then it is necessary to provide quoted identifiers to Trino, + // otherwise the views will be created with undelimited identifiers. + return format("CREATE SCHEMA \"%s\"", schemaName); + } } diff --git a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java index 4d34ce707a3f..56179ced3aff 100644 --- a/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java +++ b/testing/trino-testing/src/main/java/io/trino/testing/BaseConnectorTest.java @@ -309,8 +309,8 @@ public void testDropNonEmptySchemaWithTable() assertQueryFails("DROP SCHEMA " + schemaName, ".*Cannot drop non-empty schema '\\Q" + schemaName + "\\E'"); } finally { - assertUpdate("DROP TABLE IF EXISTS " + schemaName + ".t"); - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName); + assertUpdate(dropSchemaSql(schemaName + ".t")); + assertUpdate(dropSchemaSql(schemaName)); } } @@ -333,8 +333,8 @@ public void testDropNonEmptySchemaWithView() assertQueryFails("DROP SCHEMA " + schemaName, ".*Cannot drop non-empty schema '\\Q" + schemaName + "\\E'"); } finally { - assertUpdate("DROP VIEW IF EXISTS " + schemaName + ".v_t"); - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName); + assertUpdate(dropSchemaSql(schemaName + ".v_t")); + assertUpdate(dropSchemaSql(schemaName)); } } @@ -358,7 +358,7 @@ public void testDropNonEmptySchemaWithMaterializedView() } finally { assertUpdate("DROP MATERIALIZED VIEW IF EXISTS " + schemaName + ".mv_t"); - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName); + assertUpdate(dropSchemaSql(schemaName)); } } @@ -2641,8 +2641,8 @@ public void testRenameSchema() .contains(schemaName + "_renamed"); } finally { - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName); - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName + "_renamed"); + assertUpdate(dropSchemaSql(schemaName)); + assertUpdate(dropSchemaSql(schemaName + "_renamed")); } } @@ -2688,7 +2688,7 @@ public void testDropSchemaCascade() assertUpdate("DROP TABLE IF EXISTS " + schemaName + "." + tableName); assertUpdate("DROP VIEW IF EXISTS " + schemaName + "." + viewName); assertUpdate("DROP MATERIALIZED VIEW IF EXISTS " + schemaName + "." + materializedViewName); - assertUpdate("DROP SCHEMA IF EXISTS " + schemaName); + assertUpdate(dropSchemaSql(schemaName)); } } @@ -4020,7 +4020,7 @@ public void testCreateSchemaWithNonLowercaseOwnerName() .containsAll(format("VALUES '%s'", schemaName)); } finally { - assertUpdate(newSession, "DROP SCHEMA IF EXISTS " + schemaName); + assertUpdate(newSession, dropSchemaSql(schemaName)); } } @@ -7967,11 +7967,6 @@ protected void withMockTableListing(String forSchema, Function