feat(grid): support deleting rows from JOIN query results

This commit is contained in:
zipg authored and GitHub committed 2026-08-27 16:28:14 +08:00
1 parent 36a7b7bd3a
commit 920ab62cf1
7 files changed
+207 -4

No files matched your search

@@ -1763,7 +1763,7 @@ defineExpose({
:mongo-update-target="mongoQueryResultSaveHandler && activeTab.result.mongo_copy_documents?.length === activeTab.result.rows.length ? activeTab.mongoEditTarget : undefined"
:query-editability-reason="activeTab.queryEditabilityReason"
:allow-insert-rows="activeTab.queryAnalysis?.allowInsert ?? activeTab.queryAnalysis?.allowInsertDelete !== false"
:allow-delete-rows="activeTab.queryAnalysis?.allowInsertDelete !== false"
:allow-delete-rows="activeTab.queryAnalysis?.allowDelete ?? activeTab.queryAnalysis?.allowInsertDelete !== false"
context="results"
:auto-transpose-single-row="settingsStore.editorSettings.dataGridAutoTransposeSingleRow"
:database-type="activeEffectiveDatabaseType"
+1
View File
@@ -23,6 +23,7 @@ export interface EditableQueryInfo {
editableSourceKey?: string;
multiSource?: boolean;
allowInsert?: boolean;
allowDelete?: boolean;
allowInsertDelete?: boolean;
distinct?: boolean;
groupByColumns?: EditableQueryColumn[];
+4 -1
View File
@@ -4229,6 +4229,8 @@ export const useQueryStore = defineStore("query", () => {
const allSourceColumns = loadedSources.map((source) => ({ source: source.source, columns: source.tableMeta.columns }));
// Match DBeaver's safety model: a joined result is writable only when one
// source table has a complete row identifier and at least one writable column.
// A keyless source has no row identifier: allPrimaryKeysPresent is vacuously
// true for an empty key set, so joined results must exclude such sources.
const candidates = loadedSources
.map((loaded) => {
const metadataAnalysis = expandStarProjectionColumnsForSource(bindColumnsForSource(dbType, loaded.analysis, loaded.source, loaded.tableMeta.columns, allSourceColumns), loaded.source, loaded.tableMeta.columns);
@@ -4247,7 +4249,7 @@ export const useQueryStore = defineStore("query", () => {
editableSourceColumnCount,
};
})
.filter((loaded) => (loaded.primaryKeysPresent || loaded.keylessAllowed) && !!loaded.sourceColumns && loaded.editableSourceColumnCount > 0);
.filter((loaded) => ((loaded.primaryKeysPresent && loaded.tableMeta.primaryKeys.length > 0) || loaded.keylessAllowed) && !!loaded.sourceColumns && loaded.editableSourceColumnCount > 0);
if (loadedSources.length === 1) {
const loaded = loadedSources[0]!;
@@ -4330,6 +4332,7 @@ export const useQueryStore = defineStore("query", () => {
const queryAnalysis = {
...target.analysis,
...(target.analysis.distinct && canInsertIntoEditableQuerySource(tab, dbType as DatabaseType, target, target.sourceColumns) ? { allowInsert: true } : {}),
allowDelete: !target.analysis.distinct,
allowInsertDelete: false,
multiSource: true,
};
+1
View File
@@ -1253,6 +1253,7 @@ export interface QueryTab {
editableSourceKey?: string;
multiSource?: boolean;
allowInsert?: boolean;
allowDelete?: boolean;
allowInsertDelete?: boolean;
distinct?: boolean;
sources?: {