]> granicus.if.org Git - postgresql/commitdiff
Remove the new UPSERT command tag and use INSERT instead.
authorAndres Freund <andres@anarazel.de>
Fri, 22 May 2015 22:49:27 +0000 (00:49 +0200)
committerAndres Freund <andres@anarazel.de>
Fri, 22 May 2015 22:58:45 +0000 (00:58 +0200)
Previously, INSERT with ON CONFLICT DO UPDATE specified used a new
command tag -- UPSERT.  It was introduced out of concern that INSERT as
a command tag would be a misrepresentation for ON CONFLICT DO UPDATE, as
some affected rows may actually have been updated.

Alvaro Herrera noticed that the implementation of that new command tag
was incomplete; in subsequent discussion we concluded that having it
doesn't provide benefits that are in line with the compatibility breaks
it requires.

Catversion bump due to the removal of PlannedStmt->isUpsert.

Author: Peter Geoghegan
Discussion: 20150520215816.GI5885@postgresql.org

doc/src/sgml/protocol.sgml
doc/src/sgml/ref/insert.sgml
src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/optimizer/plan/planner.c
src/backend/tcop/pquery.c
src/bin/psql/common.c
src/include/catalog/catversion.h
src/include/nodes/plannodes.h

index d985204566cab88a209a233d102acf8b4de4b0ad..c7df697845e4eb6f55145f7e17279784cc316f83 100644 (file)
@@ -3011,16 +3011,9 @@ CommandComplete (B)
         <literal>INSERT <replaceable>oid</replaceable>
         <replaceable>rows</replaceable></literal>, where
         <replaceable>rows</replaceable> is the number of rows
-        inserted. However, if and only if <literal>ON CONFLICT
-        UPDATE</> is specified, then the tag is <literal>UPSERT
-        <replaceable>oid</replaceable>
-        <replaceable>rows</replaceable></literal>, where
-        <replaceable>rows</replaceable> is the number of rows inserted
-        <emphasis>or updated</emphasis>.
-        <replaceable>oid</replaceable> is the object ID of the
-        inserted row if <replaceable>rows</replaceable> is 1 and the
-        target table has OIDs, and (for the <literal>UPSERT</literal>
-        tag), the row was actually inserted rather than updated;
+        inserted. <replaceable>oid</replaceable> is the object ID
+        of the inserted row if <replaceable>rows</replaceable> is 1
+        and the target table has OIDs;
         otherwise <replaceable>oid</replaceable> is 0.
        </para>
 
index 3c3315eab3d6806f384a0d10b64b200147498905..7cd4577f1eafc819efeb3dbb8e98878282ab6a5a 100644 (file)
@@ -497,20 +497,13 @@ INSERT INTO <replaceable class="PARAMETER">table_name</replaceable> [ AS <replac
 <screen>
 INSERT <replaceable>oid</replaceable> <replaceable class="parameter">count</replaceable>
 </screen>
-   However, in the event of an <literal>ON CONFLICT DO UPDATE</> clause
-   (but <emphasis>not</emphasis> in the event of an <literal>ON
-   CONFLICT DO NOTHING</> clause), the command tag reports the number of
-   rows inserted or updated together, of the form
-<screen>
-UPSERT <replaceable>oid</replaceable> <replaceable class="parameter">count</replaceable>
-</screen>
-   The <replaceable class="parameter">count</replaceable> is the number
-   of rows inserted.  If <replaceable class="parameter">count</replaceable>
-   is exactly one, and the target table has OIDs, then
-   <replaceable class="parameter">oid</replaceable> is the
-   <acronym>OID</acronym>
-   assigned to the inserted row (but not if there is only a single
-   updated row).  Otherwise <replaceable
+   The <replaceable class="parameter">count</replaceable> is the
+   number of rows inserted or updated.  If <replaceable
+   class="parameter">count</replaceable> is exactly one, and the
+   target table has OIDs, then <replaceable
+   class="parameter">oid</replaceable> is the <acronym>OID</acronym>
+   assigned to the inserted row.  The single row must have been
+   inserted rather than updated.  Otherwise <replaceable
    class="parameter">oid</replaceable> is zero.
   </para>
 
index 2d9bf419bdb57844e25d07b900f4eee5573f94c2..cab93725e67b0fb7ed78ce935dbbaa6700848735 100644 (file)
@@ -81,7 +81,6 @@ _copyPlannedStmt(const PlannedStmt *from)
        COPY_SCALAR_FIELD(queryId);
        COPY_SCALAR_FIELD(hasReturning);
        COPY_SCALAR_FIELD(hasModifyingCTE);
-       COPY_SCALAR_FIELD(isUpsert);
        COPY_SCALAR_FIELD(canSetTag);
        COPY_SCALAR_FIELD(transientPlan);
        COPY_NODE_FIELD(planTree);
index 54464f8c656096175f1c3e89f9dd0535d6d5c9b5..4775acfcfc1dfd9d5b5380a19e04c4bdea7a44e8 100644 (file)
@@ -243,7 +243,6 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
        WRITE_UINT_FIELD(queryId);
        WRITE_BOOL_FIELD(hasReturning);
        WRITE_BOOL_FIELD(hasModifyingCTE);
-       WRITE_BOOL_FIELD(isUpsert);
        WRITE_BOOL_FIELD(canSetTag);
        WRITE_BOOL_FIELD(transientPlan);
        WRITE_NODE_FIELD(planTree);
index d3f5a1401702a1991ef619646e16d99661269253..60340e39eda46506929030ab6173b6f3d7fde72c 100644 (file)
@@ -261,8 +261,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
        result->queryId = parse->queryId;
        result->hasReturning = (parse->returningList != NIL);
        result->hasModifyingCTE = parse->hasModifyingCTE;
-       result->isUpsert =
-               (parse->onConflict && parse->onConflict->action == ONCONFLICT_UPDATE);
        result->canSetTag = parse->canSetTag;
        result->transientPlan = glob->transientPlan;
        result->planTree = top_plan;
index bcffd85754c7f90af50c3b96b0dae50448e41b4b..9c14e8abdf87c8af57a2fde0b6e55c2ac5782a5e 100644 (file)
@@ -202,14 +202,8 @@ ProcessQuery(PlannedStmt *plan,
                                        lastOid = queryDesc->estate->es_lastoid;
                                else
                                        lastOid = InvalidOid;
-                               if (plan->isUpsert)
-                                       snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
-                                                        "UPSERT %u %u",
-                                                        lastOid, queryDesc->estate->es_processed);
-                               else
-                                       snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
-                                                        "INSERT %u %u",
-                                                        lastOid, queryDesc->estate->es_processed);
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
+                                  "INSERT %u %u", lastOid, queryDesc->estate->es_processed);
                                break;
                        case CMD_UPDATE:
                                snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
@@ -1362,10 +1356,7 @@ PortalRunMulti(Portal portal, bool isTopLevel,
         * 0" here because technically there is no query of the matching tag type,
         * and printing a non-zero count for a different query type seems wrong,
         * e.g.  an INSERT that does an UPDATE instead should not print "0 1" if
-        * one row was updated (unless the ON CONFLICT DO UPDATE, or "UPSERT"
-        * variant of INSERT was used to update the row, where it's logically a
-        * direct effect of the top level command).  See QueryRewrite(), step 3,
-        * for details.
+        * one row was updated.  See QueryRewrite(), step 3, for details.
         */
        if (completionTag && completionTag[0] == '\0')
        {
@@ -1375,8 +1366,6 @@ PortalRunMulti(Portal portal, bool isTopLevel,
                        sprintf(completionTag, "SELECT 0 0");
                else if (strcmp(completionTag, "INSERT") == 0)
                        strcpy(completionTag, "INSERT 0 0");
-               else if (strcmp(completionTag, "UPSERT") == 0)
-                       strcpy(completionTag, "UPSERT 0 0");
                else if (strcmp(completionTag, "UPDATE") == 0)
                        strcpy(completionTag, "UPDATE 0");
                else if (strcmp(completionTag, "DELETE") == 0)
index f4155f787705abdcfe8446f7ba03e6fd229e6ec7..ff01368531a313f97834cf6413561b060d2f7d56 100644 (file)
@@ -894,12 +894,9 @@ PrintQueryResults(PGresult *results)
                                success = StoreQueryTuple(results);
                        else
                                success = PrintQueryTuples(results);
-                       /*
-                        * if it's INSERT/UPSERT/UPDATE/DELETE RETURNING, also print status
-                        */
+                       /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
                        cmdstatus = PQcmdStatus(results);
                        if (strncmp(cmdstatus, "INSERT", 6) == 0 ||
-                               strncmp(cmdstatus, "UPSERT", 6) == 0 ||
                                strncmp(cmdstatus, "UPDATE", 6) == 0 ||
                                strncmp(cmdstatus, "DELETE", 6) == 0)
                                PrintQueryStatus(results);
index 601258f2c2fb65766c122300cb986d232b906fd4..6b56fb5eb364f577216fae56e405e84e2333f7a5 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201505191
+#define CATALOG_VERSION_NO     201505231
 
 #endif
index b70231919febacfd0ceb9be939c07848c2c9c96d..61c840414073b6f1440b475540f810747e1626fb 100644 (file)
@@ -45,8 +45,6 @@ typedef struct PlannedStmt
 
        bool            hasModifyingCTE;        /* has insert|update|delete in WITH? */
 
-       bool            isUpsert;               /* is it insert ... ON CONFLICT UPDATE? */
-
        bool            canSetTag;              /* do I set the command result tag? */
 
        bool            transientPlan;  /* redo plan when TransactionXmin changes? */