CONCEPT Cited by 1 source
Semantic schema diff¶
Definition¶
A semantic schema diff is the set of SQL DDL
statements (ALTER TABLE, CREATE TABLE, DROP TABLE,
ALTER VIEW, etc.) that transform one database schema
into another. It contrasts with a textual diff (as
produced by git diff on two CREATE TABLE definitions),
which captures line-level differences but cannot be
executed against a database.
Canonical verbatim framing (Noach, 2023 PlanetScale):
*"The
git diffof the two would be:CREATE TABLE `customer` ( `id` int, + `name` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) );But that's not something a database can work with. Instead, the deploy request generates this semantic SQL diff:
ALTER TABLE `customer` ADD COLUMN `name` varchar(255) NOT NULL DEFAULT ''This semantic diff is generated for any deploy request."* (Source: sources/2026-04-21-planetscale-database-branching-three-way-merge-for-schema-changes)
Why it matters¶
Three properties make the semantic diff the right primitive for schema-change orchestration:
- Executable. Unlike a textual diff, the semantic diff can be passed to a MySQL / Postgres client and applied. This is the whole point: the diff is the thing that gets deployed.
- Compositional. The semantic diff is a function
schema → schema. Two diffs can be composed (diff2 ∘ diff1) and tested for commutativity — the foundation of the schema three-way merge conflict check. - Introspectable. Each DDL statement is a formal
object (
ALTER TABLE,CREATE INDEX, …) that can be analysed individually — enabling identical- overlap detection and equivalence- class partitioning inside a multi-change deploy.
Contrast with textual diff¶
| Property | Textual diff | Semantic schema diff |
|---|---|---|
| Unit | Line | DDL statement |
| Executable | No — produces patch hunks | Yes — directly applicable |
| Sensitive to formatting | Yes (whitespace, ordering) | No (two equivalent CREATE TABLEs with different formatting produce no diff) |
| Composability | Purely textual (hunks can be reordered, not composed as functions) | Functional composition over schemas |
| Conflict detection | Line-overlap heuristics | Diff composition commutativity |
The textual diff would misfire in both directions: it flags noise (whitespace) as changes, and it can miss real conflicts (two branches adding the same column with semantically different but textually similar DDL).
Generating the diff¶
PlanetScale uses schemadiff,
a pure-Go Vitess library. Inputs: two schema strings
(typically "current production state" and "desired
state from the deploy-request branch"). Output: the
sequence of DDL statements (CREATE TABLE, ALTER
TABLE, ALTER VIEW, DROP TABLE, etc.) to transform
the first into the second.
The library enforces validity at every step by maintaining an in-memory schema representation and mutating it statement-by-statement — catching invalid intermediate states before any DDL is issued against production.
Role in the deploy pipeline¶
- Developer branches from
mainand edits schema. - On deploy-request submission,
schemadiffcomputesdiff(main, branch)as a semantic SQL diff. - The deploy-request UI shows the semantic diff
(
ALTER TABLE foo …,CREATE TABLE bar (…), …) as the review artefact. - The three-way merge check composes this diff with any pending diffs in the queue to detect conflicts.
- If admitted, the semantic diff is executed by Vitess's Online DDL machinery against production.
Limitations¶
- Vendor-specific DDL grammar.
schemadiff's semantic diff is MySQL-flavoured. View semantics, FK semantics, charset / collation semantics all follow MySQL rules. Postgres generalisation in PlanetScale Postgres / Neki is not disclosed in the post. - No data-level diff. This concept covers schema only. Data changes (row inserts, updates) are out of scope — PlanetScale branching snapshots the schema, not the data.
- Operator-policy layer on top. Whether two diffs really conflict is not purely a syntactic question. PlanetScale's index-ordering-exemption is a policy decision that the semantic diff alone would not encode.
Seen in¶
- sources/2026-04-21-planetscale-database-branching-three-way-merge-for-schema-changes
— canonical framing: textual
git diffis "not something a database can work with"; the deploy request replaces it with a semantic SQL diff (ALTER TABLE … ADD COLUMN …). This diff is the primitive over which the three-way merge commutativity check is defined.