Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0b92348

Browse files
committed
fix ReScan in transform_plans_into_states(), show plans in EXPLAIN (without ANALYZE), more comments
1 parent4a838d3 commit0b92348

File tree

2 files changed

+106
-30
lines changed

2 files changed

+106
-30
lines changed

‎pickyappend.c

Lines changed: 98 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,30 @@ CustomScanMethodspickyappend_plan_methods;
2020
CustomExecMethodspickyappend_exec_methods;
2121

2222

23+
/*
24+
* Element of the plan_state_table
25+
*/
2326
typedefstruct
2427
{
2528
Oidrelid;/* relid of the corresponding partition */
2629
PlanState*ps;
2730
}PreservedPlanState;
2831

32+
/* Compare plans by 'original_order' */
33+
staticint
34+
cmp_child_scan_common_by_orig_order(constvoid*ap,
35+
constvoid*bp)
36+
{
37+
ChildScanCommona=*(ChildScanCommon*)ap;
38+
ChildScanCommonb=*(ChildScanCommon*)bp;
39+
40+
if (a->original_order>b->original_order)
41+
return1;
42+
elseif (a->original_order<b->original_order)
43+
return-1;
44+
else
45+
return0;
46+
}
2947

3048
staticvoid
3149
free_child_scan_common_array(ChildScanCommon*cur_plans,intn)
@@ -45,14 +63,11 @@ free_child_scan_common_array(ChildScanCommon *cur_plans, int n)
4563
staticvoid
4664
clear_plan_states(PickyAppendState*scan_state)
4765
{
48-
PreservedPlanState*pps;
49-
HASH_SEQ_STATUSseqstat;
66+
ListCell*state_cell;
5067

51-
hash_seq_init(&seqstat,scan_state->plan_state_table);
52-
53-
while ((pps= (PreservedPlanState*)hash_seq_search(&seqstat)))
68+
foreach (state_cell,scan_state->css.custom_ps)
5469
{
55-
ExecEndNode(pps->ps);
70+
ExecEndNode((PlanState*)lfirst(state_cell));
5671
}
5772
}
5873

@@ -73,15 +88,25 @@ transform_plans_into_states(PickyAppendState *scan_state,
7388
(constvoid*)&child->relid,
7489
HASH_ENTER,&pps_found);
7590

91+
/* Create new node since this plan hasn't been used yet */
7692
if (!pps_found)
7793
{
7894
pps->ps=ExecInitNode(child->content.plan,estate,0);
95+
/* Explain and clear_plan_states rely on this list */
7996
scan_state->css.custom_ps=lappend(scan_state->css.custom_ps,pps->ps);
8097
}
81-
else
98+
99+
/* Node with params will be ReScanned */
100+
if (scan_state->css.ss.ps.chgParam)
101+
UpdateChangedParamSet(pps->ps,scan_state->css.ss.ps.chgParam);
102+
103+
/*
104+
* We should ReScan this node manually since
105+
* ExecProcNode won't do this for us in this case.
106+
*/
107+
if (!pps->ps->chgParam)
82108
ExecReScan(pps->ps);
83109

84-
child->content_type=CHILD_PLAN_STATE;
85110
child->content.plan_state=pps->ps;
86111
}
87112
}
@@ -119,6 +144,7 @@ select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
119144
returnresult;
120145
}
121146

147+
/* Transform partition ranges into plain array of partition Oids */
122148
staticOid*
123149
get_partition_oids(List*ranges,int*n,PartRelationInfo*prel)
124150
{
@@ -216,7 +242,6 @@ create_pickyappend_path(PlannerInfo *root,
216242
Indexrelindex=path->parent->relid;
217243
ChildScanCommonchild=palloc(sizeof(ChildScanCommonData));
218244

219-
child->content_type=CHILD_PATH;
220245
child->content.path=path;
221246
child->relid=root->simple_rte_array[relindex]->relid;
222247
Assert(child->relid!=InvalidOid);
@@ -305,6 +330,7 @@ save_pickyappend_private(CustomScan *cscan, PickyAppendPath *path)
305330
pfree(children[i]);
306331
}
307332

333+
/* Save main table and partition relids */
308334
custom_private=list_make2(list_make1_oid(path->relid),custom_oids);
309335

310336
cscan->custom_private=custom_private;
@@ -319,24 +345,30 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
319345
intnchildren=list_length(custom_oids);
320346
HTAB*children_table=scan_state->children_table;
321347
HASHCTL*children_table_config=&scan_state->children_table_config;
348+
inti;
322349

323350
memset(children_table_config,0,sizeof(HASHCTL));
324351
children_table_config->keysize=sizeof(Oid);
325352
children_table_config->entrysize=sizeof(ChildScanCommonData);
326353

327354
children_table=hash_create("Plan storage",nchildren,
328-
children_table_config,HASH_ELEM |HASH_BLOBS);
355+
children_table_config,
356+
HASH_ELEM |HASH_BLOBS);
329357

358+
i=0;
330359
forboth (oid_cell,custom_oids,plan_cell,cscan->custom_plans)
331360
{
332-
Oidcur_oid=lfirst_oid(oid_cell);
361+
boolchild_found;
362+
Oidcur_oid=lfirst_oid(oid_cell);
333363

334-
ChildScanCommonchild=hash_search(children_table,
335-
(constvoid*)&cur_oid,
336-
HASH_ENTER,NULL);
364+
ChildScanCommonchild=hash_search(children_table,
365+
(constvoid*)&cur_oid,
366+
HASH_ENTER,&child_found);
367+
368+
Assert(!child_found);/* there should be no collisions */
337369

338-
child->content_type=CHILD_PLAN;
339370
child->content.plan= (Plan*)lfirst(plan_cell);
371+
child->original_order=i++;/* will be used in EXPLAIN */
340372
}
341373

342374
scan_state->children_table=children_table;
@@ -379,7 +411,9 @@ pickyappend_create_scan_state(CustomScan *node)
379411

380412
unpack_pickyappend_private(scan_state,node);
381413

414+
/* Fill in relation info using main table's relid */
382415
scan_state->prel=get_pathman_relation_info(scan_state->relid,NULL);
416+
Assert(scan_state->prel);
383417

384418
scan_state->cur_plans=NULL;
385419
scan_state->ncur_plans=0;
@@ -400,7 +434,8 @@ pickyappend_begin(CustomScanState *node, EState *estate, int eflags)
400434
plan_state_table_config->entrysize=sizeof(PreservedPlanState);
401435

402436
plan_state_table=hash_create("PlanState storage",128,
403-
plan_state_table_config,HASH_ELEM |HASH_BLOBS);
437+
plan_state_table_config,
438+
HASH_ELEM |HASH_BLOBS);
404439

405440
scan_state->plan_state_table=plan_state_table;
406441
scan_state->custom_expr_states= (List*)ExecInitExpr((Expr*)scan_state->custom_exprs,
@@ -474,9 +509,10 @@ pickyappend_rescan(CustomScanState *node)
474509
ranges=irange_list_intersect(ranges,wn->rangeset);
475510
}
476511

512+
/* Get Oids of the required partitions */
477513
parts=get_partition_oids(ranges,&nparts,prel);
478514

479-
/* Select new plans for thispass */
515+
/* Select new plans for thisrun using 'parts' */
480516
free_child_scan_common_array(scan_state->cur_plans,scan_state->ncur_plans);
481517
scan_state->cur_plans=select_required_plans(scan_state->children_table,
482518
parts,nparts,
@@ -490,11 +526,54 @@ pickyappend_rescan(CustomScanState *node)
490526
scan_state->css.ss.ps.state);
491527

492528
scan_state->running_idx=0;
493-
494-
/* elog(LOG, "nparts: %d, plans: %d", nparts, nplans); */
495529
}
496530

497531
void
498532
pickyppend_explain(CustomScanState*node,List*ancestors,ExplainState*es)
499533
{
534+
PickyAppendState*scan_state= (PickyAppendState*)node;
535+
536+
/* Construct excess PlanStates */
537+
if (!es->analyze)
538+
{
539+
intallocated=10;
540+
intused=0;
541+
ChildScanCommon*custom_ps=palloc(allocated*sizeof(ChildScanCommon));
542+
ChildScanCommonchild;
543+
HASH_SEQ_STATUSseqstat;
544+
inti;
545+
546+
/* There can't be any nodes since we're not scanning anything */
547+
Assert(!node->custom_ps);
548+
549+
hash_seq_init(&seqstat,scan_state->children_table);
550+
551+
while ((child= (ChildScanCommon)hash_seq_search(&seqstat)))
552+
{
553+
if (allocated <=used)
554+
{
555+
allocated *=2;
556+
custom_ps=repalloc(custom_ps,allocated*sizeof(ChildScanCommon));
557+
}
558+
559+
custom_ps[used++]=child;
560+
}
561+
562+
/*
563+
* We have to restore the original plan order
564+
* which has been lost within the hash table
565+
*/
566+
qsort(custom_ps,used,sizeof(ChildScanCommon),
567+
cmp_child_scan_common_by_orig_order);
568+
569+
/*
570+
* These PlanStates will be used by EXPLAIN,
571+
* pickyappend_end will destroy them eventually
572+
*/
573+
for (i=0;i<used;i++)
574+
node->custom_ps=lappend(node->custom_ps,
575+
ExecInitNode(custom_ps[i]->content.plan,
576+
node->ss.ps.state,
577+
0));
578+
}
500579
}

‎pickyappend.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,40 @@ extern bool pg_pathman_enable_pickyappend;
1111

1212
typedefstruct
1313
{
14-
Oidrelid;
15-
16-
enum
17-
{
18-
CHILD_PATH=0,
19-
CHILD_PLAN,
20-
CHILD_PLAN_STATE
21-
}content_type;
14+
Oidrelid;/* partition relid */
2215

2316
union
2417
{
2518
Path*path;
2619
Plan*plan;
2720
PlanState*plan_state;
2821
}content;
22+
23+
intoriginal_order;/* for sorting in EXPLAIN */
2924
}ChildScanCommonData;
3025

3126
typedefChildScanCommonData*ChildScanCommon;
3227

3328
typedefstruct
3429
{
3530
CustomPathcpath;
36-
Oidrelid;
31+
Oidrelid;/* relid of the partitioned table */
3732

38-
ChildScanCommon*children;
33+
ChildScanCommon*children;/* all available plans */
3934
intnchildren;
4035
}PickyAppendPath;
4136

4237
typedefstruct
4338
{
4439
CustomScanStatecss;
45-
Oidrelid;
40+
Oidrelid;/* relid of the partitioned table */
4641
PartRelationInfo*prel;
4742

43+
/* Restrictions to be checked during ReScan and Exec */
4844
List*custom_exprs;
4945
List*custom_expr_states;
5046

47+
/* All available plans */
5148
HTAB*children_table;
5249
HASHCTLchildren_table_config;
5350

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp