> On May 7, 2026, at 13:54, Chao Li <[email protected]> wrote:
>
>
>
>> On May 7, 2026, at 12:34, Chao Li <[email protected]> wrote:
>>
>>
>>
>>> On May 7, 2026, at 01:13, Paul A Jungwirth <[email protected]>
>>> wrote:
>>>
>>> On Wed, May 6, 2026 at 4:39 AM Peter Eisentraut <[email protected]>
>>> wrote:
>>>>
>>>> On 05.05.26 23:50, Paul A Jungwirth wrote:
>>>>> On Wed, Apr 22, 2026 at 11:03 AM Paul A Jungwirth
>>>>> <[email protected]> wrote:
>>>>>>
>>>>>> Good catch! I removed that line in v7 (attached). I also included your
>>>>>> test change to compute the range len by hand. Also a rebase was
>>>>>> necessary after d3bba04154.
>>>>>
>>>>> This needed a rebase. v8 attached.
>>>>
>>>> This patch fails the injection_points/isolation test for me. It looks
>>>> like it causes a server crash. Check please.
>>>
>>> Sorry, I didn't have injection_points enabled, but now I see it too.
>>> The attached v9 fixes it.
>>>
>>> Yours,
>>>
>>> --
>>> Paul ~{:-)
>>> [email protected]
>>> <v9-0001-Fix-some-problems-with-UPDATE-FOR-PORTION-OF.patch>
>>
>> Hi Paul,
>>
>> I didn’t review this patch earlier because, from the subject, I thought it
>> was only about recomputing generated stored columns. I just noticed that the
>> patch also changes the inheritance-table path, and I posted another patch
>> for the inheritance-table bug. Please see [1].
>>
>> I tried applying the new tests from my patch on top of this patch, and it
>> looks like this patch still does not fix the multi-inheritance case.
>>
>> So I’d like to check with you how we should proceed. I think there are two
>> options:
>>
>> 1. Keep this patch focused on the generated-column issue described in the
>> subject, and use my patch to fix the inheritance-table bug.
>> 2. I can continue from this patch and extend it to fix the multi-inheritance
>> case as well.
>>
>> Please let me know what you prefer.
>>
>> [1]
>> https://www.postgresql.org/message-id/4245F94D-84F1-4E05-BF81-C458A6CF9901%40gmail.com
>>
>
> I just looked into v9 and made a fix in ExecInitForPortionOf() that resolves
> the bug with multi-inheritance tables. I also added a test case for that.
>
> The inheritance-table bug affects not only UPDATE, but also DELETE, so I
> added test cases for DELETE as well. Please see 0002 for my changes.
>
> To make each commit self-contained, would you mind moving the code for the
> inheritance-table fix to 0002? Then you can keep focusing on 0001, and I can
> continue working on 0002.
>
> PFA v10 - 0001 the same as v9. 0002 fixed a bug with multi-inheritance tables.
>
> (Note, in 0002, there is a comment format change around line 1496, that was
> done by pgindent.)
>
> Best regards,
> --
> Chao Li (Evan)
> HighGo Software Co., Ltd.
> https://www.highgo.com/
>
>
>
>
> <v10-0001-Fix-some-problems-with-UPDATE-FOR-PORTION-OF.patch><v10-0002-Fix-FOR-PORTION-OF-on-inherited-children-with-di.patch>
A few comments for 0001:
1 - execUtils.c
```
+ updatedCols = perminfo->updatedCols;
+
/* Map the columns to child's attribute numbers if needed. */
if (relinfo->ri_RootResultRelInfo)
{
TupleConversionMap *map = ExecGetRootToChildMap(relinfo,
estate);
if (map)
- return execute_attr_map_cols(map->attrMap,
perminfo->updatedCols);
+ updatedCols = execute_attr_map_cols(map->attrMap,
updatedCols);
+ }
+
+ /*
+ * 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 manualy
+ * add it to updatedCols. Since ri_forPortionOf->fp_rangeAttno is
already
+ * mapped for the child partition, we have to add it after the mapping
just
+ * above. Also that makes it unsafe to mutate perminfo. XXX: Always add
the
+ * unmapped attno instead (before mapping), and mutate perminfo, to
avoid
+ * repeated allocations?
+ */
+ if (relinfo->ri_forPortionOf)
+ {
+ AttrNumber rangeAttno =
relinfo->ri_forPortionOf->fp_rangeAttno;
+
+ if (!bms_is_member(rangeAttno -
FirstLowInvalidHeapAttributeNumber,
+ updatedCols))
+ {
+ MemoryContext oldContext;
+
+ oldContext =
MemoryContextSwitchTo(estate->es_query_cxt);
+
+ updatedCols =
+ bms_add_member(updatedCols,
+ rangeAttno -
FirstLowInvalidHeapAttributeNumber);
```
The comment explicitly says that it is unsafe to mutate perminfo, but
bms_add_member() does not always allocate a new bitmapset. So if updatedCols
still points to perminfo->updatedCols, then bms_add_member() may mutate
perminfo->updatedCols.
To verify that, I added Assert(updatedCols != perminfo->updatedCols); right
after the bms_add_member(), then ran "make check". A lot of tests failed, which
seems to confirm that perminfo->updatedCols was being mutated.
So, I think we should make a copy the bitmapset before bms_add_member when
needed, to make sure perminfo is not mutated, something like:
```
if (updatedCols == perminfo->updatedCols)
updatedCols = bms_copy(updatedCols);
updatedCols =
bms_add_member(updatedCols,
rangeAttno -
FirstLowInvalidHeapAttributeNumber);
```
2 - execUtils.c
```
+ * because the user does not need UPDATE permission on it. Now manualy
```
Typo: manualy -> manually
3 - nodeModifyTable.c
```
+ /*
+ * If we don't have a ForPortionOfState yet, we must be a
partition
+ * child being hit for the first time. Make a copy from the
root, with
+ * our own TupleTableSlot. We do this lazily so that we don't
pay the
+ * price of unused partitions.
+ */
+ if ((((ModifyTable *) context.mtstate->ps.plan)->forPortionOf)
&&
+ !resultRelInfo->ri_forPortionOf)
+ {
+ ExecInitForPortionOf(context.mtstate, estate,
resultRelInfo);
+ }
```
I think this comment is stale. It could be a partition child or an inheritance
child.
4 - nodeModifyTable.c
```
+ /* Each partition needs a slot matching its tuple descriptor */
+ leafState->fp_Existing =
+ table_slot_create(resultRelInfo->ri_RelationDesc,
+
&mtstate->ps.state->es_tupleTable);
```
I think the comment should say "each child relation" rather than "each
partition".
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/