From 0a202070603bf38ce2e2fc11a7f897fc06603b80 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 24 Mar 2006 04:32:13 +0000
Subject: [PATCH] Arrange to emit a description of the current XLOG record as
 error context when an error occurs during xlog replay.  Also, replace the
 former risky 'write into a fixed-size buffer with no overflow detection' API
 for XLOG record description routines; use an expansible StringInfo instead. 
 (The latter accounts for most of the patch bulk.)

Qingqing Zhou
---
 src/backend/access/gist/gistxlog.c     | 32 +++++-----
 src/backend/access/hash/hash.c         |  4 +-
 src/backend/access/heap/heapam.c       | 34 +++++-----
 src/backend/access/nbtree/nbtxlog.c    | 42 ++++++-------
 src/backend/access/transam/clog.c      | 10 +--
 src/backend/access/transam/multixact.c | 14 ++---
 src/backend/access/transam/xact.c      | 42 ++++++-------
 src/backend/access/transam/xlog.c      | 86 +++++++++++++++++++-------
 src/backend/commands/dbcommands.c      | 10 +--
 src/backend/commands/sequence.c        | 10 +--
 src/backend/commands/tablespace.c      | 11 ++--
 src/backend/storage/smgr/smgr.c        | 10 +--
 src/include/access/clog.h              |  4 +-
 src/include/access/gist_private.h      |  4 +-
 src/include/access/hash.h              |  4 +-
 src/include/access/heapam.h            |  4 +-
 src/include/access/multixact.h         |  4 +-
 src/include/access/nbtree.h            |  4 +-
 src/include/access/xact.h              |  4 +-
 src/include/access/xlog.h              |  5 +-
 src/include/access/xlog_internal.h     |  4 +-
 src/include/commands/dbcommands.h      |  4 +-
 src/include/commands/sequence.h        |  4 +-
 src/include/commands/tablespace.h      |  4 +-
 src/include/storage/smgr.h             |  4 +-
 25 files changed, 198 insertions(+), 160 deletions(-)

diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index e60317c0b34..911c9a02a9c 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *			 $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.10 2006/03/05 15:58:20 momjian Exp $
+ *			 $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.11 2006/03/24 04:32:12 tgl Exp $
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
@@ -442,67 +442,67 @@ gist_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 static void
-out_target(char *buf, RelFileNode node, ItemPointerData key)
+out_target(StringInfo buf, RelFileNode node, ItemPointerData key)
 {
-	sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
+	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
 			node.spcNode, node.dbNode, node.relNode,
 			ItemPointerGetBlockNumber(&key),
 			ItemPointerGetOffsetNumber(&key));
 }
 
 static void
-out_gistxlogEntryUpdate(char *buf, gistxlogEntryUpdate *xlrec)
+out_gistxlogEntryUpdate(StringInfo buf, gistxlogEntryUpdate *xlrec)
 {
 	out_target(buf, xlrec->node, xlrec->key);
-	sprintf(buf + strlen(buf), "; block number %u",
-			xlrec->blkno);
+	appendStringInfo(buf, "; block number %u", xlrec->blkno);
 }
 
 static void
-out_gistxlogPageSplit(char *buf, gistxlogPageSplit *xlrec)
+out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec)
 {
-	strcat(buf, "page_split: ");
+	appendStringInfo(buf, "page_split: ");
 	out_target(buf, xlrec->node, xlrec->key);
-	sprintf(buf + strlen(buf), "; block number %u splits to %d pages",
+	appendStringInfo(buf, "; block number %u splits to %d pages",
 			xlrec->origblkno, xlrec->npage);
 }
 
 void
-gist_desc(char *buf, uint8 xl_info, char *rec)
+gist_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
 	switch (info)
 	{
 		case XLOG_GIST_ENTRY_UPDATE:
-			strcat(buf, "entry_update: ");
+			appendStringInfo(buf, "entry_update: ");
 			out_gistxlogEntryUpdate(buf, (gistxlogEntryUpdate *) rec);
 			break;
 		case XLOG_GIST_ENTRY_DELETE:
-			strcat(buf, "entry_delete: ");
+			appendStringInfo(buf, "entry_delete: ");
 			out_gistxlogEntryUpdate(buf, (gistxlogEntryUpdate *) rec);
 			break;
 		case XLOG_GIST_NEW_ROOT:
-			strcat(buf, "new_root: ");
+			appendStringInfo(buf, "new_root: ");
 			out_target(buf, ((gistxlogEntryUpdate *) rec)->node, ((gistxlogEntryUpdate *) rec)->key);
 			break;
 		case XLOG_GIST_PAGE_SPLIT:
 			out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec);
 			break;
 		case XLOG_GIST_CREATE_INDEX:
-			sprintf(buf + strlen(buf), "create_index: rel %u/%u/%u",
+			appendStringInfo(buf, "create_index: rel %u/%u/%u",
 					((RelFileNode *) rec)->spcNode,
 					((RelFileNode *) rec)->dbNode,
 					((RelFileNode *) rec)->relNode);
 			break;
 		case XLOG_GIST_INSERT_COMPLETE:
-			sprintf(buf + strlen(buf), "complete_insert: rel %u/%u/%u",
+			appendStringInfo(buf, "complete_insert: rel %u/%u/%u",
 					((gistxlogInsertComplete *) rec)->node.spcNode,
 					((gistxlogInsertComplete *) rec)->node.dbNode,
 					((gistxlogInsertComplete *) rec)->node.relNode);
 			break;
 		default:
-			elog(PANIC, "gist_desc: unknown op code %u", info);
+			appendStringInfo(buf, "unknown gist op code %u", info);
+			break;
 	}
 }
 
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index f78c58f5307..8e232414dc8 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.87 2006/03/05 15:58:20 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.88 2006/03/24 04:32:12 tgl Exp $
  *
  * NOTES
  *	  This file contains only the public interface routines.
@@ -675,6 +675,6 @@ hash_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-hash_desc(char *buf, uint8 xl_info, char *rec)
+hash_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 }
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 8e5bb4953e5..6327ce71173 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.208 2006/03/05 15:58:21 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.209 2006/03/24 04:32:12 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -3363,16 +3363,16 @@ heap_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 static void
-out_target(char *buf, xl_heaptid *target)
+out_target(StringInfo buf, xl_heaptid *target)
 {
-	sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
+	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
 			target->node.spcNode, target->node.dbNode, target->node.relNode,
 			ItemPointerGetBlockNumber(&(target->tid)),
 			ItemPointerGetOffsetNumber(&(target->tid)));
 }
 
 void
-heap_desc(char *buf, uint8 xl_info, char *rec)
+heap_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -3381,14 +3381,14 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_heap_insert *xlrec = (xl_heap_insert *) rec;
 
-		strcat(buf, "insert: ");
+		appendStringInfo(buf, "insert: ");
 		out_target(buf, &(xlrec->target));
 	}
 	else if (info == XLOG_HEAP_DELETE)
 	{
 		xl_heap_delete *xlrec = (xl_heap_delete *) rec;
 
-		strcat(buf, "delete: ");
+		appendStringInfo(buf, "delete: ");
 		out_target(buf, &(xlrec->target));
 	}
 	else if (info == XLOG_HEAP_UPDATE || info == XLOG_HEAP_MOVE)
@@ -3396,11 +3396,11 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
 		xl_heap_update *xlrec = (xl_heap_update *) rec;
 
 		if (info == XLOG_HEAP_UPDATE)
-			strcat(buf, "update: ");
+			appendStringInfo(buf, "update: ");
 		else
-			strcat(buf, "move: ");
+			appendStringInfo(buf, "move: ");
 		out_target(buf, &(xlrec->target));
-		sprintf(buf + strlen(buf), "; new %u/%u",
+		appendStringInfo(buf, "; new %u/%u",
 				ItemPointerGetBlockNumber(&(xlrec->newtid)),
 				ItemPointerGetOffsetNumber(&(xlrec->newtid)));
 	}
@@ -3408,7 +3408,7 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_heap_clean *xlrec = (xl_heap_clean *) rec;
 
-		sprintf(buf + strlen(buf), "clean: rel %u/%u/%u; blk %u",
+		appendStringInfo(buf, "clean: rel %u/%u/%u; blk %u",
 				xlrec->node.spcNode, xlrec->node.dbNode,
 				xlrec->node.relNode, xlrec->block);
 	}
@@ -3416,7 +3416,7 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_heap_newpage *xlrec = (xl_heap_newpage *) rec;
 
-		sprintf(buf + strlen(buf), "newpage: rel %u/%u/%u; blk %u",
+		appendStringInfo(buf, "newpage: rel %u/%u/%u; blk %u",
 				xlrec->node.spcNode, xlrec->node.dbNode,
 				xlrec->node.relNode, xlrec->blkno);
 	}
@@ -3425,16 +3425,16 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
 		xl_heap_lock *xlrec = (xl_heap_lock *) rec;
 
 		if (xlrec->shared_lock)
-			strcat(buf, "shared_lock: ");
+			appendStringInfo(buf, "shared_lock: ");
 		else
-			strcat(buf, "exclusive_lock: ");
+			appendStringInfo(buf, "exclusive_lock: ");
 		if (xlrec->xid_is_mxact)
-			strcat(buf, "mxid ");
+			appendStringInfo(buf, "mxid ");
 		else
-			strcat(buf, "xid ");
-		sprintf(buf + strlen(buf), "%u ", xlrec->locking_xid);
+			appendStringInfo(buf, "xid ");
+		appendStringInfo(buf, "%u ", xlrec->locking_xid);
 		out_target(buf, &(xlrec->target));
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index 2e30556fe1b..2b5c8f73776 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.26 2006/03/05 15:58:21 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.27 2006/03/24 04:32:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -650,16 +650,16 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 static void
-out_target(char *buf, xl_btreetid *target)
+out_target(StringInfo buf, xl_btreetid *target)
 {
-	sprintf(buf + strlen(buf), "rel %u/%u/%u; tid %u/%u",
+	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
 			target->node.spcNode, target->node.dbNode, target->node.relNode,
 			ItemPointerGetBlockNumber(&(target->tid)),
 			ItemPointerGetOffsetNumber(&(target->tid)));
 }
 
 void
-btree_desc(char *buf, uint8 xl_info, char *rec)
+btree_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -669,7 +669,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
 
-				strcat(buf, "insert: ");
+				appendStringInfo(buf, "insert: ");
 				out_target(buf, &(xlrec->target));
 				break;
 			}
@@ -677,7 +677,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
 
-				strcat(buf, "insert_upper: ");
+				appendStringInfo(buf, "insert_upper: ");
 				out_target(buf, &(xlrec->target));
 				break;
 			}
@@ -685,7 +685,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_insert *xlrec = (xl_btree_insert *) rec;
 
-				strcat(buf, "insert_meta: ");
+				appendStringInfo(buf, "insert_meta: ");
 				out_target(buf, &(xlrec->target));
 				break;
 			}
@@ -693,9 +693,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_split *xlrec = (xl_btree_split *) rec;
 
-				strcat(buf, "split_l: ");
+				appendStringInfo(buf, "split_l: ");
 				out_target(buf, &(xlrec->target));
-				sprintf(buf + strlen(buf), "; oth %u; rgh %u",
+				appendStringInfo(buf, "; oth %u; rgh %u",
 						xlrec->otherblk, xlrec->rightblk);
 				break;
 			}
@@ -703,9 +703,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_split *xlrec = (xl_btree_split *) rec;
 
-				strcat(buf, "split_r: ");
+				appendStringInfo(buf, "split_r: ");
 				out_target(buf, &(xlrec->target));
-				sprintf(buf + strlen(buf), "; oth %u; rgh %u",
+				appendStringInfo(buf, "; oth %u; rgh %u",
 						xlrec->otherblk, xlrec->rightblk);
 				break;
 			}
@@ -713,9 +713,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_split *xlrec = (xl_btree_split *) rec;
 
-				strcat(buf, "split_l_root: ");
+				appendStringInfo(buf, "split_l_root: ");
 				out_target(buf, &(xlrec->target));
-				sprintf(buf + strlen(buf), "; oth %u; rgh %u",
+				appendStringInfo(buf, "; oth %u; rgh %u",
 						xlrec->otherblk, xlrec->rightblk);
 				break;
 			}
@@ -723,9 +723,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_split *xlrec = (xl_btree_split *) rec;
 
-				strcat(buf, "split_r_root: ");
+				appendStringInfo(buf, "split_r_root: ");
 				out_target(buf, &(xlrec->target));
-				sprintf(buf + strlen(buf), "; oth %u; rgh %u",
+				appendStringInfo(buf, "; oth %u; rgh %u",
 						xlrec->otherblk, xlrec->rightblk);
 				break;
 			}
@@ -733,7 +733,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_delete *xlrec = (xl_btree_delete *) rec;
 
-				sprintf(buf + strlen(buf), "delete: rel %u/%u/%u; blk %u",
+				appendStringInfo(buf, "delete: rel %u/%u/%u; blk %u",
 						xlrec->node.spcNode, xlrec->node.dbNode,
 						xlrec->node.relNode, xlrec->block);
 				break;
@@ -743,9 +743,9 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;
 
-				strcat(buf, "delete_page: ");
+				appendStringInfo(buf, "delete_page: ");
 				out_target(buf, &(xlrec->target));
-				sprintf(buf + strlen(buf), "; dead %u; left %u; right %u",
+				appendStringInfo(buf, "; dead %u; left %u; right %u",
 						xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);
 				break;
 			}
@@ -753,7 +753,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
 
-				sprintf(buf + strlen(buf), "newroot: rel %u/%u/%u; root %u lev %u",
+				appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",
 						xlrec->node.spcNode, xlrec->node.dbNode,
 						xlrec->node.relNode,
 						xlrec->rootblk, xlrec->level);
@@ -763,7 +763,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 			{
 				xl_btree_newmeta *xlrec = (xl_btree_newmeta *) rec;
 
-				sprintf(buf + strlen(buf), "newmeta: rel %u/%u/%u; root %u lev %u fast %u lev %u",
+				appendStringInfo(buf, "newmeta: rel %u/%u/%u; root %u lev %u fast %u lev %u",
 						xlrec->node.spcNode, xlrec->node.dbNode,
 						xlrec->node.relNode,
 						xlrec->meta.root, xlrec->meta.level,
@@ -771,7 +771,7 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
 				break;
 			}
 		default:
-			strcat(buf, "UNKNOWN");
+			appendStringInfo(buf, "UNKNOWN");
 			break;
 	}
 }
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 82c259e7fb5..49f1e72c6c8 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -24,7 +24,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.37 2006/03/05 15:58:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.38 2006/03/24 04:32:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -412,17 +412,17 @@ clog_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-clog_desc(char *buf, uint8 xl_info, char *rec)
+clog_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
-	uint8		info = xl_info & ~XLR_INFO_MASK;
+	uint8			info = xl_info & ~XLR_INFO_MASK;
 
 	if (info == CLOG_ZEROPAGE)
 	{
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
-		sprintf(buf + strlen(buf), "zeropage: %d", pageno);
+		appendStringInfo(buf, "zeropage: %d", pageno);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index b7cf1362c3e..6fe1d1a6728 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.16 2006/03/05 15:58:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.17 2006/03/24 04:32:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1887,7 +1887,7 @@ multixact_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-multixact_desc(char *buf, uint8 xl_info, char *rec)
+multixact_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -1896,25 +1896,25 @@ multixact_desc(char *buf, uint8 xl_info, char *rec)
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
-		sprintf(buf + strlen(buf), "zero offsets page: %d", pageno);
+		appendStringInfo(buf, "zero offsets page: %d", pageno);
 	}
 	else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
 	{
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
-		sprintf(buf + strlen(buf), "zero members page: %d", pageno);
+		appendStringInfo(buf, "zero members page: %d", pageno);
 	}
 	else if (info == XLOG_MULTIXACT_CREATE_ID)
 	{
 		xl_multixact_create *xlrec = (xl_multixact_create *) rec;
 		int			i;
 
-		sprintf(buf + strlen(buf), "create multixact %u offset %u:",
+		appendStringInfo(buf, "create multixact %u offset %u:",
 				xlrec->mid, xlrec->moff);
 		for (i = 0; i < xlrec->nxids; i++)
-			sprintf(buf + strlen(buf), " %u", xlrec->xids[i]);
+			appendStringInfo(buf, " %u", xlrec->xids[i]);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index ec5f036f8dc..a33e0df7c45 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.217 2006/03/05 15:58:22 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.218 2006/03/24 04:32:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4179,22 +4179,22 @@ xact_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 static void
-xact_desc_commit(char *buf, xl_xact_commit *xlrec)
+xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
 {
 	struct tm  *tm = localtime(&xlrec->xtime);
 	int			i;
 
-	sprintf(buf + strlen(buf), "%04u-%02u-%02u %02u:%02u:%02u",
+	appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
 			tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 			tm->tm_hour, tm->tm_min, tm->tm_sec);
 	if (xlrec->nrels > 0)
 	{
-		sprintf(buf + strlen(buf), "; rels:");
+		appendStringInfo(buf, "; rels:");
 		for (i = 0; i < xlrec->nrels; i++)
 		{
 			RelFileNode rnode = xlrec->xnodes[i];
 
-			sprintf(buf + strlen(buf), " %u/%u/%u",
+			appendStringInfo(buf, " %u/%u/%u",
 					rnode.spcNode, rnode.dbNode, rnode.relNode);
 		}
 	}
@@ -4203,29 +4203,29 @@ xact_desc_commit(char *buf, xl_xact_commit *xlrec)
 		TransactionId *xacts = (TransactionId *)
 		&xlrec->xnodes[xlrec->nrels];
 
-		sprintf(buf + strlen(buf), "; subxacts:");
+		appendStringInfo(buf, "; subxacts:");
 		for (i = 0; i < xlrec->nsubxacts; i++)
-			sprintf(buf + strlen(buf), " %u", xacts[i]);
+			appendStringInfo(buf, " %u", xacts[i]);
 	}
 }
 
 static void
-xact_desc_abort(char *buf, xl_xact_abort *xlrec)
+xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
 {
 	struct tm  *tm = localtime(&xlrec->xtime);
 	int			i;
 
-	sprintf(buf + strlen(buf), "%04u-%02u-%02u %02u:%02u:%02u",
+	appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
 			tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 			tm->tm_hour, tm->tm_min, tm->tm_sec);
 	if (xlrec->nrels > 0)
 	{
-		sprintf(buf + strlen(buf), "; rels:");
+		appendStringInfo(buf, "; rels:");
 		for (i = 0; i < xlrec->nrels; i++)
 		{
 			RelFileNode rnode = xlrec->xnodes[i];
 
-			sprintf(buf + strlen(buf), " %u/%u/%u",
+			appendStringInfo(buf, " %u/%u/%u",
 					rnode.spcNode, rnode.dbNode, rnode.relNode);
 		}
 	}
@@ -4234,49 +4234,49 @@ xact_desc_abort(char *buf, xl_xact_abort *xlrec)
 		TransactionId *xacts = (TransactionId *)
 		&xlrec->xnodes[xlrec->nrels];
 
-		sprintf(buf + strlen(buf), "; subxacts:");
+		appendStringInfo(buf, "; subxacts:");
 		for (i = 0; i < xlrec->nsubxacts; i++)
-			sprintf(buf + strlen(buf), " %u", xacts[i]);
+			appendStringInfo(buf, " %u", xacts[i]);
 	}
 }
 
 void
-xact_desc(char *buf, uint8 xl_info, char *rec)
+xact_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
-	uint8		info = xl_info & ~XLR_INFO_MASK;
+	uint8			info = xl_info & ~XLR_INFO_MASK;
 
 	if (info == XLOG_XACT_COMMIT)
 	{
 		xl_xact_commit *xlrec = (xl_xact_commit *) rec;
 
-		strcat(buf, "commit: ");
+		appendStringInfo(buf, "commit: ");
 		xact_desc_commit(buf, xlrec);
 	}
 	else if (info == XLOG_XACT_ABORT)
 	{
 		xl_xact_abort *xlrec = (xl_xact_abort *) rec;
 
-		strcat(buf, "abort: ");
+		appendStringInfo(buf, "abort: ");
 		xact_desc_abort(buf, xlrec);
 	}
 	else if (info == XLOG_XACT_PREPARE)
 	{
-		strcat(buf, "prepare");
+		appendStringInfo(buf, "prepare");
 	}
 	else if (info == XLOG_XACT_COMMIT_PREPARED)
 	{
 		xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
 
-		sprintf(buf + strlen(buf), "commit %u: ", xlrec->xid);
+		appendStringInfo(buf, "commit %u: ", xlrec->xid);
 		xact_desc_commit(buf, &xlrec->crec);
 	}
 	else if (info == XLOG_XACT_ABORT_PREPARED)
 	{
 		xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
 
-		sprintf(buf + strlen(buf), "abort %u: ", xlrec->xid);
+		appendStringInfo(buf, "abort %u: ", xlrec->xid);
 		xact_desc_abort(buf, &xlrec->arec);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ca52f409a35..bcdb003eaf2 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.227 2006/03/05 15:58:22 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.228 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -498,10 +498,11 @@ static char *str_time(time_t tnow);
 static void issue_xlog_fsync(void);
 
 #ifdef WAL_DEBUG
-static void xlog_outrec(char *buf, XLogRecord *record);
+static void xlog_outrec(StringInfo buf, XLogRecord *record);
 #endif
 static bool read_backup_label(XLogRecPtr *checkPointLoc);
 static void remove_backup_label(void);
+static void rm_redo_error_callback(void *arg);
 
 
 /*
@@ -852,16 +853,19 @@ begin:;
 #ifdef WAL_DEBUG
 	if (XLOG_DEBUG)
 	{
-		char		buf[8192];
+		StringInfoData	buf;
 
-		sprintf(buf, "INSERT @ %X/%X: ", RecPtr.xlogid, RecPtr.xrecoff);
-		xlog_outrec(buf, record);
+		initStringInfo(&buf);
+		appendStringInfo(&buf, "INSERT @ %X/%X: ", 
+							RecPtr.xlogid, RecPtr.xrecoff);
+		xlog_outrec(&buf, record);
 		if (rdata->data != NULL)
 		{
-			strcat(buf, " - ");
-			RmgrTable[record->xl_rmid].rm_desc(buf, record->xl_info, rdata->data);
+			appendStringInfo(&buf, " - ");
+			RmgrTable[record->xl_rmid].rm_desc(&buf, record->xl_info, rdata->data);
 		}
-		elog(LOG, "%s", buf);
+		elog(LOG, "%s", buf.data);
+		pfree(buf.data);
 	}
 #endif
 
@@ -4562,6 +4566,7 @@ StartupXLOG(void)
 		{
 			bool		recoveryContinue = true;
 			bool		recoveryApply = true;
+			ErrorContextCallback	errcontext;
 
 			InRedo = true;
 			ereport(LOG,
@@ -4576,16 +4581,19 @@ StartupXLOG(void)
 #ifdef WAL_DEBUG
 				if (XLOG_DEBUG)
 				{
-					char		buf[8192];
+					StringInfoData	buf;
 
-					sprintf(buf, "REDO @ %X/%X; LSN %X/%X: ",
+					initStringInfo(&buf);
+					appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ",
 							ReadRecPtr.xlogid, ReadRecPtr.xrecoff,
 							EndRecPtr.xlogid, EndRecPtr.xrecoff);
-					xlog_outrec(buf, record);
-					strcat(buf, " - ");
-					RmgrTable[record->xl_rmid].rm_desc(buf,
-									record->xl_info, XLogRecGetData(record));
-					elog(LOG, "%s", buf);
+					xlog_outrec(&buf, record);
+					appendStringInfo(&buf, " - ");
+					RmgrTable[record->xl_rmid].rm_desc(&buf,
+													   record->xl_info,
+													   XLogRecGetData(record));
+					elog(LOG, "%s", buf.data);
+					pfree(buf.data);
 				}
 #endif
 
@@ -4600,6 +4608,12 @@ StartupXLOG(void)
 						break;
 				}
 
+				/* Setup error traceback support for ereport() */
+				errcontext.callback = rm_redo_error_callback;
+				errcontext.arg = (void *) record;
+				errcontext.previous = error_context_stack;
+				error_context_stack = &errcontext;
+
 				/* nextXid must be beyond record's xid */
 				if (TransactionIdFollowsOrEquals(record->xl_xid,
 												 ShmemVariableCache->nextXid))
@@ -4613,6 +4627,9 @@ StartupXLOG(void)
 
 				RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record);
 
+				/* Pop the error context stack */
+				error_context_stack = errcontext.previous;
+
 				LastRec = ReadRecPtr;
 
 				record = ReadRecord(NULL, LOG);
@@ -5400,16 +5417,16 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-xlog_desc(char *buf, uint8 xl_info, char *rec)
+xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
-	uint8		info = xl_info & ~XLR_INFO_MASK;
+	uint8			info = xl_info & ~XLR_INFO_MASK;
 
 	if (info == XLOG_CHECKPOINT_SHUTDOWN ||
 		info == XLOG_CHECKPOINT_ONLINE)
 	{
 		CheckPoint *checkpoint = (CheckPoint *) rec;
 
-		sprintf(buf + strlen(buf), "checkpoint: redo %X/%X; undo %X/%X; "
+		appendStringInfo(buf, "checkpoint: redo %X/%X; undo %X/%X; "
 				"tli %u; xid %u; oid %u; multi %u; offset %u; %s",
 				checkpoint->redo.xlogid, checkpoint->redo.xrecoff,
 				checkpoint->undo.xlogid, checkpoint->undo.xrecoff,
@@ -5424,21 +5441,21 @@ xlog_desc(char *buf, uint8 xl_info, char *rec)
 		Oid			nextOid;
 
 		memcpy(&nextOid, rec, sizeof(Oid));
-		sprintf(buf + strlen(buf), "nextOid: %u", nextOid);
+		appendStringInfo(buf, "nextOid: %u", nextOid);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
 
 #ifdef WAL_DEBUG
 
 static void
-xlog_outrec(char *buf, XLogRecord *record)
+xlog_outrec(StringInfo buf, XLogRecord *record)
 {
 	int			bkpb;
 	int			i;
 
-	sprintf(buf + strlen(buf), "prev %X/%X; xid %u",
+	appendStringInfo(buf, "prev %X/%X; xid %u",
 			record->xl_prev.xlogid, record->xl_prev.xrecoff,
 			record->xl_xid);
 
@@ -5450,9 +5467,9 @@ xlog_outrec(char *buf, XLogRecord *record)
 	}
 
 	if (bkpb)
-		sprintf(buf + strlen(buf), "; bkpb %d", bkpb);
+		appendStringInfo(buf, "; bkpb %d", bkpb);
 
-	sprintf(buf + strlen(buf), ": %s",
+	appendStringInfo(buf, ": %s",
 			RmgrTable[record->xl_rmid].rm_name);
 }
 #endif   /* WAL_DEBUG */
@@ -5976,3 +5993,24 @@ remove_backup_label(void)
 					 errmsg("could not remove file \"%s\": %m",
 							BACKUP_LABEL_FILE)));
 }
+
+/*
+ * Error context callback for errors occurring during rm_redo().
+ */
+static void
+rm_redo_error_callback(void *arg)
+{
+	XLogRecord		*record = (XLogRecord *) arg;
+	StringInfoData	 buf;
+
+	initStringInfo(&buf);
+	RmgrTable[record->xl_rmid].rm_desc(&buf, 
+									   record->xl_info, 
+									   XLogRecGetData(record));
+
+	/* don't bother emitting empty description */
+	if (buf.len > 0)
+		errcontext("xlog redo %s", buf.data);
+
+	pfree(buf.data);
+}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index eb1e882f062..a9b19ab89a4 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.177 2006/03/05 15:58:24 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.178 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1392,7 +1392,7 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-dbase_desc(char *buf, uint8 xl_info, char *rec)
+dbase_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -1400,7 +1400,7 @@ dbase_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec;
 
-		sprintf(buf + strlen(buf), "create db: copy dir %u/%u to %u/%u",
+		appendStringInfo(buf, "create db: copy dir %u/%u to %u/%u",
 				xlrec->src_db_id, xlrec->src_tablespace_id,
 				xlrec->db_id, xlrec->tablespace_id);
 	}
@@ -1408,9 +1408,9 @@ dbase_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
 
-		sprintf(buf + strlen(buf), "drop db: dir %u/%u",
+		appendStringInfo(buf, "drop db: dir %u/%u",
 				xlrec->db_id, xlrec->tablespace_id);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 5638f4fe9b7..144cf73c8a4 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.129 2006/03/14 22:48:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.130 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1170,19 +1170,19 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-seq_desc(char *buf, uint8 xl_info, char *rec)
+seq_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 	xl_seq_rec *xlrec = (xl_seq_rec *) rec;
 
 	if (info == XLOG_SEQ_LOG)
-		strcat(buf, "log: ");
+		appendStringInfo(buf, "log: ");
 	else
 	{
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 		return;
 	}
 
-	sprintf(buf + strlen(buf), "rel %u/%u/%u",
+	appendStringInfo(buf, "rel %u/%u/%u",
 			xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
 }
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index a5d4a7a5f24..026bbf5169f 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.31 2006/03/05 15:58:25 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.32 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1042,7 +1042,7 @@ tblspc_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-tblspc_desc(char *buf, uint8 xl_info, char *rec)
+tblspc_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -1050,16 +1050,15 @@ tblspc_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
 
-		sprintf(buf + strlen(buf), "create ts: %u \"%s\"",
+		appendStringInfo(buf, "create ts: %u \"%s\"",
 				xlrec->ts_id, xlrec->ts_path);
 	}
 	else if (info == XLOG_TBLSPC_DROP)
 	{
 		xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
 
-		sprintf(buf + strlen(buf), "drop ts: %u",
-				xlrec->ts_id);
+		appendStringInfo(buf, "drop ts: %u", xlrec->ts_id);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index bdd2af4864c..2ab1268ba1d 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.96 2006/03/05 15:58:39 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.97 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -942,7 +942,7 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
 }
 
 void
-smgr_desc(char *buf, uint8 xl_info, char *rec)
+smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
 {
 	uint8		info = xl_info & ~XLR_INFO_MASK;
 
@@ -950,7 +950,7 @@ smgr_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
 
-		sprintf(buf + strlen(buf), "file create: %u/%u/%u",
+		appendStringInfo(buf, "file create: %u/%u/%u",
 				xlrec->rnode.spcNode, xlrec->rnode.dbNode,
 				xlrec->rnode.relNode);
 	}
@@ -958,10 +958,10 @@ smgr_desc(char *buf, uint8 xl_info, char *rec)
 	{
 		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
 
-		sprintf(buf + strlen(buf), "file truncate: %u/%u/%u to %u blocks",
+		appendStringInfo(buf, "file truncate: %u/%u/%u to %u blocks",
 				xlrec->rnode.spcNode, xlrec->rnode.dbNode,
 				xlrec->rnode.relNode, xlrec->blkno);
 	}
 	else
-		strcat(buf, "UNKNOWN");
+		appendStringInfo(buf, "UNKNOWN");
 }
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index e621be58a4c..999f15bdf7f 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/clog.h,v 1.16 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/clog.h,v 1.17 2006/03/24 04:32:13 tgl Exp $
  */
 #ifndef CLOG_H
 #define CLOG_H
@@ -48,6 +48,6 @@ extern void TruncateCLOG(TransactionId oldestXact);
 #define CLOG_ZEROPAGE		0x00
 
 extern void clog_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void clog_desc(char *buf, uint8 xl_info, char *rec);
+extern void clog_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* CLOG_H */
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index fd044b16b10..3b072da6376 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.10 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.11 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -244,7 +244,7 @@ extern GISTInsertStack *gistFindPath(Relation r, BlockNumber child,
 
 /* gistxlog.c */
 extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void gist_desc(char *buf, uint8 xl_info, char *rec);
+extern void gist_desc(StringInfo buf, uint8 xl_info, char *rec);
 extern void gist_xlog_startup(void);
 extern void gist_xlog_cleanup(void);
 extern IndexTuple gist_form_invalid_tuple(BlockNumber blkno);
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index c6798dc0781..0d34b29cfaf 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.66 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.67 2006/03/24 04:32:13 tgl Exp $
  *
  * NOTES
  *		modeled after Margo Seltzer's hash implementation for unix.
@@ -306,6 +306,6 @@ extern void _hash_checkpage(Relation rel, Buffer buf, int flags);
 
 /* hash.c */
 extern void hash_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void hash_desc(char *buf, uint8 xl_info, char *rec);
+extern void hash_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* HASH_H */
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index e834928245d..cfa23c0f27a 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.106 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.107 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -178,7 +178,7 @@ extern void heap_markpos(HeapScanDesc scan);
 extern void heap_restrpos(HeapScanDesc scan);
 
 extern void heap_redo(XLogRecPtr lsn, XLogRecord *rptr);
-extern void heap_desc(char *buf, uint8 xl_info, char *rec);
+extern void heap_desc(StringInfo buf, uint8 xl_info, char *rec);
 extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
 			   OffsetNumber *unused, int uncnt);
 extern XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf,
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index 82a08a979e3..b98c5fd80bf 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/multixact.h,v 1.9 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/multixact.h,v 1.10 2006/03/24 04:32:13 tgl Exp $
  */
 #ifndef MULTIXACT_H
 #define MULTIXACT_H
@@ -67,6 +67,6 @@ extern void MultiXactAdvanceNextMXact(MultiXactId minMulti,
 						  MultiXactOffset minMultiOffset);
 
 extern void multixact_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void multixact_desc(char *buf, uint8 xl_info, char *rec);
+extern void multixact_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* MULTIXACT_H */
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 5a5e5d047eb..113134d5774 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.92 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.93 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -470,7 +470,7 @@ extern void _bt_leafbuild(BTSpool *btspool, BTSpool *spool2);
  * prototypes for functions in nbtxlog.c
  */
 extern void btree_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void btree_desc(char *buf, uint8 xl_info, char *rec);
+extern void btree_desc(StringInfo buf, uint8 xl_info, char *rec);
 extern void btree_xlog_startup(void);
 extern void btree_xlog_cleanup(void);
 
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 3b618f320d4..da2455f68fd 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.80 2006/03/05 15:58:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.81 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -175,6 +175,6 @@ extern void RecordTransactionCommit(void);
 extern int	xactGetCommittedChildren(TransactionId **ptr);
 
 extern void xact_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void xact_desc(char *buf, uint8 xl_info, char *rec);
+extern void xact_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* XACT_H */
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d0d9c503c96..bd1699f5abe 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.70 2006/03/05 15:58:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.71 2006/03/24 04:32:13 tgl Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
@@ -14,6 +14,7 @@
 #include "access/rmgr.h"
 #include "access/transam.h"
 #include "access/xlogdefs.h"
+#include "lib/stringinfo.h"
 #include "storage/buf.h"
 #include "utils/pg_crc.h"
 
@@ -152,7 +153,7 @@ extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata);
 extern void XLogFlush(XLogRecPtr RecPtr);
 
 extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void xlog_desc(char *buf, uint8 xl_info, char *rec);
+extern void xlog_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 extern void UpdateControlFile(void);
 extern Size XLOGShmemSize(void);
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index f148f0e563e..9bf46c28319 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.10 2006/03/05 15:58:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.11 2006/03/24 04:32:13 tgl Exp $
  */
 #ifndef XLOG_INTERNAL_H
 #define XLOG_INTERNAL_H
@@ -228,7 +228,7 @@ typedef struct RmgrData
 {
 	const char *rm_name;
 	void		(*rm_redo) (XLogRecPtr lsn, XLogRecord *rptr);
-	void		(*rm_desc) (char *buf, uint8 xl_info, char *rec);
+	void		(*rm_desc) (StringInfo buf, uint8 xl_info, char *rec);
 	void		(*rm_startup) (void);
 	void		(*rm_cleanup) (void);
 } RmgrData;
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index 470ef024bd7..2c9852bd0cb 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.44 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.45 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,6 @@ extern Oid	get_database_oid(const char *dbname);
 extern char *get_database_name(Oid dbid);
 
 extern void dbase_redo(XLogRecPtr lsn, XLogRecord *rptr);
-extern void dbase_desc(char *buf, uint8 xl_info, char *rec);
+extern void dbase_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* DBCOMMANDS_H */
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index b4987884d29..f334d6ba831 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/sequence.h,v 1.35 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/sequence.h,v 1.36 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,7 +91,7 @@ extern void DefineSequence(CreateSeqStmt *stmt);
 extern void AlterSequence(AlterSeqStmt *stmt);
 
 extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
-extern void seq_desc(char *buf, uint8 xl_info, char *rec);
+extern void seq_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 /* Set the upper and lower bounds of a sequence */
 #ifndef INT64_IS_BUSTED
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 5439905860a..650b21023d4 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.12 2006/03/05 15:58:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.13 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,6 +48,6 @@ extern char *get_tablespace_name(Oid spc_oid);
 extern bool directory_is_empty(const char *path);
 
 extern void tblspc_redo(XLogRecPtr lsn, XLogRecord *rptr);
-extern void tblspc_desc(char *buf, uint8 xl_info, char *rec);
+extern void tblspc_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 #endif   /* TABLESPACE_H */
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 8edce2a85e3..b768a5b5304 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.54 2006/03/05 15:59:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.55 2006/03/24 04:32:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,7 +85,7 @@ extern void smgrabort(void);
 extern void smgrsync(void);
 
 extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record);
-extern void smgr_desc(char *buf, uint8 xl_info, char *rec);
+extern void smgr_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 
 /* internals: move me elsewhere -- ay 7/94 */
-- 
GitLab