fix(tabs): distinguish structure editors by schema

Closes #6799
This commit is contained in:
t8y2 committed 2026-08-20 13:51:45 +00:00
1 parent c030835acf
commit b0448da0cc
2 files changed
+49 -1

No files matched your search

@@ -122,6 +122,54 @@ describe("queryStore database open state", () => {
expect(store.openTableStructure("doris-1", "sales", undefined, "orders", undefined, undefined, "iceberg_catalog")).toBe(icebergTabId);
});
it("keeps same-name structure editors in different schemas isolated", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const store = useQueryStore();
const publicTabId = store.openTableStructure("pg-1", "app", "public", "users");
const archiveTabId = store.openTableStructure("pg-1", "app", "archive", "users");
expect(archiveTabId).not.toBe(publicTabId);
expect(store.tabs.filter((tab) => tab.mode === "structure")).toHaveLength(2);
expect(store.tabs.find((tab) => tab.id === publicTabId)?.schema).toBe("public");
expect(store.tabs.find((tab) => tab.id === archiveTabId)?.schema).toBe("archive");
expect(store.openTableStructure("pg-1", "app", "public", "users")).toBe(publicTabId);
expect(store.activeTabId).toBe(publicTabId);
});
it("preserves case-sensitive schema and table identities", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const store = useQueryStore();
const quotedTabId = store.openTableStructure("pg-1", "app", "Sales", "Users");
const schemaCaseTabId = store.openTableStructure("pg-1", "app", "sales", "Users");
const tableCaseTabId = store.openTableStructure("pg-1", "app", "Sales", "users");
expect(new Set([quotedTabId, schemaCaseTabId, tableCaseTabId])).toHaveLength(3);
expect(store.openTableStructure("pg-1", "app", "Sales", "Users")).toBe(quotedTabId);
});
it("reuses only matching schema-less structure targets", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const store = useQueryStore();
const schemaLessTabId = store.openTableStructure("mysql-1", "app", undefined, "users");
const reusedTabId = store.openTableStructure("mysql-1", "app", undefined, "users", "columns", { kind: "column", name: "id" });
const explicitSchemaTabId = store.openTableStructure("mysql-1", "app", "public", "users");
const firstCreateTabId = store.openTableStructure("mysql-1", "app", undefined, "");
const secondCreateTabId = store.openTableStructure("mysql-1", "app", undefined, "");
expect(reusedTabId).toBe(schemaLessTabId);
expect(store.tabs.find((tab) => tab.id === schemaLessTabId)).toMatchObject({
schema: undefined,
structureInitialTab: "columns",
structureInitialTabRequestId: 1,
structureInitialTarget: { kind: "column", name: "id" },
});
expect(explicitSchemaTabId).not.toBe(schemaLessTabId);
expect(secondCreateTabId).not.toBe(firstCreateTabId);
});
it("clears the catalog when changing a query tab connection", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const store = useQueryStore();
+1 -1
View File
@@ -2244,7 +2244,7 @@ export const useQueryStore = defineStore("query", () => {
function openTableStructure(connectionId: string, database: string, schema?: string, tableName?: string, initialTab?: TableInfoTab, initialTarget?: TableStructureEditorTarget, catalog?: string) {
const resolvedTableName = tableName || "";
if (resolvedTableName) {
const existing = tabs.value.find((tab) => tab.mode === "structure" && tab.connectionId === connectionId && tab.database === database && (tab.catalog || "") === (catalog || "") && (tab.structureTableName || "") === resolvedTableName);
const existing = tabs.value.find((tab) => tab.mode === "structure" && tab.connectionId === connectionId && tab.database === database && (tab.catalog || "") === (catalog || "") && (tab.schema || "") === (schema || "") && (tab.structureTableName || "") === resolvedTableName);
if (existing) {
applyTableStructureInitialTab(existing, initialTab, initialTarget);
switchTab(existing.id);