mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 14:19:11 +03:00
## What kind of change does this PR introduce? Bug fix. ## What is the current behavior? On a project whose database server statically checks `DO` blocks before running them (Multigres does), several Studio actions fail: - Creating a table shows "Failed to update API access privileges for new table", although the table is created. - Toggling Realtime for a table fails with `EXECUTE of a runtime-built statement inside a PL/pgSQL body is not supported`. - The same error blocks editing a role or schema (rename, owner, drop) and changing column privileges. All of these come from SQL that `@supabase/pg-meta` generates. Such a server only accepts a dynamic `EXECUTE` when it can prove the statement is fixed, and two shapes in our SQL prevent that: - parentheses around the payload: `execute(format(...))` - `%s` conversions in `format()` strings, which substitute raw text (for example `%s` fed by `<oid>::regclass`, by a `string_agg(...)` subselect, or by a variable holding a table list) ## What is the new behavior? `tablePrivileges.grant/revoke`, `columnPrivileges.grant/revoke`, `publications.update`, `roles.update/remove` and `schemas.update/remove` generate SQL with no parentheses around the payload and only `%I`/`%L` conversions: - Table and column privileges name the table with `%I.%I`, taking the schema and name from `pg_class`/`pg_namespace`. - The publication update loops over the tables to drop and to add, with the same `tables` semantics as before (`undefined` keeps the tables, `null` publishes all tables, a list replaces them, bare names resolve through the search path). - `schemas.remove` picks between `drop schema … cascade` and `… restrict` with two plain statements instead of a `%s` fed by a `CASE`. - The grant and revoke format strings are built with `literal()`, so a quote in a role name can't end the string early. The statements are equivalent on regular Postgres. ## Additional context - New tests: replacing, clearing and keeping a publication's tables, switching between a table list and all tables, and a test (no database needed) that fails if the generated SQL of any of these builders goes back to `execute(...)` or `%s`. - I ran the pg-meta tests against a local Postgres 17. A set of existing snapshot tests were recorded on Postgres 14 and fail there with and without this change (for example the new `MAINTAIN` privilege in table privileges), so CI is the real check for those. The tests covering the changed SQL pass. - Some other Studio SQL is blocked on such servers for different reasons (for example creating foreign servers, and `SET` inside a `DO` block). It isn't addressed here. --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>