@@ -87,61 +87,38 @@ transform_plans_into_states(PickyAppendState *scan_state,
87
87
}
88
88
89
89
static 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 )
93
91
{
94
- ChildScanCommon * children_end = children + nchildren ;
95
- Oid * parts_end = parts + nparts ;
96
92
int allocated = 10 ;
97
93
int used = 0 ;
98
94
ChildScanCommon * result = palloc (10 * sizeof (ChildScanCommon ));
95
+ int i ;
99
96
100
- while ( children < children_end && parts < parts_end )
97
+ for ( i = 0 ; i < nparts ; i ++ )
101
98
{
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 )
105
107
{
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
+ }
115
111
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 ));
119
114
120
- result [used ++ ]= child ;
121
- children ++ ;
122
- }
123
- parts ++ ;
124
- }
115
+ result [used ++ ]= child_copy ;
125
116
}
126
117
127
118
* nres = used ;
128
119
return result ;
129
120
}
130
121
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
-
145
122
static Oid *
146
123
get_partition_oids (List * ranges ,int * n ,PartRelationInfo * prel )
147
124
{
@@ -170,27 +147,10 @@ get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
170
147
}
171
148
}
172
149
173
- if (used > 1 )
174
- qsort (result ,used ,sizeof (Oid ),oid_cmp );
175
-
176
150
* n = used ;
177
151
return result ;
178
152
}
179
153
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
-
194
154
static Path *
195
155
create_pickyappend_path (PlannerInfo * root ,
196
156
RelOptInfo * joinrel ,
@@ -261,16 +221,12 @@ create_pickyappend_path(PlannerInfo *root,
261
221
child -> relid = root -> simple_rte_array [relindex ]-> relid ;
262
222
Assert (child -> relid != InvalidOid );
263
223
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 ++ )
272
224
result -> 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
+ }
274
230
275
231
return & result -> cpath .path ;
276
232
}
@@ -357,28 +313,34 @@ save_pickyappend_private(CustomScan *cscan, PickyAppendPath *path)
357
313
static void
358
314
unpack_pickyappend_private (PickyAppendState * scan_state ,CustomScan * cscan )
359
315
{
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 ;
366
322
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 )
369
331
{
370
- ChildScanCommon child = palloc ( sizeof ( ChildScanCommonData ) );
332
+ Oid cur_oid = lfirst_oid ( oid_cell );
371
333
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 );
375
337
376
- children [i ++ ]= child ;
338
+ child -> content_type = CHILD_PLAN ;
339
+ child -> content .plan = (Plan * )lfirst (plan_cell );
377
340
}
378
341
342
+ scan_state -> children_table = children_table ;
379
343
scan_state -> relid = linitial_oid (linitial (cscan -> custom_private ));
380
- scan_state -> children = children ;
381
- scan_state -> nchildren = nchildren ;
382
344
}
383
345
384
346
Plan *
@@ -485,6 +447,7 @@ pickyappend_end(CustomScanState *node)
485
447
486
448
clear_plan_states (scan_state );
487
449
hash_destroy (scan_state -> plan_state_table );
450
+ hash_destroy (scan_state -> children_table );
488
451
}
489
452
490
453
void
@@ -515,8 +478,7 @@ pickyappend_rescan(CustomScanState *node)
515
478
516
479
/* Select new plans for this pass */
517
480
free_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 ,
520
482
parts ,nparts ,
521
483
& scan_state -> ncur_plans );
522
484
pfree (parts );