From b438df6ecb7e977aefc4017d3c86d0d136eec277 Mon Sep 17 00:00:00 2001 From: Dain Sundstrom Date: Wed, 2 Sep 2015 22:47:54 -0700 Subject: [PATCH] Add owner to view definition --- .../facebook/presto/hive/HiveMetadata.java | 12 ++-- .../presto/hive/AbstractTestHiveClient.java | 5 +- .../presto/execution/CreateViewTask.java | 2 +- .../presto/metadata/MetadataManager.java | 19 ++++--- .../presto/metadata/ViewDefinition.java | 13 ++++- .../presto/metadata/TestingMetadata.java | 8 ++- .../presto/sql/analyzer/TestAnalyzer.java | 9 +-- .../presto/raptor/RaptorMetadata.java | 7 ++- .../raptor/metadata/TestRaptorMetadata.java | 9 +-- .../presto/spi/ConnectorMetadata.java | 2 +- .../presto/spi/ConnectorViewDefinition.java | 57 +++++++++++++++++++ .../ClassLoaderSafeConnectorMetadata.java | 3 +- 12 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 presto-spi/src/main/java/com/facebook/presto/spi/ConnectorViewDefinition.java diff --git a/presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java b/presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java index 7be3e41c21e0..f0afd07349c2 100644 --- a/presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java +++ b/presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java @@ -25,6 +25,7 @@ import com.facebook.presto.spi.ConnectorTableLayoutHandle; import com.facebook.presto.spi.ConnectorTableLayoutResult; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.Constraint; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.SchemaNotFoundException; @@ -693,7 +694,7 @@ public void createView(ConnectorSession session, SchemaTableName viewName, Strin @Override public void dropView(ConnectorSession session, SchemaTableName viewName) { - String view = getViews(session, viewName.toSchemaTablePrefix()).get(viewName); + ConnectorViewDefinition view = getViews(session, viewName.toSchemaTablePrefix()).get(viewName); if (view == null) { throw new ViewNotFoundException(viewName); } @@ -719,9 +720,9 @@ public List listViews(ConnectorSession session, String schemaNa } @Override - public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) + public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) { - ImmutableMap.Builder views = ImmutableMap.builder(); + ImmutableMap.Builder views = ImmutableMap.builder(); List tableNames; if (prefix.getTableName() != null) { tableNames = ImmutableList.of(new SchemaTableName(prefix.getSchemaName(), prefix.getTableName())); @@ -733,7 +734,10 @@ public Map getViews(ConnectorSession session, SchemaTab for (SchemaTableName schemaTableName : tableNames) { Optional table = metastore.getTable(schemaTableName.getSchemaName(), schemaTableName.getTableName()); if (table.isPresent() && HiveUtil.isPrestoView(table.get())) { - views.put(schemaTableName, decodeViewData(table.get().getViewOriginalText())); + views.put(schemaTableName, new ConnectorViewDefinition( + schemaTableName, + Optional.ofNullable(table.get().getOwner()), + decodeViewData(table.get().getViewOriginalText()))); } } diff --git a/presto-hive/src/test/java/com/facebook/presto/hive/AbstractTestHiveClient.java b/presto-hive/src/test/java/com/facebook/presto/hive/AbstractTestHiveClient.java index e64a21504de5..63fc938b5b53 100644 --- a/presto-hive/src/test/java/com/facebook/presto/hive/AbstractTestHiveClient.java +++ b/presto-hive/src/test/java/com/facebook/presto/hive/AbstractTestHiveClient.java @@ -36,6 +36,7 @@ import com.facebook.presto.spi.ConnectorTableLayoutHandle; import com.facebook.presto.spi.ConnectorTableLayoutResult; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.Constraint; import com.facebook.presto.spi.Domain; import com.facebook.presto.spi.PrestoException; @@ -1296,9 +1297,9 @@ private void doCreateView(SchemaTableName viewName, boolean replace) metadata.createView(SESSION, viewName, viewData, replace); - Map views = metadata.getViews(SESSION, viewName.toSchemaTablePrefix()); + Map views = metadata.getViews(SESSION, viewName.toSchemaTablePrefix()); assertEquals(views.size(), 1); - assertEquals(views.get(viewName), viewData); + assertEquals(views.get(viewName).getViewData(), viewData); assertTrue(metadata.listViews(SESSION, viewName.getSchemaName()).contains(viewName)); } diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java index 520c8314ed75..094a42ecdacf 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java @@ -92,7 +92,7 @@ public void execute(CreateView statement, Session session, Metadata metadata, Ac .map(field -> new ViewColumn(field.getName().get(), field.getType())) .collect(toImmutableList()); - String data = codec.toJson(new ViewDefinition(sql, session.getCatalog(), session.getSchema(), columns)); + String data = codec.toJson(new ViewDefinition(sql, session.getCatalog(), session.getSchema(), columns, Optional.of(session.getUser()))); metadata.createView(session, name, data, statement.isReplace()); } diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/MetadataManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/MetadataManager.java index 6fe5d9031d10..fd021d65c034 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/MetadataManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/MetadataManager.java @@ -29,6 +29,7 @@ import com.facebook.presto.spi.ConnectorTableLayout; import com.facebook.presto.spi.ConnectorTableLayoutResult; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.Constraint; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.SchemaTableName; @@ -455,14 +456,14 @@ public Map> listTableColumns(Session se } // if table and view names overlap, the view wins - for (Entry entry : metadata.getViews(connectorSession, tablePrefix).entrySet()) { + for (Entry entry : metadata.getViews(connectorSession, tablePrefix).entrySet()) { QualifiedTableName tableName = new QualifiedTableName( prefix.getCatalogName(), entry.getKey().getSchemaName(), entry.getKey().getTableName()); ImmutableList.Builder columns = ImmutableList.builder(); - for (ViewColumn column : deserializeView(entry.getValue()).getColumns()) { + for (ViewColumn column : deserializeView(entry.getValue().getViewData()).getColumns()) { columns.add(new ColumnMetadata(column.getName(), column.getType(), false)); } @@ -621,12 +622,12 @@ public Map getViews(Session session, Qualifi Map views = new LinkedHashMap<>(); for (ConnectorMetadataEntry metadata : allConnectorsFor(prefix.getCatalogName())) { ConnectorSession connectorSession = session.toConnectorSession(metadata.getCatalog()); - for (Entry entry : metadata.getMetadata().getViews(connectorSession, tablePrefix).entrySet()) { + for (Entry entry : metadata.getMetadata().getViews(connectorSession, tablePrefix).entrySet()) { QualifiedTableName viewName = new QualifiedTableName( prefix.getCatalogName(), entry.getKey().getSchemaName(), entry.getKey().getTableName()); - views.put(viewName, deserializeView(entry.getValue())); + views.put(viewName, deserializeView(entry.getValue().getViewData())); } } return ImmutableMap.copyOf(views); @@ -637,11 +638,13 @@ public Optional getView(Session session, QualifiedTableName view { ConnectorMetadataEntry entry = getConnectorFor(viewName); if (entry != null) { - SchemaTablePrefix prefix = viewName.asSchemaTableName().toSchemaTablePrefix(); - Map views = entry.getMetadata().getViews(session.toConnectorSession(entry.getCatalog()), prefix); - String view = views.get(viewName.asSchemaTableName()); + ConnectorMetadata metadata = entry.getMetadata(); + Map views = metadata.getViews( + session.toConnectorSession(entry.getCatalog()), + viewName.asSchemaTableName().toSchemaTablePrefix()); + ConnectorViewDefinition view = views.get(viewName.asSchemaTableName()); if (view != null) { - return Optional.of(deserializeView(view)); + return Optional.of(deserializeView(view.getViewData())); } } return Optional.empty(); diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/ViewDefinition.java b/presto-main/src/main/java/com/facebook/presto/metadata/ViewDefinition.java index 29cfa5a89365..bb477d6fc476 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/ViewDefinition.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/ViewDefinition.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; +import java.util.Optional; import static com.google.common.base.MoreObjects.toStringHelper; import static java.util.Objects.requireNonNull; @@ -29,18 +30,21 @@ public final class ViewDefinition private final String catalog; private final String schema; private final List columns; + private final Optional owner; @JsonCreator public ViewDefinition( @JsonProperty("originalSql") String originalSql, @JsonProperty("catalog") String catalog, @JsonProperty("schema") String schema, - @JsonProperty("columns") List columns) + @JsonProperty("columns") List columns, + @JsonProperty("owner") Optional owner) { this.originalSql = requireNonNull(originalSql, "originalSql is null"); this.catalog = requireNonNull(catalog, "catalog is null"); this.schema = requireNonNull(schema, "schema is null"); this.columns = ImmutableList.copyOf(requireNonNull(columns, "columns is null")); + this.owner = requireNonNull(owner, "owner is null"); } @JsonProperty @@ -67,6 +71,12 @@ public List getColumns() return columns; } + @JsonProperty + public Optional getOwner() + { + return owner; + } + @Override public String toString() { @@ -75,6 +85,7 @@ public String toString() .add("catalog", catalog) .add("schema", schema) .add("columns", columns) + .add("owner", owner) .toString(); } diff --git a/presto-main/src/test/java/com/facebook/presto/metadata/TestingMetadata.java b/presto-main/src/test/java/com/facebook/presto/metadata/TestingMetadata.java index f2c448fe53f8..32cb0cf9c014 100644 --- a/presto-main/src/test/java/com/facebook/presto/metadata/TestingMetadata.java +++ b/presto-main/src/test/java/com/facebook/presto/metadata/TestingMetadata.java @@ -19,6 +19,7 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.ConnectorTableHandle; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.SchemaTableName; import com.facebook.presto.spi.SchemaTablePrefix; @@ -30,6 +31,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -181,12 +183,12 @@ public List listViews(ConnectorSession session, String schemaNa } @Override - public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) + public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) { - ImmutableMap.Builder map = ImmutableMap.builder(); + ImmutableMap.Builder map = ImmutableMap.builder(); for (Map.Entry entry : views.entrySet()) { if (prefix.matches(entry.getKey())) { - map.put(entry); + map.put(entry.getKey(), new ConnectorViewDefinition(entry.getKey(), Optional.empty(), entry.getValue())); } } return map.build(); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java index 7c54941e0031..ff02bd537acb 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java @@ -840,20 +840,17 @@ public void setup() // valid view referencing table in same schema String viewData1 = JsonCodec.jsonCodec(ViewDefinition.class).toJson( - new ViewDefinition("select a from t1", "tpch", "default", ImmutableList.of( - new ViewColumn("a", BIGINT)))); + new ViewDefinition("select a from t1", "tpch", "default", ImmutableList.of(new ViewColumn("a", BIGINT)), Optional.of("user"))); metadata.createView(SESSION, new QualifiedTableName("tpch", "default", "v1"), viewData1, false); // stale view (different column type) String viewData2 = JsonCodec.jsonCodec(ViewDefinition.class).toJson( - new ViewDefinition("select a from t1", "tpch", "default", ImmutableList.of( - new ViewColumn("a", VARCHAR)))); + new ViewDefinition("select a from t1", "tpch", "default", ImmutableList.of(new ViewColumn("a", VARCHAR)), Optional.of("user"))); metadata.createView(SESSION, new QualifiedTableName("tpch", "default", "v2"), viewData2, false); // view referencing table in different schema from itself and session String viewData3 = JsonCodec.jsonCodec(ViewDefinition.class).toJson( - new ViewDefinition("select a from t4", "c2", "s2", ImmutableList.of( - new ViewColumn("a", BIGINT)))); + new ViewDefinition("select a from t4", "c2", "s2", ImmutableList.of(new ViewColumn("a", BIGINT)), Optional.of("user"))); metadata.createView(SESSION, new QualifiedTableName("c3", "s3", "v3"), viewData3, false); analyzer = new Analyzer( diff --git a/presto-raptor/src/main/java/com/facebook/presto/raptor/RaptorMetadata.java b/presto-raptor/src/main/java/com/facebook/presto/raptor/RaptorMetadata.java index cb5ec4821c7c..a4813e9f8040 100644 --- a/presto-raptor/src/main/java/com/facebook/presto/raptor/RaptorMetadata.java +++ b/presto-raptor/src/main/java/com/facebook/presto/raptor/RaptorMetadata.java @@ -31,6 +31,7 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.ConnectorTableHandle; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.SchemaTableName; import com.facebook.presto.spi.SchemaTablePrefix; @@ -521,11 +522,11 @@ public List listViews(ConnectorSession session, String schemaNa } @Override - public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) + public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) { - ImmutableMap.Builder map = ImmutableMap.builder(); + ImmutableMap.Builder map = ImmutableMap.builder(); for (ViewResult view : dao.getViews(prefix.getSchemaName(), prefix.getTableName())) { - map.put(view.getName(), view.getData()); + map.put(view.getName(), new ConnectorViewDefinition(view.getName(), Optional.empty(), view.getData())); } return map.build(); } diff --git a/presto-raptor/src/test/java/com/facebook/presto/raptor/metadata/TestRaptorMetadata.java b/presto-raptor/src/test/java/com/facebook/presto/raptor/metadata/TestRaptorMetadata.java index b1a2eff362e7..32f135e378fe 100644 --- a/presto-raptor/src/test/java/com/facebook/presto/raptor/metadata/TestRaptorMetadata.java +++ b/presto-raptor/src/test/java/com/facebook/presto/raptor/metadata/TestRaptorMetadata.java @@ -23,6 +23,7 @@ import com.facebook.presto.spi.ConnectorMetadata; import com.facebook.presto.spi.ConnectorTableHandle; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.SchemaTableName; import com.facebook.presto.spi.SchemaTablePrefix; @@ -305,10 +306,10 @@ public void testViews() assertEqualsIgnoreOrder(list, ImmutableList.of(test1, test2)); // verify getting data - Map views = metadata.getViews(SESSION, new SchemaTablePrefix("test")); + Map views = metadata.getViews(SESSION, new SchemaTablePrefix("test")); assertEquals(views.keySet(), ImmutableSet.of(test1, test2)); - assertEquals(views.get(test1), "test1"); - assertEquals(views.get(test2), "test2"); + assertEquals(views.get(test1).getViewData(), "test1"); + assertEquals(views.get(test2).getViewData(), "test2"); // drop first view metadata.dropView(SESSION, test1); @@ -349,7 +350,7 @@ public void testCreateViewWithReplace() metadata.createView(SESSION, test, "aaa", true); metadata.createView(SESSION, test, "bbb", true); - assertEquals(metadata.getViews(SESSION, test.toSchemaTablePrefix()).get(test), "bbb"); + assertEquals(metadata.getViews(SESSION, test.toSchemaTablePrefix()).get(test).getViewData(), "bbb"); } private static ConnectorTableMetadata getOrdersTable() diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorMetadata.java b/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorMetadata.java index a83dc74ff10f..281c5ffcc4a5 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorMetadata.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorMetadata.java @@ -242,7 +242,7 @@ default List listViews(ConnectorSession session, String schemaN /** * Gets the view data for views that match the specified table prefix. */ - default Map getViews(ConnectorSession session, SchemaTablePrefix prefix) + default Map getViews(ConnectorSession session, SchemaTablePrefix prefix) { return emptyMap(); } diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorViewDefinition.java b/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorViewDefinition.java new file mode 100644 index 000000000000..f62bf057217a --- /dev/null +++ b/presto-spi/src/main/java/com/facebook/presto/spi/ConnectorViewDefinition.java @@ -0,0 +1,57 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.spi; + +import java.util.Optional; + +import static java.util.Objects.requireNonNull; + +public class ConnectorViewDefinition +{ + private final SchemaTableName name; + private final Optional owner; + private final String viewData; + + public ConnectorViewDefinition(SchemaTableName name, Optional owner, String viewData) + { + this.name = requireNonNull(name, "name is null"); + this.owner = requireNonNull(owner, "owner is null"); + this.viewData = requireNonNull(viewData, "viewData is null"); + } + + public SchemaTableName getName() + { + return name; + } + + public Optional getOwner() + { + return owner; + } + + public String getViewData() + { + return viewData; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("ConnectorViewDefinition{"); + sb.append("name=").append(name); + sb.append(", owner=").append(owner); + sb.append('}'); + return sb.toString(); + } +} diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/classloader/ClassLoaderSafeConnectorMetadata.java b/presto-spi/src/main/java/com/facebook/presto/spi/classloader/ClassLoaderSafeConnectorMetadata.java index 67246422345b..3b84d0952298 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/classloader/ClassLoaderSafeConnectorMetadata.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/classloader/ClassLoaderSafeConnectorMetadata.java @@ -24,6 +24,7 @@ import com.facebook.presto.spi.ConnectorTableLayoutHandle; import com.facebook.presto.spi.ConnectorTableLayoutResult; import com.facebook.presto.spi.ConnectorTableMetadata; +import com.facebook.presto.spi.ConnectorViewDefinition; import com.facebook.presto.spi.Constraint; import com.facebook.presto.spi.SchemaTableName; import com.facebook.presto.spi.SchemaTablePrefix; @@ -222,7 +223,7 @@ public List listViews(ConnectorSession session, String schemaNa } @Override - public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) + public Map getViews(ConnectorSession session, SchemaTablePrefix prefix) { try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(classLoader)) { return delegate.getViews(session, prefix);