Copilot commented on code in PR #11193:
URL: https://github.com/apache/gravitino/pull/11193#discussion_r3285154979
##########
catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java:
##########
@@ -430,19 +411,53 @@ public NameIdentifier[] listTables(Namespace namespace)
throws NoSuchSchemaExcep
}
}
- private static String getIcebergAndPaimonFilter() {
+ /**
+ * Best-effort removal of non-Hive tables (Iceberg, Paimon, Hudi) from
{@code allTables} using the
+ * HMS server-side {@code listTableNamesByFilter} API. This API only
supports exact-key lookups on
+ * dot-free parameter keys, so tables whose only marker is a dotted key
(e.g. Spark-managed Hudi
+ * tables exposing only {@code spark.sql.sources.provider=hudi}) cannot be
filtered out here; see
+ * the {@code list-all-tables} catalog property for the documented
limitation. We prefer this over
+ * {@code getTableObjectsByName} which materializes every Table and is slow
on databases with many
+ * tables.
+ */
+ private void filterOutNonHiveTables(String database, List<String> allTables)
+ throws InterruptedException {
+ List<String> icebergAndPaimonTables =
+ clientPool.run(
+ c ->
+ c.listTableNamesByFilter(
+ catalogName, database, buildIcebergAndPaimonFilter(),
MAX_TABLES));
+ allTables.removeAll(icebergAndPaimonTables);
+
+ // HoodieHiveSyncTool sets `provider=hudi` only on the base table; derived
`_ro` / `_rt`
+ // tables carry only dotted keys, so we strip them by exact name match
against the base list.
+ List<String> hudiBaseTables =
+ clientPool.run(
+ c ->
+ c.listTableNamesByFilter(
+ catalogName, database, buildHudiBaseTableFilter(),
MAX_TABLES));
+ removeHudiDerivedTables(allTables, hudiBaseTables);
+ }
+
+ private static String buildIcebergAndPaimonFilter() {
String icebergFilter = String.format("%stable_type like \"ICEBERG\"",
HIVE_FILTER_FIELD_PARAMS);
String paimonFilter = String.format("%stable_type like \"PAIMON\"",
HIVE_FILTER_FIELD_PARAMS);
return String.format("%s or %s", icebergFilter, paimonFilter);
}
- private void removeHudiTables(List<String> allTables, List<String>
hudiTables) {
- for (String hudiTable : hudiTables) {
+ private static String buildHudiBaseTableFilter() {
+ return String.format("%sprovider like \"hudi\"", HIVE_FILTER_FIELD_PARAMS);
+ }
+
+ /**
+ * Removes Hudi base tables together with their derived read-optimized
({@code _ro}) and real-time
+ * ({@code _rt}) tables. Exact name match is used because {@code startsWith}
would incorrectly
+ * drop unrelated tables such as {@code <base>_root}.
+ */
+ private void removeHudiDerivedTables(List<String> allTables, List<String>
hudiBaseTables) {
+ for (String hudiBase : hudiBaseTables) {
allTables.removeIf(
- t ->
- t.equals(hudiTable)
- || t.startsWith(hudiTable + "_ro")
- || t.startsWith(hudiTable + "_rt"));
+ t -> t.equals(hudiBase) || t.equals(hudiBase + "_ro") ||
t.equals(hudiBase + "_rt"));
}
}
Review Comment:
`removeHudiDerivedTables` currently calls `allTables.removeIf(...)` once per
Hudi base table, which repeatedly scans the full `allTables` list
(O(|allTables| * |hudiBaseTables|)). This can become a noticeable CPU cost on
large schemas. Build a set of names to remove and run a single `removeIf` pass
instead.
##########
docs/apache-hive-catalog.md:
##########
@@ -44,10 +44,32 @@ Besides the [common catalog
properties](./gravitino-server-config.md#apache-grav
| `default.catalog` | The default catalog name for the
Hive3 metastore backend; this configuration is ignored when using a Hive2
metastore.
| hive | No
| 1.1.0 |
:::note
-For `list-all-tables=false`, the Hive catalog will filter out:
-- Iceberg tables by table property `table_type=ICEBERG`
-- Paimon tables by table property `table_type=PAIMON`
-- Hudi tables by table property `provider=hudi`
+When `list-all-tables=false`, the Hive catalog removes the following on a
best-effort basis:
Review Comment:
The `list-all-tables` table entry above still uses the old description and
doesn’t mention the best-effort filtering behavior / known limitation that’s
now documented in the note below (and in the Java property metadata). This can
confuse users reading only the properties table.
##########
catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java:
##########
@@ -430,19 +411,53 @@ public NameIdentifier[] listTables(Namespace namespace)
throws NoSuchSchemaExcep
}
}
- private static String getIcebergAndPaimonFilter() {
+ /**
+ * Best-effort removal of non-Hive tables (Iceberg, Paimon, Hudi) from
{@code allTables} using the
+ * HMS server-side {@code listTableNamesByFilter} API. This API only
supports exact-key lookups on
+ * dot-free parameter keys, so tables whose only marker is a dotted key
(e.g. Spark-managed Hudi
+ * tables exposing only {@code spark.sql.sources.provider=hudi}) cannot be
filtered out here; see
+ * the {@code list-all-tables} catalog property for the documented
limitation. We prefer this over
+ * {@code getTableObjectsByName} which materializes every Table and is slow
on databases with many
+ * tables.
+ */
+ private void filterOutNonHiveTables(String database, List<String> allTables)
+ throws InterruptedException {
+ List<String> icebergAndPaimonTables =
+ clientPool.run(
+ c ->
+ c.listTableNamesByFilter(
+ catalogName, database, buildIcebergAndPaimonFilter(),
MAX_TABLES));
+ allTables.removeAll(icebergAndPaimonTables);
+
+ // HoodieHiveSyncTool sets `provider=hudi` only on the base table; derived
`_ro` / `_rt`
+ // tables carry only dotted keys, so we strip them by exact name match
against the base list.
+ List<String> hudiBaseTables =
+ clientPool.run(
+ c ->
+ c.listTableNamesByFilter(
+ catalogName, database, buildHudiBaseTableFilter(),
MAX_TABLES));
+ removeHudiDerivedTables(allTables, hudiBaseTables);
+ }
+
+ private static String buildIcebergAndPaimonFilter() {
String icebergFilter = String.format("%stable_type like \"ICEBERG\"",
HIVE_FILTER_FIELD_PARAMS);
String paimonFilter = String.format("%stable_type like \"PAIMON\"",
HIVE_FILTER_FIELD_PARAMS);
return String.format("%s or %s", icebergFilter, paimonFilter);
}
- private void removeHudiTables(List<String> allTables, List<String>
hudiTables) {
- for (String hudiTable : hudiTables) {
+ private static String buildHudiBaseTableFilter() {
+ return String.format("%sprovider like \"hudi\"", HIVE_FILTER_FIELD_PARAMS);
+ }
+
+ /**
+ * Removes Hudi base tables together with their derived read-optimized
({@code _ro}) and real-time
+ * ({@code _rt}) tables. Exact name match is used because {@code startsWith}
would incorrectly
+ * drop unrelated tables such as {@code <base>_root}.
+ */
+ private void removeHudiDerivedTables(List<String> allTables, List<String>
hudiBaseTables) {
+ for (String hudiBase : hudiBaseTables) {
allTables.removeIf(
- t ->
- t.equals(hudiTable)
- || t.startsWith(hudiTable + "_ro")
- || t.startsWith(hudiTable + "_rt"));
+ t -> t.equals(hudiBase) || t.equals(hudiBase + "_ro") ||
t.equals(hudiBase + "_rt"));
Review Comment:
This change fixes a correctness bug (avoids over-removal of tables like
`<base>_root` by switching from `startsWith` to exact matches), but there’s no
regression test covering the new behavior. Please add a unit test that ensures
only `<base>`, `<base>_ro`, and `<base>_rt` are removed and that
similarly-prefixed tables (e.g. `<base>_root`) remain listed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]