diesel-guard 0.10.0

Linter for dangerous Postgres migration patterns in Diesel and SQLx. Prevents downtime caused by unsafe schema changes.
Documentation
# Quick Start

## Check a Single Migration File

```sh
diesel-guard check migrations/2024_01_01_create_users/up.sql
```

## Check All Migrations in a Directory

```sh
diesel-guard check              # defaults to ./migrations/
diesel-guard check migrations/  # or specify an explicit path
```

## Pipe SQL Directly

```sh
cat migrations/2024_01_01_create_users/up.sql | diesel-guard check -
```

## Example Output

When diesel-guard finds an unsafe operation:

```
❌ Unsafe migration detected in migrations/2024_01_01_create_users/up.sql

❌ ADD COLUMN with DEFAULT

Problem:
  Adding column 'admin' with DEFAULT on table 'users' requires a full table rewrite on Postgres < 11,
  which acquires an ACCESS EXCLUSIVE lock. On large tables, this can take significant time and block all operations.

Safe alternative:
  1. Add the column without a default:
     ALTER TABLE users ADD COLUMN admin BOOLEAN;

  2. Backfill data in batches (outside migration):
     UPDATE users SET admin = <value> WHERE admin IS NULL;

  3. Add default for new rows only:
     ALTER TABLE users ALTER COLUMN admin SET DEFAULT <value>;

  Note: For Postgres 11+, this is safe if the default is a constant value.
```

## Parse Errors

If a migration file contains invalid SQL, diesel-guard reports the file name and
points to the exact failing statement:

```
× Failed to parse SQL: Invalid statement: syntax error at or near "@"
╭─[migrations/2024_01_01_create_users/up.sql:3:1]
2 │ CREATE TABLE b ();
3 │ CREATE TABLE @bad;
  ·              ▲
  · problematic SQL
╰─
help: Check that your SQL syntax is valid
```

## JSON Output

For CI/CD or programmatic processing:

```sh
diesel-guard check migrations/ --format json
```

## Inspect the AST

Use `dump-ast` to see the pg_query AST as JSON — essential for writing [custom checks](custom-checks.md):

```sh
diesel-guard dump-ast --sql "CREATE INDEX idx_users_email ON users(email);"
diesel-guard dump-ast --file migration.sql
```

Example output:

```json
[
  {
    "IndexStmt": {
      "access_method": "btree",
      "concurrent": false,
      "idxname": "idx_users_email",
      "if_not_exists": false,
      "index_params": [
        {
          "node": {
            "IndexElem": {
              "name": "email",
              ...
            }
          }
        }
      ],
      "relation": {
        "relname": "users",
        "relpersistence": "p",
        ...
      },
      "unique": false,
      ...
    }
  }
]
```

The AST structure shown here tells you exactly which fields are available when writing custom Rhai checks. For example, `node.IndexStmt.concurrent` maps to the `concurrent` field above.