Applied. Thanks. ---------------------------------------------------------------------------
Bruce Momjian wrote: > Boszormenyi Zoltan wrote: > > >>> Ah, I didn't even see that that section needed to be updated. Good > > >>> catch. I'd suggest the following wording: > > >>> > > >>> For a <command>SELECT</command> or <command>CREATE TABLE AS</command> > > >>> command, the tag is SELECT rows... [and the rest as you have it] > > >>> > > >>> We should probably also retitle that section from "Retrieving Result > > >>> Information for Other Commands" to "Retrieving Other Result > > >>> Information" and adjust the text of the opening sentence similarly. > > >>> > > >>> Also I think you need to update the docs for PQcmdtuples to mention > > >>> that it not works for SELECT and CTAS. > > >>> > > >>> > > >> Ok, I will update libpq.sgml where this section resides. > > >> What's a CTA, btw? Do you mean CTE, a.k.a. "Common Table Expression"? > > >> > > > > > > Sorry, CTAS = CREATE TABLE AS SELECT. > > > > > > > Okay, new patch is attached. Please read the docs changes, and comment. > > I have reviewed this patch and made some adjustments, attached. The > major change is that our return of "0 0" in certain cases must remain, > though I have improved the C comment explaining it with a separate CVS > commit: > > /* > * If a command completion tag was supplied, use it. Otherwise use the > * portal's commandTag as the default completion tag. > * > * Exception: Clients expect INSERT/UPDATE/DELETE tags to have > * counts, so fake them with zeros. This can happen with DO INSTEAD > * rules if there is no replacement query of the same type as the > * original. We print "0 0" here because technically there is no > * query of the matching tag type, and printing a non-zero count for > * a different query type seems wrong, e.g. an INSERT that does > * an UPDATE instead should not print "0 1" if one row > * was updated. See QueryRewrite(), step 3, for details. > */ > > I have removed the part of the patch that chagned "0 0"; it seems to > run fine without it. The rest of my adjustments were minor. > > One major part of the patch seems to be the collection of the > PORTAL_ONE_SELECT switch label into the label below it, which is a nice > cleanup. > > -- > Bruce Momjian <br...@momjian.us> http://momjian.us > EnterpriseDB http://enterprisedb.com > > + If your life is a hard drive, Christ can be your backup. + > 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 **** > </sect2> > > <sect2 id="libpq-exec-nonselect"> > ! <title>Retrieving Result Information for Other Commands</title> > > <para> > ! These functions are used to extract information from > ! <structname>PGresult</structname> objects that are not > ! <command>SELECT</> results. > </para> > > <variablelist> > --- 2869,2879 ---- > </sect2> > > <sect2 id="libpq-exec-nonselect"> > ! <title>Retrieving Other Result Information</title> > > <para> > ! These functions are used to extract other information from > ! <structname>PGresult</structname> objects. > </para> > > <variablelist> > *************** > *** 2925,2936 **** > This function returns a string containing the number of rows > affected by the <acronym>SQL</> statement that generated the > <structname>PGresult</>. This function can only be used following > ! the execution of an <command>INSERT</>, <command>UPDATE</>, > ! <command>DELETE</>, <command>MOVE</>, <command>FETCH</>, or > ! <command>COPY</> statement, or an <command>EXECUTE</> of a > ! prepared query that contains an <command>INSERT</>, > ! <command>UPDATE</>, or <command>DELETE</> statement. If the > ! command that generated the <structname>PGresult</> was anything > else, <function>PQcmdTuples</> returns an empty string. The caller > should not free the return value directly. It will be freed when > the associated <structname>PGresult</> handle is passed to > --- 2924,2935 ---- > This function returns a string containing the number of rows > affected by the <acronym>SQL</> statement that generated the > <structname>PGresult</>. This function can only be used following > ! the execution of a <command>SELECT</>, <command>CREATE TABLE AS</>, > ! <command>INSERT</>, <command>UPDATE</>, <command>DELETE</>, > ! <command>MOVE</>, <command>FETCH</>, or <command>COPY</> statement, > ! or an <command>EXECUTE</> of a prepared query that contains an > ! <command>INSERT</>, <command>UPDATE</>, or <command>DELETE</> > statement. > ! If the command that generated the <structname>PGresult</> was > anything > else, <function>PQcmdTuples</> returns an empty string. The caller > should not free the return value directly. It will be freed when > the associated <structname>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 ---- > </para> > > <para> > + For a <command>SELECT</command> or <command>CREATE TABLE > AS</command> > + command, 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 > 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) > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + If your life is a hard drive, Christ can be your backup. + -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers