fix(grid): exclude postgres serial primary keys in pk-free copies

This commit is contained in:
zipg authored and GitHub committed 2026-09-17 17:16:02 +08:00
1 parent dc4764e930
commit 6d2c8a5edb
5 files changed
+124 -7

No files matched your search

@@ -965,6 +965,32 @@ describe("useDataGridExport prepared row statements", () => {
expect(state.canCopyWithExtractor("sql-inserts")).toBe(false);
});
it("recognizes PostgreSQL serial primary keys when excluding primary keys", () => {
const serialTable: DataGridTableMeta = {
tableName: "users",
primaryKeys: ["id"],
columns: [
{
name: "id",
data_type: "integer",
is_nullable: false,
is_primary_key: true,
extra: "serial",
},
{ name: "name", data_type: "text", is_nullable: false },
],
};
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, excludePrimaryKeysFromInsert: true },
};
const state = createExportState(serialTable, ["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",
@@ -1709,7 +1709,9 @@ function effectiveColumns(sourceColumns: Array<string | undefined> | undefined,
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() ?? "");
const extra = columnInfo?.extra?.toLowerCase() ?? "";
const defaultValue = columnInfo?.column_default?.toLowerCase() ?? "";
return /\b(auto_increment|autoincrement|identity|smallserial|serial|bigserial)\b/.test(extra) || /\bnextval\s*\(/.test(defaultValue);
}
function isCopyInsertOmittedColumn(databaseType: DatabaseType | undefined, column: string, tableMeta: DataGridTableMeta | undefined, extractorOptions?: DataGridExtractorOptions): boolean {
@@ -1718,7 +1720,7 @@ function isCopyInsertOmittedColumn(databaseType: DatabaseType | undefined, colum
const normalizedType = columnInfo?.data_type.trim().replace(/^"|"$/g, "").toLowerCase();
if (databaseType === "postgres" && (normalizedType === "tsvector" || normalizedType?.endsWith(".tsvector"))) return true;
const extra = columnInfo?.extra?.toLowerCase() ?? "";
const isAutoGenerated = /\b(auto_increment|autoincrement|identity)\b/.test(extra);
const isAutoGenerated = isAutoGeneratedColumn(column, tableMeta);
const isComputed = extra.includes("generated always as") && !extra.includes("identity");
const isPrimaryKey = (tableMeta?.primaryKeys ?? []).some((key) => normalizeColumnName(key) === normalizeColumnName(column));
return ((extractorOptions?.sql.skipGeneratedColumns ?? true) && isAutoGenerated && !isPrimaryKey) || ((extractorOptions?.sql.skipComputedColumns ?? true) && isComputed);
@@ -473,7 +473,9 @@ function columnExtra(column: string, tableMeta: DataGridTableMeta | undefined):
}
function isAutoGeneratedColumn(column: string, tableMeta: DataGridTableMeta | undefined): boolean {
return /\b(auto_increment|autoincrement|identity)\b/.test(columnExtra(column, tableMeta));
const columnInfo = tableMeta?.columns?.find((item) => normalizeName(item.name) === normalizeName(column));
const defaultValue = columnInfo?.column_default?.toLowerCase() ?? "";
return /\b(auto_increment|autoincrement|identity|smallserial|serial|bigserial)\b/.test(columnExtra(column, tableMeta)) || /\bnextval\s*\(/.test(defaultValue);
}
function isComputedColumn(column: string, tableMeta: DataGridTableMeta | undefined): boolean {