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

Commit168d580

Browse files
committed
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative toraising a unique or exclusion constraint violation error when inserting.ON CONFLICT refers to constraints that can either be specified using ainference clause (by specifying the columns of a unique constraint) orby naming a unique or exclusion constraint. DO NOTHING avoids theconstraint violation, without touching the pre-existing row. DO UPDATESET ... [WHERE ...] updates the pre-existing tuple, and has access toboth the tuple proposed for insertion and the existing tuple; theoptional WHERE clause can be used to prevent an update from beingexecuted. The UPDATE SET and WHERE clauses have access to the tupleproposed for insertion using the "magic" EXCLUDED alias, and to thepre-existing tuple using the table name or its alias.This feature is often referred to as upsert.This is implemented using a new infrastructure called "speculativeinsertion". It is an optimistic variant of regular insertion that firstdoes a pre-check for existing tuples and then attempts an insert. If aviolating tuple was inserted concurrently, the speculatively insertedtuple is deleted and a new attempt is made. If the pre-check finds amatching tuple the alternative DO NOTHING or DO UPDATE action is taken.If the insertion succeeds without detecting a conflict, the tuple isdeemed inserted.To handle the possible ambiguity between the excluded alias and a tablenamed excluded, and for convenience with long relation names, INSERTINTO now can alias its target table.Bumps catversion as stored rules change.Author: Peter Geoghegan, with significant contributions from Heikki Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs, Dean Rasheed, Stephen Frost and many others.
1 parent2c8f483 commit168d580

File tree

122 files changed

+6106
-435
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+6106
-435
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,6 +2264,7 @@ JumbleQuery(pgssJumbleState *jstate, Query *query)
22642264
JumbleRangeTable(jstate,query->rtable);
22652265
JumbleExpr(jstate, (Node*)query->jointree);
22662266
JumbleExpr(jstate, (Node*)query->targetList);
2267+
JumbleExpr(jstate, (Node*)query->onConflict);
22672268
JumbleExpr(jstate, (Node*)query->returningList);
22682269
JumbleExpr(jstate, (Node*)query->groupClause);
22692270
JumbleExpr(jstate,query->havingQual);
@@ -2631,6 +2632,16 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
26312632
APP_JUMB(ce->cursor_param);
26322633
}
26332634
break;
2635+
caseT_InferenceElem:
2636+
{
2637+
InferenceElem*ie= (InferenceElem*)node;
2638+
2639+
APP_JUMB(ie->infercollid);
2640+
APP_JUMB(ie->inferopfamily);
2641+
APP_JUMB(ie->inferopcinputtype);
2642+
JumbleExpr(jstate,ie->expr);
2643+
}
2644+
break;
26342645
caseT_TargetEntry:
26352646
{
26362647
TargetEntry*tle= (TargetEntry*)node;
@@ -2667,6 +2678,20 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
26672678
JumbleExpr(jstate,from->quals);
26682679
}
26692680
break;
2681+
caseT_OnConflictExpr:
2682+
{
2683+
OnConflictExpr*conf= (OnConflictExpr*)node;
2684+
2685+
APP_JUMB(conf->action);
2686+
JumbleExpr(jstate, (Node*)conf->arbiterElems);
2687+
JumbleExpr(jstate,conf->arbiterWhere);
2688+
JumbleExpr(jstate, (Node*)conf->onConflictSet);
2689+
JumbleExpr(jstate,conf->onConflictWhere);
2690+
APP_JUMB(conf->constraint);
2691+
APP_JUMB(conf->exclRelIndex);
2692+
JumbleExpr(jstate, (Node*)conf->exclRelTlist);
2693+
}
2694+
break;
26702695
caseT_List:
26712696
foreach(temp, (List*)node)
26722697
{

‎contrib/postgres_fdw/deparse.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,8 @@ appendWhereClause(StringInfo buf,
847847
void
848848
deparseInsertSql(StringInfobuf,PlannerInfo*root,
849849
Indexrtindex,Relationrel,
850-
List*targetAttrs,List*returningList,
851-
List**retrieved_attrs)
850+
List*targetAttrs,booldoNothing,
851+
List*returningList,List**retrieved_attrs)
852852
{
853853
AttrNumberpindex;
854854
boolfirst;
@@ -892,6 +892,9 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root,
892892
else
893893
appendStringInfoString(buf," DEFAULT VALUES");
894894

895+
if (doNothing)
896+
appendStringInfoString(buf," ON CONFLICT DO NOTHING");
897+
895898
deparseReturningList(buf,root,rtindex,rel,
896899
rel->trigdesc&&rel->trigdesc->trig_insert_after_row,
897900
returningList,retrieved_attrs);

‎contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,11 @@ INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key
23272327
ERROR: duplicate key value violates unique constraint "t1_pkey"
23282328
DETAIL: Key ("C 1")=(11) already exists.
23292329
CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
2330+
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works
2331+
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported
2332+
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
2333+
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported
2334+
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
23302335
INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive
23312336
ERROR: new row for relation "T 1" violates check constraint "c2positive"
23322337
DETAIL: Failing row contains (1111, -2, null, null, null, null, ft1 , null).

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,7 @@ postgresPlanForeignModify(PlannerInfo *root,
11711171
List*targetAttrs=NIL;
11721172
List*returningList=NIL;
11731173
List*retrieved_attrs=NIL;
1174+
booldoNothing= false;
11741175

11751176
initStringInfo(&sql);
11761177

@@ -1222,14 +1223,26 @@ postgresPlanForeignModify(PlannerInfo *root,
12221223
if (plan->returningLists)
12231224
returningList= (List*)list_nth(plan->returningLists,subplan_index);
12241225

1226+
/*
1227+
* ON CONFLICT DO UPDATE and DO NOTHING case with inference specification
1228+
* should have already been rejected in the optimizer, as presently there
1229+
* is no way to recognize an arbiter index on a foreign table. Only DO
1230+
* NOTHING is supported without an inference specification.
1231+
*/
1232+
if (plan->onConflictAction==ONCONFLICT_NOTHING)
1233+
doNothing= true;
1234+
elseif (plan->onConflictAction!=ONCONFLICT_NONE)
1235+
elog(ERROR,"unexpected ON CONFLICT specification: %d",
1236+
(int)plan->onConflictAction);
1237+
12251238
/*
12261239
* Construct the SQL command string.
12271240
*/
12281241
switch (operation)
12291242
{
12301243
caseCMD_INSERT:
12311244
deparseInsertSql(&sql,root,resultRelation,rel,
1232-
targetAttrs,returningList,
1245+
targetAttrs,doNothing,returningList,
12331246
&retrieved_attrs);
12341247
break;
12351248
caseCMD_UPDATE:

‎contrib/postgres_fdw/postgres_fdw.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extern void appendWhereClause(StringInfo buf,
6060
List**params);
6161
externvoiddeparseInsertSql(StringInfobuf,PlannerInfo*root,
6262
Indexrtindex,Relationrel,
63-
List*targetAttrs,List*returningList,
63+
List*targetAttrs,booldoNothing,List*returningList,
6464
List**retrieved_attrs);
6565
externvoiddeparseUpdateSql(StringInfobuf,PlannerInfo*root,
6666
Indexrtindex,Relationrel,

‎contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@ UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *;
372372
ALTERTABLE"S 1"."T 1" ADDCONSTRAINT c2positiveCHECK (c2>=0);
373373

374374
INSERT INTO ft1(c1, c2)VALUES(11,12);-- duplicate key
375+
INSERT INTO ft1(c1, c2)VALUES(11,12)ON CONFLICT DO NOTHING;-- works
376+
INSERT INTO ft1(c1, c2)VALUES(11,12)ON CONFLICT (c1, c2) DO NOTHING;-- unsupported
377+
INSERT INTO ft1(c1, c2)VALUES(11,12)ON CONFLICT (c1, c2) DOUPDATESET c3='ffg';-- unsupported
375378
INSERT INTO ft1(c1, c2)VALUES(1111,-2);-- c2positive
376379
UPDATE ft1SET c2=-c2WHERE c1=1;-- c2positive
377380

‎contrib/test_decoding/expected/ddl.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,24 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
148148
COMMIT
149149
(9 rows)
150150

151+
-- ON CONFLICT DO UPDATE support
152+
BEGIN;
153+
INSERT INTO replication_example(id, somedata, somenum) SELECT i, i, i FROM generate_series(-15, 15) i
154+
ON CONFLICT (id) DO UPDATE SET somenum = excluded.somenum + 1;
155+
COMMIT;
156+
/* display results, but hide most of the output */
157+
SELECT count(*), min(data), max(data)
158+
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
159+
GROUP BY substring(data, 1, 40)
160+
ORDER BY 1,2;
161+
count | min | max
162+
-------+----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------
163+
1 | BEGIN | BEGIN
164+
1 | COMMIT | COMMIT
165+
15 | table public.replication_example: UPDATE: id[integer]:10 somedata[integer]:4 somenum[integer]:11 zaphod1[integer]:null zaphod2[integer]:null | table public.replication_example: UPDATE: id[integer]:9 somedata[integer]:3 somenum[integer]:10 zaphod1[integer]:null zaphod2[integer]:null
166+
16 | table public.replication_example: INSERT: id[integer]:0 somedata[integer]:0 somenum[integer]:0 zaphod1[integer]:null zaphod2[integer]:null | table public.replication_example: INSERT: id[integer]:-9 somedata[integer]:-9 somenum[integer]:-9 zaphod1[integer]:null zaphod2[integer]:null
167+
(4 rows)
168+
151169
-- hide changes bc of oid visible in full table rewrites
152170
CREATE TABLE tr_unique(id2 serial unique NOT NULL, data int);
153171
INSERT INTO tr_unique(data) VALUES(10);
@@ -196,6 +214,22 @@ ORDER BY 1,2;
196214
20467 | table public.tr_etoomuch: DELETE: id[integer]:1 | table public.tr_etoomuch: UPDATE: id[integer]:9999 data[integer]:-9999
197215
(3 rows)
198216

217+
-- check that a large, spooled, upsert works
218+
INSERT INTO tr_etoomuch (id, data)
219+
SELECT g.i, -g.i FROM generate_series(8000, 12000) g(i)
220+
ON CONFLICT(id) DO UPDATE SET data = EXCLUDED.data;
221+
SELECT substring(data, 1, 29), count(*)
222+
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
223+
GROUP BY 1
224+
ORDER BY min(location - '0/0');
225+
substring | count
226+
-------------------------------+-------
227+
BEGIN | 1
228+
table public.tr_etoomuch: UPD | 2235
229+
table public.tr_etoomuch: INS | 1766
230+
COMMIT | 1
231+
(4 rows)
232+
199233
/*
200234
* check whether we decode subtransactions correctly in relation with each
201235
* other

‎contrib/test_decoding/expected/toast.out

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ INSERT INTO xpto (toasted_col2) SELECT repeat(string_agg(to_char(g.i, 'FM0000'),
2323
-- update of existing column
2424
UPDATE xpto SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i)) WHERE id = 1;
2525
UPDATE xpto SET rand1 = 123.456 WHERE id = 1;
26+
-- updating external via INSERT ... ON CONFLICT DO UPDATE
27+
INSERT INTO xpto(id, toasted_col2) VALUES (2, 'toasted2-upsert')
28+
ON CONFLICT (id)
29+
DO UPDATE SET toasted_col2 = EXCLUDED.toasted_col2 || xpto.toasted_col2;
2630
DELETE FROM xpto WHERE id = 1;
2731
DROP TABLE IF EXISTS toasted_key;
2832
NOTICE: table "toasted_key" does not exist, skipping
@@ -64,6 +68,9 @@ SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot',
6468
table public.xpto: UPDATE: id[integer]:1 toasted_col1[text]:unchanged-toast-datum rand1[double precision]:123.456 toasted_col2[text]:unchanged-toast-datum rand2[double precision]:1578
6569
COMMIT
6670
BEGIN
71+
table public.xpto: UPDATE: id[integer]:2 toasted_col1[text]:null rand1[double precision]:3077 toasted_col2[text]:'toasted2-upsert00010002000300040005000600070008000900100011001200130014001500160017001
72+
COMMIT
73+
BEGIN
6774
table public.xpto: DELETE: id[integer]:1
6875
COMMIT
6976
BEGIN
@@ -283,7 +290,7 @@ SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot',
283290
table public.toasted_copy: INSERT: id[integer]:202 data[text]:'untoasted199'
284291
table public.toasted_copy: INSERT: id[integer]:203 data[text]:'untoasted200'
285292
COMMIT
286-
(232 rows)
293+
(235 rows)
287294

288295
SELECT pg_drop_replication_slot('regression_slot');
289296
pg_drop_replication_slot

‎contrib/test_decoding/sql/ddl.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ COMMIT;
8484
-- show changes
8585
SELECT dataFROM pg_logical_slot_get_changes('regression_slot',NULL,NULL,'include-xids','0','skip-empty-xacts','1');
8686

87+
-- ON CONFLICT DO UPDATE support
88+
BEGIN;
89+
INSERT INTO replication_example(id, somedata, somenum)SELECT i, i, iFROM generate_series(-15,15) i
90+
ON CONFLICT (id) DOUPDATESET somenum=excluded.somenum+1;
91+
COMMIT;
92+
93+
/* display results, but hide most of the output*/
94+
SELECTcount(*),min(data),max(data)
95+
FROM pg_logical_slot_get_changes('regression_slot',NULL,NULL,'include-xids','0','skip-empty-xacts','1')
96+
GROUP BYsubstring(data,1,40)
97+
ORDER BY1,2;
98+
8799
-- hide changes bc of oid visible in full table rewrites
88100
CREATETABLEtr_unique(id2serial uniqueNOT NULL, dataint);
89101
INSERT INTO tr_unique(data)VALUES(10);
@@ -114,6 +126,16 @@ FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids',
114126
GROUP BYsubstring(data,1,24)
115127
ORDER BY1,2;
116128

129+
-- check that a large, spooled, upsert works
130+
INSERT INTO tr_etoomuch (id, data)
131+
SELECTg.i,-g.iFROM generate_series(8000,12000) g(i)
132+
ON CONFLICT(id) DOUPDATESET data=EXCLUDED.data;
133+
134+
SELECTsubstring(data,1,29),count(*)
135+
FROM pg_logical_slot_get_changes('regression_slot',NULL,NULL,'include-xids','0','skip-empty-xacts','1')
136+
GROUP BY1
137+
ORDER BYmin(location-'0/0');
138+
117139
/*
118140
* check whether we decode subtransactions correctly in relation with each
119141
* other

‎contrib/test_decoding/sql/toast.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ UPDATE xpto SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_s
2525

2626
UPDATE xptoSET rand1=123.456WHERE id=1;
2727

28+
-- updating external via INSERT ... ON CONFLICT DO UPDATE
29+
INSERT INTO xpto(id, toasted_col2)VALUES (2,'toasted2-upsert')
30+
ON CONFLICT (id)
31+
DOUPDATESET toasted_col2=EXCLUDED.toasted_col2||xpto.toasted_col2;
32+
2833
DELETEFROM xptoWHERE id=1;
2934

3035
DROPTABLE IF EXISTS toasted_key;

‎doc/src/sgml/fdwhandler.sgml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,13 @@ GetForeignServerByName(const char *name, bool missing_ok);
10501050
source provides.
10511051
</para>
10521052

1053+
<para>
1054+
<command>INSERT</> with an <literal>ON CONFLICT</> clause does not
1055+
support specifying the conflict target, as remote constraints are not
1056+
locally known. This in turn implies that <literal>ON CONFLICT DO
1057+
UPDATE</> is not supported, since the specification is mandatory there.
1058+
</para>
1059+
10531060
</sect1>
10541061

10551062
</chapter>

‎doc/src/sgml/keywords.sgml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,13 @@
853853
<entry></entry>
854854
<entry></entry>
855855
</row>
856+
<row>
857+
<entry><token>CONFLICT</token></entry>
858+
<entry>non-reserved</entry>
859+
<entry></entry>
860+
<entry></entry>
861+
<entry></entry>
862+
</row>
856863
<row>
857864
<entry><token>CONNECT</token></entry>
858865
<entry></entry>

‎doc/src/sgml/mvcc.sgml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,27 @@
326326
</para>
327327

328328
<para>
329-
Because of the above rule, it is possible for an updating command to see an
330-
inconsistent snapshot: it can see the effects of concurrent updating
329+
<command>INSERT</command> with an <literal>ON CONFLICT DO UPDATE</> clause
330+
behaves similarly. In Read Committed mode, each row proposed for insertion
331+
will either insert or update. Unless there are unrelated errors, one of
332+
those two outcomes is guaranteed. If a conflict originates in another
333+
transaction whose effects are not yet visible to the <command>INSERT
334+
</command>, the <command>UPDATE</command> clause will affect that row,
335+
even though possibly <emphasis>no</> version of that row is
336+
conventionally visible to the command.
337+
</para>
338+
339+
<para>
340+
<command>INSERT</command> with an <literal>ON CONFLICT DO
341+
NOTHING</> clause may have insertion not proceed for a row due to
342+
the outcome of another transaction whose effects are not visible
343+
to the <command>INSERT</command> snapshot. Again, this is only
344+
the case in Read Committed mode.
345+
</para>
346+
347+
<para>
348+
Because of the above rules, it is possible for an updating command to see
349+
an inconsistent snapshot: it can see the effects of concurrent updating
331350
commands on the same rows it is trying to update, but it
332351
does not see effects of those commands on other rows in the database.
333352
This behavior makes Read Committed mode unsuitable for commands that

‎doc/src/sgml/plpgsql.sgml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,7 +2623,11 @@ END;
26232623
<para>
26242624

26252625
This example uses exception handling to perform either
2626-
<command>UPDATE</> or <command>INSERT</>, as appropriate:
2626+
<command>UPDATE</> or <command>INSERT</>, as appropriate. It is
2627+
recommended that applications use <command>INSERT</> with
2628+
<literal>ON CONFLICT DO UPDATE</> rather than actually using
2629+
this pattern. This example serves primarily to illustrate use of
2630+
<application>PL/pgSQL</application> control flow structures:
26272631

26282632
<programlisting>
26292633
CREATE TABLE db (a INT PRIMARY KEY, b TEXT);
@@ -3852,9 +3856,11 @@ ASSERT <replaceable class="parameter">condition</replaceable> <optional> , <repl
38523856
<command>INSERT</> and <command>UPDATE</> operations, the return value
38533857
should be <varname>NEW</>, which the trigger function may modify to
38543858
support <command>INSERT RETURNING</> and <command>UPDATE RETURNING</>
3855-
(this will also affect the row value passed to any subsequent triggers).
3856-
For <command>DELETE</> operations, the return value should be
3857-
<varname>OLD</>.
3859+
(this will also affect the row value passed to any subsequent triggers,
3860+
or passed to a special <varname>EXCLUDED</> alias reference within
3861+
an <command>INSERT</> statement with an <literal>ON CONFLICT DO
3862+
UPDATE</> clause). For <command>DELETE</> operations, the return
3863+
value should be <varname>OLD</>.
38583864
</para>
38593865

38603866
<para>

‎doc/src/sgml/postgres-fdw.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@
6868
in your user mapping must have privileges to do these things.)
6969
</para>
7070

71+
<para>
72+
Note that <filename>postgres_fdw</> currently lacks support for
73+
<command>INSERT</command> statements with an <literal>ON CONFLICT DO
74+
UPDATE</> clause. However, the <literal>ON CONFLICT DO NOTHING</>
75+
clause is supported, provided a unique index inference specification
76+
is omitted.
77+
</para>
78+
7179
<para>
7280
It is generally recommended that the columns of a foreign table be declared
7381
with exactly the same data types, and collations if applicable, as the

‎doc/src/sgml/protocol.sgml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,9 +2998,16 @@ CommandComplete (B)
29982998
<literal>INSERT <replaceable>oid</replaceable>
29992999
<replaceable>rows</replaceable></literal>, where
30003000
<replaceable>rows</replaceable> is the number of rows
3001-
inserted. <replaceable>oid</replaceable> is the object ID
3002-
of the inserted row if <replaceable>rows</replaceable> is 1
3003-
and the target table has OIDs;
3001+
inserted. However, if and only if <literal>ON CONFLICT
3002+
UPDATE</> is specified, then the tag is <literal>UPSERT
3003+
<replaceable>oid</replaceable>
3004+
<replaceable>rows</replaceable></literal>, where
3005+
<replaceable>rows</replaceable> is the number of rows inserted
3006+
<emphasis>or updated</emphasis>.
3007+
<replaceable>oid</replaceable> is the object ID of the
3008+
inserted row if <replaceable>rows</replaceable> is 1 and the
3009+
target table has OIDs, and (for the <literal>UPSERT</literal>
3010+
tag), the row was actually inserted rather than updated;
30043011
otherwise <replaceable>oid</replaceable> is 0.
30053012
</para>
30063013

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp