diff --git a/core/trino-main/src/main/java/io/trino/execution/CreateMaterializedViewTask.java b/core/trino-main/src/main/java/io/trino/execution/CreateMaterializedViewTask.java index 021ed3a89760..ff4b109d209b 100644 --- a/core/trino-main/src/main/java/io/trino/execution/CreateMaterializedViewTask.java +++ b/core/trino-main/src/main/java/io/trino/execution/CreateMaterializedViewTask.java @@ -160,8 +160,7 @@ public ListenableFuture execute( // system path elements are not stored .filter(element -> !element.getCatalogName().equals(GlobalSystemConnector.NAME)) .collect(toImmutableList()), - Optional.empty(), - properties); + Optional.empty()); Set specifiedPropertyKeys = statement.getProperties().stream() // property names are case-insensitive and normalized to lower case @@ -172,7 +171,7 @@ public ListenableFuture execute( .filter(specifiedPropertyKeys::contains) .collect(toImmutableMap(Function.identity(), properties::get)); accessControl.checkCanCreateMaterializedView(session.toSecurityContext(), name, explicitlySetProperties); - plannerContext.getMetadata().createMaterializedView(session, name, definition, statement.isReplace(), statement.isNotExists()); + plannerContext.getMetadata().createMaterializedView(session, name, definition, properties, statement.isReplace(), statement.isNotExists()); stateMachine.setOutput(analysis.getTarget()); stateMachine.setReferencedTables(analysis.getReferencedTables()); diff --git a/core/trino-main/src/main/java/io/trino/metadata/MaterializedViewDefinition.java b/core/trino-main/src/main/java/io/trino/metadata/MaterializedViewDefinition.java index caff709a19b5..6dc49947b030 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/MaterializedViewDefinition.java +++ b/core/trino-main/src/main/java/io/trino/metadata/MaterializedViewDefinition.java @@ -13,7 +13,6 @@ */ package io.trino.metadata; -import com.google.common.collect.ImmutableMap; import io.trino.spi.connector.CatalogSchemaName; import io.trino.spi.connector.CatalogSchemaTableName; import io.trino.spi.connector.ConnectorMaterializedViewDefinition; @@ -21,7 +20,6 @@ import java.time.Duration; import java.util.List; -import java.util.Map; import java.util.Optional; import static com.google.common.base.MoreObjects.toStringHelper; @@ -34,7 +32,6 @@ public class MaterializedViewDefinition { private final Optional gracePeriod; private final Optional storageTable; - private final Map properties; public MaterializedViewDefinition( String originalSql, @@ -45,14 +42,12 @@ public MaterializedViewDefinition( Optional comment, Identity owner, List path, - Optional storageTable, - Map properties) + Optional storageTable) { super(originalSql, catalog, schema, columns, comment, Optional.of(owner), path); checkArgument(gracePeriod.isEmpty() || !gracePeriod.get().isNegative(), "gracePeriod cannot be negative: %s", gracePeriod); this.gracePeriod = gracePeriod; this.storageTable = requireNonNull(storageTable, "storageTable is null"); - this.properties = ImmutableMap.copyOf(requireNonNull(properties, "properties is null")); } public Optional getGracePeriod() @@ -65,11 +60,6 @@ public Optional getStorageTable() return storageTable; } - public Map getProperties() - { - return properties; - } - public ConnectorMaterializedViewDefinition toConnectorMaterializedViewDefinition() { return new ConnectorMaterializedViewDefinition( @@ -83,8 +73,7 @@ public ConnectorMaterializedViewDefinition toConnectorMaterializedViewDefinition getGracePeriod(), getComment(), getRunAsIdentity().map(Identity::getUser), - getPath(), - properties); + getPath()); } @Override @@ -100,7 +89,6 @@ public String toString() .add("runAsIdentity", getRunAsIdentity()) .add("path", getPath()) .add("storageTable", storageTable.orElse(null)) - .add("properties", properties) .toString(); } } diff --git a/core/trino-main/src/main/java/io/trino/metadata/Metadata.java b/core/trino-main/src/main/java/io/trino/metadata/Metadata.java index bb2cad83e056..1b7ffa8e706c 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/Metadata.java +++ b/core/trino-main/src/main/java/io/trino/metadata/Metadata.java @@ -710,7 +710,13 @@ default ResolvedFunction getCoercion(Type fromType, Type toType) /** * Creates the specified materialized view with the specified view definition. */ - void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting); + void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting); /** * Drops the specified materialized view. @@ -740,6 +746,8 @@ default boolean isMaterializedView(Session session, QualifiedObjectName viewName */ Optional getMaterializedView(Session session, QualifiedObjectName viewName); + Map getMaterializedViewProperties(Session session, QualifiedObjectName objectName, MaterializedViewDefinition materializedViewDefinition); + /** * Method to get difference between the states of table at two different points in time/or as of given token-ids. * The method is used by the engine to determine if a materialized view is current with respect to the tables it depends on. 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 1adeb8d71a4a..a96e0977e6d8 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 @@ -1530,7 +1530,13 @@ public void dropView(Session session, QualifiedObjectName viewName) } @Override - public void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { CatalogMetadata catalogMetadata = getCatalogMetadataForWrite(session, viewName.getCatalogName()); CatalogHandle catalogHandle = catalogMetadata.getCatalogHandle(); @@ -1540,6 +1546,7 @@ public void createMaterializedView(Session session, QualifiedObjectName viewName session.toConnectorSession(catalogHandle), viewName.asSchemaTableName(), definition.toConnectorMaterializedViewDefinition(), + properties, replace, ignoreExisting); if (catalogMetadata.getSecurityManagement() == SYSTEM) { @@ -1673,8 +1680,7 @@ private static MaterializedViewDefinition createMaterializedViewDefinition(Conne view.getComment(), runAsIdentity, view.getPath(), - view.getStorageTable(), - view.getProperties()); + view.getStorageTable()); } private Optional getMaterializedViewInternal(Session session, QualifiedObjectName viewName) @@ -1695,6 +1701,24 @@ private Optional getMaterializedViewInterna return Optional.empty(); } + @Override + public Map getMaterializedViewProperties(Session session, QualifiedObjectName viewName, MaterializedViewDefinition materializedViewDefinition) + { + Optional catalog = getOptionalCatalogMetadata(session, viewName.getCatalogName()); + if (catalog.isPresent()) { + CatalogMetadata catalogMetadata = catalog.get(); + CatalogHandle catalogHandle = catalogMetadata.getCatalogHandle(session, viewName); + ConnectorMetadata metadata = catalogMetadata.getMetadataFor(session, catalogHandle); + + ConnectorSession connectorSession = session.toConnectorSession(catalogHandle); + return ImmutableMap.copyOf(metadata.getMaterializedViewProperties( + connectorSession, + viewName.asSchemaTableName(), + materializedViewDefinition.toConnectorMaterializedViewDefinition())); + } + return ImmutableMap.of(); + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(Session session, QualifiedObjectName viewName) { diff --git a/core/trino-main/src/main/java/io/trino/sql/rewrite/ShowQueriesRewrite.java b/core/trino-main/src/main/java/io/trino/sql/rewrite/ShowQueriesRewrite.java index 54c5ddec92f2..055bb28eb64b 100644 --- a/core/trino-main/src/main/java/io/trino/sql/rewrite/ShowQueriesRewrite.java +++ b/core/trino-main/src/main/java/io/trino/sql/rewrite/ShowQueriesRewrite.java @@ -606,7 +606,7 @@ protected Node visitShowCreate(ShowCreate node, Void context) accessControl.checkCanShowCreateTable(session.toSecurityContext(), new QualifiedObjectName(catalogName.getValue(), schemaName.getValue(), tableName.getValue())); - Map properties = viewDefinition.get().getProperties(); + Map properties = metadata.getMaterializedViewProperties(session, objectName, viewDefinition.get()); CatalogHandle catalogHandle = getRequiredCatalogHandle(metadata, session, node, catalogName.getValue()); Collection> allMaterializedViewProperties = materializedViewPropertyManager.getAllProperties(catalogHandle); List propertyNodes = buildProperties(objectName, Optional.empty(), INVALID_MATERIALIZED_VIEW_PROPERTY, properties, allMaterializedViewProperties); diff --git a/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java b/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java index 27f174bc7da5..7cbd8aabfc38 100644 --- a/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java +++ b/core/trino-main/src/main/java/io/trino/testing/TestingMetadata.java @@ -234,7 +234,13 @@ public Optional getView(ConnectorSession session, Schem } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { if (replace) { materializedViews.put(viewName, definition); @@ -264,6 +270,12 @@ public Optional getMaterializedView(Connect return Optional.ofNullable(materializedViews.get(viewName)); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition materializedViewDefinition) + { + return ImmutableMap.of(); + } + @Override public void dropMaterializedView(ConnectorSession session, SchemaTableName viewName) { 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 89de7ad8879e..774bc5b4a03a 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 @@ -1245,11 +1245,17 @@ public void validateScan(ConnectorSession session, ConnectorTableHandle handle) } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { Span span = startSpan("createMaterializedView", viewName); try (var ignored = scopedSpan(span)) { - delegate.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + delegate.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } } @@ -1289,6 +1295,15 @@ public Optional getMaterializedView(Connect } } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition materializedViewDefinition) + { + Span span = startSpan("getMaterializedViewProperties", viewName); + try (var ignored = scopedSpan(span)) { + return delegate.getMaterializedViewProperties(session, viewName, materializedViewDefinition); + } + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(ConnectorSession session, SchemaTableName name) { diff --git a/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java b/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java index 09e35c8ef453..d6e0dfedf6a5 100644 --- a/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java +++ b/core/trino-main/src/main/java/io/trino/tracing/TracingMetadata.java @@ -1302,11 +1302,17 @@ public void dropLanguageFunction(Session session, QualifiedObjectName name, Stri } @Override - public void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { Span span = startSpan("createMaterializedView", viewName); try (var ignored = scopedSpan(span)) { - delegate.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + delegate.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } } @@ -1355,6 +1361,15 @@ public Optional getMaterializedView(Session session, } } + @Override + public Map getMaterializedViewProperties(Session session, QualifiedObjectName objectName, MaterializedViewDefinition materializedViewDefinition) + { + Span span = startSpan("getMaterializedViewProperties", objectName); + try (var ignored = scopedSpan(span)) { + return delegate.getMaterializedViewProperties(session, objectName, materializedViewDefinition); + } + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(Session session, QualifiedObjectName name) { 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 82bf03c0a12a..3a3cb7a85ff1 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 @@ -665,7 +665,13 @@ public void setViewAuthorization(ConnectorSession session, SchemaTableName viewN public void dropView(ConnectorSession session, SchemaTableName viewName) {} @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) {} + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) {} @Override public List listMaterializedViews(ConnectorSession session, Optional schemaName) @@ -680,6 +686,12 @@ public Optional getMaterializedView(Connect return Optional.ofNullable(getMaterializedViews.apply(session, viewName.toSchemaTablePrefix()).get(viewName)); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition materializedViewDefinition) + { + return ImmutableMap.of(); + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(ConnectorSession session, SchemaTableName viewName) { diff --git a/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java b/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java index 8357a4d93a30..6d3dd9b72dde 100644 --- a/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java +++ b/core/trino-main/src/test/java/io/trino/execution/BaseDataDefinitionTaskTest.java @@ -42,7 +42,6 @@ import io.trino.spi.connector.ColumnHandle; import io.trino.spi.connector.ColumnMetadata; import io.trino.spi.connector.ConnectorTableMetadata; -import io.trino.spi.connector.MaterializedViewNotFoundException; import io.trino.spi.connector.SaveMode; import io.trino.spi.connector.SchemaTableName; import io.trino.spi.connector.TestingColumnHandle; @@ -108,6 +107,7 @@ public abstract class BaseDataDefinitionTaskTest protected static final String MATERIALIZED_VIEW_PROPERTY_2_NAME = "property2"; protected static final String MATERIALIZED_VIEW_PROPERTY_2_DEFAULT_VALUE = "defaultProperty2Value"; + protected static final Map MATERIALIZED_VIEW_PROPERTIES = ImmutableMap.of(MATERIALIZED_VIEW_PROPERTY_2_NAME, MATERIALIZED_VIEW_PROPERTY_2_DEFAULT_VALUE); private LocalQueryRunner queryRunner; protected Session testSession; @@ -196,8 +196,7 @@ protected MaterializedViewDefinition someMaterializedView(String sql, List tables = new ConcurrentHashMap<>(); private final Map views = new ConcurrentHashMap<>(); private final Map materializedViews = new ConcurrentHashMap<>(); + private final Map> materializedViewProperties = new ConcurrentHashMap<>(); public MockMetadata(String catalogName) { @@ -455,10 +455,23 @@ public Optional getMaterializedView(Session session, } @Override - public void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public Map getMaterializedViewProperties(Session session, QualifiedObjectName viewName, MaterializedViewDefinition materializedViewDefinition) + { + return materializedViewProperties.get(viewName.asSchemaTableName()); + } + + @Override + public void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { checkArgument(ignoreExisting || !materializedViews.containsKey(viewName.asSchemaTableName())); materializedViews.put(viewName.asSchemaTableName(), definition); + materializedViewProperties.put(viewName.asSchemaTableName(), properties); } @Override @@ -467,9 +480,7 @@ public synchronized void setMaterializedViewProperties( QualifiedObjectName viewName, Map> properties) { - MaterializedViewDefinition existingDefinition = getMaterializedView(session, viewName) - .orElseThrow(() -> new MaterializedViewNotFoundException(viewName.asSchemaTableName())); - Map newProperties = new HashMap<>(existingDefinition.getProperties()); + Map newProperties = new HashMap<>(materializedViewProperties.getOrDefault(viewName.asSchemaTableName(), ImmutableMap.of())); for (Entry> entry : properties.entrySet()) { if (entry.getValue().isPresent()) { newProperties.put(entry.getKey(), entry.getValue().orElseThrow()); @@ -478,19 +489,7 @@ public synchronized void setMaterializedViewProperties( newProperties.remove(entry.getKey()); } } - materializedViews.put( - viewName.asSchemaTableName(), - new MaterializedViewDefinition( - existingDefinition.getOriginalSql(), - existingDefinition.getCatalog(), - existingDefinition.getSchema(), - existingDefinition.getColumns(), - existingDefinition.getGracePeriod(), - existingDefinition.getComment(), - existingDefinition.getRunAsIdentity().get(), - existingDefinition.getPath(), - existingDefinition.getStorageTable(), - newProperties)); + materializedViewProperties.put(viewName.asSchemaTableName(), newProperties); } @Override @@ -510,8 +509,7 @@ public void setMaterializedViewColumnComment(Session session, QualifiedObjectNam view.getComment(), view.getRunAsIdentity().get(), view.getPath(), - view.getStorageTable(), - view.getProperties())); + view.getStorageTable())); } @Override diff --git a/core/trino-main/src/test/java/io/trino/execution/TestAddColumnTask.java b/core/trino-main/src/test/java/io/trino/execution/TestAddColumnTask.java index 5b497a1cc2f6..1d0e7699454d 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestAddColumnTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestAddColumnTask.java @@ -163,7 +163,7 @@ public void testAddColumnOnView() public void testAddColumnOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeAddColumn(asQualifiedName(materializedViewName), QualifiedName.of("test"), INTEGER, Optional.empty(), false, false))) .hasErrorCode(TABLE_NOT_FOUND) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestCommentTask.java b/core/trino-main/src/test/java/io/trino/execution/TestCommentTask.java index bca446767f66..2068a2b916f7 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestCommentTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestCommentTask.java @@ -69,7 +69,7 @@ public void testCommentTableOnView() public void testCommentTableOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(setComment(TABLE, asQualifiedName(materializedViewName), Optional.of("new comment")))) .hasErrorCode(TABLE_NOT_FOUND) @@ -102,7 +102,7 @@ public void testCommentViewOnTable() public void testCommentViewOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(setComment(VIEW, asQualifiedName(materializedViewName), Optional.of("new comment")))) .hasErrorCode(TABLE_NOT_FOUND) @@ -145,7 +145,7 @@ public void testCommentViewColumn() public void testCommentMaterializedViewColumn() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertThat(metadata.isMaterializedView(testSession, materializedViewName)).isTrue(); QualifiedName columnName = qualifiedColumnName("existing_materialized_view", "test"); diff --git a/core/trino-main/src/test/java/io/trino/execution/TestCreateMaterializedViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestCreateMaterializedViewTask.java index 7b103a902c60..c1a04c050bb8 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestCreateMaterializedViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestCreateMaterializedViewTask.java @@ -252,7 +252,7 @@ public void testCreateMaterializedViewWithDefaultProperties() Optional definitionOptional = metadata.getMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString())); assertThat(definitionOptional).isPresent(); - Map properties = definitionOptional.get().getProperties(); + Map properties = metadata.getMaterializedViewProperties(testSession, new QualifiedObjectName(TEST_CATALOG_NAME, "schema", "mv"), definitionOptional.get()); assertThat(properties.get("foo")).isEqualTo(DEFAULT_MATERIALIZED_VIEW_FOO_PROPERTY_VALUE); assertThat(properties.get("bar")).isEqualTo(DEFAULT_MATERIALIZED_VIEW_BAR_PROPERTY_VALUE); } @@ -310,11 +310,19 @@ private class MockMetadata extends AbstractMockMetadata { private final Map materializedViews = new ConcurrentHashMap<>(); + private final Map> materializedViewProperties = new ConcurrentHashMap<>(); @Override - public void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { materializedViews.put(viewName.asSchemaTableName(), definition); + materializedViewProperties.put(viewName.asSchemaTableName(), properties); if (!ignoreExisting) { throw new TrinoException(ALREADY_EXISTS, "Materialized view already exists"); } @@ -375,6 +383,12 @@ public Optional getMaterializedView(Session session, return Optional.ofNullable(materializedViews.get(viewName.asSchemaTableName())); } + @Override + public Map getMaterializedViewProperties(Session session, QualifiedObjectName viewName, MaterializedViewDefinition materializedViewDefinition) + { + return materializedViewProperties.get(viewName.asSchemaTableName()); + } + @Override public Optional getView(Session session, QualifiedObjectName viewName) { diff --git a/core/trino-main/src/test/java/io/trino/execution/TestCreateViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestCreateViewTask.java index 77c2c8240384..f9fcd7a69e68 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestCreateViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestCreateViewTask.java @@ -127,7 +127,7 @@ public void testReplaceViewOnTableIfExists() public void testCreateViewOnMaterializedView() { QualifiedObjectName viewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, viewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, viewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeCreateView(asQualifiedName(viewName), false))) .hasErrorCode(TABLE_ALREADY_EXISTS) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestDropColumnTask.java b/core/trino-main/src/test/java/io/trino/execution/TestDropColumnTask.java index a443dc529e80..8b6b234a48d0 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestDropColumnTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestDropColumnTask.java @@ -156,7 +156,7 @@ public void testDropColumnOnView() public void testDropColumnOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeDropColumn(asQualifiedName(materializedViewName), QualifiedName.of("test"), false, false))) .hasErrorCode(TABLE_NOT_FOUND) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestDropMaterializedViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestDropMaterializedViewTask.java index bfbd422399b9..2a7a2ba2fba6 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestDropMaterializedViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestDropMaterializedViewTask.java @@ -36,7 +36,7 @@ public class TestDropMaterializedViewTask public void testDropExistingMaterializedView() { QualifiedObjectName viewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, viewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, viewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertThat(metadata.isMaterializedView(testSession, viewName)).isTrue(); getFutureValue(executeDropMaterializedView(asQualifiedName(viewName), false)); diff --git a/core/trino-main/src/test/java/io/trino/execution/TestDropTableTask.java b/core/trino-main/src/test/java/io/trino/execution/TestDropTableTask.java index 79fcb4237689..48b4ba0e9c0f 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestDropTableTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestDropTableTask.java @@ -107,7 +107,7 @@ public void testDropTableIfExistsOnView() public void testDropTableOnMaterializedView() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, asQualifiedObjectName(viewName), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, asQualifiedObjectName(viewName), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeDropTable(viewName, false))) .hasErrorCode(GENERIC_USER_ERROR) @@ -118,7 +118,7 @@ public void testDropTableOnMaterializedView() public void testDropTableIfExistsOnMaterializedView() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, asQualifiedObjectName(viewName), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, asQualifiedObjectName(viewName), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeDropTable(viewName, true))) .hasErrorCode(GENERIC_USER_ERROR) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestDropViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestDropViewTask.java index 88af3f3802ee..b4838b2d6c99 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestDropViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestDropViewTask.java @@ -88,7 +88,7 @@ public void testDropViewOnTableIfExists() public void testDropViewOnMaterializedView() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeDropView(viewName, false))) .hasErrorCode(GENERIC_USER_ERROR) @@ -99,7 +99,7 @@ public void testDropViewOnMaterializedView() public void testDropViewOnMaterializedViewIfExists() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeDropView(viewName, true))) .hasErrorCode(GENERIC_USER_ERROR) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestRenameColumnTask.java b/core/trino-main/src/test/java/io/trino/execution/TestRenameColumnTask.java index 7441dc996980..ec0729f8b597 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestRenameColumnTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestRenameColumnTask.java @@ -117,7 +117,7 @@ public void testRenameColumnOnView() public void testRenameColumnOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameColumn(asQualifiedName(materializedViewName), QualifiedName.of("a"), identifier("a_renamed"), false, false))) .hasErrorCode(TABLE_NOT_FOUND) @@ -211,7 +211,7 @@ public void testRenameFieldOnView() public void testRenameFieldOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameColumn(asQualifiedName(materializedViewName), QualifiedName.of("test"), identifier("x"), false, false))) .hasErrorCode(TABLE_NOT_FOUND) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestRenameMaterializedViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestRenameMaterializedViewTask.java index e1527c7c06cf..c898c14ee83e 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestRenameMaterializedViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestRenameMaterializedViewTask.java @@ -38,7 +38,7 @@ public void testRenameExistingMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); QualifiedObjectName newMaterializedViewName = qualifiedObjectName("existing_materialized_view_new"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); getFutureValue(executeRenameMaterializedView(asQualifiedName(materializedViewName), asQualifiedName(newMaterializedViewName))); assertThat(metadata.isMaterializedView(testSession, materializedViewName)).isFalse(); @@ -90,7 +90,7 @@ public void testRenameMaterializedViewOnTableIfExists() public void testRenameMaterializedViewTargetTableExists() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); QualifiedObjectName tableName = qualifiedObjectName("existing_table"); metadata.createTable(testSession, TEST_CATALOG_NAME, someTable(tableName), FAIL); @@ -125,7 +125,7 @@ public void testRenameMaterializedViewOnViewIfExists() public void testRenameMaterializedViewTargetViewExists() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); QualifiedName viewName = qualifiedName("existing_view"); metadata.createView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someView(), false); diff --git a/core/trino-main/src/test/java/io/trino/execution/TestRenameTableTask.java b/core/trino-main/src/test/java/io/trino/execution/TestRenameTableTask.java index b6d06d046c66..791b28051b84 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestRenameTableTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestRenameTableTask.java @@ -90,7 +90,7 @@ public void testRenameTableOnViewIfExists() public void testRenameTableOnMaterializedView() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameTable(viewName, qualifiedName("existing_materialized_view_new"), false))) .hasErrorCode(GENERIC_USER_ERROR) @@ -101,7 +101,7 @@ public void testRenameTableOnMaterializedView() public void testRenameTableOnMaterializedViewIfExists() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameTable(viewName, qualifiedName("existing_materialized_view_new"), true))) .hasErrorCode(GENERIC_USER_ERROR) @@ -127,7 +127,7 @@ public void testRenameTableTargetMaterializedViewExists() QualifiedObjectName tableName = qualifiedObjectName("existing_table"); metadata.createTable(testSession, TEST_CATALOG_NAME, someTable(tableName), FAIL); QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameTable(asQualifiedName(tableName), asQualifiedName(materializedViewName), false))) .hasErrorCode(GENERIC_USER_ERROR) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestRenameViewTask.java b/core/trino-main/src/test/java/io/trino/execution/TestRenameViewTask.java index 00c55d18b0ac..2ff29c552578 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestRenameViewTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestRenameViewTask.java @@ -71,7 +71,7 @@ public void testRenameViewOnTable() public void testRenameViewOnMaterializedView() { QualifiedName viewName = qualifiedName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameView(viewName, qualifiedName("existing_materialized_view_new")))) .hasErrorCode(TABLE_NOT_FOUND) @@ -97,7 +97,7 @@ public void testRenameViewTargetMaterializedViewExists() QualifiedName viewName = qualifiedName("existing_view"); metadata.createView(testSession, QualifiedObjectName.valueOf(viewName.toString()), someView(), false); QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeRenameView(viewName, asQualifiedName(materializedViewName)))) .hasErrorCode(GENERIC_USER_ERROR) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestSetColumnTypeTask.java b/core/trino-main/src/test/java/io/trino/execution/TestSetColumnTypeTask.java index 8de522663eeb..c7a0cc5f0273 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestSetColumnTypeTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestSetColumnTypeTask.java @@ -113,7 +113,7 @@ public void testSetDataTypeOnView() public void testSetDataTypeOnMaterializedView() { QualifiedObjectName materializedViewName = qualifiedObjectName("existing_materialized_view"); - metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, QualifiedObjectName.valueOf(materializedViewName.toString()), someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); assertTrinoExceptionThrownBy(() -> getFutureValue(executeSetColumnType(asQualifiedName(materializedViewName), QualifiedName.of("test"), toSqlType(INTEGER), false))) .hasErrorCode(TABLE_NOT_FOUND) diff --git a/core/trino-main/src/test/java/io/trino/execution/TestSetPropertiesTask.java b/core/trino-main/src/test/java/io/trino/execution/TestSetPropertiesTask.java index e351361d8d69..89de2490d282 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestSetPropertiesTask.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestSetPropertiesTask.java @@ -17,6 +17,7 @@ import com.google.common.collect.ImmutableMap; import io.trino.connector.CatalogServiceProvider; import io.trino.execution.warnings.WarningCollector; +import io.trino.metadata.MaterializedViewDefinition; import io.trino.metadata.QualifiedObjectName; import io.trino.metadata.TablePropertyManager; import io.trino.security.AllowAllAccessControl; @@ -37,7 +38,7 @@ public class TestSetPropertiesTask public void testSetMaterializedViewProperties() { QualifiedObjectName materializedViewName = qualifiedObjectName("test_materialized_view"); - metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), false, false); + metadata.createMaterializedView(testSession, materializedViewName, someMaterializedView(), MATERIALIZED_VIEW_PROPERTIES, false, false); // set all properties to non-DEFAULT values and check the results executeSetProperties( @@ -47,7 +48,8 @@ public void testSetMaterializedViewProperties() ImmutableList.of( new Property(new Identifier(MATERIALIZED_VIEW_PROPERTY_1_NAME), new LongLiteral("111")), new Property(new Identifier(MATERIALIZED_VIEW_PROPERTY_2_NAME), new StringLiteral("abc"))))); - assertThat(metadata.getMaterializedView(testSession, materializedViewName).get().getProperties()).isEqualTo( + MaterializedViewDefinition materializedViewDefinition = metadata.getMaterializedView(testSession, materializedViewName).orElseThrow(); + assertThat(metadata.getMaterializedViewProperties(testSession, materializedViewName, materializedViewDefinition)).isEqualTo( ImmutableMap.of( MATERIALIZED_VIEW_PROPERTY_1_NAME, 111L, MATERIALIZED_VIEW_PROPERTY_2_NAME, "abc")); @@ -62,7 +64,7 @@ public void testSetMaterializedViewProperties() new Property(new Identifier(MATERIALIZED_VIEW_PROPERTY_2_NAME))))); // since the default value of property 1 is null, property 1 should not appear in the result, whereas property 2 should appear in // the result with its (non-null) default value - assertThat(metadata.getMaterializedView(testSession, materializedViewName).get().getProperties()).isEqualTo( + assertThat(metadata.getMaterializedViewProperties(testSession, materializedViewName, materializedViewDefinition)).isEqualTo( ImmutableMap.of(MATERIALIZED_VIEW_PROPERTY_2_NAME, MATERIALIZED_VIEW_PROPERTY_2_DEFAULT_VALUE)); } diff --git a/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java b/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java index 2611b045a74e..6e94d564b9d8 100644 --- a/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java +++ b/core/trino-main/src/test/java/io/trino/metadata/AbstractMockMetadata.java @@ -910,7 +910,13 @@ public Optional> applyTopN(Session session, T } @Override - public void createMaterializedView(Session session, QualifiedObjectName viewName, MaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + Session session, + QualifiedObjectName viewName, + MaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { throw new UnsupportedOperationException(); } @@ -939,6 +945,12 @@ public Optional getMaterializedView(Session session, throw new UnsupportedOperationException(); } + @Override + public Map getMaterializedViewProperties(Session session, QualifiedObjectName viewName, MaterializedViewDefinition materializedViewDefinition) + { + throw new UnsupportedOperationException(); + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(Session session, QualifiedObjectName name) { diff --git a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestAnalyzer.java b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestAnalyzer.java index 503f5ba2dbec..613eb7ebbdf3 100644 --- a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestAnalyzer.java +++ b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestAnalyzer.java @@ -6847,9 +6847,14 @@ public void setup() Optional.of("comment"), Identity.ofUser("user"), ImmutableList.of(), - Optional.empty(), - ImmutableMap.of()); - inSetupTransaction(session -> metadata.createMaterializedView(session, new QualifiedObjectName(TPCH_CATALOG, "s1", "mv1"), materializedViewData1, false, true)); + Optional.empty()); + inSetupTransaction(session -> metadata.createMaterializedView( + session, + new QualifiedObjectName(TPCH_CATALOG, "s1", "mv1"), + materializedViewData1, + ImmutableMap.of(), + false, + true)); // valid view referencing table in same schema ViewDefinition viewData1 = new ViewDefinition( @@ -6971,8 +6976,8 @@ public void setup() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t1")), - ImmutableMap.of()), + Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t1"))), + ImmutableMap.of(), false, false)); ViewDefinition viewDefinition = new ViewDefinition( @@ -7024,8 +7029,8 @@ public void setup() Identity.ofUser("some user"), ImmutableList.of(), // t3 has a, b column and hidden column x - Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t3")), - ImmutableMap.of()), + Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t3"))), + ImmutableMap.of(), false, false)); testingConnectorMetadata.markMaterializedViewIsFresh(freshMaterializedView.asSchemaTableName()); @@ -7043,8 +7048,8 @@ public void setup() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2")), - ImmutableMap.of()), + Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2"))), + ImmutableMap.of(), false, false)); testingConnectorMetadata.markMaterializedViewIsFresh(freshMaterializedViewMismatchedColumnCount.asSchemaTableName()); @@ -7062,8 +7067,8 @@ public void setup() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2")), - ImmutableMap.of()), + Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2"))), + ImmutableMap.of(), false, false)); testingConnectorMetadata.markMaterializedViewIsFresh(freshMaterializedMismatchedColumnName.asSchemaTableName()); @@ -7081,8 +7086,8 @@ public void setup() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2")), - ImmutableMap.of()), + Optional.of(new CatalogSchemaTableName(TPCH_CATALOG, "s1", "t2"))), + ImmutableMap.of(), false, false)); testingConnectorMetadata.markMaterializedViewIsFresh(freshMaterializedMismatchedColumnType.asSchemaTableName()); diff --git a/core/trino-main/src/test/java/io/trino/sql/planner/TestMaterializedViews.java b/core/trino-main/src/test/java/io/trino/sql/planner/TestMaterializedViews.java index 253be3ac8a24..0b5e5f98059a 100644 --- a/core/trino-main/src/test/java/io/trino/sql/planner/TestMaterializedViews.java +++ b/core/trino-main/src/test/java/io/trino/sql/planner/TestMaterializedViews.java @@ -134,13 +134,13 @@ protected LocalQueryRunner createLocalQueryRunner() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TEST_CATALOG_NAME, SCHEMA, "storage_table")), - ImmutableMap.of()); + Optional.of(new CatalogSchemaTableName(TEST_CATALOG_NAME, SCHEMA, "storage_table"))); queryRunner.inTransaction(session -> { metadata.createMaterializedView( session, freshMaterializedView, materializedViewDefinition, + ImmutableMap.of(), false, false); return null; @@ -153,6 +153,7 @@ protected LocalQueryRunner createLocalQueryRunner() session, notFreshMaterializedView, materializedViewDefinition, + ImmutableMap.of(), false, false); return null; @@ -167,14 +168,14 @@ protected LocalQueryRunner createLocalQueryRunner() Optional.empty(), Identity.ofUser("some user"), ImmutableList.of(), - Optional.of(new CatalogSchemaTableName(TEST_CATALOG_NAME, SCHEMA, "storage_table_with_casts")), - ImmutableMap.of()); + Optional.of(new CatalogSchemaTableName(TEST_CATALOG_NAME, SCHEMA, "storage_table_with_casts"))); QualifiedObjectName materializedViewWithCasts = new QualifiedObjectName(TEST_CATALOG_NAME, SCHEMA, "materialized_view_with_casts"); queryRunner.inTransaction(session -> { metadata.createMaterializedView( session, materializedViewWithCasts, materializedViewDefinitionWithCasts, + ImmutableMap.of(), false, false); return null; @@ -186,6 +187,7 @@ protected LocalQueryRunner createLocalQueryRunner() session, new QualifiedObjectName(TEST_CATALOG_NAME, SCHEMA, "stale_materialized_view_with_casts"), materializedViewDefinitionWithCasts, + ImmutableMap.of(), false, false); return null; diff --git a/core/trino-main/src/test/java/io/trino/sql/query/TestColumnMask.java b/core/trino-main/src/test/java/io/trino/sql/query/TestColumnMask.java index e1d6cc342035..bce26d122494 100644 --- a/core/trino-main/src/test/java/io/trino/sql/query/TestColumnMask.java +++ b/core/trino-main/src/test/java/io/trino/sql/query/TestColumnMask.java @@ -122,8 +122,7 @@ public TestColumnMask() Optional.of(Duration.ZERO), Optional.empty(), Optional.of(VIEW_OWNER), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); ConnectorMaterializedViewDefinition freshMaterializedView = new ConnectorMaterializedViewDefinition( "SELECT * FROM local.tiny.nation", @@ -138,8 +137,7 @@ public TestColumnMask() Optional.of(Duration.ZERO), Optional.empty(), Optional.of(VIEW_OWNER), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); ConnectorMaterializedViewDefinition materializedViewWithCasts = new ConnectorMaterializedViewDefinition( "SELECT nationkey, cast(name as varchar(1)) as name, regionkey, comment FROM local.tiny.nation", @@ -154,8 +152,7 @@ public TestColumnMask() Optional.of(Duration.ZERO), Optional.empty(), Optional.of(VIEW_OWNER), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); MockConnectorFactory mock = MockConnectorFactory.builder() .withGetColumns(schemaTableName -> { diff --git a/core/trino-main/src/test/java/io/trino/testing/TestTestingMetadata.java b/core/trino-main/src/test/java/io/trino/testing/TestTestingMetadata.java index 8b5bad533ce5..d188741497da 100644 --- a/core/trino-main/src/test/java/io/trino/testing/TestTestingMetadata.java +++ b/core/trino-main/src/test/java/io/trino/testing/TestTestingMetadata.java @@ -43,7 +43,7 @@ private void testRenameMaterializedView(String source, String target) SchemaTableName newName = schemaTableName("schema", target); TestingMetadata metadata = new TestingMetadata(); ConnectorMaterializedViewDefinition viewDefinition = someMaterializedView(); - metadata.createMaterializedView(SESSION, initialName, viewDefinition, false, false); + metadata.createMaterializedView(SESSION, initialName, viewDefinition, ImmutableMap.of(), false, false); metadata.renameMaterializedView(SESSION, initialName, newName); @@ -62,7 +62,6 @@ private static ConnectorMaterializedViewDefinition someMaterializedView() Optional.of(Duration.ZERO), Optional.empty(), Optional.of("owner"), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); } } diff --git a/core/trino-spi/pom.xml b/core/trino-spi/pom.xml index 1f76552d4fc1..4c0ffdc0393f 100644 --- a/core/trino-spi/pom.xml +++ b/core/trino-spi/pom.xml @@ -212,6 +212,20 @@ + + java.method.numberOfParametersChanged + method void io.trino.spi.connector.ConnectorMaterializedViewDefinition::<init>(java.lang.String, java.util.Optional<io.trino.spi.connector.CatalogSchemaTableName>, java.util.Optional<java.lang.String>, java.util.Optional<java.lang.String>, java.util.List<io.trino.spi.connector.ConnectorMaterializedViewDefinition.Column>, java.util.Optional<java.time.Duration>, java.util.Optional<java.lang.String>, java.util.Optional<java.lang.String>, java.util.List<io.trino.spi.connector.CatalogSchemaName>, java.util.Map<java.lang.String, java.lang.Object>) + method void io.trino.spi.connector.ConnectorMaterializedViewDefinition::<init>(java.lang.String, java.util.Optional<io.trino.spi.connector.CatalogSchemaTableName>, java.util.Optional<java.lang.String>, java.util.Optional<java.lang.String>, java.util.List<io.trino.spi.connector.ConnectorMaterializedViewDefinition.Column>, java.util.Optional<java.time.Duration>, java.util.Optional<java.lang.String>, java.util.Optional<java.lang.String>, java.util.List<io.trino.spi.connector.CatalogSchemaName>) + + + java.method.removed + method java.util.Map<java.lang.String, java.lang.Object> io.trino.spi.connector.ConnectorMaterializedViewDefinition::getProperties() + + + java.method.numberOfParametersChanged + method void io.trino.spi.connector.ConnectorMetadata::createMaterializedView(io.trino.spi.connector.ConnectorSession, io.trino.spi.connector.SchemaTableName, io.trino.spi.connector.ConnectorMaterializedViewDefinition, boolean, boolean) + method void io.trino.spi.connector.ConnectorMetadata::createMaterializedView(io.trino.spi.connector.ConnectorSession, io.trino.spi.connector.SchemaTableName, io.trino.spi.connector.ConnectorMaterializedViewDefinition, java.util.Map<java.lang.String, java.lang.Object>, boolean, boolean) + diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMaterializedViewDefinition.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMaterializedViewDefinition.java index 98a429d3dcee..d7ebd0097f49 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMaterializedViewDefinition.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorMaterializedViewDefinition.java @@ -17,7 +17,6 @@ import java.time.Duration; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.StringJoiner; @@ -37,7 +36,6 @@ public class ConnectorMaterializedViewDefinition private final Optional comment; private final Optional owner; private final List path; - private final Map properties; public ConnectorMaterializedViewDefinition( String originalSql, @@ -48,8 +46,7 @@ public ConnectorMaterializedViewDefinition( Optional gracePeriod, Optional comment, Optional owner, - List path, - Map properties) + List path) { this.originalSql = requireNonNull(originalSql, "originalSql is null"); this.storageTable = requireNonNull(storageTable, "storageTable is null"); @@ -61,7 +58,6 @@ public ConnectorMaterializedViewDefinition( this.comment = requireNonNull(comment, "comment is null"); this.owner = requireNonNull(owner, "owner is null"); this.path = List.copyOf(path); - this.properties = requireNonNull(properties, "properties are null"); if (catalog.isEmpty() && schema.isPresent()) { throw new IllegalArgumentException("catalog must be present if schema is present"); @@ -116,11 +112,6 @@ public List getPath() return path; } - public Map getProperties() - { - return properties; - } - @Override public String toString() { @@ -133,9 +124,8 @@ public String toString() gracePeriod.ifPresent(value -> joiner.add("gracePeriod=" + gracePeriod)); comment.ifPresent(value -> joiner.add("comment=" + value)); joiner.add("owner=" + owner); - joiner.add("properties=" + properties); joiner.add(path.stream().map(CatalogSchemaName::toString).collect(joining(", ", "path=(", ")"))); - return getClass().getSimpleName() + joiner.toString(); + return getClass().getSimpleName() + joiner; } @Override @@ -156,14 +146,13 @@ public boolean equals(Object o) Objects.equals(gracePeriod, that.gracePeriod) && Objects.equals(comment, that.comment) && Objects.equals(owner, that.owner) && - Objects.equals(path, that.path) && - Objects.equals(properties, that.properties); + Objects.equals(path, that.path); } @Override public int hashCode() { - return Objects.hash(originalSql, storageTable, catalog, schema, columns, gracePeriod, comment, owner, path, properties); + return Objects.hash(originalSql, storageTable, catalog, schema, columns, gracePeriod, comment, owner, path); } public static final class Column 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 3a006f8a0a84..5f0bdc7602b5 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 @@ -1661,7 +1661,13 @@ default void validateScan(ConnectorSession session, ConnectorTableHandle handle) * * @throws TrinoException with {@code ALREADY_EXISTS} if the object already exists and {@param ignoreExisting} is not set */ - default void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + default void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating materialized views"); } @@ -1709,6 +1715,11 @@ default Optional getMaterializedView(Connec return Optional.empty(); } + default Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition materializedViewDefinition) + { + throw new TrinoException(NOT_SUPPORTED, "This connector does not support materialized views"); + } + /** * The method is used by the engine to determine if a materialized view is current with respect to the tables it depends on. * diff --git a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java index dfbed636f83b..05547e0d26f5 100644 --- a/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java +++ b/lib/trino-plugin-toolkit/src/main/java/io/trino/plugin/base/classloader/ClassLoaderSafeConnectorMetadata.java @@ -1089,10 +1089,16 @@ public void validateScan(ConnectorSession session, ConnectorTableHandle handle) } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) { - delegate.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + delegate.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } } @@ -1128,6 +1134,14 @@ public Optional getMaterializedView(Connect } } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition viewDefinition) + { + try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) { + return delegate.getMaterializedViewProperties(session, viewName, viewDefinition); + } + } + @Override public MaterializedViewFreshness getMaterializedViewFreshness(ConnectorSession session, SchemaTableName name) { 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 fd5e88a633ee..f0e6341005f6 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 @@ -723,10 +723,16 @@ public ConnectorMergeTableHandle beginMerge(ConnectorSession session, ConnectorT } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { // TODO Fix BaseBigQueryFailureRecoveryTest when implementing this method - ConnectorMetadata.super.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + ConnectorMetadata.super.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMaterializedViewMetadata.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMaterializedViewMetadata.java index f47ad0dba86c..b2f405f24211 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMaterializedViewMetadata.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/HiveMaterializedViewMetadata.java @@ -25,7 +25,13 @@ public interface HiveMaterializedViewMetadata { - void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting); + void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting); void dropMaterializedView(ConnectorSession session, SchemaTableName viewName); 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 a6c53d5543a5..c95a23fde674 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 @@ -3857,9 +3857,15 @@ public void cleanupQuery(ConnectorSession session) } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { - hiveMaterializedViewMetadata.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + hiveMaterializedViewMetadata.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } @Override diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/NoneHiveMaterializedViewMetadata.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/NoneHiveMaterializedViewMetadata.java index a23d562b616d..0c99c96f3997 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/NoneHiveMaterializedViewMetadata.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/NoneHiveMaterializedViewMetadata.java @@ -33,7 +33,13 @@ public class NoneHiveMaterializedViewMetadata implements HiveMaterializedViewMetadata { @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { throw new TrinoException(NOT_SUPPORTED, "This connector does not support creating materialized views"); } 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 34c85ee6a89a..9595bb202cde 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 @@ -2749,9 +2749,15 @@ Table getIcebergTable(ConnectorSession session, SchemaTableName schemaTableName) } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map properties, + boolean replace, + boolean ignoreExisting) { - catalog.createMaterializedView(session, viewName, definition, replace, ignoreExisting); + catalog.createMaterializedView(session, viewName, definition, properties, replace, ignoreExisting); } @Override @@ -2881,6 +2887,12 @@ public Optional getMaterializedView(Connect return catalog.getMaterializedView(session, viewName); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + { + return catalog.getMaterializedViewProperties(session, viewName, definition); + } + @Override public void renameMaterializedView(ConnectorSession session, SchemaTableName source, SchemaTableName target) { diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/AbstractTrinoCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/AbstractTrinoCatalog.java index f9e80d3eb42f..9f3627088aa0 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/AbstractTrinoCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/AbstractTrinoCatalog.java @@ -77,6 +77,7 @@ import static io.trino.plugin.hive.metastore.glue.converter.GlueToTrinoConverter.mappedCopy; import static io.trino.plugin.hive.util.HiveUtil.escapeTableName; import static io.trino.plugin.iceberg.IcebergErrorCode.ICEBERG_FILESYSTEM_ERROR; +import static io.trino.plugin.iceberg.IcebergErrorCode.ICEBERG_INVALID_METADATA; import static io.trino.plugin.iceberg.IcebergMaterializedViewAdditionalProperties.STORAGE_SCHEMA; import static io.trino.plugin.iceberg.IcebergMaterializedViewAdditionalProperties.getStorageSchema; import static io.trino.plugin.iceberg.IcebergMaterializedViewDefinition.decodeMaterializedViewData; @@ -201,6 +202,25 @@ public Optional getMaterializedView(Connect protected abstract Optional doGetMaterializedView(ConnectorSession session, SchemaTableName schemaViewName); + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + { + SchemaTableName storageTableName = definition.getStorageTable() + .orElseThrow(() -> new TrinoException(ICEBERG_INVALID_METADATA, "Materialized view definition is missing a storage table")) + .getSchemaTableName(); + + try { + Table storageTable = loadTable(session, definition.getStorageTable().orElseThrow().getSchemaTableName()); + return ImmutableMap.builder() + .putAll(getIcebergTableProperties(storageTable)) + .put(STORAGE_SCHEMA, storageTableName.getSchemaName()) + .buildOrThrow(); + } + catch (RuntimeException e) { + throw new TrinoException(ICEBERG_FILESYSTEM_ERROR, "Unable to load storage table metadata for materialized view: " + viewName); + } + } + protected Transaction newCreateTableTransaction( ConnectorSession session, SchemaTableName schemaTableName, @@ -281,20 +301,24 @@ protected void deleteTableDirectory(TrinoFileSystem fileSystem, SchemaTableName } } - protected Location createMaterializedViewStorage(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + protected Location createMaterializedViewStorage( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties) { - if (getStorageSchema(definition.getProperties()).isPresent()) { + if (getStorageSchema(materializedViewProperties).isPresent()) { throw new TrinoException(NOT_SUPPORTED, "Materialized view property '%s' is not supported when hiding materialized view storage tables is enabled".formatted(STORAGE_SCHEMA)); } SchemaTableName storageTableName = new SchemaTableName(viewName.getSchemaName(), tableNameWithType(viewName.getTableName(), MATERIALIZED_VIEW_STORAGE)); - String tableLocation = getTableLocation(definition.getProperties()) + String tableLocation = getTableLocation(materializedViewProperties) .orElseGet(() -> defaultTableLocation(session, viewName)); - List columns = columnsForMaterializedView(definition); + List columns = columnsForMaterializedView(definition, materializedViewProperties); Schema schema = schemaFromMetadata(columns); - PartitionSpec partitionSpec = parsePartitionFields(schema, getPartitioning(definition.getProperties())); - SortOrder sortOrder = parseSortFields(schema, getSortOrder(definition.getProperties())); - Map properties = createTableProperties(new ConnectorTableMetadata(storageTableName, columns, definition.getProperties(), Optional.empty())); + PartitionSpec partitionSpec = parsePartitionFields(schema, getPartitioning(materializedViewProperties)); + SortOrder sortOrder = parseSortFields(schema, getSortOrder(materializedViewProperties)); + Map properties = createTableProperties(new ConnectorTableMetadata(storageTableName, columns, materializedViewProperties, Optional.empty())); TableMetadata metadata = newTableMetadata(schema, partitionSpec, sortOrder, tableLocation, properties); @@ -307,17 +331,21 @@ protected Location createMaterializedViewStorage(ConnectorSession session, Schem return metadataFileLocation; } - protected SchemaTableName createMaterializedViewStorageTable(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + protected SchemaTableName createMaterializedViewStorageTable( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties) { // Generate a storage table name and create a storage table. The properties in the definition are table properties for the // storage table as indicated in the materialized view definition. String storageTableName = "st_" + randomUUID().toString().replace("-", ""); - String storageSchema = getStorageSchema(definition.getProperties()).orElse(viewName.getSchemaName()); + String storageSchema = getStorageSchema(materializedViewProperties).orElse(viewName.getSchemaName()); SchemaTableName storageTable = new SchemaTableName(storageSchema, storageTableName); - List columns = columnsForMaterializedView(definition); + List columns = columnsForMaterializedView(definition, materializedViewProperties); - ConnectorTableMetadata tableMetadata = new ConnectorTableMetadata(storageTable, columns, definition.getProperties(), Optional.empty()); + ConnectorTableMetadata tableMetadata = new ConnectorTableMetadata(storageTable, columns, materializedViewProperties, Optional.empty()); Transaction transaction = IcebergUtil.newCreateTableTransaction(this, tableMetadata, session, false); AppendFiles appendFiles = transaction.newAppend(); commit(appendFiles, session); @@ -325,7 +353,7 @@ protected SchemaTableName createMaterializedViewStorageTable(ConnectorSession se return storageTable; } - private List columnsForMaterializedView(ConnectorMaterializedViewDefinition definition) + private List columnsForMaterializedView(ConnectorMaterializedViewDefinition definition, Map materializedViewProperties) { Schema schemaWithTimestampTzPreserved = schemaFromMetadata(mappedCopy( definition.getColumns(), @@ -340,7 +368,7 @@ private List columnsForMaterializedView(ConnectorMaterializedVie } return new ColumnMetadata(column.getName(), type); })); - PartitionSpec partitionSpec = parsePartitionFields(schemaWithTimestampTzPreserved, getPartitioning(definition.getProperties())); + PartitionSpec partitionSpec = parsePartitionFields(schemaWithTimestampTzPreserved, getPartitioning(materializedViewProperties)); Set temporalPartitioningSources = partitionSpec.fields().stream() .flatMap(partitionField -> { Types.NestedField sourceField = schemaWithTimestampTzPreserved.findField(partitionField.sourceId()); @@ -422,7 +450,6 @@ private Type typeForMaterializedViewStorageTable(Type type) } protected ConnectorMaterializedViewDefinition getMaterializedViewDefinition( - Table icebergTable, Optional owner, String viewOriginalText, SchemaTableName storageTableName) @@ -437,11 +464,7 @@ protected ConnectorMaterializedViewDefinition getMaterializedViewDefinition( definition.getGracePeriod(), definition.getComment(), owner, - definition.getPath(), - ImmutableMap.builder() - .putAll(getIcebergTableProperties(icebergTable)) - .put(STORAGE_SCHEMA, storageTableName.getSchemaName()) - .buildOrThrow()); + definition.getPath()); } protected List toSpiMaterializedViewColumns(List columns) diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/TrinoCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/TrinoCatalog.java index 8d44190ee307..e2aa957148ae 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/TrinoCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/TrinoCatalog.java @@ -163,6 +163,7 @@ void createMaterializedView( ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, boolean replace, boolean ignoreExisting); @@ -172,6 +173,8 @@ void createMaterializedView( Optional getMaterializedView(ConnectorSession session, SchemaTableName viewName); + Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition); + Optional getMaterializedViewStorageTable(ConnectorSession session, SchemaTableName viewName); void renameMaterializedView(ConnectorSession session, SchemaTableName source, SchemaTableName target); diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java index fd79f33587d3..b901158e8d0d 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/glue/TrinoGlueCatalog.java @@ -866,7 +866,7 @@ else if (isTrinoMaterializedView(tableType, parameters)) { try { // Note: this is racy from cache invalidation perspective, but it should not matter here uncheckedCacheGet(materializedViewCache, schemaTableName, () -> { - ConnectorMaterializedViewDefinition materializedView = createMaterializedViewDefinition(session, schemaTableName, table); + ConnectorMaterializedViewDefinition materializedView = createMaterializedViewDefinition(schemaTableName, table); return new MaterializedViewData( materializedView, Optional.ofNullable(parameters.get(METADATA_LOCATION_PROP))); @@ -1128,6 +1128,7 @@ public void createMaterializedView( ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, boolean replace, boolean ignoreExisting) { @@ -1146,7 +1147,7 @@ public void createMaterializedView( } if (hideMaterializedViewStorageTable) { - Location storageMetadataLocation = createMaterializedViewStorage(session, viewName, definition); + Location storageMetadataLocation = createMaterializedViewStorage(session, viewName, definition, materializedViewProperties); TableInput materializedViewTableInput = getMaterializedViewTableInput( viewName.getTableName(), encodeMaterializedViewData(fromConnectorMaterializedViewDefinition(definition)), @@ -1160,7 +1161,7 @@ public void createMaterializedView( } } else { - createMaterializedViewWithStorageTable(session, viewName, definition, existing); + createMaterializedViewWithStorageTable(session, viewName, definition, materializedViewProperties, existing); } } @@ -1168,10 +1169,11 @@ private void createMaterializedViewWithStorageTable( ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, Optional existing) { // Create the storage table - SchemaTableName storageTable = createMaterializedViewStorageTable(session, viewName, definition); + SchemaTableName storageTable = createMaterializedViewStorageTable(session, viewName, definition, materializedViewProperties); // Create a view indicating the storage table TableInput materializedViewTableInput = getMaterializedViewTableInput( viewName.getTableName(), @@ -1218,8 +1220,7 @@ public void updateMaterializedViewColumnComment(ConnectorSession session, Schema definition.getGracePeriod(), definition.getComment(), definition.getOwner(), - definition.getPath(), - definition.getProperties()); + definition.getPath()); updateMaterializedView(viewName, newDefinition); } @@ -1293,11 +1294,10 @@ protected Optional doGetMaterializedView(Co return Optional.empty(); } - return Optional.of(createMaterializedViewDefinition(session, viewName, table)); + return Optional.of(createMaterializedViewDefinition(viewName, table)); } private ConnectorMaterializedViewDefinition createMaterializedViewDefinition( - ConnectorSession session, SchemaTableName viewName, com.amazonaws.services.glue.model.Table table) { @@ -1315,54 +1315,18 @@ private ConnectorMaterializedViewDefinition createMaterializedViewDefinition( .orElse(viewName.getSchemaName()); SchemaTableName storageTableName = new SchemaTableName(storageSchema, storageTable); - Table icebergTable; - try { - icebergTable = loadTable(session, storageTableName); - } - catch (RuntimeException e) { - // The materialized view could be removed concurrently. This may manifest in a number of ways, e.g. - // - io.trino.spi.connector.TableNotFoundException - // - org.apache.iceberg.exceptions.NotFoundException when accessing manifest file - // - other failures when reading storage table's metadata files - // Retry, as we're catching broadly. - throw new MaterializedViewMayBeBeingRemovedException(e); - } - String viewOriginalText = table.getViewOriginalText(); if (viewOriginalText == null) { throw new TrinoException(ICEBERG_BAD_DATA, "Materialized view did not have original text " + viewName); } return getMaterializedViewDefinition( - icebergTable, Optional.ofNullable(table.getOwner()), viewOriginalText, storageTableName); } SchemaTableName storageTableName = new SchemaTableName(viewName.getSchemaName(), tableNameWithType(viewName.getTableName(), MATERIALIZED_VIEW_STORAGE)); - Table icebergTable; - try { - TableMetadata metadata = getMaterializedViewTableMetadata(session, storageTableName, storageMetadataLocation); - IcebergTableOperations operations = tableOperationsProvider.createTableOperations( - this, - session, - storageTableName.getSchemaName(), - storageTableName.getTableName(), - Optional.empty(), - Optional.empty()); - operations.initializeFromMetadata(metadata); - icebergTable = new BaseTable(operations, quotedTableName(storageTableName), TRINO_METRICS_REPORTER); - } - catch (RuntimeException e) { - // The materialized view could be removed concurrently. This may manifest in a number of ways, e.g. - // - org.apache.iceberg.exceptions.NotFoundException when accessing manifest file - // - other failures when reading storage table's metadata files - // Retry, as we're catching broadly. - throw new MaterializedViewMayBeBeingRemovedException(e); - } - return getMaterializedViewDefinition( - icebergTable, Optional.ofNullable(table.getOwner()), table.getViewOriginalText(), storageTableName); diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java index 6d0027e1c26d..c2de70ba78e1 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/hms/TrinoHiveCatalog.java @@ -568,6 +568,7 @@ public void createMaterializedView( ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, boolean replace, boolean ignoreExisting) { @@ -586,7 +587,7 @@ public void createMaterializedView( } if (hideMaterializedViewStorageTable) { - Location storageMetadataLocation = createMaterializedViewStorage(session, viewName, definition); + Location storageMetadataLocation = createMaterializedViewStorage(session, viewName, definition, materializedViewProperties); Map viewProperties = createMaterializedViewProperties(session, storageMetadataLocation); Column dummyColumn = new Column("dummy", HIVE_STRING, Optional.empty(), ImmutableMap.of()); @@ -614,7 +615,7 @@ public void createMaterializedView( } } else { - createMaterializedViewWithStorageTable(session, viewName, definition, existing); + createMaterializedViewWithStorageTable(session, viewName, definition, materializedViewProperties, existing); } } @@ -622,9 +623,10 @@ private void createMaterializedViewWithStorageTable( ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, Optional existing) { - SchemaTableName storageTable = createMaterializedViewStorageTable(session, viewName, definition); + SchemaTableName storageTable = createMaterializedViewStorageTable(session, viewName, definition, materializedViewProperties); // Create a view indicating the storage table Map viewProperties = createMaterializedViewProperties(session, storageTable); @@ -686,8 +688,7 @@ public void updateMaterializedViewColumnComment(ConnectorSession session, Schema definition.getGracePeriod(), definition.getComment(), definition.getOwner(), - definition.getPath(), - definition.getProperties()); + definition.getPath()); replaceMaterializedView(session, viewName, existing, newDefinition); } @@ -766,23 +767,7 @@ protected Optional doGetMaterializedView(Co String storageSchema = Optional.ofNullable(materializedView.getParameters().get(STORAGE_SCHEMA)) .orElse(viewName.getSchemaName()); SchemaTableName storageTableName = new SchemaTableName(storageSchema, storageTable); - - Table icebergTable; - try { - icebergTable = loadTable(session, storageTableName); - } - catch (RuntimeException e) { - // The materialized view could be removed concurrently. This may manifest in a number of ways, e.g. - // - io.trino.spi.connector.TableNotFoundException - // - org.apache.iceberg.exceptions.NotFoundException when accessing manifest file - // - other failures when reading storage table's metadata files - // Retry, as we're catching broadly. - metastore.invalidateTable(viewName.getSchemaName(), viewName.getTableName()); - metastore.invalidateTable(storageSchema, storageTable); - throw new MaterializedViewMayBeBeingRemovedException(e); - } return Optional.of(getMaterializedViewDefinition( - icebergTable, materializedView.getOwner(), materializedView.getViewOriginalText() .orElseThrow(() -> new TrinoException(HIVE_INVALID_METADATA, "No view original text: " + viewName)), @@ -790,33 +775,11 @@ protected Optional doGetMaterializedView(Co } SchemaTableName storageTableName = new SchemaTableName(viewName.getSchemaName(), IcebergTableName.tableNameWithType(viewName.getTableName(), MATERIALIZED_VIEW_STORAGE)); - IcebergTableOperations operations = tableOperationsProvider.createTableOperations( - this, - session, - storageTableName.getSchemaName(), - storageTableName.getTableName(), - Optional.empty(), - Optional.empty()); - try { - TableMetadata metadata = getMaterializedViewTableMetadata(session, storageTableName, materializedView); - operations.initializeFromMetadata(metadata); - Table icebergTable = new BaseTable(operations, quotedTableName(storageTableName), TRINO_METRICS_REPORTER); - - return Optional.of(getMaterializedViewDefinition( - icebergTable, - materializedView.getOwner(), - materializedView.getViewOriginalText() - .orElseThrow(() -> new TrinoException(HIVE_INVALID_METADATA, "No view original text: " + viewName)), - storageTableName)); - } - catch (RuntimeException e) { - // The materialized view could be removed concurrently. This may manifest in a number of ways, e.g. - // - org.apache.iceberg.exceptions.NotFoundException when accessing manifest file - // - other failures when reading storage table's metadata files - // Retry, as we're catching broadly. - metastore.invalidateTable(viewName.getSchemaName(), viewName.getTableName()); - throw new MaterializedViewMayBeBeingRemovedException(e); - } + return Optional.of(getMaterializedViewDefinition( + materializedView.getOwner(), + materializedView.getViewOriginalText() + .orElseThrow(() -> new TrinoException(HIVE_INVALID_METADATA, "No view original text: " + viewName)), + storageTableName)); } @Override diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/jdbc/TrinoJdbcCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/jdbc/TrinoJdbcCatalog.java index 86a8d3191e9a..1bde8682c864 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/jdbc/TrinoJdbcCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/jdbc/TrinoJdbcCatalog.java @@ -445,7 +445,13 @@ public Optional getMaterializedViewStorageTable(ConnectorSession sess } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName schemaViewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName schemaViewName, + ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, + boolean replace, + boolean ignoreExisting) { throw new TrinoException(NOT_SUPPORTED, "createMaterializedView is not supported for Iceberg JDBC catalogs"); } @@ -468,6 +474,12 @@ public Optional getMaterializedView(Connect return Optional.empty(); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + { + throw new TrinoException(NOT_SUPPORTED, "getMaterializedViewProperties is not supported for Iceberg JDBC catalogs"); + } + @Override public void renameMaterializedView(ConnectorSession session, SchemaTableName source, SchemaTableName target) { diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/nessie/TrinoNessieCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/nessie/TrinoNessieCatalog.java index 361c2cfd6986..1a8c3544920e 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/nessie/TrinoNessieCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/nessie/TrinoNessieCatalog.java @@ -405,6 +405,7 @@ public void createMaterializedView( ConnectorSession session, SchemaTableName schemaViewName, ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, boolean replace, boolean ignoreExisting) { @@ -429,6 +430,12 @@ public Optional getMaterializedView(Connect return Optional.empty(); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + { + throw new TrinoException(NOT_SUPPORTED, "The Iceberg Nessie catalog does not support materialized views"); + } + @Override public Optional getMaterializedViewStorageTable(ConnectorSession session, SchemaTableName viewName) { diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/rest/TrinoRestCatalog.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/rest/TrinoRestCatalog.java index 74d296d574ed..29f6ef8e2443 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/rest/TrinoRestCatalog.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/catalog/rest/TrinoRestCatalog.java @@ -438,7 +438,13 @@ public List listMaterializedViews(ConnectorSession session, Opt } @Override - public void createMaterializedView(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition, boolean replace, boolean ignoreExisting) + public void createMaterializedView( + ConnectorSession session, + SchemaTableName viewName, + ConnectorMaterializedViewDefinition definition, + Map materializedViewProperties, + boolean replace, + boolean ignoreExisting) { throw new TrinoException(NOT_SUPPORTED, "createMaterializedView is not supported for Iceberg REST catalog"); } @@ -461,6 +467,12 @@ public Optional getMaterializedView(Connect return Optional.empty(); } + @Override + public Map getMaterializedViewProperties(ConnectorSession session, SchemaTableName viewName, ConnectorMaterializedViewDefinition definition) + { + throw new TrinoException(NOT_SUPPORTED, "The Iceberg REST catalog does not support materialized views"); + } + @Override public Optional getMaterializedViewStorageTable(ConnectorSession session, SchemaTableName viewName) { diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergFileOperations.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergFileOperations.java index 9e1235f2a3d3..236ca6d515a0 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergFileOperations.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergFileOperations.java @@ -762,10 +762,10 @@ public void testSystemMetadataMaterializedViews() .build()); // Bulk retrieval without selecting freshness - assertFileSystemAccesses(session, "SELECT schema_name, name FROM system.metadata.materialized_views WHERE schema_name = CURRENT_SCHEMA", - ImmutableMultiset.builder() - .addCopies(new FileOperation(METADATA_JSON, INPUT_FILE_NEW_STREAM), 2) - .build()); + assertFileSystemAccesses( + session, + "SELECT schema_name, name FROM system.metadata.materialized_views WHERE schema_name = CURRENT_SCHEMA", + ImmutableMultiset.of()); // Bulk retrieval for two schemas assertFileSystemAccesses(session, "SELECT * FROM system.metadata.materialized_views WHERE schema_name IN (CURRENT_SCHEMA, 'non_existent')", @@ -780,10 +780,15 @@ public void testSystemMetadataMaterializedViews() .build()); // Pointed lookup without selecting freshness - assertFileSystemAccesses(session, "SELECT schema_name, name FROM system.metadata.materialized_views WHERE schema_name = CURRENT_SCHEMA AND name = 'mv1'", - ImmutableMultiset.builder() - .add(new FileOperation(METADATA_JSON, INPUT_FILE_NEW_STREAM)) - .build()); + assertFileSystemAccesses( + session, + "SELECT schema_name, name FROM system.metadata.materialized_views WHERE schema_name = CURRENT_SCHEMA AND name = 'mv1'", + ImmutableMultiset.of()); + + assertFileSystemAccesses( + session, + "SELECT * FROM iceberg.information_schema.columns WHERE table_schema = CURRENT_SCHEMA AND table_name = 'mv1'", + ImmutableMultiset.of()); assertUpdate("DROP SCHEMA " + schemaName + " CASCADE"); } diff --git a/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerBasic.java b/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerBasic.java index ae77214a462f..a583cfc40ec0 100644 --- a/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerBasic.java +++ b/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerBasic.java @@ -180,8 +180,7 @@ public Iterable getConnectorFactories() Optional.of(Duration.ZERO), Optional.empty(), Optional.of("alice"), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); SchemaTableName materializedViewName = new SchemaTableName("default", "test_materialized_view"); return ImmutableMap.of(materializedViewName, definition); }) diff --git a/testing/trino-tests/src/test/java/io/trino/execution/TestRefreshMaterializedView.java b/testing/trino-tests/src/test/java/io/trino/execution/TestRefreshMaterializedView.java index 423f58b13101..316f87b8b513 100644 --- a/testing/trino-tests/src/test/java/io/trino/execution/TestRefreshMaterializedView.java +++ b/testing/trino-tests/src/test/java/io/trino/execution/TestRefreshMaterializedView.java @@ -109,8 +109,7 @@ protected QueryRunner createQueryRunner() Optional.of(Duration.ZERO), Optional.empty(), Optional.of("alice"), - ImmutableList.of(), - ImmutableMap.of()))) + ImmutableList.of()))) .withDelegateMaterializedViewRefreshToConnector((connectorSession, schemaTableName) -> true) .withRefreshMaterializedView((connectorSession, schemaTableName) -> { startRefreshMaterializedView.set(null); diff --git a/testing/trino-tests/src/test/java/io/trino/security/TestAccessControl.java b/testing/trino-tests/src/test/java/io/trino/security/TestAccessControl.java index 8daed713e759..e86fe06d1d5d 100644 --- a/testing/trino-tests/src/test/java/io/trino/security/TestAccessControl.java +++ b/testing/trino-tests/src/test/java/io/trino/security/TestAccessControl.java @@ -214,8 +214,7 @@ public Map apply(Connector Optional.of(Duration.ZERO), Optional.of("comment"), Optional.of("owner"), - ImmutableList.of(), - ImmutableMap.of()); + ImmutableList.of()); return ImmutableMap.of( new SchemaTableName("default", "test_materialized_view"), materializedViewDefinition); } diff --git a/testing/trino-tests/src/test/java/io/trino/tests/TestMockConnector.java b/testing/trino-tests/src/test/java/io/trino/tests/TestMockConnector.java index 62e927c58b65..bc7f70069601 100644 --- a/testing/trino-tests/src/test/java/io/trino/tests/TestMockConnector.java +++ b/testing/trino-tests/src/test/java/io/trino/tests/TestMockConnector.java @@ -106,8 +106,7 @@ protected QueryRunner createQueryRunner() Optional.of(Duration.ZERO), Optional.empty(), Optional.of("alice"), - ImmutableList.of(), - ImmutableMap.of()))) + ImmutableList.of()))) .withData(schemaTableName -> { if (schemaTableName.equals(new SchemaTableName("default", "nation"))) { return TPCH_NATION_DATA;