jobinau / pg_partmaint

Super Simple partition maintenance automation for PostgreSQL
8 stars 3 forks source link

Partition tables with default partitions are failing #1

Closed jobinau closed 3 years ago

jobinau commented 3 years ago

Partition tables with default partitions are reported to be failing.

CREATE TABLE emp (id int,
dob timestamp(6) without time zone
) 
PARTITION BY RANGE (dob);
CREATE TABLE public."emp_2019-01-01_2020-11-30" PARTITION OF emp FOR VALUES FROM ('2019-01-01 00:00:00') TO ('2020-11-30 00:00:00');
CREATE TABLE public."emp_2020-11-30_2020-12-01" PARTITION OF emp FOR VALUES FROM ('2020-11-30 00:00:00') TO ('2020-12-01 00:00:00');
CREATE TABLE public."emp_2020-12-01_2020-12-02" PARTITION OF emp FOR VALUES FROM ('2020-12-01 00:00:00') TO ('2020-12-02 00:00:00');
CREATE TABLE public.emp_default PARTITION OF emp DEFAULT;
./pg_partmaint.py -c "" -t public.emp -i weekly -p 5 --displayddl
Version: 3.1
Connecting to Databse...
Verified that table : public.emp is a partitioned table
Current Number of Free Partitions in the table :4
Preparing 1 more new partition(s)
Traceback (most recent call last):
  File "./pg_partmaint.py", line 188, in <module>
    tab1.prepareNewPartitions(int(args.premake)-freeParts)
  File "./pg_partmaint.py", line 121, in prepareNewPartitions
    cur.execute(sql)
  File "/usr/local/lib/python2.7/dist-packages/psycopg2/extras.py", line 243, in execute
    return super(RealDictCursor, self).execute(query, vars)
psycopg2.errors.InvalidDatetimeFormat: invalid input syntax for type date: "ULT"
jobinau commented 3 years ago

The default partition needs to be identified. One of the approximate way to check the length of the relpartbound of the pg_class. For example,

postgres=# SELECT relname,length(relpartbound) from pg_class where oid in (91975,91978,91981,91996);
          relname          | length 
---------------------------+--------
 emp_2020-11-30_2020-12-01 |    547
 emp_2020-12-01_2020-12-02 |    547
 emp_default               |    133
 emp_2019-01-01_2020-11-30 |    547
(4 rows)

The exact way to check whether it is a default partition is to check is_default true in relpartbound

jobinau commented 3 years ago

Final thought was to use pg_catalog.pg_get_expr(c.relpartbound, c.oid) != 'DEFAULT' as it is more explicit

jobinau commented 3 years ago

Issue is fixed in 3.2 code base