Table Partitioning
AngaraBase supports declarative partitioning (RFC-2026-097 v1): RANGE and LIST strategies with DEFAULT catch-all.
Supported Strategies
| Strategy | Syntax | When to Use |
|---|---|---|
| RANGE | PARTITION BY RANGE (col) | Time series, ID ranges |
| LIST | PARTITION BY LIST (col) | Categorical values (region, type) |
| DEFAULT | PARTITION OF parent DEFAULT | Catch-all for rows outside of all ranges |
DDL
Creating a Partitioned Table
Use the PARTITION BY clause to create a partitioned table.
CREATE TABLE orders (
id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
amount_usd BIGINT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
month_ts BIGINT NOT NULL,
CONSTRAINT orders_pkey PRIMARY KEY (id, month_ts)
) PARTITION BY RANGE (month_ts);
Attaching a Child Partition
Child partitions are created by specifying the parent table and the range of values (for RANGE) or list of values (for LIST).
-- RANGE partition for January 2025
CREATE TABLE orders_p2025_01 PARTITION OF orders
FOR VALUES FROM (1735689600) TO (1738368000);
-- RANGE partition for February 2025
CREATE TABLE orders_p2025_02 PARTITION OF orders
FOR VALUES FROM (1738368000) TO (1740787200);
-- DEFAULT partition (catch-all)
CREATE TABLE orders_p_default PARTITION OF orders DEFAULT;
DML Through the Parent
INSERT
An INSERT into the parent is automatically routed to the appropriate child partition based on the partition key value.
-- Row will be routed to the appropriate month-partition
INSERT INTO orders (id, user_id, amount_usd, month_ts)
VALUES (1, 42, 9900, 1735689601);
No match error: if a row does not fall into any range and there is no DEFAULT partition — SQLSTATE 23514 check_violation.
ON CONFLICT constraint: ON CONFLICT is not supported on a partitioned parent — returns a feature_not_supported error (SQLSTATE 0A000).
SELECT Through the Parent (UNION ALL Expansion + Pruning)
A SELECT from the parent is automatically expanded into a UNION ALL across all children. If the WHERE clause contains a condition on the partition key — irrelevant partitions are skipped (pruning).
-- Scans only the partition for January 2025
SELECT * FROM orders WHERE month_ts >= 1735689600 AND month_ts < 1738368000;
UPDATE Through the Parent
An UPDATE on non-partition key columns works via a fan-out to all (or pruned) children.
UPDATE orders SET status = 'shipped' WHERE id = 42 AND month_ts = 1735689601;
Limitation: Updating the partition key column is forbidden — returns SQLSTATE 23514. Cross-partition row movement is not supported in v1.
DELETE Through the Parent
A DELETE with a WHERE clause on the partition key applies pruning and deletes only from the matching children.
DELETE FROM orders WHERE month_ts = 1735689601 AND id = 42;
Monitoring
| Metric | Description |
|---|---|
angarabase_partition_route_ok_total | Successful INSERT routing to a child |
angarabase_partition_route_no_match_total | INSERT without a matching partition (→ 23514) |
angarabase_partition_route_default_total | INSERT into the DEFAULT partition |
angarabase_partition_pruned_branches_total | Children skipped during SELECT/DML |
Limitations v1
- Hash partitioning — not supported (planned for v0.7)
- Subpartitioning / multi-column partition key — not supported (v0.7)
- Cross-partition UPDATE — forbidden (explicit error 23514)
- ON CONFLICT on a parent table — not supported
- REINDEX through parent — not supported
Troubleshooting
| Symptom | Cause | Solution |
|---|---|---|
ERROR 23514 check_violation during INSERT | Partition key value does not fall into any range | Add a DEFAULT partition or check the value |
ERROR 23514 during UPDATE | Attempting to modify the partition key column | Do not modify the partition key; use DELETE + INSERT instead of UPDATE |
ERROR 0A000 ON CONFLICT not supported | ON CONFLICT through the parent partition | Perform the INSERT directly into the child partition |