feat: Add maintain command (catalog discovery + per-table extend + CDC-readiness guard)#29
Closed
codybswaney wants to merge 14 commits into
Closed
feat: Add maintain command (catalog discovery + per-table extend + CDC-readiness guard)#29codybswaney wants to merge 14 commits into
codybswaney wants to merge 14 commits into
Conversation
Add tests for the partition-shape capabilities — weekly/ISO-week period, bounds-anchored extension of existing tables, UTC/timestamptz-correct bounds, composite/parent-owned primary keys, and grant inheritance — plus shared fixtures. These fail against the current implementation; the functionality follows to turn them green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement the partition-shape capabilities to turn the tests green: - Weekly (ISO-week, Monday-aligned) period: date math, IYYY"w"IW suffix, and parser in date-ranges.ts, alongside day/month/year. - Bounds-anchored extension: when a table already has partitions, anchor on the max/min existing bound and chain contiguous period-sized ranges to the horizon, by bounds rather than names — extending legacy-named tables in place with no rename, gap, or overlap; idempotent. DEFAULT/MINVALUE/MAXVALUE are recognized and ignored when anchoring. - UTC-pinned, type-correct bounds: pin the transaction to UTC and pick the cast by key type, so timestamptz tables extend deterministically. - Composite / parent-owned primary keys: skip the per-child ADD PRIMARY KEY when the parent owns the key; emit a composite child key in the classic model. - Grant inheritance: re-issue the parent's grants on each new partition (default on, --no-inherit-grants to disable), and summarize created partitions in the add_partitions command. The maintain fleet command and CDC-readiness guard are intentionally out of scope here (follow-up). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document the weekly period, managing existing (already-partitioned) tables via bounds-anchored extension, composite/parent-owned PK handling, and grant inheritance (--no-inherit-grants). Add a CHANGELOG entry. Enable a vitest v8 coverage block + `coverage` script (measured, not gated). The maintain command is documented with its own follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
From our own review + best-practices research before external review: - Genericize two internal references in a test comment for the public fork (an incident id and a CDC-vendor name). - Add coverage: forward extension is skipped past a MAXVALUE catch-all (nothing to add, no error); and a classic (parent has no PK) table retrofits with each new partition inheriting the existing 3-column composite key. - Clarify docs: formatDateForSql emits UTC-midnight (calendar-aligned) bounds, so non-midnight legacy bounds are unsupported; fix the #partitionPrimaryKeyColumns fallback wording. - README: weekly cron + monitoring examples to match the new period. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ents Address review feedback: - parseBoundValue accepts only a single quoted literal, so a multi-column RANGE bound (e.g. a (timestamp, int) compound key) is treated as unmanaged (null) rather than misread as a single date bound with the extra columns dropped. - addPartitions computes the parent primary key first and only queries existing partitions in the classic (parent-has-no-PK) path, removing a wasted catalog round-trip on every run for native parent-owned-PK tables. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review feedback: - addPartitions forward extension no longer requires future > 0. With future=0 the horizon is today, so a retrofit table's current period is still created when uncovered — matching the fresh-table path (which always includes today) and avoiding silently leaving today's partition missing on a back-fill run. - parseBoundValue's date regex is anchored (^...$ with an optional UTC offset), so unexpected trailing content yields null instead of a silently-truncated parse. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dation Address review feedback: - Grant inheritance reads grants from the original table, so the prep (--intermediate) flow propagates the original's grants onto new partitions instead of silently reading the freshly-prepped intermediate (which has none). The retrofit path is unchanged (original == target there). - parsePartitionDate's week-suffix guard rejects out-of-range ISO week numbers (e.g. w00, w54), not just non-numeric/legacy-prefixed suffixes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ediates No behavior change (the ISO-week tests cover year boundaries and week 53): name the week's Monday and Thursday explicitly and avoid mutating a value before its name is accurate, so the trickiest date math is easier to audit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…antics Comment-only (no behavior change): note the intentional inequality asymmetry between extendRanges and extendRangesBackward, and document that assertContiguous checks only finite bounds (MINVALUE/MAXVALUE/DEFAULT are ignored). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an optional per-table `format` template (stored in the settings comment,
e.g. `p{YYYY}w{WW}` or `y{YYYY}m{MM}`) so a retrofitted table can keep its
existing partition naming convention. Placeholders resolve to the same date
components already used — ISO week-year/week for weekly tables, calendar
year/month/day otherwise — so a custom format changes only the rendered name,
never which dates a partition covers. A single shared spec drives both
formatDateSuffix and parsePartitionDate, keeping them symmetric; literals are
restricted to [a-z0-9] since the suffix is recovered by splitting on `_`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bounds-anchored extension emits new partition boundaries at UTC midnight, so a table whose existing partitions sit on non-midnight boundaries cannot be extended contiguously. This previously surfaced either as a silent no-op (the midnight-rounded horizon falls short of the non-midnight anchor, so zero candidates are generated) or, with a larger --future, a partition-overlap error at CREATE time. Detect a non-midnight anchor (the max upper / min lower bound) up front and throw a clear error instead of stalling silently. Also parse the settings comment by splitting on the first ":" only, so a value containing a colon (e.g. a mistyped format template) is preserved and validated downstream rather than truncated at the second colon. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
formatDateSuffix recompiled the partition-name template (a regex scan plus
allocation) and recomputed the ISO week twice on every render — once per
{YYYY}/{WW} placeholder — so a large back-fill repeated that work for each
partition. Cache compileFormat by (period, template) and share a single
isoWeekInfo result between the two weekly placeholders within a render.
Also drop an unused zod import from pgslice.ts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…guard) Discovers every partitioned parent carrying a valid pgslice settings comment and extends each with add_partitions in one run, with per-table failure isolation and a read-only CDC-readiness guard (every leaf must have a replica identity usable for logical replication). Exits non-zero if any table failed or is CDC-unsafe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR adds a fleet-wide
Confidence Score: 5/5Safe to merge with minimal risk. The change is well-scoped to the new maintain command and supporting catalog checks. Tests cover discovery, per-period extension, idempotency, grants, CDC readiness, and per-table failure isolation. No blocking correctness or security issues were found in the changed paths. No files require special attention.
What T-Rex did
Important Files Changed
|
|
T-Rex pricing update — T-Rex was free through June 2026. Effective July 1, 2026, T-Rex adds 2 credits on top of the standard 1-credit review (3 total). T-Rex settings |
A single --future N means very different runway for weekly vs monthly vs yearly tables (3 weeks vs 3 months vs 3 years). Replace it with per-period --future-daily / --future-weekly / --future-monthly / --future-yearly (defaults 90 / 26 / 6 / 1); discovery returns each table's period, and each table is extended by the horizon for its own period, so the fleet gets comparable forward coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
maintaincommand: discover every managed partitioned table from the catalog and extend each in one run, so a scheduler runs a single command and newly-partitioned tables are picked up automatically with no per-table configuration.relkind = 'p', not themselves partitions) that carry a valid pgslice settings comment; optional--schemafilter.add_partitionsfor each discovered table; native (parent-owned PK) and classic-pgslice (per-child PK) tables are handled automatically.Test plan
src/maintain.test.ts— e2e against real Postgres (13.20): discovery (exactly the settings-commented parents; unmanaged/plain tables excluded), native-vs-classic classification, bounds-anchored extension with expected names, idempotent re-run,--schemarestriction, PK + grant inheritance on new partitions,REPLICA IDENTITY USING INDEXpropagation, a CDC-unsafe leaf flagged, and per-table failure isolation (a DEFAULT-blocked table fails alone while the rest still extend).src/commands/maintain.test.ts— command-level: exit 0 + per-table summary on a healthy fleet, exit 1 when a leaf has no usable replica identity, and the "no managed tables" message.Notes
Targets
feature/pgslice-partition-shapesso the diff is maintain-only — review/merge after that branch lands.🤖 Generated with Claude Code