Skip to content

Unescaped Double Quotes in Mermaid ER Diagrams Break Syntax #790

@Wintus

Description

@Wintus

What happened

When generating Mermaid ER diagrams from PostgreSQL schemas that use double-quoted identifiers, the foreign key definitions are output without escaping double quotes, resulting in invalid Mermaid syntax.

The generated Mermaid diagram contains unescaped double quotes that break the syntax:

erDiagram
"public.ChildTable" }o--|| "public.ParentTable" : "FOREIGN KEY (parent_id) REFERENCES "ParentTable"(id)"
Loading

The unescaped quotes around "ParentTable" inside the relationship label make this invalid Mermaid syntax and the diagram fails to render.

What you expected to happened

The Mermaid diagram should have properly escaped double quotes in the foreign key definition:

erDiagram
"public.ChildTable" }o--|| "public.ParentTable" : "FOREIGN KEY (parent_id) REFERENCES #quot;ParentTable#quot;(id)"
Loading

What stack trace or error message from tbls did you see?

No error message from tbls. The tool runs successfully and generates the documentation, but the Mermaid diagram is syntactically invalid and cannot be rendered by Mermaid parsers.

Anything else we need to know?

Steps to reproduce

  1. Create a PostgreSQL schema with double-quoted identifiers:
CREATE TABLE "ParentTable" (
  id serial PRIMARY KEY,
  name text NOT NULL
);

CREATE TABLE "ChildTable" (
  id serial PRIMARY KEY,
  "parent_id" int NOT NULL,
  description text,
  CONSTRAINT "ChildTable_parent_id_fk" FOREIGN KEY("parent_id") REFERENCES "ParentTable"(id)
);
  1. Run tbls doc with Mermaid format and foreign key definitions enabled

  2. Check the generated Mermaid diagram in the output

Root cause

The issue is in these template files:

  • output/mermaid/templates/schema.mermaid.tmpl (line 6)
  • output/mermaid/templates/table.mermaid.tmpl (line 6)

Both templates output {{ $r.Def }} without applying the escape_double_quote filter:

"{{ $r.Table.Name }}" {{ $r.Cardinality | lcardi }}--{{ $r.ParentCardinality | rcardi }} "{{ $r.ParentTable.Name }}" : "{{ if $sd }}{{ $r.Def }}{{ end }}"

The escape_double_quote function is already available (defined in output/output.go:45) and is correctly used for column comments elsewhere in the same templates (line 12). The fix is to apply the same filter to $r.Def:

"{{ $r.Table.Name }}" {{ $r.Cardinality | lcardi }}--{{ $r.ParentCardinality | rcardi }} "{{ $r.ParentTable.Name }}" : "{{ if $sd }}{{ $r.Def | escape_double_quote }}{{ end }}"

Proposed fix

In both schema.mermaid.tmpl and table.mermaid.tmpl, line 6:

-"{{ $r.Table.Name }}" ... : "{{ if $sd }}{{ $r.Def }}{{ end }}"
+"{{ $r.Table.Name }}" ... : "{{ if $sd }}{{ $r.Def | escape_double_quote }}{{ end }}"

Additional context

  • This issue was partially addressed in version 1.68.2 with the commit message "Add escape double quotes for mermaid," but the templates were not updated to actually use the available escape functionality.

Environment

  • tbls version: v1.92.1 (current main branch)
  • Database version: PostgreSQL 15
  • OS: Windows 10 (Git for Windows), macOS
  • Shell: bash
  • Stacktrace or error message from tbls: None (silent bug in output)
  • Config (.tbls.yml):
dsn: postgres://postgres:pgpass@localhost:55413/repro_test?sslmode=disable

er:
  format: mermaid
  comment: true
  hideDef: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions