3

I am trying to automate partitions in Postgres 10 in a huge table by BY RANGE (date_created).

I've noticed that there is no an automatic creation of partitioned tables, therefore I want to write a procedure to automate the creation of those tables.

I was thinking something like that:

CREATE OR REPLACE FUNCTION cdi.automating_partitions()
RETURNS TABLE(natural_id text, name text, natural_id_numeric text) AS
$func$
DECLARE
   formal_table text;
BEGIN
   FOR formal_table IN
       select '2017-01-01'::date + (n || ' months')::interval months,
       '2013-02-01'::date + (n || ' months')::interval monthsplus
       from generate_series(0, 12) n
   LOOP
      RETURN QUERY EXECUTE
   'CREATE TABLE cdi.' || 'document' || to_char(months, 'YYYY')  || ''  || to_char(months, 'MM') || ' PARTITION OF cdi.document
 FOR VALUES FROM  (''' ||  to_char(months, 'YYYY')  || to_char(months, 'MM')  || ''',
''' to_char(monthsplus, 'YYYY')  || to_char(monthsplus, 'MM')   ''');'
   END LOOP;
END
$func$  LANGUAGE plpgsql;

But I get a syntax error near (

2
  • 2
    You can't use execute outside of a PL/pgSQL block (and never as part of a SQL query) Commented Oct 17, 2017 at 10:26
  • 1
    What error are you getting? Commented Oct 17, 2017 at 10:30

1 Answer 1

6

Use the function format() in conjunction with execute to get a clear and readable code, example:

do $do$
declare
    d date;
begin
    for d in
        select generate_series(date '2017-01-01', date '2017-12-01', interval '1 month')
    loop
    execute format($f$
        create table cdi.document%s%s partition of cdi.document
        for values from (%L) to (%L)
        $f$, 
        to_char(d, 'YYYY'), to_char(d, 'MM'), d, d+ interval '1 month');
    end loop;
end 
$do$

I have used an anonymous code block as create table ... does not generate any results. However, if you want to write a function, note that the function should return void and not use RETURN QUERY.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.