diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/LegacyHiveViewReader.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/LegacyHiveViewReader.java index 622b1ff54fa8..578fb2072da9 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/LegacyHiveViewReader.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/LegacyHiveViewReader.java @@ -49,7 +49,7 @@ public ConnectorViewDefinition decodeViewData(String viewData, Table table, Cata .map(column -> new ConnectorViewDefinition.ViewColumn(column.getName(), TypeId.of(column.getType().getTypeSignature().toString()))) .collect(toImmutableList()), Optional.ofNullable(table.getParameters().get(TABLE_COMMENT)), - table.getOwner(), + Optional.empty(), // will be filled in later by HiveMetadata hiveViewsRunAsInvoker); } } diff --git a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/ViewReaderUtil.java b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/ViewReaderUtil.java index bd1a35a7a76b..0689c6c5440f 100644 --- a/plugin/trino-hive/src/main/java/io/trino/plugin/hive/ViewReaderUtil.java +++ b/plugin/trino-hive/src/main/java/io/trino/plugin/hive/ViewReaderUtil.java @@ -227,7 +227,7 @@ public ConnectorViewDefinition decodeViewData(String viewSql, Table table, Catal Optional.of(table.getDatabaseName()), columns, Optional.ofNullable(table.getParameters().get(TABLE_COMMENT)), - Optional.empty(), + Optional.empty(), // will be filled in later by HiveMetadata hiveViewsRunAsInvoker); } catch (RuntimeException e) { diff --git a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/common/Hadoop.java b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/common/Hadoop.java index 1ca470985ea8..77dbaf160124 100644 --- a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/common/Hadoop.java +++ b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/common/Hadoop.java @@ -40,6 +40,7 @@ public final class Hadoop public static final String CONTAINER_PRESTO_HIVE_PROPERTIES = CONTAINER_PRESTO_ETC + "/catalog/hive.properties"; public static final String CONTAINER_PRESTO_HIVE_WITH_EXTERNAL_WRITES_PROPERTIES = CONTAINER_PRESTO_ETC + "/catalog/hive_with_external_writes.properties"; public static final String CONTAINER_PRESTO_HIVE_TIMESTAMP_NANOS = CONTAINER_PRESTO_ETC + "/catalog/hive_timestamp_nanos.properties"; + public static final String CONTAINER_PRESTO_HIVE_RUN_VIEW_AS_INVOKER = CONTAINER_PRESTO_ETC + "/catalog/hive_with_run_view_as_invoker.properties"; public static final String CONTAINER_PRESTO_ICEBERG_PROPERTIES = CONTAINER_PRESTO_ETC + "/catalog/iceberg.properties"; private final DockerFiles dockerFiles; @@ -68,6 +69,7 @@ public void extendEnvironment(Environment.Builder builder) builder.addConnector("hive", forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive.properties")), CONTAINER_PRESTO_HIVE_PROPERTIES); builder.addConnector("hive", forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_with_external_writes.properties")), CONTAINER_PRESTO_HIVE_WITH_EXTERNAL_WRITES_PROPERTIES); builder.addConnector("hive", forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_timestamp_nanos.properties")), CONTAINER_PRESTO_HIVE_TIMESTAMP_NANOS); + builder.addConnector("hive", forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_with_run_view_as_invoker.properties")), CONTAINER_PRESTO_HIVE_RUN_VIEW_AS_INVOKER); builder.addConnector("iceberg", forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/iceberg.properties")), CONTAINER_PRESTO_ICEBERG_PROPERTIES); } diff --git a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinode.java b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinode.java index 452e1c8c8253..ddfb73e49f47 100644 --- a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinode.java +++ b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinode.java @@ -26,9 +26,11 @@ import static io.trino.tests.product.launcher.env.EnvironmentContainers.COORDINATOR; import static io.trino.tests.product.launcher.env.EnvironmentContainers.WORKER; import static io.trino.tests.product.launcher.env.common.Hadoop.CONTAINER_PRESTO_HIVE_PROPERTIES; +import static io.trino.tests.product.launcher.env.common.Hadoop.CONTAINER_PRESTO_HIVE_RUN_VIEW_AS_INVOKER; import static io.trino.tests.product.launcher.env.common.Hadoop.CONTAINER_PRESTO_HIVE_TIMESTAMP_NANOS; import static io.trino.tests.product.launcher.env.common.Hadoop.CONTAINER_PRESTO_HIVE_WITH_EXTERNAL_WRITES_PROPERTIES; import static io.trino.tests.product.launcher.env.common.Hadoop.CONTAINER_PRESTO_ICEBERG_PROPERTIES; +import static io.trino.tests.product.launcher.env.common.Standard.CONTAINER_PRESTO_ETC; import static io.trino.tests.product.launcher.env.common.Standard.CONTAINER_PRESTO_JVM_CONFIG; import static java.util.Objects.requireNonNull; import static org.testcontainers.utility.MountableFile.forHostPath; @@ -37,6 +39,8 @@ public final class EnvMultinode extends EnvironmentProvider { + public static final String CONTAINER_PRESTO_HIVE_ACCESS_CONTROL = CONTAINER_PRESTO_ETC + "/catalog/hive.properties"; + private final DockerFiles dockerFiles; private final DockerFiles.ResourceProvider configDir; @@ -59,6 +63,7 @@ public void extendEnvironment(Environment.Builder builder) .withCopyFileToContainer(forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive.properties")), CONTAINER_PRESTO_HIVE_PROPERTIES) .withCopyFileToContainer(forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_with_external_writes.properties")), CONTAINER_PRESTO_HIVE_WITH_EXTERNAL_WRITES_PROPERTIES) .withCopyFileToContainer(forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_timestamp_nanos.properties")), CONTAINER_PRESTO_HIVE_TIMESTAMP_NANOS) + .withCopyFileToContainer(forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/hive_with_run_view_as_invoker.properties")), CONTAINER_PRESTO_HIVE_RUN_VIEW_AS_INVOKER) .withCopyFileToContainer(forHostPath(dockerFiles.getDockerFilesHostPath("common/hadoop/iceberg.properties")), CONTAINER_PRESTO_ICEBERG_PROPERTIES)); } } diff --git a/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/common/hadoop/hive_with_run_view_as_invoker.properties b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/common/hadoop/hive_with_run_view_as_invoker.properties new file mode 100644 index 000000000000..440d35a7b07e --- /dev/null +++ b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/common/hadoop/hive_with_run_view_as_invoker.properties @@ -0,0 +1,8 @@ +connector.name=hive +hive.metastore.uri=thrift://hadoop-master:9083 +hive.config.resources=/docker/presto-product-tests/conf/presto/etc/hive-default-fs-site.xml +hive.metastore-cache-ttl=0s +hive.fs.cache.max-size=10 +hive.hive-views.enabled=true +hive.hive-views.run-as-invoker=true +hive.security=sql-standard diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/AbstractTestHiveViews.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/AbstractTestHiveViews.java index 41678914aa1c..391a814e36f7 100644 --- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/AbstractTestHiveViews.java +++ b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/AbstractTestHiveViews.java @@ -688,6 +688,26 @@ public void testViewWithColumnAliasesDifferingInCase() onHive().executeQuery("DROP VIEW test_namesake_column_names_view"); } + @Test(groups = HIVE_VIEWS) + public void testRunAsInvoker() + { + onTrino().executeQuery("DROP TABLE IF EXISTS run_as_invoker"); + onTrino().executeQuery("DROP VIEW IF EXISTS run_as_invoker_view"); + + onTrino().executeQuery("CREATE TABLE run_as_invoker (a INTEGER)"); + onHive().executeQuery("CREATE VIEW run_as_invoker_view AS SELECT * FROM run_as_invoker"); + onTrino().executeQuery("GRANT SELECT ON hive_with_run_view_as_invoker.default.run_as_invoker_view TO hive"); + + String definerQuery = "SELECT * FROM hive.default.run_as_invoker_view"; + String invokerQuery = "SELECT * FROM hive_with_run_view_as_invoker.default.run_as_invoker_view"; + assertThat(connectToTrino("alice@presto").executeQuery(definerQuery)).hasNoRows(); // Allowed + assertThatThrownBy(() -> connectToTrino("alice@presto").executeQuery(invokerQuery)) + .hasMessageContaining("Access Denied"); + + onHive().executeQuery("DROP VIEW run_as_invoker_view"); + onTrino().executeQuery("DROP TABLE run_as_invoker"); + } + protected static void assertViewQuery(String query, Consumer assertion) { // Ensure Hive and Presto view compatibility by comparing the results