fix(structure): show PostgreSQL index types in editor

This commit is contained in:
onenewcode 2026-07-30 16:49:14 +08:00 committed by GitHub
parent 50e49d06bc
commit 1650b0605a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 2 deletions

View File

@ -70,6 +70,7 @@ import {
rehydrateColumnDraftsFromMetadata,
resolveInsertColumnIndex,
restoreDamengLengthUnitsAfterSave,
sameStructureIndexType,
splitDataType,
toColumnNames,
} from "@/lib/table/tableStructureEditorState";
@ -212,7 +213,7 @@ function indexChanged(index: EditableStructureIndex): boolean {
!sameList(index.columns, original.columns) ||
index.isUnique !== original.is_unique ||
!sameText(index.filter, original.filter) ||
!sameText(index.indexType, original.index_type) ||
!sameStructureIndexType(index.indexType, original.index_type) ||
!sameList(index.includedColumns, original.included_columns) ||
!sameText(index.comment, original.comment)
);

View File

@ -758,6 +758,16 @@ export function rehydrateColumnDraftsFromMetadata(draftColumns: EditableStructur
return [...nextColumns, ...missingMetadataDrafts];
}
/** Canonicalize index method for structure editor options (e.g. Postgres `btree` → `BTREE`). */
export function normalizeStructureIndexType(indexType: string | null | undefined): string {
return (indexType ?? "").trim().toUpperCase();
}
/** Case-insensitive index-type equality (draft is uppercased; API may still return lowercase amname). */
export function sameStructureIndexType(left: string | null | undefined, right: string | null | undefined): boolean {
return normalizeStructureIndexType(left) === normalizeStructureIndexType(right);
}
export function createIndexDrafts(indexes: IndexInfo[]): EditableStructureIndex[] {
return indexes.map((index) => ({
id: `existing:${index.name}`,
@ -767,7 +777,8 @@ export function createIndexDrafts(indexes: IndexInfo[]): EditableStructureIndex[
isUnique: index.is_unique,
isPrimary: index.is_primary,
filter: index.filter ?? "",
indexType: index.index_type ?? "",
// Match Select options (BTREE/GIN/…); Postgres pg_am.amname is lowercase.
indexType: normalizeStructureIndexType(index.index_type),
includedColumns: index.included_columns ? [...index.included_columns] : [],
comment: index.comment ?? "",
original: index,

View File

@ -19,9 +19,11 @@ import {
isSqlServerIdentityCompatibleDataType,
mysqlEnumDataType,
normalizeDataTypeParams,
normalizeStructureIndexType,
parseExtraToColumnExtra,
rehydrateColumnDraftsFromMetadata,
resolveInsertColumnIndex,
sameStructureIndexType,
toColumnNames,
} from "../../apps/desktop/src/lib/table/tableStructureEditorState.ts";
import { firstStructureMetadataTab, isStructureMetadataTabSupported } from "../../apps/desktop/src/lib/table/tableMetadataCapabilities.ts";
@ -402,6 +404,48 @@ test("creates editable index drafts and splits pasted column lists", () => {
assert.equal(toColumnNames(["id", "name"]), "id, name");
});
test("normalizes Postgres lowercase index types when creating structure drafts", () => {
const postgresIndexes: IndexInfo[] = [
{
name: "system_big_screen_asset_pkey",
columns: ["id"],
is_unique: true,
is_primary: true,
index_type: "btree",
},
{
name: "SYSTEM_BIG_SCREEN_ASSET_TAGS_JSON_IDX",
columns: ["tags_json"],
is_unique: false,
is_primary: false,
index_type: "gin",
},
{
name: "idx_hash",
columns: ["name"],
is_unique: false,
is_primary: false,
index_type: "hash",
},
];
const drafts = createIndexDrafts(postgresIndexes);
assert.deepEqual(
drafts.map((draft) => ({ name: draft.name, indexType: draft.indexType })),
[
{ name: "system_big_screen_asset_pkey", indexType: "BTREE" },
{ name: "SYSTEM_BIG_SCREEN_ASSET_TAGS_JSON_IDX", indexType: "GIN" },
{ name: "idx_hash", indexType: "HASH" },
],
);
// Uppercased drafts must not look like a type change vs Postgres amname.
assert.equal(sameStructureIndexType(drafts[0]!.indexType, postgresIndexes[0]!.index_type), true);
assert.equal(sameStructureIndexType("BTREE", "btree"), true);
assert.equal(sameStructureIndexType("GIN", "hash"), false);
assert.equal(normalizeStructureIndexType(" gist "), "GIST");
});
test("generates conventional index names from table and columns", () => {
assert.equal(generateIndexName("A", ["B"]), "A_B_IDX");
assert.equal(generateIndexName("order item", ["customer-id", "created_at"]), "ORDER_ITEM_CUSTOMER_ID_CREATED_AT_IDX");