Rename a PostgreSQL column across mixed-version Quarkus releases with expand-contract migrations, a temporary trigger, a backfill, and real database tests.
The trigger doing double duty on both inserts and updates is the part most expand-contract writeups skip. Handling the insert case is the easy half, catching a legacy instance updating full_name after a bridge instance already wrote display_name is where most naive implementations quietly lose data, and the IS DISTINCT FROM checks are exactly the right way to avoid the stale COALESCE trap.
The trigger doing double duty on both inserts and updates is the part most expand-contract writeups skip. Handling the insert case is the easy half, catching a legacy instance updating full_name after a bridge instance already wrote display_name is where most naive implementations quietly lose data, and the IS DISTINCT FROM checks are exactly the right way to avoid the stale COALESCE trap.