Skip to content

Commit df85277

Browse files
committed
Add expression check in pathlist hooks
1 parent f78330f commit df85277

File tree

4 files changed

+60
-88
lines changed

4 files changed

+60
-88
lines changed

range.sql

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,13 @@ BEGIN
130130
END LOOP;
131131

132132
/* Check boundaries */
133-
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)',
134-
parent_relid,
135-
expression,
136-
start_value,
137-
end_value,
138-
v_atttype::TEXT);
133+
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', $1, ''%s'', ''%s''::%s)',
134+
parent_relid,
135+
start_value,
136+
end_value,
137+
v_atttype::TEXT)
138+
USING
139+
expression;
139140
END IF;
140141

141142
/* Insert new entry to pathman config */

src/hooks.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
6161
ListCell *lc;
6262
WalkerContext context;
6363
double paramsel;
64+
Node *expr;
6465

6566
/* Call hooks set by other extensions */
6667
if (set_join_pathlist_next)
@@ -105,14 +106,17 @@ pathman_join_pathlist_hook(PlannerInfo *root,
105106
otherclauses = NIL;
106107
}
107108

109+
/* Make copy of partitioning expression and fix Var's varno attributes */
110+
expr = copyObject(inner_prel->expr);
111+
if (innerrel->relid != 1)
112+
ChangeVarNodes(expr, 1, innerrel->relid, 0);
113+
108114
paramsel = 1.0;
109115
foreach (lc, joinclauses)
110116
{
111117
WrapperNode *wrap;
112118

113-
InitWalkerContext(&context, innerrel->relid,
114-
inner_prel, NULL, false);
115-
119+
InitWalkerContext(&context, expr, inner_prel, NULL, false);
116120
wrap = walk_expr_tree((Expr *) lfirst(lc), &context);
117121
paramsel *= wrap->paramsel;
118122
}
@@ -252,6 +256,12 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
252256
WalkerContext context;
253257
ListCell *lc;
254258
int i;
259+
Node *expr;
260+
261+
/* Make copy of partitioning expression and fix Var's varno attributes */
262+
expr = copyObject(prel->expr);
263+
if (rti != 1)
264+
ChangeVarNodes(expr, 1, rti, 0);
255265

256266
if (prel->parttype == PT_RANGE)
257267
{
@@ -260,11 +270,6 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
260270
*/
261271
List *pathkeys;
262272
TypeCacheEntry *tce;
263-
Node *expr;
264-
265-
expr = copyObject(prel->expr);
266-
if (rti != 1)
267-
ChangeVarNodes(expr, 1, rti, 0);
268273

269274
/* Determine operator type */
270275
tce = lookup_type_cache(prel->atttype, TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
@@ -287,7 +292,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
287292
ranges = list_make1_irange(make_irange(0, PrelLastChild(prel), IR_COMPLETE));
288293

289294
/* Make wrappers over restrictions and collect final rangeset */
290-
InitWalkerContext(&context, rti, prel, NULL, false);
295+
InitWalkerContext(&context, expr, prel, NULL, false);
291296
wrappers = NIL;
292297
foreach(lc, rel->baserestrictinfo)
293298
{

src/include/pathman.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,16 @@ typedef struct
141141

142142
typedef struct
143143
{
144-
Index prel_varno; /* Var::varno associated with prel */
144+
Node *prel_expr; /* expression from PartRelationInfo */
145145
const PartRelationInfo *prel; /* main partitioning structure */
146146
ExprContext *econtext; /* for ExecEvalExpr() */
147147
bool for_insert; /* are we in PartitionFilter now? */
148148
} WalkerContext;
149149

150150
/* Usual initialization procedure for WalkerContext */
151-
#define InitWalkerContext(context, prel_vno, prel_info, ecxt, for_ins) \
151+
#define InitWalkerContext(context, expr, prel_info, ecxt, for_ins) \
152152
do { \
153-
(context)->prel_varno = (prel_vno); \
153+
(context)->prel_expr = (expr); \
154154
(context)->prel = (prel_info); \
155155
(context)->econtext = (ecxt); \
156156
(context)->for_insert = (for_ins); \

src/pg_pathman.c

Lines changed: 36 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static Path *get_cheapest_parameterized_child_path(PlannerInfo *root,
9999
RelOptInfo *rel,
100100
Relids required_outer);
101101

102-
102+
static bool match_expr_to_operand(Node *operand, Node *expr);
103103
/* We can transform Param into Const provided that 'econtext' is available */
104104
#define IsConstValue(wcxt, node) \
105105
( IsA((node), Const) || (WcxtHasExprContext(wcxt) ? IsA((node), Param) : false) )
@@ -895,36 +895,22 @@ static WrapperNode *
895895
handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
896896
{
897897
WrapperNode *result = (WrapperNode *) palloc(sizeof(WrapperNode));
898-
Node *varnode = (Node *) linitial(expr->args);
899-
Var *var;
898+
Node *exprnode = (Node *) linitial(expr->args);
900899
Node *arraynode = (Node *) lsecond(expr->args);
901900
const PartRelationInfo *prel = context->prel;
902901

903902
result->orig = (const Node *) expr;
904903
result->args = NIL;
905904
result->paramsel = 0.0;
906905

907-
Assert(varnode != NULL);
906+
Assert(exprnode != NULL);
908907

909-
/* If variable is not the partition key then skip it */
910-
if (IsA(varnode, Var) || IsA(varnode, RelabelType))
911-
{
912-
var = !IsA(varnode, RelabelType) ?
913-
(Var *) varnode :
914-
(Var *) ((RelabelType *) varnode)->arg;
915-
916-
/* Skip if base types or attribute numbers do not match */
917-
/* FIX: use exprsssion
918-
if (getBaseType(var->vartype) != getBaseType(prel->atttype) ||
919-
var->varoattno != prel->attnum ||
920-
var->varno != context->prel_varno)
921-
{
922-
goto handle_arrexpr_return;
923-
} */
924-
}
925-
else
908+
if (!match_expr_to_operand(context->prel_expr, exprnode))
926909
goto handle_arrexpr_return;
927910

911+
if (exprnode && IsA(exprnode, RelabelType))
912+
exprnode = (Node *) ((RelabelType *) exprnode)->arg;
913+
928914
if (arraynode && IsA(arraynode, Const) &&
929915
!((Const *) arraynode)->constisnull)
930916
{
@@ -1084,16 +1070,9 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
10841070
{
10851071
int strategy;
10861072
TypeCacheEntry *tce;
1087-
Oid vartype;
10881073
const OpExpr *expr = (const OpExpr *) result->orig;
10891074
const PartRelationInfo *prel = context->prel;
10901075

1091-
Assert(IsA(varnode, Var) || IsA(varnode, RelabelType));
1092-
1093-
vartype = !IsA(varnode, RelabelType) ?
1094-
((Var *) varnode)->vartype :
1095-
((RelabelType *) varnode)->resulttype;
1096-
10971076
/* Exit if Constant is NULL */
10981077
if (c->constisnull)
10991078
{
@@ -1102,7 +1081,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
11021081
return;
11031082
}
11041083

1105-
tce = lookup_type_cache(vartype, TYPECACHE_BTREE_OPFAMILY);
1084+
tce = lookup_type_cache(prel->atttype, TYPECACHE_BTREE_OPFAMILY);
11061085
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
11071086

11081087
/* There's no strategy for this operator, go to end */
@@ -1164,25 +1143,36 @@ handle_binary_opexpr_param(const PartRelationInfo *prel,
11641143
const OpExpr *expr = (const OpExpr *) result->orig;
11651144
TypeCacheEntry *tce;
11661145
int strategy;
1167-
Oid vartype;
1168-
1169-
Assert(IsA(varnode, Var) || IsA(varnode, RelabelType));
1170-
1171-
vartype = !IsA(varnode, RelabelType) ?
1172-
((Var *) varnode)->vartype :
1173-
((RelabelType *) varnode)->resulttype;
11741146

11751147
/* Determine operator type */
1176-
tce = lookup_type_cache(vartype, TYPECACHE_BTREE_OPFAMILY);
1148+
tce = lookup_type_cache(prel->atttype, TYPECACHE_BTREE_OPFAMILY);
11771149
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
11781150

11791151
result->rangeset = list_make1_irange(make_irange(0, PrelLastChild(prel), IR_LOSSY));
11801152
result->paramsel = estimate_paramsel_using_prel(prel, strategy);
11811153
}
11821154

1155+
1156+
/*
1157+
* Compare clause operand with our expression
1158+
*/
1159+
static bool
1160+
match_expr_to_operand(Node *operand, Node *expr)
1161+
{
1162+
/* strip relabeling for both operand and expr */
1163+
if (operand && IsA(operand, RelabelType))
1164+
operand = (Node *) ((RelabelType *) operand)->arg;
1165+
1166+
if (expr && IsA(expr, RelabelType))
1167+
expr = (Node *) ((RelabelType *) expr)->arg;
1168+
1169+
/* compare expressions and return result right away */
1170+
return equal(expr, operand);
1171+
}
1172+
11831173
/*
11841174
* Checks if expression is a KEY OP PARAM or PARAM OP KEY, where KEY is
1185-
* partition key (it could be Var or RelableType) and PARAM is whatever.
1175+
* partition expression and PARAM is whatever.
11861176
*
11871177
* NOTE: returns false if partition key is not in expression.
11881178
*/
@@ -1194,45 +1184,21 @@ pull_var_param(const WalkerContext *ctx,
11941184
{
11951185
Node *left = linitial(expr->args),
11961186
*right = lsecond(expr->args);
1197-
Var *v = NULL;
11981187

1199-
/* Check the case when variable is on the left side */
1200-
if (IsA(left, Var) || IsA(left, RelabelType))
1188+
if (match_expr_to_operand(left, ctx->prel_expr))
12011189
{
1202-
v = !IsA(left, RelabelType) ?
1203-
(Var *) left :
1204-
(Var *) ((RelabelType *) left)->arg;
1205-
1206-
/* Check if 'v' is partitioned column of 'prel' */
1207-
/* FIX this */
1208-
if (v->varoattno == 0 &&
1209-
v->varno == ctx->prel_varno)
1210-
{
1211-
*var_ptr = left;
1212-
*param_ptr = right;
1213-
return true;
1214-
}
1190+
*var_ptr = left;
1191+
*param_ptr = right;
1192+
return true;
12151193
}
12161194

1217-
/* ... variable is on the right side */
1218-
if (IsA(right, Var) || IsA(right, RelabelType))
1195+
if (match_expr_to_operand(right, ctx->prel_expr))
12191196
{
1220-
v = !IsA(right, RelabelType) ?
1221-
(Var *) right :
1222-
(Var *) ((RelabelType *) right)->arg;
1223-
1224-
/* Check if 'v' is partitioned column of 'prel' */
1225-
/* FIX this */
1226-
if (v->varoattno == 0 &&
1227-
v->varno == ctx->prel_varno)
1228-
{
1229-
*var_ptr = right;
1230-
*param_ptr = left;
1231-
return true;
1232-
}
1197+
*var_ptr = right;
1198+
*param_ptr = left;
1199+
return true;
12331200
}
12341201

1235-
/* Variable isn't a partitionig key */
12361202
return false;
12371203
}
12381204

0 commit comments

Comments
 (0)