mirror of
https://github.com/postgres/postgres.git
synced 2025-11-04 20:11:56 +03:00
Fix some more cases of missed GENERATED-column updates.
If UPDATE is forced to retry after an EvalPlanQual check, it neglected to repeat GENERATED-column computations, even though those might well have changed since we're dealing with a different tuple than before. Fixing this is mostly a matter of looping back a bit further when we retry. In v15 and HEAD that's most easily done by altering the API of ExecUpdateAct so that it includes computing GENERATED expressions. Also, if an UPDATE in a partitioned table turns into a cross-partition INSERT operation, we failed to recompute GENERATED columns. That's a bug since8bf6ec3baallowed partitions to have different generation expressions; although it seems to have no ill effects before that. Fixing this is messier because we can now have situations where the same query needs both the UPDATE-aligned set of GENERATED columns and the INSERT-aligned set, and it's unclear which set will be generated first (else we could hack things by forcing the INSERT-aligned set to be generated, which is indeed howfe9e658f4made it work for MERGE). The best fix seems to be to build and store separate sets of expressions for the INSERT and UPDATE cases. That would create ABI issues in the back branches, but so far it seems we can leave this alone in the back branches. Per bug #17823 from Hisahiro Kauchi. The first part of this affects all branches back to v12 where GENERATED columns were added. Discussion: https://postgr.es/m/17823-b64909cf7d63de84@postgresql.org
This commit is contained in:
@@ -462,7 +462,7 @@ typedef struct ResultRelInfo
|
||||
*/
|
||||
AttrNumber ri_RowIdAttNo;
|
||||
|
||||
/* For INSERT/UPDATE, attnums of generated columns to be computed */
|
||||
/* For UPDATE, attnums of generated columns to be computed */
|
||||
Bitmapset *ri_extraUpdatedCols;
|
||||
|
||||
/* Projection to generate new tuple in an INSERT/UPDATE */
|
||||
@@ -516,11 +516,13 @@ typedef struct ResultRelInfo
|
||||
/* array of constraint-checking expr states */
|
||||
ExprState **ri_ConstraintExprs;
|
||||
|
||||
/* array of stored generated columns expr states */
|
||||
ExprState **ri_GeneratedExprs;
|
||||
/* arrays of stored generated columns expr states, for INSERT and UPDATE */
|
||||
ExprState **ri_GeneratedExprsI;
|
||||
ExprState **ri_GeneratedExprsU;
|
||||
|
||||
/* number of stored generated columns we need to compute */
|
||||
int ri_NumGeneratedNeeded;
|
||||
int ri_NumGeneratedNeededI;
|
||||
int ri_NumGeneratedNeededU;
|
||||
|
||||
/* list of RETURNING expressions */
|
||||
List *ri_returningList;
|
||||
|
||||
Reference in New Issue
Block a user