The Apache runtime library, which is using a similar concept for
allocating heap-based memory out of a pool, has some since utility
functions, named apr_psprintf and apr_pstrdup.
These functions allocate a memory-block out of a pool and print a
formatted string into that block, or duplicate a string respectively.
Since such useful functions are missing in PostgreSQL's Server
Programming Interface, I created two similar functions:
char *SPI_psprintf(const char *fmt, ...);
allocates a block of memory out of the memory pool and prints a
formatted string into it
SPI_pstrdup(const char *src);
allocates a block of memory out of the memory pool and copies an
existing string into it.
I includes a patch containing these functions to be applied onto version
8.2.3 and 8.2.4. I would appreciate seeing it in one of the next
versions.
Jacob Rief
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.0 +0100
+++ postgresql-8.2.3.strdup/src/backend/executor/spi.c 2007-04-16 17:26:46.0 +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.0 +0200
+++ postgresql-8.2.3.strdup/src/include/executor/spi.h 2007-04-16 17:03:04.0 +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);
---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate