-<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.63 2006/01/18 06:49:25 neilc Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.64 2006/03/03 19:54:09 tgl Exp $ -->
 
 <chapter id="protocol">
  <title>Frontend/Backend Protocol</title>
         String
 </term>
 <listitem>
-<para>
+       <para>
         The command tag.  This is usually a single
         word that identifies which SQL command was completed.
        </para>
         <literal>FETCH <replaceable>rows</replaceable></literal> where
         <replaceable>rows</replaceable> is the number of rows that
         have been retrieved from the cursor.
-</para>
+       </para>
+
+       <para>
+        For a <command>COPY</command> command, the tag is
+        <literal>COPY <replaceable>rows</replaceable></literal> where
+        <replaceable>rows</replaceable> is the number of rows copied.
+        (Note: the row count appears only in
+        <productname>PostgreSQL</productname> 8.2 and later.)
+       </para>
+
 </listitem>
 </varlistentry>
 </variablelist>
 
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.72 2005/12/28 14:38:32 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.73 2006/03/03 19:54:10 tgl Exp $
 PostgreSQL documentation
 -->
 
   </variablelist>
  </refsect1>
 
+ <refsect1>
+  <title>Outputs</title>
+
+  <para>
+   On successful completion, a <command>COPY</> command returns a command
+   tag of the form
+<screen>
+COPY <replaceable class="parameter">count</replaceable>
+</screen>
+   The <replaceable class="parameter">count</replaceable> is the number
+   of rows inserted into or copied from the table.
+  </para>
+ </refsect1>
+
  <refsect1>
   <title>Notes</title>
 
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.258 2006/02/03 12:41:07 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.259 2006/03/03 19:54:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
    int         client_encoding;    /* remote side's character encoding */
    bool        need_transcoding;       /* client encoding diff from server? */
    bool        encoding_embeds_ascii;  /* ASCII can be non-first byte? */
+   uint64      processed;      /* # of tuples processed */
 
    /* parameters from the COPY command */
    Relation    rel;            /* relation to copy to or from */
  * Do not allow the copy if user doesn't have proper permission to access
  * the table.
  */
-void
+uint64
 DoCopy(const CopyStmt *stmt)
 {
    CopyState   cstate;
    AclMode     required_access = (is_from ? ACL_INSERT : ACL_SELECT);
    AclResult   aclresult;
    ListCell   *option;
+   uint64      processed;
 
    /* Allocate workspace and zero all fields */
    cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
    cstate->line_buf_converted = false;
    cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
    cstate->raw_buf_index = cstate->raw_buf_len = 0;
+   cstate->processed = 0;
 
    /* Set up encoding conversion info */
    cstate->client_encoding = pg_get_client_encoding();
    heap_close(cstate->rel, (is_from ? NoLock : AccessShareLock));
 
    /* Clean up storage (probably not really necessary) */
+   processed = cstate->processed;
+
    pfree(cstate->attribute_buf.data);
    pfree(cstate->line_buf.data);
    pfree(cstate->raw_buf);
    pfree(cstate);
+
+   return processed;
 }
 
 
        CopySendEndOfRow(cstate);
 
        MemoryContextSwitchTo(oldcontext);
+       
+       cstate->processed++;
    }
 
    heap_endscan(scandesc);
 
            /* AFTER ROW INSERT Triggers */
            ExecARInsertTriggers(estate, resultRelInfo, tuple);
+
+           /*
+            * We count only tuples not suppressed by a BEFORE INSERT trigger;
+            * this is the same definition used by execMain.c for counting
+            * tuples inserted by an INSERT command.
+            */
+           cstate->processed++;
        }
    }
 
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.253 2006/03/03 03:30:53 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.254 2006/03/03 19:54:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
            break;
 
        case T_CopyStmt:
-           DoCopy((CopyStmt *) parsetree);
+           {
+               uint64  processed = DoCopy((CopyStmt *) parsetree);
+
+               if (completionTag)
+                   snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
+                            "COPY " UINT64_FORMAT, processed);
+           }
            break;
 
        case T_PrepareStmt:
 
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/copy.h,v 1.25 2004/12/31 22:03:28 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/copy.h,v 1.26 2006/03/03 19:54:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "nodes/parsenodes.h"
 
 
-extern void DoCopy(const CopyStmt *stmt);
+extern uint64 DoCopy(const CopyStmt *stmt);
 
 #endif   /* COPY_H */