KASHII UPDATEZ Everyday Student Requirements & Python Coding Tutorials by Python Kashi
← Back to Tech Blog Database & SQL

sqlfluff/sqlfluff Architecture: AST Parsing, Lexer State Machines & Dialect Normalization

Analyzing the 10,000+ star repository: How sqlfluff solves the notoriously difficult challenge of tokenizing, parsing, and linting multi-dialect SQL statements through recursive AST state machines.

Kashinath Chavan
Kashinath Chavan
Founder & Software Architect • ⏱️ 3 min read • Oct 06, 2026
Follow on Instagram ↗
sqlfluff/sqlfluff Architecture: AST Parsing, Lexer State Machines & Dialect Normalization
## Why SQL Is the Hardest Language to Parse Parsing general-purpose programming languages like Python or Go is relatively straightforward: they have formal context-free grammars, strict token definitions, and a single reference compiler. SQL, in contrast, is an anarchic collection of dozens of conflicting dialects: - PostgreSQL supports dollar-quoted strings (`$$body$$`) and custom operator definitions. - Snowflake and BigQuery introduce bespoke syntax for semi-structured JSON traversing (`col:field.subfield`). - MySQL allows backtick identifiers (`SELECT `col` FROM `table``), while ANSI SQL reserves backticks. - In production, SQL is often wrapped in Jinja template tags (`{% if is_prod %} ... {% endif %}`). This is the monumental challenge solved by **[`sqlfluff/sqlfluff`](https://github.com/sqlfluff/sqlfluff)** (10,000+ ⭐)—the open-source dialect-flexible SQL linter and auto-formatter. --- ## 1. The 4-Stage SQLFluff Parser Pipeline SQLFluff transforms raw SQL string buffers into formatted code through four decoupled stages: 1. **Templating (Jinja/dbt):** Slices out Jinja macros and tracks string position maps so errors in compiled SQL map back to original source template lines. 2. **Lexing:** Converts raw character streams into continuous segments (`WhitespaceSegment`, `KeywordSegment`, `IdentifierSegment`). 3. **Grammar Parsing:** Uses recursive grammar matchers (`Sequence`, `OneOf`, `AnyNumberOf`, `Ref`) to construct a concrete Syntax Tree (CST). 4. **Rule Linting & Auto-Fixing:** Crawls the syntax tree, checks style/correctness rules (e.g. indentation, column quoting, reserved keyword capitalization), and applies atomic tree transformations. ```python import sqlfluff query = """ select id, company_name, salary_usd, posted_date from public.job_postings where is_active = true and deadline > now() order by posted_date desc limit 10 """ # Lint SQL query against ANSI dialect rules lint_errors = sqlfluff.lint(query, dialect="postgres") for err in lint_errors: print(f"Line {err['line_no']}: [{err['code']}] {err['description']}") # Auto-format and fix keywords to standard uppercase fixed_sql = sqlfluff.fix(query, dialect="postgres") print("=== Formatted SQL ===") print(fixed_sql) ``` --- ## 2. Dialect Inheritance Hierarchy Rather than rewriting grammar definitions for every database vendor from scratch, SQLFluff employs an **Object-Oriented Dialect Inheritance Tree**: - The **`ansi`** dialect defines baseline SQL-92 / SQL-99 grammar. - The **`postgres`** dialect inherits from `ansi`, overriding specific rules (e.g. adding `ILIKE`, `ON CONFLICT DO NOTHING`, and JSONB operator grammars). - The **`redshift`** dialect inherits from `postgres`, modifying syntax rules specific to AWS data warehouses. This inheritance architecture allows SQLFluff to support 25+ dialects with minimal code duplication. --- ## 3. Key Takeaways from `sqlfluff/sqlfluff` 1. **Maintain Position Mapping Across Preprocessors:** When compiling or linting templated code, always preserve byte offset mappings back to the user's source file. 2. **Inheritance for Dialect Trees:** Base grammar plus override leaves creates scalable multi-dialect compilers. 3. **Explore the Repository:** [github.com/sqlfluff/sqlfluff](https://github.com/sqlfluff/sqlfluff)
Topics: #Ast #Compilers #Databases #Github-Repo #Sql #Sqlfluff
👁️ 3981 views •

More from Database & SQL

Chat Chat with Kashii