$--- title: Conversion Philosophy outline: deep
Conversion Philosophy
SQL development often follows the same pattern: build a SELECT to understand the rows that matter, then translate it into INSERT, UPDATE, DELETE, or MERGE. That process makes the original query vanish, leaving only the opaque mutation and the WHERE clause that filters it.
Why the SELECT-first habit feels broken
- CUD statements hide what data they actually read or write, because the read path is implicit and often spans joins, subqueries, or CTEs that become invisible once rewritten as mutation syntax.
- Developers naturally rely on
SELECTqueries to inspect data before applying a mutation; rewriting those queries into DML destroys the readable representation and makes debugging harder. - When you inspect a bug, you often take the mutation, tear out the
UPDATE/DELETE/INSERT, and rebuild aSELECTto observe the data. That back-and-forth is inefficient. - SQL compatibility issues make it tempting to keep
SELECTqueries as the truth and convert them to CUD as the final step instead of writing mutation-first code.
How conversion helpers unlock a better workflow
- Conversion helpers let you keep the readable
SELECTas the primary asset and generate the DML only when you need to run it, so side-effect-free observations stay in sync with the mutation semantics. - Because the
SELECTis the source of truth, debugging stays focused on projections and predicates, not on tracing through an opaqueUPDATEorMERGEstatement. - Because the library preserves the
SELECTas an AST, the mutation conversion is always derived from a structured representation rather than string rewriting. - Maintaining a single
SELECTand deriving mutations from it reduces duplication, avoids manual translation errors, and keeps the codebase aligned with tooling that operates on result rows. - When compatibility concerns arise, you can still run the conversion helper to emit the exact
INSERT/UPDATE/DELETE/MERGEflavors your platform expects while the test harness continues to work with the fixture-backedSELECT.
The promise of SELECT-centric tooling
This philosophy makes the SELECT the canonical representation of data shape, letting you:
- Keep your test fixtures, analyzers, and debugging efforts focused on the deterministic result set rather than the mutation syntax.
- Reuse the same select-based AST for both runtime engines (
QueryBuilder) and testing utilities (SelectConverter). - Eliminate the need for dual maintenance of a
SELECTand a matching mutation, because conversion helpers keep them in lockstep.
Ultimately, the library treats SELECT as the pure, observable contract and uses conversion helpers to derive the mutating operations only when needed. This also aligns testing with reality: if a mutation can be expressed as a SELECT, then its correctness can be validated without a database, using fixtures that describe nothing more than the data shape itself.