|
13 | 13 | #include"relation_info.h"
|
14 | 14 | #include"utils.h"
|
15 | 15 | #include"xact_handling.h"
|
| 16 | +#include"fmgr.h" |
16 | 17 |
|
17 | 18 | #include"access/htup_details.h"
|
18 | 19 | #include"access/nbtree.h"
|
19 | 20 | #include"access/xact.h"
|
20 | 21 | #include"catalog/indexing.h"
|
| 22 | +#include"catalog/pg_type.h" |
| 23 | +#include"catalog/pg_proc.h" |
21 | 24 | #include"commands/sequence.h"
|
22 | 25 | #include"commands/tablespace.h"
|
23 | 26 | #include"miscadmin.h"
|
|
28 | 31 | #include"utils/lsyscache.h"
|
29 | 32 | #include"utils/syscache.h"
|
30 | 33 | #include"utils/typcache.h"
|
| 34 | +#include"utils/jsonb.h" |
| 35 | +#include"utils/fmgroids.h" |
31 | 36 |
|
32 | 37 |
|
33 | 38 | /* declarations */
|
@@ -57,7 +62,8 @@ PG_FUNCTION_INFO_V1( lock_partitioned_relation );
|
57 | 62 | PG_FUNCTION_INFO_V1(prevent_relation_modification );
|
58 | 63 | PG_FUNCTION_INFO_V1(debug_capture );
|
59 | 64 | 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 ); |
61 | 67 |
|
62 | 68 | staticvoidon_partitions_created_internal(Oidpartitioned_table,booladd_callbacks);
|
63 | 69 | staticvoidon_partitions_updated_internal(Oidpartitioned_table,booladd_callbacks);
|
@@ -776,3 +782,87 @@ get_rel_tablespace_name(PG_FUNCTION_ARGS)
|
776 | 782 | result=get_tablespace_name(tablespace_id);
|
777 | 783 | PG_RETURN_TEXT_P(cstring_to_text(result));
|
778 | 784 | }
|
| 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 | +} |