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

Commitc4b0063

Browse files
committed
generic PickyAppend for prepared statements, remove redundant EXPLAIN-related code
1 parent2a7ac06 commitc4b0063

File tree

5 files changed

+111
-65
lines changed

5 files changed

+111
-65
lines changed

‎hooks.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include"optimizer/cost.h"
33
#include"optimizer/restrictinfo.h"
44
#include"hooks.h"
5+
#include"utils.h"
56
#include"pathman.h"
67
#include"pickyappend.h"
78

@@ -239,6 +240,63 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
239240
rel->pathlist=NIL;
240241
set_append_rel_pathlist(root,rel,rti,rte,pathkeyAsc,pathkeyDesc);
241242
set_append_rel_size(root,rel,rti,rte);
243+
244+
foreach (lc,rel->pathlist)
245+
{
246+
AppendPath*cur_path= (AppendPath*)lfirst(lc);
247+
Relidsinner_required=PATH_REQ_OUTER((Path*)cur_path);
248+
ParamPathInfo*ppi=get_appendrel_parampathinfo(rel,inner_required);
249+
Path*inner_path;
250+
ListCell*subpath_cell;
251+
List*picky_quals=NIL;
252+
253+
if (!IsA(cur_path,AppendPath)||
254+
rel->has_eclass_joins||
255+
rel->joininfo)
256+
{
257+
continue;
258+
}
259+
260+
foreach (subpath_cell,cur_path->subpaths)
261+
{
262+
Path*subpath= (Path*)lfirst(subpath_cell);
263+
RelOptInfo*child_rel=subpath->parent;
264+
List*quals;
265+
ListCell*qual_cell;
266+
ReplaceVarsContextrepl_var_cxt;
267+
268+
repl_var_cxt.child=subpath->parent;
269+
repl_var_cxt.parent=rel;
270+
repl_var_cxt.sublevels_up=0;
271+
272+
quals=extract_actual_clauses(child_rel->baserestrictinfo, false);
273+
274+
/* Do not proceed if there's a rel containing quals without params */
275+
if (!clause_contains_extern_params((Node*)quals))
276+
break;
277+
278+
/* Replace child Vars with a parent rel's Var */
279+
quals= (List*)replace_child_vars_with_parent_var((Node*)quals,
280+
&repl_var_cxt);
281+
282+
/* Combine unique 'picky' quals */
283+
foreach (qual_cell,quals)
284+
picky_quals=list_append_unique(picky_quals,
285+
(Node*)lfirst(qual_cell));
286+
}
287+
288+
/*
289+
* Dismiss PickyAppend if there
290+
* are no parameterized quals
291+
*/
292+
if (picky_quals==NIL)
293+
continue;
294+
295+
inner_path=create_pickyappend_path(root,cur_path,
296+
ppi,picky_quals);
297+
298+
add_path(rel,inner_path);
299+
}
242300
}
243301

244302
/* Invoke original hook if needed */

‎nodes_common.c

Lines changed: 14 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ transform_plans_into_states(PickyAppendState *scan_state,
5252
* We should ReScan this node manually since
5353
* ExecProcNode won't do this for us in this case.
5454
*/
55-
if (!pps->ps->chgParam)
55+
if (bms_is_empty(pps->ps->chgParam))
5656
ExecReScan(pps->ps);
5757

5858
child->content.plan_state=pps->ps;
@@ -125,22 +125,6 @@ get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
125125
returnresult;
126126
}
127127

128-
/* Compare plans by 'original_order' */
129-
staticint
130-
cmp_child_scan_common_by_orig_order(constvoid*ap,
131-
constvoid*bp)
132-
{
133-
ChildScanCommona=*(ChildScanCommon*)ap;
134-
ChildScanCommonb=*(ChildScanCommon*)bp;
135-
136-
if (a->original_order>b->original_order)
137-
return1;
138-
elseif (a->original_order<b->original_order)
139-
return-1;
140-
else
141-
return0;
142-
}
143-
144128
staticvoid
145129
pack_pickyappend_private(CustomScan*cscan,PickyAppendPath*path)
146130
{
@@ -172,7 +156,6 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
172156
intnchildren=list_length(custom_oids);
173157
HTAB*children_table=scan_state->children_table;
174158
HASHCTL*children_table_config=&scan_state->children_table_config;
175-
inti;
176159

177160
memset(children_table_config,0,sizeof(HASHCTL));
178161
children_table_config->keysize=sizeof(Oid);
@@ -182,7 +165,6 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
182165
children_table_config,
183166
HASH_ELEM |HASH_BLOBS);
184167

185-
i=0;
186168
forboth (oid_cell,custom_oids,plan_cell,cscan->custom_plans)
187169
{
188170
boolchild_found;
@@ -195,7 +177,6 @@ unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
195177
Assert(!child_found);/* there should be no collisions */
196178

197179
child->content.plan= (Plan*)lfirst(plan_cell);
198-
child->original_order=i++;/* will be used in EXPLAIN */
199180
}
200181

201182
scan_state->children_table=children_table;
@@ -333,6 +314,18 @@ begin_append_common(CustomScanState *node, EState *estate, int eflags)
333314
scan_state->plan_state_table=plan_state_table;
334315
scan_state->custom_expr_states= (List*)ExecInitExpr((Expr*)scan_state->custom_exprs,
335316
(PlanState*)scan_state);
317+
318+
/*
319+
* ExecProcNode() won't ReScan plans without params, do this
320+
* provided that there are no external PARAM_EXEC params.
321+
*
322+
* rescan_append_common is required for prepared statements,
323+
* but at the same time we don't want it to be called several
324+
* times within a single run (for example, ExecNestLoop calls
325+
* ExecReScan itself)
326+
*/
327+
if (!node->ss.ps.chgParam&&bms_is_empty(node->ss.ps.plan->extParam))
328+
rescan_append_common(node);
336329
}
337330

338331
void
@@ -391,47 +384,5 @@ rescan_append_common(CustomScanState *node)
391384
void
392385
explain_append_common(CustomScanState*node,HTAB*children_table,ExplainState*es)
393386
{
394-
/* Construct excess PlanStates */
395-
if (!es->analyze)
396-
{
397-
intallocated=10;
398-
intused=0;
399-
ChildScanCommon*custom_ps=palloc(allocated*sizeof(ChildScanCommon));
400-
ChildScanCommonchild;
401-
HASH_SEQ_STATUSseqstat;
402-
inti;
403-
404-
/* There can't be any nodes since we're not scanning anything */
405-
Assert(!node->custom_ps);
406-
407-
hash_seq_init(&seqstat,children_table);
408-
409-
while ((child= (ChildScanCommon)hash_seq_search(&seqstat)))
410-
{
411-
if (allocated <=used)
412-
{
413-
allocated *=2;
414-
custom_ps=repalloc(custom_ps,allocated*sizeof(ChildScanCommon));
415-
}
416-
417-
custom_ps[used++]=child;
418-
}
419-
420-
/*
421-
* We have to restore the original plan order
422-
* which has been lost within the hash table
423-
*/
424-
qsort(custom_ps,used,sizeof(ChildScanCommon),
425-
cmp_child_scan_common_by_orig_order);
426-
427-
/*
428-
* These PlanStates will be used by EXPLAIN,
429-
* arrangeappend_end will destroy them eventually
430-
*/
431-
for (i=0;i<used;i++)
432-
node->custom_ps=lappend(node->custom_ps,
433-
ExecInitNode(custom_ps[i]->content.plan,
434-
node->ss.ps.state,
435-
0));
436-
}
387+
/* Nothing to do here */
437388
}

‎nodes_common.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ typedef struct
2424
Plan*plan;
2525
PlanState*plan_state;
2626
}content;
27-
28-
intoriginal_order;/* for sorting in EXPLAIN */
2927
}ChildScanCommonData;
3028

3129
typedefChildScanCommonData*ChildScanCommon;

‎utils.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include"nodes/nodeFuncs.h"
33
#include"parser/parse_param.h"
44
#include"utils/builtins.h"
5+
#include"rewrite/rewriteManip.h"
56

67

78
staticboolclause_contains_extern_params_walker(Node*node,void*context);
@@ -31,3 +32,30 @@ clause_contains_extern_params_walker(Node *node, void *context)
3132
clause_contains_extern_params_walker,
3233
context);
3334
}
35+
36+
staticNode*
37+
replace_child_var(Var*var,replace_rte_variables_context*context)
38+
{
39+
ReplaceVarsContext*cxt= (ReplaceVarsContext*)context->callback_arg;
40+
Var*new_var;
41+
42+
new_var=makeNode(Var);
43+
memcpy(new_var,var,sizeof(Var));
44+
45+
/*
46+
* Replace a partition's Var with a Var
47+
* pointing to the PickyAppend's results
48+
*/
49+
new_var->varno=cxt->parent->relid;
50+
new_var->location=-1;
51+
new_var->varnoold=0;
52+
53+
return (Node*)new_var;
54+
}
55+
56+
Node*
57+
replace_child_vars_with_parent_var(Node*node,ReplaceVarsContext*context)
58+
{
59+
returnreplace_rte_variables(node,context->child->relid,context->sublevels_up,
60+
replace_child_var, (void*)context,NULL);
61+
}

‎utils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22
#defineUTILS_H
33

44
#include"postgres.h"
5+
#include"nodes/relation.h"
56
#include"nodes/nodeFuncs.h"
67

8+
typedefstruct
9+
{
10+
RelOptInfo*child;
11+
RelOptInfo*parent;
12+
intsublevels_up;
13+
}ReplaceVarsContext;
14+
715
boolclause_contains_extern_params(Node*clause);
816

17+
Node*replace_child_vars_with_parent_var(Node*node,
18+
ReplaceVarsContext*context);
19+
920
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp