@@ -30,21 +30,6 @@ cmp_child_scan_common_by_orig_order(const void *ap,
3030 return 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 ,
5035 ChildScanCommon * selected_plans , int n ,
@@ -55,33 +40,35 @@ transform_plans_into_states(RuntimeAppendState *scan_state,
5540 for (i = 0 ; i < n ; i ++ )
5641 {
5742 ChildScanCommon 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 */
7461 if (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
9683 for (i = 0 ; i < nparts ; i ++ )
9784 {
98- ChildScanCommon child_copy ;
9985 ChildScanCommon child = hash_search (children_table ,
10086 (const void * ) & parts [i ],
10187 HASH_FIND , NULL );
10288 if (!child )
103- continue ;
89+ continue ; /* no plan for this partition */
10490
10591 if (allocated <= used )
10692 {
10793 allocated *= 2 ;
10894 result = 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
205188 Assert (!child_found ); /* there should be no collisions */
206189
190+ child -> content_type = CHILD_PLAN ;
207191 child -> content .plan = (Plan * ) lfirst (plan_cell );
208192 child -> original_order = i ++ ; /* will be used in EXPLAIN */
209193 }
@@ -265,6 +249,7 @@ create_append_path_common(PlannerInfo *root,
265249 result -> cpath .path .startup_cost += path -> startup_cost ;
266250 result -> cpath .path .total_cost += path -> total_cost ;
267251
252+ child -> content_type = CHILD_PATH ;
268253 child -> content .path = path ;
269254 child -> relid = root -> simple_rte_array [relindex ]-> relid ;
270255 Assert (child -> relid != InvalidOid );
@@ -336,18 +321,7 @@ void
336321begin_append_common (CustomScanState * node , EState * estate , int eflags )
337322{
338323 RuntimeAppendState * 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 ;
351325 scan_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)
359333 RuntimeAppendState * scan_state = (RuntimeAppendState * ) node ;
360334
361335 clear_plan_states (& scan_state -> css );
362- hash_destroy (scan_state -> plan_state_table );
363336 hash_destroy (scan_state -> children_table );
364337}
365338
@@ -391,7 +364,9 @@ rescan_append_common(CustomScanState *node)
391364 parts = 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 */
395370 scan_state -> cur_plans = select_required_plans (scan_state -> children_table ,
396371 parts , nparts ,
397372 & scan_state -> ncur_plans );
0 commit comments