diff --git a/agents/drivers/dameng/src/main/java/com/dbx/agent/dameng/DamengAgent.java b/agents/drivers/dameng/src/main/java/com/dbx/agent/dameng/DamengAgent.java index 0110a8fa3..45e445463 100644 --- a/agents/drivers/dameng/src/main/java/com/dbx/agent/dameng/DamengAgent.java +++ b/agents/drivers/dameng/src/main/java/com/dbx/agent/dameng/DamengAgent.java @@ -26,6 +26,7 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.SQLXML; import java.sql.Statement; import java.sql.Types; @@ -73,7 +74,7 @@ public final class DamengAgent extends BaseDatabaseAgent { """.stripIndent().trim(); private static final Set SYSTEM_USERS = Set.of( "SYS", "SYSAUDITOR", "SYSSSO", "CTISYS", - "SYS_DBA", "_SYS_STATISTICS", "SYS_PHM" + "SYSDBA", "SYS_DBA", "_SYS_STATISTICS", "SYS_PHM" ); private Connection connection; @@ -140,7 +141,18 @@ public final class DamengAgent extends BaseDatabaseAgent { @Override public List listSchemas() { - return unchecked(this::listVisibleSchemas); + return unchecked(() -> { + try { + return listVisibleSchemas(); + } catch (SQLException catalogError) { + try { + return listVisibleUsers(); + } catch (Exception fallbackError) { + catalogError.addSuppressed(fallbackError); + throw catalogError; + } + } + }); } private List listVisibleUsers() throws Exception { diff --git a/agents/drivers/dameng/src/test/java/com/dbx/agent/dameng/DamengAgentMetadataTest.java b/agents/drivers/dameng/src/test/java/com/dbx/agent/dameng/DamengAgentMetadataTest.java index 528fac90a..09b5e28f9 100644 --- a/agents/drivers/dameng/src/test/java/com/dbx/agent/dameng/DamengAgentMetadataTest.java +++ b/agents/drivers/dameng/src/test/java/com/dbx/agent/dameng/DamengAgentMetadataTest.java @@ -112,6 +112,20 @@ class DamengAgentMetadataTest { Assertions.assertTrue(sqls.stream().noneMatch(sql -> sql.contains("ALL_OBJECTS")), String.join("\n", sqls)); } + @Test + void listSchemasFallsBackToAllUsersWithoutSysObjectsPrivilege() { + DamengAgent agent = new DamengAgent(); + List sqls = new ArrayList<>(); + TestSupport.setPrivateConnection(agent, restrictedSchemaConnection(sqls)); + + List schemas = agent.listSchemas(); + + Assertions.assertEquals(List.of("APP", "REPORTING"), schemas); + Assertions.assertEquals(2, sqls.size(), String.join("\n", sqls)); + Assertions.assertTrue(sqls.get(0).contains("SYS.SYSOBJECTS"), sqls.get(0)); + Assertions.assertTrue(sqls.get(1).contains("ALL_USERS"), sqls.get(1)); + } + @Test void mapsMaterializedViewsFromMetadata() { DamengAgent agent = new DamengAgent(); @@ -696,6 +710,30 @@ class DamengAgentMetadataTest { }); } + private static Connection restrictedSchemaConnection(List sqls) { + return proxy(Connection.class, (method, args) -> { + String name = method.getName(); + if ("prepareStatement".equals(name)) { + String sql = (String) args[0]; + sqls.add(sql); + if (sql.contains("SYS.SYSOBJECTS")) { + return failingMetadataStatement("no SYS.SYSOBJECTS privilege"); + } + if (sql.contains("ALL_USERS")) { + return metadataStatement(List.of(List.of("APP"), List.of("REPORTING"))); + } + throw new AssertionError("Unexpected SQL: " + sql); + } + if ("close".equals(name)) { + return null; + } + if ("isClosed".equals(name)) { + return false; + } + return defaultValue(method.getReturnType()); + }); + } + private static PreparedStatement failingMetadataStatement(String message) { return proxy(PreparedStatement.class, (method, args) -> { if ("executeQuery".equals(method.getName())) {