@@ -70,7 +70,15 @@ static bool init_pathman_relation_oids(void);
7070static void fini_pathman_relation_oids (void );
7171static void init_local_cache (void );
7272static void fini_local_cache (void );
73- static void read_pathman_config (void );
73+
74+ /* Special handlers for read_pathman_config() */
75+ static void add_partrel_to_array (Datum * values , bool * isnull , void * context );
76+ static void startup_invalidate_parent (Datum * values , bool * isnull , void * context );
77+
78+ static void read_pathman_config (void (* per_row_cb )(Datum * values ,
79+ bool * isnull ,
80+ void * context ),
81+ void * context );
7482
7583static bool validate_range_opexpr (const Expr * expr ,
7684 const PartRelationInfo * prel ,
@@ -82,8 +90,6 @@ static bool read_opexpr_const(const OpExpr *opexpr,
8290 const PartRelationInfo * prel ,
8391 Datum * value );
8492
85- static int oid_cmp (const void * p1 , const void * p2 );
86-
8793
8894/* Validate SQL facade */
8995static uint32 build_sql_facade_version (char * version_cstr );
@@ -202,8 +208,11 @@ load_config(void)
202208 /* Validate pg_pathman's Pl/PgSQL facade (might be outdated) */
203209 validate_sql_facade_version (get_sql_facade_version ());
204210
205- init_local_cache (); /* create various hash tables (caches) */
206- read_pathman_config (); /* read PATHMAN_CONFIG table & fill cache */
211+ /* Create various hash tables (caches) */
212+ init_local_cache ();
213+
214+ /* Read PATHMAN_CONFIG table & fill cache */
215+ read_pathman_config (startup_invalidate_parent , NULL );
207216
208217 /* Register pathman_relcache_hook(), currently we can't unregister it */
209218 if (relcache_callback_needed )
@@ -781,11 +790,83 @@ read_pathman_params(Oid relid, Datum *values, bool *isnull)
781790}
782791
783792
793+ typedef struct
794+ {
795+ Oid * array ;
796+ int nelems ;
797+ int capacity ;
798+ } read_parent_oids_cxt ;
799+
800+ /*
801+ * Get a sorted array of partitioned tables' Oids.
802+ */
803+ Oid *
804+ read_parent_oids (int * nelems )
805+ {
806+ read_parent_oids_cxt context = { NULL , 0 , 0 };
807+
808+ read_pathman_config (add_partrel_to_array , & context );
809+
810+ /* Perform sorting */
811+ qsort (context .array , context .nelems , sizeof (Oid ), oid_cmp );
812+
813+ /* Return values */
814+ * nelems = context .nelems ;
815+ return context .array ;
816+ }
817+
818+
819+ /* read_pathman_config(): add parent to array of Oids */
820+ static void
821+ add_partrel_to_array (Datum * values , bool * isnull , void * context )
822+ {
823+ Oid relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
824+ read_parent_oids_cxt * result = (read_parent_oids_cxt * ) context ;
825+
826+ if (result -> array == NULL )
827+ {
828+ result -> capacity = PART_RELS_SIZE ;
829+ result -> array = palloc (result -> capacity * sizeof (Oid ));
830+ }
831+
832+ if (result -> nelems >= result -> capacity )
833+ {
834+ result -> capacity = result -> capacity * 2 + 1 ;
835+ result -> array = repalloc (result -> array , result -> capacity * sizeof (Oid ));
836+ }
837+
838+ /* Append current relid */
839+ result -> array [result -> nelems ++ ] = relid ;
840+ }
841+
842+ /* read_pathman_config(): create dummy cache entry for parent */
843+ static void
844+ startup_invalidate_parent (Datum * values , bool * isnull , void * context )
845+ {
846+ Oid relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
847+
848+ /* Check that relation 'relid' exists */
849+ if (!SearchSysCacheExists1 (RELOID , ObjectIdGetDatum (relid )))
850+ {
851+ DisablePathman (); /* disable pg_pathman since config is broken */
852+ ereport (ERROR ,
853+ (errmsg ("table \"%s\" contains nonexistent relation %u" ,
854+ PATHMAN_CONFIG , relid ),
855+ errhint (INIT_ERROR_HINT )));
856+ }
857+
858+ /* get_pathman_relation_info() will refresh this entry */
859+ invalidate_pathman_relation_info (relid , NULL );
860+ }
861+
784862/*
785863 * Go through the PATHMAN_CONFIG table and create PartRelationInfo entries.
786864 */
787865static void
788- read_pathman_config (void )
866+ read_pathman_config (void (* per_row_cb )(Datum * values ,
867+ bool * isnull ,
868+ void * context ),
869+ void * context )
789870{
790871 Relation rel ;
791872 HeapScanDesc scan ;
@@ -811,7 +892,6 @@ read_pathman_config(void)
811892 {
812893 Datum values [Natts_pathman_config ];
813894 bool isnull [Natts_pathman_config ];
814- Oid relid ; /* partitioned table */
815895
816896 /* Extract Datums from tuple 'htup' */
817897 heap_deform_tuple (htup , RelationGetDescr (rel ), values , isnull );
@@ -821,21 +901,8 @@ read_pathman_config(void)
821901 Assert (!isnull [Anum_pathman_config_parttype - 1 ]);
822902 Assert (!isnull [Anum_pathman_config_expr - 1 ]);
823903
824- /* Extract values from Datums */
825- relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
826-
827- /* Check that relation 'relid' exists */
828- if (!SearchSysCacheExists1 (RELOID , ObjectIdGetDatum (relid )))
829- {
830- DisablePathman (); /* disable pg_pathman since config is broken */
831- ereport (ERROR ,
832- (errmsg ("table \"%s\" contains nonexistent relation %u" ,
833- PATHMAN_CONFIG , relid ),
834- errhint (INIT_ERROR_HINT )));
835- }
836-
837- /* get_pathman_relation_info() will refresh this entry */
838- invalidate_pathman_relation_info (relid , NULL );
904+ /* Execute per row callback */
905+ per_row_cb (values , isnull , context );
839906 }
840907
841908 /* Clean resources */
@@ -1127,20 +1194,6 @@ validate_hash_constraint(const Expr *expr,
11271194 return false;
11281195}
11291196
1130- /* needed for find_inheritance_children_array() function */
1131- static int
1132- oid_cmp (const void * p1 , const void * p2 )
1133- {
1134- Oid v1 = * ((const Oid * ) p1 );
1135- Oid v2 = * ((const Oid * ) p2 );
1136-
1137- if (v1 < v2 )
1138- return -1 ;
1139- if (v1 > v2 )
1140- return 1 ;
1141- return 0 ;
1142- }
1143-
11441197
11451198/* Parse cstring and build uint32 representing the version */
11461199static uint32
0 commit comments