What does validation have to prove?
That every object in scope gives the same output on the same input, and that anyone can check it. That sentence has four parts, and each can fail on its own.
“Every object in scope” needs an agreed list. “The same output” needs a defined comparison, with tolerances. “The same input” needs a frozen snapshot that both sides read. “Anyone can check it” needs evidence a person who did not do the work can read.
One limit belongs beside any validation claim. Matching the original shows equivalence on the tested inputs. It does not show that the original was right. Known defects carry over, and should be fixed afterwards as separate, logged changes.
Method. This note compares five families of validation, using the published documentation of the main platform tools (Databricks Lakebridge, Databricks Genie Migrate, Snowflake SnowConvert AI) and the research literature on proving query equivalence. It uses no Novuz customer data.
Method 1: summary checks
Summary checks compare row counts and totals between the old and new tables: how many rows, the sum of an amount column, the number of distinct customers.
They are fast and cheap, and they catch gross errors such as a missing load or a duplicated batch. They are also the method most likely to give false comfort. A join that assigns one customer’s balance to another keeps the row count exact. Two wrong rows can add up to the right total.
- Proves
- That the volume and the headline totals agree
- Misses
- Wrong rows with the right total, swapped values, rounding differences that cancel out
- Use it for
- A first pass on every table, and as a cheap gate before more expensive checks
Method 2: table reconciliation
Table reconciliation compares the old and new versions of a table more closely: the schema, a hash of every row, or row-by-row values matched on key columns.
Databricks’ free Lakebridge tool is a good example of this method. Its Reconcile module offers four report types. A schema report compares column names and data types. A row report compares a hash of each row and needs no join key. A data report compares row and column values using join columns, with mismatch detail per column. An all report runs the data and schema checks together.
Lakebridge’s documentation also shows where the method needs care. For Teradata, row-hash reports need a hash function the user installs. For BigQuery, some types cannot be compared exactly, and some lossy matches, such as a DATETIME column against a timestamp, can be reported as matches and should be checked by hand.
Snowflake’s SnowConvert AI offers a similar data validation step, run from its command line, with results written to Snowflake tables. Databricks’ documentation for Genie Migrate advises running the converted code and comparing results with the source.
- Proves
- That a table on the new platform holds the same rows and values as on the old one
- Misses
- Which procedure, package or job produced a difference, and why
- Use it for
- Data movement, and as evidence that the target tables match at cutover
Method 3: per-object reconciliation
Per-object reconciliation goes one level deeper. Instead of comparing the final tables, it runs each converted object (a procedure, a package, a script or a job) and its original on the same frozen inputs, and compares what each one produces.
This is what a migration of logic needs, because it ties every difference to the object that caused it. A failed check points to one procedure and one line, not to a table that thousands of objects touched.
It is also more work to set up. Each object needs inputs that exercise its risky branches, and each comparison needs agreed tolerances. The checks usually run in tiers, cheapest first, and stop an object at its first failure.
- Schema: names, types, precision, scale and nullability of each output.
- Row counts: per output table, and per partition or business date on large tables.
- Column aggregates: sums, counts, distinct counts, minimums and maximums on numeric and key columns.
- Rows: sampled rows matched on keys, or keyed row hashes where every row matters, such as ledgers and regulatory returns.
- Business checks: the queries the business owner already trusts, run on both sides.
This is the method Novuz uses, stated so readers can weigh this note: every converted object gets a report marked pass, fail or review, on agreed inputs, with each miss listed by line.
Method 4: parallel running
In a parallel run, the old and new systems both run in production for a period, and someone compares their outputs as real data flows through.
Parallel runs catch problems no test data predicted, because they see real inputs. They are also the most expensive method. Every month of a parallel run means paying for two platforms and two teams. Without an agreed pass rule, they end when someone gets tired, not when the numbers are proven.
Parallel runs work best when they are short and narrow: one domain at a time, for as long as finance needs to close a period or two, after per-object reconciliation has already cleared the logic.
- Proves
- That the new system matches the old on real production inputs, for the period observed
- Misses
- Branches that real data did not exercise during the run
- Use it for
- The final weeks before each domain cuts over
Method 5: formal proof of query equivalence
The strongest possible check would prove that two queries give the same result for every possible input, not just the inputs tested. Researchers have worked on this for decades.
The best-known recent example is Cosette, from the University of Washington, presented at CIDR 2017. Cosette takes two SQL queries and returns “equivalent”, “inequivalent” or “unknown”. When the queries differ, it produces a counterexample input. When they match, it aims to produce a machine-checked proof.
Its authors are clear about the limits. Equivalence for arbitrary SQL queries is undecidable, so no tool can settle every case. Cosette did not yet handle string operations such as LIKE, ORDER BY or floating-point numbers, and some proofs needed human help: in one set of 23 equivalent query pairs, 17 were proven automatically.
Formal methods are valuable research and useful for checking query rewrites. They are not yet a practical way to validate thousands of procedures with loops, temporary tables and error handling. Migrations still rely on testing with well-chosen inputs.
How do the methods compare?
Most migrations need more than one. The table sets out what each proves and when it pays.
| Method | What it proves | What it misses | Cost | Best use |
|---|---|---|---|---|
| Summary checks | Volumes and totals agree | Wrong rows with the right total | Low | First pass on every table |
| Table reconciliation | Tables hold the same rows and values | Which object caused a difference | Medium | Data movement and cutover evidence |
| Per-object reconciliation | Each converted object matches its original on the same inputs | Branches the inputs did not exercise | Medium to high | Converted logic: procedures, packages, jobs |
| Parallel running | The new system matches on real production data | Branches real data did not hit during the run | High | The last weeks before each domain cuts over |
| Formal equivalence proof | Two queries match for every input | Most real procedures; undecidable in general | Research-grade | Checking individual query rewrites |
Why do validations fail?
In our reading of published guidance and our own experience, the same few mistakes recur.
- Comparing two different days. If the source loads overnight between reads, every mismatch is noise. Pin both sides to one snapshot.
- Normalizing away real differences. Trimming every string or rounding every decimal can hide real errors. Normalize only for documented, agreed differences, and show each rule in the report.
- Ignoring type and collation rules. A DECIMAL that lands as a DOUBLE, or a case-insensitive comparison that becomes case-sensitive, changes results quietly.
- Testing only easy objects. A validation that never runs the error path or the dynamic SQL proves nothing about them.
- Defining success afterwards. Tolerances agreed after the first failure are negotiations, not tests.
What are the limits of this note?
Tool capabilities change. The descriptions of Lakebridge, SnowConvert AI and Genie Migrate come from their documentation as published in November 2026; check the current version before relying on them.
The comparison of methods is qualitative. We know of no public study that measures how often each method misses errors in real warehouse migrations.
