I probably just need to learn the right coding pattern for this.
What is it?

What I want this code to do:

a) If there is a table 'mytable', set theSavedStuff to a pstrdup'd in
   TopMemoryContext copy of column s from one row if present.

b) In case of an error because there is no table 'mytable', just swallow
   the error and do nothing. That's an expected case.

c) In case of any other error (something unexpected), rethrow.

Case (a) works. Case (c) works. Case (b) works but produces this:

WARNING:  01000: transaction left non-empty SPI stack
HINT:  Check for missing "SPI_finish" calls.

I can verify that my SPI_finish call is being reached. In fact, in
case b, it returns SPI_ERROR_UNCONNECTED, as if even before my
PG_CATCH received control, the SPI "connection" got closed. But the
"SPI stack" still appears as if something is open?

In the context where this is called, there is no SPI connection already
open (if I try SPI_push_conditional at the start, it returns false).

I'm sure the only bug is in my understanding of how to approach this.
Can someone point out what I'm missing?

Thanks,
-Chap

{
    MemoryContext curr;
    SPI_connect();
    curr = CurrentMemoryContext;
    PG_TRY();
    {
        if ( SPI_OK_SELECT == SPI_execute(
            "SELECT s FROM mytable", true, 1) && 1 == SPI_processed )
        {
            MemoryContextSwitchTo(TopMemoryContext);
            theSavedStuff = (char const *)SPI_getvalue(
                SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
            MemoryContextSwitchTo(curr);
        }
    }
    PG_CATCH();
    {
        if ( ERRCODE_UNDEFINED_TABLE != geterrcode() )
            PG_RE_THROW();
        MemoryContextSwitchTo(curr);
        FlushErrorState();
    }
    PG_END_TRY();
    SPI_finish();
}


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to