6-pg85-provide-rowcount-for-utility-select-5-ctxdiff.patch
text/x-patch
Filename: 6-pg85-provide-rowcount-for-utility-select-5-ctxdiff.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| doc/src/sgml/protocol.sgml | 7 | 0 |
| src/backend/tcop/pquery.c | 35 | 26 |
| src/interfaces/libpq/fe-exec.c | 1 | 0 |
diff -dcrpN pgsql.orig/doc/src/sgml/protocol.sgml pgsql/doc/src/sgml/protocol.sgml
*** pgsql.orig/doc/src/sgml/protocol.sgml 2010-02-03 11:12:23.000000000 +0100
--- pgsql/doc/src/sgml/protocol.sgml 2010-02-12 16:44:18.000000000 +0100
*************** CommandComplete (B)
*** 2222,2227 ****
--- 2222,2234 ----
</para>
<para>
+ For a <command>SELECT [INTO]</command> and
+ <command>CREATE TABLE ... AS query</command> commands,
+ the tag is <literal>SELECT <replaceable>rows</replaceable></literal>
+ where <replaceable>rows</replaceable> is the number of rows retrieved.
+ </para>
+
+ <para>
For a <command>MOVE</command> command, the tag is
<literal>MOVE <replaceable>rows</replaceable></literal> where
<replaceable>rows</replaceable> is the number of rows the
diff -dcrpN pgsql.orig/src/backend/tcop/pquery.c pgsql/src/backend/tcop/pquery.c
*** pgsql.orig/src/backend/tcop/pquery.c 2010-01-03 12:54:25.000000000 +0100
--- pgsql/src/backend/tcop/pquery.c 2010-02-08 11:46:33.000000000 +0100
*************** ProcessQuery(PlannedStmt *plan,
*** 205,211 ****
switch (queryDesc->operation)
{
case CMD_SELECT:
! strcpy(completionTag, "SELECT");
break;
case CMD_INSERT:
if (queryDesc->estate->es_processed == 1)
--- 205,212 ----
switch (queryDesc->operation)
{
case CMD_SELECT:
! snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
! "SELECT %u", queryDesc->estate->es_processed);
break;
case CMD_INSERT:
if (queryDesc->estate->es_processed == 1)
*************** PortalRun(Portal portal, long count, boo
*** 714,719 ****
--- 715,721 ----
char *completionTag)
{
bool result;
+ uint32 nprocessed;
ResourceOwner saveTopTransactionResourceOwner;
MemoryContext saveTopTransactionContext;
Portal saveActivePortal;
*************** PortalRun(Portal portal, long count, boo
*** 776,814 ****
switch (portal->strategy)
{
case PORTAL_ONE_SELECT:
- (void) PortalRunSelect(portal, true, count, dest);
-
- /* we know the query is supposed to set the tag */
- if (completionTag && portal->commandTag)
- strcpy(completionTag, portal->commandTag);
-
- /* Mark portal not active */
- portal->status = PORTAL_READY;
-
- /*
- * Since it's a forward fetch, say DONE iff atEnd is now true.
- */
- result = portal->atEnd;
- break;
-
case PORTAL_ONE_RETURNING:
case PORTAL_UTIL_SELECT:
/*
* If we have not yet run the command, do so, storing its
! * results in the portal's tuplestore.
*/
! if (!portal->holdStore)
FillPortalStore(portal, isTopLevel);
/*
* Now fetch desired portion of results.
*/
! (void) PortalRunSelect(portal, true, count, dest);
! /* we know the query is supposed to set the tag */
if (completionTag && portal->commandTag)
! strcpy(completionTag, portal->commandTag);
/* Mark portal not active */
portal->status = PORTAL_READY;
--- 778,812 ----
switch (portal->strategy)
{
case PORTAL_ONE_SELECT:
case PORTAL_ONE_RETURNING:
case PORTAL_UTIL_SELECT:
/*
* If we have not yet run the command, do so, storing its
! * results in the portal's tuplestore. Do this only for the
! * PORTAL_ONE_RETURNING and PORTAL_UTIL_SELECT cases.
*/
! if ((portal->strategy != PORTAL_ONE_SELECT) && (!portal->holdStore))
FillPortalStore(portal, isTopLevel);
/*
* Now fetch desired portion of results.
*/
! nprocessed = PortalRunSelect(portal, true, count, dest);
! /*
! * If the portal result contains a command tag and the caller
! * gave us a pointer to store it, copy it. Patch the "SELECT"
! * tag to also provide the rowcount.
! */
if (completionTag && portal->commandTag)
! {
! if (strcmp(portal->commandTag, "SELECT") == 0)
! snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
! "SELECT %u", nprocessed);
! else
! strcpy(completionTag, portal->commandTag);
! }
/* Mark portal not active */
portal->status = PORTAL_READY;
*************** PortalRunMulti(Portal portal, bool isTop
*** 1318,1337 ****
* If a command completion tag was supplied, use it. Otherwise use the
* portal's commandTag as the default completion tag.
*
! * Exception: clients will expect INSERT/UPDATE/DELETE tags to have
! * counts, so fake something up if necessary. (This could happen if the
* original query was replaced by a DO INSTEAD rule.)
*/
if (completionTag && completionTag[0] == '\0')
{
if (portal->commandTag)
strcpy(completionTag, portal->commandTag);
if (strcmp(completionTag, "INSERT") == 0)
! strcpy(completionTag, "INSERT 0 0");
else if (strcmp(completionTag, "UPDATE") == 0)
! strcpy(completionTag, "UPDATE 0");
else if (strcmp(completionTag, "DELETE") == 0)
! strcpy(completionTag, "DELETE 0");
}
}
--- 1316,1346 ----
* If a command completion tag was supplied, use it. Otherwise use the
* portal's commandTag as the default completion tag.
*
! * Exception: clients will expect SELECT/INSERT/UPDATE/DELETE tags to have
! * counts, so try to provide the proper info. (This could happen if the
* original query was replaced by a DO INSTEAD rule.)
*/
if (completionTag && completionTag[0] == '\0')
{
+ Oid lastOid = InvalidOid;
+ uint32 processed = 0;
+
+ if (portal->queryDesc && portal->queryDesc->estate)
+ {
+ lastOid = portal->queryDesc->estate->es_lastoid;
+ processed = portal->queryDesc->estate->es_processed;
+ }
+
if (portal->commandTag)
strcpy(completionTag, portal->commandTag);
if (strcmp(completionTag, "INSERT") == 0)
! sprintf(completionTag, "INSERT %u %u", lastOid, processed);
else if (strcmp(completionTag, "UPDATE") == 0)
! sprintf(completionTag, "UPDATE %u", processed);
else if (strcmp(completionTag, "DELETE") == 0)
! sprintf(completionTag, "DELETE %u", processed);
! else if (strcmp(completionTag, "SELECT") == 0)
! sprintf(completionTag, "SELECT %u", processed);
}
}
diff -dcrpN pgsql.orig/src/interfaces/libpq/fe-exec.c pgsql/src/interfaces/libpq/fe-exec.c
*** pgsql.orig/src/interfaces/libpq/fe-exec.c 2010-01-21 20:45:39.000000000 +0100
--- pgsql/src/interfaces/libpq/fe-exec.c 2010-02-08 10:32:25.000000000 +0100
*************** PQcmdTuples(PGresult *res)
*** 2753,2758 ****
--- 2753,2759 ----
p++;
}
else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
+ strncmp(res->cmdStatus, "SELECT ", 7) == 0 ||
strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
p = res->cmdStatus + 7;
else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)