Skip to content

feat: add support for DBML Checks block syntax - #47

Open
frenzzy wants to merge 3 commits into
softwaretechnik-berlin:mainfrom
frenzzy:feat/checks-support
Open

feat: add support for DBML Checks block syntax#47
frenzzy wants to merge 3 commits into
softwaretechnik-berlin:mainfrom
frenzzy:feat/checks-support

Conversation

@frenzzy

@frenzzy frenzzy commented Jan 9, 2026

Copy link
Copy Markdown

Fixes #49

Summary

Add parser support for the DBML Checks block syntax, which was introduced in the official DBML specification (v5.0.0). This allows parsing DBML files generated by @dbml/cli sql2dbml that include CHECK constraint definitions.

Problem

When using sql2dbml to convert PostgreSQL schemas that contain CHECK constraints, the generated DBML includes Checks blocks:

Table "user_role" {
  id uuid [pk]
  role_id uuid
  platform_role_id uuid

  Checks {
    `(num_nonnulls(role_id, platform_role_id) = 1)` [name: 'user_role_ck']
  }
}

This causes dbml-renderer to fail with:

Could not parse input at line X. Expected "'", "'''", "\"", or whitespace but "`" found.

Solution

Added parser support following the existing Indices block pattern:

Grammar (src/dbml.pegjs)

TableItem =
  Column
  / Indices
  / Checks  // Added
  / option:Option { return { type: "option", option }; }

Checks = "Checks"i __ "{" __ checks:ChecksList __ "}" { return { type: "checks", checks }; }
ChecksList = (head:CheckItem tail:(EOL __ check:CheckItem { return check; })* { return [head, ...tail]; })?
CheckItem = expression:Function _ settings:Settings? { return { expression, settings } }

Types (src/types.ts)

export const TableChecks = z.object({
  type: z.literal("checks"),
  checks: z.array(
    z.object({
      expression: z.string(),
      settings: Settings.nullable().transform((v) => v || {}),
    }),
  ),
});

Checker (src/checker.ts)

  • Added checks property to NormalizedTable
  • Added checks extraction using existing extract() helper

Implementation Notes

  • Checks are parsed and stored in the AST but not rendered visually (same as index details), since they are constraint metadata
  • The implementation exactly mirrors the existing Indices pattern for consistency
  • Tested against real-world PostgreSQL schema with multiple Checks blocks

Test Coverage

Added examples/checks.dbml test file covering:

  • Simple check constraints (price > 0)
  • Named checks with settings ([name: 'constraint_name'])
  • Complex expressions with AND/OR logic
  • Multiple checks per table
  • Checks combined with indexes and references

Test count: 100 → 104 (4 new tests added)

References

Test Plan

  • All 104 tests pass
  • npm run format:check passes
  • npm run build passes
  • Successfully parses DBML files with Checks blocks
  • Generates valid SVG/DOT output from schemas containing Checks
  • No regressions in existing functionality

frenzzy and others added 3 commits January 9, 2026 14:50
Add parser support for the Checks block introduced in the official DBML
specification. This allows parsing DBML files generated by @dbml/cli sql2dbml
that include CHECK constraint definitions.

Changes:
- Add Checks, ChecksList, CheckItem grammar rules to dbml.pegjs
- Add TableChecks Zod schema to types.ts
- Add checks extraction to checker.ts

The implementation follows the existing Indices block pattern exactly.
Checks are parsed and stored in the AST but not rendered visually (same
as index details) since they are constraint metadata.

Fixes parsing errors like:
  Could not parse input at line X. Expected "'", "'''", "\"", or
  whitespace but "`" found.

References:
- DBML Checks syntax: https://dbml.dbdiagram.io/docs/#checks-definition
- @dbml/core Checks support: holistics/dbml@9dc6e17

Co-Authored-By: Claude <noreply@anthropic.com>
Reset generated files to origin/main and regenerate with proper
Prettier formatting to minimize diff for easier code review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add test example covering various Checks block scenarios:
- Simple check constraints (price > 0)
- Named checks with settings [name: 'constraint_name']
- Complex expressions with AND/OR logic
- Multiple checks per table
- Checks combined with indexes and references

This adds 4 new tests (100 → 104 total) to prevent future
regressions in Checks parsing.

Co-Authored-By: Claude <noreply@anthropic.com>
@frenzzy

frenzzy commented Jan 9, 2026

Copy link
Copy Markdown
Author

While waiting for this PR to be merged, I've published a temporary fork to npm:

Package: @frenzzy/dbml-renderer
Version: 1.0.31-checks.0
Tag: checks

Usage

# Using npx
npx @frenzzy/dbml-renderer@checks -i schema.dbml -o schema.svg

# Or install as dependency
npm install @frenzzy/dbml-renderer@checks

This is a drop-in replacement until the official package is updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parser fails on Checks blocks (DBML v5.0.0 check definitions) emitted by sql2dbml

1 participant