waterfall night
waterfall night
CREATE TABLE sales.orders_new3 (
  created_at  timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  order_id    uuid NOT NULL DEFAULT gen_random_uuid(),
  customer_id bigint NOT NULL,
  amount      numeric(12,2) NOT NULL,

  PRIMARY KEY (created_at, order_id)
) PARTITION BY RANGE (created_at);

-- Helpful for point lookups by order_id
CREATE INDEX ON sales.orders_new3 (order_id);
# Create past and future partitions
DO $$
DECLARE
  start_ts timestamp(3) := '2023-01-01 00:00:00';
  -- create through next Sunday + 2 weeks for breathing room
  end_ts   timestamp(3) := (
              date_trunc('day', now())  -- today at midnight (local server time, but it's timestamp)
              - (extract(dow from now())::int) * interval '1 day'  -- go back to Sunday 00:00
              + interval '3 weeks'  -- this Sunday + 3 weeks (i.e., two weeks ahead from next boundary)
            )::timestamp(3);

  cur      timestamp(3);
  nxt      timestamp(3);
  partname text;
BEGIN
  cur := start_ts;

  WHILE cur < end_ts LOOP
    nxt := (cur + interval '1 week')::timestamp(3);

    -- partitions named like orders_new3_p20230101, orders_new_p20230108, ...
    partname := format('orders_new3_p%s', to_char(cur, 'YYYYMMDD'));

    EXECUTE format(
      'CREATE TABLE IF NOT EXISTS sales.%I
         PARTITION OF sales.orders_new3
         FOR VALUES FROM (%L) TO (%L);',
      partname, cur, nxt
    );

    cur := nxt;
  END LOOP;
END $$;
-- Add the job to add new partitions
SELECT partman.create_parent(
  p_parent_table := 'sales.orders_new3',
  p_control      := 'created_at',
  p_type         := 'range',
  p_interval     := '1 week'
);
-- Verify the partitions
SELECT
  child.relname AS partition,
  pg_get_expr(child.relpartbound, child.oid) AS bound
FROM pg_inherits i
JOIN pg_class parent ON parent.oid = i.inhparent
JOIN pg_class child  ON child.oid  = i.inhrelid
WHERE parent.oid = 'sales.orders_new3'::regclass
ORDER BY child.relname;

By Rudy