fix(dameng): support low-privilege schema loading

This commit is contained in:
zipg 2026-07-20 23:28:21 +08:00 committed by GitHub
parent 574172f667
commit f4ce0dc435
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 2 deletions

View File

@ -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<String> 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<String> 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<String> listVisibleUsers() throws Exception {

View File

@ -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<String> sqls = new ArrayList<>();
TestSupport.setPrivateConnection(agent, restrictedSchemaConnection(sqls));
List<String> 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<String> 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())) {