diff options
| author | David Rowley | 2021-11-08 01:40:33 +0000 |
|---|---|---|
| committer | David Rowley | 2021-11-08 01:40:33 +0000 |
| commit | 39a3105678a247bbfdc132cd95db5b515b8cd7f6 (patch) | |
| tree | 3267d3ecbefa5306f13682c927b828155f112ada /src/backend/optimizer/path | |
| parent | e2fbb883720aa222f61eb9f3affad1c63bac7cbb (diff) | |
Fix incorrect hash equality operator bug in Memoize
In v14, because we don't have a field in RestrictInfo to cache both the
left and right type's hash equality operator, we just restrict the scope
of Memoize to only when the left and right types of a RestrictInfo are the
same.
In master we add another field to RestrictInfo and cache both hash
equality operators.
Reported-by: Jaime Casanova
Author: David Rowley
Discussion: https://postgr.es/m/20210929185544.GB24346%40ahch-to
Backpatch-through: 14
Diffstat (limited to 'src/backend/optimizer/path')
| -rw-r--r-- | src/backend/optimizer/path/joinpath.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 6407ede12a6..0f3ad8aa658 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -394,9 +394,15 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); OpExpr *opexpr; Node *expr; + Oid hasheqoperator; - /* can't use a memoize node without a valid hash equals operator */ - if (!OidIsValid(rinfo->hasheqoperator) || + opexpr = (OpExpr *) rinfo->clause; + + /* + * Bail if the rinfo is not compatible. We need a join OpExpr + * with 2 args. + */ + if (!IsA(opexpr, OpExpr) || list_length(opexpr->args) != 2 || !clause_sides_match_join(rinfo, outerrel, innerrel)) { list_free(*operators); @@ -404,17 +410,26 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, return false; } - /* - * We already checked that this is an OpExpr with 2 args when - * setting hasheqoperator. - */ - opexpr = (OpExpr *) rinfo->clause; if (rinfo->outer_is_left) + { expr = (Node *) linitial(opexpr->args); + hasheqoperator = rinfo->left_hasheqoperator; + } else + { expr = (Node *) lsecond(opexpr->args); + hasheqoperator = rinfo->right_hasheqoperator; + } + + /* can't do memoize if we can't hash the outer type */ + if (!OidIsValid(hasheqoperator)) + { + list_free(*operators); + list_free(*param_exprs); + return false; + } - *operators = lappend_oid(*operators, rinfo->hasheqoperator); + *operators = lappend_oid(*operators, hasheqoperator); *param_exprs = lappend(*param_exprs, expr); } } |
