This is an automated email from the ASF dual-hosted git repository.
yuqi1129 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 6968f0b0ba [#13916] fix(jdbc): reject unsupported StarRocks and
OceanBase purge (#13917)
6968f0b0ba is described below
commit 6968f0b0baf258eeeaa8b29c17c91892657131b0
Author: Qi Yu <[email protected]>
AuthorDate: Mon Oct 19 15:46:44 2026 +0800
[#13916] fix(jdbc): reject unsupported StarRocks and OceanBase purge
(#13917)
### What changes were proposed in this pull request?
Reject unsupported table purge in the StarRocks and OceanBase JDBC
catalogs instead of executing `TRUNCATE TABLE`.
Remove StarRocks' two-argument purge SQL override so the actual JDBC
purge path reaches its existing unsupported-operation check. Make
OceanBase report the same unsupported-operation contract. Add regression
tests through `purge()` that verify the exception, no destructive SQL
execution, and connection release; also verify ordinary `drop()` still
executes `DROP TABLE`. Update the existing OceanBase integration test to
expect unsupported purge for both present and absent tables and verify
rejection preserves the existing table.
Document in both catalog pages that drop runs `DROP TABLE` and purge is
rejected without changing the table.
### Why are the changes needed?
Both catalogs currently clear the data while retaining the table, then
report `dropped: true`. This violates the table-purge contract and can
cause Gravitino to remove its registration for a table that still
exists.
Fix: #13916
### Does this PR introduce _any_ user-facing change?
Yes. Purge on these two catalogs now reports an unsupported-operation
error instead of clearing table data and reporting successful deletion.
Use ordinary drop to delete a table. This does not claim that ordinary
drop skips the backend's recycle bin.
### How was this patch tested?
- All non-Docker unit tests in both affected modules: 22 passed
(StarRocks 13, OceanBase 9).
- Spotless checks and `git diff --check` passed.
- Restored both old implementations temporarily: both new purge
regressions failed because no unsupported-operation exception was
thrown. The fixes were restored afterward.
- Focused OceanBase Docker integration test
`CatalogOceanBaseIT.testNameSpec`: 1 passed against a real OceanBase
container and embedded Gravitino server.
---
.../operation/OceanBaseTableOperations.java | 3 +-
.../integration/test/CatalogOceanBaseIT.java | 6 +++-
.../TestOceanBaseTableOperationsSqlGeneration.java | 34 ++++++++++++++++++++++
.../operations/StarRocksTableOperations.java | 6 ----
.../TestStarRocksTableOperationsSqlGeneration.java | 34 ++++++++++++++++++++++
docs/jdbc-oceanbase-catalog.md | 7 +++++
docs/jdbc-starrocks-catalog.md | 7 +++++
7 files changed, 89 insertions(+), 8 deletions(-)
diff --git
a/catalogs-contrib/catalog-jdbc-oceanbase/src/main/java/org/apache/gravitino/catalog/oceanbase/operation/OceanBaseTableOperations.java
b/catalogs-contrib/catalog-jdbc-oceanbase/src/main/java/org/apache/gravitino/catalog/oceanbase/operation/OceanBaseTableOperations.java
index fd1aceeec5..312e6d7a1e 100644
---
a/catalogs-contrib/catalog-jdbc-oceanbase/src/main/java/org/apache/gravitino/catalog/oceanbase/operation/OceanBaseTableOperations.java
+++
b/catalogs-contrib/catalog-jdbc-oceanbase/src/main/java/org/apache/gravitino/catalog/oceanbase/operation/OceanBaseTableOperations.java
@@ -196,7 +196,8 @@ public class OceanBaseTableOperations extends
JdbcTableOperations {
@Override
protected String generatePurgeTableSql(String tableName) {
- return String.format("TRUNCATE TABLE `%s`", tableName);
+ throw new UnsupportedOperationException(
+ "OceanBase does not support purge table in Gravitino, please use drop
table");
}
/**
diff --git
a/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
b/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
index f930af31ec..ac997a4d60 100644
---
a/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
+++
b/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/integration/test/CatalogOceanBaseIT.java
@@ -1462,9 +1462,13 @@ public class CatalogOceanBaseIT extends BaseIT {
catalog.asTableCatalog().listTables(Namespace.of(testSchemaName));
Assertions.assertTrue(Arrays.stream(tableIdents).anyMatch(t ->
t.name().equals(testTableName)));
+ Assertions.assertThrows(
+ UnsupportedOperationException.class, () ->
catalog.asTableCatalog().purgeTable(tableIdent));
+ Assertions.assertTrue(catalog.asTableCatalog().tableExists(tableIdent));
Assertions.assertTrue(catalog.asTableCatalog().dropTable(tableIdent));
Assertions.assertFalse(catalog.asTableCatalog().tableExists(tableIdent));
- Assertions.assertFalse(catalog.asTableCatalog().purgeTable(tableIdent));
+ Assertions.assertThrows(
+ UnsupportedOperationException.class, () ->
catalog.asTableCatalog().purgeTable(tableIdent));
catalog.asSchemas().dropSchema(testSchemaName, true);
// sql injection
diff --git
a/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/operation/TestOceanBaseTableOperationsSqlGeneration.java
b/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/operation/TestOceanBaseTableOperationsSqlGeneration.java
index 2897660bfc..74ea40b2d5 100644
---
a/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/operation/TestOceanBaseTableOperationsSqlGeneration.java
+++
b/catalogs-contrib/catalog-jdbc-oceanbase/src/test/java/org/apache/gravitino/catalog/oceanbase/operation/TestOceanBaseTableOperationsSqlGeneration.java
@@ -19,9 +19,11 @@
package org.apache.gravitino.catalog.oceanbase.operation;
import java.util.Collections;
+import java.util.List;
import org.apache.gravitino.catalog.jdbc.JdbcColumn;
import
org.apache.gravitino.catalog.jdbc.converter.JdbcColumnDefaultValueConverter;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.apache.gravitino.catalog.jdbc.utils.ConnectionCountingDataSource;
import org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter;
import org.apache.gravitino.rel.expressions.distributions.Distributions;
import org.apache.gravitino.rel.expressions.literals.Literals;
@@ -40,6 +42,11 @@ public class TestOceanBaseTableOperationsSqlGeneration {
super.columnDefaultValueConverter = new
JdbcColumnDefaultValueConverter();
}
+ private TestableOceanBaseTableOperations(ConnectionCountingDataSource
connections) {
+ this();
+ dataSource = connections.dataSource();
+ }
+
public String createTableSql(String tableName, JdbcColumn[] columns) {
return generateCreateTableSql(
tableName,
@@ -52,6 +59,33 @@ public class TestOceanBaseTableOperationsSqlGeneration {
}
}
+ @Test
+ void testPurgeIsRejectedWithoutExecutingSql() {
+ ConnectionCountingDataSource connections = new
ConnectionCountingDataSource();
+ TestableOceanBaseTableOperations ops = new
TestableOceanBaseTableOperations(connections);
+
+ UnsupportedOperationException exception =
+ Assertions.assertThrows(
+ UnsupportedOperationException.class, () -> ops.purge("database",
"test_table"));
+
+ Assertions.assertEquals(
+ "OceanBase does not support purge table in Gravitino, please use drop
table",
+ exception.getMessage());
+ Assertions.assertTrue(connections.executedSql().isEmpty());
+ Assertions.assertEquals(0, connections.borrowed());
+ }
+
+ @Test
+ void testDropStillExecutesDropTable() {
+ ConnectionCountingDataSource connections = new
ConnectionCountingDataSource();
+ TestableOceanBaseTableOperations ops = new
TestableOceanBaseTableOperations(connections);
+
+ Assertions.assertTrue(ops.drop("database", "test_table"));
+
+ Assertions.assertEquals(List.of("DROP TABLE `test_table`"),
connections.executedSql());
+ Assertions.assertEquals(0, connections.borrowed());
+ }
+
@Test
public void testCreateTableWithEmptyStringDefaultValue() {
TestableOceanBaseTableOperations ops = new
TestableOceanBaseTableOperations();
diff --git
a/catalogs/catalog-jdbc-starrocks/src/main/java/org/apache/gravitino/catalog/starrocks/operations/StarRocksTableOperations.java
b/catalogs/catalog-jdbc-starrocks/src/main/java/org/apache/gravitino/catalog/starrocks/operations/StarRocksTableOperations.java
index 8d6af056fc..439deee4dd 100644
---
a/catalogs/catalog-jdbc-starrocks/src/main/java/org/apache/gravitino/catalog/starrocks/operations/StarRocksTableOperations.java
+++
b/catalogs/catalog-jdbc-starrocks/src/main/java/org/apache/gravitino/catalog/starrocks/operations/StarRocksTableOperations.java
@@ -306,16 +306,10 @@ public class StarRocksTableOperations extends
JdbcTableOperations {
@Override
protected String generatePurgeTableSql(String tableName) {
- // never called, as implemented generatePurgeTableSql(String databaseName,
String tableName)
throw new UnsupportedOperationException(
"StarRocks does not support purge table in Gravitino, please use drop
table");
}
- @Override
- protected String generatePurgeTableSql(String databaseName, String
tableName) {
- return String.format("TRUNCATE TABLE `%s`.`%s`", databaseName, tableName);
- }
-
@Override
protected Distribution getDistributionInfo(
Connection connection, String databaseName, String tableName) throws
SQLException {
diff --git
a/catalogs/catalog-jdbc-starrocks/src/test/java/org/apache/gravitino/catalog/starrocks/operation/TestStarRocksTableOperationsSqlGeneration.java
b/catalogs/catalog-jdbc-starrocks/src/test/java/org/apache/gravitino/catalog/starrocks/operation/TestStarRocksTableOperationsSqlGeneration.java
index b16e0e96b4..fa2d6c40f8 100644
---
a/catalogs/catalog-jdbc-starrocks/src/test/java/org/apache/gravitino/catalog/starrocks/operation/TestStarRocksTableOperationsSqlGeneration.java
+++
b/catalogs/catalog-jdbc-starrocks/src/test/java/org/apache/gravitino/catalog/starrocks/operation/TestStarRocksTableOperationsSqlGeneration.java
@@ -20,11 +20,13 @@ package org.apache.gravitino.catalog.starrocks.operation;
import java.sql.Connection;
import java.util.Collections;
+import java.util.List;
import org.apache.gravitino.StringIdentifier;
import org.apache.gravitino.catalog.jdbc.JdbcColumn;
import org.apache.gravitino.catalog.jdbc.JdbcTable;
import
org.apache.gravitino.catalog.jdbc.converter.JdbcColumnDefaultValueConverter;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
+import org.apache.gravitino.catalog.jdbc.utils.ConnectionCountingDataSource;
import org.apache.gravitino.catalog.starrocks.converter.StarRocksTypeConverter;
import
org.apache.gravitino.catalog.starrocks.operations.StarRocksTableOperations;
import org.apache.gravitino.rel.TableChange;
@@ -53,6 +55,11 @@ public class TestStarRocksTableOperationsSqlGeneration {
super.columnDefaultValueConverter = new
JdbcColumnDefaultValueConverter();
}
+ private TestableStarRocksTableOperations(ConnectionCountingDataSource
connections) {
+ this();
+ dataSource = connections.dataSource();
+ }
+
public String createTableSql(
String tableName, JdbcColumn[] columns, Distribution distribution) {
return createTableSql(tableName, columns, distribution, "comment");
@@ -143,6 +150,33 @@ public class TestStarRocksTableOperationsSqlGeneration {
"test_table", new JdbcColumn[] {column}, distribution, "comment",
indexes));
}
+ @Test
+ void testPurgeIsRejectedWithoutExecutingSql() {
+ ConnectionCountingDataSource connections = new
ConnectionCountingDataSource();
+ TestableStarRocksTableOperations ops = new
TestableStarRocksTableOperations(connections);
+
+ UnsupportedOperationException exception =
+ Assertions.assertThrows(
+ UnsupportedOperationException.class, () -> ops.purge("database",
"test_table"));
+
+ Assertions.assertEquals(
+ "StarRocks does not support purge table in Gravitino, please use drop
table",
+ exception.getMessage());
+ Assertions.assertTrue(connections.executedSql().isEmpty());
+ Assertions.assertEquals(0, connections.borrowed());
+ }
+
+ @Test
+ void testDropStillExecutesDropTable() {
+ ConnectionCountingDataSource connections = new
ConnectionCountingDataSource();
+ TestableStarRocksTableOperations ops = new
TestableStarRocksTableOperations(connections);
+
+ Assertions.assertTrue(ops.drop("database", "test_table"));
+
+ Assertions.assertEquals(List.of("DROP TABLE `test_table`"),
connections.executedSql());
+ Assertions.assertEquals(0, connections.borrowed());
+ }
+
@Test
public void testCreateTableWithEmptyStringDefaultValue() {
TestableStarRocksTableOperations ops = new
TestableStarRocksTableOperations();
diff --git a/docs/jdbc-oceanbase-catalog.md b/docs/jdbc-oceanbase-catalog.md
index cd44ed518d..192af85017 100644
--- a/docs/jdbc-oceanbase-catalog.md
+++ b/docs/jdbc-oceanbase-catalog.md
@@ -264,6 +264,13 @@ The OceanBase catalog does not support creating
partitioned tables in the curren
Refer to [Manage Relational Metadata Using
Gravitino](./manage-relational-metadata-using-gravitino.md#table-operations)
for more details.
+#### Drop and Purge Table
+
+- Dropping a table runs `DROP TABLE` in OceanBase. Whether OceanBase keeps the
dropped table in its
+ recycle bin depends on the OceanBase configuration.
+- Purging a table is not supported. A purge request fails with an
unsupported-operation error, and
+ the table and its data stay unchanged. Use drop instead.
+
#### Alter Table Operations
Gravitino supports these table alteration operations:
diff --git a/docs/jdbc-starrocks-catalog.md b/docs/jdbc-starrocks-catalog.md
index e94615f4c2..cb87bad97e 100644
--- a/docs/jdbc-starrocks-catalog.md
+++ b/docs/jdbc-starrocks-catalog.md
@@ -181,6 +181,13 @@ For the `RANDOM` distribution strategy, Gravitino uses the
`EVEN` to represent i
Refer to [Manage Relational Metadata Using
Gravitino](./manage-relational-metadata-using-gravitino.md#table-operations)
for more details.
+#### Drop and Purge Table
+
+- Dropping a table runs `DROP TABLE` in StarRocks. Whether StarRocks keeps the
dropped table in its
+ recycle bin depends on the StarRocks configuration.
+- Purging a table is not supported. A purge request fails with an
unsupported-operation error, and
+ the table and its data stay unchanged. Use drop instead.
+
#### Alter Table Operations
Gravitino supports these table alteration operations: