feat(cli): upgrade pg-delta next to alpha.46 - #6300
Conversation
Consume OWNED BY / load assist, drop the CLI parameter-ACL workaround, pretty-print generated SQL, and only strip image extensions when declarations recreate them.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f387bcc80e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const maskSqlNonCode = (sql: string): string => | ||
| sql.replaceAll( | ||
| /--[^\r\n]*|\/\*[\s\S]*?\*\/|'(?:''|[^'])*'|\$(?:[a-zA-Z_][\w$]*)?\$[\s\S]*?\$(?:[a-zA-Z_][\w$]*)?\$/g, | ||
| (matched) => matched.replaceAll(/[^\r\n]/g, " "), |
There was a problem hiding this comment.
Parse PostgreSQL lexical forms before detecting extensions
When a schema file contains PostgreSQL constructs this regex does not understand—such as nested block comments or E'...' strings with backslash-escaped quotes—it can expose a commented/string-literal CREATE EXTENSION pgcrypto to the following matcher. The prep then drops the image-default extension even though the file never recreates it, so a manifest-backed declarative sync can plan an unintended extension removal. Use a PostgreSQL-aware tokenizer, or at least correctly mask nested comments and escape strings, before deciding which defaults to drop.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d57990e. The masker now nests block comments and treats E'...' / e'...' backslash escapes as literals before CREATE EXTENSION detection.
There was a problem hiding this comment.
Follow-up in ec9946d: we dropped nested-comment / E-string / dollar-quote lexing. Detection is now -- / /* */ / simple '...' plus a regex. Pathological SQL is an accepted miss.
| yield* Effect.tryPromise({ | ||
| try: () => client.query(sql), | ||
| catch: (cause) => queryError(sql, cause), | ||
| }); |
There was a problem hiding this comment.
Make shadow-prep queries interruptible
When a DROP EXTENSION query blocks on a database lock, interrupting the command only interrupts the Effect: this tryPromise wrapper neither passes a cancellation signal nor installs cleanup for the in-flight pg query. Because the pool cannot release that connection until the query settles, Ctrl-C and sibling-fiber failure can leave scoped teardown hanging behind the blocked statement; adapt the query boundary so interruption cancels or closes the exact owned operation.
AGENTS.md reference: AGENTS.md:L68-L72
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d57990e. Prep checks out a pool client and release(error) on interrupt or socket error so a locked DROP cannot hang or crash the shared pool.
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@ec9946d8af48f8acf100bd966e814743737c0bc6Preview package for commit |
PG17 ships pgcrypto without pgjwt. Restoring pgjwt after every pgcrypto recreate invented a CREATE EXTENSION the project never declared.
Nested comments and E-strings were still leaking CREATE EXTENSION into prep drops. Checkout the shadow client so interrupt and socket errors cannot hang or crash the shared pool.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d57990ece8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ): ReadonlySet<string> => { | ||
| const declared = new Set<string>(); | ||
| for (const file of files) { | ||
| for (const match of maskSqlNonCode(file.sql).matchAll(CREATE_EXTENSION_RE)) { |
There was a problem hiding this comment.
Mask double-quoted identifiers before scanning extensions
Although the final tree now handles nested comments and escape strings, the masker still copies double-quoted identifiers verbatim. A valid declaration such as CREATE TABLE "CREATE EXTENSION pgcrypto" (id int); therefore matches this regex as if it declared pgcrypto; declarative shadow prep then drops the image-default extension even though no file recreates it, allowing the resulting sync plan to propose an unintended extension removal. Mask PostgreSQL quoted identifiers, including doubled quotes, before matching.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 6af0469. CREATE EXTENSION names are scanned while skipping double-quoted identifiers (including "" escapes), so a table named "CREATE EXTENSION pgcrypto" is not treated as a declaration. Quoted names like "uuid-ossp" still count.
There was a problem hiding this comment.
Reverted the quoted-ident scanner in ec9946d. CREATE EXTENSION detection is now comments + simple strings + a regex. A table named "CREATE EXTENSION pgcrypto" is an accepted false positive — not a real schema-file case.
A table named "CREATE EXTENSION pgcrypto" was treated as a declaration and could drop the image default. Scan keywords while skipping "..." spans.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6af0469c46
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (c === "$") { | ||
| const tagMatch = DOLLAR_TAG_RE.exec(sql.slice(i)); |
There was a problem hiding this comment.
Require a token boundary before masking dollar quotes
PostgreSQL permits $ inside unquoted identifiers, but this branch treats every $tag$ substring as a dollar-quote opener. For example, in the valid SQL CREATE TABLE foo$tag$(id int); CREATE EXTENSION pgcrypto; SELECT $tag$body$tag$;, masking starts inside foo$tag$ and consumes through the later delimiter, hiding the real extension declaration. Fresh evidence after the earlier lexical fixes is that the final scanner still lacks a preceding-identifier boundary check here; consequently shadow prep leaves the image extension installed, causing an unguarded declaration to fail or an IF NOT EXISTS ... WITH SCHEMA/VERSION declaration to silently retain the wrong baseline state.
AGENTS.md reference: apps/cli/AGENTS.md:L52-L53
Useful? React with 👍 / 👎.
| if (declared.has("pgcrypto") && !declared.has("pgjwt")) { | ||
| const installed = yield* queryShadow(client, INSTALLED_PGJWT_SQL); | ||
| restorePgjwt = rowHasPgjwt(installed.rows); |
There was a problem hiding this comment.
Honor explicit pgjwt drops before scheduling restoration
When a PG14 declarative tree recreates pgcrypto but also explicitly runs DROP EXTENSION IF EXISTS pgjwt—for example, custom SQL added alongside an exported pgcrypto declaration—declared contains pgcrypto but never records the DROP. This condition therefore marks the installed baseline pgjwt for restoration; prep removes it, the user's guarded DROP becomes a no-op, and the synthetic tail file recreates it, so the desired shadow still contains pgjwt and sync cannot plan the requested removal. Treat an explicit pgjwt DROP as non-restorable.
AGENTS.md reference: apps/cli/AGENTS.md:L52-L53
Useful? React with 👍 / 👎.
Shadow prep only needs comments and simple strings stripped before a regex. Nested comments, E-strings, and quoted-ident scanning were not worth the complexity.
Summary
@supabase/pg-deltafrom1.0.0-alpha.42to1.0.0-alpha.46sodb diff,db pull, anddb schema declarative generatepick up supabase-profile parameter-ACL filtering,OWNED BYwith the owning table, per-statement load fallback,vault_presence, and reconnect-on-stuck load assist.pgjwt/pgcrypto/uuid-ossp). Unconditional drops were planning destructiveDROP EXTENSIONand writingCREATE EXTENSIONthatdb startcannot replay.Extracted from #6274 so the engine upgrade can land on
developwithout the schema-first command stack.Linked issue
Supabase maintainer change; no public issue to close.
open-for-contributionlabel (or I'm a Supabase maintainer).Checklist
fix(cli): …).pnpm check:allandpnpm testpass for the workspace(s) I touched.