Multi-Phase Conversion Pipeline

Every SQL file goes through five distinct phases instead of one giant LLM call, so mistakes get caught before they ship, dependencies get resolved in the right order, and every output file comes with an honest confidence grade.

A single-shot "convert this SQL to PySpark" prompt is fast, but it has no way to check its own work, no way to know what a referenced view or procedure actually looks like once converted, and no way to safely apply a fix without risking the file it's trying to improve. 3XCode CLI splits the job into five phases: discovery, planning, conversion, validation, and auto-fix, each a fresh, focused pass over the file. The result is code that's converted in the right dependency order, checked against real cross-file signatures instead of guesses, and never silently marked "done" when it isn't.

5
pipeline phases per file
10
source platforms fingerprinted
3
validation stages before auto-fix
A+–F
confidence grade per output file

The Five Phases

1. Discovery

Reads the SQL file and builds a structured inventory of every convertible object (procedures, functions, views, triggers) with exact line boundaries, parameters, cross-references, and complexity scoring. Also detects the source dialect and, separately, fingerprints the specific source platform (Databricks, Snowflake, SQL Server, Oracle, and more) with zero extra LLM cost.

2. Planning

Builds the dependency graph across every discovered object and sorts conversion into levels: views and standalone functions first, then anything that depends on them. Writes targeted, per-object conversion instructions so later phases never need the full knowledge base shipped to them.

3. Conversion

Produces the actual PySpark code, one output file per group of related objects, processed strictly in dependency-tier order. Each file's prompt includes the real function signatures of anything it depends on, never a guess, so cross-file calls are correct from the first draft.

4. Validation

A three-stage review of every generated file: free local syntax and pattern checks, dependency-signature cross-checking against files it calls into, and a full Claude review against the validation checklist and known gotcha list, returning structured, per-issue severity.

5. Auto-Fix

Files with HIGH or ERROR-severity issues get a targeted fix pass, only for issues classified as safely auto-fixable. Fixes are verified before they ever touch disk: a syntax check and a truncation guard both have to pass, or the original file is left untouched.

Why Order Matters

Planning doesn't just list what needs converting. It topologically sorts every object into dependency levels, following a fixed precedence: views → functions → procedures → triggers. A procedure that selects from a view needs the view's converted PySpark signature to exist before it can be correctly converted or validated, so the pipeline never converts a consumer before what it depends on. The same principle carries through to conversion: groups are processed in dependency tiers (utilities, then standalone objects, then the main pipeline), and a signature registry is snapshotted after each tier so every later file sees the real signatures of what it calls, not a guess.

1

Views

No dependencies, converted first

2

Functions

Depend only on views, if at all

3

Procedures

May call views and functions

4

Triggers

Converted last, everything else is known

Whenever a plan or the initial discovery pass can't be fully validated, the pipeline degrades gracefully instead of failing outright: salvaging every object that does parse correctly, or falling back to a simple sequential plan, so one bad object never takes down the whole file.

Running the Pipeline

By default, 3xcode pyspark convert runs all five phases. Several flags let you run just part of the pipeline, useful for a quick look at what would be converted, or for skipping a phase you don't need on a given run.

terminal
# Analysis only: discovery + planning, no code generated
3xcode pyspark analyze legacy_proc.sql

# Same effect via the convert command
3xcode pyspark convert legacy_proc.sql --dry-run

# Convert but skip phase 4 (validation)
3xcode pyspark convert legacy_proc.sql --skip-validation

# Convert but skip phase 5 (auto-fix)
3xcode pyspark convert legacy_proc.sql --skip-audit

# Run only specific phases
3xcode pyspark convert legacy_proc.sql --phases analyze,convert

Pipeline control flags

FlagDefaultWhat it does
--dry-runfalseRuns discovery + planning only: inspect what would be converted without generating any code.
--skip-validationfalseSkips phase 4 (validation). The file is still converted, just not reviewed.
--skip-auditfalseSkips phase 5 (auto-fix). Issues found in validation are reported but not auto-repaired.
--phasesnone (all phases run)Comma-separated list restricting the run to specific phases: `analyze,convert,validate,audit`.

Safety & Grading

Auto-fix never overwrites a file on a hope. A fix is only written to disk after it passes every guardrail, and if any check fails, the original file is left exactly as it was.

Verify before write

The fixed content must parse as valid Python and must not be more than 50% shorter than the original file. Either failure reverts the fix and leaves the original file untouched. The write to disk only happens after both checks pass.

Per-file confidence grade

Every generated file gets a completion percentage and a confidence percentage, built from syntax validity, correctness review, resolved dependencies, remaining TODOs, and any manual-review patterns like cursors or dynamic SQL. The lower of the two maps to a letter grade from A+ to F.

Issues that validation surfaces are never silently dropped, whether or not auto-fix can touch them. Each one is sorted into an action bucket: auto-fixed, requires manual attention (cursors, dynamic SQL, MERGE logic), needs infrastructure setup (Delta Lake, JDBC, streaming), or recommended for review, so you always know exactly what still needs a human look.