Index: doc/src/sgml/libpq.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v retrieving revision 1.297 diff -c -c -r1.297 libpq.sgml *** doc/src/sgml/libpq.sgml 5 Feb 2010 03:09:04 -0000 1.297 --- doc/src/sgml/libpq.sgml 14 Feb 2010 03:11:00 -0000 *************** *** 2869,2880 **** ! Retrieving Result Information for Other Commands ! These functions are used to extract information from ! PGresult objects that are not ! SELECT results. --- 2869,2879 ---- ! Retrieving Other Result Information ! These functions are used to extract other information from ! PGresult objects. *************** *** 2925,2936 **** This function returns a string containing the number of rows affected by the SQL statement that generated the PGresult. This function can only be used following ! the execution of an INSERT, UPDATE, ! DELETE, MOVE, FETCH, or ! COPY statement, or an EXECUTE of a ! prepared query that contains an INSERT, ! UPDATE, or DELETE statement. If the ! command that generated the PGresult was anything else, PQcmdTuples returns an empty string. The caller should not free the return value directly. It will be freed when the associated PGresult handle is passed to --- 2924,2935 ---- This function returns a string containing the number of rows affected by the SQL statement that generated the PGresult. This function can only be used following ! the execution of a SELECT, CREATE TABLE AS, ! INSERT, UPDATE, DELETE, ! MOVE, FETCH, or COPY statement, ! or an EXECUTE of a prepared query that contains an ! INSERT, UPDATE, or DELETE statement. ! If the command that generated the PGresult was anything else, PQcmdTuples returns an empty string. The caller should not free the return value directly. It will be freed when the associated PGresult handle is passed to Index: doc/src/sgml/protocol.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v retrieving revision 1.78 diff -c -c -r1.78 protocol.sgml *** doc/src/sgml/protocol.sgml 3 Feb 2010 09:47:19 -0000 1.78 --- doc/src/sgml/protocol.sgml 14 Feb 2010 03:11:00 -0000 *************** *** 2222,2227 **** --- 2222,2233 ---- + For a SELECT or CREATE TABLE AS + command, the tag is SELECT rows + where rows is the number of rows retrieved. + + + For a MOVE command, the tag is MOVE rows where rows is the number of rows the Index: src/backend/tcop/pquery.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/tcop/pquery.c,v retrieving revision 1.135 diff -c -c -r1.135 pquery.c *** src/backend/tcop/pquery.c 13 Feb 2010 22:45:41 -0000 1.135 --- src/backend/tcop/pquery.c 14 Feb 2010 03:11:04 -0000 *************** *** 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) *************** *** 714,719 **** --- 715,721 ---- char *completionTag) { bool result; + uint32 nprocessed; ResourceOwner saveTopTransactionResourceOwner; MemoryContext saveTopTransactionContext; Portal saveActivePortal; *************** *** 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; *************** *** 1331,1337 **** { 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"); --- 1329,1337 ---- { if (portal->commandTag) strcpy(completionTag, portal->commandTag); ! if (strcmp(completionTag, "SELECT") == 0) ! sprintf(completionTag, "SELECT 0 0"); ! else if (strcmp(completionTag, "INSERT") == 0) strcpy(completionTag, "INSERT 0 0"); else if (strcmp(completionTag, "UPDATE") == 0) strcpy(completionTag, "UPDATE 0"); Index: src/interfaces/libpq/fe-exec.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v retrieving revision 1.208 diff -c -c -r1.208 fe-exec.c *** src/interfaces/libpq/fe-exec.c 21 Jan 2010 18:43:25 -0000 1.208 --- src/interfaces/libpq/fe-exec.c 14 Feb 2010 03:11:04 -0000 *************** *** 2752,2758 **** goto interpret_error; /* no space? */ p++; } ! else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 || strncmp(res->cmdStatus, "UPDATE ", 7) == 0) p = res->cmdStatus + 7; else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0) --- 2752,2759 ---- goto interpret_error; /* no space? */ p++; } ! else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 || ! strncmp(res->cmdStatus, "DELETE ", 7) == 0 || strncmp(res->cmdStatus, "UPDATE ", 7) == 0) p = res->cmdStatus + 7; else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)