Skip to content

Commit 90586ef

Browse files
committed
Fix ON CONFLICT DO UPDATE for tables with oids.
When taking the UPDATE path in an INSERT .. ON CONFLICT .. UPDATE tables with oids were not supported. The tuple generated by the update target list was projected without space for an oid - a simple oversight. Reported-By: Peter Geoghegan Author: Andres Freund Backpatch: 9.5, where ON CONFLICT was introduced
1 parent 80e2694 commit 90586ef

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

src/backend/executor/nodeModifyTable.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
16781678

16791679
/* create target slot for UPDATE SET projection */
16801680
tupDesc = ExecTypeFromTL((List *) node->onConflictSet,
1681-
false);
1681+
resultRelInfo->ri_RelationDesc->rd_rel->relhasoids);
16821682
mtstate->mt_conflproj = ExecInitExtraTupleSlot(mtstate->ps.state);
16831683
ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc);
16841684

src/test/regress/expected/insert_conflict.out

+59
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,62 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET
507507

508508
-- clean up
509509
drop table excluded;
510+
-- Check tables w/o oids are handled correctly
511+
create table testoids(key int primary key, data text) without oids;
512+
-- first without oids
513+
insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *;
514+
key | data
515+
-----+------
516+
1 | 1
517+
(1 row)
518+
519+
insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
520+
key | data
521+
-----+------
522+
1 | 2
523+
(1 row)
524+
525+
-- add oids
526+
alter table testoids set with oids;
527+
-- update existing row, that didn't have an oid
528+
insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *;
529+
key | data
530+
-----+------
531+
1 | 3
532+
(1 row)
533+
534+
-- insert a new row
535+
insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *;
536+
key | data
537+
-----+------
538+
2 | 1
539+
(1 row)
540+
541+
-- and update it
542+
insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *;
543+
key | data
544+
-----+------
545+
2 | 2
546+
(1 row)
547+
548+
-- remove oids again, test
549+
alter table testoids set without oids;
550+
insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *;
551+
key | data
552+
-----+------
553+
1 | 4
554+
(1 row)
555+
556+
insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *;
557+
key | data
558+
-----+------
559+
3 | 1
560+
(1 row)
561+
562+
insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *;
563+
key | data
564+
-----+------
565+
3 | 2
566+
(1 row)
567+
568+
DROP TABLE testoids;

src/test/regress/sql/insert_conflict.sql

+22
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,25 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET
295295

296296
-- clean up
297297
drop table excluded;
298+
299+
300+
-- Check tables w/o oids are handled correctly
301+
create table testoids(key int primary key, data text) without oids;
302+
-- first without oids
303+
insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *;
304+
insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
305+
-- add oids
306+
alter table testoids set with oids;
307+
-- update existing row, that didn't have an oid
308+
insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *;
309+
-- insert a new row
310+
insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *;
311+
-- and update it
312+
insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *;
313+
-- remove oids again, test
314+
alter table testoids set without oids;
315+
insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *;
316+
insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *;
317+
insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *;
318+
319+
DROP TABLE testoids;

0 commit comments

Comments
 (0)