On Wed, Jul 24, 2013 at 08:08:32PM +0200, Andres Freund wrote: > On 2013-07-24 13:48:23 -0400, Tom Lane wrote: > > Vik Fearing <vik.fearing@xxxxxxxxxx> writes: > > > Also worth mentioning is bug #7766. > > > http://www.postgresql.org/message-id/E1Tlli5-0007tR-HO@xxxxxxxxxxxxxxxxxxxxxxx > > > > Yeah, did you read that whole thread? The real issue here is going to > > be whether client-side code falls over on wider-than-32-bit counts. > > We can fix the backend and be pretty sure that we've found all the > > relevant places inside it, but we'll just be exporting the issue. > > > I did look at libpq and noted that it doesn't seem to have any internal > > problem, because it returns the count to callers as a string (!). > > But what do you think are the odds that callers are using code that > > won't overflow? I'd bet on finding atoi() or suchlike in a lot of > > callers. Even if they thought to use strtoul(), unsigned long is > > not necessarily 64 bits wide. > > Application code that relies on the values already has problems though > since the returned values are pretty bogus now. Including the fact that > it can return 0 as the number of modified rows which is checked for more > frequently than the actual number IME... > So I think client code that uses simplistic stuff like atoi isn't worse > off afterwards since the values will be about as bogus. I am more > worried about code that does range checks like java's string conversion > routines... > > I think fixing this for 9.4 is fine, but due to the compat issues I > think it's to late for 9.3. Where are we on this? There was a posted patch, attached, but Vik Fearing said it was insufficent and he was working on a new one: http://www.postgresql.org/message-id/51EFF67A.7020509@xxxxxxxxxx -- Bruce Momjian <bruce@xxxxxxxxxx> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +
*** a/src/backend/commands/createas.c --- b/src/backend/commands/createas.c *************** *** 172,178 **** ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, /* save the rowcount if we're given a completionTag to fill */ if (completionTag) snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "SELECT %u", queryDesc->estate->es_processed); /* and clean up */ ExecutorFinish(queryDesc); --- 172,178 ---- /* save the rowcount if we're given a completionTag to fill */ if (completionTag) snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "SELECT " UINT64_FORMAT, queryDesc->estate->es_processed); /* and clean up */ ExecutorFinish(queryDesc); *** a/src/backend/tcop/pquery.c --- b/src/backend/tcop/pquery.c *************** *** 195,201 **** ProcessQuery(PlannedStmt *plan, { case CMD_SELECT: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "SELECT %u", queryDesc->estate->es_processed); break; case CMD_INSERT: if (queryDesc->estate->es_processed == 1) --- 195,201 ---- { case CMD_SELECT: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "SELECT " UINT64_FORMAT, queryDesc->estate->es_processed); break; case CMD_INSERT: if (queryDesc->estate->es_processed == 1) *************** *** 203,217 **** ProcessQuery(PlannedStmt *plan, else lastOid = InvalidOid; snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "INSERT %u %u", lastOid, queryDesc->estate->es_processed); break; case CMD_UPDATE: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "UPDATE %u", queryDesc->estate->es_processed); break; case CMD_DELETE: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "DELETE %u", queryDesc->estate->es_processed); break; default: strcpy(completionTag, "???"); --- 203,217 ---- else lastOid = InvalidOid; snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "INSERT %u " UINT64_FORMAT, lastOid, queryDesc->estate->es_processed); break; case CMD_UPDATE: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "UPDATE " UINT64_FORMAT, queryDesc->estate->es_processed); break; case CMD_DELETE: snprintf(completionTag, COMPLETION_TAG_BUFSIZE, ! "DELETE " UINT64_FORMAT, queryDesc->estate->es_processed); break; default: strcpy(completionTag, "???"); *** a/src/include/nodes/execnodes.h --- b/src/include/nodes/execnodes.h *************** *** 375,381 **** typedef struct EState List *es_rowMarks; /* List of ExecRowMarks */ ! uint32 es_processed; /* # of tuples processed */ Oid es_lastoid; /* last oid processed (by INSERT) */ int es_top_eflags; /* eflags passed to ExecutorStart */ --- 375,381 ---- List *es_rowMarks; /* List of ExecRowMarks */ ! uint64 es_processed; /* # of tuples processed */ Oid es_lastoid; /* last oid processed (by INSERT) */ int es_top_eflags; /* eflags passed to ExecutorStart */
-- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general