fix(sqlserver): restrict identity to compatible column types

Co-authored-by: staff <staff@qimaos-MacBook-Pro.local>
This commit is contained in:
zipgandstaff authored and GitHub committed 2026-07-01 12:48:37 +08:00
1 parent a224a6747c
commit 5d2ce9f189
13 files changed
+144 -12

No files matched your search

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { combineDataTypeForDatabase, createColumnDrafts, dataTypeLengthInputValue, isDataTypeLengthDisabled, splitDataType } from "../tableStructureEditorState";
import { combineDataTypeForDatabase, createColumnDrafts, dataTypeLengthInputValue, isDataTypeLengthDisabled, isSqlServerIdentityCompatibleDataType, splitDataType } from "../tableStructureEditorState";
describe("tableStructureEditorState", () => {
it("keeps mysql unsigned attributes in the editable base type", () => {
@@ -70,4 +70,13 @@ describe("tableStructureEditorState", () => {
expect(drafts.map((draft) => draft.defaultValue)).toEqual(["''", "1", "sysdatetime()", "'prefix (internal)'"]);
expect(drafts.map((draft) => draft.original?.column_default)).toEqual(["''", "1", "sysdatetime()", "'prefix (internal)'"]);
});
it("limits SQL Server identity columns to supported data types", () => {
expect(isSqlServerIdentityCompatibleDataType("int")).toBe(true);
expect(isSqlServerIdentityCompatibleDataType("bigint")).toBe(true);
expect(isSqlServerIdentityCompatibleDataType("numeric(18, 0)")).toBe(true);
expect(isSqlServerIdentityCompatibleDataType("decimal(10)")).toBe(true);
expect(isSqlServerIdentityCompatibleDataType("varchar(255)")).toBe(false);
expect(isSqlServerIdentityCompatibleDataType("numeric(18, 2)")).toBe(false);
});
});
@@ -725,6 +725,20 @@ export function splitDataType(raw: string): { baseType: string; params: string }
return { baseType, params };
}
export function isSqlServerIdentityCompatibleDataType(rawDataType: string): boolean {
const { baseType, params } = splitDataType(rawDataType);
const normalized = baseType.trim().replace(/\s+/g, " ").toLowerCase();
if (["tinyint", "smallint", "int", "integer", "bigint"].includes(normalized)) return true;
if (normalized !== "decimal" && normalized !== "numeric") return false;
const normalizedParams = params.replace(/\s+/g, "");
if (!normalizedParams) return true;
const parts = normalizedParams.split(",");
if (parts.length === 1) return /^\d+$/.test(parts[0] ?? "");
if (parts.length !== 2) return false;
const [precision, scale] = parts;
return /^\d+$/.test(precision ?? "") && scale === "0";
}
export function combineDataType(baseType: string, params: string): string {
const type = baseType.trim();
const p = params.trim();