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

Commitda48f47

Browse files
committed
perform ReScan in pickyappend_exec (required for IndexScans), restore previous EXPLAIN behavior
1 parent5b2c983 commitda48f47

File tree

3 files changed

+72
-13
lines changed

3 files changed

+72
-13
lines changed

‎nodes_common.c

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@
1313
#include"pickyappend.h"
1414

1515

16+
17+
/* Compare plans by 'original_order' */
18+
staticint
19+
cmp_child_scan_common_by_orig_order(constvoid*ap,
20+
constvoid*bp)
21+
{
22+
ChildScanCommona=*(ChildScanCommon*)ap;
23+
ChildScanCommonb=*(ChildScanCommon*)bp;
24+
25+
if (a->original_order>b->original_order)
26+
return1;
27+
elseif (a->original_order<b->original_order)
28+
return-1;
29+
else
30+
return0;
31+
}
32+
1633
staticvoid
1734
free_child_scan_common_array(ChildScanCommon*cur_plans,intn)
1835
{
@@ -165,6 +182,7 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
165182
intnchildren=list_length(custom_oids);
166183
HTAB*children_table=scan_state->children_table;
167184
HASHCTL*children_table_config=&scan_state->children_table_config;
185+
inti;
168186

169187
memset(children_table_config,0,sizeof(HASHCTL));
170188
children_table_config->keysize=sizeof(Oid);
@@ -174,6 +192,7 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
174192
children_table_config,
175193
HASH_ELEM |HASH_BLOBS);
176194

195+
i=0;
177196
forboth (oid_cell,custom_oids,plan_cell,cscan->custom_plans)
178197
{
179198
boolchild_found;
@@ -186,6 +205,7 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
186205
Assert(!child_found);/* there should be no collisions */
187206

188207
child->content.plan= (Plan*)lfirst(plan_cell);
208+
child->original_order=i++;/* will be used in EXPLAIN */
189209
}
190210

191211
scan_state->children_table=children_table;
@@ -323,18 +343,6 @@ begin_append_common(CustomScanState *node, EState *estate, int eflags)
323343
scan_state->plan_state_table=plan_state_table;
324344
scan_state->custom_expr_states= (List*)ExecInitExpr((Expr*)scan_state->custom_exprs,
325345
(PlanState*)scan_state);
326-
327-
/*
328-
* ExecProcNode() won't ReScan plans without params, do this
329-
* provided that there are no external PARAM_EXEC params.
330-
*
331-
* rescan_append_common is required for prepared statements,
332-
* but at the same time we don't want it to be called several
333-
* times within a single run (for example, ExecNestLoop calls
334-
* ExecReScan itself)
335-
*/
336-
if (!node->ss.ps.chgParam&&bms_is_empty(node->ss.ps.plan->extParam))
337-
rescan_append_common(node);
338346
}
339347

340348
void
@@ -393,5 +401,49 @@ rescan_append_common(CustomScanState *node)
393401
void
394402
explain_append_common(CustomScanState*node,HTAB*children_table,ExplainState*es)
395403
{
396-
/* Nothing to do here */
404+
PickyAppendState*scan_state= (PickyAppendState*)node;
405+
406+
/* Construct excess PlanStates */
407+
if (!es->analyze)
408+
{
409+
intallocated=10;
410+
intused=0;
411+
ChildScanCommon*custom_ps=palloc(allocated*sizeof(ChildScanCommon));
412+
ChildScanCommonchild;
413+
HASH_SEQ_STATUSseqstat;
414+
inti;
415+
416+
/* There can't be any nodes since we're not scanning anything */
417+
Assert(!node->custom_ps);
418+
419+
hash_seq_init(&seqstat,scan_state->children_table);
420+
421+
while ((child= (ChildScanCommon)hash_seq_search(&seqstat)))
422+
{
423+
if (allocated <=used)
424+
{
425+
allocated *=2;
426+
custom_ps=repalloc(custom_ps,allocated*sizeof(ChildScanCommon));
427+
}
428+
429+
custom_ps[used++]=child;
430+
}
431+
432+
/*
433+
* We have to restore the original plan order
434+
* which has been lost within the hash table
435+
*/
436+
qsort(custom_ps,used,sizeof(ChildScanCommon),
437+
cmp_child_scan_common_by_orig_order);
438+
439+
/*
440+
* These PlanStates will be used by EXPLAIN,
441+
* pickyappend_end will destroy them eventually
442+
*/
443+
for (i=0;i<used;i++)
444+
node->custom_ps=lappend(node->custom_ps,
445+
ExecInitNode(custom_ps[i]->content.plan,
446+
node->ss.ps.state,
447+
0));
448+
}
397449
}

‎nodes_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ typedef struct
3333
Plan*plan;
3434
PlanState*plan_state;
3535
}content;
36+
37+
intoriginal_order;/* for sorting in EXPLAIN */
3638
}ChildScanCommonData;
3739

3840
typedefChildScanCommonData*ChildScanCommon;

‎pickyappend.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pickyappend_exec(CustomScanState *node)
6060
{
6161
PickyAppendState*scan_state= (PickyAppendState*)node;
6262

63+
if (scan_state->ncur_plans==0)
64+
ExecReScan(&node->ss.ps);
65+
6366
while (scan_state->running_idx<scan_state->ncur_plans)
6467
{
6568
ChildScanCommonchild=scan_state->cur_plans[scan_state->running_idx];
@@ -85,6 +88,8 @@ pickyappend_exec(CustomScanState *node)
8588
scan_state->running_idx++;
8689
}
8790

91+
/* Force ReScan */
92+
scan_state->ncur_plans=0;
8893
returnNULL;
8994
}
9095

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp