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

Commit095eb98

Browse files
committed
Fix pathlist hooks
1 parent102bb31 commit095eb98

File tree

9 files changed

+154
-67
lines changed

9 files changed

+154
-67
lines changed

‎sql/pathman_basic.sql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ CREATE TABLE test.hash_rel (
1111
INSERT INTOtest.hash_relVALUES (1,1);
1212
INSERT INTOtest.hash_relVALUES (2,2);
1313
INSERT INTOtest.hash_relVALUES (3,3);
14-
:gdb
15-
SELECT pg_sleep(10);
1614
SELECTpathman.create_hash_partitions('test.hash_rel','value + 1',3);
1715
ALTERTABLEtest.hash_rel ALTER COLUMN valueSETNOT NULL;
1816
SELECTpathman.create_hash_partitions('test.hash_rel','value',3, partition_data:=false);

‎src/hooks.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,15 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
248248
Relationparent_rel;/* parent's relation (heap) */
249249
Oid*children;/* selected children oids */
250250
List*ranges,/* a list of IndexRanges */
251-
*wrappers,/* a list of WrapperNodes */
252-
*rel_part_clauses=NIL;/* clauses with part. column */
251+
*wrappers;/* a list of WrapperNodes */
253252
PathKey*pathkeyAsc=NULL,
254253
*pathkeyDesc=NULL;
255254
doubleparamsel=1.0;/* default part selectivity */
256255
WalkerContextcontext;
257256
ListCell*lc;
258257
inti;
259258
Node*expr;
259+
boolmodify_append_nodes;
260260

261261
/* Make copy of partitioning expression and fix Var's varno attributes */
262262
expr=copyObject(prel->expr);
@@ -306,6 +306,12 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
306306
ranges=irange_list_intersection(ranges,wrap->rangeset);
307307
}
308308

309+
/*
310+
* Walker should been have filled these parameter while checking.
311+
* Runtime[Merge]Append is pointless if there are no params in clauses.
312+
*/
313+
modify_append_nodes=context.found_params;
314+
309315
/* Get number of selected partitions */
310316
irange_len=irange_list_length(ranges);
311317
if (prel->enable_parent)
@@ -382,12 +388,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
382388
pg_pathman_enable_runtime_merge_append))
383389
return;
384390

385-
/* Check that rel's RestrictInfo contains partitioned column */
386-
rel_part_clauses=get_partitioned_attr_clauses(rel->baserestrictinfo,
387-
prel,rel->relid);
388-
389-
/* Runtime[Merge]Append is pointless if there are no params in clauses */
390-
if (!clause_contains_params((Node*)rel_part_clauses))
391+
if (!modify_append_nodes)
391392
return;
392393

393394
/* Generate Runtime[Merge]Append paths if needed */
@@ -416,7 +417,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
416417
* Skip if neither rel->baserestrictinfo nor
417418
* ppi->ppi_clauses reference partition attribute
418419
*/
419-
if (!(rel_part_clauses||ppi_part_clauses))
420+
if (!(modify_append_nodes||ppi_part_clauses))
420421
continue;
421422

422423
if (IsA(cur_path,AppendPath)&&pg_pathman_enable_runtimeappend)

‎src/include/pathman.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,12 @@ typedef struct
141141

142142
typedefstruct
143143
{
144-
Node*prel_expr;/* expression from PartRelationInfo */
145-
constPartRelationInfo*prel;/* main partitioning structure */
146-
ExprContext*econtext;/* for ExecEvalExpr() */
147-
boolfor_insert;/* are we in PartitionFilter now? */
144+
Node*prel_expr;/* expression from PartRelationInfo */
145+
constPartRelationInfo*prel;/* main partitioning structure */
146+
ExprContext*econtext;/* for ExecEvalExpr() */
147+
boolfor_insert;/* are we in PartitionFilter now? */
148+
boolfound_params;/* mark if left or right argument
149+
of clause is Param */
148150
}WalkerContext;
149151

150152
/* Usual initialization procedure for WalkerContext */
@@ -154,6 +156,7 @@ typedef struct
154156
(context)->prel = (prel_info); \
155157
(context)->econtext = (ecxt); \
156158
(context)->for_insert = (for_ins); \
159+
(context)->found_params = (false); \
157160
} while (0)
158161

159162
/* Check that WalkerContext contains ExprContext (plan execution stage) */

‎src/include/relation_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ typedef struct
139139

140140
constchar*attname;/* original expression */
141141
Node*expr;/* planned expression */
142+
List*expr_vars;/* vars from expression, lazy */
142143
Oidatttype;/* expression type */
143144
int32atttypmod;/* expression type modifier */
144145
boolattbyval;/* is partitioned column stored by value? */

‎src/include/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
boolclause_contains_params(Node*clause);
2929
boolis_date_type_internal(Oidtypid);
3030
boolcheck_security_policy_internal(Oidrelid,Oidrole);
31+
boolmatch_expr_to_operand(Node*operand,Node*expr);
3132

3233
/*
3334
* Misc.

‎src/nodes_common.c

Lines changed: 112 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* ------------------------------------------------------------------------
99
*/
1010

11+
#include"init.h"
1112
#include"nodes_common.h"
1213
#include"runtimeappend.h"
1314
#include"utils.h"
@@ -128,41 +129,83 @@ replace_tlist_varnos(List *tlist, Index old_varno, Index new_varno)
128129
returntemp_tlist;
129130
}
130131

132+
/* Check that one of arguments of OpExpr is expression */
133+
staticbool
134+
extract_vars(Node*node,PartRelationInfo*prel)
135+
{
136+
if (node==NULL)
137+
return false;
138+
139+
if (IsA(node,Var))
140+
{
141+
prel->expr_vars=lappend(prel->expr_vars,node);
142+
return false;
143+
}
144+
145+
returnexpression_tree_walker(node,extract_vars, (void*)prel);
146+
}
147+
148+
149+
/*
150+
* This function fills 'expr_vars' attribute in PartRelationInfo.
151+
* For now it's static because there are no other places where we need it.
152+
*/
153+
staticinlineList*
154+
extract_vars_from_expression(PartRelationInfo*prel)
155+
{
156+
if (prel->expr_vars==NIL)
157+
{
158+
MemoryContextctx;
159+
160+
prel->expr_vars=NIL;
161+
ctx=MemoryContextSwitchTo(PathmanRelationCacheContext);
162+
extract_vars(prel->expr,prel);
163+
MemoryContextSwitchTo(ctx);
164+
}
165+
166+
returnprel->expr_vars;
167+
}
168+
131169
/* Append partition attribute in case it's not present in target list */
132170
staticList*
133171
append_part_attr_to_tlist(List*tlist,Indexrelno,constPartRelationInfo*prel)
134172
{
135-
ListCell*lc;
136-
boolpart_attr_found= false;
173+
ListCell*lc,
174+
*lc_var;
175+
List*vars=extract_vars_from_expression((PartRelationInfo*)prel);
176+
List*vars_not_found=NIL;
137177

138-
foreach (lc,tlist)
178+
foreach (lc_var,vars)
139179
{
140-
TargetEntry*te= (TargetEntry*)lfirst(lc);
141-
Var*var= (Var*)te->expr;
180+
boolpart_attr_found= false;
181+
Var*expr_var= (Var*)lfirst(lc_var);
182+
183+
foreach (lc,tlist)
184+
{
185+
TargetEntry*te= (TargetEntry*)lfirst(lc);
186+
Var*var= (Var*)te->expr;
187+
188+
if (IsA(var,Var)&&var->varoattno==expr_var->varattno)
189+
{
190+
part_attr_found= true;
191+
break;
192+
}
193+
}
142194

143-
/* FIX this
144-
if (IsA(var, Var) && var->varoattno == prel->attnum)
145-
part_attr_found = true;
146-
*/
195+
if (!part_attr_found)
196+
vars_not_found=lappend(vars_not_found,expr_var);
147197
}
148198

149-
/* FIX this
150-
if (!part_attr_found)
199+
foreach(lc,vars_not_found)
151200
{
152-
Var *newvar = makeVar(relno,
153-
prel->attnum,
154-
prel->atttype,
155-
prel->atttypmod,
156-
prel->attcollid,
157-
0);
158-
201+
Var*var= (Var*)lfirst(lc);
159202
Indexlast_item=list_length(tlist)+1;
160-
161-
tlist = lappend(tlist, makeTargetEntry((Expr *) newvar,
203+
tlist=lappend(tlist,makeTargetEntry((Expr*)var,
162204
last_item,
163205
NULL, false));
164-
} */
206+
}
165207

208+
list_free(vars_not_found);
166209
returntlist;
167210
}
168211

@@ -242,6 +285,37 @@ unpack_runtimeappend_private(RuntimeAppendState *scan_state, CustomScan *cscan)
242285
scan_state->enable_parent= (bool)linitial_int(lthird(runtimeappend_private));
243286
}
244287

288+
structcheck_clause_context
289+
{
290+
Node*prel_expr;
291+
intcount;
292+
};
293+
294+
/* Check that one of arguments of OpExpr is expression */
295+
staticbool
296+
check_clause_for_expression(Node*node,structcheck_clause_context*ctx)
297+
{
298+
if (node==NULL)
299+
return false;
300+
301+
if (IsA(node,OpExpr))
302+
{
303+
OpExpr*expr= (OpExpr*)node;
304+
Node*left=linitial(expr->args),
305+
*right=lsecond(expr->args);
306+
307+
if (match_expr_to_operand(left,ctx->prel_expr))
308+
ctx->count+=1;
309+
310+
if (match_expr_to_operand(right,ctx->prel_expr))
311+
ctx->count+=1;
312+
313+
return false;
314+
}
315+
316+
returnexpression_tree_walker(node,check_clause_for_expression, (void*)ctx);
317+
}
318+
245319
/*
246320
* Filter all available clauses and extract relevant ones.
247321
*/
@@ -250,27 +324,22 @@ get_partitioned_attr_clauses(List *restrictinfo_list,
250324
constPartRelationInfo*prel,
251325
Indexpartitioned_rel)
252326
{
253-
#defineAdjustAttno(attno) \
254-
( (AttrNumber) (attno + FirstLowInvalidHeapAttributeNumber) )
255-
256327
List*result=NIL;
257328
ListCell*l;
258329

259330
foreach(l,restrictinfo_list)
260331
{
261-
RestrictInfo*rinfo= (RestrictInfo*)lfirst(l);
262-
Bitmapset*varattnos=NULL;
263-
intpart_attno;
332+
RestrictInfo*rinfo= (RestrictInfo*)lfirst(l);
333+
structcheck_clause_contextctx;
264334

265335
Assert(IsA(rinfo,RestrictInfo));
266-
pull_varattnos((Node*)rinfo->clause,partitioned_rel,&varattnos);
267336

268-
/* FIX this
269-
if (bms_get_singleton_member(varattnos, &part_attno) &&
270-
AdjustAttno(part_attno) == prel->attnum)
271-
{
337+
ctx.count=0;
338+
ctx.prel_expr=prel->expr;
339+
check_clause_for_expression((Node*)rinfo->clause,&ctx);
340+
341+
if (ctx.count==1)
272342
result=lappend(result,rinfo->clause);
273-
} */
274343
}
275344
returnresult;
276345
}
@@ -554,14 +623,23 @@ rescan_append_common(CustomScanState *node)
554623
WalkerContextwcxt;
555624
Oid*parts;
556625
intnparts;
626+
Node*prel_expr;
557627

558628
prel=get_pathman_relation_info(scan_state->relid);
559629
Assert(prel);
560630

631+
/* Prepare expression */
632+
prel_expr=prel->expr;
633+
if (INDEX_VAR!=1)
634+
{
635+
prel_expr=copyObject(prel_expr);
636+
ChangeVarNodes(prel_expr,1,INDEX_VAR,0);
637+
}
638+
561639
/* First we select all available partitions... */
562640
ranges=list_make1_irange(make_irange(0,PrelLastChild(prel),IR_COMPLETE));
563641

564-
InitWalkerContext(&wcxt,INDEX_VAR,prel,econtext, false);
642+
InitWalkerContext(&wcxt,prel_expr,prel,econtext, false);
565643
foreach (lc,scan_state->custom_exprs)
566644
{
567645
WrapperNode*wn;

‎src/pg_pathman.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ static Path *get_cheapest_parameterized_child_path(PlannerInfo *root,
9999
RelOptInfo*rel,
100100
Relidsrequired_outer);
101101

102-
staticboolmatch_expr_to_operand(Node*operand,Node*expr);
103102
/* We can transform Param into Const provided that 'econtext' is available */
104103
#defineIsConstValue(wcxt,node) \
105104
( IsA((node), Const) || (WcxtHasExprContext(wcxt) ? IsA((node), Param) : false) )
@@ -1052,6 +1051,9 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
10521051
}
10531052
elseif (IsA(param,Param)||IsA(param,Var))
10541053
{
1054+
if (IsA(param,Param))
1055+
context->found_params= true;
1056+
10551057
handle_binary_opexpr_param(prel,result,var);
10561058
returnresult;
10571059
}
@@ -1153,23 +1155,6 @@ handle_binary_opexpr_param(const PartRelationInfo *prel,
11531155
}
11541156

11551157

1156-
/*
1157-
* Compare clause operand with our expression
1158-
*/
1159-
staticbool
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-
returnequal(expr,operand);
1171-
}
1172-
11731158
/*
11741159
* Checks if expression is a KEY OP PARAM or PARAM OP KEY, where KEY is
11751160
* partition expression and PARAM is whatever.

‎src/relation_info.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ refresh_pathman_relation_info(Oid relid,
187187

188188
prel->attname=TextDatumGetCString(values[Anum_pathman_config_expression-1]);
189189
prel->expr= (Node*)stringToNode(expr);
190+
prel->expr_vars=NIL;
190191
fix_opfuncids(prel->expr);
191192

192193
MemoryContextSwitchTo(oldcontext);

‎src/utils.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,22 @@ extract_binary_interval_from_text(Datum interval_text,/* interval as TEXT */
467467

468468
returninterval_binary;
469469
}
470+
471+
472+
/*
473+
* Compare clause operand with expression
474+
*/
475+
bool
476+
match_expr_to_operand(Node*operand,Node*expr)
477+
{
478+
/* strip relabeling for both operand and expr */
479+
if (operand&&IsA(operand,RelabelType))
480+
operand= (Node*) ((RelabelType*)operand)->arg;
481+
482+
if (expr&&IsA(expr,RelabelType))
483+
expr= (Node*) ((RelabelType*)expr)->arg;
484+
485+
/* compare expressions and return result right away */
486+
returnequal(expr,operand);
487+
}
488+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp