@@ -24,37 +24,179 @@ CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
2424parttypeINTEGER NOT NULL ,
2525range_intervalTEXT ,
2626
27- CHECK (parttype>= 1 OR parttype <= 2 )/* check for allowed part types*/
27+ CHECK (parttypeIN ( 1 , 2 ) )/* check for allowed part types*/
2828);
2929
30+ CREATE TABLE IF NOT EXISTS @extschema@.pathman_config_params (
31+ partrelREGCLASSNOT NULL ,
32+ enable_parentBOOLEAN NOT NULL DEFAULT TRUE
33+ );
34+ CREATE UNIQUE INDEX i_pathman_config_params
35+ ON @extschema@.pathman_config_params(partrel);
3036
3137SELECT pg_catalog .pg_extension_config_dump (' @extschema@.pathman_config' ,' ' );
38+ SELECT pg_catalog .pg_extension_config_dump (' @extschema@.pathman_config_params' ,' ' );
39+
40+
41+ CREATEOR REPLACE FUNCTION @extschema@.on_enable_parent(relidOID )
42+ RETURNSOID AS ' pg_pathman' LANGUAGE C STRICT;
43+
44+ CREATEOR REPLACE FUNCTION @extschema@.on_disable_parent(relidOID )
45+ RETURNSOID AS ' pg_pathman' LANGUAGE C STRICT;
46+
47+ /* Include parent relation into query plan's for specified relation*/
48+ CREATEOR REPLACE FUNCTION @extschema@.enable_parent(relation REGCLASS)
49+ RETURNS VOIDAS
50+ $$
51+ BEGIN
52+ INSERT INTO @extschema@.pathman_config_paramsvalues (relation, True)
53+ ON CONFLICT (partrel) DO
54+ UPDATE SET enable_parent= True;
55+
56+ PERFORM @extschema@.on_enable_parent(relation::oid );
57+ END
58+ $$
59+ LANGUAGE plpgsql;
60+
61+ /* Do not include parent relation into query plan's for specified relation*/
62+ CREATEOR REPLACE FUNCTION @extschema@.disable_parent(relation REGCLASS)
63+ RETURNS VOIDAS
64+ $$
65+ BEGIN
66+ INSERT INTO @extschema@.pathman_config_paramsvalues (relation, False)
67+ ON CONFLICT (partrel) DO
68+ UPDATE SET enable_parent= False;
69+
70+ PERFORM @extschema@.on_disable_parent(relation::oid );
71+ END
72+ $$
73+ LANGUAGE plpgsql;
3274
75+ /*
76+ * Partitioning data tools
77+ */
78+ CREATEOR REPLACE FUNCTION @extschema@.active_workers()
79+ RETURNS TABLE (
80+ pidINT ,
81+ dbidINT ,
82+ relidINT ,
83+ processedINT ,
84+ statusTEXT
85+ )AS ' pg_pathman' LANGUAGE C STRICT;
86+
87+ CREATEOR REPLACE VIEW @extschema@.pathman_active_workers
88+ AS SELECT * FROM @extschema@.active_workers();
89+
90+ CREATEOR REPLACE FUNCTION @extschema@.partition_data_worker(relation regclass)
91+ RETURNS VOIDAS ' pg_pathman' LANGUAGE C STRICT;
92+
93+ CREATEOR REPLACE FUNCTION @extschema@.stop_worker(relation regclass)
94+ RETURNS BOOLAS ' pg_pathman' LANGUAGE C STRICT;
95+
96+ /* PathmanRange type*/
97+ CREATEOR REPLACE FUNCTION @extschema@.pathman_range_in(cstring)
98+ RETURNS PathmanRange
99+ AS ' pg_pathman'
100+ LANGUAGE C IMMUTABLE STRICT;
101+
102+ CREATEOR REPLACE FUNCTION @extschema@.pathman_range_out(PathmanRange)
103+ RETURNS cstring
104+ AS ' pg_pathman'
105+ LANGUAGE C IMMUTABLE STRICT;
106+
107+ /*
108+ CREATE OR REPLACE FUNCTION @extschema@.get_whole_range(relid OID)
109+ RETURNS PathmanRange
110+ AS 'pg_pathman'
111+ LANGUAGE C STRICT;
112+
113+ CREATE OR REPLACE FUNCTION @extschema@.range_value_cmp(range PathmanRange, value ANYELEMENT)
114+ RETURNS INTEGER
115+ AS 'pg_pathman'
116+ LANGUAGE C STRICT;
117+
118+ CREATE OR REPLACE FUNCTION @extschema@.range_lower(range PathmanRange, dummy ANYELEMENT)
119+ RETURNS ANYELEMENT
120+ AS 'pg_pathman'
121+ LANGUAGE C;
122+
123+ CREATE OR REPLACE FUNCTION @extschema@.range_upper(range PathmanRange, dummy ANYELEMENT)
124+ RETURNS ANYELEMENT
125+ AS 'pg_pathman'
126+ LANGUAGE C;
127+
128+ CREATE OR REPLACE FUNCTION @extschema@.range_oid(range PathmanRange)
129+ RETURNS OID
130+ AS 'pg_pathman'
131+ LANGUAGE C STRICT;
132+
133+ CREATE OR REPLACE FUNCTION @extschema@.range_partitions_list(parent_relid OID)
134+ RETURNS SETOF PATHMANRANGE AS 'pg_pathman'
135+ LANGUAGE C STRICT;
136+ */
137+ CREATE TYPE @extschema@.PathmanRange (
138+ internallength= 32 ,
139+ input= pathman_range_in,
140+ output= pathman_range_out
141+ );
33142
34143/*
35144 * Copy rows to partitions
36145*/
37146CREATEOR REPLACE FUNCTION @extschema@.partition_data(
38- parent_relidREGCLASS,
39- OUT p_totalBIGINT )
147+ p_relation regclass
148+ , p_min ANYELEMENT DEFAULTNULL ::text
149+ , p_max ANYELEMENT DEFAULTNULL ::text
150+ , p_limitINT DEFAULTNULL
151+ , OUT p_totalBIGINT )
40152AS
41153$$
42154DECLARE
43- relnameTEXT ;
44- recRECORD;
45- cntBIGINT := 0 ;
46-
155+ v_attrTEXT ;
156+ v_limit_clauseTEXT := ' ' ;
157+ v_where_clauseTEXT := ' ' ;
47158BEGIN
48- p_total := 0 ;
49-
50- /* Create partitions and copy rest of the data*/
51- EXECUTE format(' WITH part_data AS (DELETE FROM ONLY %1$s RETURNING *)
52- INSERT INTO %1$s SELECT * FROM part_data' ,
53- @extschema@.get_schema_qualified_name(parent_relid));
54-
55- /* Get number of inserted rows*/
56- GET DIAGNOSTICS p_total= ROW_COUNT;
57- RETURN;
159+ SELECT attname INTO v_attr
160+ FROM @extschema@.pathman_configWHERE partrel= p_relation;
161+
162+ PERFORM @extschema@.debug_capture();
163+
164+ p_total := 0 ;
165+
166+ /* Format LIMIT clause if needed*/
167+ IF NOT p_limit ISNULL THEN
168+ v_limit_clause := format(' LIMIT %s' , p_limit);
169+ END IF;
170+
171+ /* Format WHERE clause if needed*/
172+ IF NOT p_min ISNULL THEN
173+ v_where_clause := format(' %1$s >= $1' , v_attr);
174+ END IF;
175+
176+ IF NOT p_max ISNULL THEN
177+ IF NOT p_min ISNULL THEN
178+ v_where_clause := v_where_clause|| ' AND' ;
179+ END IF;
180+ v_where_clause := v_where_clause|| format(' %1$s < $2' , v_attr);
181+ END IF;
182+
183+ IF v_where_clause!= ' ' THEN
184+ v_where_clause := ' WHERE' || v_where_clause;
185+ END IF;
186+
187+ /* Lock rows and copy data*/
188+ RAISE NOTICE' Copying data to partitions...' ;
189+ EXECUTE format('
190+ WITH data AS (
191+ DELETE FROM ONLY %1$s WHERE ctid IN (
192+ SELECT ctid FROM ONLY %1$s %2$s %3$s FOR UPDATE NOWAIT
193+ ) RETURNING *)
194+ INSERT INTO %1$s SELECT * FROM data'
195+ , p_relation, v_where_clause, v_limit_clause)
196+ USING p_min, p_max;
197+
198+ GET DIAGNOSTICS p_total= ROW_COUNT;
199+ RETURN;
58200END
59201$$
60202LANGUAGE plpgsql;