diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 47cc693e9f47ea74dfec9eb8301445d59e9bc70c..07caedde8be9a7a69da264bcd08fa004b11332f8 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 1994-5, Regents of the University of California
  *
- *	  $Id: explain.c,v 1.45 1999/08/16 23:47:23 tgl Exp $
+ *	  $Id: explain.c,v 1.46 1999/08/31 01:28:28 tgl Exp $
  *
  */
 
@@ -31,6 +31,9 @@ static char *Explain_PlanToString(Plan *plan, ExplainState *es);
 static void printLongNotice(const char *header, const char *message);
 static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest);
 
+/* Convert a null string pointer into "<>" */
+#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
+
 
 /*
  * ExplainQuery -
diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c
index e98a5c5f4d59486c6c4a52c1b59efb97d36270b2..d25a2a00a79d1f436b7d435672e299e9838e24d9 100644
--- a/src/backend/lib/stringinfo.c
+++ b/src/backend/lib/stringinfo.c
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *	  $Id: stringinfo.c,v 1.20 1999/07/17 20:16:59 momjian Exp $
+ *	  $Id: stringinfo.c,v 1.21 1999/08/31 01:28:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,7 +17,6 @@
 #include "postgres.h"
 #include "lib/stringinfo.h"
 
-#ifdef NOT_USED
 /*
  * makeStringInfo
  *
@@ -36,7 +35,6 @@ makeStringInfo(void)
 
 	return res;
 }
-#endif
 
 /*
  * initStringInfo
@@ -49,7 +47,7 @@ initStringInfo(StringInfo str)
 {
 	int			size = 256;		/* initial default buffer size */
 
-	str->data = palloc(size);
+	str->data = (char *) palloc(size);
 	if (str->data == NULL)
 		elog(ERROR,
 			 "initStringInfo: Out of memory (%d bytes requested)", size);
@@ -68,7 +66,6 @@ static void
 enlargeStringInfo(StringInfo str, int needed)
 {
 	int			newlen;
-	char	   *newdata;
 
 	needed += str->len + 1;		/* total space required now */
 	if (needed <= str->maxlen)
@@ -84,15 +81,11 @@ enlargeStringInfo(StringInfo str, int needed)
 	while (needed > newlen)
 		newlen = 2 * newlen;
 
-	newdata = palloc(newlen);
-	if (newdata == NULL)
+	str->data = (char *) repalloc(str->data, newlen);
+	if (str->data == NULL)
 		elog(ERROR,
-		"enlargeStringInfo: Out of memory (%d bytes requested)", newlen);
+			 "enlargeStringInfo: Out of memory (%d bytes requested)", newlen);
 
-	/* OK, transfer data into new buffer, and release old buffer */
-	memcpy(newdata, str->data, str->len + 1);
-	pfree(str->data);
-	str->data = newdata;
 	str->maxlen = newlen;
 }
 
@@ -103,29 +96,41 @@ enlargeStringInfo(StringInfo str, int needed)
  * and append it to whatever is already in str.  More space is allocated
  * to str if necessary.  This is sort of like a combination of sprintf and
  * strcat.
- *
- * CAUTION: the current implementation has a 1K limit on the amount of text
- * generated in a single call (not on the total string length).
  */
 void
 appendStringInfo(StringInfo str, const char *fmt,...)
 {
 	va_list		args;
-	char		buffer[1024];
-	int			buflen;
+	int			avail,
+				nprinted;
 
 	Assert(str != NULL);
 
-	va_start(args, fmt);
-	buflen = vsnprintf(buffer, sizeof(buffer), fmt, args);
-	va_end(args);
-
-	/* Make more room if needed */
-	enlargeStringInfo(str, buflen);
-
-	/* OK, append the data, including the trailing null */
-	memcpy(str->data + str->len, buffer, buflen + 1);
-	str->len += buflen;
+	for (;;)
+	{
+		/*----------
+		 * Try to format the given string into the available space;
+		 * but if there's hardly any space, don't bother trying,
+		 * just fall through to enlarge the buffer first.
+		 *----------
+		 */
+		avail = str->maxlen - str->len - 1;
+		if (avail > 16)
+		{
+			va_start(args, fmt);
+			nprinted = vsnprintf(str->data + str->len, avail,
+								 fmt, args);
+			va_end(args);
+			if (nprinted < avail-1)
+			{
+				/* Success.  Note nprinted does not include trailing null. */
+				str->len += nprinted;
+				break;
+			}
+		}
+		/* Double the buffer size and try again. */
+		enlargeStringInfo(str, str->maxlen);
+	}
 }
 
 /*------------------------
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 226dbb1cef0d16f709b8080966440a0a05bb6251..13e32ed54fe330be8d1d887cecbefb9841e16f7d 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *	$Id: outfuncs.c,v 1.94 1999/08/21 03:48:58 tgl Exp $
+ *	$Id: outfuncs.c,v 1.95 1999/08/31 01:28:32 tgl Exp $
  *
  * NOTES
  *	  Every (plan) node in POSTGRES has an associated "out" routine which
@@ -42,6 +42,10 @@
 static void _outDatum(StringInfo str, Datum value, Oid type);
 static void _outNode(StringInfo str, void *obj);
 
+/* Convert a null string pointer into "<>" */
+#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
+
+
 /*
  * _outIntList -
  *	   converts a List of integers
diff --git a/src/backend/port/snprintf.c b/src/backend/port/snprintf.c
index e6ee698e66da24e3079519e1f6b33dd65a79f849..95a79a504d802e056fa208d1d04f08a5f1c13fa1 100644
--- a/src/backend/port/snprintf.c
+++ b/src/backend/port/snprintf.c
@@ -74,7 +74,7 @@ typedef unsigned long ulong_long;
  * causing nast effects.
  **************************************************************/
 
-/*static char _id[] = "$Id: snprintf.c,v 1.25 1999/07/17 20:17:28 momjian Exp $";*/
+/*static char _id[] = "$Id: snprintf.c,v 1.26 1999/08/31 01:28:37 tgl Exp $";*/
 static char *end;
 static int	SnprfOverflow;
 
@@ -98,14 +98,14 @@ snprintf(char *str, size_t count, const char *fmt,...)
 int
 vsnprintf(char *str, size_t count, const char *fmt, va_list args)
 {
-	str[0] = 0;
+	str[0] = '\0';
 	end = str + count - 1;
 	SnprfOverflow = 0;
 	dopr(str, fmt, args);
 	if (count > 0)
-		end[0] = 0;
+		end[0] = '\0';
 	if (SnprfOverflow)
-		elog(NOTICE, "vsnprintf overflow, len = %d, str = %s",
+		elog(DEBUG, "vsnprintf overflow, len = %d, str = %s",
 			 count, str);
 	return strlen(str);
 }
@@ -152,6 +152,7 @@ dopr(char *buffer, const char *format, va_list args)
 				{
 					case 0:
 						dostr("**end of format**", 0);
+						*output = '\0';
 						return;
 					case '-':
 						ljust = 1;
@@ -287,7 +288,7 @@ dopr(char *buffer, const char *format, va_list args)
 				break;
 		}
 	}
-	*output = 0;
+	*output = '\0';
 }
 
 static void
diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h
index da806aa433c6c07282ac2bb934a61de7301f0ac7..afdad2f8d32490130a0f0d17ccb4e56d3f2d63fd 100644
--- a/src/include/lib/stringinfo.h
+++ b/src/include/lib/stringinfo.h
@@ -9,7 +9,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: stringinfo.h,v 1.13 1999/05/26 12:56:27 momjian Exp $
+ * $Id: stringinfo.h,v 1.14 1999/08/31 01:28:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -60,13 +60,11 @@ typedef StringInfoData *StringInfo;
  *-------------------------
  */
 
-#ifdef NOT_USED
 /*------------------------
  * makeStringInfo
  * Create an empty 'StringInfoData' & return a pointer to it.
  */
 extern StringInfo makeStringInfo(void);
-#endif
 
 /*------------------------
  * initStringInfo
@@ -81,8 +79,6 @@ extern void initStringInfo(StringInfo str);
  * and append it to whatever is already in str.  More space is allocated
  * to str if necessary.  This is sort of like a combination of sprintf and
  * strcat.
- * CAUTION: the current implementation has a 1K limit on the amount of text
- * generated in a single call (not on the total string length).
  */
 extern void appendStringInfo(StringInfo str, const char *fmt,...);
 
@@ -101,11 +97,4 @@ extern void appendStringInfoChar(StringInfo str, char ch);
 extern void appendBinaryStringInfo(StringInfo str,
 					   const char *data, int datalen);
 
-/*------------------------
- * stringStringInfo
- * Return the string itself or "<>" if it is NULL.
- * This is just a convenience macro used by many callers of appendStringInfo.
- */
-#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
-
 #endif	 /* STRINGINFO_H */