Re: GiST opclass and varlena - Mailing list pgsql-hackers

From Dimitri Fontaine
Subject Re: GiST opclass and varlena
Date
Msg-id 200804101739.15041.dfontaine@hi-media.com
Whole thread Raw
In response to Re: GiST opclass and varlena  (Gregory Stark <stark@enterprisedb.com>)
List pgsql-hackers
Le jeudi 10 avril 2008, Gregory Stark a écrit :
> I'm getting interested now. How was __pr_penalty defined? What was the
> declaration you were missing in prefix.c?

In fact __pr_penalty is the internal code called from both the SQL callable
functions (and some other calling sites). The problem was that I missed some
SQL callable definitions and it got called with internal parameters instead
of the prefix_range * it expects.

Details:
http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/prefix/prefix/prefix.c.diff?r1=1.33&r2=1.32
http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/prefix/prefix/prefix.sql.in.diff?r1=1.15&r2=1.14

> Was it specifically related to a varlena or was it a char or something like
> that?

The datatype I'm playing with is prefix_range and is used as a varlena:
typedef struct { char first; char last; char prefix[1]; /* this is a varlena structure, data follows */
} prefix_range;

Then have a look at make_varlena() function and those macros:

#define DatumGetPrefixRange(X)            ((prefix_range *)
PREFIX_VARDATA(DatumGetPointer(X)) )
#define PrefixRangeGetDatum(X)            PointerGetDatum(make_varlena(X))
#define PG_GETARG_PREFIX_RANGE_P(n)
DatumGetPrefixRange(PG_DETOAST_DATUM(PG_GETARG_DATUM(n)))
#define PG_RETURN_PREFIX_RANGE_P(x)       return PrefixRangeGetDatum(x)

> And was it something gcc -Wall was warning about or somehow was it slipping
> by?

I didn't see any errors from gcc nor from PostgreSQL. I just was using the
following function definition for the two following SQL functions:

PG_FUNCTION_INFO_V1(pr_penalty);
Datum
pr_penalty(PG_FUNCTION_ARGS)
{ float penalty = __pr_penalty(PG_GETARG_PREFIX_RANGE_P(0),                              PG_GETARG_PREFIX_RANGE_P(1));
PG_RETURN_FLOAT4(penalty);
}

CREATE OR REPLACE FUNCTION gpr_penalty(internal, internal, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE 'C' STRICT;

CREATE OR REPLACE FUNCTION gpr_penalty(prefix_range, prefix_range)
RETURNS float4
AS 'MODULE_PATHNAME'
LANGUAGE 'C' STRICT;

This last one is now pr_penalty and as a matching function defined in the
prefix.c file, which was not the case when all was wrong. And of course the
gpr_penalty code has been rewrote to be correct WRT its arguments processing.

Sorry to be using CVS at pgfoundry, if it was something more elaborate a
revision id could get you easily to the buggy version, here you'll have to
play some cvs game to get the version before the commit with this message, if
you wanted to try the bug yourself: Respect GiST calling conventions for gpr_penalty()

Hope this helps, regards,
--
dim

pgsql-hackers by date:

Previous
From: "Joshua D. Drake"
Date:
Subject: Re: Commit fest queue
Next
From: Alvaro Herrera
Date:
Subject: Re: Commit fest queue