2121#include "access/htup_details.h"
2222#include "access/sysattr.h"
2323#include "catalog/indexing.h"
24- #include "catalog/pg_constraint.h"
2524#include "catalog/pg_extension.h"
2625#include "catalog/pg_inherits.h"
2726#include "catalog/pg_inherits_fn.h"
3837#include "utils/syscache.h"
3938#include "utils/typcache.h"
4039
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"
4840
4941/* Initial size of 'partitioned_rels' table */
5042#define PART_RELS_SIZE 10
@@ -57,6 +49,9 @@ HTAB *partitioned_rels = NULL;
5749/* Storage for PartParentInfos */
5850HTAB * parent_cache = NULL ;
5951
52+ /* Storage for partition constraints */
53+ HTAB * constraint_cache = NULL ;
54+
6055/* pg_pathman's init status */
6156PathmanInitState pg_pathman_init_state ;
6257
@@ -71,8 +66,6 @@ static void init_local_cache(void);
7166static void fini_local_cache (void );
7267static void read_pathman_config (void );
7368
74- static Expr * get_partition_constraint_expr (Oid partition ,AttrNumber part_attno );
75-
7669static int cmp_range_entries (const void * p1 ,const void * p2 ,void * arg );
7770
7871static bool validate_range_constraint (const Expr * expr ,
@@ -312,6 +305,7 @@ init_local_cache(void)
312305/* Destroy caches, just in case */
313306hash_destroy (partitioned_rels );
314307hash_destroy (parent_cache );
308+ hash_destroy (constraint_cache );
315309
316310memset (& ctl ,0 ,sizeof (ctl ));
317311ctl .keysize = sizeof (Oid );
@@ -329,6 +323,15 @@ init_local_cache(void)
329323parent_cache = hash_create ("pg_pathman's partition parents cache" ,
330324PART_RELS_SIZE * CHILD_FACTOR ,
331325& 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 );
332335}
333336
334337/*
@@ -386,10 +389,10 @@ fill_prel_with_partitions(const Oid *partitions,
386389/* Raise ERROR if there's no such column */
387390if (part_attno == InvalidAttrNumber )
388391elog (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 );
391393
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 );
393396
394397/* Perform a partitioning_type-dependent task */
395398switch (prel -> parttype )
@@ -863,58 +866,6 @@ read_pathman_config(void)
863866heap_close (rel ,AccessShareLock );
864867}
865868
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-
918869/* qsort comparison function for RangeEntries */
919870static int
920871cmp_range_entries (const void * p1 ,const void * p2 ,void * arg )