fix(mysql): refresh stale snapshots and streamline table reloads
This commit is contained in:
11 files changed
+911
-54
No files matched your search
@@ -55,6 +55,20 @@ describe("tableMetadataCache columns facet request counts", () => {
|
||||
mocks.listIndexes.mockResolvedValue([]);
|
||||
});
|
||||
|
||||
it("does not treat failed index discovery as a complete cacheable row identity", async () => {
|
||||
mocks.getColumns.mockResolvedValue([{ ...column("id"), is_primary_key: false }]);
|
||||
mocks.listIndexes.mockRejectedValueOnce(new Error("indexes unavailable"));
|
||||
const failed = await loadTableMetadata(usersRequest);
|
||||
expect(failed.metadata.rowIdentityResolved).toBe(false);
|
||||
expect(failed.metadata.primaryKeys).toEqual([]);
|
||||
expect(getCachedTableMetadata(usersRequest)).toBeUndefined();
|
||||
|
||||
const retried = await loadTableMetadata(usersRequest);
|
||||
expect(retried.metadata.rowIdentityResolved).toBe(true);
|
||||
expect(mocks.listIndexes).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.getColumns).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("R1 — cold single-source columns load: 1 getColumns, 0 listIndexes", async () => {
|
||||
const result = await loadTableColumns({ ...usersRequest });
|
||||
expect(result.columns[0]?.name).toBe("users");
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface TableMetadata {
|
||||
columns: ColumnInfo[];
|
||||
indexes: IndexInfo[];
|
||||
primaryKeys: string[];
|
||||
rowIdentityResolved?: boolean;
|
||||
cachedAt: number;
|
||||
}
|
||||
|
||||
@@ -331,11 +332,16 @@ export async function loadTableMetadata(request: TableMetadataRequest): Promise<
|
||||
// discovery independently unless an agent-backed PostgreSQL-family
|
||||
// relation must first report its visible schema for the index lookup.
|
||||
const resolveReportedSchema = (request.databaseType === "vastbase" || request.databaseType === "kingbase") && !request.schema;
|
||||
const indexesPromise = resolveReportedSchema ? undefined : loadTableIndexes(request).catch((): IndexInfo[] => []);
|
||||
let rowIdentityResolved = true;
|
||||
const indexFailure = (): IndexInfo[] => {
|
||||
rowIdentityResolved = false;
|
||||
return [];
|
||||
};
|
||||
const indexesPromise = resolveReportedSchema ? undefined : loadTableIndexes(request).catch(indexFailure);
|
||||
const columnsResult = await columnsPromise;
|
||||
const columns = columnsResult.columns;
|
||||
const resolvedSchema = resolveReportedSchema ? columns.find((column) => column.resolved_schema)?.resolved_schema : request.schema;
|
||||
const indexes = columns.length > 0 ? await (indexesPromise ?? loadTableIndexes({ ...request, schema: resolvedSchema }).catch((): IndexInfo[] => [])) : [];
|
||||
const indexes = columns.length > 0 ? await (indexesPromise ?? loadTableIndexes({ ...request, schema: resolvedSchema }).catch(indexFailure)) : [];
|
||||
const primaryKeys = editableRowIdentifierColumns(request.databaseType as DatabaseType, columns, indexes, request.tableType);
|
||||
return {
|
||||
schema: resolvedSchema || undefined,
|
||||
@@ -346,6 +352,7 @@ export async function loadTableMetadata(request: TableMetadataRequest): Promise<
|
||||
columns,
|
||||
indexes,
|
||||
primaryKeys,
|
||||
rowIdentityResolved: rowIdentityResolved && columns.length > 0,
|
||||
cachedAt: columnsResult.cachedAt,
|
||||
};
|
||||
},
|
||||
@@ -353,7 +360,7 @@ export async function loadTableMetadata(request: TableMetadataRequest): Promise<
|
||||
);
|
||||
|
||||
// 必须在 unregister 前比较:最后一个在途加载注销时会顺带清掉代数记录
|
||||
if (invalidationStampAtStart === (tableMetadataInvalidationStamps.get(scopeKey) ?? 0)) {
|
||||
if (metadata.rowIdentityResolved && invalidationStampAtStart === (tableMetadataInvalidationStamps.get(scopeKey) ?? 0)) {
|
||||
tableMetadataCache.set(scope, metadata, { cachedAt: metadata.cachedAt });
|
||||
}
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user