Skip to content

Commit 6b0dd08

Browse files
committed
store potentially reusable plan states in hash table
1 parent b72ad1a commit 6b0dd08

File tree

2 files changed

+51
-18
lines changed

2 files changed

+51
-18
lines changed

pickyappend.c

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,51 @@ CustomScanMethods pickyappend_plan_methods;
1717
CustomExecMethods pickyappend_exec_methods;
1818

1919

20+
typedef struct
21+
{
22+
Oid relid; /* relid of the corresponding partition */
23+
PlanState *ps;
24+
} PreservedPlanState;
25+
26+
2027
static 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

3641
static 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
{
3946
int i;
4047

4148
for (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

4563
child->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,
158176
RelOptInfo *outerrel,
159177
RelOptInfo *innerrel,
160178
ParamPathInfo *param_info,
161-
JoinPathExtraData *extra,
162-
PartRelationInfo *inner_prel)
179+
JoinPathExtraData *extra)
163180
{
164181
AppendPath *inner_append = (AppendPath *) innerrel->cheapest_total_path;
165182
List *joinrestrictclauses = extra->restrictlist;
@@ -279,7 +296,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
279296
inner = create_pickyappend_path(root, joinrel, outerrel, innerrel,
280297
get_appendrel_parampathinfo(innerrel,
281298
inner_required),
282-
extra, inner_prel);
299+
extra);
283300

284301
initial_cost_nestloop(root, &workspace, jointype,
285302
outer, inner,
@@ -393,7 +410,17 @@ void
393410
pickyappend_begin(CustomScanState *node, EState *estate, int eflags)
394411
{
395412
PickyAppendState *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;
397424
scan_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
{
437464
PickyAppendState *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

442470
void
@@ -465,15 +493,15 @@ pickyappend_rescan(CustomScanState *node)
465493

466494
parts = get_partition_oids(ranges, &nparts, prel);
467495

468-
clear_plan_states(scan_state->cur_plans, scan_state->ncur_plans);
469-
470496
scan_state->cur_plans = select_required_plans(scan_state->children,
471497
scan_state->nchildren,
472498
parts, nparts,
473499
&scan_state->ncur_plans);
474500
pfree(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,
477505
scan_state->css.ss.ps.state);
478506

479507
scan_state->running_idx = 0;
@@ -484,4 +512,6 @@ pickyappend_rescan(CustomScanState *node)
484512
void
485513
pickyppend_explain(CustomScanState *node, List *ancestors, ExplainState *es)
486514
{
515+
PickyAppendState *scan_state = (PickyAppendState *) node;
516+
StringInfoData str;
487517
}

pickyappend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ typedef struct
5151
ChildScanCommon *cur_plans;
5252
int ncur_plans;
5353
int running_idx;
54+
55+
HTAB *plan_state_table;
56+
HASHCTL plan_state_table_config;
5457
} PickyAppendState;
5558

5659
extern set_join_pathlist_hook_type set_join_pathlist_next;

0 commit comments

Comments
 (0)