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

Commit39a3105

Browse files
committed
Fix incorrect hash equality operator bug in Memoize
In v14, because we don't have a field in RestrictInfo to cache both theleft and right type's hash equality operator, we just restrict the scopeof Memoize to only when the left and right types of a RestrictInfo are thesame.In master we add another field to RestrictInfo and cache both hashequality operators.Reported-by: Jaime CasanovaAuthor: David RowleyDiscussion:https://postgr.es/m/20210929185544.GB24346%40ahch-toBackpatch-through: 14
1 parente2fbb88 commit39a3105

File tree

6 files changed

+54
-22
lines changed

6 files changed

+54
-22
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2362,7 +2362,8 @@ _copyRestrictInfo(const RestrictInfo *from)
23622362
COPY_SCALAR_FIELD(right_bucketsize);
23632363
COPY_SCALAR_FIELD(left_mcvfreq);
23642364
COPY_SCALAR_FIELD(right_mcvfreq);
2365-
COPY_SCALAR_FIELD(hasheqoperator);
2365+
COPY_SCALAR_FIELD(left_hasheqoperator);
2366+
COPY_SCALAR_FIELD(right_hasheqoperator);
23662367

23672368
returnnewnode;
23682369
}

‎src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2565,7 +2565,8 @@ _outRestrictInfo(StringInfo str, const RestrictInfo *node)
25652565
WRITE_NODE_FIELD(right_em);
25662566
WRITE_BOOL_FIELD(outer_is_left);
25672567
WRITE_OID_FIELD(hashjoinoperator);
2568-
WRITE_OID_FIELD(hasheqoperator);
2568+
WRITE_OID_FIELD(left_hasheqoperator);
2569+
WRITE_OID_FIELD(right_hasheqoperator);
25692570
}
25702571

25712572
staticvoid

‎src/backend/optimizer/path/joinpath.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,27 +394,42 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info,
394394
RestrictInfo*rinfo= (RestrictInfo*)lfirst(lc);
395395
OpExpr*opexpr;
396396
Node*expr;
397+
Oidhasheqoperator;
397398

398-
/* can't use a memoize node without a valid hash equals operator */
399-
if (!OidIsValid(rinfo->hasheqoperator)||
399+
opexpr= (OpExpr*)rinfo->clause;
400+
401+
/*
402+
* Bail if the rinfo is not compatible. We need a join OpExpr
403+
* with 2 args.
404+
*/
405+
if (!IsA(opexpr,OpExpr)||list_length(opexpr->args)!=2||
400406
!clause_sides_match_join(rinfo,outerrel,innerrel))
401407
{
402408
list_free(*operators);
403409
list_free(*param_exprs);
404410
return false;
405411
}
406412

407-
/*
408-
* We already checked that this is an OpExpr with 2 args when
409-
* setting hasheqoperator.
410-
*/
411-
opexpr= (OpExpr*)rinfo->clause;
412413
if (rinfo->outer_is_left)
414+
{
413415
expr= (Node*)linitial(opexpr->args);
416+
hasheqoperator=rinfo->left_hasheqoperator;
417+
}
414418
else
419+
{
415420
expr= (Node*)lsecond(opexpr->args);
421+
hasheqoperator=rinfo->right_hasheqoperator;
422+
}
423+
424+
/* can't do memoize if we can't hash the outer type */
425+
if (!OidIsValid(hasheqoperator))
426+
{
427+
list_free(*operators);
428+
list_free(*param_exprs);
429+
return false;
430+
}
416431

417-
*operators=lappend_oid(*operators,rinfo->hasheqoperator);
432+
*operators=lappend_oid(*operators,hasheqoperator);
418433
*param_exprs=lappend(*param_exprs,expr);
419434
}
420435
}

‎src/backend/optimizer/plan/initsplan.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,15 +2711,16 @@ check_hashjoinable(RestrictInfo *restrictinfo)
27112711
/*
27122712
* check_memoizable
27132713
* If the restrictinfo's clause is suitable to be used for a Memoize node,
2714-
* set thehasheqoperatorto the hash equality operator that will be needed
2715-
* during caching.
2714+
* set thelefthasheqoperator and righthasheqoperatorto the hash equality
2715+
*operator that will be neededduring caching.
27162716
*/
27172717
staticvoid
27182718
check_memoizable(RestrictInfo*restrictinfo)
27192719
{
27202720
TypeCacheEntry*typentry;
27212721
Expr*clause=restrictinfo->clause;
2722-
Node*leftarg;
2722+
Oidlefttype;
2723+
Oidrighttype;
27232724

27242725
if (restrictinfo->pseudoconstant)
27252726
return;
@@ -2728,13 +2729,24 @@ check_memoizable(RestrictInfo *restrictinfo)
27282729
if (list_length(((OpExpr*)clause)->args)!=2)
27292730
return;
27302731

2731-
leftarg=linitial(((OpExpr*)clause)->args);
2732+
lefttype=exprType(linitial(((OpExpr*)clause)->args));
27322733

2733-
typentry=lookup_type_cache(exprType(leftarg),TYPECACHE_HASH_PROC |
2734+
typentry=lookup_type_cache(lefttype,TYPECACHE_HASH_PROC |
27342735
TYPECACHE_EQ_OPR);
27352736

2736-
if (!OidIsValid(typentry->hash_proc)|| !OidIsValid(typentry->eq_opr))
2737-
return;
2737+
if (OidIsValid(typentry->hash_proc)&&OidIsValid(typentry->eq_opr))
2738+
restrictinfo->left_hasheqoperator=typentry->eq_opr;
2739+
2740+
righttype=exprType(lsecond(((OpExpr*)clause)->args));
2741+
2742+
/*
2743+
* Lookup the right type, unless it's the same as the left type, in which
2744+
* case typentry is already pointing to the required TypeCacheEntry.
2745+
*/
2746+
if (lefttype!=righttype)
2747+
typentry=lookup_type_cache(righttype,TYPECACHE_HASH_PROC |
2748+
TYPECACHE_EQ_OPR);
27382749

2739-
restrictinfo->hasheqoperator=typentry->eq_opr;
2750+
if (OidIsValid(typentry->hash_proc)&&OidIsValid(typentry->eq_opr))
2751+
restrictinfo->right_hasheqoperator=typentry->eq_opr;
27402752
}

‎src/backend/optimizer/util/restrictinfo.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ make_restrictinfo_internal(PlannerInfo *root,
217217
restrictinfo->left_mcvfreq=-1;
218218
restrictinfo->right_mcvfreq=-1;
219219

220-
restrictinfo->hasheqoperator=InvalidOid;
220+
restrictinfo->left_hasheqoperator=InvalidOid;
221+
restrictinfo->right_hasheqoperator=InvalidOid;
221222

222223
returnrestrictinfo;
223224
}
@@ -368,7 +369,8 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op)
368369
result->right_bucketsize=rinfo->left_bucketsize;
369370
result->left_mcvfreq=rinfo->right_mcvfreq;
370371
result->right_mcvfreq=rinfo->left_mcvfreq;
371-
result->hasheqoperator=InvalidOid;
372+
result->left_hasheqoperator=InvalidOid;
373+
result->right_hasheqoperator=InvalidOid;
372374

373375
returnresult;
374376
}

‎src/include/nodes/pathnodes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,8 +2122,9 @@ typedef struct RestrictInfo
21222122
Selectivityleft_mcvfreq;/* left side's most common val's freq */
21232123
Selectivityright_mcvfreq;/* right side's most common val's freq */
21242124

2125-
/* hash equality operator used for memoize nodes, else InvalidOid */
2126-
Oidhasheqoperator;
2125+
/* hash equality operators used for memoize nodes, else InvalidOid */
2126+
Oidleft_hasheqoperator;
2127+
Oidright_hasheqoperator;
21272128
}RestrictInfo;
21282129

21292130
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp