Hi Paul,

On 2014-09-23 09:55:32 -0700, Paul Ramsey wrote:
> I’m trying to implement an spgist index in the PostGIS extension, which seems 
> like it should work, but is thus far not working for what appear (to me) to 
> be issues in the way spgist expects to pass pointers to user-defined 
> functions.  
> 
> Right before anything happens, spgist calls a ‘config’ routine in the user 
> code. This is the code from the example implementation (which is internal to 
> pgsql, not a run-time add-on like postgis)  
> 
>  Datum  
>  spg_quad_config(PG_FUNCTION_ARGS)
>  {
>  /* spgConfigIn *cfgin = (spgConfigIn *) PG_GETARG_POINTER(0); */
>  spgConfigOut *cfg = (spgConfigOut *) PG_GETARG_POINTER(1); 
> 
>  cfg->prefixType = POINTOID;  
>  cfg->labelType = VOIDOID; /* we don't need node labels */
>  cfg->canReturnData = true;
>  cfg->longValuesOK = false;
>  PG_RETURN_VOID();
>  }
> 
> It is called from the spgist core in the spgGetCache() function, via 
> 
>  FunctionCall2Coll(procinfo,
>    index->rd_indcollation[0],
>    PointerGetDatum(&in),
>    PointerGetDatum(&cache->config));
> 
> The part the user function cares about is the pointer to cache->config. 
> 
> In the core code, the call stack to the user function goes like this:
> 
> postgres`spg_quad_config(fcinfo=0x00007fff5f0faf90) + 18 at 
> spgquadtreeproc.c:29
> postgres`FunctionCall2Coll(flinfo=0x00007ff59a804cc8, collation=0, 
> arg1=140734788252568, arg2=140692835814944) + 150 at fmgr.c:1327
>  postgres`spgGetCache(index=0x000000010254be68) + 220 at spgutils.c:71
> 
> So, spgGetCache to FunctionCall2Coll to spg_quad_config.
> 
> In my user-defined version of the same thing (I just copied the C code and 
> wrote a CREATE OPERATOR CLASS for it) the call stack is this
> 
> postgis-2.2.so`gserialized_spgist_quadtree_2d_config(fcinfo=0x00007fff5f0fb398)
>  + 30 at gserialized_spgist_2d.c:60
> postgres`fmgr_oldstyle(fcinfo=0x00007fff5f0faf90) + 424 at fmgr.c:678
> postgres`FunctionCall2Coll(flinfo=0x00007ff59a039cc8, collation=0, 
> arg1=140734788252568, arg2=140692827643424) + 150 at fmgr.c:1327
> postgres`spgGetCache(index=0x000000010254be68) + 220 at spgutils.c:71
> 
> So, spgGetCache to FunctionCall2Coll to fmgr_oldstyle to 
> gserialized_spgist_quadtree_2d_config! 
> 
> On the way through fmgr_oldstyle things go very much awry and the 
> gserialized_spgist_quadtree_2d_config doesn’t get called with a pointer to an 
> fcinfo, but with a pointer to the block of memory occupied by the first 
> argument, and from there things naturally stop working.
> 
> So, I’m wondering what I could have done that is causing my calls to route 
> through fmgr_oldstyle instead of the usual path?

You forgot to add a PG_FUNCTION_INFO_V1(yourfunc); for the function.

I really, really think we should get rid of v0 functions. I've seen
errors like this far too many, and they really don't buy us much.

Greetings,

Andres Freund

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


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

Reply via email to