Semantic Diff

The diff command compares SQL files between git commits and reports semantic changes: tables added/removed, WHERE clauses dropped, JOIN types changed, columns added to SELECT.

Quick Start

# Compare main branch to current HEAD
lexega-sql diff main..HEAD models/ -r

# Compare specific commits
lexega-sql diff abc123..def456 models/ -r

# JSON output for CI/CD
lexega-sql diff main..HEAD -o json

# PostgreSQL projects
lexega-sql diff main..HEAD models/ -r --dialect postgresql

Comparison to git diff

git diff shows text changes:

- SELECT id, name FROM users WHERE active = true
+ SELECT id, name, email FROM users

Semantic diff reports structured change types:

─── models/users.sql ───
  🟢 DIFF-COL-ADD New column added to output.
  🟠 DIFF-WHERE-RMV WHERE clause removed. Query is now unbounded.

Detected Changes

Change TypeRisk LevelDescription
DIFF-WHERE-RMVHIGHQuery lost filtering — may return unbounded results
DIFF-WRITE-WHERE-RMVCRITICALDELETE/UPDATE lost WHERE clause
DIFF-COL-ADDLOWNew column in SELECT
DIFF-JOIN-CROSS-ADD / DIFF-JOIN-NARROW / DIFF-JOIN-TYPE-CHGCRITICAL/HIGH/MEDIUMCRITICAL: →CROSS JOIN; HIGH: LEFT/SEMI/ANTI→INNER; MEDIUM: other
DIFF-LIMIT-RMV-MULTI / DIFF-LIMIT-RMVCRITICAL/HIGHCRITICAL: multi-table (cartesian risk); HIGH: single-table
DIFF-TBL-ADDLOWNew table in query
DIFF-COL-RMVLOWColumn removed from SELECT

CI/CD Integration

# GitHub Actions example
name: SQL Semantic Review
on: pull_request

jobs:
  semantic-diff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Need full history
      
      - name: Semantic Diff
        run: lexega-sql diff origin/main..HEAD models/ -r --policy .lexega/policy.yml --env prod --decision-out .lexega/decisions/
        env:
          LEXEGA_LICENSE_KEY: ${{ secrets.LEXEGA_LICENSE_KEY }}
        # Exit code 2 = blocked by policy, 0 = passed

Jinja/dbt Support

The diff command renders Jinja templates on both sides before comparison, so semantic changes are computed on the rendered SQL, not template source.

Need Help?

Can't find what you're looking for? Check out our GitHub or reach out to support.