Search Postgresql Archives

Re: [HACKERS] Insert result does not match record count

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux