Don't use SubPlan-containing expressions for startup-time pruning

match_clause_to_partition_key() tells whether a comparison value can
be evaluated during executor-startup pruning by checking that it has
no Vars, no volatile functions and no PARAM_EXEC Params.  A SubPlan
normally fails the last test, since the testexpr of an ANY/ALL SubPlan
references the subplan's output Params.  But if the left-hand side is
a NULL constant, the strict comparison operator in the testexpr is
const-folded to a NULL Const, and an uncorrelated SubPlan has no
parParam or args either, so nothing is left for pull_exec_paramids()
to find.  The expression then reaches initial_pruning_steps, where
ExecDoInitialPruning() must evaluate it before any PlanState exists,
and we fail with "SubPlan found with no parent plan".

To fix, don't allow such an expression to be used for startup-time
pruning.  It's still fine for per-scan pruning, which has a PlanState
to evaluate it with.  Expressions containing exec Params are
unaffected.

This has been broken since d47cbf474, which moved initial pruning out
of ExecInitNode(); before that, pruning always had the parent node's
PlanState available.  Back-patch to v18.

Author: Richard Guo <[email protected]>
Reviewed-by: Amit Langote <[email protected]>
Discussion: 
https://postgr.es/m/cambws48nydu7joyeymkydx8khol_aseax2fqzh6l+hhqo2n...@mail.gmail.com
Backpatch-through: 18

Branch
------
REL_18_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/70ffc30e12b1de43d6160682fc44c78b8de00f24

Modified Files
--------------
src/backend/partitioning/partprune.c          | 12 +++++++++++-
src/test/regress/expected/partition_prune.out | 16 ++++++++++++++++
src/test/regress/sql/partition_prune.sql      |  6 ++++++
3 files changed, 33 insertions(+), 1 deletion(-)

Reply via email to