Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a3b7e5

Browse files
committed
on partition created callback
1 parent2f8eb90 commit0a3b7e5

File tree

10 files changed

+301
-14
lines changed

10 files changed

+301
-14
lines changed

‎expected/pg_pathman.out

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,3 +1768,59 @@ NOTICE: 100 rows copied from test_fkey_0
17681768
10
17691769
(1 row)
17701770

1771+
/* Check callbacks */
1772+
CREATE TABLE log(id serial, message text);
1773+
CREATE FUNCTION abc_on_partition_created_callback(args jsonb)
1774+
RETURNS VOID AS $$
1775+
DECLARE
1776+
start_value TEXT := args->>'start';
1777+
end_value TEXT := args::jsonb->'end';
1778+
BEGIN
1779+
-- raise notice 'callback: %', args->start;
1780+
INSERT INTO log(message)
1781+
VALUES (start_value || '-' || end_value);
1782+
END
1783+
$$ language plpgsql;
1784+
CREATE TABLE abc(a serial, b int);
1785+
SELECT create_range_partitions('abc', 'a', 1, 100, 2);
1786+
NOTICE: sequence "abc_seq" does not exist, skipping
1787+
create_range_partitions
1788+
-------------------------
1789+
2
1790+
(1 row)
1791+
1792+
SELECT set_callback('abc', 'abc_on_partition_created_callback');
1793+
set_callback
1794+
--------------
1795+
1796+
(1 row)
1797+
1798+
INSERT INTO abc VALUES (123, 1);
1799+
INSERT INTO abc VALUES (223, 1);
1800+
SELECT append_range_partition('abc');
1801+
append_range_partition
1802+
------------------------
1803+
public.abc_4
1804+
(1 row)
1805+
1806+
SELECT prepend_range_partition('abc');
1807+
prepend_range_partition
1808+
-------------------------
1809+
public.abc_5
1810+
(1 row)
1811+
1812+
SELECT add_range_partition('abc', 401, 501);
1813+
add_range_partition
1814+
---------------------
1815+
public.abc_6
1816+
(1 row)
1817+
1818+
SELECT message FROM log;
1819+
message
1820+
---------
1821+
201-301
1822+
301-401
1823+
-99-1
1824+
401-501
1825+
(4 rows)
1826+

‎init.sql

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,17 @@ CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
3131
*partrel - regclass (relation type, stored as Oid)
3232
*enable_parent - add parent table to plan
3333
*auto - enable automatic partition creation
34+
*callback -
3435
*/
3536
CREATETABLEIF NOT EXISTS @extschema@.pathman_config_params (
3637
partrelREGCLASSNOT NULLPRIMARY KEY,
3738
enable_parentBOOLEANNOT NULL DEFAULT TRUE,
38-
autoBOOLEANNOT NULL DEFAULT TRUE
39+
autoBOOLEANNOT NULL DEFAULT TRUE,
40+
callbackREGPROCEDURE
3941
);
4042
CREATEUNIQUE INDEXi_pathman_config_params
4143
ON @extschema@.pathman_config_params(partrel);
4244

43-
CREATETYPEpartitionAS (
44-
parentREGCLASS,
45-
parttypeINTEGER,
46-
childREGCLASS,
47-
start_valueTEXT,
48-
end_valueTEXT
49-
);
50-
5145
/*
5246
* Invalidate relcache every time someone changes parameters config.
5347
*/
@@ -101,7 +95,7 @@ LANGUAGE plpgsql;
10195
CREATEOR REPLACE FUNCTION @extschema@.pathman_set_param(
10296
relationREGCLASS,
10397
paramTEXT,
104-
valueBOOLEAN)
98+
valueANYELEMENT)
10599
RETURNS VOIDAS
106100
$$
107101
BEGIN
@@ -161,6 +155,19 @@ END
161155
$$
162156
LANGUAGE plpgsql;
163157

158+
/*
159+
* Set partition creation callback
160+
*/
161+
CREATEOR REPLACE FUNCTION @extschema@.set_callback(relation REGCLASS, callback REGPROC)
162+
RETURNS VOIDAS
163+
$$
164+
BEGIN
165+
PERFORM @extschema@.validate_on_partition_created_callback(callback);
166+
PERFORM @extschema@.pathman_set_param(relation,'callback', callback);
167+
END
168+
$$
169+
LANGUAGE plpgsql;
170+
164171
/*
165172
* Show all existing concurrent partitioning tasks.
166173
*/
@@ -710,3 +717,23 @@ LANGUAGE C STRICT;
710717
CREATEOR REPLACE FUNCTION @extschema@.get_rel_tablespace_name(relation REGCLASS)
711718
RETURNSTEXTAS'pg_pathman','get_rel_tablespace_name'
712719
LANGUAGE C STRICT;
720+
721+
/*
722+
* Checks that callback function meets specific requirements. Particularly it
723+
* must have the only JSONB argument and VOID return type
724+
*/
725+
CREATEOR REPLACE FUNCTION @extschema@.validate_on_partition_created_callback(callback REGPROC)
726+
RETURNS VOIDAS'pg_pathman','validate_on_partition_created_callback'
727+
LANGUAGE C STRICT;
728+
729+
/*
730+
* Builds JSONB object containing new partition parameters and invoke the
731+
* callback
732+
*/
733+
CREATEOR REPLACE FUNCTION @extschema@.invoke_on_partition_created_callback(
734+
parentREGCLASS,
735+
partitionREGCLASS,
736+
start_valueANYELEMENT,
737+
end_valueANYELEMENT)
738+
RETURNS VOIDAS'pg_pathman','invoke_on_partition_created_callback'
739+
LANGUAGE C STRICT;

‎range.sql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ BEGIN
504504
if NOT tablespace ISNULL THEN
505505
v_create_table_query := v_create_table_query||' TABLESPACE'||tablespace;
506506
END IF;
507-
RAISE NOTICE'query: %', v_create_table_query;
508507

509508
EXECUTE format(v_create_table_query,
510509
v_child_relname,
@@ -519,6 +518,10 @@ BEGIN
519518
p_end_value));
520519

521520
PERFORM @extschema@.copy_foreign_keys(parent_relid, v_child_relname::REGCLASS);
521+
PERFORM @extschema@.invoke_on_partition_created_callback(parent_relid,
522+
v_child_relname,
523+
p_start_value,
524+
p_end_value);
522525

523526
RETURN v_child_relname;
524527
END
@@ -1234,7 +1237,6 @@ BEGIN
12341237
END
12351238
$$ LANGUAGE plpgsql;
12361239

1237-
12381240
/*
12391241
* Construct CHECK constraint condition for a range partition.
12401242
*/

‎sql/pg_pathman.sql

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,3 +665,27 @@ SELECT create_hash_partitions('test_fkey', 'id', 10);
665665
INSERT INTO test_fkeyVALUES(1,'wrong');
666666
INSERT INTO test_fkeyVALUES(1,'test');
667667
SELECT drop_partitions('test_fkey');
668+
669+
/* Check callbacks*/
670+
CREATETABLElog(idserial, messagetext);
671+
672+
CREATE OR REPLACEFUNCTIONabc_on_partition_created_callback(args jsonb)
673+
RETURNS VOIDAS $$
674+
DECLARE
675+
start_valueTEXT := args->>'start';
676+
end_valueTEXT := args::jsonb->'end';
677+
BEGIN
678+
INSERT INTO log(message)
679+
VALUES (start_value||'-'|| end_value);
680+
END
681+
$$ language plpgsql;
682+
683+
CREATETABLEabc(aserial, bint);
684+
SELECT create_range_partitions('abc','a',1,100,2);
685+
SELECT set_callback('abc','abc_on_partition_created_callback');
686+
INSERT INTO abcVALUES (123,1);
687+
INSERT INTO abcVALUES (223,1);
688+
SELECT append_range_partition('abc');
689+
SELECT prepend_range_partition('abc');
690+
SELECT add_range_partition('abc',401,501);
691+
SELECT messageFROM log;

‎src/pathman.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,11 @@
5555
* Definitions for the "pathman_config_params" table
5656
*/
5757
#definePATHMAN_CONFIG_PARAMS"pathman_config_params"
58-
#defineNatts_pathman_config_params3
58+
#defineNatts_pathman_config_params4
5959
#defineAnum_pathman_config_params_partrel1/* primary key */
6060
#defineAnum_pathman_config_params_enable_parent2/* include parent into plan */
6161
#defineAnum_pathman_config_params_auto3/* auto partitions creation */
62+
#defineAnum_pathman_config_params_callback4/* auto partitions creation */
6263

6364
/*
6465
* Cache current PATHMAN_CONFIG relid (set during load_config()).

‎src/pl_funcs.c

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
#include"relation_info.h"
1414
#include"utils.h"
1515
#include"xact_handling.h"
16+
#include"fmgr.h"
1617

1718
#include"access/htup_details.h"
1819
#include"access/nbtree.h"
1920
#include"access/xact.h"
2021
#include"catalog/indexing.h"
22+
#include"catalog/pg_type.h"
23+
#include"catalog/pg_proc.h"
2124
#include"commands/sequence.h"
2225
#include"commands/tablespace.h"
2326
#include"miscadmin.h"
@@ -28,6 +31,8 @@
2831
#include"utils/lsyscache.h"
2932
#include"utils/syscache.h"
3033
#include"utils/typcache.h"
34+
#include"utils/jsonb.h"
35+
#include"utils/fmgroids.h"
3136

3237

3338
/* declarations */
@@ -57,7 +62,8 @@ PG_FUNCTION_INFO_V1( lock_partitioned_relation );
5762
PG_FUNCTION_INFO_V1(prevent_relation_modification );
5863
PG_FUNCTION_INFO_V1(debug_capture );
5964
PG_FUNCTION_INFO_V1(get_rel_tablespace_name );
60-
65+
PG_FUNCTION_INFO_V1(validate_on_partition_created_callback );
66+
PG_FUNCTION_INFO_V1(invoke_on_partition_created_callback );
6167

6268
staticvoidon_partitions_created_internal(Oidpartitioned_table,booladd_callbacks);
6369
staticvoidon_partitions_updated_internal(Oidpartitioned_table,booladd_callbacks);
@@ -776,3 +782,87 @@ get_rel_tablespace_name(PG_FUNCTION_ARGS)
776782
result=get_tablespace_name(tablespace_id);
777783
PG_RETURN_TEXT_P(cstring_to_text(result));
778784
}
785+
786+
/*
787+
* Checks that callback function meets specific requirements. Particularly it
788+
* must have the only JSONB argument and VOID return type
789+
*/
790+
Datum
791+
validate_on_partition_created_callback(PG_FUNCTION_ARGS)
792+
{
793+
HeapTupletp;
794+
Oidcallback=PG_GETARG_OID(0);
795+
Form_pg_procfunctup;
796+
797+
tp=SearchSysCache1(PROCOID,ObjectIdGetDatum(callback));
798+
if (!HeapTupleIsValid(tp))
799+
elog(ERROR,"cache lookup failed for function %u",callback);
800+
functup= (Form_pg_proc)GETSTRUCT(tp);
801+
802+
if (functup->pronargs!=1||functup->proargtypes.values[0]!=JSONBOID||
803+
functup->prorettype!=VOIDOID)
804+
elog(ERROR,
805+
"Callback function must have only one JSNOB argument "
806+
"and return VOID");
807+
808+
ReleaseSysCache(tp);
809+
PG_RETURN_VOID();
810+
}
811+
812+
/*
813+
* Builds JSONB object containing new partition parameters and invoke the
814+
* callback
815+
*/
816+
Datum
817+
invoke_on_partition_created_callback(PG_FUNCTION_ARGS)
818+
{
819+
char*json;
820+
Datumjsonb;
821+
Oidparent_oid=PG_GETARG_OID(0);
822+
Oidpartition_oid=PG_GETARG_OID(1);
823+
Oidtype=get_fn_expr_argtype(fcinfo->flinfo,2);
824+
Datumstart_value=PG_GETARG_DATUM(2);
825+
Datumend_value=PG_GETARG_DATUM(3);
826+
constPartRelationInfo*prel;
827+
828+
if ((prel=get_pathman_relation_info(parent_oid))==NULL)
829+
elog(ERROR,
830+
"Relation %s isn't partitioned by pg_pathman",
831+
get_rel_name(parent_oid));
832+
833+
/* If there is no callback function specified then we're done */
834+
if (!prel->callback)
835+
PG_RETURN_VOID();
836+
837+
/* Convert ANYELEMENT arguments to jsonb */
838+
start_value=convert_to_jsonb(start_value,type);
839+
end_value=convert_to_jsonb(end_value,type);
840+
841+
/*
842+
* Build jsonb object to pass into callback
843+
*
844+
* XXX it would be nice to have this rewrited with pushJsonbValue() to get
845+
* rid of string formatting and parsing. See jsonb_build_object() for
846+
* example
847+
*/
848+
json=psprintf("{"
849+
"\"parent\": %u,"
850+
"\"partition\": %u,"
851+
"\"part_type\": %u,"
852+
"\"start\": %s,"
853+
"\"end\": %s,"
854+
"\"value_type\": %u}",
855+
parent_oid,
856+
partition_oid,
857+
prel->parttype,
858+
datum_to_cstring(start_value,JSONBOID),
859+
datum_to_cstring(end_value,JSONBOID),
860+
type
861+
);
862+
jsonb=OidFunctionCall1(F_JSONB_IN,CStringGetDatum(json));
863+
864+
/* Invoke callback */
865+
OidFunctionCall1(prel->callback,JsonbGetDatum(jsonb));
866+
867+
PG_RETURN_JSONB(jsonb);
868+
}

‎src/relation_info.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,14 @@ refresh_pathman_relation_info(Oid relid,
165165
{
166166
prel->enable_parent=param_values[Anum_pathman_config_params_enable_parent-1];
167167
prel->auto_partition=param_values[Anum_pathman_config_params_auto-1];
168+
prel->callback=param_values[Anum_pathman_config_params_callback-1];
168169
}
169170
/* Else set default values if they cannot be found */
170171
else
171172
{
172173
prel->enable_parent= false;
173174
prel->auto_partition= true;
175+
prel->callback=InvalidOid;
174176
}
175177

176178
/* We've successfully built a cache entry */

‎src/relation_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct
4949
boolvalid;/* is this entry valid? */
5050
boolenable_parent;/* include parent to the plan */
5151
boolauto_partition;/* auto partition creation */
52+
Oidcallback;/* callback for partition creation */
5253

5354
uint32children_count;
5455
Oid*children;/* Oids of child partitions */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp