@@ -17,33 +17,51 @@ CustomScanMethodspickyappend_plan_methods;
1717CustomExecMethods pickyappend_exec_methods ;
1818
1919
20+ typedef struct
21+ {
22+ Oid relid ;/* relid of the corresponding partition */
23+ PlanState * ps ;
24+ }PreservedPlanState ;
25+
26+
2027static void
21- clear_plan_states (ChildScanCommon * selected_plans , int n )
28+ clear_plan_states (PickyAppendState * scan_state )
2229{
23- int i ;
30+ PreservedPlanState * pps ;
31+ HASH_SEQ_STATUS seqstat ;
2432
25- if (!selected_plans )
26- return ;
33+ hash_seq_init (& seqstat ,scan_state -> plan_state_table );
2734
28- for ( i = 0 ; i < n ; i ++ )
35+ while (( pps = ( PreservedPlanState * ) hash_seq_search ( & seqstat )) )
2936{
30- ChildScanCommon child = selected_plans [i ];
31-
32- ExecEndNode (child -> content .plan_state );
37+ ExecEndNode (pps -> ps );
3338}
3439}
3540
3641static void
37- transform_plans_into_states (ChildScanCommon * selected_plans ,int n ,EState * estate )
42+ transform_plans_into_states (PickyAppendState * scan_state ,
43+ ChildScanCommon * selected_plans ,int n ,
44+ EState * estate )
3845{
3946int i ;
4047
4148for (i = 0 ;i < n ;i ++ )
4249{
43- ChildScanCommon child = selected_plans [i ];
50+ ChildScanCommon child = selected_plans [i ];
51+ PreservedPlanState * pps ;
52+ bool pps_found ;
53+
54+ pps = (PreservedPlanState * )hash_search (scan_state -> plan_state_table ,
55+ (const void * )& child -> relid ,
56+ HASH_ENTER ,& pps_found );
57+
58+ if (!pps_found )
59+ pps -> ps = ExecInitNode (child -> content .plan ,estate ,0 );
60+ else
61+ ExecReScan (pps -> ps );
4462
4563child -> content_type = CHILD_PLAN_STATE ;
46- child -> content .plan_state = ExecInitNode ( child -> content . plan , estate , 0 ) ;
64+ child -> content .plan_state = pps -> ps ;
4765}
4866}
4967
@@ -158,8 +176,7 @@ create_pickyappend_path(PlannerInfo *root,
158176RelOptInfo * outerrel ,
159177RelOptInfo * innerrel ,
160178ParamPathInfo * param_info ,
161- JoinPathExtraData * extra ,
162- PartRelationInfo * inner_prel )
179+ JoinPathExtraData * extra )
163180{
164181AppendPath * inner_append = (AppendPath * )innerrel -> cheapest_total_path ;
165182List * joinrestrictclauses = extra -> restrictlist ;
@@ -279,7 +296,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
279296inner = create_pickyappend_path (root ,joinrel ,outerrel ,innerrel ,
280297get_appendrel_parampathinfo (innerrel ,
281298inner_required ),
282- extra , inner_prel );
299+ extra );
283300
284301initial_cost_nestloop (root ,& workspace ,jointype ,
285302outer ,inner ,
@@ -393,7 +410,17 @@ void
393410pickyappend_begin (CustomScanState * node ,EState * estate ,int eflags )
394411{
395412PickyAppendState * scan_state = (PickyAppendState * )node ;
413+ HTAB * plan_state_table = scan_state -> plan_state_table ;
414+ HASHCTL * plan_state_table_config = & scan_state -> plan_state_table_config ;
415+
416+ memset (plan_state_table_config ,0 ,sizeof (HASHCTL ));
417+ plan_state_table_config -> keysize = sizeof (Oid );
418+ plan_state_table_config -> entrysize = sizeof (PreservedPlanState );
396419
420+ plan_state_table = hash_create ("PlanState storage" ,128 ,
421+ plan_state_table_config ,HASH_ELEM |HASH_BLOBS );
422+
423+ scan_state -> plan_state_table = plan_state_table ;
397424scan_state -> custom_expr_states = (List * )ExecInitExpr ((Expr * )scan_state -> custom_exprs ,
398425 (PlanState * )scan_state );
399426}
@@ -436,7 +463,8 @@ pickyappend_end(CustomScanState *node)
436463{
437464PickyAppendState * scan_state = (PickyAppendState * )node ;
438465
439- clear_plan_states (scan_state -> cur_plans ,scan_state -> ncur_plans );
466+ clear_plan_states (scan_state );
467+ hash_destroy (scan_state -> plan_state_table );
440468}
441469
442470void
@@ -465,15 +493,15 @@ pickyappend_rescan(CustomScanState *node)
465493
466494parts = get_partition_oids (ranges ,& nparts ,prel );
467495
468- clear_plan_states (scan_state -> cur_plans ,scan_state -> ncur_plans );
469-
470496scan_state -> cur_plans = select_required_plans (scan_state -> children ,
471497scan_state -> nchildren ,
472498parts ,nparts ,
473499& scan_state -> ncur_plans );
474500pfree (parts );
475501
476- transform_plans_into_states (scan_state -> cur_plans ,scan_state -> ncur_plans ,
502+ transform_plans_into_states (scan_state ,
503+ scan_state -> cur_plans ,
504+ scan_state -> ncur_plans ,
477505scan_state -> css .ss .ps .state );
478506
479507scan_state -> running_idx = 0 ;
@@ -484,4 +512,6 @@ pickyappend_rescan(CustomScanState *node)
484512void
485513pickyppend_explain (CustomScanState * node ,List * ancestors ,ExplainState * es )
486514{
515+ PickyAppendState * scan_state = (PickyAppendState * )node ;
516+ StringInfoData str ;
487517}