fix(dameng): fall back from invalid catalog dates

Closes #5586
This commit is contained in:
t8y2 2026-08-07 12:51:51 +08:00
parent d7a3a03357
commit 9a00c10da4
No known key found for this signature in database
2 changed files with 73 additions and 1 deletions

View File

@ -287,6 +287,9 @@ public final class DamengAgent extends AbstractJdbcAgent {
try {
return executeConstrainedTables(buildConstrainedTablesQuery(schema, constraints), constraints);
} catch (RuntimeException e) {
if (isDamengInvalidDatetimeMetadataError(e)) {
return executeJdbcMetadataTables(schema, constraints);
}
if (!isDamengMetadataPermissionError(e)) {
throw e;
}
@ -299,6 +302,9 @@ public final class DamengAgent extends AbstractJdbcAgent {
constraints
);
} catch (RuntimeException e) {
if (isDamengInvalidDatetimeMetadataError(e)) {
return executeJdbcMetadataTables(schema, constraints);
}
if (!isDamengMetadataPermissionError(e)) {
throw e;
}
@ -312,6 +318,9 @@ public final class DamengAgent extends AbstractJdbcAgent {
constraints
);
} catch (RuntimeException e) {
if (isDamengInvalidDatetimeMetadataError(e)) {
return executeJdbcMetadataTables(schema, constraints);
}
if (!isDamengMetadataPermissionError(e)) {
throw e;
}
@ -321,6 +330,9 @@ public final class DamengAgent extends AbstractJdbcAgent {
try {
return executeRawConstrainedTables(schema, constraints);
} catch (RuntimeException e) {
if (isDamengInvalidDatetimeMetadataError(e)) {
return executeJdbcMetadataTables(schema, constraints);
}
if (!isDamengMetadataPermissionError(e)) {
throw e;
}
@ -372,6 +384,21 @@ public final class DamengAgent extends AbstractJdbcAgent {
.replace("%", escape + "%");
}
private static boolean isDamengInvalidDatetimeMetadataError(Throwable error) {
// DM7 ALL_OBJECTS casts SYSOBJINFOS.ALTTIME text to DATETIME and can fail on legacy catalog values.
for (Throwable current = error; current != null; current = current.getCause()) {
if (!(current instanceof SQLException sqlError)) {
continue;
}
for (SQLException candidate = sqlError; candidate != null; candidate = candidate.getNextException()) {
if (candidate.getErrorCode() == -6118) {
return true;
}
}
}
return false;
}
private static boolean isDamengMetadataPermissionError(Throwable error) {
for (Throwable current = error; current != null; current = current.getCause()) {
if (!(current instanceof SQLException sqlError)) {

View File

@ -133,6 +133,31 @@ class DamengAgentMetadataTest {
Assertions.assertEquals(List.of("catalog=null,schema=APP\\_DATA\\%2026,table=%,types=null"), jdbcMetadataCalls);
}
@Test
void fallsBackImmediatelyWhenAllObjectsContainsInvalidDatetimeMetadata() {
DamengAgent agent = new DamengAgent();
List<String> sqls = new ArrayList<>();
List<String> jdbcMetadataCalls = new ArrayList<>();
TestSupport.setPrivateConnection(agent, restrictedTableConnection(
sqls,
jdbcMetadataCalls,
List.of(
List.of("VIEW_B", "VIEW", "view comment"),
List.of("TABLE_A", "TABLE", "table comment"),
List.of("MTAB$_INTERNAL", "TABLE", "internal table")
),
null,
new SQLException("非法的时间日期类型数据", "22015", -6118)
));
MetadataListConstraints constraints = new MetadataListConstraints(null, 20, null, List.of("TABLE"));
List<TableInfo> tables = agent.listTables("APP", constraints);
Assertions.assertEquals(List.of("TABLE_A"), tables.stream().map(TableInfo::getName).toList());
Assertions.assertEquals(1, sqls.size(), String.join("\n", sqls));
Assertions.assertEquals(List.of("catalog=null,schema=APP,table=%,types=null"), jdbcMetadataCalls);
}
@Test
void returnsEmptyWhenRestrictedSchemaJdbcMetadataHasNoTables() {
DamengAgent agent = new DamengAgent();
@ -1054,6 +1079,22 @@ class DamengAgentMetadataTest {
List<List<Object>> rows,
SQLException jdbcMetadataError,
String catalogError
) {
return restrictedTableConnection(
sqls,
jdbcMetadataCalls,
rows,
jdbcMetadataError,
new SQLException(catalogError)
);
}
private static Connection restrictedTableConnection(
List<String> sqls,
List<String> jdbcMetadataCalls,
List<List<Object>> rows,
SQLException jdbcMetadataError,
SQLException catalogError
) {
return proxy(Connection.class, (method, args) -> {
String name = method.getName();
@ -1165,9 +1206,13 @@ class DamengAgentMetadataTest {
}
private static PreparedStatement failingMetadataStatement(String message) {
return failingMetadataStatement(new SQLException(message));
}
private static PreparedStatement failingMetadataStatement(SQLException error) {
return proxy(PreparedStatement.class, (method, args) -> {
if ("executeQuery".equals(method.getName())) {
throw new SQLException(message);
throw error;
}
if ("close".equals(method.getName())) {
return null;