Skip to content

Commit 023570f

Browse files
committed
Make the COPY command return a command tag that includes the number of
rows copied. Backend side of Volkan Yazici's recent patch, with corrections and documentation.
1 parent 4e086f7 commit 023570f

File tree

5 files changed

+55
-10
lines changed

5 files changed

+55
-10
lines changed

doc/src/sgml/protocol.sgml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.63 2006/01/18 06:49:25 neilc Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.64 2006/03/03 19:54:09 tgl Exp $ -->
22

33
<chapter id="protocol">
44
<title>Frontend/Backend Protocol</title>
@@ -2069,7 +2069,7 @@ CommandComplete (B)
20692069
String
20702070
</term>
20712071
<listitem>
2072-
<para>
2072+
<para>
20732073
The command tag. This is usually a single
20742074
word that identifies which SQL command was completed.
20752075
</para>
@@ -2109,7 +2109,16 @@ CommandComplete (B)
21092109
<literal>FETCH <replaceable>rows</replaceable></literal> where
21102110
<replaceable>rows</replaceable> is the number of rows that
21112111
have been retrieved from the cursor.
2112-
</para>
2112+
</para>
2113+
2114+
<para>
2115+
For a <command>COPY</command> command, the tag is
2116+
<literal>COPY <replaceable>rows</replaceable></literal> where
2117+
<replaceable>rows</replaceable> is the number of rows copied.
2118+
(Note: the row count appears only in
2119+
<productname>PostgreSQL</productname> 8.2 and later.)
2120+
</para>
2121+
21132122
</listitem>
21142123
</varlistentry>
21152124
</variablelist>

doc/src/sgml/ref/copy.sgml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.72 2005/12/28 14:38:32 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.73 2006/03/03 19:54:10 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -253,6 +253,20 @@ COPY <replaceable class="parameter">tablename</replaceable> [ ( <replaceable cla
253253
</variablelist>
254254
</refsect1>
255255

256+
<refsect1>
257+
<title>Outputs</title>
258+
259+
<para>
260+
On successful completion, a <command>COPY</> command returns a command
261+
tag of the form
262+
<screen>
263+
COPY <replaceable class="parameter">count</replaceable>
264+
</screen>
265+
The <replaceable class="parameter">count</replaceable> is the number
266+
of rows inserted into or copied from the table.
267+
</para>
268+
</refsect1>
269+
256270
<refsect1>
257271
<title>Notes</title>
258272

src/backend/commands/copy.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.258 2006/02/03 12:41:07 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.259 2006/03/03 19:54:10 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -102,6 +102,7 @@ typedef struct CopyStateData
102102
int client_encoding; /* remote side's character encoding */
103103
bool need_transcoding; /* client encoding diff from server? */
104104
bool encoding_embeds_ascii; /* ASCII can be non-first byte? */
105+
uint64 processed; /* # of tuples processed */
105106

106107
/* parameters from the COPY command */
107108
Relation rel; /* relation to copy to or from */
@@ -710,7 +711,7 @@ CopyLoadRawBuf(CopyState cstate)
710711
* Do not allow the copy if user doesn't have proper permission to access
711712
* the table.
712713
*/
713-
void
714+
uint64
714715
DoCopy(const CopyStmt *stmt)
715716
{
716717
CopyState cstate;
@@ -724,6 +725,7 @@ DoCopy(const CopyStmt *stmt)
724725
AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT);
725726
AclResult aclresult;
726727
ListCell *option;
728+
uint64 processed;
727729

728730
/* Allocate workspace and zero all fields */
729731
cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
@@ -1019,6 +1021,7 @@ DoCopy(const CopyStmt *stmt)
10191021
cstate->line_buf_converted = false;
10201022
cstate->raw_buf = (char *) palloc(RAW_BUF_SIZE + 1);
10211023
cstate->raw_buf_index = cstate->raw_buf_len = 0;
1024+
cstate->processed = 0;
10221025

10231026
/* Set up encoding conversion info */
10241027
cstate->client_encoding = pg_get_client_encoding();
@@ -1161,10 +1164,14 @@ DoCopy(const CopyStmt *stmt)
11611164
heap_close(cstate->rel, (is_from ? NoLock : AccessShareLock));
11621165

11631166
/* Clean up storage (probably not really necessary) */
1167+
processed = cstate->processed;
1168+
11641169
pfree(cstate->attribute_buf.data);
11651170
pfree(cstate->line_buf.data);
11661171
pfree(cstate->raw_buf);
11671172
pfree(cstate);
1173+
1174+
return processed;
11681175
}
11691176

11701177

@@ -1401,6 +1408,8 @@ CopyTo(CopyState cstate)
14011408
CopySendEndOfRow(cstate);
14021409

14031410
MemoryContextSwitchTo(oldcontext);
1411+
1412+
cstate->processed++;
14041413
}
14051414

14061415
heap_endscan(scandesc);
@@ -2002,6 +2011,13 @@ CopyFrom(CopyState cstate)
20022011

20032012
/* AFTER ROW INSERT Triggers */
20042013
ExecARInsertTriggers(estate, resultRelInfo, tuple);
2014+
2015+
/*
2016+
* We count only tuples not suppressed by a BEFORE INSERT trigger;
2017+
* this is the same definition used by execMain.c for counting
2018+
* tuples inserted by an INSERT command.
2019+
*/
2020+
cstate->processed++;
20052021
}
20062022
}
20072023

src/backend/tcop/utility.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.253 2006/03/03 03:30:53 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.254 2006/03/03 19:54:10 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -636,7 +636,13 @@ ProcessUtility(Node *parsetree,
636636
break;
637637

638638
case T_CopyStmt:
639-
DoCopy((CopyStmt *) parsetree);
639+
{
640+
uint64 processed = DoCopy((CopyStmt *) parsetree);
641+
642+
if (completionTag)
643+
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
644+
"COPY " UINT64_FORMAT, processed);
645+
}
640646
break;
641647

642648
case T_PrepareStmt:

src/include/commands/copy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/copy.h,v 1.25 2004/12/31 22:03:28 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/copy.h,v 1.26 2006/03/03 19:54:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,6 +17,6 @@
1717
#include "nodes/parsenodes.h"
1818

1919

20-
extern void DoCopy(const CopyStmt *stmt);
20+
extern uint64 DoCopy(const CopyStmt *stmt);
2121

2222
#endif /* COPY_H */

0 commit comments

Comments
 (0)