I think the strongest version of this proposal is to make the contract explicit before trying to make every SDK behave identically. The main question is whether a builder is intended to be a reusable query description or a single-use mutable request. Both models can work, but silently sharing a mutable builder across tasks is the dangerous case. A practical path could be: - Document the current mutation and reuse semantics for each SDK. - Add an explicit clone/fork operation first, with tests proving that filters, modifiers, headers, and pagination state do not leak between branches. - Treat copy-on-write as a follow-up where the SDK maintainers are comfortable with the allocation and compatibility cost. - Add a concurrency-focused test that starts from one base query and builds two branches with different filters and ranges, then verifies the generated requests independently. I would also avoid promising identical method behavior across all languages until the underlying request-builder types have the same lifecycle and ownership model. An explicit clone API plus clear documentation would solve the immediate race/cross-contamination problem while leaving room for copy-on-write in SDKs where it fits naturally.
The linked pg_net discussion appears to apply to unaccent as well: on hosted projects, the extension objects are owned by the internal supabase_admin role, so the postgres role cannot reliably revoke privileges that were granted by that owner. The warning and unchanged ACL are consistent with that ownership boundary. The important distinction is that a PUBLIC EXECUTE grant is not automatically a Data API exposure. Since extensions is not in db_schema, PostgREST should reject direct REST or RPC access to those functions. I would still treat that as an exposure boundary, not as a reason to assume the ACL can be changed from a migration. For the least-privilege check, I would: - Keep extensions out of db_schema unless there is a specific reason to expose it. - Avoid SECURITY DEFINER functions in public or graphql_public that call extensions.unaccent(...) without tightly restricting EXECUTE. - Explicitly grant EXECUTE only to the application roles that need your own wrapper functions, rather than trying to rewrite the extension-owned ACL. - Re-check the ACL after an extension upgrade or reinstall, since the platform may recreate extension objects. I would not stop migrations over this alone, but I would ask Supabase Support to confirm whether the unaccent ACL is platform-managed and whether they consider it an expected default. If Support removes or changes it, verify the result again after the next extension lifecycle event.
I think a lightweight validation step would be worthwhile, but I would keep it focused on install and upgrade behavior rather than trying to lint arbitrary SQL patterns. The pgmq failure is a good example: the static DROP FUNCTION statements assumed a single signature, while newer pgmq versions introduced an overload. A useful check could install each extension into a clean database for the supported PostgreSQL versions, run the extension's after-create.sql, and then exercise the upgrade/reset path. That would catch failures caused by overloaded functions, changed argument types, or objects that are no longer extension members. For the SQL itself, a lint rule could flag hardcoded function drops when an extension has multiple matching entries in pg_proc, but I would treat that as a warning rather than a correctness rule. Some scripts intentionally target one specific signature, and the authoritative check is whether the object is registered in pg_depend for that extension. So my preference would be: 1. Add a regression fixture for each extension script that runs on the supported PostgreSQL versions. 2. Include at least one overloaded-function case in the fixture set. 3. Add optional static checks for suspicious hardcoded signatures, with an escape hatch for intentional cases. That gives us protection against the class of bug without requiring every extension to follow one rigid implementation pattern.