fix(xugu): enable safe row editing without primary keys

This commit is contained in:
Elias authored and GitHub committed 2026-09-07 22:44:30 +08:00
1 parent 39b2d2a6ac
commit 3e75be87eb
17 files changed
+236 -50

No files matched your search

@@ -112,7 +112,7 @@ import {
isClickHouseExistingRowReadonlyColumn,
isHiddenGridColumn,
isTdengineExistingRowReadonlyColumn,
usesSyntheticRowIdKey,
shouldIncludeSyntheticRowId,
} from "@/lib/table/tableEditing";
import { buildDataGridColumnDistinctValuesSql, buildDataGridConditionalUpdateSql, buildDataGridContextFilterCondition, buildDataGridCountSql, buildHiveTablePropertiesSql, type DataGridContextFilterMode } from "@/lib/dataGrid/dataGridSql";
import {
@@ -4349,7 +4349,7 @@ async function refreshSavedRows(request: { dirtyRows: ReadonlyMap<number, Readon
...tableDataLargeValuePreviewOptions(resolvedDatabaseType.value, tableMeta.columns, tableMeta.primaryKeys, pageSize.value),
whereInput: identityConditions.join(" OR "),
limit: planResult.plan.sourceIndexes.length + 1,
includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
});
const refreshed = await api.executeQuery(connectionId, props.executionDatabase ?? props.database ?? "", sql, tableMeta.schema ?? props.schema, undefined, {
maxRows: planResult.plan.sourceIndexes.length + 1,
@@ -5542,7 +5542,7 @@ async function hydrateVisibleLargeValuePreviews(generation: number) {
whereInput: predicates.map((predicate) => `(${predicate})`).join(" OR "),
limit: requests.size,
offset: 0,
includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
});
if (!visibleLargeValuePreviewActive || generation !== visibleLargeValuePreviewRequestedGeneration || props.result !== sourceResult) return;
const connection = connectionStore.getConfig(props.connectionId);
@@ -5709,7 +5709,7 @@ async function fetchLargeValueRequestChunk(columnIndex: number, requests: LargeV
whereInput: predicates.map((predicate) => `(${predicate})`).join(" OR "),
limit: requests.length,
offset: 0,
includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
});
const connection = props.connectionId ? connectionStore.getConfig(props.connectionId) : undefined;
const results = await api.executeMulti(props.connectionId!, props.executionDatabase ?? props.database ?? "", sql, undefined, uuid(), {
@@ -7120,7 +7120,7 @@ async function applyOrderBySearch() {
injectDefaultTimeSeriesWhere: true,
limit: pageSize.value,
whereInput: currentWhereInput(),
includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
});
markConditionInputsApplied();
await props.onExecuteSql(sql);
@@ -7159,7 +7159,7 @@ async function applyWhereFilter() {
limit: pageSize.value,
injectDefaultTimeSeriesWhere: true,
whereInput,
includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType),
});
markConditionInputsApplied();
await props.onExecuteSql(sql);
@@ -18,12 +18,12 @@ describe("DataGrid large-value reload SQL", () => {
// Keyless Oracle tables address rows via the hidden __DBX_ROWID alias; the
// reload must opt into the ROWIDTOCHAR inline view so the generated SQL
// never references __DBX_ROWID as a base-table column (ORA-00904).
expect(fetchChunkSource).toContain("includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType)");
expect(fetchChunkSource).toContain("includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType)");
});
it("keeps the visible-preview hydration consistent with the synthetic key", () => {
const hydrateSource = functionSource("hydrateVisibleLargeValuePreviews", "runVisibleLargeValuePreviewHydration");
expect(hydrateSource).toContain("includeRowId: usesSyntheticRowIdKey(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType)");
expect(hydrateSource).toContain("includeRowId: shouldIncludeSyntheticRowId(resolvedDatabaseType.value, tableMeta.primaryKeys, tableMeta.tableType)");
});
});