Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/cli/docs/supabase/db/diff.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ By default, all schemas in the target database are diffed. Use the `--schema pub

Projects created by a recent `supabase init` default to the pg-delta diff engine (`[experimental.pgdelta] enabled = true` in `config.toml`). Existing projects are unaffected and keep using migra unless they opt in. To fall back to the legacy migra engine, set `enabled = false` under `[experimental.pgdelta]`, or pass `--use-migra` for a single run.

With the bundled pg-delta engine, diff SQL defaults to lowercase keywords and a maximum width of 180, matching its declarative export. When `-f` writes migrations, execution-aware transaction semantics are preserved as ordered per-unit files; non-transactional units carry a directive that the CLI apply path honors. Flattened review output retains the rendered SQL and preambles, but not the unit boundaries supplied to a migration runner. Configure overrides with `[experimental.pgdelta] format_options`, or set `format_options = "null"` to emit raw, unformatted statements.
With the bundled pg-delta engine, diff SQL defaults to uppercase keywords, indent 2, a maximum width of 180, trailing commas, and column/key alignment, matching its declarative export. When `-f` writes migrations, execution-aware transaction semantics are preserved as ordered per-unit files; non-transactional units carry a directive that the CLI apply path honors. Flattened review output retains the rendered SQL and preambles, but not the unit boundaries supplied to a migration runner. Configure overrides with `[experimental.pgdelta] format_options`, or set `format_options = "null"` to emit raw, unformatted statements.

While the diff command is able to capture most schema changes, there are cases where it is known to fail. Currently, this could happen if you schema contains:

Expand Down
2 changes: 2 additions & 0 deletions apps/cli/docs/supabase/db/schema-declarative-generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ Exports the schema of a live database (local, linked, or custom URL) into SQL fi

The bundled pg-delta engine writes one directory per schema at the root of that directory (`supabase/schemas/public/tables/users.sql`, `supabase/schemas/public/schema.sql`), with cluster-level objects that belong to no schema under a reserved `_cluster/` directory (`supabase/schemas/_cluster/roles.sql`). A schema literally named `_cluster` or `_custom`, in any casing, has its leading underscore percent-encoded (`%5Fcluster/`) so it can never claim a directory the export owns. Hand-authored SQL that pg-delta does not model belongs in `_custom/`, which the export never writes to and never prunes.

Emitted SQL uses the same default format as `db pull` (uppercase keywords, indent 2, width 180, column-aligned). Override with `[experimental.pgdelta] format_options`, or set `format_options = "null"` for raw statements.

Requires `--experimental` flag or `[experimental.pgdelta] enabled = true` in config.
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@parcel/watcher": "^2.6.0",
"@supabase/api": "workspace:*",
"@supabase/config": "workspace:*",
"@supabase/pg-delta": "1.0.0-alpha.42",
"@supabase/pg-delta": "1.0.0-alpha.46",
"@supabase/pg-topo": "1.0.0-alpha.5",
"@supabase/process-compose": "workspace:*",
"@supabase/stack": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { LegacyPgDeltaImplementation } from "../../../../shared/legacy-pgdelta-next-flag.ts";
import { legacySchemaToCsvField } from "../../../../shared/legacy-schema-flags.ts";
import { legacyDeclaredSqlExtensions } from "../../shared/legacy-pgdelta-declarative-shadow-prep.ts";
import type { LegacyPgDeltaRemovalSummary } from "../../shared/legacy-pgdelta-engine.service.ts";

/** Extensions that legacy pg-delta treated as part of its implicit Supabase baseline. */
Expand Down Expand Up @@ -159,18 +160,6 @@ function matchImplicitExtension(message: string): LegacyImplicitExtensionMatch |
};
}

/**
* Masks SQL comments and strings while preserving offsets. Extension declarations
* are DDL, so occurrences inside comments, quoted values, and dollar bodies must
* not suppress compatibility guidance.
*/
function maskSqlNonCode(sql: string): string {
return sql.replaceAll(
/--[^\r\n]*|\/\*[\s\S]*?\*\/|'(?:''|[^'])*'|\$(?:[a-zA-Z_][\w$]*)?\$[\s\S]*?\$(?:[a-zA-Z_][\w$]*)?\$/g,
(matched) => matched.replaceAll(/[^\r\n]/g, " "),
);
}

function maskSqlComments(sql: string): string {
return sql.replaceAll(/--[^\r\n]*|\/\*[\s\S]*?\*\//g, (matched) =>
matched.replaceAll(/[^\r\n]/g, " "),
Expand All @@ -180,16 +169,7 @@ function maskSqlComments(sql: string): string {
export function legacyDeclaredExtensions(
files: readonly LegacyDeclarativeSqlFile[],
): ReadonlySet<string> {
const declared = new Set<string>();
const pattern =
/\bCREATE\s+EXTENSION\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:"([^"]+)"|([a-zA-Z_][\w$-]*))/gi;
for (const file of files) {
for (const match of maskSqlNonCode(file.sql).matchAll(pattern)) {
const extension = match[1] ?? match[2];
if (extension !== undefined) declared.add(extension.toLowerCase());
}
}
return declared;
return legacyDeclaredSqlExtensions(files);
}

function declaredImplicitExtensions(
Expand Down
Loading
Loading