Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d9adda0

Browse files
committed
Merge branch 'picky_nodes' of github.com:postgrespro/pg_pathman into picky_nodes
2 parents 8514324 + 6025cae commit d9adda0

File tree

7 files changed

+115
-24
lines changed

7 files changed

+115
-24
lines changed

hooks.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
4040
List *joinclauses,
4141
*otherclauses;
4242
ListCell *lc;
43+
double paramsel;
4344

4445
if (set_join_pathlist_next)
4546
set_join_pathlist_next(root, joinrel, outerrel,
@@ -74,6 +75,15 @@ pathman_join_pathlist_hook(PlannerInfo *root,
7475
otherclauses = NIL;
7576
}
7677

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+
7787
foreach (lc, innerrel->pathlist)
7888
{
7989
AppendPath *cur_inner_path = (AppendPath *) lfirst(lc);
@@ -89,7 +99,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
8999
inner = create_pickyappend_path(root, cur_inner_path,
90100
get_appendrel_parampathinfo(innerrel,
91101
inner_required),
92-
joinclauses);
102+
joinclauses, paramsel);
93103

94104
initial_cost_nestloop(root, &workspace, jointype,
95105
outer, inner,
@@ -139,6 +149,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
139149
*wrappers;
140150
PathKey *pathkeyAsc = NULL,
141151
*pathkeyDesc = NULL;
152+
double paramsel = 1.0;
142153

143154
if (prel->parttype == PT_RANGE)
144155
{
@@ -186,6 +197,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
186197
RestrictInfo *rinfo = (RestrictInfo*) lfirst(lc);
187198

188199
wrap = walk_expr_tree(NULL, rinfo->clause, prel);
200+
paramsel *= wrap->paramsel;
189201
wrappers = lappend(wrappers, wrap);
190202
ranges = irange_list_intersect(ranges, wrap->rangeset);
191203
}
@@ -305,7 +317,8 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
305317
continue;
306318

307319
inner_path = create_pickyappend_path(root, cur_path,
308-
ppi, picky_quals);
320+
ppi, picky_quals,
321+
paramsel);
309322

310323
add_path(rel, inner_path);
311324
}

nodes_common.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ create_append_path_common(PlannerInfo *root,
217217
AppendPath *inner_append,
218218
ParamPathInfo *param_info,
219219
List *picky_clauses,
220-
CustomPathMethods *path_methods)
220+
CustomPathMethods *path_methods,
221+
double sel)
221222
{
222223
RelOptInfo *innerrel = inner_append->path.parent;
223224
ListCell *lc;
@@ -237,13 +238,13 @@ create_append_path_common(PlannerInfo *root,
237238
#if PG_VERSION_NUM >= 90600
238239
result->cpath.path.pathtarget = inner_append->path.pathtarget;
239240
#endif
240-
result->cpath.path.rows = inner_append->path.rows;
241+
result->cpath.path.rows = inner_append->path.rows * sel;
241242
result->cpath.flags = 0;
242243
result->cpath.methods = path_methods;
243244

244245
/* TODO: real costs */
245-
result->cpath.path.startup_cost = 0;
246-
result->cpath.path.total_cost = 0;
246+
result->cpath.path.startup_cost = 0.0;
247+
result->cpath.path.total_cost = 0.0;
247248

248249
/* Set 'partitioned column'-related clauses */
249250
result->cpath.custom_private = picky_clauses;
@@ -261,6 +262,9 @@ create_append_path_common(PlannerInfo *root,
261262
Index relindex = path->parent->relid;
262263
ChildScanCommon child = palloc(sizeof(ChildScanCommonData));
263264

265+
result->cpath.path.startup_cost += path->startup_cost;
266+
result->cpath.path.total_cost += path->total_cost;
267+
264268
child->content.path = path;
265269
child->relid = root->simple_rte_array[relindex]->relid;
266270
Assert(child->relid != InvalidOid);
@@ -272,6 +276,9 @@ create_append_path_common(PlannerInfo *root,
272276
i++;
273277
}
274278

279+
result->cpath.path.startup_cost *= sel;
280+
result->cpath.path.total_cost *= sel;
281+
275282
return &result->cpath.path;
276283
}
277284

nodes_common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ Path * create_append_path_common(PlannerInfo *root,
5757
AppendPath *inner_append,
5858
ParamPathInfo *param_info,
5959
List *picky_clauses,
60-
CustomPathMethods *path_methods);
60+
CustomPathMethods *path_methods,
61+
double sel);
6162

6263
Plan * create_append_plan_common(PlannerInfo *root, RelOptInfo *rel,
6364
CustomPath *best_path, List *tlist,

pathman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ typedef struct
212212
const Node *orig;
213213
List *args;
214214
List *rangeset;
215+
double paramsel;
215216
} WrapperNode;
216217

217218
typedef struct

pg_pathman.c

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
#include "utils/elog.h"
3131
#include "utils/array.h"
3232
#include "utils/date.h"
33-
#include "utils/lsyscache.h"
3433
#include "utils/guc.h"
34+
#include "utils/lsyscache.h"
35+
#include "utils/selfuncs.h"
3536
#include "access/heapam.h"
3637
#include "access/nbtree.h"
3738
#include "storage/ipc.h"
@@ -841,6 +842,7 @@ walk_expr_tree(WalkerContext *wcxt, Expr *expr, const PartRelationInfo *prel)
841842
result->orig = (const Node *)expr;
842843
result->args = NIL;
843844
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
845+
result->paramsel = 1.0;
844846
return result;
845847
}
846848
}
@@ -866,8 +868,7 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
866868
TypeCacheEntry *tce;
867869

868870
/* Determine operator type */
869-
tce = lookup_type_cache(v->vartype,
870-
TYPECACHE_EQ_OPR | TYPECACHE_LT_OPR | TYPECACHE_GT_OPR | TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);
871+
tce = lookup_type_cache(v->vartype, TYPECACHE_BTREE_OPFAMILY | TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);
871872
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
872873
cmp_proc_oid = get_opfamily_proc(tce->btree_opf,
873874
c->consttype,
@@ -1036,6 +1037,38 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
10361037
}
10371038

10381039
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
1040+
result->paramsel = 1.0;
1041+
}
1042+
1043+
/*
1044+
* Estimate selectivity of parametrized quals.
1045+
*/
1046+
static void
1047+
handle_binary_opexpr_param(const PartRelationInfo *prel,
1048+
WrapperNode *result, const Var *v)
1049+
{
1050+
const OpExpr *expr = (const OpExpr *)result->orig;
1051+
TypeCacheEntry *tce;
1052+
int strategy;
1053+
1054+
/* Determine operator type */
1055+
tce = lookup_type_cache(v->vartype, TYPECACHE_BTREE_OPFAMILY);
1056+
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
1057+
1058+
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
1059+
1060+
if (strategy == BTEqualStrategyNumber)
1061+
{
1062+
result->paramsel = 1.0 / (double) prel->children_count;
1063+
}
1064+
else if (prel->parttype == PT_RANGE && strategy > 0)
1065+
{
1066+
result->paramsel = DEFAULT_INEQ_SEL;
1067+
}
1068+
else
1069+
{
1070+
result->paramsel = 1.0;
1071+
}
10391072
}
10401073

10411074
/*
@@ -1135,24 +1168,36 @@ handle_opexpr(WalkerContext *wcxt, const OpExpr *expr, const PartRelationInfo *p
11351168

11361169
if (list_length(expr->args) == 2)
11371170
{
1138-
firstarg = (Node *) linitial(expr->args);
1139-
secondarg = (Node *) lsecond(expr->args);
1140-
1141-
if (IsA(firstarg, Var) && IsConstValue(wcxt, secondarg) &&
1142-
((Var *)firstarg)->varattno == prel->attnum)
1171+
if (IsA(linitial(expr->args), Var)
1172+
&& ((Var *)linitial(expr->args))->varattno == prel->attnum)
11431173
{
1144-
handle_binary_opexpr(prel, result, (Var *)firstarg, ExtractConst(wcxt, secondarg));
1145-
return result;
1174+
firstarg = (Node *) linitial(expr->args);
1175+
secondarg = (Node *) lsecond(expr->args);
11461176
}
1147-
else if (IsA(secondarg, Var) && IsConstValue(wcxt, firstarg) &&
1148-
((Var *)secondarg)->varattno == prel->attnum)
1177+
else if (IsA(lsecond(expr->args), Var)
1178+
&& ((Var *)lsecond(expr->args))->varattno == prel->attnum)
11491179
{
1150-
handle_binary_opexpr(prel, result, (Var *)secondarg, ExtractConst(wcxt, firstarg));
1151-
return result;
1180+
firstarg = (Node *) lsecond(expr->args);
1181+
secondarg = (Node *) linitial(expr->args);
1182+
}
1183+
1184+
if (firstarg && secondarg)
1185+
{
1186+
if (IsConstValue(wcxt, secondarg))
1187+
{
1188+
handle_binary_opexpr(prel, result, (Var *)firstarg, ExtractConst(wcxt, secondarg));
1189+
return result;
1190+
}
1191+
else if (IsA(secondarg, Param) || IsA(secondarg, Var))
1192+
{
1193+
handle_binary_opexpr_param(prel, result, (Var *)firstarg);
1194+
return result;
1195+
}
11521196
}
11531197
}
11541198

11551199
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
1200+
result->paramsel = 1.0;
11561201
return result;
11571202
}
11581203

@@ -1167,6 +1212,7 @@ handle_boolexpr(WalkerContext *wcxt, const BoolExpr *expr, const PartRelationInf
11671212

11681213
result->orig = (const Node *)expr;
11691214
result->args = NIL;
1215+
result->paramsel = 1.0;
11701216

11711217
if (expr->boolop == AND_EXPR)
11721218
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, false));
@@ -1186,13 +1232,28 @@ handle_boolexpr(WalkerContext *wcxt, const BoolExpr *expr, const PartRelationInf
11861232
break;
11871233
case AND_EXPR:
11881234
result->rangeset = irange_list_intersect(result->rangeset, arg->rangeset);
1235+
result->paramsel *= arg->paramsel;
11891236
break;
11901237
default:
11911238
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, false));
11921239
break;
11931240
}
11941241
}
11951242

1243+
if (expr->boolop == OR_EXPR)
1244+
{
1245+
int totallen = irange_list_length(result->rangeset);
1246+
1247+
foreach (lc, result->args)
1248+
{
1249+
WrapperNode *arg = (WrapperNode *) lfirst(lc);
1250+
int len = irange_list_length(arg->rangeset);
1251+
1252+
result->paramsel *= (1.0 - arg->paramsel * (double)len / (double)totallen);
1253+
}
1254+
result->paramsel = 1.0 - result->paramsel;
1255+
}
1256+
11961257
return result;
11971258
}
11981259

@@ -1209,6 +1270,7 @@ handle_arrexpr(WalkerContext *wcxt, const ScalarArrayOpExpr *expr, const PartRel
12091270

12101271
result->orig = (const Node *)expr;
12111272
result->args = NIL;
1273+
result->paramsel = 1.0;
12121274

12131275
if (varnode == NULL || !IsA(varnode, Var))
12141276
{
@@ -1254,6 +1316,11 @@ handle_arrexpr(WalkerContext *wcxt, const ScalarArrayOpExpr *expr, const PartRel
12541316
return result;
12551317
}
12561318

1319+
if (IsA(arraynode, Param))
1320+
{
1321+
result->paramsel = DEFAULT_INEQ_SEL;
1322+
}
1323+
12571324
result->rangeset = list_make1_irange(make_irange(0, prel->children_count - 1, true));
12581325
return result;
12591326
}

pickyappend.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ Path *
2323
create_pickyappend_path(PlannerInfo *root,
2424
AppendPath *inner_append,
2525
ParamPathInfo *param_info,
26-
List *picky_clauses)
26+
List *picky_clauses,
27+
double sel)
2728
{
2829
return create_append_path_common(root, inner_append,
2930
param_info, picky_clauses,
30-
&pickyappend_path_methods);
31+
&pickyappend_path_methods, sel);
3132
}
3233

3334
Plan *

pickyappend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ extern CustomScanMethods pickyappend_plan_methods;
6161
extern CustomExecMethods pickyappend_exec_methods;
6262

6363
Path * create_pickyappend_path(PlannerInfo *root, AppendPath *inner_append,
64-
ParamPathInfo *param_info, List *picky_clauses);
64+
ParamPathInfo *param_info, List *picky_clauses,
65+
double sel);
6566

6667
Plan * create_pickyappend_plan(PlannerInfo *root, RelOptInfo *rel,
6768
CustomPath *best_path, List *tlist,

0 commit comments

Comments
 (0)