From c4e578755068a436ec1aef0c910a89578bf0b877 Mon Sep 17 00:00:00 2001 From: Dejan Gvozdenac Date: Wed, 9 Oct 2024 15:19:32 -0400 Subject: [PATCH] implement run-views-as-invoker --- .../src/main/java/io/trino/FeaturesConfig.java | 14 ++++++++++++++ .../java/io/trino/SystemSessionProperties.java | 13 ++++++++++++- .../java/io/trino/metadata/MetadataManager.java | 8 +++++++- .../trino/sql/analyzer/TestFeaturesConfig.java | 7 +++++-- .../spi/connector/ConnectorViewDefinition.java | 13 +++++++++++++ .../connector/TestConnectorViewDefinition.java | 17 +++++++++++++++++ 6 files changed, 68 insertions(+), 4 deletions(-) diff --git a/core/trino-main/src/main/java/io/trino/FeaturesConfig.java b/core/trino-main/src/main/java/io/trino/FeaturesConfig.java index 707b3300e8ca..8c4b8994d438 100644 --- a/core/trino-main/src/main/java/io/trino/FeaturesConfig.java +++ b/core/trino-main/src/main/java/io/trino/FeaturesConfig.java @@ -122,6 +122,8 @@ public class FeaturesConfig private boolean faultTolerantExecutionExchangeEncryptionEnabled = true; + private boolean runViewsAsInvokerEnabled; + public enum DataIntegrityVerification { NONE, @@ -518,4 +520,16 @@ public void applyFaultTolerantExecutionDefaults() { exchangeCompressionCodec = LZ4; } + + public boolean isRunViewsAsInvokerEnabled() + { + return runViewsAsInvokerEnabled; + } + + @Config("run-views-as-invoker") + public FeaturesConfig setRunViewsAsInvokerEnabled(boolean runViewsAsInvokerEnabled) + { + this.runViewsAsInvokerEnabled = runViewsAsInvokerEnabled; + return this; + } } diff --git a/core/trino-main/src/main/java/io/trino/SystemSessionProperties.java b/core/trino-main/src/main/java/io/trino/SystemSessionProperties.java index 59be671b8ce1..05d165ba59a5 100644 --- a/core/trino-main/src/main/java/io/trino/SystemSessionProperties.java +++ b/core/trino-main/src/main/java/io/trino/SystemSessionProperties.java @@ -219,6 +219,7 @@ public final class SystemSessionProperties public static final String IDLE_WRITER_MIN_DATA_SIZE_THRESHOLD = "idle_writer_min_data_size_threshold"; public static final String CLOSE_IDLE_WRITERS_TRIGGER_DURATION = "close_idle_writers_trigger_duration"; public static final String COLUMNAR_FILTER_EVALUATION_ENABLED = "columnar_filter_evaluation_enabled"; + public static final String RUN_VIEWS_AS_INVOKER_ENABLED = "run-views-as-invoker"; private final List> sessionProperties; @@ -1128,7 +1129,12 @@ public SystemSessionProperties( ALLOW_UNSAFE_PUSHDOWN, "Allow pushing down expressions that may fail for some inputs", optimizerConfig.isUnsafePushdownAllowed(), - true)); + true), + booleanProperty( + RUN_VIEWS_AS_INVOKER_ENABLED, + "Execute all views with permissions of the invoker", + featuresConfig.isRunViewsAsInvokerEnabled(), + false)); } @Override @@ -2022,4 +2028,9 @@ public static boolean isUnsafePushdownAllowed(Session session) { return session.getSystemProperty(ALLOW_UNSAFE_PUSHDOWN, Boolean.class); } + + public static boolean isRunViewsAsInvokerEnabled(Session session) + { + return session.getSystemProperty(RUN_VIEWS_AS_INVOKER_ENABLED, Boolean.class); + } } 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 ff6d7d0e640b..8b3a4f9d1c03 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 @@ -149,6 +149,7 @@ import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static io.airlift.concurrent.MoreFutures.toListenableFuture; import static io.trino.SystemSessionProperties.getRetryPolicy; +import static io.trino.SystemSessionProperties.isRunViewsAsInvokerEnabled; import static io.trino.metadata.CatalogMetadata.SecurityManagement.CONNECTOR; import static io.trino.metadata.CatalogMetadata.SecurityManagement.SYSTEM; import static io.trino.metadata.GlobalFunctionCatalog.BUILTIN_SCHEMA; @@ -1592,7 +1593,12 @@ private Optional getViewInternal(Session session, Quali ConnectorMetadata metadata = catalogMetadata.getMetadataFor(session, catalogHandle); ConnectorSession connectorSession = session.toConnectorSession(catalogHandle); - return metadata.getView(connectorSession, viewName.asSchemaTableName()); + if (isRunViewsAsInvokerEnabled(session)) { + return metadata.getView(connectorSession, viewName.asSchemaTableName()).map(view -> view.withRunAsInvoker()); + } + else { + return metadata.getView(connectorSession, viewName.asSchemaTableName()); + } } return Optional.empty(); } diff --git a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java index ca8b7134d1cb..c7213a21037a 100644 --- a/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java +++ b/core/trino-main/src/test/java/io/trino/sql/analyzer/TestFeaturesConfig.java @@ -66,7 +66,8 @@ public void testDefaults() .setHideInaccessibleColumns(false) .setForceSpillingJoin(false) .setColumnarFilterEvaluationEnabled(true) - .setFaultTolerantExecutionExchangeEncryptionEnabled(true)); + .setFaultTolerantExecutionExchangeEncryptionEnabled(true) + .setRunViewsAsInvokerEnabled(false)); } @Test @@ -101,6 +102,7 @@ public void testExplicitPropertyMappings() .put("force-spilling-join-operator", "true") .put("experimental.columnar-filter-evaluation.enabled", "false") .put("fault-tolerant-execution-exchange-encryption-enabled", "false") + .put("run-views-as-invoker", "true") .buildOrThrow(); FeaturesConfig expected = new FeaturesConfig() @@ -131,7 +133,8 @@ public void testExplicitPropertyMappings() .setHideInaccessibleColumns(true) .setForceSpillingJoin(true) .setColumnarFilterEvaluationEnabled(false) - .setFaultTolerantExecutionExchangeEncryptionEnabled(false); + .setFaultTolerantExecutionExchangeEncryptionEnabled(false) + .setRunViewsAsInvokerEnabled(true); assertFullMapping(properties, expected); } } diff --git a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorViewDefinition.java b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorViewDefinition.java index 401993aec056..0ec7fc989309 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorViewDefinition.java +++ b/core/trino-spi/src/main/java/io/trino/spi/connector/ConnectorViewDefinition.java @@ -126,6 +126,19 @@ public ConnectorViewDefinition withoutOwner() path); } + public ConnectorViewDefinition withRunAsInvoker() + { + return new ConnectorViewDefinition( + originalSql, + catalog, + schema, + columns, + comment, + Optional.empty(), + true, + path); + } + @Override public String toString() { diff --git a/core/trino-spi/src/test/java/io/trino/spi/connector/TestConnectorViewDefinition.java b/core/trino-spi/src/test/java/io/trino/spi/connector/TestConnectorViewDefinition.java index 2f336a558949..305bf78b443b 100644 --- a/core/trino-spi/src/test/java/io/trino/spi/connector/TestConnectorViewDefinition.java +++ b/core/trino-spi/src/test/java/io/trino/spi/connector/TestConnectorViewDefinition.java @@ -67,6 +67,23 @@ public void testViewWithOwner() assertThat(view.isRunAsInvoker()).isFalse(); } + @Test + public void testViewWithRunAsInvoker() + { + ConnectorViewDefinition viewWithRunAsInvoker; + ConnectorViewDefinition definerView = CODEC.fromJson("{" + BASE_JSON + ", \"owner\": \"abc\", \"runAsInvoker\": false}"); + viewWithRunAsInvoker = definerView.withRunAsInvoker(); + assertBaseView(viewWithRunAsInvoker); + assertThat(viewWithRunAsInvoker.getOwner().isPresent()).isFalse(); + assertThat(viewWithRunAsInvoker.isRunAsInvoker()).isTrue(); + + ConnectorViewDefinition invokerView = CODEC.fromJson("{" + BASE_JSON + ", \"runAsInvoker\": true}"); + viewWithRunAsInvoker = invokerView.withRunAsInvoker(); + assertBaseView(viewWithRunAsInvoker); + assertThat(viewWithRunAsInvoker.getOwner().isPresent()).isFalse(); + assertThat(viewWithRunAsInvoker.isRunAsInvoker()).isTrue(); + } + @Test public void testViewComment() {