This is an automated email from the ASF dual-hosted git repository.
yuqi1129 pushed a commit to branch cherry-pick-6968f0b0-to-branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to
refs/heads/cherry-pick-6968f0b0-to-branch-1.3 by this push:
new ea6598ceef fix(jdbc): include purge backport prerequisites
ea6598ceef is described below
commit ea6598ceefd08fdd98e9a6bbc487fa4b4df17033
Author: yuqi <[email protected]>
AuthorDate: Mon Oct 19 18:03:26 2026 +0800
fix(jdbc): include purge backport prerequisites
---
.../TestOceanBaseTableOperationsSqlGeneration.java | 1 +
.../jdbc/operation/JdbcTableOperations.java | 4 +-
.../jdbc/utils/ConnectionCountingDataSource.java | 168 +++++++++++++++++++++
.../TestStarRocksTableOperationsSqlGeneration.java | 1 +
4 files changed, 173 insertions(+), 1 deletion(-)
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 74ea40b2d5..fb15beb030 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
@@ -72,6 +72,7 @@ public class TestOceanBaseTableOperationsSqlGeneration {
"OceanBase does not support purge table in Gravitino, please use drop
table",
exception.getMessage());
Assertions.assertTrue(connections.executedSql().isEmpty());
+ Assertions.assertEquals(0, connections.totalBorrows());
Assertions.assertEquals(0, connections.borrowed());
}
diff --git
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
index 516b3c01b9..e52564ba70 100644
---
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
+++
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
@@ -378,8 +378,10 @@ public abstract class JdbcTableOperations implements
TableOperation {
protected void purgeTable(String databaseName, String tableName) {
LOG.info("Attempting to purge table {} from database {}", tableName,
databaseName);
+ // Reject unsupported purge operations before borrowing an execution
connection.
+ String sql = generatePurgeTableSql(databaseName, tableName);
try (Connection connection = getConnection(databaseName)) {
- JdbcConnectorUtils.executeUpdate(connection,
generatePurgeTableSql(databaseName, tableName));
+ JdbcConnectorUtils.executeUpdate(connection, sql);
LOG.info("Purge table {} from database {}", tableName, databaseName);
} catch (final SQLException se) {
throw this.exceptionMapper.toGravitinoException(se);
diff --git
a/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/ConnectionCountingDataSource.java
b/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/ConnectionCountingDataSource.java
new file mode 100644
index 0000000000..e2a947745b
--- /dev/null
+++
b/catalogs/catalog-jdbc-common/src/test/java/org/apache/gravitino/catalog/jdbc/utils/ConnectionCountingDataSource.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.gravitino.catalog.jdbc.utils;
+
+import java.lang.reflect.Proxy;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Statement;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.sql.DataSource;
+
+/**
+ * A test {@link DataSource} whose connections only record the SQL they
execute. It tracks how many
+ * connections are borrowed at once, so tests can assert that an operation
never holds one
+ * connection while borrowing another.
+ */
+public class ConnectionCountingDataSource {
+
+ private final DatabaseMetaData metadata;
+
+ private final AtomicInteger borrowed = new AtomicInteger();
+ private final AtomicInteger peakBorrowed = new AtomicInteger();
+ private final AtomicInteger totalBorrows = new AtomicInteger();
+ private final List<String> executedSql = new CopyOnWriteArrayList<>();
+ private final DataSource dataSource =
+ (DataSource)
+ Proxy.newProxyInstance(
+ DataSource.class.getClassLoader(),
+ new Class<?>[] {DataSource.class},
+ (proxy, method, args) -> {
+ if ("getConnection".equals(method.getName())) {
+ return borrow();
+ }
+ return objectMethod(proxy, method.getName(), args,
"DataSource");
+ });
+
+ /** Creates a counting data source whose driver reports a null version. */
+ public ConnectionCountingDataSource() {
+ this(metaData());
+ }
+
+ /**
+ * Creates a counting data source with the supplied JDBC metadata.
+ *
+ * @param metadata the metadata returned by each borrowed connection
+ */
+ public ConnectionCountingDataSource(DatabaseMetaData metadata) {
+ this.metadata = metadata;
+ }
+
+ /** Returns the data source to pass to the operations under test. */
+ public DataSource dataSource() {
+ return dataSource;
+ }
+
+ /** Returns the number of connections currently borrowed and not yet closed.
*/
+ public int borrowed() {
+ return borrowed.get();
+ }
+
+ /** Returns the largest number of connections that were borrowed at the same
time. */
+ public int peakBorrowed() {
+ return peakBorrowed.get();
+ }
+
+ /** Returns how many connections were borrowed in total. */
+ public int totalBorrows() {
+ return totalBorrows.get();
+ }
+
+ /** Returns the update statements executed so far, in order. */
+ public List<String> executedSql() {
+ return executedSql;
+ }
+
+ private Connection borrow() {
+ totalBorrows.incrementAndGet();
+ peakBorrowed.accumulateAndGet(borrowed.incrementAndGet(), Math::max);
+ AtomicBoolean closed = new AtomicBoolean();
+ return (Connection)
+ Proxy.newProxyInstance(
+ Connection.class.getClassLoader(),
+ new Class<?>[] {Connection.class},
+ (proxy, method, args) -> {
+ switch (method.getName()) {
+ case "close":
+ if (closed.compareAndSet(false, true)) {
+ borrowed.decrementAndGet();
+ }
+ return null;
+ case "setCatalog":
+ case "setSchema":
+ return null;
+ case "createStatement":
+ return statement();
+ case "getMetaData":
+ return metadata;
+ default:
+ return objectMethod(proxy, method.getName(), args,
"Connection");
+ }
+ });
+ }
+
+ // Answers Object methods so the proxies can be printed or compared, and
rejects anything else.
+ private static Object objectMethod(Object proxy, String name, Object[] args,
String type) {
+ switch (name) {
+ case "toString":
+ return "Counting" + type + "@" +
Integer.toHexString(System.identityHashCode(proxy));
+ case "hashCode":
+ return System.identityHashCode(proxy);
+ case "equals":
+ return proxy == args[0];
+ default:
+ throw new UnsupportedOperationException(type + "." + name);
+ }
+ }
+
+ // Reports a null driver version, which the JDBC contract allows.
+ private static DatabaseMetaData metaData() {
+ return (DatabaseMetaData)
+ Proxy.newProxyInstance(
+ DatabaseMetaData.class.getClassLoader(),
+ new Class<?>[] {DatabaseMetaData.class},
+ (proxy, method, args) -> {
+ if ("getDriverVersion".equals(method.getName())) {
+ return null;
+ }
+ return objectMethod(proxy, method.getName(), args,
"DatabaseMetaData");
+ });
+ }
+
+ private Statement statement() {
+ return (Statement)
+ Proxy.newProxyInstance(
+ Statement.class.getClassLoader(),
+ new Class<?>[] {Statement.class},
+ (proxy, method, args) -> {
+ switch (method.getName()) {
+ case "executeUpdate":
+ executedSql.add((String) args[0]);
+ return 0;
+ case "close":
+ return null;
+ default:
+ return objectMethod(proxy, method.getName(), args,
"Statement");
+ }
+ });
+ }
+}
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 5fc1a2114a..3d43b413e1 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
@@ -99,6 +99,7 @@ public class TestStarRocksTableOperationsSqlGeneration {
"StarRocks does not support purge table in Gravitino, please use drop
table",
exception.getMessage());
Assertions.assertTrue(connections.executedSql().isEmpty());
+ Assertions.assertEquals(0, connections.totalBorrows());
Assertions.assertEquals(0, connections.borrowed());
}