Fix hash join when inner hashkey expressions contain Params.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 Jun 2023 21:47:36 +0000 (17:47 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 Jun 2023 21:47:53 +0000 (17:47 -0400)
commit45392626c95c6345d48c1b1b7541add0102ba59f
treef9a901ea4e762d5cc7db57ac725391aba0e0932b
parent8a300fc3afce4a0fe8a4c55bc22b2aeec092cf23
Fix hash join when inner hashkey expressions contain Params.

If the inner-side expressions contain PARAM_EXEC Params, we must
re-hash whenever the values of those Params change.  The executor
mechanism for that exists already, but we failed to invoke it because
finalize_plan() neglected to search the Hash.hashkeys field for
Params.  This allowed a previous scan's hash table to be re-used
when it should not be, leading to rows missing from the join's output.
(I believe incorrectly-included join rows are impossible however,
since checking the real hashclauses would reject false matches.)

This bug is very ancient, dating probably to d24d75ff1 of 7.4.
Sadly, this simple fix depends on the plan representational changes
made by 2abd7ae9b, so it will only work back to v12.  I thought
about trying to make some kind of hack for v11, but I'm leery
of putting code significantly different from what is used in the
newer branches into a nearly-EOL branch.  Seeing that the bug
escaped detection for a full twenty years, problematic cases
must be rare; so I don't feel too awful about leaving v11 as-is.

Per bug #17985 from Zuming Jiang.  Back-patch to v12.

Discussion: https://postgr.es/m/17985-748b66607acd432e@postgresql.org
src/backend/optimizer/plan/subselect.c
src/test/regress/expected/join_hash.out
src/test/regress/sql/join_hash.sql