From 222056ec0ce0374fcaa9f64ac73ec0896ac979c2 Mon Sep 17 00:00:00 2001 From: jian he Date: Fri, 17 Apr 2026 16:03:44 +0800 Subject: [PATCH v4 1/1] add UPDATE FOR PORTION OF col to ExecGetUpdatedCols Discussion: https://postgr.es/m/CAHg+QDcd=t69gLf9yQexO07EJ2mx0Z70NFHo6h94X1EDA=hM0g@mail.gmail.com Discussion: https://postgr.es/m/CAHg+QDcsXsUVaZ+JwM02yDRQEi=cL_rTH_ROLDYgOx004sQu7A@mail.gmail.com --- src/backend/executor/execUtils.c | 47 ++++++++++++++------------ src/backend/executor/nodeModifyTable.c | 15 -------- 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 5df7f2edf85..2c0ab1c0214 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -1412,6 +1412,31 @@ ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate) if (perminfo == NULL) return NULL; + /* + * For UPDATE ... FOR PORTION OF, the range column is being modified + * (narrowed via intersection), but it is not included in updatedCols + * because the user does not need UPDATE permission on it. Now mannualy + * add it to updatedCols. + */ + if (relinfo->ri_forPortionOf) + { + AttrNumber rangeAttno = relinfo->ri_forPortionOf->fp_rangeAttno; + + if (!bms_is_member(rangeAttno - FirstLowInvalidHeapAttributeNumber, + perminfo->updatedCols)) + { + MemoryContext oldContext; + + oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + + perminfo->updatedCols = + bms_add_member(perminfo->updatedCols, + rangeAttno - FirstLowInvalidHeapAttributeNumber); + + MemoryContextSwitchTo(oldContext); + } + } + /* Map the columns to child's attribute numbers if needed. */ if (relinfo->ri_RootResultRelInfo) { @@ -1430,29 +1455,7 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate) { /* Compute the info if we didn't already */ if (!relinfo->ri_extraUpdatedCols_valid) - { - if (relinfo->ri_forPortionOf) - { - MemoryContext oldContext; - - AttrNumber rangeAttno = relinfo->ri_forPortionOf->fp_rangeAttno; - - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); - - /* - * For UPDATE ... FOR PORTION OF, the range column is actually - * being modified (narrowed via intersection), but it is not - * included in updatedCols because the user does not need UPDATE - * permission on it. So we need to add it to ri_extraUpdatedCols - */ - relinfo->ri_extraUpdatedCols = - bms_add_member(relinfo->ri_extraUpdatedCols, rangeAttno - FirstLowInvalidHeapAttributeNumber); - - MemoryContextSwitchTo(oldContext); - } - ExecInitGenerated(relinfo, estate, CMD_UPDATE); - } return relinfo->ri_extraUpdatedCols; } diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 4395089565f..7af0268646b 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -477,21 +477,6 @@ ExecInitGenerated(ResultRelInfo *resultRelInfo, else updatedCols = NULL; - /* - * For UPDATE ... FOR PORTION OF, the range column is also being modified - * (narrowed via intersection), but it is not included in updatedCols - * because the user does not need UPDATE permission on it. We must - * account for it here so that generated columns referencing the range - * column are recomputed. - */ - if (resultRelInfo->ri_forPortionOf) - { - AttrNumber rangeAttno = resultRelInfo->ri_forPortionOf->fp_rangeAttno; - - updatedCols = bms_add_member(bms_copy(updatedCols), - rangeAttno - FirstLowInvalidHeapAttributeNumber); - } - /* * Make sure these data structures are built in the per-query memory * context so they'll survive throughout the query. -- 2.34.1