diff -ur postgresql-8.2.3/src/backend/executor/spi.c postgresql-8.2.3.strdup/src/backend/executor/spi.c
--- postgresql-8.2.3/src/backend/executor/spi.c	2006-12-26 17:56:22.000000000 +0100
+++ postgresql-8.2.3.strdup/src/backend/executor/spi.c	2007-04-16 17:26:46.000000000 +0200
@@ -818,7 +818,47 @@
 		MemoryContextDelete(tuptable->tuptabcxt);
 }
 
+char*
+SPI_psprintf(const char *fmt, ...)
+{
+	int n, size = 0;
+	char *p;
+	va_list ap;
+
+	if (fmt==NULL)
+		return NULL;
+	for (n = 0; fmt[n]!='\0'; n++) {
+		size += (fmt[n]=='%') ? 10 : 1;
+	}
+	if ((p = SPI_palloc(size))==NULL)
+		return NULL;
+	while (1) {
+		va_start(ap, fmt);
+		n = vsnprintf(p, size, fmt, ap);
+		va_end(ap);
+		if (n > -1 && n < size)
+			return p;
+		if (n > -1)
+			size = n+1; /* glibc 2.1 */
+		else
+			size *= 2; /* glibc 2.0 */
+		if ((p = SPI_repalloc(p, size))==NULL)
+			return NULL;
+	}
+	return NULL;
+}
 
+char*
+SPI_pstrdup(const char *src)
+{
+	int size;
+	char *p;
+	size = strlen(src)+1;
+	if ((p = SPI_palloc(size))==NULL)
+		return NULL;
+	strcpy(p, src);
+	return p;
+}
 
 /*
  * SPI_cursor_open()
diff -ur postgresql-8.2.3/src/include/executor/spi.h postgresql-8.2.3.strdup/src/include/executor/spi.h
--- postgresql-8.2.3/src/include/executor/spi.h	2006-10-04 02:30:08.000000000 +0200
+++ postgresql-8.2.3.strdup/src/include/executor/spi.h	2007-04-16 17:03:04.000000000 +0200
@@ -119,6 +119,8 @@
 extern char *SPI_getnspname(Relation rel);
 extern void *SPI_palloc(Size size);
 extern void *SPI_repalloc(void *pointer, Size size);
+extern char *SPI_psprintf(const char* fmt, ...);
+extern char *SPI_pstrdup(const char* src);
 extern void SPI_pfree(void *pointer);
 extern void SPI_freetuple(HeapTuple pointer);
 extern void SPI_freetuptable(SPITupleTable *tuptable);
