Re: Logical Decoding Callbacks - Mailing list pgsql-general

From Xavier Stevens
Subject Re: Logical Decoding Callbacks
Date
Msg-id CAFu3Q-+WGOCEL+cd88nvyugrdd2ewwSL_Miq1XmY631Av0h6xQ@mail.gmail.com
Whole thread Raw
In response to Re: Logical Decoding Callbacks  (Andres Freund <andres@2ndquadrant.com>)
List pgsql-general
There was no reason I needed to run full statements in this case. I just didn't know I could get the type ids like that.

Thanks for all of your help Andres!



On Tue, Feb 10, 2015 at 1:23 PM, Andres Freund <andres@2ndquadrant.com> wrote:
On 2015-02-10 10:33:41 -0800, Xavier Stevens wrote:
> Sorry to raise the issue on startup_cb. I added a whole bunch of logging
> statements and I was only running the section of code I wanted when the
> startup callback had options.

Heh.

Just to make sure: You can pass options via replication protocol too.

> This now gets me to the next issue I encounter. In my output plugin, I'm
> trying to use the SPI interface to query about PostGIS OIDs in the startup
> callback. Just calling SPI_connect() seems to be causing a segfault.

> This is the last thing I see in the logs before the segfault occurs:
>
> https://github.com/xstevens/decoderbufs/blob/master/src/decoderbufs.c#L151

The problem likely is that in the startup callback you're neither
guaranteed to be in a transaction, nor to have a snapshot set up.

It'd generally be easier to analyze such problems if you provide a
backtrace (e.g. by enabling core files). Another generally very
adviseable thing to do when developing code running in the backend is to
enable assertions (you may already do that...).

You can lookup types much easier than that btw. C.f. TypenameGetTypid(typname)

But note that both that and what you do would possibly fail if there's
more than one geometry type around. You could either hardcode postgis'
schema name and use
namespaceId = LookupExplicitNamespace(schemaname, false);
typoid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId));
if (typoid == InvalidOid)
   elog(ERROR, "cache lookup failed for type %u", typoid);

or be a bit more complex and lookup the postgis' extension's schema
pg_extension.extnamespace first.


Anyway, to run full queries in the startup callback you're going to have
to do something like:

if (!IsTransactionState())
{
    tx_started = true;
    StartTransactionCommand();
}
PushActiveSnapshot(GetTransactionSnapshot());

/* do your stuff */

PopActiveSnapshot();
if (tx_started)
    CommitTransactionCommand();


Note that the begin, change, commit callbacks *do* run with a
transaction and snapshot setup. But you can't run general SQL queries -
only catalog tables (or tables marked as such) are accessible.

Greetings,

Andres Freund

--
 Andres Freund                     http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services

pgsql-general by date:

Previous
From: Jeremiah Ocasio
Date:
Subject: Re: [ADMIN] Change postgresql encoding
Next
From: Mathieu Basille
Date:
Subject: Hardware requirements for a PostGIS server