@@ -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 ,
7684const PartRelationInfo * prel ,
@@ -200,8 +208,11 @@ load_config(void)
200208/* Validate pg_pathman's Pl/PgSQL facade (might be outdated) */
201209validate_sql_facade_version (get_sql_facade_version ());
202210
203- init_local_cache ();/* create various hash tables (caches) */
204- 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 );
205216
206217/* Register pathman_relcache_hook(), currently we can't unregister it */
207218if (relcache_callback_needed )
@@ -777,11 +788,83 @@ read_pathman_params(Oid relid, Datum *values, bool *isnull)
777788}
778789
779790
791+ typedef struct
792+ {
793+ Oid * array ;
794+ int nelems ;
795+ int capacity ;
796+ }read_parent_oids_cxt ;
797+
798+ /*
799+ * Get a sorted array of partitioned tables' Oids.
800+ */
801+ Oid *
802+ read_parent_oids (int * nelems )
803+ {
804+ read_parent_oids_cxt context = {NULL ,0 ,0 };
805+
806+ read_pathman_config (add_partrel_to_array ,& context );
807+
808+ /* Perform sorting */
809+ qsort (context .array ,context .nelems ,sizeof (Oid ),oid_cmp );
810+
811+ /* Return values */
812+ * nelems = context .nelems ;
813+ return context .array ;
814+ }
815+
816+
817+ /* read_pathman_config(): add parent to array of Oids */
818+ static void
819+ add_partrel_to_array (Datum * values ,bool * isnull ,void * context )
820+ {
821+ Oid relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
822+ read_parent_oids_cxt * result = (read_parent_oids_cxt * )context ;
823+
824+ if (result -> array == NULL )
825+ {
826+ result -> capacity = PART_RELS_SIZE ;
827+ result -> array = palloc (result -> capacity * sizeof (Oid ));
828+ }
829+
830+ if (result -> nelems >=result -> capacity )
831+ {
832+ result -> capacity = result -> capacity * 2 + 1 ;
833+ result -> array = repalloc (result -> array ,result -> capacity * sizeof (Oid ));
834+ }
835+
836+ /* Append current relid */
837+ result -> array [result -> nelems ++ ]= relid ;
838+ }
839+
840+ /* read_pathman_config(): create dummy cache entry for parent */
841+ static void
842+ startup_invalidate_parent (Datum * values ,bool * isnull ,void * context )
843+ {
844+ Oid relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
845+
846+ /* Check that relation 'relid' exists */
847+ if (!SearchSysCacheExists1 (RELOID ,ObjectIdGetDatum (relid )))
848+ {
849+ DisablePathman ();/* disable pg_pathman since config is broken */
850+ ereport (ERROR ,
851+ (errmsg ("table \"%s\" contains nonexistent relation %u" ,
852+ PATHMAN_CONFIG ,relid ),
853+ errhint (INIT_ERROR_HINT )));
854+ }
855+
856+ /* get_pathman_relation_info() will refresh this entry */
857+ invalidate_pathman_relation_info (relid ,NULL );
858+ }
859+
780860/*
781861 * Go through the PATHMAN_CONFIG table and create PartRelationInfo entries.
782862 */
783863static void
784- read_pathman_config (void )
864+ read_pathman_config (void (* per_row_cb )(Datum * values ,
865+ bool * isnull ,
866+ void * context ),
867+ void * context )
785868{
786869Relation rel ;
787870HeapScanDesc scan ;
@@ -807,7 +890,6 @@ read_pathman_config(void)
807890{
808891Datum values [Natts_pathman_config ];
809892bool isnull [Natts_pathman_config ];
810- Oid relid ;/* partitioned table */
811893
812894/* Extract Datums from tuple 'htup' */
813895heap_deform_tuple (htup ,RelationGetDescr (rel ),values ,isnull );
@@ -817,21 +899,8 @@ read_pathman_config(void)
817899Assert (!isnull [Anum_pathman_config_parttype - 1 ]);
818900Assert (!isnull [Anum_pathman_config_expr - 1 ]);
819901
820- /* Extract values from Datums */
821- relid = DatumGetObjectId (values [Anum_pathman_config_partrel - 1 ]);
822-
823- /* Check that relation 'relid' exists */
824- if (!SearchSysCacheExists1 (RELOID ,ObjectIdGetDatum (relid )))
825- {
826- DisablePathman ();/* disable pg_pathman since config is broken */
827- ereport (ERROR ,
828- (errmsg ("table \"%s\" contains nonexistent relation %u" ,
829- PATHMAN_CONFIG ,relid ),
830- errhint (INIT_ERROR_HINT )));
831- }
832-
833- /* get_pathman_relation_info() will refresh this entry */
834- invalidate_pathman_relation_info (relid ,NULL );
902+ /* Execute per row callback */
903+ per_row_cb (values ,isnull ,context );
835904}
836905
837906/* Clean resources */
@@ -1123,6 +1192,7 @@ validate_hash_constraint(const Expr *expr,
11231192return false;
11241193}
11251194
1195+
11261196/* Parse cstring and build uint32 representing the version */
11271197static uint32
11281198build_sql_facade_version (char * version_cstr )