fix(dameng): degrade trigger metadata to unavailable on permission errors

This commit is contained in:
Xsyl.way
2026-10-12 21:28:52 +08:00
committed by GitHub
parent d219f2b8ba
commit 4740942e8b
2 changed files with 55 additions and 0 deletions
@@ -744,6 +744,9 @@ public final class DamengAgent extends AbstractJdbcAgent {
if (errorCode == -3325 || errorCode == -2207) {
return true;
}
if (isDamengPermissionError(candidate)) {
return true;
}
String message = candidate.getMessage();
if (message == null) {
continue;
@@ -786,6 +789,27 @@ public final class DamengAgent extends AbstractJdbcAgent {
return false;
}
/**
* 达梦中文环境在无权限时只返回「权限不足」(vendorCode -5669),消息里不带对象名,
* 无法通过 {@link #isDamengMetadataUnavailableError} 的对象名匹配识别。
* 这类错误同样应按「元数据不可用」处理:走字典视图降级,而不是让查看对象直接报错。
*/
private static boolean isDamengPermissionError(SQLException error) {
if (error.getErrorCode() == -5669) {
return true;
}
String message = error.getMessage();
if (message == null) {
return false;
}
String normalized = message.toLowerCase(Locale.ROOT);
return normalized.contains("权限")
|| normalized.contains("privilege")
|| normalized.contains("permission")
|| normalized.contains("access denied")
|| normalized.contains("not authorized");
}
/** 连接类错误(断连/超时等)不属于元数据不可用,必须继续上抛。 */
private static boolean isDamengConnectionError(Throwable error) {
for (Throwable current = error; current != null; current = current.getCause()) {
@@ -1159,6 +1159,37 @@ class DamengAgentMetadataTest {
Assertions.assertTrue(source.getSource().contains("系统字典视图"), source.getSource());
}
@Test
void fallsBackToTriggerCatalogWhenDbmsMetadataPermissionDenied() {
DamengAgent agent = new DamengAgent();
List<String> sqls = new ArrayList<>();
TestSupport.setPrivateConnection(agent, proxy(Connection.class, (method, args) -> {
if ("prepareStatement".equals(method.getName())) {
String sql = (String) args[0];
sqls.add(sql);
if (sql.contains("DBMS_METADATA.GET_DDL")) {
return failingMetadataStatement(new SQLException("权限不足", "28000", -5669));
}
if (sql.contains("ALL_TRIGGERS")) {
return metadataStatement(List.of(List.of("BEGIN NULL; END;")));
}
}
if ("close".equals(method.getName())) {
return null;
}
if ("isClosed".equals(method.getName())) {
return false;
}
return defaultValue(method.getReturnType());
}));
ObjectSource source = agent.getObjectSource("APP", "TRG_AUDIT", "TRIGGER");
Assertions.assertTrue(source.getSource().contains("BEGIN NULL; END;"), source.getSource());
Assertions.assertTrue(source.getSource().contains("系统字典视图"), source.getSource());
Assertions.assertTrue(sqls.stream().anyMatch(sql -> sql.contains("ALL_TRIGGERS")), String.join("\n", sqls));
}
@Test
void tableDdlFallsBackToViewAndMaterializedViewCatalogDefinitions() {
DamengAgent agent = new DamengAgent();