pgsql: Fix reuse of stale hash tables by duplicated hashed SubPlans

From: Richard Guo <rguo(at)postgresql(dot)org>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: Fix reuse of stale hash tables by duplicated hashed SubPlans
Date: 2026-11-02 05:42:15
Message-ID: E1xNkoB-00000001kZL-0i9m@gemulon.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Fix reuse of stale hash tables by duplicated hashed SubPlans

The same SubPlan can appear more than once in a plan tree. For
example, when an equivalence class has a constant member containing a
SubPlan, each derived "member = constant" clause references that
SubPlan; a hash join's hash keys and its hash clauses can both contain
it; and extract_restriction_or_clauses() can copy it into a new
restriction clause while leaving it in the original join clause. Each
reference gets its own SubPlanState, with its own hash tables, but
they all share the subplan's PlanState.

A hashed SubPlan whose subquery references outer query levels must
rebuild its hash tables whenever those parameters change.
ExecHashSubPlan() detected that by checking chgParam of the subplan's
PlanState. But buildSubPlanHash() rescans that PlanState, which
clears its chgParam, so after one SubPlanState had rebuilt its hash
tables, the others no longer saw the change and kept probing hash
tables built for previous parameter values, producing wrong query
results.

To fix, give each SubPlanState its own flag to mark its hash tables as
stale. ExecReScan() sets it, alongside propagating chgParam to the
node's subplans, ExecHashSubPlan() checks it instead of the subplan's
chgParam, and buildSubPlanHash() clears it. The new field fits into
existing padding in SubPlanState, so this does not change the struct's
size or the offsets of its other fields.

Reported-by: Samuel Olaoye <dapsalmy(at)gmail(dot)com>
Author: Rahul Yadav <rahul(at)rhyadav(dot)dev>
Reviewed-by: Alexandra Wang <alexandra(dot)wang(dot)oss(at)gmail(dot)com>
Reviewed-by: Richard Guo <guofenglinux(at)gmail(dot)com>
Reviewed-by: shihao zhong <zhong950419(at)gmail(dot)com>
Discussion: https://postgr.es/m/179087936257.78721.1170374394656748858@mail.gmail.com
Backpatch-through: 14

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/303c9b36205d11e41c7d5d61a1802ec50bccbf5a

Modified Files
--------------
src/backend/executor/execAmi.c | 7 +++++++
src/backend/executor/nodeSubplan.c | 5 +++--
src/include/nodes/execnodes.h | 1 +
src/test/regress/expected/subselect.out | 33 +++++++++++++++++++++++++++++++++
src/test/regress/sql/subselect.sql | 13 +++++++++++++
5 files changed, 57 insertions(+), 2 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Michael Paquier 2026-11-02 06:21:01 pgsql: Delay checkpoint start in RecordTransactionAbortPrepared()
Previous Message Tom Lane 2026-11-02 01:46:16 pgsql: Fix double-free when XMLSERIALIZE(... INDENT) output exceeds 1GB