diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index d985204566cab88a209a233d102acf8b4de4b0ad..c7df697845e4eb6f55145f7e17279784cc316f83 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -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>
 
diff --git a/doc/src/sgml/ref/insert.sgml b/doc/src/sgml/ref/insert.sgml
index 3c3315eab3d6806f384a0d10b64b200147498905..7cd4577f1eafc819efeb3dbb8e98878282ab6a5a 100644
--- a/doc/src/sgml/ref/insert.sgml
+++ b/doc/src/sgml/ref/insert.sgml
@@ -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>
 
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 2d9bf419bdb57844e25d07b900f4eee5573f94c2..cab93725e67b0fb7ed78ce935dbbaa6700848735 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 54464f8c656096175f1c3e89f9dd0535d6d5c9b5..4775acfcfc1dfd9d5b5380a19e04c4bdea7a44e8 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -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);
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index d3f5a1401702a1991ef619646e16d99661269253..60340e39eda46506929030ab6173b6f3d7fde72c 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -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;
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index bcffd85754c7f90af50c3b96b0dae50448e41b4b..9c14e8abdf87c8af57a2fde0b6e55c2ac5782a5e 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -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)
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index f4155f787705abdcfe8446f7ba03e6fd229e6ec7..ff01368531a313f97834cf6413561b060d2f7d56 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -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);
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 601258f2c2fb65766c122300cb986d232b906fd4..6b56fb5eb364f577216fae56e405e84e2333f7a5 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201505191
+#define CATALOG_VERSION_NO	201505231
 
 #endif
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index b70231919febacfd0ceb9be939c07848c2c9c96d..61c840414073b6f1440b475540f810747e1626fb 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -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? */