21
21
#include "access/htup_details.h"
22
22
#include "access/sysattr.h"
23
23
#include "catalog/indexing.h"
24
- #include "catalog/pg_constraint.h"
25
24
#include "catalog/pg_extension.h"
26
25
#include "catalog/pg_inherits.h"
27
26
#include "catalog/pg_inherits_fn.h"
38
37
#include "utils/syscache.h"
39
38
#include "utils/typcache.h"
40
39
41
- #if PG_VERSION_NUM >= 90600
42
- #include "catalog/pg_constraint_fn.h"
43
- #endif
44
-
45
-
46
- /* Help user in case of emergency */
47
- #define INIT_ERROR_HINT "pg_pathman will be disabled to allow you to resolve this issue"
48
40
49
41
/* Initial size of 'partitioned_rels' table */
50
42
#define PART_RELS_SIZE 10
@@ -57,6 +49,9 @@ HTAB *partitioned_rels = NULL;
57
49
/* Storage for PartParentInfos */
58
50
HTAB * parent_cache = NULL ;
59
51
52
+ /* Storage for partition constraints */
53
+ HTAB * constraint_cache = NULL ;
54
+
60
55
/* pg_pathman's init status */
61
56
PathmanInitState pg_pathman_init_state ;
62
57
@@ -71,8 +66,6 @@ static void init_local_cache(void);
71
66
static void fini_local_cache (void );
72
67
static void read_pathman_config (void );
73
68
74
- static Expr * get_partition_constraint_expr (Oid partition , AttrNumber part_attno );
75
-
76
69
static int cmp_range_entries (const void * p1 , const void * p2 , void * arg );
77
70
78
71
static bool validate_range_constraint (const Expr * expr ,
@@ -312,6 +305,7 @@ init_local_cache(void)
312
305
/* Destroy caches, just in case */
313
306
hash_destroy (partitioned_rels );
314
307
hash_destroy (parent_cache );
308
+ hash_destroy (constraint_cache );
315
309
316
310
memset (& ctl , 0 , sizeof (ctl ));
317
311
ctl .keysize = sizeof (Oid );
@@ -329,6 +323,15 @@ init_local_cache(void)
329
323
parent_cache = hash_create ("pg_pathman's partition parents cache" ,
330
324
PART_RELS_SIZE * CHILD_FACTOR ,
331
325
& ctl , HASH_ELEM | HASH_BLOBS );
326
+
327
+ memset (& ctl , 0 , sizeof (ctl ));
328
+ ctl .keysize = sizeof (Oid );
329
+ ctl .entrysize = sizeof (PartConstraintInfo );
330
+ ctl .hcxt = TopMemoryContext ; /* place data to persistent mcxt */
331
+
332
+ constraint_cache = hash_create ("pg_pathman's partition constraints cache" ,
333
+ PART_RELS_SIZE * CHILD_FACTOR ,
334
+ & ctl , HASH_ELEM | HASH_BLOBS );
332
335
}
333
336
334
337
/*
@@ -386,10 +389,10 @@ fill_prel_with_partitions(const Oid *partitions,
386
389
/* Raise ERROR if there's no such column */
387
390
if (part_attno == InvalidAttrNumber )
388
391
elog (ERROR , "partition \"%s\" has no column \"%s\"" ,
389
- get_rel_name_or_relid (partitions [i ]),
390
- part_column_name );
392
+ get_rel_name_or_relid (partitions [i ]), part_column_name );
391
393
392
- con_expr = get_partition_constraint_expr (partitions [i ], part_attno );
394
+ /* Fetch constraint's expression tree */
395
+ con_expr = get_constraint_of_partition (partitions [i ], part_attno );
393
396
394
397
/* Perform a partitioning_type-dependent task */
395
398
switch (prel -> parttype )
@@ -863,58 +866,6 @@ read_pathman_config(void)
863
866
heap_close (rel , AccessShareLock );
864
867
}
865
868
866
- /*
867
- * Get constraint expression tree for a partition.
868
- *
869
- * build_check_constraint_name_internal() is used to build conname.
870
- */
871
- static Expr *
872
- get_partition_constraint_expr (Oid partition , AttrNumber part_attno )
873
- {
874
- Oid conid ; /* constraint Oid */
875
- char * conname ; /* constraint name */
876
- HeapTuple con_tuple ;
877
- Datum conbin_datum ;
878
- bool conbin_isnull ;
879
- Expr * expr ; /* expression tree for constraint */
880
-
881
- conname = build_check_constraint_name_relid_internal (partition , part_attno );
882
- conid = get_relation_constraint_oid (partition , conname , true);
883
- if (conid == InvalidOid )
884
- {
885
- DisablePathman (); /* disable pg_pathman since config is broken */
886
- ereport (ERROR ,
887
- (errmsg ("constraint \"%s\" for partition \"%s\" does not exist" ,
888
- conname , get_rel_name_or_relid (partition )),
889
- errhint (INIT_ERROR_HINT )));
890
- }
891
-
892
- con_tuple = SearchSysCache1 (CONSTROID , ObjectIdGetDatum (conid ));
893
- conbin_datum = SysCacheGetAttr (CONSTROID , con_tuple ,
894
- Anum_pg_constraint_conbin ,
895
- & conbin_isnull );
896
- if (conbin_isnull )
897
- {
898
- DisablePathman (); /* disable pg_pathman since config is broken */
899
- ereport (WARNING ,
900
- (errmsg ("constraint \"%s\" for partition \"%s\" has NULL conbin" ,
901
- conname , get_rel_name_or_relid (partition )),
902
- errhint (INIT_ERROR_HINT )));
903
- pfree (conname );
904
-
905
- return NULL ; /* could not parse */
906
- }
907
- pfree (conname );
908
-
909
- /* Finally we get a constraint expression tree */
910
- expr = (Expr * ) stringToNode (TextDatumGetCString (conbin_datum ));
911
-
912
- /* Don't foreget to release syscache tuple */
913
- ReleaseSysCache (con_tuple );
914
-
915
- return expr ;
916
- }
917
-
918
869
/* qsort comparison function for RangeEntries */
919
870
static int
920
871
cmp_range_entries (const void * p1 , const void * p2 , void * arg )
0 commit comments