From 5c7832720ef47308645a71199c982dd13da411f2 Mon Sep 17 00:00:00 2001 From: zipg Date: Fri, 17 Jul 2026 00:06:37 +0800 Subject: [PATCH] fix(gbase8a): preserve native table DDL --- .../com/dbx/agent/gbase8a/Gbase8aAgent.java | 54 +++++++++++-------- .../dbx/agent/gbase8a/Gbase8aAgentTest.java | 19 +++++++ 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/agents/drivers/gbase8a/src/main/java/com/dbx/agent/gbase8a/Gbase8aAgent.java b/agents/drivers/gbase8a/src/main/java/com/dbx/agent/gbase8a/Gbase8aAgent.java index e12e7e7132..43a7dba7ea 100644 --- a/agents/drivers/gbase8a/src/main/java/com/dbx/agent/gbase8a/Gbase8aAgent.java +++ b/agents/drivers/gbase8a/src/main/java/com/dbx/agent/gbase8a/Gbase8aAgent.java @@ -170,37 +170,49 @@ public final class Gbase8aAgent extends ConfiguredJdbcAgent { } } + @Override + public String getTableDdl(String schema, String table) { + try { + String ddl = showCreateDefinition("TABLE", schema, table); + if (!ddl.isEmpty()) { + return ddl; + } + } catch (RuntimeException ignored) { + // Keep metadata-based DDL available for servers that restrict SHOW CREATE TABLE. + } + return super.getTableDdl(schema, table); + } + @Override public ObjectSource getObjectSource(String schema, String name, String objectType) { + String normalizedType = objectType.toUpperCase(Locale.ROOT); + if (!List.of("VIEW", "PROCEDURE", "FUNCTION").contains(normalizedType)) { + throw new IllegalArgumentException("Unsupported object type: " + objectType); + } + return new ObjectSource(name, normalizedType, schema, showCreateDefinition(normalizedType, schema, name)); + } + + private String showCreateDefinition(String objectType, String schema, String name) { return unchecked(() -> { - String normalizedType = objectType.toUpperCase(Locale.ROOT); - String sql = switch (normalizedType) { - case "VIEW" -> "SHOW CREATE VIEW "; - case "PROCEDURE" -> "SHOW CREATE PROCEDURE "; - case "FUNCTION" -> "SHOW CREATE FUNCTION "; - default -> throw new IllegalArgumentException("Unsupported object type: " + objectType); - }; String qualifiedName = hasSchema(schema) ? JdbcIdentifiers.INSTANCE.backtick(schema) + "." + JdbcIdentifiers.INSTANCE.backtick(name) : JdbcIdentifiers.INSTANCE.backtick(name); - - String source = ""; try (Statement stmt = requireConnection().createStatement(); - ResultSet rs = stmt.executeQuery(sql + qualifiedName)) { - if (rs.next()) { - // SHOW CREATE result layouts vary by GBase driver version, so locate the definition column by label. - ResultSetMetaData metadata = rs.getMetaData(); - for (int index = 1; index <= metadata.getColumnCount(); index++) { - String label = metadata.getColumnLabel(index); - if (label != null && label.toUpperCase(Locale.ROOT).startsWith("CREATE ")) { - String value = rs.getString(index); - source = value == null ? "" : value; - break; - } + ResultSet rs = stmt.executeQuery("SHOW CREATE " + objectType + " " + qualifiedName)) { + if (!rs.next()) { + return ""; + } + // SHOW CREATE result layouts vary by GBase driver version, so locate the definition column by label. + ResultSetMetaData metadata = rs.getMetaData(); + for (int index = 1; index <= metadata.getColumnCount(); index++) { + String label = metadata.getColumnLabel(index); + if (label != null && label.toUpperCase(Locale.ROOT).startsWith("CREATE ")) { + String value = rs.getString(index); + return value == null ? "" : value; } } + return ""; } - return new ObjectSource(name, normalizedType, schema, source); }); } diff --git a/agents/drivers/gbase8a/src/test/java/com/dbx/agent/gbase8a/Gbase8aAgentTest.java b/agents/drivers/gbase8a/src/test/java/com/dbx/agent/gbase8a/Gbase8aAgentTest.java index e17769de1f..a6fa09cae3 100644 --- a/agents/drivers/gbase8a/src/test/java/com/dbx/agent/gbase8a/Gbase8aAgentTest.java +++ b/agents/drivers/gbase8a/src/test/java/com/dbx/agent/gbase8a/Gbase8aAgentTest.java @@ -98,6 +98,25 @@ class Gbase8aAgentTest { Assertions.assertTrue(sql.get(0).contains("LIMIT ?"), sql.get(0)); } + @Test + void getTableDdlUsesShowCreateToPreserveNativeColumnClauses() { + List sql = new ArrayList<>(); + String nativeDdl = "CREATE TABLE \"orders`archive\" (\n" + + " \"UPDATE_TIME\" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'updated at'\n" + + ") ENGINE=EXPRESS DEFAULT CHARSET=utf8"; + Gbase8aAgent agent = new Gbase8aAgent(); + TestSupport.setPrivateConnection(agent, statementConnection(sql, resultSet( + new String[]{"Table", "Create Table"}, + new Object[][]{{"orders`archive", nativeDdl}} + ))); + + String ddl = agent.getTableDdl("app`prod", "orders`archive"); + + Assertions.assertEquals(nativeDdl, ddl); + Assertions.assertTrue(ddl.contains("ON UPDATE CURRENT_TIMESTAMP"), ddl); + Assertions.assertEquals("SHOW CREATE TABLE `app``prod`.`orders``archive`", sql.get(0)); + } + @Test void getObjectSourceUsesShowCreateForRoutines() { List sql = new ArrayList<>();