fix(hive): allow non-transactional grid edits

This commit is contained in:
t8y2
2026-05-13 20:04:42 +08:00
parent 3eb00b7fe2
commit ea6b2bb36c
6 changed files with 76 additions and 6 deletions
+2 -1
View File
@@ -17,6 +17,7 @@ const QueryChart = defineAsyncComponent(() => import("@/components/chart/QueryCh
import { useQueryStore } from "@/stores/queryStore";
import { canCancelQueryExecution, queryExecutionLabelKey } from "@/lib/queryExecutionState";
import { databaseDisplayNameForTab } from "@/lib/tabPresentation";
import { isTableDataEditable } from "@/lib/tableEditing";
import type { QueryTab, ConnectionConfig } from "@/types/database";
import type { SqlFormatDialect } from "@/lib/sqlFormatter";
@@ -390,7 +391,7 @@ defineExpose({ focusSearch });
:result="activeTab.result"
:sql="activeTab.sql"
:loading="activeTab.isExecuting"
:editable="!!activeTab.tableMeta?.primaryKeys?.length"
:editable="isTableDataEditable(activeConnection?.db_type, activeTab.tableMeta?.primaryKeys ?? [])"
context="table-data"
:initial-where-input="activeTab.whereInput"
:database-type="activeConnection?.db_type"
+10 -5
View File
@@ -4,9 +4,11 @@ import {
buildDataGridRollbackStatements,
buildDataGridSaveStatements,
dataGridSaveExecutionSchema,
normalizeDataGridSaveError,
validateDataGridSave,
} from "@/lib/dataGridSql";
import { rowStatusFilterAfterAddingRow, type RowStatusFilter } from "@/lib/gridRowStatus";
import { supportsDataGridTransaction } from "@/lib/tableEditing";
import { useConnectionStore } from "@/stores/connectionStore";
import { useHistoryStore } from "@/stores/historyStore";
import type { ColumnInfo, DatabaseType } from "@/types/database";
@@ -125,7 +127,10 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
const saveError = ref("");
const useTransaction = computed(
() => editable.value && (!!customSave?.value || (!!connectionId.value && !!database.value && !!tableMeta.value)),
() =>
editable.value &&
supportsDataGridTransaction(databaseType.value) &&
(!!customSave?.value || (!!connectionId.value && !!database.value && !!tableMeta.value)),
);
function enterTransaction() {
@@ -536,7 +541,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
rows: result.value.rows,
});
} catch (e: any) {
saveError.value = String(e.message || e);
saveError.value = normalizeDataGridSaveError(databaseType.value, e);
isSaving.value = false;
return;
}
@@ -599,7 +604,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
dataGridSaveExecutionSchema(databaseType.value, tableMeta.value),
);
} catch (e: any) {
saveError.value = String(e.message || e);
saveError.value = normalizeDataGridSaveError(databaseType.value, e);
isSaving.value = false;
return;
}
@@ -607,7 +612,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
try {
apiResult = await api.executeBatch(connectionId.value, database.value, stmts);
} catch (e: any) {
saveError.value = String(e.message || e);
saveError.value = normalizeDataGridSaveError(databaseType.value, e);
isSaving.value = false;
return;
}
@@ -617,7 +622,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
await onExecuteSql.value(sqlStmt);
}
} catch (e: any) {
saveError.value = String(e.message || e);
saveError.value = normalizeDataGridSaveError(databaseType.value, e);
isSaving.value = false;
return;
}
+9
View File
@@ -181,6 +181,14 @@ export function dataGridSaveExecutionSchema(
return tableMeta?.schema;
}
export function normalizeDataGridSaveError(databaseType: DatabaseType | undefined, error: unknown): string {
const message = error instanceof Error ? error.message : String(error);
if (databaseType === "hive" && /Attempt to do update or delete|Error 10294/i.test(message)) {
return "Hive UPDATE/DELETE are not enabled for this table or server. Add rows with INSERT, or enable ACID transactional tables in Hive before editing/deleting existing rows.";
}
return message;
}
export function formatGridSqlLiteral(value: GridCellValue, databaseType?: DatabaseType): string {
if (value === null || value === undefined) return "NULL";
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
@@ -197,6 +205,7 @@ function buildPrimaryKeyWhere(
columns: string[],
row: GridCellValue[],
): string {
if (databaseType === "hive" && primaryKeys.length === 0) return buildRowWhere(databaseType, columns, row);
return primaryKeys
.map((primaryKey) => {
const value = row[columns.indexOf(primaryKey)];
+9
View File
@@ -10,6 +10,15 @@ export function editablePrimaryKeys(databaseType: DatabaseType | undefined, colu
return primaryKeys;
}
export function isTableDataEditable(databaseType: DatabaseType | undefined, primaryKeys: string[]): boolean {
if (databaseType === "hive") return true;
return primaryKeys.length > 0;
}
export function supportsDataGridTransaction(databaseType: DatabaseType | undefined): boolean {
return databaseType !== "hive";
}
export function usesSyntheticRowIdKey(databaseType: DatabaseType | undefined, primaryKeys: string[]): boolean {
return (
primaryKeys.length === 1 &&