aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/primnodes.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-02-25 14:44:14 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-02-25 14:44:14 -0500
commita033f9165c2c024756d9cd3033263724d53fd9ef (patch)
tree17e147c607060fdac85ecfbfa51ec65d8c642964 /src/include/nodes/primnodes.h
parent8e5b4e0013a8a24644243cdb9516ac52287a81c8 (diff)
downloadpostgresql-a033f9165c2c024756d9cd3033263724d53fd9ef.tar.gz
postgresql-a033f9165c2c024756d9cd3033263724d53fd9ef.zip
Fix MULTIEXPR_SUBLINK with partitioned target tables, yet again.
We already tried to fix this in commits 3f7323cbb et al (and follow-on fixes), but now it emerges that there are still unfixed cases; moreover, these cases affect all branches not only pre-v14. I thought we had eliminated all cases of making multiple clones of an UPDATE's target list when we nuked inheritance_planner. But it turns out we still do that in some partitioned-UPDATE cases, notably including INSERT ... ON CONFLICT UPDATE, because ExecInitPartitionInfo thinks it's okay to clone and modify the parent's targetlist. This fix is based on a suggestion from Andres Freund: let's stop abusing the ParamExecData.execPlan mechanism, which was only ever meant to handle initplans, and instead solve the execution timing problem by having the expression compiler move MULTIEXPR_SUBLINK steps to the front of their expression step lists. This is feasible because (a) all branches still in support compile the entire targetlist of an UPDATE into a single ExprState, and (b) we know that all MULTIEXPR_SUBLINKs do need to be evaluated --- none could be buried inside a CASE, for example. There is a minor semantics change concerning the order of execution of the MULTIEXPR's subquery versus other parts of the parent targetlist, but that seems like something we can get away with. By doing that, we no longer need to worry about whether different clones of a MULTIEXPR_SUBLINK share output Params; their usage of that data structure won't overlap. Per bug #17800 from Alexander Lakhin. Back-patch to all supported branches. In v13 and earlier, we can revert 3f7323cbb and follow-on fixes; however, I chose to keep the SubPlan.subLinkId field added in ccbb54c72. We don't need that anymore in the core code, but it's cheap enough to fill, and removing a plan node field in a minor release seems like it'd be asking for trouble. Andres Freund and Tom Lane Discussion: https://postgr.es/m/17800-ff90866b3906c964@postgresql.org
Diffstat (limited to 'src/include/nodes/primnodes.h')
-rw-r--r--src/include/nodes/primnodes.h10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 3d48dbb4bd9..80ecf6c142f 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -732,9 +732,9 @@ typedef struct SubLink
* The values are assigned to the global PARAM_EXEC params indexed by parParam
* (the parParam and args lists must have the same ordering). setParam is a
* list of the PARAM_EXEC params that are computed by the sub-select, if it
- * is an initplan; they are listed in order by sub-select output column
- * position. (parParam and setParam are integer Lists, not Bitmapsets,
- * because their ordering is significant.)
+ * is an initplan or MULTIEXPR plan; they are listed in order by sub-select
+ * output column position. (parParam and setParam are integer Lists, not
+ * Bitmapsets, because their ordering is significant.)
*
* Also, the planner computes startup and per-call costs for use of the
* SubPlan. Note that these include the cost of the subquery proper,
@@ -767,8 +767,8 @@ typedef struct SubPlan
/* Note: parallel_safe does not consider contents of testexpr or args */
/* Information for passing params into and out of the subselect: */
/* setParam and parParam are lists of integers (param IDs) */
- List *setParam; /* initplan subqueries have to set these
- * Params for parent plan */
+ List *setParam; /* initplan and MULTIEXPR subqueries have to
+ * set these Params for parent plan */
List *parParam; /* indices of input Params from parent plan */
List *args; /* exprs to pass as parParam values */
/* Estimated execution costs: */