fix(grid): keep manual primary keys in exclude-PK insert copies

Closes #8293
This commit is contained in:
t8y2 committed 2026-09-07 18:24:37 +08:00
1 parent f64827a607
commit e3d5d14183
5 files changed
+261 -7

No files matched your search

@@ -923,17 +923,43 @@ describe("useDataGridExport prepared row statements", () => {
});
it("disables INSERT when primary-key exclusion removes every selected column", () => {
const autoIncrementTable: DataGridTableMeta = {
tableName: "users",
primaryKeys: ["id"],
columns: [{ name: "id", data_type: "int", is_nullable: false, is_primary_key: true, extra: "auto_increment" }],
};
const matrix: CellSelectionMatrix = { rowIndexes: [0], columnIndexes: [0], columns: ["id"], rows: [[1]] };
const excludePrimaryKeys = {
...DEFAULT_DATA_GRID_EXTRACTOR_OPTIONS,
sql: { ...DEFAULT_DATA_GRID_EXTRACTOR_OPTIONS.sql, skipGeneratedColumns: false, excludePrimaryKeysFromInsert: true },
};
const state = createExportState(editableTable, ["id"], matrix, [1], undefined, undefined, [], excludePrimaryKeys);
const state = createExportState(autoIncrementTable, ["id"], matrix, [1], undefined, undefined, [], excludePrimaryKeys);
expect(state.canCopyWithExtractor("sql-inserts")).toBe(false);
});
it("keeps a manually-assigned primary key insertable under primary-key exclusion", () => {
const compositeKeyTable: DataGridTableMeta = {
tableName: "daily_stats",
primaryKeys: ["id", "stat_date"],
columns: [
{ name: "id", data_type: "bigint", is_nullable: false, is_primary_key: true, extra: "auto_increment" },
{ name: "stat_date", data_type: "date", is_nullable: false, is_primary_key: true },
{ name: "name", data_type: "varchar", is_nullable: false },
],
};
const matrix: CellSelectionMatrix = { rowIndexes: [0], columnIndexes: [1], columns: ["stat_date"], rows: [["2026-08-18"]] };
const excludePrimaryKeys = {
...DEFAULT_DATA_GRID_EXTRACTOR_OPTIONS,
sql: { ...DEFAULT_DATA_GRID_EXTRACTOR_OPTIONS.sql, skipGeneratedColumns: false, excludePrimaryKeysFromInsert: true },
};
const state = createExportState(compositeKeyTable, ["id", "stat_date", "name"], matrix, [1, "2026-08-18", "Ada"], undefined, undefined, [], excludePrimaryKeys);
expect(state.canCopyWithExtractor("sql-inserts")).toBe(true);
});
it("keeps an auto-increment primary key when copying only the primary key column as INSERT", () => {
const autoIncrementTable: DataGridTableMeta = {
tableName: "users",
@@ -582,7 +582,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
function insertableCopyColumnCount(excludePrimaryKeys: boolean, copyColumns = effectiveColumns(sourceColumns.value, columns.value), extractorOptions?: DataGridExtractorOptions): number {
const primaryKeySet = new Set((tableMeta.value?.primaryKeys ?? []).map(normalizeColumnName));
return copyColumns.filter((column): column is string => !!column && !isCopyInsertOmittedColumn(databaseType.value, column, tableMeta.value, extractorOptions) && (!excludePrimaryKeys || !primaryKeySet.has(normalizeColumnName(column)))).length;
return copyColumns.filter((column): column is string => !!column && !isCopyInsertOmittedColumn(databaseType.value, column, tableMeta.value, extractorOptions) && (!excludePrimaryKeys || !primaryKeySet.has(normalizeColumnName(column)) || !isAutoGeneratedColumn(column, tableMeta.value))).length;
}
async function buildMongoExtractorInsert(extractorOptions: DataGridExtractorOptions, rowLimit?: number): Promise<string | undefined> {
@@ -1502,6 +1502,11 @@ function effectiveColumns(sourceColumns: Array<string | undefined> | undefined,
return sourceColumns;
}
function isAutoGeneratedColumn(column: string, tableMeta: DataGridTableMeta | undefined): boolean {
const columnInfo = tableMeta?.columns?.find((item) => normalizeColumnName(item.name) === normalizeColumnName(column));
return /\b(auto_increment|autoincrement|identity)\b/.test(columnInfo?.extra?.toLowerCase() ?? "");
}
function isCopyInsertOmittedColumn(databaseType: DatabaseType | undefined, column: string, tableMeta: DataGridTableMeta | undefined, extractorOptions?: DataGridExtractorOptions): boolean {
if (usesSyntheticRowIdKey(databaseType, [column])) return true;
const columnInfo = tableMeta?.columns?.find((item) => normalizeColumnName(item.name) === normalizeColumnName(column));