From 8e55130ee28c82acd16930a81571d91e2e8e0340 Mon Sep 17 00:00:00 2001 From: efeire <15682810+efeire@users.noreply.github.com> Date: Fri, 9 Oct 2026 18:11:02 +0800 Subject: [PATCH] fix(oceanbase): retain LOB refs until their owning result closes --- apps/desktop/src/composables/useDataGridLargeValues.ts | 5 ----- apps/desktop/src/stores/queryStore.ts | 10 ++++++---- apps/desktop/src/types/database.ts | 2 ++ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/desktop/src/composables/useDataGridLargeValues.ts b/apps/desktop/src/composables/useDataGridLargeValues.ts index 1b1771c3e9..0363f1c8df 100644 --- a/apps/desktop/src/composables/useDataGridLargeValues.ts +++ b/apps/desktop/src/composables/useDataGridLargeValues.ts @@ -610,11 +610,6 @@ export function useDataGridLargeValues(options: UseDataGridLargeValuesOptions) { const rows = sourceResult.rows.slice(); rows[item.sourceIndex!] = row; sourceResult.rows = rows; - const snapshotRef = sourceResult.large_value_cells?.find((cell) => cell.row_index === item.sourceIndex && cell.column_index === columnIndex)?.value_ref; - if (snapshotRef && sourceResult.large_value_context) { - void api.releaseLargeValue({ ...sourceResult.large_value_context, valueRef: snapshotRef }) - .catch((error) => options.appendDebugLog("warn", "[DBX][DataGrid:large-value] release failed", error)); - } visibleLargeValuePreviewCaches.get(sourceResult)?.forget(item.sourceIndex!, columnIndex); sourceResult.large_value_cells = sourceResult.large_value_cells?.filter((cell) => cell.row_index !== item.sourceIndex || cell.column_index !== columnIndex); options.largeValueResolutionVersion.value += 1; diff --git a/apps/desktop/src/stores/queryStore.ts b/apps/desktop/src/stores/queryStore.ts index de81bb0576..fca21d9a12 100644 --- a/apps/desktop/src/stores/queryStore.ts +++ b/apps/desktop/src/stores/queryStore.ts @@ -2137,11 +2137,12 @@ export const useQueryStore = defineStore("query", () => { for (const result of results) { const context = result?.large_value_context; if (!context) continue; - for (const cell of result.large_value_cells ?? []) { - if (!cell.value_ref || released.has(cell.value_ref)) continue; - released.add(cell.value_ref); + const refs = new Set([...(result.large_value_refs ?? []), ...(result.large_value_cells ?? []).flatMap((cell) => cell.value_ref ? [cell.value_ref] : [])]); + for (const valueRef of refs) { + if (released.has(valueRef)) continue; + released.add(valueRef); try { - await api.releaseLargeValue({ ...context, valueRef: cell.value_ref }); + await api.releaseLargeValue({ ...context, valueRef }); } catch (error) { console.warn("[DBX][large-value:release:error]", error); } @@ -8212,6 +8213,7 @@ export const useQueryStore = defineStore("query", () => { }]; } if (result.large_value_cells?.some((cell) => cell.value_ref)) { + result.large_value_refs = result.large_value_cells.flatMap((cell) => cell.value_ref ? [cell.value_ref] : []); result.large_value_context = { connectionId: executionConnectionId, database: executionDatabase, clientSessionId: executionClientSessionId, txnSessionId: tab.autoCommit === false ? tab.txnSessionId : undefined, diff --git a/apps/desktop/src/types/database.ts b/apps/desktop/src/types/database.ts index 4e23b265da..d203eb0f6d 100644 --- a/apps/desktop/src/types/database.ts +++ b/apps/desktop/src/types/database.ts @@ -1394,6 +1394,8 @@ export interface QueryResult { large_value_cells?: Array<{ row_index: number; column_index: number; original_bytes: number; value_ref?: string }>; /** Frontend-only original result connection, independent of the currently active tab. */ large_value_context?: { connectionId: string; database: string; clientSessionId?: string; txnSessionId?: string; catalog?: string }; + /** Retained result refs also cover cells already hydrated into complete local values. */ + large_value_refs?: string[]; session_id?: string | null; has_more?: boolean; /** For Elasticsearch REST search results parsed into a _source table,