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.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);
---------------------------(end of broadcast)--------------------------- TIP 7: You can help support the PostgreSQL project by donating at http://www.postgresql.org/about/donate