Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pcVkR-0002oB-4d for pgsql-admin@arkaria.postgresql.org; Wed, 15 Mar 2023 18:21:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pcVjQ-00060c-BL for pgsql-admin@arkaria.postgresql.org; Wed, 15 Mar 2023 18:20:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pcVjP-00060R-UQ for pgsql-admin@lists.postgresql.org; Wed, 15 Mar 2023 18:20:12 +0000 Received: from impout009aa.msg.chrl.nc.charter.net ([47.43.20.33] helo=impout009.msg.chrl.nc.charter.net) by magus.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pcVjI-0005AD-JU for pgsql-admin@lists.postgresql.org; Wed, 15 Mar 2023 18:20:11 +0000 Received: from cerberus.crazybean.net ([71.11.29.254]) by cmsmtp with ESMTP id cVjFp7bjQHhkncVjFpkKKW; Wed, 15 Mar 2023 18:20:02 +0000 Authentication-Results: crazybean.net; none X-Authority-Analysis: v=2.4 cv=VJjOIvDX c=1 sm=1 tr=0 ts=64120c52 a=GkUsAQdcAzAk0MT19QAIRQ==:117 a=GkUsAQdcAzAk0MT19QAIRQ==:17 a=xqWC_Br6kY4A:10 a=k__wU0fu6RkA:10 a=_iPV34EaAAAA:8 a=6C-Jyyw-N2CvkqTy0WMA:9 a=QEXdDO2ut3YA:10 a=lwW00GfrRp5OoKgiR_QA:9 a=7CEhpGZrIX6VTDrd:21 a=_W_S_7VecoQA:10 a=lqcHg5cX4UMA:10 a=Pfhc3Wcpa4gTIBL5Gzq4:22 Received: from smtpclient.apple ( [2001:470:e117:4:5d15:aaf7:a4e:efc3]) by cerberus.crazybean.net (OpenSMTPD) with ESMTPSA id 2f0e6724 (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO); Wed, 15 Mar 2023 14:20:00 -0400 (EDT) From: Rui DeSousa Message-Id: Content-Type: multipart/alternative; boundary="Apple-Mail=_0257405F-7FDA-443B-B2AD-D4601C003623" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.2\)) Subject: Re: Automatic partition creation? Date: Wed, 15 Mar 2023 14:20:00 -0400 In-Reply-To: <001805b4-c039-49b1-344b-9c52016c6f3b@quadratum-braccas.com> Cc: Pgsql-admin To: Sbob References: <001805b4-c039-49b1-344b-9c52016c6f3b@quadratum-braccas.com> X-Mailer: Apple Mail (2.3696.120.41.1.2) X-CMAE-Envelope: MS4xfBst77dlyP+HoGS6GFpV/EvU9K3ErOPx6AVMXB9Iaaf12My+7H1O5y2cO2H7iym/2az0ZqhhMUoX1+OUV7wFyS2RKlBvfTzDk89BmCdhqgAKp0sfORkr 3FXOgyY/ImMuQmijb1qAILrIDYo3G1N7kl+bVbdAQFuj6mKEdN9h9zOyT7XpY2btbYWTCU9P+H7t3Ooz6ExEyA2V6Ac54xzqkUfTtmJkHXxRcFuPRzOoEbzj w68Ll22F3JFNyxNUdr5aVQ== List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_0257405F-7FDA-443B-B2AD-D4601C003623 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Mar 15, 2023, at 1:24 PM, Sbob wrote: >=20 > Is it possible to auto create new partitions as needed with = declarative partitioning as well? >=20 I=E2=80=99ve created and used the following function to create yearly = partitions. I would just call the function periodical from cron and = provide a lead time; i.e. The partition should be there a month before = the new year, etc.=20 create or replace function dba.add_yearly_partition(_schema name, _table = name, _lead_time interval) returns boolean as $body$ declare _create_table_template constant text :=3D ' create table %1$s.%2$s_%3$s partition of %1$s.%2$s for values from (''%4$s'') to (''%5$s'') ; '; _date timestamp with time zone :=3D now() + _lead_time; _is_valid boolean; _sql text; begin for _sql in=20 select replace( replace( pg_get_expr(c.relpartbound, c.oid) , 'FOR VALUES FROM' ,'select' ) , 'TO' , '<=3D $1 and $1 <' ) || ';' from pg_class p join pg_namespace ns on ns.oid =3D p.relnamespace and ns.nspname =3D _schema join pg_inherits i on i.inhparent =3D p.oid join pg_class c on c.oid =3D i.inhrelid where p.relname =3D _table order by c.oid desc loop execute _sql into _is_valid using _date; exit when _is_valid; end loop; if _is_valid is null then raise exception 'Failed to identify partitioned table.'; elsif not _is_valid then execute format(_create_table_template , _schema , _table , extract(year from _date) , date_trunc('year', _date) , date_trunc('year', _date) + '1 year'::interval ); end if; return (not _is_valid); end; $body$ language plpgsql set search_path =3D dba ; --Apple-Mail=_0257405F-7FDA-443B-B2AD-D4601C003623 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
On = Mar 15, 2023, at 1:24 PM, Sbob <sbob@quadratum-braccas.com> wrote:

Is it possible to auto create = new partitions as needed with declarative partitioning as well?


I=E2=80=99ve created and used the = following function to create yearly partitions.  I would just call = the function periodical from cron and provide a lead time; i.e. The = partition should be there a month before the new year, etc. 


create = or replace function dba.add_yearly_partition(_schema name, _table name, = _lead_time interval)
  = returns boolean
as = $body$
declare
  = _create_table_template constant text :=3D '
    create table = %1$s.%2$s_%3$s
  =   partition of %1$s.%2$s
  =   for values from (''%4$s'') to (''%5$s'')
    ;
  ';
  _date timestamp with time zone :=3D= now() + _lead_time;
  = _is_valid boolean;
  = _sql text;
begin
  = for _sql in 
  =   select replace(
  =       replace(
  =           pg_get_expr(c.relpartbound, = c.oid)
  =           , 'FOR VALUES FROM'
          =   ,'select'
  =         )
  =       , 'TO'
  =       , '<=3D $1 and $1 <'
      )
      || = ';'
  =   from pg_class p
  =   join pg_namespace ns on ns.oid =3D = p.relnamespace
  =     and ns.nspname =3D _schema
    join pg_inherits i on i.inhparent =3D = p.oid
  =   join pg_class c on c.oid =3D i.inhrelid
    where p.relname =3D = _table
  =   order by c.oid desc
  = loop
  =   execute _sql into _is_valid using _date;
    exit when = _is_valid;
  = end loop;

  = if _is_valid is null then
  =   raise exception 'Failed to identify partitioned = table.';
  = elsif not _is_valid then
  =   execute format(_create_table_template
        , = _schema
  =       , _table
  =       , extract(year from _date)
        , = date_trunc('year', _date)
  =       , date_trunc('year', _date) + '1 = year'::interval
  =     );
  = end if;

  = return (not _is_valid);
end;
$body$
  = language plpgsql
  = set search_path =3D dba
;

= --Apple-Mail=_0257405F-7FDA-443B-B2AD-D4601C003623--