Denis A Ustimenko wrote:
> Hello Bruce!
> 
> You have patched fe-connect.c and dropeed out one check in line 1078:
> 
> < while (rp == NULL || remains.tv_sec > 0 || (remains.tv_sec == 0 && remains.tv_usec > 0))
> ---
> > while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
> 
> As I understand it is dangerous. The remains.tv_usec can be greater than zero while remains.tv_sec is below zero. It must exit form the loop in that conditions.

[ CC to hackers.]

Well, I can see how it could go negative, but if that happens, we have a
bigger problem.  tv_sec on my system is an unsigned int, so I think the
value will show as huge rather than negative.  If you want negative
values, I think you are going to need to use a real signed integer. 
Would you send a context diff (diff -c) against CVS with a fix?

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Thu, 10 Oct 2002 23:48:54 -0400 (EDT)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: Diff for src/interfaces/libpq/fe-connect.c between version 1.195
OK, I have applied the following patch which should fix the problem by
preventing tv_sec from becoming negative.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> Denis A Ustimenko wrote:
> > Hello Bruce!
> > 
> > You have patched fe-connect.c and dropeed out one check in line 1078:
> > 
> > < while (rp == NULL || remains.tv_sec > 0 || (remains.tv_sec == 0 && remains.tv_usec > 0))
> > ---
> > > while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
> > 
> > As I understand it is dangerous. The remains.tv_usec can be greater than zero while remains.tv_sec is below zero. It must exit form the loop in that conditions.
> 
> [ CC to hackers.]
> 
> Well, I can see how it could go negative, but if that happens, we have a
> bigger problem.  tv_sec on my system is an unsigned int, so I think the
> value will show as huge rather than negative.  If you want negative
> values, I think you are going to need to use a real signed integer. 
> Would you send a context diff (diff -c) against CVS with a fix?
> 
> -- 
>   Bruce Momjian                        |  http://candle.pha.pa.us
>   pgman@candle.pha.pa.us               |  (610) 359-1001
>   +  If your life is a hard drive,     |  13 Roberts Road
>   +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
> 

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Index: doc/src/FAQ/FAQ.html
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/FAQ/FAQ.html,v
retrieving revision 1.155
diff -c -c -r1.155 FAQ.html
*** doc/src/FAQ/FAQ.html	10 Oct 2002 03:15:19 -0000	1.155
--- doc/src/FAQ/FAQ.html	11 Oct 2002 04:05:56 -0000
***************
*** 143,148 ****
--- 143,149 ----
      from a function?<BR>
       <A href="#4.26">4.26</A>) Why can't I reliably create/drop
      temporary tables in PL/PgSQL functions?<BR>
+      <A href="#4.27">4.27</A>) What replication options are available?<BR>
       
  
      <H2 align="center">Extending PostgreSQL</H2>
***************
*** 1346,1357 ****
      <H4><A name="4.24">4.24</A>) How do I perform queries using
      multiple databases?</H4>
  
!     <P>There is no way to query any database except the current one.
      Because PostgreSQL loads database-specific system catalogs, it is
      uncertain how a cross-database query should even behave.</P>
  
!     <P>Of course, a client can make simultaneous connections to
!     different databases and merge the information that way.</P>
  
      <H4><A name="4.25">4.25</A>) How do I return multiple rows or
      columns from a function?</H4>
--- 1347,1360 ----
      <H4><A name="4.24">4.24</A>) How do I perform queries using
      multiple databases?</H4>
  
!     <P>There is no way to query a database other than the current one.
      Because PostgreSQL loads database-specific system catalogs, it is
      uncertain how a cross-database query should even behave.</P>
  
!     <P><I>/contrib/dblink</I> allows cross-database queries using
!     function calls. Of course, a client can make simultaneous
!     connections to different databases and merge the results on the
!     client side.</P>
  
      <H4><A name="4.25">4.25</A>) How do I return multiple rows or
      columns from a function?</H4>
***************
*** 1364,1376 ****
  
      <H4><A name="4.26">4.26</A>) Why can't I reliably create/drop
      temporary tables in PL/PgSQL functions?</H4>
!     PL/PgSQL caches function contents, and an unfortunate side effect
      is that if a PL/PgSQL function accesses a temporary table, and that
      table is later dropped and recreated, and the function called
      again, the function will fail because the cached function contents
      still point to the old temporary table. The solution is to use
      <SMALL>EXECUTE</SMALL> for temporary table access in PL/PgSQL. This
!     will cause the query to be reparsed every time. 
  
      <HR>
  
--- 1367,1385 ----
  
      <H4><A name="4.26">4.26</A>) Why can't I reliably create/drop
      temporary tables in PL/PgSQL functions?</H4>
!     <P>PL/PgSQL caches function contents, and an unfortunate side effect
      is that if a PL/PgSQL function accesses a temporary table, and that
      table is later dropped and recreated, and the function called
      again, the function will fail because the cached function contents
      still point to the old temporary table. The solution is to use
      <SMALL>EXECUTE</SMALL> for temporary table access in PL/PgSQL. This
!     will cause the query to be reparsed every time.</P>
! 
!     <H4><A name="4.27">4.27</A>) What replication options are available?
!     </H4>
!     <P>There are several master/slave replication solutions available.
!     These allow only one server to make database changes and the slave 
!     merely allow database reading.
  
      <HR>
  
Index: src/backend/nodes/nodes.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/nodes/nodes.c,v
retrieving revision 1.15
diff -c -c -r1.15 nodes.c
*** src/backend/nodes/nodes.c	20 Jun 2002 20:29:29 -0000	1.15
--- src/backend/nodes/nodes.c	11 Oct 2002 04:05:58 -0000
***************
*** 28,42 ****
   *	  macro makeNode. eg. to create a Resdom node, use makeNode(Resdom)
   *
   */
! Node *
! newNode(Size size, NodeTag tag)
! {
! 	Node	   *newNode;
  
- 	Assert(size >= sizeof(Node));		/* need the tag, at least */
- 
- 	newNode = (Node *) palloc(size);
- 	MemSet((char *) newNode, 0, size);
- 	newNode->type = tag;
- 	return newNode;
- }
--- 28,32 ----
   *	  macro makeNode. eg. to create a Resdom node, use makeNode(Resdom)
   *
   */
! Node *newNodeMacroHolder;
  
Index: src/backend/utils/mmgr/mcxt.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/mmgr/mcxt.c,v
retrieving revision 1.32
diff -c -c -r1.32 mcxt.c
*** src/backend/utils/mmgr/mcxt.c	12 Aug 2002 00:36:12 -0000	1.32
--- src/backend/utils/mmgr/mcxt.c	11 Oct 2002 04:06:02 -0000
***************
*** 453,458 ****
--- 453,481 ----
  }
  
  /*
+  * MemoryContextAllocZero
+  *		Like MemoryContextAlloc, but clears allocated memory
+  *
+  *	We could just call MemoryContextAlloc then clear the memory, but this
+  *	function is called too many times, so we have a separate version.
+  */
+ void *
+ MemoryContextAllocZero(MemoryContext context, Size size)
+ {
+ 	void *ret;
+ 
+ 	AssertArg(MemoryContextIsValid(context));
+ 
+ 	if (!AllocSizeIsValid(size))
+ 		elog(ERROR, "MemoryContextAllocZero: invalid request size %lu",
+ 			 (unsigned long) size);
+ 
+ 	ret = (*context->methods->alloc) (context, size);
+ 	MemSet(ret, 0, size);
+ 	return ret;
+ }
+ 
+ /*
   * pfree
   *		Release an allocated chunk.
   */
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/nodes/nodes.h,v
retrieving revision 1.118
diff -c -c -r1.118 nodes.h
*** src/include/nodes/nodes.h	31 Aug 2002 22:10:47 -0000	1.118
--- src/include/nodes/nodes.h	11 Oct 2002 04:06:05 -0000
***************
*** 261,266 ****
--- 261,284 ----
  
  #define nodeTag(nodeptr)		(((Node*)(nodeptr))->type)
  
+ /*
+  *	There is no way to dereference the palloc'ed pointer to assign the
+  *	tag, and return the pointer itself, so we need a holder variable.
+  *	Fortunately, this function isn't recursive so we just define
+  *	a global variable for this purpose.
+  */
+ extern Node *newNodeMacroHolder;
+ 
+ #define newNode(size, tag) \
+ ( \
+ 	AssertMacro((size) >= sizeof(Node)),		/* need the tag, at least */ \
+ \
+ 	newNodeMacroHolder = (Node *) palloc0(size), \
+ 	newNodeMacroHolder->type = (tag), \
+ 	newNodeMacroHolder \
+ )
+ 
+ 
  #define makeNode(_type_)		((_type_ *) newNode(sizeof(_type_),T_##_type_))
  #define NodeSetTag(nodeptr,t)	(((Node*)(nodeptr))->type = (t))
  
***************
*** 281,291 ****
   *					  extern declarations follow
   * ----------------------------------------------------------------
   */
- 
- /*
-  * nodes/nodes.c
-  */
- extern Node *newNode(Size size, NodeTag tag);
  
  /*
   * nodes/{outfuncs.c,print.c}
--- 299,304 ----
Index: src/include/utils/palloc.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/utils/palloc.h,v
retrieving revision 1.19
diff -c -c -r1.19 palloc.h
*** src/include/utils/palloc.h	20 Jun 2002 20:29:53 -0000	1.19
--- src/include/utils/palloc.h	11 Oct 2002 04:06:06 -0000
***************
*** 46,53 ****
--- 46,56 ----
   * Fundamental memory-allocation operations (more are in utils/memutils.h)
   */
  extern void *MemoryContextAlloc(MemoryContext context, Size size);
+ extern void *MemoryContextAllocZero(MemoryContext context, Size size);
  
  #define palloc(sz)	MemoryContextAlloc(CurrentMemoryContext, (sz))
+ 
+ #define palloc0(sz)	MemoryContextAllocZero(CurrentMemoryContext, (sz))
  
  extern void pfree(void *pointer);
  
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.206
diff -c -c -r1.206 fe-connect.c
*** src/interfaces/libpq/fe-connect.c	3 Oct 2002 17:09:42 -0000	1.206
--- src/interfaces/libpq/fe-connect.c	11 Oct 2002 04:06:15 -0000
***************
*** 1131,1137 ****
  				return 0;
  			}
  
! 			remains.tv_sec = finish_time - current_time;
  			remains.tv_usec = 0;
  		}
  	}
--- 1131,1140 ----
  				return 0;
  			}
  
! 			if (finish_time > current_time)
! 				remains.tv_sec = finish_time - current_time;
! 			else
! 				remains.tv_sec = 0;
  			remains.tv_usec = 0;
  		}
  	}
Fri, 11 Oct 2002 00:10:42 -0400 (EDT)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: Diff for src/interfaces/libpq/fe-connect.c between version