|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -205,7 +205,8 @@ ProcessQuery(PlannedStmt *plan,
|
205 | 205 | switch (queryDesc->operation)
|
206 | 206 | {
|
207 | 207 | case CMD_SELECT:
|
208 |
| - strcpy(completionTag, "SELECT"); |
| 208 | + snprintf(completionTag, COMPLETION_TAG_BUFSIZE, |
| 209 | + "SELECT %u", queryDesc->estate->es_processed); |
209 | 210 | break;
|
210 | 211 | case CMD_INSERT:
|
211 | 212 | if (queryDesc->estate->es_processed == 1)
|
@@ -714,6 +715,7 @@ PortalRun(Portal portal, long count, bool isTopLevel,
|
714 | 715 | char *completionTag)
|
715 | 716 | {
|
716 | 717 | bool result;
|
| 718 | + uint32 nprocessed; |
717 | 719 | ResourceOwner saveTopTransactionResourceOwner;
|
718 | 720 | MemoryContext saveTopTransactionContext;
|
719 | 721 | Portal saveActivePortal;
|
@@ -776,39 +778,35 @@ PortalRun(Portal portal, long count, bool isTopLevel,
|
776 | 778 | switch (portal->strategy)
|
777 | 779 | {
|
778 | 780 | 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 |
| - |
794 | 781 | case PORTAL_ONE_RETURNING:
|
795 | 782 | case PORTAL_UTIL_SELECT:
|
796 | 783 |
|
797 | 784 | /*
|
798 | 785 | * 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. |
800 | 788 | */
|
801 |
| - if (!portal->holdStore) |
| 789 | + if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore) |
802 | 790 | FillPortalStore(portal, isTopLevel);
|
803 | 791 |
|
804 | 792 | /*
|
805 | 793 | * Now fetch desired portion of results.
|
806 | 794 | */
|
807 |
| - (void) PortalRunSelect(portal, true, count, dest); |
| 795 | + nprocessed = PortalRunSelect(portal, true, count, dest); |
808 | 796 |
|
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 | + */ |
810 | 802 | 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 | + } |
812 | 810 |
|
813 | 811 | /* Mark portal not active */
|
814 | 812 | portal->status = PORTAL_READY;
|
@@ -1331,7 +1329,9 @@ PortalRunMulti(Portal portal, bool isTopLevel,
|
1331 | 1329 | {
|
1332 | 1330 | if (portal->commandTag)
|
1333 | 1331 | 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) |
1335 | 1335 | strcpy(completionTag, "INSERT 0 0");
|
1336 | 1336 | else if (strcmp(completionTag, "UPDATE") == 0)
|
1337 | 1337 | strcpy(completionTag, "UPDATE 0");
|
|
0 commit comments