@@ -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 ,
@@ -200,8 +208,11 @@ load_config(void)
200208 /* Validate pg_pathman's Pl/PgSQL facade (might be outdated) */
201209 validate_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 */
207218 if (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{
786869 Relation rel ;
787870 HeapScanDesc scan ;
@@ -807,7 +890,6 @@ read_pathman_config(void)
807890 {
808891 Datum values [Natts_pathman_config ];
809892 bool isnull [Natts_pathman_config ];
810- Oid relid ; /* partitioned table */
811893
812894 /* Extract Datums from tuple 'htup' */
813895 heap_deform_tuple (htup , RelationGetDescr (rel ), values , isnull );
@@ -817,21 +899,8 @@ read_pathman_config(void)
817899 Assert (!isnull [Anum_pathman_config_parttype - 1 ]);
818900 Assert (!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,
11231192 return false;
11241193}
11251194
1195+
11261196/* Parse cstring and build uint32 representing the version */
11271197static uint32
11281198build_sql_facade_version (char * version_cstr )
0 commit comments