Skip to content

[P0][bug] extractBaseType/extractLength discard column modifiers — UNSIGNED, ZEROFILL, CHARACTER SET, COLLATE, ON UPDATE CURRENT_TIMESTAMP lost on round-trip #377

Description

@EVWorth

Context

Table Designer loads existing table structure in alter mode via getColumns/getIndexes, then saves back via generateAlterTable.

Problem

src/components/designer/TableDesigner.tsx:920-940 (extractBaseType, extractLength) parses the inspector's column_type string. For INT(11) UNSIGNED ZEROFILL, it captures baseType: "INT", length: "11" — UNSIGNED and ZEROFILL are dropped. buildColumnDef (ddl-generator.ts:48-72) emits INT(11) NOT NULL AUTO_INCREMENT DEFAULT … COMMENT … but never UNSIGNED ZEROFILL. On save, MySQL silently narrows the column to signed INT — values > 2^31-1 fail with ERROR 1264 (22003): Out of range value. Similarly, VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin loses both modifiers → MySQL falls back to table default (may differ). DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP — the extra field "DEFAULT_GENERATED on update CURRENT_TIMESTAMP" is dropped (only auto_increment check on line 920-940 catches one EXTRA pattern).

Files

  • src/components/designer/TableDesigner.tsx:920-940 (extractBaseType, extractLength)
  • src/lib/ddl-generator.ts:48-72 (buildColumnDef)
  • src/types/index.ts:173-182 (ColumnInfo interface)
  • src-tauri/crates/mas-core/src/schema/inspector.rs (get_columns)

Repro

  1. CREATE TABLE t (id INT(11) UNSIGNED ZEROFILL NOT NULL)
  2. Open Table Designer in alter mode for t
  3. Click Apply Changes
  4. SHOW CREATE TABLE t shows int(11) NOT NULL — UNSIGNED ZEROFILL lost

Expected

Round-trip preserves all column modifiers.

Proposed fix

(1) Extend ColumnInfo in src/types/index.ts and inspector.rs:get_columns to include column_attributes: String[] (split from COLUMN_TYPE on whitespace after the length parens — e.g. ["UNSIGNED", "ZEROFILL"]). Add extra_on_update: Option from EXTRA column. (2) Extend DesignerColumn (ddl-generator.ts:5-14) with unsigned, zerofill, charset, collate, onUpdate. (3) extractBaseType/extractLength parse the suffix. (4) buildColumnDef appends UNSIGNED/ZEROFILL after the type and CHARACTER SET/COLLATE after NOT NULL. (5) Add a separate ALTER TABLE … MODIFY COLUMN x TIMESTAMP … ON UPDATE CURRENT_TIMESTAMP emission for timestamp columns. Scope: M.

Acceptance

INT(11) UNSIGNED ZEROFILL NOT NULL round-trips: load → save → SHOW CREATE TABLE shows UNSIGNED ZEROFILL preserved. VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin round-trips with charset/collate. created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP round-trips with ON UPDATE preserved.

Needs human verify

yes

Doc drift

no

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/designerAudit areaauditTracks a feature-by-feature codebase audit findingkind/bugAudit finding categoryseverity/p0Audit finding severity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions