Skip to content

Instantly share code, notes, and snippets.

@redexp
Created March 28, 2015 05:28
Show Gist options
  • Save redexp/a26a6758907e0ad17a92 to your computer and use it in GitHub Desktop.
Save redexp/a26a6758907e0ad17a92 to your computer and use it in GitHub Desktop.
Postgres auto partition function
-- customers table
-- id: INT
-- poll_id: INT # Foreign key for table poll
-- ... other columns
CREATE SCHEMA customers_partitions;
CREATE OR REPLACE FUNCTION insert_customers()
RETURNS TRIGGER AS $$
DECLARE
prefix text := 'customers_partitions.';
table_name text;
insert_into text;
BEGIN
table_name := 'poll' || NEW.poll_id;
insert_into := 'INSERT INTO ' || prefix || table_name || ' SELECT ($1).*';
EXECUTE insert_into USING NEW;
RETURN NULL;
EXCEPTION
WHEN undefined_table THEN
EXECUTE 'CREATE TABLE ' || prefix || table_name || ' ( CHECK(poll_id = ' || NEW.poll_id || ')) INHERITS (customers)';
EXECUTE 'CREATE INDEX ' || table_name || '_poll_id ON ' || prefix || table_name || ' (poll_id)';
EXECUTE insert_into USING NEW;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER insert_customers_trigger
BEFORE INSERT ON customers
FOR EACH ROW EXECUTE PROCEDURE insert_customers();
-- now insert some data to customers
-- if search just by id then postgre will look over all poll* tables
EXPLAIN SELECT * FROM customers WHERE id = 201651;
-- if you add check poll_id then it will look only into poll{poll_id}
EXPLAIN SELECT * FROM customers WHERE poll_id = 10 AND id = 201651;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment