diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/TestHiveIntegrationSmokeTest.java b/presto-hive/src/test/java/com/facebook/presto/hive/TestHiveIntegrationSmokeTest.java index 25234d867f0d4..998117af2222a 100644 --- a/presto-hive/src/test/java/com/facebook/presto/hive/TestHiveIntegrationSmokeTest.java +++ b/presto-hive/src/test/java/com/facebook/presto/hive/TestHiveIntegrationSmokeTest.java @@ -5350,9 +5350,28 @@ public void testCreateMaterializedView() @Test public void testShowCreateOnMaterializedView() { + String createMaterializedViewSql = formatSqlText(format("CREATE MATERIALIZED VIEW %s.%s.test_customer_mv_1\n" + + "WITH (\n" + + " format = 'ORC'," + + " partitioned_by = ARRAY['nationkey']\n" + + retentionDays(15) + + ") AS SELECT\n" + + " name\n" + + ", nationkey\n" + + "FROM\n" + + " test_customer_base_1", + getSession().getCatalog().get(), + getSession().getSchema().get())); + computeActual("CREATE TABLE test_customer_base_1 WITH (partitioned_by = ARRAY['nationkey']) AS SELECT custkey, name, address, nationkey FROM customer LIMIT 10"); - computeActual("CREATE MATERIALIZED VIEW test_customer_mv_1 WITH (partitioned_by = ARRAY['nationkey']" + retentionDays(30) + ") AS SELECT name, nationkey FROM test_customer_base_1"); + computeActual(createMaterializedViewSql); + MaterializedResult actualResult = computeActual("SHOW CREATE MATERIALIZED VIEW test_customer_mv_1"); + assertEquals(getOnlyElement(actualResult.getOnlyColumnAsSet()), createMaterializedViewSql.trim()); + + assertQueryFails( + "SHOW CREATE MATERIALIZED VIEW test_customer_base_1", + format(".*Relation '%s.%s.test_customer_base_1' is a table, not a materialized view", getSession().getCatalog().get(), getSession().getSchema().get())); assertQueryFails( "SHOW CREATE VIEW test_customer_mv_1", format(".*Relation '%s.%s.test_customer_mv_1' is a materialized view, not a view", getSession().getCatalog().get(), getSession().getSchema().get())); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java index 709d85f068c9b..9418b8b642320 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java @@ -46,6 +46,7 @@ import com.facebook.presto.sql.tree.BooleanLiteral; import com.facebook.presto.sql.tree.ColumnDefinition; import com.facebook.presto.sql.tree.CreateFunction; +import com.facebook.presto.sql.tree.CreateMaterializedView; import com.facebook.presto.sql.tree.CreateTable; import com.facebook.presto.sql.tree.CreateView; import com.facebook.presto.sql.tree.DoubleLiteral; @@ -140,6 +141,7 @@ import static com.facebook.presto.sql.tree.RoutineCharacteristics.Determinism; import static com.facebook.presto.sql.tree.RoutineCharacteristics.Language; import static com.facebook.presto.sql.tree.RoutineCharacteristics.NullCallClause; +import static com.facebook.presto.sql.tree.ShowCreate.Type.MATERIALIZED_VIEW; import static com.facebook.presto.sql.tree.ShowCreate.Type.TABLE; import static com.facebook.presto.sql.tree.ShowCreate.Type.VIEW; import static com.google.common.base.Strings.nullToEmpty; @@ -460,6 +462,36 @@ protected Node visitShowCreate(ShowCreate node, Void context) return singleValueQuery("Create View", sql); } + if (node.getType() == MATERIALIZED_VIEW) { + Optional tableHandle = metadata.getTableHandle(session, objectName); + + if (!materializedViewDefinition.isPresent()) { + if (viewDefinition.isPresent()) { + throw new SemanticException(NOT_SUPPORTED, node, "Relation '%s' is a view, not a materialized view", objectName); + } + if (tableHandle.isPresent()) { + throw new SemanticException(NOT_SUPPORTED, node, "Relation '%s' is a table, not a materialized view", objectName); + } + throw new SemanticException(MISSING_TABLE, node, "Materialized view '%s' does not exist", objectName); + } + + Query query = parseView(materializedViewDefinition.get().getOriginalSql(), objectName, node); + + ConnectorTableMetadata connectorTableMetadata = metadata.getTableMetadata(session, tableHandle.get()).getMetadata(); + Map properties = connectorTableMetadata.getProperties(); + Map> allTableProperties = metadata.getTablePropertyManager().getAllProperties().get(tableHandle.get().getConnectorId()); + List propertyNodes = buildProperties(objectName, Optional.empty(), INVALID_TABLE_PROPERTY, properties, allTableProperties); + + CreateMaterializedView createMaterializedView = new CreateMaterializedView( + Optional.empty(), + createQualifiedName(objectName), + query, + false, + propertyNodes, + connectorTableMetadata.getComment()); + return singleValueQuery("Create Materialized View", formatSql(createMaterializedView, Optional.of(parameters)).trim()); + } + if (node.getType() == TABLE) { if (viewDefinition.isPresent()) { throw new SemanticException(NOT_SUPPORTED, node, "Relation '%s' is a view, not a table", objectName); diff --git a/presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 b/presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 index 82d74c9d53147..d642a7f901ffd 100644 --- a/presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 +++ b/presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 @@ -102,6 +102,7 @@ statement ('(' explainOption (',' explainOption)* ')')? statement #explain | SHOW CREATE TABLE qualifiedName #showCreateTable | SHOW CREATE VIEW qualifiedName #showCreateView + | SHOW CREATE MATERIALIZED VIEW qualifiedName #showCreateMaterializedView | SHOW CREATE FUNCTION qualifiedName types? #showCreateFunction | SHOW TABLES ((FROM | IN) qualifiedName)? (LIKE pattern=string (ESCAPE escape=string)?)? #showTables diff --git a/presto-parser/src/main/java/com/facebook/presto/sql/SqlFormatter.java b/presto-parser/src/main/java/com/facebook/presto/sql/SqlFormatter.java index 8f15bc51ff033..6ededfc66b726 100644 --- a/presto-parser/src/main/java/com/facebook/presto/sql/SqlFormatter.java +++ b/presto-parser/src/main/java/com/facebook/presto/sql/SqlFormatter.java @@ -781,6 +781,10 @@ else if (node.getType() == ShowCreate.Type.VIEW) { builder.append("SHOW CREATE VIEW ") .append(formatName(node.getName())); } + else if (node.getType() == ShowCreate.Type.MATERIALIZED_VIEW) { + builder.append("SHOW CREATE MATERIALIZED VIEW ") + .append(formatName(node.getName())); + } return null; } diff --git a/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java b/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java index 9919ab5f6ee50..08a79b162e8a9 100644 --- a/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java +++ b/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java @@ -944,6 +944,12 @@ public Node visitShowCreateView(SqlBaseParser.ShowCreateViewContext context) return new ShowCreate(getLocation(context), ShowCreate.Type.VIEW, getQualifiedName(context.qualifiedName())); } + @Override + public Node visitShowCreateMaterializedView(SqlBaseParser.ShowCreateMaterializedViewContext context) + { + return new ShowCreate(getLocation(context), ShowCreate.Type.MATERIALIZED_VIEW, getQualifiedName(context.qualifiedName())); + } + @Override public Node visitShowFunctions(SqlBaseParser.ShowFunctionsContext context) { diff --git a/presto-parser/src/main/java/com/facebook/presto/sql/tree/ShowCreate.java b/presto-parser/src/main/java/com/facebook/presto/sql/tree/ShowCreate.java index ba5863bb85df9..ef6501450d5ad 100644 --- a/presto-parser/src/main/java/com/facebook/presto/sql/tree/ShowCreate.java +++ b/presto-parser/src/main/java/com/facebook/presto/sql/tree/ShowCreate.java @@ -28,7 +28,8 @@ public class ShowCreate public enum Type { TABLE, - VIEW + VIEW, + MATERIALIZED_VIEW } private final Type type;