Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitecbdd00

Browse files
committed
Fix system column accesses in ON CONFLICT ... RETURNING.
After277cb78 ON CONFLICT ... SET ... RETURNING failed withERROR: virtual tuple table slot does not have system attributeswhen taking the update path, as the slot used to insert into thetable (and then process RETURNING) was defined to be a virtual slot inthat commit. Virtual slots don't support system columns except fortableoid and ctid, as the other system columns are AM dependent.Fix that by using a slot of the table's type. Add tests for systemcolumn accesses in ON CONFLICT ... RETURNING.Reported-By: Roby, bisected to the relevant commit by Jeff JanesAuthor: Andres FreundDiscussion:https://postgr.es/m/73436355-6432-49B1-92ED-1FE4F7E7E100@finefun.com.auBackpatch: 12-, where the bug was introduced in277cb78
1 parentc8e177f commitecbdd00

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

‎src/backend/executor/nodeModifyTable.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,11 +2542,16 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
25422542
table_slot_create(resultRelInfo->ri_RelationDesc,
25432543
&mtstate->ps.state->es_tupleTable);
25442544

2545-
/* create the tuple slot for the UPDATE SET projection */
2545+
/*
2546+
* Create the tuple slot for the UPDATE SET projection. We want a slot
2547+
* of the table's type here, because the slot will be used to insert
2548+
* into the table, and for RETURNING processing - which may access
2549+
* system attributes.
2550+
*/
25462551
tupDesc=ExecTypeFromTL((List*)node->onConflictSet);
25472552
resultRelInfo->ri_onConflict->oc_ProjSlot=
25482553
ExecInitExtraTupleSlot(mtstate->ps.state,tupDesc,
2549-
&TTSOpsVirtual);
2554+
table_slot_callbacks(resultRelInfo->ri_RelationDesc));
25502555

25512556
/* build UPDATE SET projection state */
25522557
resultRelInfo->ri_onConflict->oc_ProjInfo=

‎src/test/regress/expected/update.out

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,29 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
227227
1 | Foo, Correlated, Excluded
228228
(1 row)
229229

230+
-- ON CONFLICT using system attributes in RETURNING, testing both the
231+
-- inserting and updating paths. See bug report at:
232+
-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au
233+
CREATE FUNCTION xid_current() RETURNS xid LANGUAGE SQL AS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$;
234+
INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a)
235+
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
236+
RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = 0 AS xmax_correct;
237+
tableoid | xmin_correct | xmax_correct
238+
-------------+--------------+--------------
239+
upsert_test | t | t
240+
(1 row)
241+
242+
-- currently xmax is set after a conflict - that's probably not good,
243+
-- but it seems worthwhile to have to be explicit if that changes.
244+
INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a)
245+
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
246+
RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = xid_current() AS xmax_correct;
247+
tableoid | xmin_correct | xmax_correct
248+
-------------+--------------+--------------
249+
upsert_test | t | t
250+
(1 row)
251+
252+
DROP FUNCTION xid_current();
230253
DROP TABLE update_test;
231254
DROP TABLE upsert_test;
232255
---------------------------

‎src/test/regress/sql/update.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
114114
DOUPDATESET (b, a)= (SELECT b||', Excluded', afrom upsert_test iWHEREi.a=excluded.a)
115115
RETURNING*;
116116

117+
-- ON CONFLICT using system attributes in RETURNING, testing both the
118+
-- inserting and updating paths. See bug report at:
119+
-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au
120+
CREATEFUNCTIONxid_current() RETURNS xid LANGUAGE SQLAS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$;
121+
INSERT INTO upsert_testVALUES (2,'Beeble')ON CONFLICT(a)
122+
DOUPDATESET (b, a)= (SELECT b||', Excluded', afrom upsert_test iWHEREi.a=excluded.a)
123+
RETURNING tableoid::regclass, xmin= xid_current()AS xmin_correct, xmax=0AS xmax_correct;
124+
-- currently xmax is set after a conflict - that's probably not good,
125+
-- but it seems worthwhile to have to be explicit if that changes.
126+
INSERT INTO upsert_testVALUES (2,'Brox')ON CONFLICT(a)
127+
DOUPDATESET (b, a)= (SELECT b||', Excluded', afrom upsert_test iWHEREi.a=excluded.a)
128+
RETURNING tableoid::regclass, xmin= xid_current()AS xmin_correct, xmax= xid_current()AS xmax_correct;
129+
130+
131+
DROPFUNCTION xid_current();
117132
DROPTABLE update_test;
118133
DROPTABLE upsert_test;
119134

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp