Skip to content

Commit

Permalink
add list views
Browse files Browse the repository at this point in the history
  • Loading branch information
JingsongLi committed Oct 17, 2024
1 parent 3da88e4 commit d12face
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 39 deletions.
10 changes: 10 additions & 0 deletions paimon-core/src/main/java/org/apache/paimon/catalog/Catalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,16 @@ default void createView(Identifier identifier, View view, boolean ignoreIfExists
throw new UnsupportedOperationException();
}

/**
* Get names of all views under this database. An empty list is returned if none exists.
*
* @return a list of the names of all views in this database
* @throws DatabaseNotExistException if the database does not exist
*/
default List<String> listViews(String databaseName) throws DatabaseNotExistException {
throw new UnsupportedOperationException();
}

/** Return a boolean that indicates whether this catalog allow upper case. */
boolean allowUpperCase();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ public void createView(Identifier identifier, View view, boolean ignoreIfExists)
wrapped.createView(identifier, view, ignoreIfExists);
}

@Override
public List<String> listViews(String databaseName) throws DatabaseNotExistException {
return wrapped.listViews(databaseName);
}

@Override
public Path getTableLocation(Identifier identifier) {
return wrapped.getTableLocation(identifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,12 @@ public View copy(Map<String, String> dynamicOptions) {

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ViewImpl view = (ViewImpl) o;
return Objects.equals(identifier, view.identifier)
&& Objects.equals(rowType, view.rowType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,9 @@ public void testView() throws Exception {
assertThatThrownBy(() -> catalog.createView(identifier, view, false))
.isInstanceOf(Catalog.DatabaseNotExistException.class);

assertThatThrownBy(() -> catalog.listViews(identifier.getDatabaseName()))
.isInstanceOf(Catalog.DatabaseNotExistException.class);

catalog.createDatabase(identifier.getDatabaseName(), false);

assertThatThrownBy(() -> catalog.getView(identifier))
Expand All @@ -878,6 +881,9 @@ public void testView() throws Exception {
assertThat(catalogView.comment()).isEqualTo(view.comment());
assertThat(catalogView.options()).containsAllEntriesOf(view.options());

List<String> views = catalog.listViews(identifier.getDatabaseName());
assertThat(views).containsOnly(identifier.getObjectName());

catalog.createView(identifier, view, true);
assertThatThrownBy(() -> catalog.createView(identifier, view, false))
.isInstanceOf(Catalog.ViewAlreadyExistException.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@ public CatalogBaseTable getTable(ObjectPath tablePath, long timestamp)

private CatalogBaseTable getTable(ObjectPath tablePath, @Nullable Long timestamp)
throws TableNotExistException {
Identifier identifier = toIdentifier(tablePath);
Table table;
try {
table = catalog.getTable(toIdentifier(tablePath));
Expand Down Expand Up @@ -387,41 +386,15 @@ public void createTable(ObjectPath tablePath, CatalogBaseTable table, boolean ig
"Creating table in default database is disabled, please specify a database name.");
}

Identifier identifier = toIdentifier(tablePath);
// the returned value of "table.getOptions" may be unmodifiable (for example from
// TableDescriptor)
Map<String, String> options = new HashMap<>(table.getOptions());

if (table instanceof CatalogView) {
ResolvedCatalogView viewTable = (ResolvedCatalogView) table;
org.apache.paimon.types.RowType.Builder builder =
org.apache.paimon.types.RowType.builder();
viewTable
.getResolvedSchema()
.getColumns()
.forEach(
column ->
builder.field(
column.getName(),
toDataType(column.getDataType().getLogicalType()),
column.getComment().orElse(null)));
View view =
new ViewImpl(
identifier,
builder.build(),
viewTable.getExpandedQuery(),
viewTable.getComment(),
viewTable.getOptions());
try {
catalog.createView(identifier, view, ignoreIfExists);
} catch (Catalog.ViewAlreadyExistException e) {
throw new TableAlreadyExistException(getName(), tablePath);
} catch (Catalog.DatabaseNotExistException e) {
throw new DatabaseNotExistException(getName(), tablePath.getDatabaseName());
}
createView(tablePath, (ResolvedCatalogView) table, ignoreIfExists);
return;
}

Identifier identifier = toIdentifier(tablePath);
// the returned value of "table.getOptions" may be unmodifiable (for example from
// TableDescriptor)
Map<String, String> options = new HashMap<>(table.getOptions());
if (table instanceof CatalogMaterializedTable) {
fillOptionsForMaterializedTable((CatalogMaterializedTable) table, options);
}
Expand All @@ -443,6 +416,34 @@ public void createTable(ObjectPath tablePath, CatalogBaseTable table, boolean ig
}
}

private void createView(ObjectPath tablePath, ResolvedCatalogView table, boolean ignoreIfExists)
throws TableAlreadyExistException, DatabaseNotExistException {
Identifier identifier = toIdentifier(tablePath);
org.apache.paimon.types.RowType.Builder builder = org.apache.paimon.types.RowType.builder();
table.getResolvedSchema()
.getColumns()
.forEach(
column ->
builder.field(
column.getName(),
toDataType(column.getDataType().getLogicalType()),
column.getComment().orElse(null)));
View view =
new ViewImpl(
identifier,
builder.build(),
table.getOriginalQuery(),
table.getComment(),
table.getOptions());
try {
catalog.createView(identifier, view, ignoreIfExists);
} catch (Catalog.ViewAlreadyExistException e) {
throw new TableAlreadyExistException(getName(), tablePath);
} catch (Catalog.DatabaseNotExistException e) {
throw new DatabaseNotExistException(getName(), tablePath.getDatabaseName());
}
}

private static void fillOptionsForMaterializedTable(
CatalogMaterializedTable mt, Map<String, String> options) {
Options mtOptions = new Options();
Expand Down Expand Up @@ -1096,8 +1097,13 @@ public final void renameTable(
}

@Override
public final List<String> listViews(String databaseName) throws CatalogException {
return Collections.emptyList();
public final List<String> listViews(String databaseName)
throws DatabaseNotExistException, CatalogException {
try {
return catalog.listViews(databaseName);
} catch (Catalog.DatabaseNotExistException e) {
throw new DatabaseNotExistException(getName(), databaseName);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,33 @@ public void dropView(Identifier identifier, boolean ignoreIfNotExists)
}
}

@Override
public List<String> listViews(String databaseName) throws DatabaseNotExistException {
if (isSystemDatabase(databaseName)) {
return Collections.emptyList();
}
if (!databaseExists(databaseName)) {
throw new DatabaseNotExistException(databaseName);
}

try {
List<String> tables = clients.run(client -> client.getAllTables(databaseName));
List<String> views = new ArrayList<>();
for (String tableName : tables) {
Table table = clients.run(client -> client.getTable(databaseName, tableName));
if (TableType.valueOf(table.getTableType()) == TableType.VIRTUAL_VIEW) {
views.add(tableName);
}
}
return views;
} catch (TException e) {
throw new RuntimeException("Failed to list all tables in database " + databaseName, e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted in call to listTables " + databaseName, e);
}
}

@Override
public FormatTable getFormatTable(Identifier identifier) throws TableNotExistException {
if (!formatTableEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1921,9 +1921,8 @@ public void testView() throws Exception {
tEnv.executeSql("CREATE VIEW flink_v AS SELECT a + 1, b FROM t").await();
assertThat(collect("SELECT * FROM flink_v"))
.containsExactlyInAnyOrder(Row.of(2, "Hi"), Row.of(3, "Hello"));

// hive cannot query flink view, flink view will expand table name to
// `my_hive`.`test_db`.`t`
assertThat(hiveShell.executeQuery("SELECT * FROM flink_v"))
.containsExactlyInAnyOrder("2\tHi", "3\tHello");

// test hive view
hiveShell.executeQuery("CREATE VIEW hive_v AS SELECT a + 1, b FROM t");
Expand All @@ -1932,6 +1931,9 @@ public void testView() throws Exception {
assertThat(hiveShell.executeQuery("SELECT * FROM hive_v"))
.containsExactlyInAnyOrder("2\tHi", "3\tHello");

assertThat(collect("SHOW VIEWS"))
.containsExactlyInAnyOrder(Row.of("flink_v"), Row.of("hive_v"));

collect("DROP VIEW flink_v");
collect("DROP VIEW hive_v");
}
Expand Down

0 comments on commit d12face

Please sign in to comment.