1 parent
eccbc5a315
commit
e977e886c3
2 files changed
+43
-3
No files matched your search
@@ -387,6 +387,42 @@ describe("queryStore hidden primary key editing", () => {
|
||||
expect(tab.tableMeta?.schema).toBe("reporting");
|
||||
});
|
||||
|
||||
it("executes a constant projection without waiting for Oracle table metadata", async () => {
|
||||
getConnectionConfig.mockReturnValue({ id: "oracle-1", name: "Oracle", db_type: "oracle", database: "ORCL", query_timeout_secs: 30 });
|
||||
getColumns.mockResolvedValue([{ name: "DUMMY", data_type: "VARCHAR2(1)", is_nullable: true, column_default: null, is_primary_key: false, extra: null }]);
|
||||
listIndexes.mockResolvedValue([]);
|
||||
listTables.mockReturnValue(new Promise(() => undefined));
|
||||
analyzeEditableQueryEditability.mockResolvedValue({
|
||||
editable: true,
|
||||
analysis: {
|
||||
schema: undefined,
|
||||
tableName: "DUAL",
|
||||
selectStar: false,
|
||||
columns: [{ resultName: "1", expression: "1" }],
|
||||
},
|
||||
});
|
||||
const result = [{ columns: ["1"], rows: [[1]], affected_rows: 0, execution_time_ms: 1 }];
|
||||
const executionGate = deferred<typeof result>();
|
||||
executeMulti.mockReturnValue(executionGate.promise);
|
||||
|
||||
const { useQueryStore } = await import("@/stores/queryStore");
|
||||
const store = useQueryStore();
|
||||
const tabId = store.createTab("oracle-1", "ORCL", "Query");
|
||||
store.setAutoCommit(tabId, true);
|
||||
const sql = "SELECT 1 FROM DUAL";
|
||||
|
||||
const execution = store.executeTabSql(tabId, sql);
|
||||
await vi.waitFor(() => expect(executeMulti).toHaveBeenCalled(), { timeout: 250 });
|
||||
|
||||
expect(executeMulti).toHaveBeenCalledWith("oracle-1", "ORCL", sql, undefined, expect.any(String), expect.objectContaining({ timeoutSecs: 30 }));
|
||||
expect(getColumns).not.toHaveBeenCalled();
|
||||
expect(listIndexes).not.toHaveBeenCalled();
|
||||
expect(listTables).not.toHaveBeenCalled();
|
||||
|
||||
executionGate.resolve(result);
|
||||
await execution;
|
||||
});
|
||||
|
||||
it("uses a hidden Oracle ROWID to keep keyless base-table query results editable", async () => {
|
||||
getConnectionConfig.mockReturnValue({ id: "oracle-1", name: "Oracle", db_type: "oracle", database: "ORCL", query_timeout_secs: 30 });
|
||||
getColumns.mockResolvedValue([
|
||||
|
||||
@@ -3958,11 +3958,15 @@ export const useQueryStore = defineStore("query", () => {
|
||||
const analysis = editability.analysis;
|
||||
const sources = editableQuerySources(analysis);
|
||||
if (sources.length !== 1 || analysis.distinct) return unchanged;
|
||||
const source = sources[0]!;
|
||||
const wholeSourceProjected = projectsAllColumnsForSource(analysis, source.key);
|
||||
const hasDirectSourceProjection = analysis.columns.some((column) => Boolean(column.sourceName) && (!column.sourceKey || column.sourceKey === source.key));
|
||||
if (!wholeSourceProjected && !hasDirectSourceProjection) return unchanged;
|
||||
// Whole-source projections already include declared primary keys. Only
|
||||
// Oracle needs preflight metadata here to add ROWID for a keyless table.
|
||||
if (databaseType !== "oracle" && projectsAllColumnsForSource(analysis, sources[0]!.key)) return unchanged;
|
||||
if (databaseType !== "oracle" && wholeSourceProjected) return unchanged;
|
||||
|
||||
const target = resolveEditableSourceMetadataTarget(tab, analysis, sources[0]!, conn, databaseType, executionDatabase);
|
||||
const target = resolveEditableSourceMetadataTarget(tab, analysis, source, conn, databaseType, executionDatabase);
|
||||
const cached = getCachedTableMetadata(target.request);
|
||||
let loaded = cached ? loadedEditableSourceFromMetadata(target, cached.metadata) : undefined;
|
||||
if (!cached && databaseType === "oracle") {
|
||||
@@ -3981,7 +3985,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
loaded = loadedEditableSourceFromMetadata(target, (await fullMetadataPromise).metadata);
|
||||
}
|
||||
|
||||
loaded ??= await loadEditableQuerySource(tab, analysis, sources[0]!, conn, databaseType, executionDatabase, traceId, elapsed);
|
||||
loaded ??= await loadEditableQuerySource(tab, analysis, source, conn, databaseType, executionDatabase, traceId, elapsed);
|
||||
if (loaded.tableMeta.columns.length === 0) return unchanged;
|
||||
if (loaded.tableMeta.tableType?.toUpperCase().includes("VIEW")) return unchanged;
|
||||
const columnPrimaryKeys = loaded.tableMeta.columns.filter((column) => column.is_primary_key).map((column) => column.name);
|
||||
|
||||
Reference in new issue
Block a user