# `Electric.Replication.Eval.SqlGenerator`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.6.2/packages/sync-service/lib/electric/replication/eval/sql_generator.ex#L1)

Converts a parsed WHERE clause AST back into a SQL string.

This is the inverse of `Parser` — where `Parser` turns SQL text into an AST,
`SqlGenerator` turns that AST back into SQL text. Used whenever the server
needs to embed a condition in a generated query (snapshot active_conditions,
move-in exclusion clauses, etc.).

Uses precedence-aware parenthesization to produce minimal, readable SQL.
Parentheses are only added when needed to preserve the AST's evaluation order.

Must handle every AST node type that `Parser` can produce. Raises
`ArgumentError` for unrecognised nodes so gaps are caught at shape
creation time, but the property-based round-trip test (see Tests below)
enforces that no parseable expression triggers this error.

# `to_sql`

```elixir
@spec to_sql(term()) :: String.t()
```

Convert an AST node to a SQL string.

Handles: comparison operators (=, <>, <, >, <=, >=), pattern matching
(LIKE, ILIKE, NOT LIKE, NOT ILIKE), nullability (IS NULL, IS NOT NULL),
membership (IN), logical operators (AND, OR, NOT), boolean tests
(IS TRUE, IS FALSE, IS UNKNOWN, etc.), column references, constants
(strings, integers, floats, booleans, NULL), type casts, arithmetic
operators (+, -, *, /, ^, |/, @, &, |, #, ~), string concatenation (||),
array operators (@>, <@, &&), array/slice access, DISTINCT/NOT DISTINCT,
ANY/ALL, and sublink membership checks.

Raises `ArgumentError` for unrecognised AST nodes.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
