create or replace function partition_insert_trigger() returns trigger language 'plpgsql' as $$ declare column_name text := TG_ARGV[0]; columnt_format text := TG_ARGV[1]; column_value timestamp; table_name text; insert_stmt_tpl text := 'insert into %I select ($1).*'; insert_stmt text; create_table_tpl text := ' create table {table_name} ( like {base_table_name} including all ); alter table {table_name} inherit {base_table_name}; '; begin execute format('select $1.%s', column_name) using NEW into column_value; -- TODO: move table_name := format('%s_%s', TG_TABLE_NAME, to_char(column_value, columnt_format)); insert_stmt = format(insert_stmt_tpl, table_name); begin execute format(insert_stmt_tpl, table_name) using new; exception when undefined_table then begin execute replace(replace(create_table_tpl, '{table_name}', table_name), '{base_table_name}', TG_TABLE_NAME); exception when duplicate_table then -- ignore end; execute insert_stmt using new; end; return NEW; end; $$; create or replace function init_partition(table_name text, column_name text, partition_interval text) returns void language 'plpgsql' as $$ declare columnt_format text; query_tpl text := ' create trigger on_inserted_{table_name} before insert on {table_name} for each row execute procedure partition_insert_trigger(''{column_name}'', ''{columnt_format}'');'; begin CASE WHEN partition_interval = 'monthly' THEN columnt_format = '"y"yy_"m"mm'; WHEN partition_interval = 'weekly' THEN columnt_format = '"y"yy_"m"mm_"w"w'; WHEN partition_interval = 'daily' THEN columnt_format = '"y"yy_"m"mm_"d"dd'; WHEN partition_interval = 'hourly' THEN columnt_format = '"y"yy_"m"mm_"d"dd_"h"hh24'; ELSE RAISE EXCEPTION 'Must use a predefined time interval: monthly, weekly, daily, hourly.'; END CASE; execute replace(replace(replace(query_tpl, '{table_name}', table_name), '{column_name}', column_name), '{columnt_format}', columnt_format); end; $$;