From 16a1d4b1ddba65192e41e236c3174f3e19dd0ed3 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Tue, 30 Jun 2026 23:20:43 +0800 Subject: [PATCH] fix(grid): parse mysql enum type suffixes --- apps/desktop/src/lib/dataGridEnumEditor.ts | 39 +++++++++++-------- packages/app-tests/dataGridEnumEditor.test.ts | 9 +++++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/apps/desktop/src/lib/dataGridEnumEditor.ts b/apps/desktop/src/lib/dataGridEnumEditor.ts index a6d3374453..fdec7dc171 100644 --- a/apps/desktop/src/lib/dataGridEnumEditor.ts +++ b/apps/desktop/src/lib/dataGridEnumEditor.ts @@ -17,37 +17,44 @@ export function isEnumColumn(columnInfo: Pick | undefin export function enumValuesForColumn(columnInfo: Pick | undefined): string[] { if (!isEnumColumn(columnInfo)) return []; const raw = columnInfo!.data_type.trim(); - const inner = raw.match(/^enum\s*\(\s*(.+?)\s*\)\s*$/is)?.[1]; - if (!inner) return []; + const match = raw.match(/^enum\s*\(/i); + if (!match) return []; const values: string[] = []; - let i = 0; - while (i < inner.length) { - // Skip whitespace and commas between values - while (i < inner.length && (inner[i] === " " || inner[i] === ",")) i++; - if (i >= inner.length) break; + let i = match[0].length; + while (i < raw.length) { + // MySQL may append CHARACTER SET/COLLATE after the enum value list. + if (raw[i] === ")") { + i++; + return i >= raw.length || /\s/.test(raw[i]) ? values : []; + } - if (inner[i] !== "'") break; // unexpected token + while (i < raw.length && (/\s/.test(raw[i]) || raw[i] === ",")) i++; + if (i >= raw.length) break; + if (raw[i] === ")") continue; - i++; // skip opening quote + if (raw[i] !== "'") return []; + + i++; let value = ""; - while (i < inner.length) { - if (inner[i] === "'") { - if (i + 1 < inner.length && inner[i + 1] === "'") { - // Escaped single quote: '' + let closed = false; + while (i < raw.length) { + if (raw[i] === "'") { + if (i + 1 < raw.length && raw[i + 1] === "'") { value += "'"; i += 2; } else { - // Closing quote i++; + closed = true; break; } } else { - value += inner[i]; + value += raw[i]; i++; } } + if (!closed) return []; values.push(value); } - return values; + return []; } diff --git a/packages/app-tests/dataGridEnumEditor.test.ts b/packages/app-tests/dataGridEnumEditor.test.ts index 0acb612483..8c941eb1eb 100644 --- a/packages/app-tests/dataGridEnumEditor.test.ts +++ b/packages/app-tests/dataGridEnumEditor.test.ts @@ -31,6 +31,15 @@ test("parses enum with escaped single quotes", () => { assert.deepEqual(enumValuesForColumn({ data_type: "enum('it''s','normal')" }), ["it's", "normal"]); }); +test("parses MySQL enum values with charset and collation suffixes", () => { + assert.deepEqual( + enumValuesForColumn({ + data_type: "enum('id','string','text','long','double','bool','date','datetime','object','secret') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci", + }), + ["id", "string", "text", "long", "double", "bool", "date", "datetime", "object", "secret"], + ); +}); + test("returns empty array for non-enum types", () => { assert.deepEqual(enumValuesForColumn({ data_type: "varchar(255)" }), []); assert.deepEqual(enumValuesForColumn(undefined), []);