All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ebeaninternal.dbmigration.builtin-extra-ddl-partitioning.xml Maven / Gradle / Ivy

There is a newer version: 15.8.0
Show newest version
<?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,yugabyte">
-- 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,
      schema_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
  if (meta.schema_name = '') then
    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);
  else
    execute format('create table if not exists %I partition of %I.%I for values from (''%s'') TO (''%s'')', meta.part_name, meta.schema_name, meta.base_name, meta.period_start, meta.period_end);
  end if;
  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,
  schemaName    text default '')
  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, schemaName, baseName, format('%s_%s', baseName, partName)
    into meta.period_name, meta.schema_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);
--   select partition('year',  'log',   1, 'my_schema');
--
------------------------------------------------------------------------------------
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
  schemaName     text default '',            -- schema
  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, schemaName))
  from _partition_over(mode, fromDate, partitionCount) poDate;
  return 'done';
end;
$$;
</ddl-script>

</extra-ddl>




© 2015 - 2024 Weber Informatics LLC | Privacy Policy