fix(dameng): fall back for restricted schema objects
This commit is contained in:
parent
313b1c4b2a
commit
6c41bb4da1
|
|
@ -576,33 +576,66 @@ public final class DamengAgent extends AbstractJdbcAgent {
|
|||
if (!includesSupportedObjectTypes(constraints)) {
|
||||
return List.of();
|
||||
}
|
||||
RuntimeException permissionError;
|
||||
try {
|
||||
return executeConstrainedObjects(schema, buildConstrainedObjectsQuery(schema, constraints), constraints);
|
||||
} catch (RuntimeException e) {
|
||||
if (needsMaterializedViewClassification(constraints)) {
|
||||
try {
|
||||
return executeConstrainedObjects(
|
||||
schema,
|
||||
buildAccessibleConstrainedObjectsQuery(schema, constraints),
|
||||
constraints
|
||||
);
|
||||
} catch (RuntimeException ignored) {
|
||||
// Fall through to owner-local and raw catalog fallbacks.
|
||||
}
|
||||
if (!isDamengMetadataPermissionError(e)) {
|
||||
throw e;
|
||||
}
|
||||
if (needsMaterializedViewClassification(constraints) && schemaMatchesConnectedUser(schema)) {
|
||||
try {
|
||||
return executeConstrainedObjects(
|
||||
schema,
|
||||
buildConstrainedObjectsQuery(schema, constraints, DAMENG_USER_MATERIALIZED_VIEW_JOIN_SQL),
|
||||
constraints
|
||||
);
|
||||
} catch (RuntimeException ignored) {
|
||||
// Fall through to the raw catalog path below.
|
||||
}
|
||||
}
|
||||
return executeRawConstrainedObjects(schema, constraints);
|
||||
permissionError = e;
|
||||
}
|
||||
if (needsMaterializedViewClassification(constraints)) {
|
||||
try {
|
||||
return executeConstrainedObjects(
|
||||
schema,
|
||||
buildAccessibleConstrainedObjectsQuery(schema, constraints),
|
||||
constraints
|
||||
);
|
||||
} catch (RuntimeException e) {
|
||||
if (!isDamengMetadataPermissionError(e)) {
|
||||
throw e;
|
||||
}
|
||||
permissionError.addSuppressed(e);
|
||||
}
|
||||
}
|
||||
if (needsMaterializedViewClassification(constraints) && schemaMatchesConnectedUser(schema)) {
|
||||
try {
|
||||
return executeConstrainedObjects(
|
||||
schema,
|
||||
buildConstrainedObjectsQuery(schema, constraints, DAMENG_USER_MATERIALIZED_VIEW_JOIN_SQL),
|
||||
constraints
|
||||
);
|
||||
} catch (RuntimeException e) {
|
||||
if (!isDamengMetadataPermissionError(e)) {
|
||||
throw e;
|
||||
}
|
||||
permissionError.addSuppressed(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return executeRawConstrainedObjects(schema, constraints);
|
||||
} catch (RuntimeException e) {
|
||||
if (!isDamengMetadataPermissionError(e)) {
|
||||
throw e;
|
||||
}
|
||||
permissionError.addSuppressed(e);
|
||||
}
|
||||
try {
|
||||
return executeJdbcMetadataObjects(schema, constraints);
|
||||
} catch (RuntimeException e) {
|
||||
e.addSuppressed(permissionError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ObjectInfo> executeJdbcMetadataObjects(String schema, MetadataListConstraints constraints) {
|
||||
if (!constraints.includesTableLikeTypes()) {
|
||||
return List.of();
|
||||
}
|
||||
return executeJdbcMetadataTables(schema, constraints).stream()
|
||||
.map(table -> new ObjectInfo(table.getName(), table.getTable_type(), schema, table.getComment()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private List<ObjectInfo> executeConstrainedObjects(
|
||||
|
|
|
|||
|
|
@ -196,6 +196,104 @@ class DamengAgentMetadataTest {
|
|||
Assertions.assertEquals("用户示例表", objects.get(0).getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
void fallsBackToJdbcMetadataForRestrictedSchemaObjects() {
|
||||
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("MV_C", "MATERIALIZED VIEW", "mv comment"),
|
||||
List.of("APP_PROC", "PROCEDURE", "procedure comment"),
|
||||
List.of("MTAB$_INTERNAL", "TABLE", "internal table")
|
||||
),
|
||||
null,
|
||||
"没有[SYS.ALL_OBJECTS]对象的查询权限"
|
||||
));
|
||||
setConnectedUsername(agent, "APP_DATA%2026");
|
||||
|
||||
List<ObjectInfo> objects = agent.listObjects("APP_DATA%2026");
|
||||
|
||||
Assertions.assertEquals(List.of("MV_C", "TABLE_A", "VIEW_B"), objects.stream().map(ObjectInfo::getName).toList());
|
||||
Assertions.assertEquals(List.of("MATERIALIZED_VIEW", "TABLE", "VIEW"), objects.stream().map(ObjectInfo::getObject_type).toList());
|
||||
Assertions.assertEquals(List.of("APP_DATA%2026", "APP_DATA%2026", "APP_DATA%2026"), objects.stream().map(ObjectInfo::getSchema).toList());
|
||||
Assertions.assertEquals(List.of("mv comment", "table comment", "view comment"), objects.stream().map(ObjectInfo::getComment).toList());
|
||||
Assertions.assertEquals(4, sqls.size(), String.join("\n", sqls));
|
||||
Assertions.assertTrue(sqls.stream().allMatch(sql -> sql.contains("ALL_OBJECTS")), String.join("\n", sqls));
|
||||
Assertions.assertEquals(List.of("catalog=null,schema=APP\\_DATA\\%2026,table=%,types=null"), jdbcMetadataCalls);
|
||||
}
|
||||
|
||||
@Test
|
||||
void appliesConstraintsToRestrictedSchemaObjectFallback() {
|
||||
DamengAgent agent = new DamengAgent();
|
||||
TestSupport.setPrivateConnection(agent, restrictedTableConnection(
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
List.of(
|
||||
List.of("VIEW_B", "VIEW", "keep view"),
|
||||
List.of("TABLE_A", "TABLE", "keep table"),
|
||||
List.of("TABLE_Z", "TABLE", "other"),
|
||||
List.of("MV_C", "MATERIALIZED VIEW", "keep materialized view")
|
||||
),
|
||||
null,
|
||||
"no SYS.ALL_OBJECTS privilege"
|
||||
));
|
||||
MetadataListConstraints constraints = new MetadataListConstraints(
|
||||
"keep",
|
||||
1,
|
||||
1,
|
||||
List.of("TABLE", "VIEW")
|
||||
);
|
||||
|
||||
List<ObjectInfo> objects = agent.listObjects("APP", constraints);
|
||||
|
||||
Assertions.assertEquals(1, objects.size());
|
||||
Assertions.assertEquals("VIEW_B", objects.get(0).getName());
|
||||
Assertions.assertEquals("VIEW", objects.get(0).getObject_type());
|
||||
Assertions.assertEquals("keep view", objects.get(0).getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotFallbackForNonPermissionObjectMetadataErrors() {
|
||||
DamengAgent agent = new DamengAgent();
|
||||
List<String> sqls = new ArrayList<>();
|
||||
List<String> jdbcMetadataCalls = new ArrayList<>();
|
||||
TestSupport.setPrivateConnection(agent, restrictedTableConnection(
|
||||
sqls,
|
||||
jdbcMetadataCalls,
|
||||
List.of(),
|
||||
null,
|
||||
"ALL_OBJECTS metadata query timed out"
|
||||
));
|
||||
|
||||
RuntimeException error = Assertions.assertThrows(RuntimeException.class, () -> agent.listObjects("APP"));
|
||||
|
||||
Assertions.assertEquals("ALL_OBJECTS metadata query timed out", error.getCause().getMessage());
|
||||
Assertions.assertEquals(1, sqls.size(), String.join("\n", sqls));
|
||||
Assertions.assertTrue(jdbcMetadataCalls.isEmpty(), jdbcMetadataCalls.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void propagatesJdbcMetadataObjectFallbackErrors() {
|
||||
DamengAgent agent = new DamengAgent();
|
||||
TestSupport.setPrivateConnection(agent, restrictedTableConnection(
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
List.of(),
|
||||
new SQLException("JDBC metadata getTables failed"),
|
||||
"没有[SYS.ALL_OBJECTS]对象的查询权限"
|
||||
));
|
||||
|
||||
RuntimeException error = Assertions.assertThrows(RuntimeException.class, () -> agent.listObjects("APP"));
|
||||
|
||||
Assertions.assertEquals("JDBC metadata getTables failed", error.getCause().getMessage());
|
||||
Assertions.assertEquals(1, error.getSuppressed().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listSchemasIncludesSchemaObjectsWithoutChildren() {
|
||||
DamengAgent agent = new DamengAgent();
|
||||
|
|
|
|||
Loading…
Reference in New Issue