fix(hana): show tables under schemas
This commit is contained in:
1 parent
562edef4dc
commit
b121240b2f
3 files changed
+140
-9
No files matched your search
@@ -123,12 +123,12 @@ public final class StandardJdbcMetadata {
|
||||
listObjects(listTables(conn, profile, configuredDatabase, schema, tableConstraints), schema)
|
||||
);
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
appendRoutines(result, meta, null, blankToNull(schema), schema);
|
||||
appendRoutines(result, meta, null, schema, schema);
|
||||
if (!containsRoutine(result)
|
||||
&& profile.getCatalogFallbackEnabled()
|
||||
&& configuredDatabase != null
|
||||
&& !configuredDatabase.trim().isEmpty()) {
|
||||
appendRoutines(result, meta, configuredDatabase, blankToNull(schema), schema);
|
||||
appendRoutines(result, meta, configuredDatabase, schema, schema);
|
||||
}
|
||||
result.sort(Comparator.comparing(ObjectInfo::getName));
|
||||
return normalized.filterObjects(result);
|
||||
@@ -332,7 +332,9 @@ public final class StandardJdbcMetadata {
|
||||
return;
|
||||
}
|
||||
// JDBC has no portable metadata limit/offset. Use table types for safe pushdown and filter/page locally.
|
||||
try (ResultSet rs = meta.getTables(catalog, blankToNull(schema), "%", tableTypes)) {
|
||||
// schema 是 DatabaseMetaData.getTables() 的 schemaPattern,_ 和 % 具有通配符语义;
|
||||
// HANA 存在 _SYS_RT 等含下划线的 schema,需按 getSearchStringEscape() 转义,避免混入其他 schema 的对象。
|
||||
try (ResultSet rs = meta.getTables(catalog, escapeSchemaPattern(meta, schema), "%", tableTypes)) {
|
||||
while (rs.next()) {
|
||||
result.add(new TableInfo(
|
||||
rs.getString("TABLE_NAME"),
|
||||
@@ -618,16 +620,18 @@ public final class StandardJdbcMetadata {
|
||||
List<ObjectInfo> result,
|
||||
DatabaseMetaData meta,
|
||||
String catalog,
|
||||
String schemaPattern,
|
||||
String schema
|
||||
String schema,
|
||||
String schemaLabel
|
||||
) {
|
||||
// schema 作为 getProcedures/getFunctions 的 schemaPattern,同样需要转义 _ 和 % 通配符。
|
||||
String schemaPattern = escapeSchemaPattern(meta, 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")));
|
||||
result.add(new ObjectInfo(name, "PROCEDURE", schemaLabel, rs.getString("REMARKS")));
|
||||
}
|
||||
}
|
||||
} catch (Exception | AbstractMethodError ignored) {
|
||||
@@ -637,7 +641,7 @@ public final class StandardJdbcMetadata {
|
||||
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")));
|
||||
result.add(new ObjectInfo(name, "FUNCTION", schemaLabel, rs.getString("REMARKS")));
|
||||
}
|
||||
}
|
||||
} catch (Exception | AbstractMethodError ignored) {
|
||||
@@ -676,6 +680,38 @@ public final class StandardJdbcMetadata {
|
||||
return value == null || value.trim().isEmpty() ? null : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 schema 名转义为可安全用作 {@link DatabaseMetaData#getTables(String, String, String, String[])}
|
||||
* 等 schemaPattern 参数的形式。
|
||||
*
|
||||
* <p>JDBC 的 schemaPattern 把 {@code _}(匹配任意单字符)和 {@code %}(匹配任意字符序列)当作通配符。
|
||||
* 当 schema 名本身含有这些字符时(例如 HANA 的 {@code _SYS_RT}、{@code _SYS_BIC},或被引号引用的含
|
||||
* {@code %} 的 schema),直接作为 schemaPattern 传入会误匹配到其他 schema 的对象。参考 DBeaver 的
|
||||
* {@code JDBCUtils.escapeWildCards()},按 {@link DatabaseMetaData#getSearchStringEscape()} 对通配符做转义。
|
||||
*
|
||||
* <p>当 schema 为空白(将映射为 {@code null},表示不做 schema 过滤)或驱动未提供转义字符时,原样返回。
|
||||
*/
|
||||
private static String escapeSchemaPattern(DatabaseMetaData meta, String schema) {
|
||||
String normalized = blankToNull(schema);
|
||||
if (normalized == null) {
|
||||
return null;
|
||||
}
|
||||
String escape;
|
||||
try {
|
||||
escape = meta.getSearchStringEscape();
|
||||
} catch (Exception ignored) {
|
||||
escape = null;
|
||||
}
|
||||
if (escape == null || escape.isEmpty()) {
|
||||
return normalized;
|
||||
}
|
||||
// 先转义 escape 自身,再转义 % 和 _,顺序与 PreparedStatement.setEscapeProcessing / DBeaver 一致。
|
||||
String escapedEscape = normalized.replace(escape, escape + escape);
|
||||
String escapedPercent = escapedEscape.replace("%", escape + "%");
|
||||
String escapedUnderscore = escapedPercent.replace("_", escape + "_");
|
||||
return escapedUnderscore;
|
||||
}
|
||||
|
||||
private static void addNonBlank(Set<String> values, String value) {
|
||||
if (value != null && !value.trim().isEmpty()) {
|
||||
values.add(value);
|
||||
|
||||
Reference in new issue
Block a user