Skip to content

Commit a3ca85d

Browse files
committed
improve paramsel estimation in handle_arrexpr()
1 parent a20c446 commit a3ca85d

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

src/pg_pathman.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,9 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10801080
tce = lookup_type_cache(prel->ev_type, TYPECACHE_BTREE_OPFAMILY);
10811081
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
10821082

1083+
/* Save expression */
1084+
result->orig = (const Node *) expr;
1085+
10831086
/* Check if expression tree is a partitioning expression */
10841087
if (!match_expr_to_operand(context->prel_expr, part_expr))
10851088
goto handle_arrexpr_all;
@@ -1097,10 +1100,12 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
10971100

10981101
/* Array is NULL */
10991102
if (c->constisnull)
1100-
goto handle_arrexpr_none;
1103+
{
1104+
result->rangeset = NIL;
1105+
result->paramsel = 0.0;
11011106

1102-
/* Provide expression for optimizations */
1103-
result->orig = (const Node *) expr;
1107+
return; /* done, exit */
1108+
}
11041109

11051110
/* Examine array */
11061111
handle_array(DatumGetArrayTypeP(c->constvalue),
@@ -1114,7 +1119,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11141119
{
11151120
ArrayExpr *arr_expr = (ArrayExpr *) array;
11161121
Oid elem_type = arr_expr->element_typeid;
1117-
bool array_has_params = false;
1122+
int array_params = 0;
1123+
double paramsel = 1.0;
11181124
List *ranges;
11191125
ListCell *lc;
11201126

@@ -1158,25 +1164,40 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11581164
irange_list_union(ranges, wrap.rangeset) :
11591165
irange_list_intersection(ranges, wrap.rangeset);
11601166
}
1161-
else array_has_params = true; /* we have non-const nodes */
1167+
else array_params++; /* we've just met non-const nodes */
11621168
}
11631169

11641170
/* Check for PARAM-related optimizations */
1165-
if (array_has_params)
1171+
if (array_params > 0)
11661172
{
1167-
/* We can't say anything if PARAMs + ANY */
1173+
double sel = estimate_paramsel_using_prel(prel, strategy);
1174+
int i;
1175+
11681176
if (expr->useOr)
1169-
goto handle_arrexpr_all;
1177+
{
1178+
/* We can't say anything if PARAMs + ANY */
1179+
ranges = list_make1_irange_full(prel, IR_LOSSY);
1180+
1181+
/* See handle_boolexpr() */
1182+
for (i = 0; i < array_params; i++)
1183+
paramsel *= (1 - sel);
1184+
1185+
paramsel = 1 - paramsel;
1186+
}
1187+
else
1188+
{
1189+
/* Recheck condition on a narrowed set of partitions */
1190+
ranges = irange_list_set_lossiness(ranges, IR_LOSSY);
11701191

1171-
/* Recheck condition on a narrowed set of partitions */
1172-
ranges = irange_list_set_lossiness(ranges, IR_LOSSY);
1192+
/* See handle_boolexpr() */
1193+
for (i = 0; i < array_params; i++)
1194+
paramsel *= sel;
1195+
}
11731196
}
11741197

1175-
/* Save rangeset */
1198+
/* Save result */
11761199
result->rangeset = ranges;
1177-
1178-
/* Save expression */
1179-
result->orig = (const Node *) expr;
1200+
result->paramsel = paramsel;
11801201

11811202
return; /* done, exit */
11821203
}
@@ -1187,21 +1208,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr,
11871208

11881209
handle_arrexpr_all:
11891210
result->rangeset = list_make1_irange_full(prel, IR_LOSSY);
1190-
result->paramsel = estimate_paramsel_using_prel(prel, strategy);
1191-
1192-
/* Save expression */
1193-
result->orig = (const Node *) expr;
1194-
1195-
return;
1196-
1197-
handle_arrexpr_none:
1198-
result->rangeset = NIL;
1199-
result->paramsel = 0.0;
1200-
1201-
/* Save expression */
1202-
result->orig = (const Node *) expr;
1203-
1204-
return;
1211+
result->paramsel = 1.0;
12051212
}
12061213

12071214
/* Operator expression handler */

0 commit comments

Comments
 (0)