
io.ebeaninternal.dbmigration.builtin-extra-ddl-partitioning.xml Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ebean Show documentation
Show all versions of ebean Show documentation
composite of common runtime dependencies for all platforms
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <extra-ddl xmlns="http://ebean-orm.github.io/xml/ns/extraddl"> <ddl-script name="partition help" init="true" platforms="postgres"> -- partitioning helper functions (UTC based) ------------------------------------------------------------------------------------ -- Type: partition_meta -- -- Type used to hold common partitioning parameters such as period start and end etc ------------------------------------------------------------------------------------ do $$ begin if not exists (select 1 from pg_type where typname = 'partition_meta') THEN create type partition_meta as ( period_start timestamptz, period_end timestamptz, period_name text, base_name text, part_name text ); end if; end$$; ------------------------------------------------------------------------------------ -- Function: _partition_create -- -- Internal helper method to create a partition given meta data ------------------------------------------------------------------------------------ create or replace function _partition_create(meta partition_meta) returns text language plpgsql set timezone to 'UTC' as $$ begin execute format('create table if not exists %I partition of %I for values from (''%s'') TO (''%s'')', meta.part_name, meta.base_name, meta.period_start, meta.period_end); return meta.part_name; end; $$; ------------------------------------------------------------------------------------ -- Function: _partition_meta -- -- Internal helper method to create and return meta data used to create a partition. -- Helps work out start and end periods for day, week, month and year partitions. ------------------------------------------------------------------------------------ create or replace function _partition_meta( mode text, asOf date, baseName text) returns partition_meta language plpgsql set timezone to 'UTC' as $$ declare partName text; meta partition_meta; asOfUtc timestamptz; begin asOfUtc = timezone('utc', asOf); if (mode = 'day') then asOfUtc = date_trunc('day', asOfUtc); partName = to_char(asOfUtc, 'YYYY_MM_DD'); select asOfUtc, asOfUtc + interval '1 days' into meta.period_start, meta.period_end; elseif (mode = 'week') then asOfUtc = date_trunc('week', asOfUtc); partName = format('%s_w%s', extract(ISOYEAR FROM asOfUtc), extract(WEEK FROM asOfUtc)); select asOfUtc, asOfUtc + interval '7 days' into meta.period_start, meta.period_end; elseif (mode = 'year') then asOfUtc = date_trunc('year', asOfUtc); partName = to_char(date_trunc('year', asOfUtc), 'YYYY'); select asOfUtc, asOfUtc + interval '1 year' into meta.period_start, meta.period_end; else asOfUtc = date_trunc('month', asOfUtc); partName = to_char(asOfUtc, 'YYYY_MM'); select asOfUtc, asOfUtc + interval '1 month' into meta.period_start, meta.period_end; end if; select partName, baseName, format('%s_%s', baseName, partName) into meta.period_name, meta.base_name, meta.part_name; return meta; end; $$; ------------------------------------------------------------------------------------ -- Function: _partition_over -- -- Internal helper method to return a set/table of dates to ensure partitions exists for. -- Typically we want to ensure some future partitions exist and this helps return dates -- for which we loop to create partitions. ------------------------------------------------------------------------------------ create or replace function _partition_over( mode text, fromDate date default current_date, _count integer default 0) returns TABLE(of_date date) language plpgsql as $$ declare endDate date; begin if (mode = 'day') then endDate = fromDate + (interval '1 day' * _count); fromDate = fromDate - interval '1 day'; -- allow for timezone return query select s::date from generate_series(fromDate, endDate, '1 day') s; elseif (mode = 'week') then fromDate = date_trunc('week', fromDate); endDate = fromDate + (interval '1 week' * _count); return query select s::date from generate_series(fromDate, endDate, '1 week') s; elseif (mode = 'year') then fromDate = date_trunc('year', fromDate); endDate = fromDate + (interval '1 year' * _count); return query select s::date from generate_series(fromDate, endDate, '1 year') s; else fromDate = date_trunc('month', fromDate); endDate = fromDate + (interval '1 month' * _count); return query select s::date from generate_series(fromDate, endDate, '1 month') s; end if; end; $$; ------------------------------------------------------------------------------------ -- Function: partition -- -- Helper to ensure we create partitions into the future as needed for day, week, month -- and year based partitioning. Typically we call this periodically (e.g. every day). -- -- Examples: -- -- select partition('week', 'trip', 4); -- select partition('month', 'event', 1); -- ------------------------------------------------------------------------------------ create or replace function partition( mode text, -- one of 'day','week','month','year' baseName text, -- base table name partitionCount integer default 0, -- number of additional partitions fromDate date default current_date) -- date to create first partition for returns text language plpgsql set timezone to 'UTC' as $$ begin perform _partition_create(_partition_meta(mode, poDate, baseName)) from _partition_over(mode, fromDate, partitionCount) poDate; return 'done'; end; $$; ------------------------------------------------------------------------------------ -- Function: partition_init -- -- Similar to partition but allows the first partition to be bigger with an explicit -- initDate typically to allow back dated rows to go into the initial partition. -- -- Examples: -- -- select partition_init(date '2001-01-01', 'week', 'event'); -- ------------------------------------------------------------------------------------ create or replace function partition_init( initDate date, -- first partition period start date mode text, -- one of 'day','week','month','year' baseName text, -- base table name partitionCount integer default 0, -- number of additional partitions fromDate date default current_date) -- date to create first partition for returns text language plpgsql set timezone to 'UTC' as $$ declare meta partition_meta; begin -- override the period start for the first partition meta = _partition_meta(mode, fromDate, baseName); meta.period_start = initDate; perform _partition_create(meta); if (partitionCount > 0) then -- create additional partitions normally fromDate = fromDate + interval '1 day'; perform _partition_create(_partition_meta(mode, poDate, baseName)) from _partition_over(mode, fromDate, partitionCount) poDate; end if; return 'done'; end; $$; </ddl-script> </extra-ddl>
© 2015 - 2025 Weber Informatics LLC | Privacy Policy