Version Specific PostgreSQL Extension Features
When I say version specific here, I’m speaking of the PostgreSQL version (9.1, 9,2, etc), not the extension version. An upcoming update to PG Partition Manager takes advantage of the range data type, which is a 9.2 feature. But I also wanted to keep backward compatibility with 9.1 by excluding this new feature.
The more important thing is to get the extension installed in the first place, so the Makefile was where I started.
EXTENSION = pg_partman
EXTVERSION = $(shell grep default_version $(EXTENSION).control | \
sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/")
DATA = $(filter-out $(wildcard updates/*--*.sql),$(wildcard sql/*.sql))
DOCS = $(wildcard doc/*.md)
SCRIPTS = bin/dump_partition.py bin/partition_data.py bin/reapply_indexes.py bin/undo_partition.py
PG_CONFIG = pg_config
PG91 = $(shell $(PG_CONFIG) --version | egrep " 8\.| 9\.0" > /dev/null && echo no || echo yes)
PG92 = $(shell $(PG_CONFIG) --version | egrep " 8\.| 9\.0| 9\.1" > /dev/null && echo no || echo yes)
ifeq ($(PG91),yes)
all: sql/$(EXTENSION)--$(EXTVERSION).sql
ifeq ($(PG92),yes)
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/types/*.sql sql/constraints/*.sql sql/tables/*.sql sql/functions/*.sql sql/92/tables/*.sql
cat $^ > $@
else
sql/$(EXTENSION)--$(EXTVERSION).sql: sql/types/*.sql sql/constraints/*.sql sql/tables/*.sql sql/functions/*.sql
cat $^ > $@
endif
DATA = $(wildcard updates/*--*.sql) sql/$(EXTENSION)--$(EXTVERSION).sql
EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql
endif
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
Keep in mind, I know very little about Makefiles in the first place, so my solution is using just what I already knew how to do in the original Makefile. There may be a better way, and if there is, I’d love feedback. I just expanded on the already existing lines that check for a minimal version of 9.1 to even allow the extension to install. And I organized my code folders to have one specifically for 9.2+ features (sql/92/tables/). After that it’s just another check to see if the PG92 variable is true, and if so, grab the code from that additional folder.
Now the next challenge is checking the version when installing an update to an already existing installation. First, we need a means of checking if the current version is new enough. I made up the below function for inclusion in my extension since I’ll actually be doing version checking elsewhere as well.
/*
* Check PostgreSQL version number. Parameter must be full 3 point version.
* Returns true if current version is greater than or equal to the parameter given.
*/
CREATE FUNCTION check_version(p_check_version text) RETURNS boolean
LANGUAGE plpgsql STABLE
AS $$
DECLARE
v_check_version text[];
v_current_version text[] := string_to_array(current_setting('server_version'), '.');
BEGIN
v_check_version := string_to_array(p_check_version, '.');
IF v_current_version[1]::int > v_check_version[1]::int THEN
RETURN true;
END IF;
IF v_current_version[1]::int = v_check_version[1]::int THEN
IF v_current_version[2]::int > v_check_version[2]::int THEN
RETURN true;
END IF;
IF v_current_version[2]::int = v_check_version[2]::int THEN
IF v_current_version[3]::int >= v_check_version[3]::int THEN
RETURN true;
END IF; -- 0.0.x
END IF; -- 0.x.0
END IF; -- x.0.0
RETURN false;
END
$$;
Now we can just take advantage of the DO block syntax to allow script code in a plain SQL file.
/********* 9.2+ stuff ********/
DO $$
BEGIN
IF @extschema@.check_version('9.2.0') THEN
CREATE TABLE custom_time_partitions (
parent_table text NOT NULL
, child_table text NOT NULL
, partition_range tstzrange NOT NULL
, PRIMARY KEY (parent_table, child_table));
CREATE INDEX custom_time_partitions_partition_range_idx ON custom_time_partitions USING gist (partition_range);
END IF;
END
$$;
/********* end 9.2+ stuff ********/
The full implementation of this will be available in the 1.6.0 update for pg_partman that I’ll be releasing in the near future. It contains a feature I’ve wanted to get done for a while now: custom time intervals!