diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-02-25 14:44:14 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-02-25 14:44:14 -0500 |
commit | a033f9165c2c024756d9cd3033263724d53fd9ef (patch) | |
tree | 17e147c607060fdac85ecfbfa51ec65d8c642964 /src/include/nodes/primnodes.h | |
parent | 8e5b4e0013a8a24644243cdb9516ac52287a81c8 (diff) | |
download | postgresql-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.h | 10 |
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: */ |