Discovered while testing #3973's fix
The PR for #3973 restores WITH (...) on newly created views. A related but distinct gap remains: when a view already exists and only its reloptions change, db diff emits nothing.
Repro
- Declare a view with
with (security_invoker=true), run supabase db diff -f initial and apply the migration.
- Change the schema file to
with (security_invoker=false) (or any other reloption swap).
- Run
supabase db diff -f update_view.
Expected
The diff captures the reloption change, e.g.:
ALTER VIEW "public"."user_details" SET (security_invoker=false);
Actual
The old value (true) silently persists in the database. For security_invoker specifically, that means a view can remain SECURITY DEFINER after the user thinks they've moved it to SECURITY INVOKER — same risky failure mode as #3973, just on updates instead of creations.
Root cause
The underlying diff engines used by db diff (djrobstep/migra, @pgkit/migra) do not read pg_class.reloptions when comparing views, so reloption-only differences are invisible to them. The #3973 fix paper-overs this for the create path by re-attaching reloptions from the live target catalog into emitted CREATE VIEW statements; there is no CREATE VIEW statement to patch in the update case.
Possible directions
- Extend the post-processor to also diff source-vs-target reloptions and emit
ALTER VIEW ... SET (...) / RESET (...) for reloption-only changes.
- Or, accept this as one more reason to move declarative-schema workflows over to pg-delta (per commit 6c19b38), and document the migra limitation in the meantime.
Discovered while testing #3973's fix
The PR for #3973 restores
WITH (...)on newly created views. A related but distinct gap remains: when a view already exists and only its reloptions change,db diffemits nothing.Repro
with (security_invoker=true), runsupabase db diff -f initialand apply the migration.with (security_invoker=false)(or any other reloption swap).supabase db diff -f update_view.Expected
The diff captures the reloption change, e.g.:
Actual
The old value (
true) silently persists in the database. Forsecurity_invokerspecifically, that means a view can remainSECURITY DEFINERafter the user thinks they've moved it toSECURITY INVOKER— same risky failure mode as #3973, just on updates instead of creations.Root cause
The underlying diff engines used by
db diff(djrobstep/migra, @pgkit/migra) do not readpg_class.reloptionswhen comparing views, so reloption-only differences are invisible to them. The #3973 fix paper-overs this for the create path by re-attaching reloptions from the live target catalog into emittedCREATE VIEWstatements; there is noCREATE VIEWstatement to patch in the update case.Possible directions
ALTER VIEW ... SET (...)/RESET (...)for reloption-only changes.