#1127·chartdb

Bug: DBML/SQL export corrupts index names containing the substring `default`

Author: hmzisbCreated May 22, 2026Updated May 22, 2026

Hit this consistently when importing DBML generated by LLMs (Claude, ChatGPT). Tracked it down to index names containing the substring default, which the SQL export path corrupts. Full root-cause analysis, and a suggested fix below (analysis by Claude).

Summary

When a diagram contains an index whose name includes the substring default (e.g. idx_payment_methods_is_default), the SQL generation path in Mx produces invalid CREATE INDEX statements. The token default is uppercased to DEFAULT and an 'ON' string literal is injected, breaking the SQL and causing import/regeneration to fail with a parser diagnostic.

ChartDB is generating invalid SQL because the DBML index name contains default after is_. Its exporter seems to tokenize is_default badly and turns ON into a quoted string.

Environment

  • chartDB: self-hosted
  • Trigger: DBML import containing Indexes { } blocks where an index name contains default

Steps to reproduce

  1. Import a DBML schema containing an index named with the substring default, for example:
    dbml
    Table "public"."payment_methods" {
      "id" bigint [pk, not null, increment]
      "is_default" boolean [not null, default: false]
      "status" varchar(500) [not null, default: 'active']
    
      Indexes {
        is_default [name: "idx_payment_methods_is_default"]
        status [name: "idx_payment_methods_status"]
      }
    }
  2. Trigger SQL/DBML regeneration (the Mx function path).

Expected

Valid SQL:

sql
CREATE INDEX idx_payment_methods_is_default ON "public"."payment_methods" ("is_default");

Actual

Invalid SQL is generated and the parser throws T {diags: Array(1)}:

sql
CREATE INDEX idx_payment_methods_is_DEFAULT 'ON' "public"."payment_methods" ("is_default");

The default token in the index name is uppercased to DEFAULT and the ON keyword is replaced with the string literal 'ON'.

Suspected cause

The SQL post-processing transform chain inside Mx (the Nx / Ax / Sx / Cx / jx / Ix / kx / Lx passes applied after gf(...)) appears to run a case-insensitive replacement targeting the default keyword without respecting identifier boundaries. This rewrites the substring inside the unquoted index identifier and corrupts the surrounding ON keyword.

Note: column names and default-value clauses are unaffected because they are quoted in the generated SQL ("is_default", DEFAULT 'active'). Only unquoted index identifiers containing the substring are corrupted.

Compounding issue

The bug fires against the diagram held in application state, not the freshly imported file. Re-importing a corrected file over an existing canvas keeps emitting the corrupted index names; a clean/empty diagram is required for the fix to take effect. This makes the bug appear to persist after the user has already removed the offending index.

Workaround

  • Rename indexes to remove the default substring (e.g. idx_payment_methods_is_def), or remove the index, and import into a new blank diagram rather than over an existing one.

Suggested fix

  • Scope the keyword replacement so it only matches SQL keywords as whole, unquoted tokens, not as substrings of identifiers. Quote index identifiers in generated CREATE INDEX statements as is already done for table and column identifiers.