fix(oracle): support editing query results without primary key

This commit is contained in:
zipg authored and GitHub committed 2026-08-24 12:50:45 +08:00
1 parent c462272d8e
commit 2124cccef7
3 files changed
+118 -2

No files matched your search

+28 -2
View File
@@ -42,7 +42,7 @@ import { tableMetaForDataTab } from "@/lib/table/tableDataTabMeta";
import { isDataTabMetadataLifecycleStale } from "@/lib/sidebar/dataTabOpenPolicy";
import { dataTabExecutionDatabase } from "@/lib/table/dataTabExecutionDatabase";
import { tableOpenPageLimit } from "@/lib/table/tableOpenPageLimit";
import { getCachedTableMetadata, loadTableColumns, loadTableIndexes, loadTableMetadata, tableMetadataToDataTabMeta, type TableMetadataRequest } from "@/lib/metadata/tableMetadataCache";
import { getCachedTableMetadata, loadTableColumns, loadTableIndexes, loadTableMetadata, tableMetadataToDataTabMeta, updateCachedTableMetadataType, type TableMetadataRequest } from "@/lib/metadata/tableMetadataCache";
import { MetadataTaskLimiter } from "@/lib/metadata/metadataTaskLimiter";
import { buildTableSelectSql, quoteTableDataIdentifier } from "@/lib/table/tableSelectSql";
import { connectionObjectTreeNodeSchema, connectionQueryExecutionSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, gaussdbCountQueryDopHint, metadataSchemaForConnection } from "@/lib/database/jdbcDialect";
@@ -3848,6 +3848,32 @@ export const useQueryStore = defineStore("query", () => {
return matches.length === 1 && matches[0]?.type === "table";
}
async function resolveOracleRowIdSafety(tab: QueryTab, loaded: LoadedEditableSource): Promise<boolean> {
if (oracleRowIdIsSafeForQuery(tab, loaded)) return true;
if (loaded.tableMeta.tableType?.trim()) return false;
const connection = useConnectionStore().getConfig(tab.connectionId!);
const schema = loaded.tableMeta.schema?.trim() || tab.schema?.trim() || connection?.default_schema?.trim() || "";
const tables = await api.listTables(tab.connectionId!, loaded.tableMeta.database ?? tab.database, schema, loaded.tableMeta.tableName);
const exactMatches = tables.filter((table) => table.name === loaded.tableMeta.tableName);
if (exactMatches.length !== 1) return false;
loaded.tableMeta.tableType = exactMatches[0]!.table_type;
updateCachedTableMetadataType(
{
connectionId: tab.connectionId!,
database: loaded.tableMeta.database ?? tab.database,
schema: loaded.tableMeta.schema,
tableName: loaded.tableMeta.tableName,
databaseType: "oracle",
driverProfile: connection?.driver_profile || connection?.db_type,
catalog: loaded.tableMeta.catalog,
},
loaded.tableMeta.tableType,
);
return oracleRowIdIsSafeForQuery(tab, loaded);
}
function primaryKeyIndex(indexes: IndexInfo[]): IndexInfo | undefined {
return indexes.find((index) => !index.filter && index.columns.length > 0 && index.is_primary);
}
@@ -3921,7 +3947,7 @@ export const useQueryStore = defineStore("query", () => {
// Oracle base tables without a natural identifier use the same ROWID
// identity as table-data tabs. Confirm the object is a base table because
// selecting ROWID from a view can fail with ORA-01445.
if (syntheticOracleRowId && !oracleRowIdIsSafeForQuery(tab, loaded)) return unchanged;
if (syntheticOracleRowId && !(await resolveOracleRowIdSafety(tab, loaded))) return unchanged;
const declaredPrimaryKeys = databaseType === "oracle" && !syntheticOracleRowId ? primaryKeys : columnPrimaryKeys;
return buildHiddenPrimaryKeyPreparation(tab, sql, databaseType, loaded, primaryKeys, declaredPrimaryKeys, traceId, elapsed);
} catch (error) {