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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
/node_modules/
/dist/

# Coverage
/coverage/

# Claude Code
/.claude/
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## Unreleased

- Added support for managing existing (already-partitioned) tables: bounds-anchored extension that recognizes legacy-named partitions and extends contiguously without renaming, gaps, or overlaps
- Added a weekly (ISO-week, Monday-aligned) period
- Added composite / parent-owned primary key support to `add_partitions` (skips the redundant per-partition key when the parent owns one)
- Added grant inheritance on new partitions, on by default (`--no-inherit-grants` to disable)
- Added UTC-pinned, type-correct bounds so `timestamptz`-keyed tables extend deterministically regardless of session timezone

## 0.7.1 (2025-07-27)

- Fixed `analyze` analyzing partitions twice with declarative partitioning
Expand Down
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export PGSLICE_URL=postgres://localhost/myapp_development
pgslice prep <table> <column> <period>
```

The column should be a `timestamp`, `timestamptz`, or `date` column and period can be `day`, `month`, or `year`.
The column should be a `timestamp`, `timestamptz`, or `date` column and period can be `day`, `week` (ISO-week, Monday-aligned), `month`, or `year`.

This creates a partitioned table named `<table>_intermediate` using range partitioning.

Expand Down Expand Up @@ -280,12 +280,15 @@ To add partitions, use:
pgslice add_partitions <table> --future 3
```

Add this as a cron job to create a new partition each day, month, or year.
Add this as a cron job to create a new partition each day, week, month, or year.

```sh
# day
0 0 * * * pgslice add_partitions <table> --future 3 --url ...

# week (Monday-aligned ISO weeks)
0 0 * * 1 pgslice add_partitions <table> --future 3 --url ...

# month
0 0 1 * * pgslice add_partitions <table> --future 3 --url ...

Expand All @@ -304,10 +307,43 @@ WHERE
c.relkind = 'r' AND
n.nspname = 'public' AND
c.relname = '<table>_' || to_char(NOW() + INTERVAL '3 days', 'YYYYMMDD')
-- for weeks, use to_char(NOW() + INTERVAL '3 weeks', 'IYYY"w"IW')
-- for months, use to_char(NOW() + INTERVAL '3 months', 'YYYYMM')
-- for years, use to_char(NOW() + INTERVAL '3 years', 'YYYY')
```

## Managing Existing Tables

pgslice can manage tables that were already partitioned outside of it (for example by an application migration), so you can converge future-partition creation onto a single tool without recreating or renaming anything.

Mark a table as managed by giving it the pgslice settings comment:

```sql
COMMENT ON TABLE <table> IS 'column:created_at,period:week,cast:date,version:3';
```

Then extend it like any other table:

```sh
pgslice add_partitions <table> --future 3
```

When a table already has partitions, pgslice extends it **by partition bounds**: it anchors on the maximum existing upper bound and chains contiguous, period-sized ranges from there. This means it:

- never renames or collides with existing (legacy-named) partitions,
- introduces no gap or overlap at the boundary, and
- continues whatever scheme the table already uses — ISO weeks, calendar months, or a year-resetting weekly scheme — rather than snapping to an absolute calendar.

Because extension is keyed on bounds rather than names, newly-created partitions use pgslice's own naming (`<table>_<suffix>`), which may differ cosmetically from a legacy naming convention. Partition names are not functional, so mixed naming is expected and harmless. `DEFAULT` and `MINVALUE`/`MAXVALUE` partitions are recognized and ignored when choosing the extension anchor.

### Primary keys

If the partitioned parent owns a primary key (including a composite key), Postgres propagates it — and any partitioned indexes — to each new partition, so pgslice does not add a per-partition key. Tables in the classic pgslice model (no key on the parent) still get a per-partition key.

### Grants

By default, pgslice re-issues the parent table's grants on each new partition, because Postgres does not cascade a parent's grants to its partitions. This keeps a replication/CDC role's access intact as new partitions appear. Disable it with `--no-inherit-grants`.

## Archiving Partitions

Back up and drop older partitions each day, month, or year.
Expand Down
Loading
Loading