On Fri, 26 Jan 2024 at 16:51, Tom Lane <t...@sss.pgh.pa.us> wrote:
> >> However ... it seems like we're not out of the woods yet.  Why
> >> is Richard's proposed test case still showing
> >> +         ->  Memoize (actual rows=5000 loops=N)
> >> +               Cache Key: t1.two, t1.two
> >> Seems like there is missing de-duplication logic, or something.
>
> > This seems separate and isn't quite causing the same problems as what
> > Richard wants to fix so I didn't touch this for now.
>
> Fair enough, but I think it might be worth pursuing later.

Here's a patch for that.

David
diff --git a/src/backend/optimizer/path/joinpath.c 
b/src/backend/optimizer/path/joinpath.c
index c0ba087b40..8ecf9fe8dc 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -492,8 +492,16 @@ paraminfo_get_equal_hashops(PlannerInfo *root, 
ParamPathInfo *param_info,
                                return false;
                        }
 
-                       *operators = lappend_oid(*operators, hasheqoperator);
-                       *param_exprs = lappend(*param_exprs, expr);
+                       /*
+                        * 'expr' may already exist as a parameter from a 
previous ppi_clauses.  No
+                        * need to include it again, however we'd better ensure 
we do switch into
+                        * binary mode if required.  See below.
+                        */
+                       if (!list_member(*param_exprs, expr))
+                       {
+                               *operators = lappend_oid(*operators, 
hasheqoperator);
+                               *param_exprs = lappend(*param_exprs, expr);
+                       }
 
                        /*
                         * When the join operator is not hashable then it's 
possible that
@@ -536,8 +544,16 @@ paraminfo_get_equal_hashops(PlannerInfo *root, 
ParamPathInfo *param_info,
                        return false;
                }
 
-               *operators = lappend_oid(*operators, typentry->eq_opr);
-               *param_exprs = lappend(*param_exprs, expr);
+               /*
+                * 'expr' may already exist as a parameter from the 
ppi_clauses.  No need to
+                * include it again, however we'd better ensure we do switch 
into binary
+                * mode.
+                */
+               if (!list_member(*param_exprs, expr))
+               {
+                       *operators = lappend_oid(*operators, typentry->eq_opr);
+                       *param_exprs = lappend(*param_exprs, expr);
+               }
 
                /*
                 * We must go into binary mode as we don't have too much of an 
idea of
diff --git a/src/test/regress/expected/memoize.out 
b/src/test/regress/expected/memoize.out
index ca198ec3b8..17bb3c8661 100644
--- a/src/test/regress/expected/memoize.out
+++ b/src/test/regress/expected/memoize.out
@@ -107,7 +107,7 @@ WHERE t1.unique1 < 10;', false);
          ->  Index Scan using tenk1_unique1 on tenk1 t1 (actual rows=10 
loops=N)
                Index Cond: (unique1 < 10)
          ->  Memoize (actual rows=2 loops=N)
-               Cache Key: t1.two, t1.two
+               Cache Key: t1.two
                Cache Mode: binary
                Hits: 8  Misses: 2  Evictions: Zero  Overflows: 0  Memory 
Usage: NkB
                ->  Subquery Scan on t2 (actual rows=2 loops=N)

Reply via email to