Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
103 changes: 103 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,106 @@
2026-05-03 v1.0.19

Bug fixes:
- Refactored comment-related query construction into dedicated
helper methods on `Dump`:
`build_tables_standalone_query`,
`build_regular_views_query`,
`build_materialized_views_query`,
`build_view_column_comments_query`,
`build_sequences_standalone_query`,
and on `Table`: `build_indexes_bulk_query`.
- Kept `pg_description` joins scoped to relation comments by
filtering on `pg_description.classoid = 'pg_class'::regclass`
and `pg_description.objsubid = 0` to avoid catalog
collisions.
- Normalized SQL formatting in the new helper query strings.
- `Comparer::compare_grants` no longer runs a duplicate
`iter().find(...)` over `from_cols` for every TO column
whose own ACL is empty. The first scan was discarded
and the second was redone unconditionally; both are
now replaced by a single per-table
`HashMap<&str, &[String]>` lookup, which also reduces
the column-grants emission from O(C^2) to O(C) on
wide tables.
- `Comparer::mark_serial_columns` now keys
`serial_columns` by `(schema, table, column)` tuple
instead of a `format!("{}.{}.{}", ...)` string that
was parsed back via `splitn(3, '.')`. The string
form silently misparsed any identifier containing a
literal `.` (legal in PostgreSQL when quoted),
leaving the corresponding column unmarked.
- `Comparer::compare_sequences` had a dead
`dropped_sequences: HashSet<String>` that was
checked and updated on every iteration of a loop
over `self.from.sequences`. Sequences are unique by
`(schema, name)` so the dedupe could never fire;
the set and its per-iteration `format!`/`contains`/
`insert` calls are removed.
- `Comparer::compare_routines` and
`Comparer::compare_routines_and_views` no longer
clone every `Routine` (each carries the full
`source_code` string). The drop path now holds
`routines_to_drop: Vec<&Routine>` borrowing into
`self.from.routines`. The create/update path —
previously forced to clone because
`process_target_routine` took `&mut self` and so
conflicted with any borrow into `self.from` /
`self.to` — is unblocked by refactoring that
method into a free associated function
`Self::emit_routine_diff(&mut script, use_drop,
routine, from_routine)`. Disjoint-field split
borrows now allow `&mut self.script` to coexist
with `&Routine` borrows out of the dump fields,
removing the per-emit clones. Same pattern as the
pre-existing `Self::emit_drop`.

Performance:
- `Dump::process` no longer materializes the entire
serialized dump as a `String` before handing it to
the zip writer. The JSON payload is now streamed
into `ZipWriter` via `serde_json::to_writer`
through a 256 KiB `BufWriter`, bounding peak
memory at the buffer plus zlib's internal state
rather than ~2x the uncompressed dump size. The
`BufWriter` is required for speed: `to_writer`
emits one write per JSON token, and feeding those
straight into the deflate stream paid a per-call
cost on every one (an early unbuffered version of
this change made dumps roughly 10x slower). The
write path is exposed as `Dump::write_to_file`,
mirroring the existing `Dump::read_from_file` and
making the round-trip directly testable.

Tests:
- Added regression tests proving every new query
builder includes the `pg_class` classoid filter:
`build_tables_standalone_query_filters_by_pg_class`,
`build_regular_views_query_filters_by_pg_class`,
`build_materialized_views_query_filters_by_pg_class`,
`build_view_column_comments_query_filters_by_pg_class`,
`build_sequences_standalone_query_filters_by_pg_class`,
and `build_indexes_bulk_query_filters_by_pg_class`.
- `write_to_file_round_trips_via_read_from_file`
builds a Dump with schemas, extensions, tables,
views, sequences, and routines, writes it via the
new streaming path, reads it back, and asserts
every collection size and a few content fields
match.
- `compare_column_grants_dispatches_per_column_acl_correctly`
builds a table with three columns whose effective
`from_acl` differs (kept / revoked / newly
granted) and verifies that the per-table
column-ACL HashMap dispatches each column to the
right diff outcome — guarding against off-by-one
mistakes that single-column tests would miss.
- `mark_serial_columns_handles_dotted_identifier_names`
drives the `mark_serial_columns` path with a
schema, table, and column name that all contain a
literal `.`, asserting that the new tuple key
still locates the target column. The pre-fix
`splitn(3, '.')` parser would have failed on this
input.

2026-04-25 v1.0.18

Bug fixes:
Expand Down
2 changes: 1 addition & 1 deletion app/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pgc"
version = "1.0.18"
version = "1.0.19"
edition = "2024"
license = "MIT"

Expand Down
Loading
Loading