@@ -87,61 +87,38 @@ transform_plans_into_states(PickyAppendState *scan_state,
8787}
8888
8989static ChildScanCommon *
90- select_required_plans (ChildScanCommon * children ,int nchildren ,
91- Oid * parts ,int nparts ,
92- int * nres )
90+ select_required_plans (HTAB * children_table ,Oid * parts ,int nparts ,int * nres )
9391{
94- ChildScanCommon * children_end = children + nchildren ;
95- Oid * parts_end = parts + nparts ;
9692int allocated = 10 ;
9793int used = 0 ;
9894ChildScanCommon * result = palloc (10 * sizeof (ChildScanCommon ));
95+ int i ;
9996
100- while ( children < children_end && parts < parts_end )
97+ for ( i = 0 ; i < nparts ; i ++ )
10198{
102- if ((* children )-> relid < * parts )
103- children ++ ;
104- else
99+ ChildScanCommon child_copy ;
100+ ChildScanCommon child = hash_search (children_table ,
101+ (const void * )& parts [i ],
102+ HASH_FIND ,NULL );
103+ if (!child )
104+ continue ;
105+
106+ if (allocated <=used )
105107{
106- if (!(* parts < (* children )-> relid ))
107- {
108- ChildScanCommon child = palloc (sizeof (ChildScanCommonData ));
109-
110- if (allocated <=used )
111- {
112- allocated *=2 ;
113- result = repalloc (result ,allocated * sizeof (ChildScanCommon ));
114- }
108+ allocated *=2 ;
109+ result = repalloc (result ,allocated * sizeof (ChildScanCommon ));
110+ }
115111
116- child -> content_type = CHILD_PLAN ;
117- child -> content .plan = (* children )-> content .plan ;
118- child -> relid = (* children )-> relid ;
112+ child_copy = palloc (sizeof (ChildScanCommonData ));
113+ memcpy (child_copy ,child ,sizeof (ChildScanCommonData ));
119114
120- result [used ++ ]= child ;
121- children ++ ;
122- }
123- parts ++ ;
124- }
115+ result [used ++ ]= child_copy ;
125116}
126117
127118* nres = used ;
128119return result ;
129120}
130121
131- /* qsort comparison function for oids */
132- static int
133- oid_cmp (const void * p1 ,const void * p2 )
134- {
135- Oid v1 = * ((const Oid * )p1 );
136- Oid v2 = * ((const Oid * )p2 );
137-
138- if (v1 < v2 )
139- return -1 ;
140- if (v1 > v2 )
141- return 1 ;
142- return 0 ;
143- }
144-
145122static Oid *
146123get_partition_oids (List * ranges ,int * n ,PartRelationInfo * prel )
147124{
@@ -170,27 +147,10 @@ get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
170147}
171148}
172149
173- if (used > 1 )
174- qsort (result ,used ,sizeof (Oid ),oid_cmp );
175-
176150* n = used ;
177151return result ;
178152}
179153
180- static int
181- cmp_child_scan_common (const void * a ,const void * b )
182- {
183- ChildScanCommon child_a = * (ChildScanCommon * )a ;
184- ChildScanCommon child_b = * (ChildScanCommon * )b ;
185-
186- if (child_a -> relid > child_b -> relid )
187- return 1 ;
188- else if (child_a -> relid < child_b -> relid )
189- return -1 ;
190- else
191- return 0 ;
192- }
193-
194154static Path *
195155create_pickyappend_path (PlannerInfo * root ,
196156RelOptInfo * joinrel ,
@@ -261,16 +221,12 @@ create_pickyappend_path(PlannerInfo *root,
261221child -> relid = root -> simple_rte_array [relindex ]-> relid ;
262222Assert (child -> relid != InvalidOid );
263223
264- result -> children [i ++ ]= child ;
265- }
266-
267- qsort (result -> children ,result -> nchildren ,
268- sizeof (ChildScanCommon ),cmp_child_scan_common );
269-
270- /* Fill 'custom_paths' with paths in sort order */
271- for (i = 0 ;i < result -> nchildren ;i ++ )
272224result -> cpath .custom_paths = lappend (result -> cpath .custom_paths ,
273- result -> children [i ]-> content .path );
225+ child -> content .path );
226+ result -> children [i ]= child ;
227+
228+ i ++ ;
229+ }
274230
275231return & result -> cpath .path ;
276232}
@@ -357,28 +313,34 @@ save_pickyappend_private(CustomScan *cscan, PickyAppendPath *path)
357313static void
358314unpack_pickyappend_private (PickyAppendState * scan_state ,CustomScan * cscan )
359315{
360- List * custom_oids = ( List * ) lsecond ( cscan -> custom_private ) ;
361- int nchildren = list_length ( custom_oids ) ;
362- ChildScanCommon * children = palloc ( nchildren * sizeof ( ChildScanCommon ) );
363- ListCell * cur_oid ;
364- ListCell * cur_plan ;
365- int i ;
316+ ListCell * oid_cell ;
317+ ListCell * plan_cell ;
318+ List * custom_oids = ( List * ) lsecond ( cscan -> custom_private );
319+ int nchildren = list_length ( custom_oids ) ;
320+ HTAB * children_table = scan_state -> children_table ;
321+ HASHCTL * children_table_config = & scan_state -> children_table_config ;
366322
367- i = 0 ;
368- forboth (cur_oid ,custom_oids ,cur_plan ,cscan -> custom_plans )
323+ memset (children_table_config ,0 ,sizeof (HASHCTL ));
324+ children_table_config -> keysize = sizeof (Oid );
325+ children_table_config -> entrysize = sizeof (ChildScanCommonData );
326+
327+ children_table = hash_create ("Plan storage" ,nchildren ,
328+ children_table_config ,HASH_ELEM |HASH_BLOBS );
329+
330+ forboth (oid_cell ,custom_oids ,plan_cell ,cscan -> custom_plans )
369331{
370- ChildScanCommon child = palloc ( sizeof ( ChildScanCommonData ) );
332+ Oid cur_oid = lfirst_oid ( oid_cell );
371333
372- child -> content_type = CHILD_PLAN ;
373- child -> content . plan = ( Plan * )lfirst ( cur_plan );
374- child -> relid = lfirst_oid ( cur_oid );
334+ ChildScanCommon child = hash_search ( children_table ,
335+ ( const void * )& cur_oid ,
336+ HASH_ENTER , NULL );
375337
376- children [i ++ ]= child ;
338+ child -> content_type = CHILD_PLAN ;
339+ child -> content .plan = (Plan * )lfirst (plan_cell );
377340}
378341
342+ scan_state -> children_table = children_table ;
379343scan_state -> relid = linitial_oid (linitial (cscan -> custom_private ));
380- scan_state -> children = children ;
381- scan_state -> nchildren = nchildren ;
382344}
383345
384346Plan *
@@ -485,6 +447,7 @@ pickyappend_end(CustomScanState *node)
485447
486448clear_plan_states (scan_state );
487449hash_destroy (scan_state -> plan_state_table );
450+ hash_destroy (scan_state -> children_table );
488451}
489452
490453void
@@ -515,8 +478,7 @@ pickyappend_rescan(CustomScanState *node)
515478
516479/* Select new plans for this pass */
517480free_child_scan_common_array (scan_state -> cur_plans ,scan_state -> ncur_plans );
518- scan_state -> cur_plans = select_required_plans (scan_state -> children ,
519- scan_state -> nchildren ,
481+ scan_state -> cur_plans = select_required_plans (scan_state -> children_table ,
520482parts ,nparts ,
521483& scan_state -> ncur_plans );
522484pfree (parts );