feat(metadata): optimize agent metadata loading
This commit is contained in:
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) {
|
||||
|
||||
+16
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user