fix(mysql): preserve empty string column defaults

This commit is contained in:
t8y2 2026-07-22 01:12:02 +08:00
parent a737b31e0e
commit f25759dcf0
2 changed files with 115 additions and 1 deletions

View File

@ -355,6 +355,115 @@ describe("tableStructureEditorState", () => {
expect(drafts.map((draft) => draft.original?.column_default)).toEqual(["''", "1", "sysdatetime()", "'prefix (internal)'"]);
});
it("distinguishes MySQL empty string defaults from no default", () => {
const drafts = createColumnDrafts(
[
{
name: "empty_label",
data_type: "varchar(100)",
is_nullable: false,
column_default: "",
is_primary_key: false,
extra: null,
},
{
name: "optional_label",
data_type: "varchar(100)",
is_nullable: true,
column_default: null,
is_primary_key: false,
extra: null,
},
],
"mysql",
);
expect(drafts.map((draft) => draft.defaultValue)).toEqual(["''", ""]);
expect(drafts.map((draft) => draft.original?.column_default)).toEqual(["''", null]);
});
it("preserves MySQL ordinary string and expression defaults", () => {
const drafts = createColumnDrafts(
[
{
name: "status",
data_type: "varchar(20)",
is_nullable: false,
column_default: "active",
is_primary_key: false,
extra: null,
},
{
name: "created_at",
data_type: "timestamp",
is_nullable: false,
column_default: "CURRENT_TIMESTAMP",
is_primary_key: false,
extra: null,
},
],
"mysql",
);
expect(drafts.map((draft) => draft.defaultValue)).toEqual(["active", "CURRENT_TIMESTAMP"]);
expect(drafts.map((draft) => draft.original?.column_default)).toEqual(["active", "CURRENT_TIMESTAMP"]);
});
it("keeps a MySQL empty string default when renaming a column", () => {
const [column] = createColumnDrafts(
[
{
name: "old_name",
data_type: "varchar(100)",
is_nullable: false,
column_default: "",
is_primary_key: false,
extra: null,
},
],
"mysql",
);
column!.name = "new_name";
expect(column!.defaultValue).toBe("''");
expect(column!.original?.column_default).toBe("''");
});
it("retains Postgres and SQL Server default normalization", () => {
const [postgres] = createColumnDrafts(
[
{
name: "label",
data_type: "character varying(100)",
is_nullable: false,
column_default: "''::character varying",
is_primary_key: false,
extra: null,
},
],
"postgres",
);
const [sqlserver] = createColumnDrafts(
[
{
name: "label",
data_type: "nvarchar(100)",
is_nullable: false,
column_default: "('')",
is_primary_key: false,
extra: null,
},
],
"sqlserver",
);
expect(postgres!.defaultValue).toBe("''");
expect(postgres!.original?.column_default).toBe("''");
expect(sqlserver!.defaultValue).toBe("''");
expect(sqlserver!.original?.column_default).toBe("''");
});
it("limits SQL Server identity columns to supported data types", () => {
expect(isSqlServerIdentityCompatibleDataType("int")).toBe(true);
expect(isSqlServerIdentityCompatibleDataType("bigint")).toBe(true);

View File

@ -632,7 +632,12 @@ function stripSqlServerDefaultOuterParens(defaultValue: string): string {
}
function columnDefaultForEditor(column: ColumnInfo, databaseType?: DatabaseType): string {
const defaultValue = column.column_default ?? "";
if (column.column_default === null) return "";
const defaultValue = column.column_default;
if (databaseType === "mysql" && defaultValue === "" && isMysqlCharacterDataType(column.data_type)) {
// MySQL metadata uses an empty string for DEFAULT '', so keep it distinct from no default.
return "''";
}
if (databaseType === "postgres") return stripPostgresStringDefaultCast(defaultValue, column.data_type);
if (databaseType === "sqlserver") return stripSqlServerDefaultOuterParens(defaultValue);
return defaultValue;