Skip site navigation (1) Skip section navigation (2)

Re: [JDBC] Strange server error with current 8.0beta driver

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Oliver Jowett <oliver(at)opencloud(dot)com>
Cc: Barry Lind <blind(at)xythos(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: [JDBC] Strange server error with current 8.0beta driver
Date: 2004-11-28 22:23:04
Message-ID: 21575.1101680584@sss.pgh.pa.us (view raw or flat)
Thread:
Lists: pgsql-hackerspgsql-jdbc
Oliver Jowett <oliver(at)opencloud(dot)com> writes:
>> Perhaps PerformCursorOpen should copy the query tree before planning, or 
>> plan in a different memory context?

> Patch attached. It moves query planning inside the new portal's memory 
> context. With this applied I can run Barry's testcase without errors, 
> and valgrind seems OK with it too.

I think the better solution is the first way (copy the querytree first).
The problem with the way you did it is that all the temporary structures
built by the planner will be left behind in the cursor's memory context,
and can't be reclaimed until the cursor is destroyed.  In the case of a
complex query that could represent a pretty serious memory leak.  It
seems better to eat the cost of copying the querytree an extra time,
especially since this way forms a patch that's easy to reverse whenever
we fix the planner to be less cavalier about scribbling on its input.

I've applied the attached patch instead (and analogously in 7.4 branch).
Would you confirm it fixes the problem you see?

			regards, tom lane

*** src/backend/commands/portalcmds.c.orig	Thu Sep 16 12:58:28 2004
--- src/backend/commands/portalcmds.c	Sun Nov 28 17:02:22 2004
***************
*** 62,73 ****
  		RequireTransactionChain((void *) stmt, "DECLARE CURSOR");
  
  	/*
  	 * The query has been through parse analysis, but not rewriting or
  	 * planning as yet.  Note that the grammar ensured we have a SELECT
  	 * query, so we are not expecting rule rewriting to do anything
  	 * strange.
  	 */
! 	rewritten = QueryRewrite((Query *) stmt->query);
  	if (list_length(rewritten) != 1 || !IsA(linitial(rewritten), Query))
  		elog(ERROR, "unexpected rewrite result");
  	query = (Query *) linitial(rewritten);
--- 62,82 ----
  		RequireTransactionChain((void *) stmt, "DECLARE CURSOR");
  
  	/*
+ 	 * Because the planner is not cool about not scribbling on its input,
+ 	 * we make a preliminary copy of the source querytree.  This prevents
+ 	 * problems in the case that the DECLARE CURSOR is in a portal and is
+ 	 * executed repeatedly.  XXX the planner really shouldn't modify its
+ 	 * input ... FIXME someday.
+ 	 */
+ 	query = copyObject(stmt->query);
+ 
+ 	/*
  	 * The query has been through parse analysis, but not rewriting or
  	 * planning as yet.  Note that the grammar ensured we have a SELECT
  	 * query, so we are not expecting rule rewriting to do anything
  	 * strange.
  	 */
! 	rewritten = QueryRewrite(query);
  	if (list_length(rewritten) != 1 || !IsA(linitial(rewritten), Query))
  		elog(ERROR, "unexpected rewrite result");
  	query = (Query *) linitial(rewritten);

In response to

pgsql-hackers by date

Next:From: Thomas HallgrenDate: 2004-11-28 22:23:29
Subject: Re: Status of server side Large Object support?
Previous:From: Simon RiggsDate: 2004-11-28 22:16:19
Subject: Re: Stopgap solution for table-size-estimate updating

pgsql-jdbc by date

Next:From: Antje.StejskalDate: 2004-11-29 12:34:55
Subject: Bug in JDBC-Driver?
Previous:From: jonathan.listerDate: 2004-11-28 17:00:23
Subject: Re: Is there a size limit on setBinaryStream?

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group