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

Commit3629c43

Browse files
committed
extract common code from PickyAppend & ArrangeAppend
1 parent8f33649 commit3629c43

File tree

4 files changed

+412
-337
lines changed

4 files changed

+412
-337
lines changed

‎nodes_common.c

Lines changed: 370 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,130 @@
11
#include"postgres.h"
22
#include"optimizer/paths.h"
33
#include"nodes_common.h"
4+
#include"pickyappend.h"
45

56

7+
staticvoid
8+
free_child_scan_common_array(ChildScanCommon*cur_plans,intn)
9+
{
10+
inti;
11+
12+
if (!cur_plans)
13+
return;
14+
15+
/* We shouldn't free inner objects e.g. Plans here */
16+
for (i=0;i<n;i++)
17+
pfree(cur_plans[i]);
18+
19+
pfree(cur_plans);
20+
}
21+
22+
staticvoid
23+
transform_plans_into_states(PickyAppendState*scan_state,
24+
ChildScanCommon*selected_plans,intn,
25+
EState*estate)
26+
{
27+
inti;
28+
29+
for (i=0;i<n;i++)
30+
{
31+
ChildScanCommonchild=selected_plans[i];
32+
PreservedPlanState*pps;
33+
boolpps_found;
34+
35+
pps= (PreservedPlanState*)hash_search(scan_state->plan_state_table,
36+
(constvoid*)&child->relid,
37+
HASH_ENTER,&pps_found);
38+
39+
/* Create new node since this plan hasn't been used yet */
40+
if (!pps_found)
41+
{
42+
pps->ps=ExecInitNode(child->content.plan,estate,0);
43+
/* Explain and clear_plan_states rely on this list */
44+
scan_state->css.custom_ps=lappend(scan_state->css.custom_ps,pps->ps);
45+
}
46+
47+
/* Node with params will be ReScanned */
48+
if (scan_state->css.ss.ps.chgParam)
49+
UpdateChangedParamSet(pps->ps,scan_state->css.ss.ps.chgParam);
50+
51+
/*
52+
* We should ReScan this node manually since
53+
* ExecProcNode won't do this for us in this case.
54+
*/
55+
if (!pps->ps->chgParam)
56+
ExecReScan(pps->ps);
57+
58+
child->content.plan_state=pps->ps;
59+
}
60+
}
61+
62+
staticChildScanCommon*
63+
select_required_plans(HTAB*children_table,Oid*parts,intnparts,int*nres)
64+
{
65+
intallocated=10;
66+
intused=0;
67+
ChildScanCommon*result=palloc(10*sizeof(ChildScanCommon));
68+
inti;
69+
70+
for (i=0;i<nparts;i++)
71+
{
72+
ChildScanCommonchild_copy;
73+
ChildScanCommonchild=hash_search(children_table,
74+
(constvoid*)&parts[i],
75+
HASH_FIND,NULL);
76+
if (!child)
77+
continue;
78+
79+
if (allocated <=used)
80+
{
81+
allocated *=2;
82+
result=repalloc(result,allocated*sizeof(ChildScanCommon));
83+
}
84+
85+
child_copy=palloc(sizeof(ChildScanCommonData));
86+
memcpy(child_copy,child,sizeof(ChildScanCommonData));
87+
88+
result[used++]=child_copy;
89+
}
90+
91+
*nres=used;
92+
returnresult;
93+
}
94+
95+
/* Transform partition ranges into plain array of partition Oids */
96+
staticOid*
97+
get_partition_oids(List*ranges,int*n,PartRelationInfo*prel)
98+
{
99+
ListCell*range_cell;
100+
intallocated=10;
101+
intused=0;
102+
Oid*result=palloc(allocated*sizeof(Oid));
103+
Oid*children=dsm_array_get_pointer(&prel->children);
104+
105+
foreach (range_cell,ranges)
106+
{
107+
inti;
108+
inta=irange_lower(lfirst_irange(range_cell));
109+
intb=irange_upper(lfirst_irange(range_cell));
110+
111+
for (i=a;i <=b;i++)
112+
{
113+
if (allocated <=used)
114+
{
115+
allocated *=2;
116+
result=repalloc(result,allocated*sizeof(Oid));
117+
}
118+
119+
Assert(i<prel->children_count);
120+
result[used++]=children[i];
121+
}
122+
}
123+
124+
*n=used;
125+
returnresult;
126+
}
127+
6128
/* Compare plans by 'original_order' */
7129
staticint
8130
cmp_child_scan_common_by_orig_order(constvoid*ap,
@@ -19,8 +141,255 @@ cmp_child_scan_common_by_orig_order(const void *ap,
19141
return0;
20142
}
21143

144+
staticvoid
145+
pack_pickyappend_private(CustomScan*cscan,PickyAppendPath*path)
146+
{
147+
ChildScanCommon*children=path->children;
148+
intnchildren=path->nchildren;
149+
List*custom_private=NIL;
150+
List*custom_oids=NIL;
151+
inti;
152+
153+
for (i=0;i<nchildren;i++)
154+
{
155+
/* We've already filled 'custom_paths' in create_pickyappend_path */
156+
custom_oids=lappend_oid(custom_oids,children[i]->relid);
157+
pfree(children[i]);
158+
}
159+
160+
/* Save main table and partition relids */
161+
custom_private=list_make2(list_make1_oid(path->relid),custom_oids);
162+
163+
cscan->custom_private=custom_private;
164+
}
165+
166+
staticvoid
167+
unpack_pickyappend_private(PickyAppendState*scan_state,CustomScan*cscan)
168+
{
169+
ListCell*oid_cell;
170+
ListCell*plan_cell;
171+
List*custom_oids= (List*)lsecond(cscan->custom_private);
172+
intnchildren=list_length(custom_oids);
173+
HTAB*children_table=scan_state->children_table;
174+
HASHCTL*children_table_config=&scan_state->children_table_config;
175+
inti;
176+
177+
memset(children_table_config,0,sizeof(HASHCTL));
178+
children_table_config->keysize=sizeof(Oid);
179+
children_table_config->entrysize=sizeof(ChildScanCommonData);
180+
181+
children_table=hash_create("Plan storage",nchildren,
182+
children_table_config,
183+
HASH_ELEM |HASH_BLOBS);
184+
185+
i=0;
186+
forboth (oid_cell,custom_oids,plan_cell,cscan->custom_plans)
187+
{
188+
boolchild_found;
189+
Oidcur_oid=lfirst_oid(oid_cell);
190+
191+
ChildScanCommonchild=hash_search(children_table,
192+
(constvoid*)&cur_oid,
193+
HASH_ENTER,&child_found);
194+
195+
Assert(!child_found);/* there should be no collisions */
196+
197+
child->content.plan= (Plan*)lfirst(plan_cell);
198+
child->original_order=i++;/* will be used in EXPLAIN */
199+
}
200+
201+
scan_state->children_table=children_table;
202+
scan_state->relid=linitial_oid(linitial(cscan->custom_private));
203+
}
204+
205+
Path*
206+
create_append_path_common(PlannerInfo*root,
207+
AppendPath*inner_append,
208+
ParamPathInfo*param_info,
209+
List*picky_clauses,
210+
CustomPathMethods*path_methods)
211+
{
212+
RelOptInfo*innerrel=inner_append->path.parent;
213+
ListCell*lc;
214+
inti;
215+
216+
RangeTblEntry*inner_entry=root->simple_rte_array[innerrel->relid];
217+
218+
PickyAppendPath*result;
219+
220+
result=palloc0(sizeof(PickyAppendPath));
221+
NodeSetTag(result,T_CustomPath);
222+
223+
result->cpath.path.pathtype=T_CustomScan;
224+
result->cpath.path.parent=innerrel;
225+
result->cpath.path.param_info=param_info;
226+
result->cpath.path.pathkeys=NIL;
227+
#ifPG_VERSION_NUM >=90600
228+
result->cpath.path.pathtarget=inner_append->path.pathtarget;
229+
#endif
230+
result->cpath.path.rows=inner_append->path.rows;
231+
result->cpath.flags=0;
232+
result->cpath.methods=path_methods;
233+
234+
/* TODO: real costs */
235+
result->cpath.path.startup_cost=0;
236+
result->cpath.path.total_cost=0;
237+
238+
/* Set 'partitioned column'-related clauses */
239+
result->cpath.custom_private=picky_clauses;
240+
result->cpath.custom_paths=NIL;
241+
242+
Assert(inner_entry->relid!=0);
243+
result->relid=inner_entry->relid;
244+
245+
result->nchildren=list_length(inner_append->subpaths);
246+
result->children=palloc(result->nchildren*sizeof(ChildScanCommon));
247+
i=0;
248+
foreach (lc,inner_append->subpaths)
249+
{
250+
Path*path=lfirst(lc);
251+
Indexrelindex=path->parent->relid;
252+
ChildScanCommonchild=palloc(sizeof(ChildScanCommonData));
253+
254+
child->content.path=path;
255+
child->relid=root->simple_rte_array[relindex]->relid;
256+
Assert(child->relid!=InvalidOid);
257+
258+
result->cpath.custom_paths=lappend(result->cpath.custom_paths,
259+
child->content.path);
260+
result->children[i]=child;
261+
262+
i++;
263+
}
264+
265+
return&result->cpath.path;
266+
}
267+
268+
Plan*
269+
create_append_plan_common(PlannerInfo*root,RelOptInfo*rel,
270+
CustomPath*best_path,List*tlist,
271+
List*clauses,List*custom_plans,
272+
CustomScanMethods*scan_methods)
273+
{
274+
PickyAppendPath*gpath= (PickyAppendPath*)best_path;
275+
CustomScan*cscan;
276+
277+
cscan=makeNode(CustomScan);
278+
cscan->scan.plan.qual=NIL;
279+
cscan->scan.plan.targetlist=tlist;
280+
cscan->custom_scan_tlist=tlist;
281+
cscan->scan.scanrelid=0;
282+
283+
cscan->custom_exprs=gpath->cpath.custom_private;
284+
cscan->custom_plans=custom_plans;
285+
286+
cscan->methods=scan_methods;
287+
288+
pack_pickyappend_private(cscan,gpath);
289+
290+
return&cscan->scan.plan;
291+
}
292+
293+
Node*
294+
create_append_scan_state_common(CustomScan*node,
295+
CustomExecMethods*exec_methods,
296+
uint32size)
297+
{
298+
PickyAppendState*scan_state=palloc0(size);
299+
300+
NodeSetTag(scan_state,T_CustomScanState);
301+
scan_state->css.flags=node->flags;
302+
scan_state->css.methods=exec_methods;
303+
scan_state->custom_exprs=node->custom_exprs;
304+
305+
unpack_pickyappend_private(scan_state,node);
306+
307+
/* Fill in relation info using main table's relid */
308+
scan_state->prel=get_pathman_relation_info(scan_state->relid,NULL);
309+
Assert(scan_state->prel);
310+
311+
scan_state->cur_plans=NULL;
312+
scan_state->ncur_plans=0;
313+
scan_state->running_idx=0;
314+
315+
return (Node*)scan_state;
316+
}
317+
318+
void
319+
begin_append_common(CustomScanState*node,EState*estate,inteflags)
320+
{
321+
PickyAppendState*scan_state= (PickyAppendState*)node;
322+
HTAB*plan_state_table=scan_state->plan_state_table;
323+
HASHCTL*plan_state_table_config=&scan_state->plan_state_table_config;
324+
325+
memset(plan_state_table_config,0,sizeof(HASHCTL));
326+
plan_state_table_config->keysize=sizeof(Oid);
327+
plan_state_table_config->entrysize=sizeof(PreservedPlanState);
328+
329+
plan_state_table=hash_create("PlanState storage",128,
330+
plan_state_table_config,
331+
HASH_ELEM |HASH_BLOBS);
332+
333+
scan_state->plan_state_table=plan_state_table;
334+
scan_state->custom_expr_states= (List*)ExecInitExpr((Expr*)scan_state->custom_exprs,
335+
(PlanState*)scan_state);
336+
}
337+
338+
void
339+
end_append_common(CustomScanState*node)
340+
{
341+
PickyAppendState*scan_state= (PickyAppendState*)node;
342+
343+
clear_plan_states(&scan_state->css);
344+
hash_destroy(scan_state->plan_state_table);
345+
hash_destroy(scan_state->children_table);
346+
}
347+
348+
void
349+
rescan_append_common(CustomScanState*node)
350+
{
351+
PickyAppendState*scan_state= (PickyAppendState*)node;
352+
ExprContext*econtext=node->ss.ps.ps_ExprContext;
353+
PartRelationInfo*prel=scan_state->prel;
354+
List*ranges;
355+
ListCell*lc;
356+
Oid*parts;
357+
intnparts;
358+
359+
ranges=list_make1_int(make_irange(0,prel->children_count-1, false));
360+
361+
foreach (lc,scan_state->custom_exprs)
362+
{
363+
WrapperNode*wn;
364+
WalkerContextwcxt;
365+
366+
wcxt.econtext=econtext;
367+
wn=walk_expr_tree(&wcxt, (Expr*)lfirst(lc),prel);
368+
369+
ranges=irange_list_intersect(ranges,wn->rangeset);
370+
}
371+
372+
/* Get Oids of the required partitions */
373+
parts=get_partition_oids(ranges,&nparts,prel);
374+
375+
/* Select new plans for this run using 'parts' */
376+
free_child_scan_common_array(scan_state->cur_plans,scan_state->ncur_plans);
377+
scan_state->cur_plans=select_required_plans(scan_state->children_table,
378+
parts,nparts,
379+
&scan_state->ncur_plans);
380+
pfree(parts);
381+
382+
/* Transform selected plans into executable plan states */
383+
transform_plans_into_states(scan_state,
384+
scan_state->cur_plans,
385+
scan_state->ncur_plans,
386+
scan_state->css.ss.ps.state);
387+
388+
scan_state->running_idx=0;
389+
}
390+
22391
void
23-
explain_common(CustomScanState*node,HTAB*children_table,ExplainState*es)
392+
explain_append_common(CustomScanState*node,HTAB*children_table,ExplainState*es)
24393
{
25394
/* Construct excess PlanStates */
26395
if (!es->analyze)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp