feat(metadata): optimize agent metadata loading

This commit is contained in:
t8y2 committed 2026-07-05 12:09:24 +08:00
1 parent 8883a6b3b7
commit e74782f651
65 files changed
+6192 -571

No files matched your search

@@ -8,12 +8,15 @@ import com.dbx.agent.ForeignKeyInfo;
import com.dbx.agent.IndexInfo;
import com.dbx.agent.JdbcIdentifiers;
import com.dbx.agent.JsonRpcServer;
import com.dbx.agent.MetadataListConstraints;
import com.dbx.agent.MetadataSqlSupport;
import com.dbx.agent.TableInfo;
import com.dbx.agent.TriggerInfo;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public final class BigQueryAgent extends AbstractJdbcAgent {
@@ -70,6 +73,56 @@ public final class BigQueryAgent extends AbstractJdbcAgent {
});
}
@Override
public List<TableInfo> listTables(String schema, MetadataListConstraints constraints) {
MetadataListConstraints normalized = MetadataListConstraints.orNone(constraints);
if (isUnconstrained(normalized)) {
return listTables(schema);
}
if (!normalized.includesTableLikeTypes()) {
return List.of();
}
if (hasLikeWildcard(normalized.getFilter())) {
return normalized.filterTables(listTables(schema));
}
try {
return queryConstrainedTables(schema, normalized);
} catch (RuntimeException e) {
return normalized.filterTables(listTables(schema));
}
}
private List<TableInfo> queryConstrainedTables(String schema, MetadataListConstraints constraints) {
return unchecked(() -> {
List<TableInfo> result = new ArrayList<>();
List<Object> args = new ArrayList<>();
String quotedSchema = JdbcIdentifiers.INSTANCE.backtick(schema);
StringBuilder sql = new StringBuilder("SELECT table_name, table_type FROM ")
.append(quotedSchema)
.append(".INFORMATION_SCHEMA.TABLES WHERE 1 = 1");
appendBigQueryTableTypePredicate(sql, args, constraints);
if (constraints.hasFilter()) {
sql.append(" AND UPPER(table_name) LIKE ?");
args.add(constraints.fuzzyLikePattern().toUpperCase(Locale.ROOT));
}
sql.append(" ORDER BY table_name");
MetadataSqlSupport.appendLiteralLimitOffset(sql, constraints);
try (java.sql.PreparedStatement stmt = requireConnected().prepareStatement(sql.toString())) {
MetadataSqlSupport.bind(stmt, args);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
result.add(new TableInfo(
rs.getString("table_name"),
normalizeTableType(rs.getString("table_type")),
null
));
}
}
}
return constraints.withoutPaging().filterTables(result);
});
}
@Override
public List<ColumnInfo> getColumns(String schema, String table) {
return unchecked(() -> {
@@ -136,7 +189,43 @@ public final class BigQueryAgent extends AbstractJdbcAgent {
}
private static String normalizeTableType(String type) {
return "BASE TABLE".equals(type) ? "TABLE" : type;
if ("BASE TABLE".equals(type)) {
return "TABLE";
}
if ("MATERIALIZED VIEW".equals(type)) {
return "MATERIALIZED_VIEW";
}
return type;
}
private static boolean isUnconstrained(MetadataListConstraints constraints) {
return !constraints.hasFilter() && !constraints.hasLimit() && !constraints.hasOffset() && !constraints.hasObjectTypes();
}
private static void appendBigQueryTableTypePredicate(StringBuilder sql, List<Object> args, MetadataListConstraints constraints) {
if (!constraints.hasObjectTypes()) {
return;
}
List<String> types = new ArrayList<>();
if (constraints.tableTypeAllowed("TABLE")) {
types.add("BASE TABLE");
}
if (constraints.tableTypeAllowed("VIEW")) {
types.add("VIEW");
}
if (constraints.tableTypeAllowed("MATERIALIZED_VIEW")) {
types.add("MATERIALIZED VIEW");
}
if (types.isEmpty()) {
sql.append(" AND 1 = 0");
return;
}
sql.append(" AND table_type IN (").append(MetadataSqlSupport.placeholders(types.size())).append(")");
args.addAll(types);
}
private static boolean hasLikeWildcard(String value) {
return value != null && (value.contains("%") || value.contains("_") || value.contains("\\"));
}
public static void main(String[] args) {
@@ -2,9 +2,11 @@ package com.dbx.agent.bigquery;
import com.dbx.agent.test.TestSupport;
import com.dbx.agent.ConnectParams;
import com.dbx.agent.MetadataListConstraints;
import com.dbx.agent.test.JdbcAgentFake;
import com.dbx.agent.test.JdbcMetadataSqlFake;
import java.sql.Connection;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -46,4 +48,18 @@ class BigQueryAgentMetadataTest {
BigQueryAgent.buildUrl(params)
);
}
@Test
void constrainedTableMetadataPushesFilterTypesAndPaging() {
BigQueryAgent agent = new BigQueryAgent();
TestSupport.setPrivateConnection(agent, JdbcMetadataSqlFake.connection());
agent.listTables("demo`dataset", new MetadataListConstraints("ord", 25, 50, List.of("TABLE", "VIEW")));
String sql = JdbcMetadataSqlFake.statements.get(0);
Assertions.assertTrue(sql.contains("FROM `demo``dataset`.INFORMATION_SCHEMA.TABLES"), sql);
Assertions.assertTrue(sql.contains("table_type IN (?, ?)"), sql);
Assertions.assertTrue(sql.contains("UPPER(table_name) LIKE ?"), sql);
Assertions.assertTrue(sql.endsWith("LIMIT 25 OFFSET 50"), sql);
}
}