diff --git a/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java b/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java index cf734b1c36f6..874f10fc09b2 100644 --- a/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java +++ b/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java @@ -2798,15 +2798,17 @@ protected Scope visitMerge(Merge merge, Optional scope) { Relation relation = merge.getTarget(); Table table = getMergeTargetTable(relation); - QualifiedObjectName tableName = createQualifiedObjectName(session, table, table.getName()); - if (metadata.isMaterializedView(session, tableName)) { + QualifiedObjectName originalTableName = createQualifiedObjectName(session, table, table.getName()); + if (metadata.isMaterializedView(session, originalTableName)) { throw semanticException(NOT_SUPPORTED, merge, "Merging into materialized views is not supported"); } - if (metadata.getView(session, tableName).isPresent()) { + if (metadata.isView(session, originalTableName)) { throw semanticException(NOT_SUPPORTED, merge, "Merging into views is not supported"); } - TableHandle targetTableHandle = metadata.getTableHandle(session, tableName) + RedirectionAwareTableHandle redirection = metadata.getRedirectionAwareTableHandle(session, originalTableName); + QualifiedObjectName tableName = redirection.getRedirectedTableName().orElse(originalTableName); + TableHandle targetTableHandle = redirection.getTableHandle() .orElseThrow(() -> semanticException(TABLE_NOT_FOUND, table, "Table '%s' does not exist", tableName)); StatementAnalyzer analyzer = statementAnalyzerFactory diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestHiveRedirectionToIceberg.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestHiveRedirectionToIceberg.java index d06d57bd1da1..ec91faaee67d 100644 --- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestHiveRedirectionToIceberg.java +++ b/testing/trino-product-tests/src/main/java/io/trino/tests/product/hive/TestHiveRedirectionToIceberg.java @@ -224,6 +224,33 @@ public void testUpdate() onTrino().executeQuery("DROP TABLE " + icebergTableName); } + @Test(groups = {HIVE_ICEBERG_REDIRECTIONS, PROFILE_SPECIFIC_TESTS}) + public void testMerge() + { + String sourceTableName = "iceberg_merge_source_" + randomTableSuffix(); + String targetTableName = "iceberg_merge_target_" + randomTableSuffix(); + String hiveSourceTableName = "hive.default." + sourceTableName; + String hiveTargetTableName = "hive.default." + targetTableName; + String icebergSourceTableName = "iceberg.default." + sourceTableName; + String icebergTargetTableName = "iceberg.default." + targetTableName; + + createIcebergTable(icebergSourceTableName, true, true); + createIcebergTable(icebergTargetTableName, true, false); + + assertThat(onTrino().executeQuery("" + + "MERGE INTO " + hiveTargetTableName + " t USING " + hiveSourceTableName + " s ON t.nationkey = s.nationkey " + + "WHEN NOT MATCHED " + + " THEN INSERT (nationkey, name, regionkey, comment) " + + " VALUES (s.nationkey, s.name, s.regionkey, s.comment)")) + .updatedRowsCountIsEqualTo(25); + assertResultsEqual( + onTrino().executeQuery("TABLE " + icebergSourceTableName), + onTrino().executeQuery("TABLE " + icebergTargetTableName)); + + onTrino().executeQuery("DROP TABLE " + icebergSourceTableName); + onTrino().executeQuery("DROP TABLE " + icebergTargetTableName); + } + @Test(groups = {HIVE_ICEBERG_REDIRECTIONS, PROFILE_SPECIFIC_TESTS}) public void testDropTable() {