Fix: 修复 SQL Server 修改默认值时报错 (#2190)

* Fix SQL Server default constraint DDL

* Polish SQL Server default display

---------

Co-authored-by: staff <staff@qimaos-MacBook-Pro.local>
This commit is contained in:
zipgandstaff authored and GitHub committed 2026-06-30 20:14:50 +08:00
1 parent 25dcbeb7e4
commit 73a996ebe6
5 files changed
+288 -7

No files matched your search

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { combineDataTypeForDatabase, dataTypeLengthInputValue, isDataTypeLengthDisabled, splitDataType } from "../tableStructureEditorState";
import { combineDataTypeForDatabase, createColumnDrafts, dataTypeLengthInputValue, isDataTypeLengthDisabled, splitDataType } from "../tableStructureEditorState";
describe("tableStructureEditorState", () => {
it("keeps mysql unsigned attributes in the editable base type", () => {
@@ -27,4 +27,47 @@ describe("tableStructureEditorState", () => {
expect(dataTypeLengthInputValue("mysql", dataType)).toBe("");
expect(dataTypeLengthInputValue("mysql", "set('manual','auto')")).toBe("");
});
it("strips SQL Server metadata parentheses from editable defaults", () => {
const drafts = createColumnDrafts(
[
{
name: "name",
data_type: "nvarchar(100)",
is_nullable: true,
column_default: "('')",
is_primary_key: false,
extra: null,
},
{
name: "active",
data_type: "bit",
is_nullable: false,
column_default: "((1))",
is_primary_key: false,
extra: null,
},
{
name: "created_at",
data_type: "datetime2(7)",
is_nullable: false,
column_default: "((sysdatetime()))",
is_primary_key: false,
extra: null,
},
{
name: "label",
data_type: "nvarchar(100)",
is_nullable: true,
column_default: "('prefix (internal)')",
is_primary_key: false,
extra: null,
},
],
"sqlserver",
);
expect(drafts.map((draft) => draft.defaultValue)).toEqual(["''", "1", "sysdatetime()", "'prefix (internal)'"]);
expect(drafts.map((draft) => draft.original?.column_default)).toEqual(["''", "1", "sysdatetime()", "'prefix (internal)'"]);
});
});
@@ -533,9 +533,58 @@ function stripPostgresStringDefaultCast(defaultValue: string, dataType: string):
return match?.[1] ?? defaultValue;
}
function isWrappedByOuterParens(value: string): boolean {
if (value.length < 2 || value[0] !== "(" || value[value.length - 1] !== ")") return false;
let depth = 0;
let inString = false;
let inBracketIdentifier = false;
for (let index = 0; index < value.length; index += 1) {
const char = value[index];
if (inString) {
if (char === "'" && value[index + 1] === "'") {
index += 1;
} else if (char === "'") {
inString = false;
}
continue;
}
if (inBracketIdentifier) {
if (char === "]") inBracketIdentifier = false;
continue;
}
if (char === "'") {
inString = true;
continue;
}
if (char === "[") {
inBracketIdentifier = true;
continue;
}
if (char === "(") {
depth += 1;
} else if (char === ")") {
depth -= 1;
if (depth < 0) return false;
if (depth === 0 && index < value.length - 1) return false;
}
}
return depth === 0;
}
function stripSqlServerDefaultOuterParens(defaultValue: string): string {
let value = defaultValue.trim();
while (isWrappedByOuterParens(value)) {
value = value.slice(1, -1).trim();
}
return value;
}
function columnDefaultForEditor(column: ColumnInfo, databaseType?: DatabaseType): string {
const defaultValue = column.column_default ?? "";
return databaseType === "postgres" ? stripPostgresStringDefaultCast(defaultValue, column.data_type) : defaultValue;
if (databaseType === "postgres") return stripPostgresStringDefaultCast(defaultValue, column.data_type);
if (databaseType === "sqlserver") return stripSqlServerDefaultOuterParens(defaultValue);
return defaultValue;
}
export function createColumnDrafts(columns: ColumnInfo[], databaseType?: DatabaseType): EditableStructureColumn[] {