Re: How to return a large String with C

Поиск
Список
Период
Сортировка
От Stefan Niantschur
Тема Re: How to return a large String with C
Дата
Msg-id 20080218162207.2d5f03c3@trabant.niantschur.de
обсуждение исходный текст
Ответ на Re: How to return a large String with C  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: How to return a large String with C
Список pgsql-general
Am Sun, 17 Feb 2008 14:28:18 -0500
schrieb Tom Lane <tgl@sss.pgh.pa.us>:

> Stefan Niantschur <sniantschur@web.de> writes:
> > Am Sun, 17 Feb 2008 09:17:08 -0500
> > schrieb Tom Lane <tgl@sss.pgh.pa.us>:
> >> Hardly surprising when you're printing the string into a fixed-size
> >> 8K buffer. The buffer overflow is smashing the stack, in particular
> >> the function's return address.
>
> > Yes, I know, but the backend does not allow for a bigger buffer.
> > Trying to use a 80K (char[81920])buffer did not work and returns:
>
> So you've got some other bug in code you didn't show us.  It's highly
> unlikely that you wouldn't be able to allocate an 80K buffer.
> (Whether that's big enough for your data even yet is a separate
> question.)
>
> What I was wondering was why you even bothered with the char[] buffer,
> when it looked like the actually useful return value was being
> accumulated in an expansible StringInfo buffer.
>
>             regards, tom lane
>

Please find below the most recent code snippet. It is mainly based on
examples from the pg documentation:
-------8< -------
#define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin,
CStringGetDatum(cstrp)))
(...)
char *cres;
int  ret;
(...)
 if ((ret = SPI_connect()) < 0)
 {
 elog(ERROR, "get_info: SPI_connect returned %d", ret);
 }

proc = SPI_processed;

initStringInfo(&result_buf);
if (ret > 0 && SPI_tuptable != NULL)
{
 TupleDesc tupdesc = SPI_tuptable->tupdesc;
 SPITupleTable *tuptable = SPI_tuptable;
 int i,k;
 for (i = 0; i < proc; i++)
 {
  HeapTuple tuple = tuptable->vals[i];
  for (k = 1; k <= tupdesc->natts; k++)
  {
   cres = SPI_getvalue(tuple, tupdesc, k);
   appendStringInfo(&result_buf, SPI_getvalue(tuple, tupdesc, k));
   elog(INFO, "info: %s", cres);
  }
 }
}
SPI_finish();
elog(INFO, "---");
PG_RETURN_TEXT_P(GET_TEXT(result_buf.data));
------->8 -------

I still have the problem that I can use the C function via
select from within psql if the result is not too long. If the result is
a really long string, then I see this:
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.


The problem is not the query via SPI (this works and I can see the
result in elog). The issue I have is that I cannot see the string in
psql when it is a long string. For short strings it does the trick.

Even if I use a (char *) and return it this only works for short
strings.

As short strings are not the problem, what do I need to do to get a
long string handed back to my select in psql?

Best Regards,
Stefan

В списке pgsql-general по дате отправления:

Предыдущее
От: Magnus Hagander
Дата:
Сообщение: Re: msvcr80.dll and PostgreSQL 8.3 under Windows XP
Следующее
От: pgsql_user
Дата:
Сообщение: Re: Auto incrementing primary keys