From: | Stefan Niantschur <sniantschur(at)web(dot)de> |
---|---|
To: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: How to return a large String with C |
Date: | 2008-02-18 15:22:07 |
Message-ID: | 20080218162207.2d5f03c3@trabant.niantschur.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Am Sun, 17 Feb 2008 14:28:18 -0500
schrieb Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>:
> Stefan Niantschur <sniantschur(at)web(dot)de> writes:
> > Am Sun, 17 Feb 2008 09:17:08 -0500
> > schrieb Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)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
From | Date | Subject | |
---|---|---|---|
Next Message | Tony Caduto | 2008-02-18 15:38:33 | Re: msvcr80.dll and PostgreSQL 8.3 under Windows XP |
Previous Message | Magnus Hagander | 2008-02-18 15:20:57 | Re: msvcr80.dll and PostgreSQL 8.3 under Windows XP |