fix(jdbc): include routines in object metadata

This commit is contained in:
t8y2 committed 2026-07-11 09:21:17 +08:00
1 parent 5d5f7feb4a
commit fda65621e2
3 files changed
+134 -5

No files matched your search

@@ -73,15 +73,24 @@ public abstract class ConfiguredJdbcAgent extends AbstractJdbcAgent {
@Override
public List<ObjectInfo> listObjects(String schema) {
return StandardJdbcMetadata.INSTANCE.listObjects(listTables(schema), schema);
return StandardJdbcMetadata.INSTANCE.listObjects(
requireConnection(),
profile,
configuredDatabase,
schema,
MetadataListConstraints.NONE
);
}
@Override
public List<ObjectInfo> listObjects(String schema, MetadataListConstraints constraints) {
MetadataListConstraints normalized = MetadataListConstraints.orNone(constraints);
MetadataListConstraints tableConstraints =
new MetadataListConstraints(normalized.getFilter(), null, null, normalized.getObjectTypes());
return StandardJdbcMetadata.INSTANCE.listObjects(listTables(schema, tableConstraints), schema, normalized);
return StandardJdbcMetadata.INSTANCE.listObjects(
requireConnection(),
profile,
configuredDatabase,
schema,
constraints
);
}
@Override
@@ -108,6 +108,33 @@ public final class StandardJdbcMetadata {
return MetadataListConstraints.orNone(constraints).filterObjects(result);
}
public List<ObjectInfo> listObjects(
Connection conn,
JdbcAgentProfile profile,
String configuredDatabase,
String schema,
MetadataListConstraints constraints
) {
return unchecked(() -> {
MetadataListConstraints normalized = MetadataListConstraints.orNone(constraints);
MetadataListConstraints tableConstraints =
new MetadataListConstraints(normalized.getFilter(), null, null, normalized.getObjectTypes());
List<ObjectInfo> result = new ArrayList<>(
listObjects(listTables(conn, profile, configuredDatabase, schema, tableConstraints), schema)
);
DatabaseMetaData meta = conn.getMetaData();
appendRoutines(result, meta, null, blankToNull(schema), schema);
if (!containsRoutine(result)
&& profile.getCatalogFallbackEnabled()
&& configuredDatabase != null
&& !configuredDatabase.trim().isEmpty()) {
appendRoutines(result, meta, configuredDatabase, blankToNull(schema), schema);
}
result.sort(Comparator.comparing(ObjectInfo::getName));
return normalized.filterObjects(result);
});
}
public List<String> listDataTypes(Connection conn) {
return unchecked(() -> {
Set<String> seen = new LinkedHashSet<>();
@@ -587,6 +614,47 @@ public final class StandardJdbcMetadata {
return type;
}
private static void appendRoutines(
List<ObjectInfo> result,
DatabaseMetaData meta,
String catalog,
String schemaPattern,
String schema
) {
Set<String> procedureNames = new LinkedHashSet<>();
try (ResultSet rs = meta.getProcedures(catalog, schemaPattern, "%")) {
while (rs.next()) {
String name = rs.getString("PROCEDURE_NAME");
if (name != null && !name.trim().isEmpty()) {
procedureNames.add(name);
result.add(new ObjectInfo(name, "PROCEDURE", schema, rs.getString("REMARKS")));
}
}
} catch (Exception | AbstractMethodError ignored) {
// Some JDBC drivers don't implement routine metadata.
}
try (ResultSet rs = meta.getFunctions(catalog, schemaPattern, "%")) {
while (rs.next()) {
String name = rs.getString("FUNCTION_NAME");
if (name != null && !name.trim().isEmpty() && !procedureNames.contains(name)) {
result.add(new ObjectInfo(name, "FUNCTION", schema, rs.getString("REMARKS")));
}
}
} catch (Exception | AbstractMethodError ignored) {
// Some JDBC drivers don't implement function metadata separately.
}
}
private static boolean containsRoutine(List<ObjectInfo> objects) {
for (ObjectInfo object : objects) {
if ("PROCEDURE".equalsIgnoreCase(object.getObject_type())
|| "FUNCTION".equalsIgnoreCase(object.getObject_type())) {
return true;
}
}
return false;
}
private static Integer intOrNull(ResultSet rs, String column) throws Exception {
Object value = rs.getObject(column);
return value instanceof Number ? ((Number) value).intValue() : null;