@@ -30,21 +30,6 @@ cmp_child_scan_common_by_orig_order(const void *ap,
3030return 0 ;
3131}
3232
33- static void
34- free_child_scan_common_array (ChildScanCommon * cur_plans ,int n )
35- {
36- int i ;
37-
38- if (!cur_plans )
39- return ;
40-
41- /* We shouldn't free inner objects e.g. Plans here */
42- for (i = 0 ;i < n ;i ++ )
43- pfree (cur_plans [i ]);
44-
45- pfree (cur_plans );
46- }
47-
4833static void
4934transform_plans_into_states (RuntimeAppendState * scan_state ,
5035ChildScanCommon * selected_plans ,int n ,
@@ -55,33 +40,35 @@ transform_plans_into_states(RuntimeAppendState *scan_state,
5540for (i = 0 ;i < n ;i ++ )
5641{
5742ChildScanCommon child = selected_plans [i ];
58- PreservedPlanState * pps ;
59- bool pps_found ;
60-
61- pps = (PreservedPlanState * )hash_search (scan_state -> plan_state_table ,
62- (const void * )& child -> relid ,
63- HASH_ENTER ,& pps_found );
43+ PlanState * ps ;
6444
6545/* Create new node since this plan hasn't been used yet */
66- if (! pps_found )
46+ if (child -> content_type != CHILD_PLAN_STATE )
6747{
68- pps -> ps = ExecInitNode (child -> content .plan ,estate ,0 );
48+ Assert (child -> content_type == CHILD_PLAN );/* no paths allowed */
49+
50+ ps = ExecInitNode (child -> content .plan ,estate ,0 );
51+ child -> content .plan_state = ps ;
52+ child -> content_type = CHILD_PLAN_STATE ;/* update content type */
53+
6954/* Explain and clear_plan_states rely on this list */
70- scan_state -> css .custom_ps = lappend (scan_state -> css .custom_ps ,pps -> ps );
55+ scan_state -> css .custom_ps = lappend (scan_state -> css .custom_ps ,ps );
7156}
72-
57+ else
58+ ps = child -> content .plan_state ;
59+
7360/* Node with params will be ReScanned */
7461if (scan_state -> css .ss .ps .chgParam )
75- UpdateChangedParamSet (pps -> ps ,scan_state -> css .ss .ps .chgParam );
62+ UpdateChangedParamSet (ps ,scan_state -> css .ss .ps .chgParam );
7663
7764/*
7865 * We should ReScan this node manually since
7966 * ExecProcNode won't do this for us in this case.
8067 */
81- if (bms_is_empty (pps -> ps -> chgParam ))
82- ExecReScan (pps -> ps );
68+ if (bms_is_empty (ps -> chgParam ))
69+ ExecReScan (ps );
8370
84- child -> content .plan_state = pps -> ps ;
71+ child -> content .plan_state = ps ;
8572}
8673}
8774
@@ -95,23 +82,19 @@ select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
9582
9683for (i = 0 ;i < nparts ;i ++ )
9784{
98- ChildScanCommon child_copy ;
9985ChildScanCommon child = hash_search (children_table ,
10086(const void * )& parts [i ],
10187HASH_FIND ,NULL );
10288if (!child )
103- continue ;
89+ continue ;/* no plan for this partition */
10490
10591if (allocated <=used )
10692{
10793allocated *=2 ;
10894result = repalloc (result ,allocated * sizeof (ChildScanCommon ));
10995}
11096
111- child_copy = palloc (sizeof (ChildScanCommonData ));
112- memcpy (child_copy ,child ,sizeof (ChildScanCommonData ));
113-
114- result [used ++ ]= child_copy ;
97+ result [used ++ ]= child ;
11598}
11699
117100* nres = used ;
@@ -204,6 +187,7 @@ unpack_runtimeappend_private(RuntimeAppendState *scan_state, CustomScan *cscan)
204187
205188Assert (!child_found );/* there should be no collisions */
206189
190+ child -> content_type = CHILD_PLAN ;
207191child -> content .plan = (Plan * )lfirst (plan_cell );
208192child -> original_order = i ++ ;/* will be used in EXPLAIN */
209193}
@@ -265,6 +249,7 @@ create_append_path_common(PlannerInfo *root,
265249result -> cpath .path .startup_cost += path -> startup_cost ;
266250result -> cpath .path .total_cost += path -> total_cost ;
267251
252+ child -> content_type = CHILD_PATH ;
268253child -> content .path = path ;
269254child -> relid = root -> simple_rte_array [relindex ]-> relid ;
270255Assert (child -> relid != InvalidOid );
@@ -336,18 +321,7 @@ void
336321begin_append_common (CustomScanState * node ,EState * estate ,int eflags )
337322{
338323RuntimeAppendState * scan_state = (RuntimeAppendState * )node ;
339- HTAB * plan_state_table ;
340- HASHCTL * plan_state_table_config = & scan_state -> plan_state_table_config ;
341-
342- memset (plan_state_table_config ,0 ,sizeof (HASHCTL ));
343- plan_state_table_config -> keysize = sizeof (Oid );
344- plan_state_table_config -> entrysize = sizeof (PreservedPlanState );
345-
346- plan_state_table = hash_create ("PlanState storage" ,128 ,
347- plan_state_table_config ,
348- HASH_ELEM |HASH_BLOBS );
349324
350- scan_state -> plan_state_table = plan_state_table ;
351325scan_state -> custom_expr_states =
352326(List * )ExecInitExpr ((Expr * )scan_state -> custom_exprs ,
353327 (PlanState * )scan_state );
@@ -359,7 +333,6 @@ end_append_common(CustomScanState *node)
359333RuntimeAppendState * scan_state = (RuntimeAppendState * )node ;
360334
361335clear_plan_states (& scan_state -> css );
362- hash_destroy (scan_state -> plan_state_table );
363336hash_destroy (scan_state -> children_table );
364337}
365338
@@ -391,7 +364,9 @@ rescan_append_common(CustomScanState *node)
391364parts = get_partition_oids (ranges ,& nparts ,prel );
392365
393366/* Select new plans for this run using 'parts' */
394- free_child_scan_common_array (scan_state -> cur_plans ,scan_state -> ncur_plans );
367+ if (scan_state -> cur_plans )
368+ pfree (scan_state -> cur_plans );/* shallow free since cur_plans
369+ * belong to children_table */
395370scan_state -> cur_plans = select_required_plans (scan_state -> children_table ,
396371parts ,nparts ,
397372& scan_state -> ncur_plans );