Move contrib/seg to only use V1 calling conventions.
authorAndres Freund <andres@anarazel.de>
Wed, 29 Mar 2017 20:16:30 +0000 (13:16 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 30 Mar 2017 13:25:46 +0000 (06:25 -0700)
A later commit will remove V0 support.

Author: Andres Freund, with contributions by Craig Ringer
Reviewed-By: Peter Eisentraut, Craig Ringer
Discussion: https://postgr.es/m/20161208213441.k3mbno4twhg2qf7g@alap3.anarazel.de

contrib/seg/seg.c

index 895d8794982540ab5f1b45bd953ec43664e939c5..61e72937eee07490f95e616979ef2813b31f48e0 100644 (file)
 
 #include "segdata.h"
 
+
+#define DatumGetSegP(X) ((SEG *) DatumGetPointer(X))
+#define PG_GETARG_SEG_P(n) DatumGetSegP(PG_GETARG_POINTER(n))
+
+
 /*
 #define GIST_DEBUG
 #define GIST_QUERY_DEBUG
@@ -47,52 +52,45 @@ PG_FUNCTION_INFO_V1(seg_center);
 /*
 ** GiST support methods
 */
-bool gseg_consistent(GISTENTRY *entry,
-               SEG *query,
-               StrategyNumber strategy,
-               Oid subtype,
-               bool *recheck);
-GISTENTRY  *gseg_compress(GISTENTRY *entry);
-GISTENTRY  *gseg_decompress(GISTENTRY *entry);
-float     *gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result);
-GIST_SPLITVEC *gseg_picksplit(GistEntryVector *entryvec, GIST_SPLITVEC *v);
-bool       gseg_leaf_consistent(SEG *key, SEG *query, StrategyNumber strategy);
-bool       gseg_internal_consistent(SEG *key, SEG *query, StrategyNumber strategy);
-SEG           *gseg_union(GistEntryVector *entryvec, int *sizep);
-SEG           *gseg_binary_union(SEG *r1, SEG *r2, int *sizep);
-bool      *gseg_same(SEG *b1, SEG *b2, bool *result);
+PG_FUNCTION_INFO_V1(gseg_consistent);
+PG_FUNCTION_INFO_V1(gseg_compress);
+PG_FUNCTION_INFO_V1(gseg_decompress);
+PG_FUNCTION_INFO_V1(gseg_picksplit);
+PG_FUNCTION_INFO_V1(gseg_penalty);
+PG_FUNCTION_INFO_V1(gseg_union);
+PG_FUNCTION_INFO_V1(gseg_same);
+static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy);
+static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy);
+static Datum gseg_binary_union(Datum r1, Datum r2, int *sizep);
 
 
 /*
 ** R-tree support functions
 */
-bool       seg_same(SEG *a, SEG *b);
-bool       seg_contains_int(SEG *a, int *b);
-bool       seg_contains_float4(SEG *a, float4 *b);
-bool       seg_contains_float8(SEG *a, float8 *b);
-bool       seg_contains(SEG *a, SEG *b);
-bool       seg_contained(SEG *a, SEG *b);
-bool       seg_overlap(SEG *a, SEG *b);
-bool       seg_left(SEG *a, SEG *b);
-bool       seg_over_left(SEG *a, SEG *b);
-bool       seg_right(SEG *a, SEG *b);
-bool       seg_over_right(SEG *a, SEG *b);
-SEG           *seg_union(SEG *a, SEG *b);
-SEG           *seg_inter(SEG *a, SEG *b);
-void       rt_seg_size(SEG *a, float *sz);
+PG_FUNCTION_INFO_V1(seg_same);
+PG_FUNCTION_INFO_V1(seg_contains);
+PG_FUNCTION_INFO_V1(seg_contained);
+PG_FUNCTION_INFO_V1(seg_overlap);
+PG_FUNCTION_INFO_V1(seg_left);
+PG_FUNCTION_INFO_V1(seg_over_left);
+PG_FUNCTION_INFO_V1(seg_right);
+PG_FUNCTION_INFO_V1(seg_over_right);
+PG_FUNCTION_INFO_V1(seg_union);
+PG_FUNCTION_INFO_V1(seg_inter);
+static void rt_seg_size(SEG *a, float *size);
 
 /*
 ** Various operators
 */
-int32      seg_cmp(SEG *a, SEG *b);
-bool       seg_lt(SEG *a, SEG *b);
-bool       seg_le(SEG *a, SEG *b);
-bool       seg_gt(SEG *a, SEG *b);
-bool       seg_ge(SEG *a, SEG *b);
-bool       seg_different(SEG *a, SEG *b);
+PG_FUNCTION_INFO_V1(seg_cmp);
+PG_FUNCTION_INFO_V1(seg_lt);
+PG_FUNCTION_INFO_V1(seg_le);
+PG_FUNCTION_INFO_V1(seg_gt);
+PG_FUNCTION_INFO_V1(seg_ge);
+PG_FUNCTION_INFO_V1(seg_different);
 
 /*
-** Auxiliary funxtions
+** Auxiliary functions
 */
 static int restore(char *s, float val, int n);
 
@@ -120,7 +118,7 @@ seg_in(PG_FUNCTION_ARGS)
 Datum
 seg_out(PG_FUNCTION_ARGS)
 {
-   SEG        *seg = (SEG *) PG_GETARG_POINTER(0);
+   SEG        *seg = PG_GETARG_SEG_P(0);
    char       *result;
    char       *p;
 
@@ -161,7 +159,7 @@ seg_out(PG_FUNCTION_ARGS)
 Datum
 seg_center(PG_FUNCTION_ARGS)
 {
-   SEG        *seg = (SEG *) PG_GETARG_POINTER(0);
+   SEG        *seg = PG_GETARG_SEG_P(0);
 
    PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
 }
@@ -169,7 +167,7 @@ seg_center(PG_FUNCTION_ARGS)
 Datum
 seg_lower(PG_FUNCTION_ARGS)
 {
-   SEG        *seg = (SEG *) PG_GETARG_POINTER(0);
+   SEG        *seg = PG_GETARG_SEG_P(0);
 
    PG_RETURN_FLOAT4(seg->lower);
 }
@@ -177,7 +175,7 @@ seg_lower(PG_FUNCTION_ARGS)
 Datum
 seg_upper(PG_FUNCTION_ARGS)
 {
-   SEG        *seg = (SEG *) PG_GETARG_POINTER(0);
+   SEG        *seg = PG_GETARG_SEG_P(0);
 
    PG_RETURN_FLOAT4(seg->upper);
 }
@@ -193,13 +191,16 @@ seg_upper(PG_FUNCTION_ARGS)
 ** the predicate x op query == FALSE, where op is the oper
 ** corresponding to strategy in the pg_amop table.
 */
-bool
-gseg_consistent(GISTENTRY *entry,
-               SEG *query,
-               StrategyNumber strategy,
-               Oid subtype,
-               bool *recheck)
+Datum
+gseg_consistent(PG_FUNCTION_ARGS)
 {
+   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+   Datum       query = PG_GETARG_DATUM(1);
+   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+   /* Oid      subtype = PG_GETARG_OID(3); */
+   bool       *recheck = (bool *) PG_GETARG_POINTER(4);
+
    /* All cases served by this function are exact */
    *recheck = false;
 
@@ -208,73 +209,77 @@ gseg_consistent(GISTENTRY *entry,
     * gseg_leaf_consistent
     */
    if (GIST_LEAF(entry))
-       return (gseg_leaf_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
+       return gseg_leaf_consistent(entry->key, query, strategy);
    else
-       return (gseg_internal_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
+       return gseg_internal_consistent(entry->key, query, strategy);
 }
 
 /*
 ** The GiST Union method for segments
 ** returns the minimal bounding seg that encloses all the entries in entryvec
 */
-SEG *
-gseg_union(GistEntryVector *entryvec, int *sizep)
+Datum
+gseg_union(PG_FUNCTION_ARGS)
 {
+   GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+   int        *sizep = (int *) PG_GETARG_POINTER(1);
    int         numranges,
                i;
-   SEG        *out = (SEG *) NULL;
-   SEG        *tmp;
+   Datum       out = 0;
+   Datum       tmp;
 
 #ifdef GIST_DEBUG
    fprintf(stderr, "union\n");
 #endif
 
    numranges = entryvec->n;
-   tmp = (SEG *) DatumGetPointer(entryvec->vector[0].key);
+   tmp = entryvec->vector[0].key;
    *sizep = sizeof(SEG);
 
    for (i = 1; i < numranges; i++)
    {
-       out = gseg_binary_union(tmp, (SEG *)
-                               DatumGetPointer(entryvec->vector[i].key),
-                               sizep);
+       out = gseg_binary_union(tmp, entryvec->vector[i].key, sizep);
        tmp = out;
    }
 
-   return (out);
+   PG_RETURN_DATUM(out);
 }
 
 /*
 ** GiST Compress and Decompress methods for segments
 ** do not do anything.
 */
-GISTENTRY *
-gseg_compress(GISTENTRY *entry)
+Datum
+gseg_compress(PG_FUNCTION_ARGS)
 {
-   return (entry);
+   PG_RETURN_POINTER(PG_GETARG_POINTER(0));
 }
 
-GISTENTRY *
-gseg_decompress(GISTENTRY *entry)
+Datum
+gseg_decompress(PG_FUNCTION_ARGS)
 {
-   return (entry);
+   PG_RETURN_POINTER(PG_GETARG_POINTER(0));
 }
 
 /*
 ** The GiST Penalty method for segments
 ** As in the R-tree paper, we use change in area as our penalty metric
 */
-float *
-gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
+Datum
+gseg_penalty(PG_FUNCTION_ARGS)
 {
+   GISTENTRY  *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
+   GISTENTRY  *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+   float      *result = (float *) PG_GETARG_POINTER(2);
    SEG        *ud;
    float       tmp1,
                tmp2;
 
-   ud = seg_union((SEG *) DatumGetPointer(origentry->key),
-                  (SEG *) DatumGetPointer(newentry->key));
+   ud = DatumGetSegP(DirectFunctionCall2(seg_union,
+                                         origentry->key,
+                                         newentry->key));
    rt_seg_size(ud, &tmp1);
-   rt_seg_size((SEG *) DatumGetPointer(origentry->key), &tmp2);
+   rt_seg_size(DatumGetSegP(origentry->key), &tmp2);
    *result = tmp1 - tmp2;
 
 #ifdef GIST_DEBUG
@@ -282,7 +287,7 @@ gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
    fprintf(stderr, "\t%g\n", *result);
 #endif
 
-   return (result);
+   PG_RETURN_POINTER(result);
 }
 
 /*
@@ -309,14 +314,15 @@ gseg_picksplit_item_cmp(const void *a, const void *b)
  * it's easier and more robust to just sort the segments by center-point and
  * split at the middle.
  */
-GIST_SPLITVEC *
-gseg_picksplit(GistEntryVector *entryvec,
-              GIST_SPLITVEC *v)
+Datum
+gseg_picksplit(PG_FUNCTION_ARGS)
 {
+   GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+   GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
    int         i;
-   SEG        *datum_l,
-              *datum_r,
-              *seg;
+   SEG        *seg,
+              *seg_l,
+              *seg_r;
    gseg_picksplit_item *sort_items;
    OffsetNumber *left,
               *right;
@@ -337,7 +343,7 @@ gseg_picksplit(GistEntryVector *entryvec,
        palloc(maxoff * sizeof(gseg_picksplit_item));
    for (i = 1; i <= maxoff; i++)
    {
-       seg = (SEG *) DatumGetPointer(entryvec->vector[i].key);
+       seg = DatumGetSegP(entryvec->vector[i].key);
        /* center calculation is done this way to avoid possible overflow */
        sort_items[i - 1].center = seg->lower * 0.5f + seg->upper * 0.5f;
        sort_items[i - 1].index = i;
@@ -359,13 +365,17 @@ gseg_picksplit(GistEntryVector *entryvec,
    /*
     * Emit segments to the left output page, and compute its bounding box.
     */
-   datum_l = (SEG *) palloc(sizeof(SEG));
-   memcpy(datum_l, sort_items[0].data, sizeof(SEG));
+   seg_l = (SEG *) palloc(sizeof(SEG));
+   memcpy(seg_l, sort_items[0].data, sizeof(SEG));
    *left++ = sort_items[0].index;
    v->spl_nleft++;
    for (i = 1; i < firstright; i++)
    {
-       datum_l = seg_union(datum_l, sort_items[i].data);
+       Datum       sortitem = PointerGetDatum(sort_items[i].data);
+
+       seg_l = DatumGetSegP(DirectFunctionCall2(seg_union,
+                                                PointerGetDatum(seg_l),
+                                                sortitem));
        *left++ = sort_items[i].index;
        v->spl_nleft++;
    }
@@ -373,30 +383,36 @@ gseg_picksplit(GistEntryVector *entryvec,
    /*
     * Likewise for the right page.
     */
-   datum_r = (SEG *) palloc(sizeof(SEG));
-   memcpy(datum_r, sort_items[firstright].data, sizeof(SEG));
+   seg_r = (SEG *) palloc(sizeof(SEG));
+   memcpy(seg_r, sort_items[firstright].data, sizeof(SEG));
    *right++ = sort_items[firstright].index;
    v->spl_nright++;
    for (i = firstright + 1; i < maxoff; i++)
    {
-       datum_r = seg_union(datum_r, sort_items[i].data);
+       Datum       sortitem = PointerGetDatum(sort_items[i].data);
+
+       seg_r = DatumGetSegP(DirectFunctionCall2(seg_union,
+                                                PointerGetDatum(seg_r),
+                                                sortitem));
        *right++ = sort_items[i].index;
        v->spl_nright++;
    }
 
-   v->spl_ldatum = PointerGetDatum(datum_l);
-   v->spl_rdatum = PointerGetDatum(datum_r);
+   v->spl_ldatum = PointerGetDatum(seg_l);
+   v->spl_rdatum = PointerGetDatum(seg_r);
 
-   return v;
+   PG_RETURN_POINTER(v);
 }
 
 /*
 ** Equality methods
 */
-bool *
-gseg_same(SEG *b1, SEG *b2, bool *result)
+Datum
+gseg_same(PG_FUNCTION_ARGS)
 {
-   if (seg_same(b1, b2))
+   bool       *result = (bool *) PG_GETARG_POINTER(2);
+
+   if (DirectFunctionCall2(seg_same, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)))
        *result = TRUE;
    else
        *result = FALSE;
@@ -405,18 +421,16 @@ gseg_same(SEG *b1, SEG *b2, bool *result)
    fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
 #endif
 
-   return (result);
+   PG_RETURN_POINTER(result);
 }
 
 /*
 ** SUPPORT ROUTINES
 */
-bool
-gseg_leaf_consistent(SEG *key,
-                    SEG *query,
-                    StrategyNumber strategy)
+static Datum
+gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy)
 {
-   bool        retval;
+   Datum       retval;
 
 #ifdef GIST_QUERY_DEBUG
    fprintf(stderr, "leaf_consistent, %d\n", strategy);
@@ -425,41 +439,40 @@ gseg_leaf_consistent(SEG *key,
    switch (strategy)
    {
        case RTLeftStrategyNumber:
-           retval = (bool) seg_left(key, query);
+           retval = DirectFunctionCall2(seg_left, key, query);
            break;
        case RTOverLeftStrategyNumber:
-           retval = (bool) seg_over_left(key, query);
+           retval = DirectFunctionCall2(seg_over_left, key, query);
            break;
        case RTOverlapStrategyNumber:
-           retval = (bool) seg_overlap(key, query);
+           retval = DirectFunctionCall2(seg_overlap, key, query);
            break;
        case RTOverRightStrategyNumber:
-           retval = (bool) seg_over_right(key, query);
+           retval = DirectFunctionCall2(seg_over_right, key, query);
            break;
        case RTRightStrategyNumber:
-           retval = (bool) seg_right(key, query);
+           retval = DirectFunctionCall2(seg_right, key, query);
            break;
        case RTSameStrategyNumber:
-           retval = (bool) seg_same(key, query);
+           retval = DirectFunctionCall2(seg_same, key, query);
            break;
        case RTContainsStrategyNumber:
        case RTOldContainsStrategyNumber:
-           retval = (bool) seg_contains(key, query);
+           retval = DirectFunctionCall2(seg_contains, key, query);
            break;
        case RTContainedByStrategyNumber:
        case RTOldContainedByStrategyNumber:
-           retval = (bool) seg_contained(key, query);
+           retval = DirectFunctionCall2(seg_contained, key, query);
            break;
        default:
            retval = FALSE;
    }
-   return (retval);
+
+   PG_RETURN_DATUM(retval);
 }
 
-bool
-gseg_internal_consistent(SEG *key,
-                        SEG *query,
-                        StrategyNumber strategy)
+static Datum
+gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
 {
    bool        retval;
 
@@ -470,117 +483,147 @@ gseg_internal_consistent(SEG *key,
    switch (strategy)
    {
        case RTLeftStrategyNumber:
-           retval = (bool) !seg_over_right(key, query);
+           retval =
+               !DatumGetBool(DirectFunctionCall2(seg_over_right, key, query));
            break;
        case RTOverLeftStrategyNumber:
-           retval = (bool) !seg_right(key, query);
+           retval =
+               !DatumGetBool(DirectFunctionCall2(seg_right, key, query));
            break;
        case RTOverlapStrategyNumber:
-           retval = (bool) seg_overlap(key, query);
+           retval =
+               DatumGetBool(DirectFunctionCall2(seg_overlap, key, query));
            break;
        case RTOverRightStrategyNumber:
-           retval = (bool) !seg_left(key, query);
+           retval =
+               !DatumGetBool(DirectFunctionCall2(seg_left, key, query));
            break;
        case RTRightStrategyNumber:
-           retval = (bool) !seg_over_left(key, query);
+           retval =
+               !DatumGetBool(DirectFunctionCall2(seg_over_left, key, query));
            break;
        case RTSameStrategyNumber:
        case RTContainsStrategyNumber:
        case RTOldContainsStrategyNumber:
-           retval = (bool) seg_contains(key, query);
+           retval =
+               DatumGetBool(DirectFunctionCall2(seg_contains, key, query));
            break;
        case RTContainedByStrategyNumber:
        case RTOldContainedByStrategyNumber:
-           retval = (bool) seg_overlap(key, query);
+           retval =
+               DatumGetBool(DirectFunctionCall2(seg_overlap, key, query));
            break;
        default:
            retval = FALSE;
    }
-   return (retval);
+
+   PG_RETURN_BOOL(retval);
 }
 
-SEG *
-gseg_binary_union(SEG *r1, SEG *r2, int *sizep)
+static Datum
+gseg_binary_union(Datum r1, Datum r2, int *sizep)
 {
-   SEG        *retval;
+   Datum       retval;
 
-   retval = seg_union(r1, r2);
+   retval = DirectFunctionCall2(seg_union, r1, r2);
    *sizep = sizeof(SEG);
 
    return (retval);
 }
 
 
-bool
-seg_contains(SEG *a, SEG *b)
+Datum
+seg_contains(PG_FUNCTION_ARGS)
 {
-   return ((a->lower <= b->lower) && (a->upper >= b->upper));
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
+   PG_RETURN_BOOL((a->lower <= b->lower) && (a->upper >= b->upper));
 }
 
-bool
-seg_contained(SEG *a, SEG *b)
+Datum
+seg_contained(PG_FUNCTION_ARGS)
 {
-   return (seg_contains(b, a));
+   Datum       a = PG_GETARG_DATUM(0);
+   Datum       b = PG_GETARG_DATUM(1);
+
+   PG_RETURN_DATUM(DirectFunctionCall2(seg_contains, b, a));
 }
 
 /*****************************************************************************
  * Operator class for R-tree indexing
  *****************************************************************************/
 
-bool
-seg_same(SEG *a, SEG *b)
+Datum
+seg_same(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) == 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp == 0);
 }
 
 /* seg_overlap -- does a overlap b?
  */
-bool
-seg_overlap(SEG *a, SEG *b)
+Datum
+seg_overlap(PG_FUNCTION_ARGS)
 {
-   return (
-           ((a->upper >= b->upper) && (a->lower <= b->upper))
-           ||
-           ((b->upper >= a->upper) && (b->lower <= a->upper))
-       );
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
+   PG_RETURN_BOOL(((a->upper >= b->upper) && (a->lower <= b->upper)) ||
+                  ((b->upper >= a->upper) && (b->lower <= a->upper)));
 }
 
-/* seg_overleft -- is the right edge of (a) located at or left of the right edge of (b)?
+/* seg_over_left -- is the right edge of (a) located at or left of the right edge of (b)?
  */
-bool
-seg_over_left(SEG *a, SEG *b)
+Datum
+seg_over_left(PG_FUNCTION_ARGS)
 {
-   return (a->upper <= b->upper);
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
+   PG_RETURN_BOOL(a->upper <= b->upper);
 }
 
 /* seg_left -- is (a) entirely on the left of (b)?
  */
-bool
-seg_left(SEG *a, SEG *b)
+Datum
+seg_left(PG_FUNCTION_ARGS)
 {
-   return (a->upper < b->lower);
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
+   PG_RETURN_BOOL(a->upper < b->lower);
 }
 
 /* seg_right -- is (a) entirely on the right of (b)?
  */
-bool
-seg_right(SEG *a, SEG *b)
+Datum
+seg_right(PG_FUNCTION_ARGS)
 {
-   return (a->lower > b->upper);
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
+   PG_RETURN_BOOL(a->lower > b->upper);
 }
 
-/* seg_overright -- is the left edge of (a) located at or right of the left edge of (b)?
+/* seg_over_right -- is the left edge of (a) located at or right of the left edge of (b)?
  */
-bool
-seg_over_right(SEG *a, SEG *b)
+Datum
+seg_over_right(PG_FUNCTION_ARGS)
 {
-   return (a->lower >= b->lower);
-}
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
 
+   PG_RETURN_BOOL(a->lower >= b->lower);
+}
 
-SEG *
-seg_union(SEG *a, SEG *b)
+Datum
+seg_union(PG_FUNCTION_ARGS)
 {
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
    SEG        *n;
 
    n = (SEG *) palloc(sizeof(*n));
@@ -613,13 +656,14 @@ seg_union(SEG *a, SEG *b)
        n->l_ext = b->l_ext;
    }
 
-   return (n);
+   PG_RETURN_POINTER(n);
 }
 
-
-SEG *
-seg_inter(SEG *a, SEG *b)
+Datum
+seg_inter(PG_FUNCTION_ARGS)
 {
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
    SEG        *n;
 
    n = (SEG *) palloc(sizeof(*n));
@@ -652,10 +696,10 @@ seg_inter(SEG *a, SEG *b)
        n->l_ext = b->l_ext;
    }
 
-   return (n);
+   PG_RETURN_POINTER(n);
 }
 
-void
+static void
 rt_seg_size(SEG *a, float *size)
 {
    if (a == (SEG *) NULL || a->upper <= a->lower)
@@ -669,7 +713,7 @@ rt_seg_size(SEG *a, float *size)
 Datum
 seg_size(PG_FUNCTION_ARGS)
 {
-   SEG        *seg = (SEG *) PG_GETARG_POINTER(0);
+   SEG        *seg = PG_GETARG_SEG_P(0);
 
    PG_RETURN_FLOAT4((float) Abs(seg->upper - seg->lower));
 }
@@ -678,16 +722,19 @@ seg_size(PG_FUNCTION_ARGS)
 /*****************************************************************************
  *                Miscellaneous operators
  *****************************************************************************/
-int32
-seg_cmp(SEG *a, SEG *b)
+Datum
+seg_cmp(PG_FUNCTION_ARGS)
 {
+   SEG        *a = PG_GETARG_SEG_P(0);
+   SEG        *b = PG_GETARG_SEG_P(1);
+
    /*
     * First compare on lower boundary position
     */
    if (a->lower < b->lower)
-       return -1;
+       PG_RETURN_INT32(-1);
    if (a->lower > b->lower)
-       return 1;
+       PG_RETURN_INT32(1);
 
    /*
     * a->lower == b->lower, so consider type of boundary.
@@ -699,27 +746,27 @@ seg_cmp(SEG *a, SEG *b)
    if (a->l_ext != b->l_ext)
    {
        if (a->l_ext == '-')
-           return -1;
+           PG_RETURN_INT32(-1);
        if (b->l_ext == '-')
-           return 1;
+           PG_RETURN_INT32(1);
        if (a->l_ext == '<')
-           return -1;
+           PG_RETURN_INT32(-1);
        if (b->l_ext == '<')
-           return 1;
+           PG_RETURN_INT32(1);
        if (a->l_ext == '>')
-           return 1;
+           PG_RETURN_INT32(1);
        if (b->l_ext == '>')
-           return -1;
+           PG_RETURN_INT32(-1);
    }
 
    /*
     * For other boundary types, consider # of significant digits first.
     */
    if (a->l_sigd < b->l_sigd)  /* (a) is blurred and is likely to include (b) */
-       return -1;
+       PG_RETURN_INT32(-1);
    if (a->l_sigd > b->l_sigd)  /* (a) is less blurred and is likely to be
                                 * included in (b) */
-       return 1;
+       PG_RETURN_INT32(1);
 
    /*
     * For same # of digits, an approximate boundary is more blurred than
@@ -728,9 +775,9 @@ seg_cmp(SEG *a, SEG *b)
    if (a->l_ext != b->l_ext)
    {
        if (a->l_ext == '~')    /* (a) is approximate, while (b) is exact */
-           return -1;
+           PG_RETURN_INT32(-1);
        if (b->l_ext == '~')
-           return 1;
+           PG_RETURN_INT32(1);
        /* can't get here unless data is corrupt */
        elog(ERROR, "bogus lower boundary types %d %d",
             (int) a->l_ext, (int) b->l_ext);
@@ -742,9 +789,9 @@ seg_cmp(SEG *a, SEG *b)
     * First compare on upper boundary position
     */
    if (a->upper < b->upper)
-       return -1;
+       PG_RETURN_INT32(-1);
    if (a->upper > b->upper)
-       return 1;
+       PG_RETURN_INT32(1);
 
    /*
     * a->upper == b->upper, so consider type of boundary.
@@ -756,17 +803,17 @@ seg_cmp(SEG *a, SEG *b)
    if (a->u_ext != b->u_ext)
    {
        if (a->u_ext == '-')
-           return 1;
+           PG_RETURN_INT32(1);
        if (b->u_ext == '-')
-           return -1;
+           PG_RETURN_INT32(-1);
        if (a->u_ext == '<')
-           return -1;
+           PG_RETURN_INT32(-1);
        if (b->u_ext == '<')
-           return 1;
+           PG_RETURN_INT32(1);
        if (a->u_ext == '>')
-           return 1;
+           PG_RETURN_INT32(1);
        if (b->u_ext == '>')
-           return -1;
+           PG_RETURN_INT32(-1);
    }
 
    /*
@@ -774,10 +821,10 @@ seg_cmp(SEG *a, SEG *b)
     * result here is converse of the lower-boundary case.
     */
    if (a->u_sigd < b->u_sigd)  /* (a) is blurred and is likely to include (b) */
-       return 1;
+       PG_RETURN_INT32(1);
    if (a->u_sigd > b->u_sigd)  /* (a) is less blurred and is likely to be
                                 * included in (b) */
-       return -1;
+       PG_RETURN_INT32(-1);
 
    /*
     * For same # of digits, an approximate boundary is more blurred than
@@ -786,45 +833,61 @@ seg_cmp(SEG *a, SEG *b)
    if (a->u_ext != b->u_ext)
    {
        if (a->u_ext == '~')    /* (a) is approximate, while (b) is exact */
-           return 1;
+           PG_RETURN_INT32(1);
        if (b->u_ext == '~')
-           return -1;
+           PG_RETURN_INT32(-1);
        /* can't get here unless data is corrupt */
        elog(ERROR, "bogus upper boundary types %d %d",
             (int) a->u_ext, (int) b->u_ext);
    }
 
-   return 0;
+   PG_RETURN_INT32(0);
 }
 
-bool
-seg_lt(SEG *a, SEG *b)
+Datum
+seg_lt(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) < 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp < 0);
 }
 
-bool
-seg_le(SEG *a, SEG *b)
+Datum
+seg_le(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) <= 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp <= 0);
 }
 
-bool
-seg_gt(SEG *a, SEG *b)
+Datum
+seg_gt(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) > 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp > 0);
 }
 
-bool
-seg_ge(SEG *a, SEG *b)
+Datum
+seg_ge(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) >= 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp >= 0);
 }
 
-bool
-seg_different(SEG *a, SEG *b)
+
+Datum
+seg_different(PG_FUNCTION_ARGS)
 {
-   return seg_cmp(a, b) != 0;
+   int         cmp = DatumGetInt32(
+      DirectFunctionCall2(seg_cmp, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
+
+   PG_RETURN_BOOL(cmp != 0);
 }
 
 
@@ -985,24 +1048,6 @@ restore(char *result, float val, int n)
 ** Miscellany
 */
 
-bool
-seg_contains_int(SEG *a, int *b)
-{
-   return ((a->lower <= *b) && (a->upper >= *b));
-}
-
-bool
-seg_contains_float4(SEG *a, float4 *b)
-{
-   return ((a->lower <= *b) && (a->upper >= *b));
-}
-
-bool
-seg_contains_float8(SEG *a, float8 *b)
-{
-   return ((a->lower <= *b) && (a->upper >= *b));
-}
-
 /* find out the number of significant digits in a string representing
  * a floating point number
  */