Hi,

Dean raised a comment on my patch [1] about RETURNING processing for UPDATE ... 
FOR PORTION OF. While addressing that comment, I found a new problem: 
UPDATE/DELETE ... FOR PORTION OF currently processes RETURNING for leftover 
rows as well, which seems wrong because it can cause unexpected side effects.

Here is a simple repro using a sequence:
```
evantest=# create sequence s;
CREATE SEQUENCE
evantest=# create table t (r int4range, val int);
CREATE TABLE
evantest=# insert into t values ('[1,4)', 0);
INSERT 0 1
evantest=# update t for portion of r from 2 to 3 set val=1 returning 
nextval('s') as n;
 n
---
 3
(1 row)

UPDATE 1
evantest=# select last_value from s;
 last_value
------------
          3
(1 row)
```

The UPDATE FOR PORTION OF command generates two leftover rows, and both cause 
RETURNING to be processed. As a result, the sequence is advanced three times, 
which seems unexpected from the user's perspective.

To fix the problem, since leftover rows are inserted by calling ExecInsert(), 
and ExecInsert() is a local static function, I think a simple and safe solution 
is to add a new parameter to ExecInsert() to indicate whether to process 
RETURNING for this insert. Then UPDATE/DELETE FOR PORTION OF can bypass 
RETURNING processing for leftover rows.

See the attached patch for details.

[1] https://postgr.es/m/[email protected]

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/




Attachment: v1-0001-Avoid-RETURNING-side-effects-for-FOR-PORTION-OF-l.patch
Description: Binary data

Reply via email to