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

Commitcc89414

Browse files
committed
Merge branch 'picky_nodes' into arrange_append
2 parentsde2b9bd +b127837 commitcc89414

20 files changed

+941
-622
lines changed

‎.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
.deps
2+
results/pg_pathman.out
3+
regression.diffs
4+
regression.out
25
*.o
36
*.so
4-
pg_pathman--*.sql
7+
pg_pathman--*.sql

‎Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# contrib/pg_pathman/Makefile
22

33
MODULE_big = pg_pathman
4-
OBJS = init.opickyappend.o pg_pathman.o dsm_array.o\
5-
rangeset.o pl_funcs.o worker.ojoin_hook.o nodes_common.o$(WIN32RES)
4+
OBJS = init.outils.o runtimeappend.o pg_pathman.o dsm_array.o\
5+
rangeset.o pl_funcs.o worker.ohooks.o nodes_common.o$(WIN32RES)
66

77
EXTENSION = pg_pathman
88
EXTVERSION = 0.1

‎dsm_array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ resize_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
290290
}
291291

292292
void*
293-
dsm_array_get_pointer(constDsmArray*arr)
293+
dsm_array_get_pointer(constDsmArray*arr)
294294
{
295295
return (char*)dsm_segment_address(segment)+arr->offset+sizeof(BlockHeader);
296296
}

‎hooks.c

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
/* ------------------------------------------------------------------------
2+
*
3+
* hooks.c
4+
*definitions of rel_pathlist and join_pathlist hooks
5+
*
6+
* Copyright (c) 2016, Postgres Professional
7+
*
8+
* ------------------------------------------------------------------------
9+
*/
10+
#include"postgres.h"
11+
#include"optimizer/cost.h"
12+
#include"optimizer/restrictinfo.h"
13+
#include"hooks.h"
14+
#include"utils.h"
15+
#include"pathman.h"
16+
#include"runtimeappend.h"
17+
18+
19+
set_join_pathlist_hook_typeset_join_pathlist_next=NULL;
20+
set_rel_pathlist_hook_typeset_rel_pathlist_hook_next=NULL;
21+
22+
23+
void
24+
pathman_join_pathlist_hook(PlannerInfo*root,
25+
RelOptInfo*joinrel,
26+
RelOptInfo*outerrel,
27+
RelOptInfo*innerrel,
28+
JoinTypejointype,
29+
JoinPathExtraData*extra)
30+
{
31+
JoinCostWorkspaceworkspace;
32+
Path*outer,
33+
*inner;
34+
Relidsinner_required;
35+
RangeTblEntry*inner_entry=root->simple_rte_array[innerrel->relid];
36+
PartRelationInfo*inner_prel;
37+
NestPath*nest_path;
38+
List*pathkeys=NIL;
39+
List*joinrestrictclauses=extra->restrictlist;
40+
List*joinclauses,
41+
*otherclauses;
42+
ListCell*lc;
43+
doubleparamsel;
44+
45+
if (set_join_pathlist_next)
46+
set_join_pathlist_next(root,joinrel,outerrel,
47+
innerrel,jointype,extra);
48+
49+
if (jointype==JOIN_UNIQUE_OUTER||
50+
jointype==JOIN_UNIQUE_INNER)
51+
{
52+
jointype=JOIN_INNER;
53+
}
54+
55+
if (jointype==JOIN_FULL|| !pg_pathman_enable_runtimeappend)
56+
return;
57+
58+
if (innerrel->reloptkind!=RELOPT_BASEREL||
59+
!inner_entry->inh||
60+
!(inner_prel=get_pathman_relation_info(inner_entry->relid,NULL)))
61+
{
62+
return;/* Obviously not our case */
63+
}
64+
65+
/* Extract join clauses which will separate partitions */
66+
if (IS_OUTER_JOIN(extra->sjinfo->jointype))
67+
{
68+
extract_actual_join_clauses(joinrestrictclauses,
69+
&joinclauses,&otherclauses);
70+
}
71+
else
72+
{
73+
/* We can treat all clauses alike for an inner join */
74+
joinclauses=extract_actual_clauses(joinrestrictclauses, false);
75+
otherclauses=NIL;
76+
}
77+
78+
paramsel=1.0;
79+
foreach (lc,joinclauses)
80+
{
81+
WrapperNode*wrap;
82+
83+
wrap=walk_expr_tree(NULL, (Expr*)lfirst(lc),inner_prel);
84+
paramsel *=wrap->paramsel;
85+
}
86+
87+
foreach (lc,innerrel->pathlist)
88+
{
89+
AppendPath*cur_inner_path= (AppendPath*)lfirst(lc);
90+
91+
if (!IsA(cur_inner_path,AppendPath))
92+
continue;
93+
94+
outer=outerrel->cheapest_total_path;
95+
96+
inner_required=bms_union(PATH_REQ_OUTER((Path*)cur_inner_path),
97+
bms_make_singleton(outerrel->relid));
98+
99+
inner=create_runtimeappend_path(root,cur_inner_path,
100+
get_appendrel_parampathinfo(innerrel,
101+
inner_required),
102+
joinclauses,paramsel);
103+
104+
initial_cost_nestloop(root,&workspace,jointype,
105+
outer,inner,
106+
extra->sjinfo,&extra->semifactors);
107+
108+
pathkeys=build_join_pathkeys(root,joinrel,jointype,outer->pathkeys);
109+
110+
nest_path=create_nestloop_path(root,joinrel,jointype,&workspace,
111+
extra->sjinfo,&extra->semifactors,
112+
outer,inner,extra->restrictlist,
113+
pathkeys,
114+
calc_nestloop_required_outer(outer,inner));
115+
116+
add_path(joinrel, (Path*)nest_path);
117+
}
118+
}
119+
120+
/*
121+
* Main hook. All the magic goes here
122+
*/
123+
void
124+
pathman_rel_pathlist_hook(PlannerInfo*root,RelOptInfo*rel,Indexrti,RangeTblEntry*rte)
125+
{
126+
PartRelationInfo*prel=NULL;
127+
RangeTblEntry**new_rte_array;
128+
RelOptInfo**new_rel_array;
129+
boolfound;
130+
intlen;
131+
intfirst_child_relid=0;
132+
133+
/* Invoke original hook if needed */
134+
if (set_rel_pathlist_hook_next!=NULL)
135+
set_rel_pathlist_hook_next(root,rel,rti,rte);
136+
137+
if (!pg_pathman_enable)
138+
return;
139+
140+
/* This works only for SELECT queries */
141+
if (root->parse->commandType!=CMD_SELECT|| !inheritance_disabled)
142+
return;
143+
144+
/* Lookup partitioning information for parent relation */
145+
prel=get_pathman_relation_info(rte->relid,&found);
146+
147+
if (prel!=NULL&&found)
148+
{
149+
ListCell*lc;
150+
inti;
151+
Oid*dsm_arr;
152+
List*ranges,
153+
*wrappers;
154+
PathKey*pathkeyAsc=NULL,
155+
*pathkeyDesc=NULL;
156+
doubleparamsel=1.0;
157+
158+
if (prel->parttype==PT_RANGE)
159+
{
160+
/*
161+
* Get pathkeys for ascending and descending sort by partition
162+
* column
163+
*/
164+
List*pathkeys;
165+
Var*var;
166+
Oidvartypeid,
167+
varcollid;
168+
int32type_mod;
169+
TypeCacheEntry*tce;
170+
171+
/* Make Var from patition column */
172+
get_rte_attribute_type(rte,prel->attnum,
173+
&vartypeid,&type_mod,&varcollid);
174+
var=makeVar(rti,prel->attnum,vartypeid,type_mod,varcollid,0);
175+
var->location=-1;
176+
177+
/* Determine operator type */
178+
tce=lookup_type_cache(var->vartype,TYPECACHE_LT_OPR |TYPECACHE_GT_OPR);
179+
180+
/* Make pathkeys */
181+
pathkeys=build_expression_pathkey(root, (Expr*)var,NULL,
182+
tce->lt_opr,NULL, false);
183+
if (pathkeys)
184+
pathkeyAsc= (PathKey*)linitial(pathkeys);
185+
pathkeys=build_expression_pathkey(root, (Expr*)var,NULL,
186+
tce->gt_opr,NULL, false);
187+
if (pathkeys)
188+
pathkeyDesc= (PathKey*)linitial(pathkeys);
189+
}
190+
191+
rte->inh= true;
192+
dsm_arr= (Oid*)dsm_array_get_pointer(&prel->children);
193+
ranges=list_make1_int(make_irange(0,prel->children_count-1, false));
194+
195+
/* Make wrappers over restrictions and collect final rangeset */
196+
wrappers=NIL;
197+
foreach(lc,rel->baserestrictinfo)
198+
{
199+
WrapperNode*wrap;
200+
201+
RestrictInfo*rinfo= (RestrictInfo*)lfirst(lc);
202+
203+
wrap=walk_expr_tree(NULL,rinfo->clause,prel);
204+
paramsel *=wrap->paramsel;
205+
wrappers=lappend(wrappers,wrap);
206+
ranges=irange_list_intersect(ranges,wrap->rangeset);
207+
}
208+
209+
/*
210+
* Expand simple_rte_array and simple_rel_array
211+
*/
212+
213+
if (ranges)
214+
{
215+
len=irange_list_length(ranges);
216+
217+
/* Expand simple_rel_array and simple_rte_array */
218+
new_rel_array= (RelOptInfo**)
219+
palloc0((root->simple_rel_array_size+len)*sizeof(RelOptInfo*));
220+
221+
/* simple_rte_array is an array equivalent of the rtable list */
222+
new_rte_array= (RangeTblEntry**)
223+
palloc0((root->simple_rel_array_size+len)*sizeof(RangeTblEntry*));
224+
225+
/* Copy relations to the new arrays */
226+
for (i=0;i<root->simple_rel_array_size;i++)
227+
{
228+
new_rel_array[i]=root->simple_rel_array[i];
229+
new_rte_array[i]=root->simple_rte_array[i];
230+
}
231+
232+
/* Free old arrays */
233+
pfree(root->simple_rel_array);
234+
pfree(root->simple_rte_array);
235+
236+
root->simple_rel_array_size+=len;
237+
root->simple_rel_array=new_rel_array;
238+
root->simple_rte_array=new_rte_array;
239+
}
240+
241+
/*
242+
* Iterate all indexes in rangeset and append corresponding child
243+
* relations.
244+
*/
245+
foreach(lc,ranges)
246+
{
247+
IndexRangeirange=lfirst_irange(lc);
248+
OidchildOid;
249+
250+
for (i=irange_lower(irange);i <=irange_upper(irange);i++)
251+
{
252+
intidx;
253+
254+
childOid=dsm_arr[i];
255+
idx=append_child_relation(root,rel,rti,rte,i,childOid,wrappers);
256+
257+
if (!first_child_relid)
258+
first_child_relid=idx;
259+
}
260+
}
261+
262+
/* Clear old path list */
263+
list_free(rel->pathlist);
264+
265+
rel->pathlist=NIL;
266+
set_append_rel_pathlist(root,rel,rti,rte,pathkeyAsc,pathkeyDesc);
267+
set_append_rel_size(root,rel,rti,rte);
268+
269+
if (!pg_pathman_enable_runtimeappend)
270+
return;
271+
272+
foreach (lc,rel->pathlist)
273+
{
274+
AppendPath*cur_path= (AppendPath*)lfirst(lc);
275+
Relidsinner_required=PATH_REQ_OUTER((Path*)cur_path);
276+
ParamPathInfo*ppi=get_appendrel_parampathinfo(rel,inner_required);
277+
Path*inner_path;
278+
ListCell*subpath_cell;
279+
List*runtime_quals=NIL;
280+
281+
if (!IsA(cur_path,AppendPath)||
282+
rel->has_eclass_joins||
283+
rel->joininfo)
284+
{
285+
continue;
286+
}
287+
288+
foreach (subpath_cell,cur_path->subpaths)
289+
{
290+
Path*subpath= (Path*)lfirst(subpath_cell);
291+
RelOptInfo*child_rel=subpath->parent;
292+
List*quals;
293+
ListCell*qual_cell;
294+
ReplaceVarsContextrepl_var_cxt;
295+
296+
repl_var_cxt.child=subpath->parent;
297+
repl_var_cxt.parent=rel;
298+
repl_var_cxt.sublevels_up=0;
299+
300+
quals=extract_actual_clauses(child_rel->baserestrictinfo, false);
301+
302+
/* Do not proceed if there's a rel containing quals without params */
303+
if (!clause_contains_params((Node*)quals))
304+
{
305+
runtime_quals=NIL;/* skip this path */
306+
break;
307+
}
308+
309+
/* Replace child Vars with a parent rel's Var */
310+
quals= (List*)replace_child_vars_with_parent_var((Node*)quals,
311+
&repl_var_cxt);
312+
313+
/* Combine unique quals for RuntimeAppend */
314+
foreach (qual_cell,quals)
315+
runtime_quals=list_append_unique(runtime_quals,
316+
(Node*)lfirst(qual_cell));
317+
}
318+
319+
/*
320+
* Dismiss RuntimeAppend if there
321+
* are no parameterized quals
322+
*/
323+
if (runtime_quals==NIL)
324+
continue;
325+
326+
inner_path=create_runtimeappend_path(root,cur_path,
327+
ppi,runtime_quals,
328+
paramsel);
329+
330+
add_path(rel,inner_path);
331+
}
332+
}
333+
}

‎hooks.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* ------------------------------------------------------------------------
2+
*
3+
* hooks.h
4+
*prototypes of rel_pathlist and join_pathlist hooks
5+
*
6+
* Copyright (c) 2016, Postgres Professional
7+
*
8+
* ------------------------------------------------------------------------
9+
*/
10+
#ifndefJOIN_HOOK_H
11+
#defineJOIN_HOOK_H
12+
13+
#include"postgres.h"
14+
#include"optimizer/paths.h"
15+
16+
externset_join_pathlist_hook_typeset_join_pathlist_next;
17+
externset_rel_pathlist_hook_typeset_rel_pathlist_hook_next;
18+
19+
voidpathman_join_pathlist_hook(PlannerInfo*root,RelOptInfo*joinrel,RelOptInfo*outerrel,
20+
RelOptInfo*innerrel,JoinTypejointype,JoinPathExtraData*extra);
21+
22+
voidpathman_rel_pathlist_hook(PlannerInfo*root,RelOptInfo*rel,Indexrti,RangeTblEntry*rte);
23+
24+
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp