feat(grid): inherit physical column formatting in query results
This commit is contained in:
19 files changed
+329
-53
No files matched your search
@@ -115,7 +115,7 @@ describe("queryStore grouped-result column comments", () => {
|
||||
// Only the directly projected physical column carries its comment; the
|
||||
// aggregate expression resolves to nothing and must not guess.
|
||||
expect(tab.resultColumnComments).toEqual(["所属部门", undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "users:0", sourceColumn: "department" }, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "users:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" }, undefined]);
|
||||
});
|
||||
|
||||
it("resolves aliased grouped columns back to their physical column (T2)", async () => {
|
||||
@@ -139,7 +139,7 @@ describe("queryStore grouped-result column comments", () => {
|
||||
await vi.waitFor(() => expect(tab.resultColumnComments).toBeDefined());
|
||||
expect(tab.queryEditabilityReason).toBe("aggregation");
|
||||
expect(tab.resultColumnComments).toEqual(["所属部门", undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "users:0", sourceColumn: "department" }, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "users:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" }, undefined]);
|
||||
});
|
||||
|
||||
it("keeps comments for HAVING queries (T3)", async () => {
|
||||
@@ -186,7 +186,7 @@ describe("queryStore grouped-result column comments", () => {
|
||||
await vi.waitFor(() => expect(tab.resultColumnComments).toBeDefined());
|
||||
expect(tab.queryEditabilityReason).toBe("aggregation");
|
||||
expect(tab.resultColumnComments).toEqual(["所属部门", undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "department" }, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" }, undefined]);
|
||||
});
|
||||
|
||||
it("maps multiple grouped physical columns (T5)", async () => {
|
||||
@@ -236,7 +236,7 @@ describe("queryStore grouped-result column comments", () => {
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([undefined, undefined]);
|
||||
});
|
||||
|
||||
it("keeps ordinary editable queries free of the new display fields (T10)", async () => {
|
||||
it("stores physical source identities for ordinary editable queries (T10)", async () => {
|
||||
analyzeEditableQueryEditability.mockResolvedValue({
|
||||
editable: true,
|
||||
analysis: {
|
||||
@@ -268,7 +268,10 @@ describe("queryStore grouped-result column comments", () => {
|
||||
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||
await vi.waitFor(() => expect(tab.tableMeta?.tableName).toBe("users"));
|
||||
expect(tab.resultColumnComments).toBeUndefined();
|
||||
expect(tab.queryDisplaySourceColumns).toBeUndefined();
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "users:0", sourceColumn: "id", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "users:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" },
|
||||
]);
|
||||
expect(tab.querySourceColumns).toEqual(["id", "department"]);
|
||||
});
|
||||
|
||||
|
||||
+18
-14
@@ -137,12 +137,13 @@ describe("queryStore multi-source result column comments", () => {
|
||||
// keeps its own comment instead of first-source-wins on the name.
|
||||
expect(tab.resultColumnComments).toEqual(["订单ID", "下单用户", "用户ID", "用户名"]);
|
||||
|
||||
// The display mapping carries source identity per ordinal.
|
||||
// The display mapping carries both source identity and physical table
|
||||
// identity per ordinal, so display-only features can share table settings.
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "a", sourceColumn: "id" },
|
||||
{ sourceKey: "a", sourceColumn: "user_id" },
|
||||
{ sourceKey: "b", sourceColumn: "id" },
|
||||
{ sourceKey: "b", sourceColumn: "name" },
|
||||
{ sourceKey: "a", sourceColumn: "id", database: "app", schema: "app", tableName: "orders" },
|
||||
{ sourceKey: "a", sourceColumn: "user_id", database: "app", schema: "app", tableName: "orders" },
|
||||
{ sourceKey: "b", sourceColumn: "id", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "b", sourceColumn: "name", database: "app", schema: "app", tableName: "users" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -187,8 +188,8 @@ describe("queryStore multi-source result column comments", () => {
|
||||
await vi.waitFor(() => expect(tab.resultColumnComments).toBeDefined());
|
||||
expect(tab.resultColumnComments).toEqual(["订单ID", "用户名"]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "a", sourceColumn: "id" },
|
||||
{ sourceKey: "b", sourceColumn: "name" },
|
||||
{ sourceKey: "a", sourceColumn: "id", database: "app", schema: "app", tableName: "orders" },
|
||||
{ sourceKey: "b", sourceColumn: "name", database: "app", schema: "app", tableName: "users" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -279,9 +280,9 @@ describe("queryStore multi-source result column comments", () => {
|
||||
// of the previous map would have collapsed them.
|
||||
expect(tab.resultColumnComments).toEqual(["订单ID", "大写ID", "大写Name"]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "a", sourceColumn: "id" },
|
||||
{ sourceKey: "a", sourceColumn: "ID" },
|
||||
{ sourceKey: "b", sourceColumn: "Name" },
|
||||
{ sourceKey: "a", sourceColumn: "id", database: "app", schema: undefined, tableName: "orders" },
|
||||
{ sourceKey: "a", sourceColumn: "ID", database: "app", schema: undefined, tableName: "orders" },
|
||||
{ sourceKey: "b", sourceColumn: "Name", database: "app", schema: undefined, tableName: "users" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -326,12 +327,12 @@ describe("queryStore multi-source result column comments", () => {
|
||||
await vi.waitFor(() => expect(tab.resultColumnComments).toBeDefined());
|
||||
expect(tab.resultColumnComments).toEqual(["订单ID", "用户ID"]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "a", sourceColumn: "id" },
|
||||
{ sourceKey: "b", sourceColumn: "id" },
|
||||
{ sourceKey: "a", sourceColumn: "id", database: "app", schema: "app", tableName: "orders" },
|
||||
{ sourceKey: "b", sourceColumn: "id", database: "app", schema: "app", tableName: "users" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps single-source results free of multi-source comment fields", async () => {
|
||||
it("stores physical source identities for single-source result columns", async () => {
|
||||
analyzeEditableQueryEditability.mockResolvedValue({
|
||||
editable: true,
|
||||
analysis: {
|
||||
@@ -363,7 +364,10 @@ describe("queryStore multi-source result column comments", () => {
|
||||
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||
await vi.waitFor(() => expect(tab.tableMeta?.tableName).toBe("orders"));
|
||||
expect(tab.resultColumnComments).toBeUndefined();
|
||||
expect(tab.queryDisplaySourceColumns).toBeUndefined();
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "orders:0", sourceColumn: "id", database: "app", schema: "app", tableName: "orders" },
|
||||
{ sourceKey: "orders:0", sourceColumn: "amount", database: "app", schema: "app", tableName: "orders" },
|
||||
]);
|
||||
expect(tab.querySourceColumns).toEqual(["id", "amount"]);
|
||||
});
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ describe("queryStore MySQL grouped-result editing", () => {
|
||||
expect(tab.querySourceColumns).toEqual(["id", "department", undefined]);
|
||||
expect(tab.tableMeta).toMatchObject({ tableName: "users", primaryKeys: ["id"] });
|
||||
expect(tab.resultColumnComments).toEqual(["user id", "department", undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "id" }, { sourceKey: "u:0", sourceColumn: "department" }, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "id", database: "app", schema: "app", tableName: "users" }, { sourceKey: "u:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" }, undefined]);
|
||||
expect(listIndexes).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -124,7 +124,12 @@ describe("queryStore MySQL grouped-result editing", () => {
|
||||
|
||||
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||
expect(tab.querySourceColumns).toEqual(["id", "department", undefined, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "id" }, { sourceKey: "u:0", sourceColumn: "department" }, { sourceKey: "o:1", sourceColumn: "user_id" }, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "u:0", sourceColumn: "id", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "u:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "o:1", sourceColumn: "user_id", database: "app", schema: "app", tableName: "orders" },
|
||||
undefined,
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps a non-root source read-only even when its complete primary key is grouped", async () => {
|
||||
@@ -199,7 +204,14 @@ describe("queryStore MySQL grouped-result editing", () => {
|
||||
|
||||
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||
expect(tab.querySourceColumns).toEqual(["id", "department", undefined, undefined, undefined, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([{ sourceKey: "u:0", sourceColumn: "id" }, { sourceKey: "u:0", sourceColumn: "department" }, { sourceKey: "u:0", sourceColumn: "display_label" }, { sourceKey: "u:0", sourceColumn: "stored_label" }, undefined, undefined]);
|
||||
expect(tab.queryDisplaySourceColumns).toEqual([
|
||||
{ sourceKey: "u:0", sourceColumn: "id", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "u:0", sourceColumn: "department", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "u:0", sourceColumn: "display_label", database: "app", schema: "app", tableName: "users" },
|
||||
{ sourceKey: "u:0", sourceColumn: "stored_label", database: "app", schema: "app", tableName: "users" },
|
||||
undefined,
|
||||
undefined,
|
||||
]);
|
||||
});
|
||||
|
||||
it("accepts a complete composite primary key only when it is the exact grouping key", async () => {
|
||||
|
||||
@@ -3844,7 +3844,12 @@ export const useQueryStore = defineStore("query", () => {
|
||||
const loaded = loadedSources.find((entry) => entry.source.key === ref.sourceKey);
|
||||
const comment = loaded?.tableMeta.columns.find((column) => column.name === ref.sourceColumn)?.comment?.trim();
|
||||
comments.push(comment || undefined);
|
||||
mapping.push(ref);
|
||||
mapping.push({
|
||||
...ref,
|
||||
database: loaded?.tableMeta.database,
|
||||
schema: loaded?.tableMeta.schema,
|
||||
tableName: loaded?.tableMeta.tableName,
|
||||
});
|
||||
}
|
||||
return { comments, mapping };
|
||||
}
|
||||
@@ -4335,7 +4340,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
const metadataAnalysis = expandStarProjectionColumnsForSource(bindColumnsForSource(dbType, loaded.analysis, loaded.source, loaded.tableMeta.columns, allSourceColumns), loaded.source, loaded.tableMeta.columns);
|
||||
const syntheticRowIdProjection = hiddenPrimaryKeys.find((projection) => projection.sourceName.toUpperCase() === DBX_ROWID_COLUMN);
|
||||
const primaryKeys = loaded.tableMeta.primaryKeys.length === 0 && syntheticRowIdProjection ? [DBX_ROWID_COLUMN] : loaded.tableMeta.primaryKeys;
|
||||
const keylessResultInfo = primaryKeys.length === 0 ? resolveResultColumnInfo(dbType, analysis, tab.result.columns, loadedSources) : undefined;
|
||||
const displaySourceInfo = resolveResultColumnInfo(dbType, analysis, tab.result.columns, loadedSources);
|
||||
const sourceColumns = sourceColumnsForResult(metadataAnalysis, tab.result.columns, loaded.source.key);
|
||||
if (sourceColumns && syntheticRowIdProjection) {
|
||||
const resultIndex = tab.result.columns.findIndex((column) => column.toLowerCase() === syntheticRowIdProjection.alias.toLowerCase());
|
||||
@@ -4347,7 +4352,8 @@ export const useQueryStore = defineStore("query", () => {
|
||||
querySourceColumns: undefined,
|
||||
queryEditabilityReason: "no-primary-key",
|
||||
tableMeta: loaded.tableMeta,
|
||||
resultColumnComments: keylessResultInfo?.comments,
|
||||
resultColumnComments: displaySourceInfo.comments,
|
||||
queryDisplaySourceColumns: displaySourceInfo.mapping,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4358,6 +4364,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
querySourceColumns: undefined,
|
||||
queryEditabilityReason: "primary-key-not-returned",
|
||||
tableMeta: loaded.tableMeta,
|
||||
queryDisplaySourceColumns: displaySourceInfo.mapping,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4367,6 +4374,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
querySourceColumns: undefined,
|
||||
queryEditabilityReason: "aliased-columns",
|
||||
tableMeta: loaded.tableMeta,
|
||||
queryDisplaySourceColumns: displaySourceInfo.mapping,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4375,7 +4383,8 @@ export const useQueryStore = defineStore("query", () => {
|
||||
querySourceColumns: sourceColumns,
|
||||
queryEditabilityReason: undefined,
|
||||
tableMeta: primaryKeys === loaded.tableMeta.primaryKeys ? loaded.tableMeta : { ...loaded.tableMeta, primaryKeys },
|
||||
resultColumnComments: keylessResultInfo?.comments,
|
||||
resultColumnComments: primaryKeys.length === 0 ? displaySourceInfo.comments : undefined,
|
||||
queryDisplaySourceColumns: displaySourceInfo.mapping,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user