Skip to content

Commit aa7e7ae

Browse files
committed
Have SELECT and CREATE TABLE AS queries return a row count. While this
is invisible in psql, other interfaces, like libpq, make this value visible. Boszormenyi Zoltan
1 parent 346a721 commit aa7e7ae

File tree

4 files changed

+43
-37
lines changed

4 files changed

+43
-37
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.297 2010/02/05 03:09:04 joe Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.298 2010/02/16 20:58:13 momjian Exp $ -->
22

33
<chapter id="libpq">
44
<title><application>libpq</application> - C Library</title>
@@ -2869,12 +2869,11 @@ typedef struct {
28692869
</sect2>
28702870

28712871
<sect2 id="libpq-exec-nonselect">
2872-
<title>Retrieving Result Information for Other Commands</title>
2872+
<title>Retrieving Other Result Information</title>
28732873

28742874
<para>
2875-
These functions are used to extract information from
2876-
<structname>PGresult</structname> objects that are not
2877-
<command>SELECT</> results.
2875+
These functions are used to extract other information from
2876+
<structname>PGresult</structname> objects.
28782877
</para>
28792878

28802879
<variablelist>
@@ -2925,12 +2924,12 @@ typedef struct {
29252924
This function returns a string containing the number of rows
29262925
affected by the <acronym>SQL</> statement that generated the
29272926
<structname>PGresult</>. This function can only be used following
2928-
the execution of an <command>INSERT</>, <command>UPDATE</>,
2929-
<command>DELETE</>, <command>MOVE</>, <command>FETCH</>, or
2930-
<command>COPY</> statement, or an <command>EXECUTE</> of a
2931-
prepared query that contains an <command>INSERT</>,
2932-
<command>UPDATE</>, or <command>DELETE</> statement. If the
2933-
command that generated the <structname>PGresult</> was anything
2927+
the execution of a <command>SELECT</>, <command>CREATE TABLE AS</>,
2928+
<command>INSERT</>, <command>UPDATE</>, <command>DELETE</>,
2929+
<command>MOVE</>, <command>FETCH</>, or <command>COPY</> statement,
2930+
or an <command>EXECUTE</> of a prepared query that contains an
2931+
<command>INSERT</>, <command>UPDATE</>, or <command>DELETE</> statement.
2932+
If the command that generated the <structname>PGresult</> was anything
29342933
else, <function>PQcmdTuples</> returns an empty string. The caller
29352934
should not free the return value directly. It will be freed when
29362935
the associated <structname>PGresult</> handle is passed to

doc/src/sgml/protocol.sgml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.79 2010/02/16 20:15:14 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.80 2010/02/16 20:58:14 momjian Exp $ -->
22

33
<chapter id="protocol">
44
<title>Frontend/Backend Protocol</title>
@@ -2221,6 +2221,12 @@ CommandComplete (B)
22212221
<replaceable>rows</replaceable> is the number of rows updated.
22222222
</para>
22232223

2224+
<para>
2225+
For a <command>SELECT</command> or <command>CREATE TABLE AS</command>
2226+
command, the tag is <literal>SELECT <replaceable>rows</replaceable></literal>
2227+
where <replaceable>rows</replaceable> is the number of rows retrieved.
2228+
</para>
2229+
22242230
<para>
22252231
For a <command>MOVE</command> command, the tag is
22262232
<literal>MOVE <replaceable>rows</replaceable></literal> where

src/backend/tcop/pquery.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.135 2010/02/13 22:45:41 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.136 2010/02/16 20:58:14 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -205,7 +205,8 @@ ProcessQuery(PlannedStmt *plan,
205205
switch (queryDesc->operation)
206206
{
207207
case CMD_SELECT:
208-
strcpy(completionTag, "SELECT");
208+
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
209+
"SELECT %u", queryDesc->estate->es_processed);
209210
break;
210211
case CMD_INSERT:
211212
if (queryDesc->estate->es_processed == 1)
@@ -714,6 +715,7 @@ PortalRun(Portal portal, long count, bool isTopLevel,
714715
char *completionTag)
715716
{
716717
bool result;
718+
uint32 nprocessed;
717719
ResourceOwner saveTopTransactionResourceOwner;
718720
MemoryContext saveTopTransactionContext;
719721
Portal saveActivePortal;
@@ -776,39 +778,35 @@ PortalRun(Portal portal, long count, bool isTopLevel,
776778
switch (portal->strategy)
777779
{
778780
case PORTAL_ONE_SELECT:
779-
(void) PortalRunSelect(portal, true, count, dest);
780-
781-
/* we know the query is supposed to set the tag */
782-
if (completionTag && portal->commandTag)
783-
strcpy(completionTag, portal->commandTag);
784-
785-
/* Mark portal not active */
786-
portal->status = PORTAL_READY;
787-
788-
/*
789-
* Since it's a forward fetch, say DONE iff atEnd is now true.
790-
*/
791-
result = portal->atEnd;
792-
break;
793-
794781
case PORTAL_ONE_RETURNING:
795782
case PORTAL_UTIL_SELECT:
796783

797784
/*
798785
* If we have not yet run the command, do so, storing its
799-
* results in the portal's tuplestore.
786+
* results in the portal's tuplestore. Do this only for the
787+
* PORTAL_ONE_RETURNING and PORTAL_UTIL_SELECT cases.
800788
*/
801-
if (!portal->holdStore)
789+
if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
802790
FillPortalStore(portal, isTopLevel);
803791

804792
/*
805793
* Now fetch desired portion of results.
806794
*/
807-
(void) PortalRunSelect(portal, true, count, dest);
795+
nprocessed = PortalRunSelect(portal, true, count, dest);
808796

809-
/* we know the query is supposed to set the tag */
797+
/*
798+
* If the portal result contains a command tag and the caller
799+
* gave us a pointer to store it, copy it. Patch the "SELECT"
800+
* tag to also provide the rowcount.
801+
*/
810802
if (completionTag && portal->commandTag)
811-
strcpy(completionTag, portal->commandTag);
803+
{
804+
if (strcmp(portal->commandTag, "SELECT") == 0)
805+
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
806+
"SELECT %u", nprocessed);
807+
else
808+
strcpy(completionTag, portal->commandTag);
809+
}
812810

813811
/* Mark portal not active */
814812
portal->status = PORTAL_READY;
@@ -1331,7 +1329,9 @@ PortalRunMulti(Portal portal, bool isTopLevel,
13311329
{
13321330
if (portal->commandTag)
13331331
strcpy(completionTag, portal->commandTag);
1334-
if (strcmp(completionTag, "INSERT") == 0)
1332+
if (strcmp(completionTag, "SELECT") == 0)
1333+
sprintf(completionTag, "SELECT 0 0");
1334+
else if (strcmp(completionTag, "INSERT") == 0)
13351335
strcpy(completionTag, "INSERT 0 0");
13361336
else if (strcmp(completionTag, "UPDATE") == 0)
13371337
strcpy(completionTag, "UPDATE 0");

src/interfaces/libpq/fe-exec.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.208 2010/01/21 18:43:25 rhaas Exp $
11+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.209 2010/02/16 20:58:14 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2752,7 +2752,8 @@ PQcmdTuples(PGresult *res)
27522752
goto interpret_error; /* no space? */
27532753
p++;
27542754
}
2755-
else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
2755+
else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
2756+
strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
27562757
strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
27572758
p = res->cmdStatus + 7;
27582759
else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy