|
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