]> granicus.if.org Git - postgresql/commitdiff
Migrate rtree_gist functionality into the core system, and add some
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jul 2005 19:19:05 +0000 (19:19 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jul 2005 19:19:05 +0000 (19:19 +0000)
basic regression tests for GiST to the standard regression tests.
I took the opportunity to add an rtree-equivalent gist opclass for
circles; the contrib version only covered boxes and polygons, but
indexing circles is very handy for distance searches.

16 files changed:
src/backend/access/gist/Makefile
src/backend/access/gist/gistproc.c [new file with mode: 0644]
src/backend/utils/adt/geo_ops.c
src/include/catalog/catversion.h
src/include/catalog/pg_amop.h
src/include/catalog/pg_amproc.h
src/include/catalog/pg_opclass.h
src/include/catalog/pg_operator.h
src/include/catalog/pg_proc.h
src/include/utils/geo_decls.h
src/test/regress/data/rect.data
src/test/regress/expected/create_index.out
src/test/regress/expected/opr_sanity.out
src/test/regress/expected/sanity_check.out
src/test/regress/sql/create_index.sql
src/test/regress/sql/opr_sanity.sql

index 12f770ddb880693f42fa21453076afae6efd1cee..10b091e170602dae119e770da0662efa1917d4d3 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for access/gist
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/access/gist/Makefile,v 1.14 2005/06/20 10:29:36 teodor Exp $
+#    $PostgreSQL: pgsql/src/backend/access/gist/Makefile,v 1.15 2005/07/01 19:19:02 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,7 +12,8 @@ subdir = src/backend/access/gist
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = gist.o gistutil.o gistxlog.o gistvacuum.o gistget.o gistscan.o
+OBJS = gist.o gistutil.o gistxlog.o gistvacuum.o gistget.o gistscan.o \
+       gistproc.o
 
 all: SUBSYS.o
 
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
new file mode 100644 (file)
index 0000000..a43d145
--- /dev/null
@@ -0,0 +1,708 @@
+/*-------------------------------------------------------------------------
+ *
+ * gistproc.c
+ *       Support procedures for GiSTs over 2-D objects (boxes, polygons, circles).
+ *
+ * This gives R-tree behavior, with Guttman's poly-time split algorithm.
+ *
+ *
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *     $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.1 2005/07/01 19:19:02 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/gist.h"
+#include "access/itup.h"
+#include "access/rtree.h"
+#include "utils/geo_decls.h"
+
+
+typedef struct
+{
+       BOX                *key;
+       int                     pos;
+}      KBsort;
+
+static int     compare_KB(const void *a, const void *b);
+static bool gist_box_leaf_consistent(BOX *key, BOX *query,
+                                                                        StrategyNumber strategy);
+static double size_box(Datum dbox);
+static bool rtree_internal_consistent(BOX *key, BOX *query,
+                                                                         StrategyNumber strategy);
+
+
+/**************************************************
+ * Box ops
+ **************************************************/
+
+/*
+ * The GiST Consistent method for boxes
+ *
+ * Should return false if for all data items x below entry,
+ * the predicate x op query must be FALSE, where op is the oper
+ * corresponding to strategy in the pg_amop table.
+ */
+Datum
+gist_box_consistent(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       BOX                *query = PG_GETARG_BOX_P(1);
+       StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+       if (DatumGetBoxP(entry->key) == NULL || query == NULL)
+               PG_RETURN_BOOL(FALSE);
+
+       /*
+        * if entry is not leaf, use rtree_internal_consistent, else use
+        * gist_box_leaf_consistent
+        */
+       if (GIST_LEAF(entry))
+               PG_RETURN_BOOL(gist_box_leaf_consistent(DatumGetBoxP(entry->key),
+                                                                                               query,
+                                                                                               strategy));
+       else
+               PG_RETURN_BOOL(rtree_internal_consistent(DatumGetBoxP(entry->key),
+                                                                                                query,
+                                                                                                strategy));
+}
+
+
+/*
+ * The GiST Union method for boxes
+ *
+ * returns the minimal bounding box that encloses all the entries in entryvec
+ */
+Datum
+gist_box_union(PG_FUNCTION_ARGS)
+{
+       GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+       int                *sizep = (int *) PG_GETARG_POINTER(1);
+       int                     numranges,
+                               i;
+       BOX                *cur,
+                          *pageunion;
+
+       numranges = entryvec->n;
+       pageunion = (BOX *) palloc(sizeof(BOX));
+       cur = DatumGetBoxP(entryvec->vector[0].key);
+       memcpy((void *) pageunion, (void *) cur, sizeof(BOX));
+
+       for (i = 1; i < numranges; i++)
+       {
+               cur = DatumGetBoxP(entryvec->vector[i].key);
+               if (pageunion->high.x < cur->high.x)
+                       pageunion->high.x = cur->high.x;
+               if (pageunion->low.x > cur->low.x)
+                       pageunion->low.x = cur->low.x;
+               if (pageunion->high.y < cur->high.y)
+                       pageunion->high.y = cur->high.y;
+               if (pageunion->low.y > cur->low.y)
+                       pageunion->low.y = cur->low.y;
+       }
+       *sizep = sizeof(BOX);
+
+       PG_RETURN_POINTER(pageunion);
+}
+
+/*
+ * GiST Compress methods for boxes
+ *
+ * do not do anything.
+ */
+Datum
+gist_box_compress(PG_FUNCTION_ARGS)
+{
+       PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+
+/*
+ * GiST DeCompress method for boxes (also used for polygons and circles)
+ *
+ * do not do anything --- we just use the stored box as is.
+ */
+Datum
+gist_box_decompress(PG_FUNCTION_ARGS)
+{
+       PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+
+/*
+ * The GiST Penalty method for boxes
+ *
+ * As in the R-tree paper, we use change in area as our penalty metric
+ */
+Datum
+gist_box_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);
+       Datum           ud;
+
+       ud = DirectFunctionCall2(rt_box_union, origentry->key, newentry->key);
+       *result = (float) (size_box(ud) - size_box(origentry->key));
+       PG_RETURN_POINTER(result);
+}
+
+/*
+ * qsort comparator for box areas
+ */
+static int
+compare_KB(const void *a, const void *b)
+{
+       BOX                *abox = ((const KBsort *) a)->key;
+       BOX                *bbox = ((const KBsort *) b)->key;
+       double          sa = (abox->high.x - abox->low.x) * (abox->high.y - abox->low.y);
+       double          sb = (bbox->high.x - bbox->low.x) * (bbox->high.y - bbox->low.y);
+
+       if (sa == sb)
+               return 0;
+       return (sa > sb) ? 1 : -1;
+}
+
+/*
+ * The GiST PickSplit method
+ *
+ * New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree',
+ * C.H.Ang and T.C.Tan
+ */
+Datum
+gist_box_picksplit(PG_FUNCTION_ARGS)
+{
+       GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+       GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+       OffsetNumber i;
+       OffsetNumber *listL,
+                          *listR,
+                          *listB,
+                          *listT;
+       BOX                *unionL,
+                          *unionR,
+                          *unionB,
+                          *unionT;
+       int                     posL,
+                               posR,
+                               posB,
+                               posT;
+       BOX                     pageunion;
+       BOX                *cur;
+       char            direction = ' ';
+       bool            allisequal = true;
+       OffsetNumber maxoff;
+       int                     nbytes;
+
+       posL = posR = posB = posT = 0;
+       maxoff = entryvec->n - 1;
+
+       cur = DatumGetBoxP(entryvec->vector[FirstOffsetNumber].key);
+       memcpy((void *) &pageunion, (void *) cur, sizeof(BOX));
+
+       /* find MBR */
+       for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i))
+       {
+               cur = DatumGetBoxP(entryvec->vector[i].key);
+               if (allisequal == true && (
+                                                                  pageunion.high.x != cur->high.x ||
+                                                                  pageunion.high.y != cur->high.y ||
+                                                                  pageunion.low.x != cur->low.x ||
+                                                                  pageunion.low.y != cur->low.y
+                                                                  ))
+                       allisequal = false;
+
+               if (pageunion.high.x < cur->high.x)
+                       pageunion.high.x = cur->high.x;
+               if (pageunion.low.x > cur->low.x)
+                       pageunion.low.x = cur->low.x;
+               if (pageunion.high.y < cur->high.y)
+                       pageunion.high.y = cur->high.y;
+               if (pageunion.low.y > cur->low.y)
+                       pageunion.low.y = cur->low.y;
+       }
+
+       nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+       listL = (OffsetNumber *) palloc(nbytes);
+       listR = (OffsetNumber *) palloc(nbytes);
+       unionL = (BOX *) palloc(sizeof(BOX));
+       unionR = (BOX *) palloc(sizeof(BOX));
+       if (allisequal)
+       {
+               cur = DatumGetBoxP(entryvec->vector[OffsetNumberNext(FirstOffsetNumber)].key);
+               if (memcmp((void *) cur, (void *) &pageunion, sizeof(BOX)) == 0)
+               {
+                       v->spl_left = listL;
+                       v->spl_right = listR;
+                       v->spl_nleft = v->spl_nright = 0;
+                       memcpy((void *) unionL, (void *) &pageunion, sizeof(BOX));
+                       memcpy((void *) unionR, (void *) &pageunion, sizeof(BOX));
+
+                       for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+                       {
+                               if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
+                               {
+                                       v->spl_left[v->spl_nleft] = i;
+                                       v->spl_nleft++;
+                               }
+                               else
+                               {
+                                       v->spl_right[v->spl_nright] = i;
+                                       v->spl_nright++;
+                               }
+                       }
+                       v->spl_ldatum = BoxPGetDatum(unionL);
+                       v->spl_rdatum = BoxPGetDatum(unionR);
+
+                       PG_RETURN_POINTER(v);
+               }
+       }
+
+       listB = (OffsetNumber *) palloc(nbytes);
+       listT = (OffsetNumber *) palloc(nbytes);
+       unionB = (BOX *) palloc(sizeof(BOX));
+       unionT = (BOX *) palloc(sizeof(BOX));
+
+#define ADDLIST( list, unionD, pos, num ) do { \
+       if ( pos ) { \
+               if ( (unionD)->high.x < cur->high.x ) (unionD)->high.x  = cur->high.x; \
+               if ( (unionD)->low.x  > cur->low.x  ) (unionD)->low.x   = cur->low.x; \
+               if ( (unionD)->high.y < cur->high.y ) (unionD)->high.y  = cur->high.y; \
+               if ( (unionD)->low.y  > cur->low.y  ) (unionD)->low.y   = cur->low.y; \
+       } else { \
+                       memcpy( (void*)(unionD), (void*) cur, sizeof( BOX ) );  \
+       } \
+       (list)[pos] = num; \
+       (pos)++; \
+} while(0)
+
+       for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+       {
+               cur = DatumGetBoxP(entryvec->vector[i].key);
+               if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x)
+                       ADDLIST(listL, unionL, posL, i);
+               else
+                       ADDLIST(listR, unionR, posR, i);
+               if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y)
+                       ADDLIST(listB, unionB, posB, i);
+               else
+                       ADDLIST(listT, unionT, posT, i);
+       }
+
+       /* bad disposition, sort by ascending and resplit */
+       if ((posR == 0 || posL == 0) && (posT == 0 || posB == 0))
+       {
+               KBsort     *arr = (KBsort *) palloc(sizeof(KBsort) * maxoff);
+
+               posL = posR = posB = posT = 0;
+               for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+               {
+                       arr[i - 1].key = DatumGetBoxP(entryvec->vector[i].key);
+                       arr[i - 1].pos = i;
+               }
+               qsort(arr, maxoff, sizeof(KBsort), compare_KB);
+               for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
+               {
+                       cur = arr[i - 1].key;
+                       if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x)
+                               ADDLIST(listL, unionL, posL, arr[i - 1].pos);
+                       else if (cur->low.x - pageunion.low.x == pageunion.high.x - cur->high.x)
+                       {
+                               if (posL > posR)
+                                       ADDLIST(listR, unionR, posR, arr[i - 1].pos);
+                               else
+                                       ADDLIST(listL, unionL, posL, arr[i - 1].pos);
+                       }
+                       else
+                               ADDLIST(listR, unionR, posR, arr[i - 1].pos);
+
+                       if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y)
+                               ADDLIST(listB, unionB, posB, arr[i - 1].pos);
+                       else if (cur->low.y - pageunion.low.y == pageunion.high.y - cur->high.y)
+                       {
+                               if (posB > posT)
+                                       ADDLIST(listT, unionT, posT, arr[i - 1].pos);
+                               else
+                                       ADDLIST(listB, unionB, posB, arr[i - 1].pos);
+                       }
+                       else
+                               ADDLIST(listT, unionT, posT, arr[i - 1].pos);
+               }
+       }
+
+       /* which split more optimal? */
+       if (Max(posL, posR) < Max(posB, posT))
+               direction = 'x';
+       else if (Max(posL, posR) > Max(posB, posT))
+               direction = 'y';
+       else
+       {
+               Datum           interLR = DirectFunctionCall2(rt_box_inter,
+                                                                                                 BoxPGetDatum(unionL),
+                                                                                                 BoxPGetDatum(unionR));
+               Datum           interBT = DirectFunctionCall2(rt_box_inter,
+                                                                                                 BoxPGetDatum(unionB),
+                                                                                                 BoxPGetDatum(unionT));
+               double          sizeLR,
+                                       sizeBT;
+
+               sizeLR = size_box(interLR);
+               sizeBT = size_box(interBT);
+
+               if (sizeLR < sizeBT)
+                       direction = 'x';
+               else
+                       direction = 'y';
+       }
+
+       if (direction == 'x')
+       {
+               v->spl_left = listL;
+               v->spl_right = listR;
+               v->spl_nleft = posL;
+               v->spl_nright = posR;
+               v->spl_ldatum = BoxPGetDatum(unionL);
+               v->spl_rdatum = BoxPGetDatum(unionR);
+       }
+       else
+       {
+               v->spl_left = listB;
+               v->spl_right = listT;
+               v->spl_nleft = posB;
+               v->spl_nright = posT;
+               v->spl_ldatum = BoxPGetDatum(unionB);
+               v->spl_rdatum = BoxPGetDatum(unionT);
+       }
+
+       PG_RETURN_POINTER(v);
+}
+
+/*
+ * Equality method
+ */
+Datum
+gist_box_same(PG_FUNCTION_ARGS)
+{
+       BOX                *b1 = PG_GETARG_BOX_P(0);
+       BOX                *b2 = PG_GETARG_BOX_P(1);
+       bool       *result = (bool *) PG_GETARG_POINTER(2);
+
+       if (b1 && b2)
+               *result = DatumGetBool(DirectFunctionCall2(box_same,
+                                                                                                  PointerGetDatum(b1),
+                                                                                                  PointerGetDatum(b2)));
+       else
+               *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE;
+       PG_RETURN_POINTER(result);
+}
+
+/*
+ * Leaf-level consistency for boxes: just apply the query operator
+ */
+static bool
+gist_box_leaf_consistent(BOX *key, BOX *query, StrategyNumber strategy)
+{
+       bool            retval;
+
+       switch (strategy)
+       {
+               case RTLeftStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_left,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverLeftStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overleft,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverlapStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overlap,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverRightStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overright,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTRightStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_right,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTSameStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_same,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTContainsStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_contain,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTContainedByStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_contained,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverBelowStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overbelow,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTBelowStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_below,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTAboveStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_above,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverAboveStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overabove,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               default:
+                       retval = FALSE;
+       }
+       return retval;
+}
+
+static double
+size_box(Datum dbox)
+{
+       BOX        *box = DatumGetBoxP(dbox);
+
+       if (box == NULL || box->high.x <= box->low.x || box->high.y <= box->low.y)
+               return 0.0;
+       return (box->high.x - box->low.x) * (box->high.y - box->low.y);
+}
+
+/*****************************************
+ * Common rtree functions (for boxes, polygons, and circles)
+ *****************************************/
+
+/*
+ * Internal-page consistency for all these types
+ *
+ * We can use the same function since all types use bounding boxes as the
+ * internal-page representation.
+ *
+ * This implements the same logic as the rtree internal-page strategy map.
+ */
+static bool
+rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy)
+{
+       bool            retval;
+
+       switch (strategy)
+       {
+               case RTLeftStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_overright,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTOverLeftStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_right,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTOverlapStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overlap,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverRightStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_left,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTRightStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_overleft,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTSameStrategyNumber:
+               case RTContainsStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_contain,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTContainedByStrategyNumber:
+                       retval = DatumGetBool(DirectFunctionCall2(box_overlap,
+                                                                                                         PointerGetDatum(key),
+                                                                                                         PointerGetDatum(query)));
+                       break;
+               case RTOverBelowStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_above,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTBelowStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_overabove,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTAboveStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_overbelow,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               case RTOverAboveStrategyNumber:
+                       retval = !DatumGetBool(DirectFunctionCall2(box_below,
+                                                                                                          PointerGetDatum(key),
+                                                                                                          PointerGetDatum(query)));
+                       break;
+               default:
+                       retval = FALSE;
+       }
+       return retval;
+}
+
+/**************************************************
+ * Polygon ops
+ **************************************************/
+
+/*
+ * GiST compress for polygons: represent a polygon by its bounding box
+ */
+Datum
+gist_poly_compress(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       GISTENTRY  *retval;
+
+       if (entry->leafkey)
+       {
+               retval = palloc(sizeof(GISTENTRY));
+               if (DatumGetPointer(entry->key) != NULL)
+               {
+                       POLYGON    *in = DatumGetPolygonP(entry->key);
+                       BOX                *r;
+
+                       r = (BOX *) palloc(sizeof(BOX));
+                       memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));
+                       gistentryinit(*retval, PointerGetDatum(r),
+                                                 entry->rel, entry->page,
+                                                 entry->offset, sizeof(BOX), FALSE);
+
+               }
+               else
+               {
+                       gistentryinit(*retval, (Datum) 0,
+                                                 entry->rel, entry->page,
+                                                 entry->offset, 0, FALSE);
+               }
+       }
+       else
+               retval = entry;
+       PG_RETURN_POINTER(retval);
+}
+
+/*
+ * The GiST Consistent method for polygons
+ */
+Datum
+gist_poly_consistent(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       POLYGON    *query = PG_GETARG_POLYGON_P(1);
+       StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+       bool            result;
+
+       if (DatumGetBoxP(entry->key) == NULL || query == NULL)
+               PG_RETURN_BOOL(FALSE);
+
+       /*
+        * Since the operators are marked lossy anyway, we can just use
+        * rtree_internal_consistent even at leaf nodes.  (This works
+        * in part because the index entries are bounding boxes not polygons.)
+        */
+       result = rtree_internal_consistent(DatumGetBoxP(entry->key),
+                                                                          &(query->boundbox), strategy);
+
+       /* Avoid memory leak if supplied poly is toasted */
+       PG_FREE_IF_COPY(query, 1);
+
+       PG_RETURN_BOOL(result);
+}
+
+/**************************************************
+ * Circle ops
+ **************************************************/
+
+/*
+ * GiST compress for circles: represent a circle by its bounding box
+ */
+Datum
+gist_circle_compress(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       GISTENTRY  *retval;
+
+       if (entry->leafkey)
+       {
+               retval = palloc(sizeof(GISTENTRY));
+               if (DatumGetCircleP(entry->key) != NULL)
+               {
+                       CIRCLE    *in = DatumGetCircleP(entry->key);
+                       BOX                *r;
+
+                       r = (BOX *) palloc(sizeof(BOX));
+                       r->high.x = in->center.x + in->radius;
+                       r->low.x = in->center.x - in->radius;
+                       r->high.y = in->center.y + in->radius;
+                       r->low.y = in->center.y - in->radius;
+                       gistentryinit(*retval, PointerGetDatum(r),
+                                                 entry->rel, entry->page,
+                                                 entry->offset, sizeof(BOX), FALSE);
+
+               }
+               else
+               {
+                       gistentryinit(*retval, (Datum) 0,
+                                                 entry->rel, entry->page,
+                                                 entry->offset, 0, FALSE);
+               }
+       }
+       else
+               retval = entry;
+       PG_RETURN_POINTER(retval);
+}
+
+/*
+ * The GiST Consistent method for circles
+ */
+Datum
+gist_circle_consistent(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       CIRCLE    *query = PG_GETARG_CIRCLE_P(1);
+       StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+       BOX                     bbox;
+       bool            result;
+
+       if (DatumGetBoxP(entry->key) == NULL || query == NULL)
+               PG_RETURN_BOOL(FALSE);
+
+       /*
+        * Since the operators are marked lossy anyway, we can just use
+        * rtree_internal_consistent even at leaf nodes.  (This works
+        * in part because the index entries are bounding boxes not circles.)
+        */
+       bbox.high.x = query->center.x + query->radius;
+       bbox.low.x = query->center.x - query->radius;
+       bbox.high.y = query->center.y + query->radius;
+       bbox.low.y = query->center.y - query->radius;
+
+       result = rtree_internal_consistent(DatumGetBoxP(entry->key),
+                                                                          &bbox, strategy);
+
+       PG_RETURN_BOOL(result);
+}
index e2794482633f768dafcc40913a0f0f259d509641..1786da6dd1c6997eedf4d99b2f64bda2a6164ee5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.89 2005/06/24 20:53:31 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.90 2005/07/01 19:19:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4605,8 +4605,7 @@ circle_contain(PG_FUNCTION_ARGS)
 }
 
 
-/*             circle_positionop               -
- *                             is circle1 entirely {above,below} circle2?
+/*             circle_below            -               is circle1 strictly below circle2?
  */
 Datum
 circle_below(PG_FUNCTION_ARGS)
@@ -4614,18 +4613,46 @@ circle_below(PG_FUNCTION_ARGS)
        CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
        CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);
 
-       PG_RETURN_BOOL(FPle(circle1->center.y + circle1->radius,
-                                               circle2->center.y - circle2->radius));
+       PG_RETURN_BOOL(FPlt((circle1->center.y + circle1->radius),
+                                               (circle2->center.y - circle2->radius)));
 }
 
+/*             circle_above    -               is circle1 strictly above circle2?
+ */
 Datum
 circle_above(PG_FUNCTION_ARGS)
 {
        CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
        CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);
 
-       PG_RETURN_BOOL(FPge(circle1->center.y - circle1->radius,
-                                               circle2->center.y + circle2->radius));
+       PG_RETURN_BOOL(FPgt((circle1->center.y - circle1->radius),
+                                               (circle2->center.y + circle2->radius)));
+}
+
+/*             circle_overbelow -              is the upper edge of circle1 at or below
+ *                                                             the upper edge of circle2?
+ */
+Datum
+circle_overbelow(PG_FUNCTION_ARGS)
+{
+       CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
+       CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);
+
+       PG_RETURN_BOOL(FPle((circle1->center.y + circle1->radius),
+                                               (circle2->center.y + circle2->radius)));
+}
+
+/*             circle_overabove        -       is the lower edge of circle1 at or above
+ *                                                             the lower edge of circle2?
+ */
+Datum
+circle_overabove(PG_FUNCTION_ARGS)
+{
+       CIRCLE     *circle1 = PG_GETARG_CIRCLE_P(0);
+       CIRCLE     *circle2 = PG_GETARG_CIRCLE_P(1);
+
+       PG_RETURN_BOOL(FPge((circle1->center.y - circle1->radius),
+                                               (circle2->center.y - circle2->radius)));
 }
 
 
index 5a1943723dc9561b8cb9c12865761aaf98af4bac..a465037e4b390d9538ba8083cd7a2f282581fe2a 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.283 2005/06/28 05:09:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.284 2005/07/01 19:19:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200506272
+#define CATALOG_VERSION_NO     200507011
 
 #endif
index e318898f4f6c21b490680a6f782a1c3b5d469789..35589750d160f80500b8aa1c1fc4ed373bea1e6a 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.64 2005/06/24 20:53:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.65 2005/07/01 19:19:03 tgl Exp $
  *
  * NOTES
  *      the genbki.sh script reads this file and generates .bki
@@ -619,4 +619,55 @@ DATA(insert (      2232    0 1 f 2334 ));
 /* aclitem_ops */
 DATA(insert (  2235    0 1 f  974 ));
 
+/*
+ *     gist box_ops
+ */
+
+DATA(insert (  2593    0 1  f  493 ));
+DATA(insert (  2593    0 2  f  494 ));
+DATA(insert (  2593    0 3  f  500 ));
+DATA(insert (  2593    0 4  f  495 ));
+DATA(insert (  2593    0 5  f  496 ));
+DATA(insert (  2593    0 6  f  499 ));
+DATA(insert (  2593    0 7  f  498 ));
+DATA(insert (  2593    0 8  f  497 ));
+DATA(insert (  2593    0 9  f  2571 ));
+DATA(insert (  2593    0 10 f  2570 ));
+DATA(insert (  2593    0 11 f  2573 ));
+DATA(insert (  2593    0 12 f  2572 ));
+
+/*
+ *     gist poly_ops (supports polygons)
+ */
+
+DATA(insert (  2594    0 1  t  485 ));
+DATA(insert (  2594    0 2  t  486 ));
+DATA(insert (  2594    0 3  t  492 ));
+DATA(insert (  2594    0 4  t  487 ));
+DATA(insert (  2594    0 5  t  488 ));
+DATA(insert (  2594    0 6  t  491 ));
+DATA(insert (  2594    0 7  t  490 ));
+DATA(insert (  2594    0 8  t  489 ));
+DATA(insert (  2594    0 9  t  2575 ));
+DATA(insert (  2594    0 10 t  2574 ));
+DATA(insert (  2594    0 11 t  2577 ));
+DATA(insert (  2594    0 12 t  2576 ));
+
+/*
+ *     gist circle_ops
+ */
+
+DATA(insert (  2595    0 1  t  1506 ));
+DATA(insert (  2595    0 2  t  1507 ));
+DATA(insert (  2595    0 3  t  1513 ));
+DATA(insert (  2595    0 4  t  1508 ));
+DATA(insert (  2595    0 5  t  1509 ));
+DATA(insert (  2595    0 6  t  1512 ));
+DATA(insert (  2595    0 7  t  1511 ));
+DATA(insert (  2595    0 8  t  1510 ));
+DATA(insert (  2595    0 9  t  2589 ));
+DATA(insert (  2595    0 10 t  1515 ));
+DATA(insert (  2595    0 11 t  1514 ));
+DATA(insert (  2595    0 12 t  2590 ));
+
 #endif   /* PG_AMOP_H */
index f9eb419a1694e5dbcd0c69b34c9992606a5ee065..38c4f257837bff6e46bf67c0c6d1191f3fb6b3f8 100644 (file)
@@ -19,7 +19,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.53 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.54 2005/07/01 19:19:03 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -170,4 +170,28 @@ DATA(insert (      2231    0 1 456 ));
 DATA(insert (  2232    0 1 455 ));
 DATA(insert (  2235    0 1 329 ));
 
+
+/* gist */
+DATA(insert (  2593    0 1 2578 ));
+DATA(insert (  2593    0 2 2583 ));
+DATA(insert (  2593    0 3 2579 ));
+DATA(insert (  2593    0 4 2580 ));
+DATA(insert (  2593    0 5 2581 ));
+DATA(insert (  2593    0 6 2582 ));
+DATA(insert (  2593    0 7 2584 ));
+DATA(insert (  2594    0 1 2585 ));
+DATA(insert (  2594    0 2 2583 ));
+DATA(insert (  2594    0 3 2586 ));
+DATA(insert (  2594    0 4 2580 ));
+DATA(insert (  2594    0 5 2581 ));
+DATA(insert (  2594    0 6 2582 ));
+DATA(insert (  2594    0 7 2584 ));
+DATA(insert (  2595    0 1 2591 ));
+DATA(insert (  2595    0 2 2583 ));
+DATA(insert (  2595    0 3 2592 ));
+DATA(insert (  2595    0 4 2580 ));
+DATA(insert (  2595    0 5 2581 ));
+DATA(insert (  2595    0 6 2582 ));
+DATA(insert (  2595    0 7 2584 ));
+
 #endif   /* PG_AMPROC_H */
index 23485ff0ebbd4a56c7d3aa6749e701ac0e95997f..24b4059a83193e2527d126d3a3f38b297c77e671 100644 (file)
@@ -27,7 +27,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.65 2005/06/28 05:09:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.66 2005/07/01 19:19:03 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -175,5 +175,8 @@ DATA(insert OID = 2232 (    405             name_pattern_ops        PGNSP PGUID   19 f 0 ));
 DATA(insert OID = 2233 (       403             reltime_ops             PGNSP PGUID  703 t 0 ));
 DATA(insert OID = 2234 (       403             tinterval_ops   PGNSP PGUID  704 t 0 ));
 DATA(insert OID = 2235 (       405             aclitem_ops             PGNSP PGUID 1033 t 0 ));
+DATA(insert OID = 2593 (       783             box_ops                 PGNSP PGUID  603 t 0 ));
+DATA(insert OID = 2594 (       783             poly_ops                PGNSP PGUID  604 t 603 ));
+DATA(insert OID = 2595 (       783             circle_ops              PGNSP PGUID  718 t 603 ));
 
 #endif   /* PG_OPCLASS_H */
index 9de43736eae27e953f1d78b56361f9e39a99a10f..ef04e960a79b237dcf4bf71f05071296a83d68b6 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.135 2005/06/28 05:09:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.136 2005/07/01 19:19:03 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -568,8 +568,8 @@ DATA(insert OID = 1510 (  "@"         PGNSP PGUID b f  718  718 16 1511    0        0        0       0       0
 DATA(insert OID = 1511 (  "~"    PGNSP PGUID b f  718  718 16 1510    0        0        0       0       0 circle_contain contsel contjoinsel ));
 DATA(insert OID = 1512 (  "~="   PGNSP PGUID b f  718  718 16 1512    0        0        0       0       0 circle_same eqsel eqjoinsel ));
 DATA(insert OID = 1513 (  "&&"   PGNSP PGUID b f  718  718 16 1513    0        0        0       0       0 circle_overlap areasel areajoinsel ));
-DATA(insert OID = 1514 (  ">^"   PGNSP PGUID b f  718  718 16    0    0        0        0       0       0 circle_above positionsel positionjoinsel ));
-DATA(insert OID = 1515 (  "<^"   PGNSP PGUID b f  718  718 16    0    0        0        0       0       0 circle_below positionsel positionjoinsel ));
+DATA(insert OID = 1514 (  "|>>"          PGNSP PGUID b f  718  718 16    0    0        0        0       0       0 circle_above positionsel positionjoinsel ));
+DATA(insert OID = 1515 (  "<<|"          PGNSP PGUID b f  718  718 16    0    0        0        0       0       0 circle_below positionsel positionjoinsel ));
 
 DATA(insert OID = 1516 (  "+"    PGNSP PGUID b f  718  600  718          0    0        0        0       0       0 circle_add_pt - - ));
 DATA(insert OID = 1517 (  "-"    PGNSP PGUID b f  718  600  718          0    0        0        0       0       0 circle_sub_pt - - ));
@@ -874,6 +874,8 @@ DATA(insert OID = 2574 (  "<<|"        PGNSP PGUID b f 604 604      16       0       0       0       0       0       0
 DATA(insert OID = 2575 (  "&<|"           PGNSP PGUID b f 604 604      16       0       0       0       0       0       0 poly_overbelow positionsel positionjoinsel ));
 DATA(insert OID = 2576 (  "|&>"           PGNSP PGUID b f 604 604      16       0       0       0       0       0       0 poly_overabove positionsel positionjoinsel ));
 DATA(insert OID = 2577 (  "|>>"           PGNSP PGUID b f 604 604      16       0       0       0       0       0       0 poly_above positionsel positionjoinsel ));
+DATA(insert OID = 2589 (  "&<|"           PGNSP PGUID b f 718 718      16       0       0       0       0       0       0 circle_overbelow positionsel positionjoinsel ));
+DATA(insert OID = 2590 (  "|&>"           PGNSP PGUID b f 718 718      16       0       0       0       0       0       0 circle_overabove positionsel positionjoinsel ));
 
 
 /*
index 5326a770592d7b0b6c8a9fb08bdc41bf09dc62da..340052792f76cda8d3448c3e6fd635d0ba7b6039 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.372 2005/06/28 05:09:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.373 2005/07/01 19:19:03 tgl Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -3675,6 +3675,34 @@ DATA(insert OID = 2568 (  poly_overabove   PGNSP PGUID 12 f f t f i 2 16 "604 60
 DESCR("overlaps or is above");
 DATA(insert OID = 2569 (  poly_above      PGNSP PGUID 12 f f t f i 2 16 "604 604" _null_ _null_ _null_ poly_above - _null_ ));
 DESCR("is above");
+DATA(insert OID = 2587 (  circle_overbelow             PGNSP PGUID 12 f f t f i 2      16 "718 718" _null_ _null_ _null_  circle_overbelow - _null_ ));
+DESCR("overlaps or is below");
+DATA(insert OID = 2588 (  circle_overabove             PGNSP PGUID 12 f f t f i 2      16 "718 718" _null_ _null_ _null_  circle_overabove - _null_ ));
+DESCR("overlaps or is above");
+
+/* support functions for GiST r-tree emulation */
+DATA(insert OID = 2578 (  gist_box_consistent  PGNSP PGUID 12 f f t f i 3 16 "2281 603 23" _null_ _null_ _null_        gist_box_consistent - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2579 (  gist_box_compress            PGNSP PGUID 12 f f t f i 1 2281 "2281" _null_ _null_ _null_     gist_box_compress - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2580 (  gist_box_decompress  PGNSP PGUID 12 f f t f i 1 2281 "2281" _null_ _null_ _null_     gist_box_decompress - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2581 (  gist_box_penalty             PGNSP PGUID 12 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_   gist_box_penalty - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2582 (  gist_box_picksplit   PGNSP PGUID 12 f f t f i 2 2281 "2281 2281" _null_ _null_ _null_        gist_box_picksplit - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2583 (  gist_box_union               PGNSP PGUID 12 f f t f i 2 603 "2281 2281" _null_ _null_ _null_ gist_box_union - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2584 (  gist_box_same                        PGNSP PGUID 12 f f t f i 3 2281 "603 603 2281" _null_ _null_ _null_     gist_box_same - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2585 (  gist_poly_consistent PGNSP PGUID 12 f f t f i 3 16 "2281 604 23" _null_ _null_ _null_        gist_poly_consistent - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2586 (  gist_poly_compress   PGNSP PGUID 12 f f t f i 1 2281 "2281" _null_ _null_ _null_     gist_poly_compress - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2591 (  gist_circle_consistent PGNSP PGUID 12 f f t f i 3 16 "2281 718 23" _null_ _null_ _null_      gist_circle_consistent - _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2592 (  gist_circle_compress PGNSP PGUID 12 f f t f i 1 2281 "2281" _null_ _null_ _null_     gist_circle_compress - _null_ ));
+DESCR("GiST support");
 
 
 /*
index 9bf7ce089984e6f997cbe7209c0fb5ebdf54bf4b..1795a9f14a00f72e06c389c12f5817e5b3ea53ee 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.47 2005/06/24 20:53:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.48 2005/07/01 19:19:04 tgl Exp $
  *
  * NOTE
  *       These routines do *not* use the float types from adt/.
@@ -379,6 +379,8 @@ extern Datum circle_contained(PG_FUNCTION_ARGS);
 extern Datum circle_contain(PG_FUNCTION_ARGS);
 extern Datum circle_below(PG_FUNCTION_ARGS);
 extern Datum circle_above(PG_FUNCTION_ARGS);
+extern Datum circle_overbelow(PG_FUNCTION_ARGS);
+extern Datum circle_overabove(PG_FUNCTION_ARGS);
 extern Datum circle_eq(PG_FUNCTION_ARGS);
 extern Datum circle_ne(PG_FUNCTION_ARGS);
 extern Datum circle_lt(PG_FUNCTION_ARGS);
@@ -404,7 +406,7 @@ extern Datum poly_circle(PG_FUNCTION_ARGS);
 extern Datum circle_poly(PG_FUNCTION_ARGS);
 extern Datum circle_area(PG_FUNCTION_ARGS);
 
-/* support routines for the rtree access method (rtproc.c) */
+/* support routines for the rtree access method (access/rtree/rtproc.c) */
 extern Datum rt_box_union(PG_FUNCTION_ARGS);
 extern Datum rt_box_inter(PG_FUNCTION_ARGS);
 extern Datum rt_box_size(PG_FUNCTION_ARGS);
@@ -412,6 +414,19 @@ extern Datum rt_poly_size(PG_FUNCTION_ARGS);
 extern Datum rt_poly_union(PG_FUNCTION_ARGS);
 extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
 
+/* support routines for the GiST access method (access/gist/gistproc.c) */
+extern Datum gist_box_compress(PG_FUNCTION_ARGS);
+extern Datum gist_box_decompress(PG_FUNCTION_ARGS);
+extern Datum gist_box_union(PG_FUNCTION_ARGS);
+extern Datum gist_box_picksplit(PG_FUNCTION_ARGS);
+extern Datum gist_box_consistent(PG_FUNCTION_ARGS);
+extern Datum gist_box_penalty(PG_FUNCTION_ARGS);
+extern Datum gist_box_same(PG_FUNCTION_ARGS);
+extern Datum gist_poly_compress(PG_FUNCTION_ARGS);
+extern Datum gist_poly_consistent(PG_FUNCTION_ARGS);
+extern Datum gist_circle_compress(PG_FUNCTION_ARGS);
+extern Datum gist_circle_consistent(PG_FUNCTION_ARGS);
+
 /* geo_selfuncs.c */
 extern Datum areasel(PG_FUNCTION_ARGS);
 extern Datum areajoinsel(PG_FUNCTION_ARGS);
index a8d36d02ca85eb04981e95de751ab517a0888927..e32b6fe2513d3e51ca675af967486481fe0d10de 100644 (file)
@@ -48,6 +48,7 @@
 (5739,1740,5715,1731)
 (25120,27935,25054,27876)
 (27475,46084,27447,46003)
+\N
 (33197,3252,33161,3245)
 (10892,15691,10869,15662)
 (39012,44712,38995,44640)
 (23649,6338,23610,6314)
 (25942,10008,25911,9928)
 (25651,29943,25590,29906)
+\N
 (24555,40334,24546,40330)
 (46870,43762,46789,43709)
+\N
 (20030,2752,19945,2687)
 (30758,26754,30718,26678)
+\N
 (4320,44673,4286,44625)
+\N
 (1011,15576,939,15574)
 (41936,40699,41854,40655)
 (20594,19002,20561,18995)
 (9388,41056,9325,41042)
 (34771,46693,34751,46645)
 (49398,46359,49332,46357)
+\N
 (23115,35380,23036,35306)
 (46305,34840,46283,34765)
 (16768,21692,16691,21647)
@@ -85,6 +91,7 @@
 (14913,49873,14849,49836)
 (37013,820,36955,736)
 (39071,1399,39022,1381)
+\N
 (9785,42546,9687,42540)
 (13423,14066,13354,14052)
 (3417,14558,3336,14478)
 (32914,9549,32828,9503)
 (49023,37827,48978,37799)
 (22183,10691,22111,10669)
+\N
 (38036,15828,38014,15759)
 (34604,16801,34508,16746)
 (26737,29997,26675,29976)
 (45005,3842,45001,3816)
 (21672,23566,21603,23566)
 (33360,43465,33302,43429)
+\N
 (29884,9544,29838,9520)
+\N
 (5599,15012,5596,14930)
 (22396,21481,22344,21422)
 (24810,14955,24780,14887)
 (39013,39245,38953,39237)
 (12863,40534,12803,40529)
 (351,37068,310,37019)
+\N
 (12916,34327,12891,34240)
+\N
 (49191,2694,49170,2628)
 (24127,38407,24050,38325)
 (3264,23053,3213,23007)
 (49503,23432,49484,23383)
 (31089,23146,31062,23093)
 (47758,2734,47670,2703)
+\N
 (35276,1027,35259,972)
 (26337,17603,26313,17579)
 (35649,16777,35626,16777)
 (42454,5105,42362,5101)
 (21682,24951,21646,24920)
+\N
 (48383,25174,48303,25156)
 (14672,3532,14601,3460)
 (22570,22587,22515,22512)
 (12479,25042,12447,24991)
 (16568,22916,16499,22864)
 (42700,13084,42676,12992)
+\N
 (35523,40973,35504,40932)
 (32948,16962,32857,16901)
 (7808,13469,7712,13469)
 (13920,35203,13870,35131)
 (22731,31563,22658,31557)
+\N
 (22909,43956,22900,43857)
 (33077,35080,33074,35030)
 (48064,29307,48022,29280)
 (2947,19819,2857,19788)
 (4900,47934,4818,47894)
 (27193,19014,27174,18976)
+\N
 (15597,27948,15590,27939)
 (11090,28623,11002,28589)
 (26956,18651,26920,18620)
 (2412,18357,2383,18354)
 (37060,1443,36974,1366)
 (15501,6230,15429,6190)
+\N
 (30333,50,30273,6)
 (35567,9965,35482,9912)
 (49847,7128,49798,7067)
+\N
 (27685,36396,27668,36384)
 (43832,18491,43825,18431)
 (36849,34600,36785,34589)
 (2348,47938,2307,47902)
+\N
 (20473,22131,20445,22113)
 (38486,4293,38471,4288)
 (30611,30451,30553,30400)
 (17780,43602,17714,43565)
 (45073,3491,45041,3434)
 (35043,2136,35017,2084)
+\N
 (39653,19215,39646,19198)
 (23970,25560,23935,25502)
 (28698,49233,28600,49223)
 (2730,32454,2671,32436)
 (1722,49089,1635,49067)
 (40954,5743,40921,5722)
+\N
 (21382,4426,21298,4331)
 (7885,18629,7872,18605)
 (42838,6459,42748,6451)
 (31911,15168,31906,15113)
 (3454,36839,3438,36831)
 (4832,47554,4820,47473)
+\N
 (11590,8292,11539,8272)
 (8193,33323,8106,33317)
 (16043,14799,16001,14710)
 (19574,11395,19514,11316)
 (26290,41424,26224,41342)
 (22844,12516,22807,12471)
+\N
 (15709,49580,15655,49553)
 (13387,28084,13379,28066)
 (2780,38807,2690,38711)
 (47262,11940,47201,11939)
 (30584,42868,30555,42838)
 (23144,24089,23056,24067)
+\N
 (35930,11609,35847,11573)
 (7812,17271,7789,17203)
 (17946,37554,17878,37480)
 (48976,17733,48962,17731)
 (10686,41470,10597,41434)
 (18053,27059,17989,27012)
+\N
 (35495,25950,35459,25912)
 (41896,45014,41881,44999)
 (22654,41896,22572,41801)
 (18581,7087,18524,6988)
+\N
 (14697,22406,14681,22311)
 (40092,28122,40043,28030)
 (35844,24243,35816,24238)
 (6843,17280,6765,17248)
 (16972,39744,16912,39700)
 (10608,38741,10553,38708)
+\N
 (4917,34801,4828,34766)
 (39281,33659,39268,33618)
 (31706,7119,31645,7063)
 (3427,44006,3422,44004)
+\N
 (10134,42608,10044,42599)
 (26294,32080,26200,32068)
 (21777,34680,21769,34606)
 (34220,27947,34132,27865)
 (35105,39792,35011,39727)
 (21919,27314,21839,27286)
+\N
 (23963,3723,23917,3699)
 (16312,14078,16236,14045)
 (19233,49824,19185,49794)
 (16422,13957,16376,13897)
 (47369,7665,47353,7629)
 (11982,40874,11956,40806)
+\N
 (9552,27580,9496,27562)
 (32247,19399,32176,19337)
 (32704,2169,32635,2091)
 (6326,32360,6267,32317)
 (1711,47519,1654,47430)
 (49540,16510,49521,16426)
+\N
 (26975,618,26908,579)
 (24118,30880,24020,30821)
 (3675,15477,3625,15418)
 (44002,43326,43920,43257)
 (30337,1023,30271,968)
 (34436,23357,34432,23345)
+\N
 (21367,8168,21353,8091)
 (36370,21611,36369,21569)
 (4152,36488,4080,36476)
 (12574,3072,12573,2975)
 (3995,21243,3943,21167)
 (44553,30126,44513,30108)
+\N
 (4599,45275,4552,45254)
 (33191,11404,33176,11348)
+\N
 (14245,18633,14177,18540)
 (32457,20705,32393,20700)
 (40052,10499,40016,10457)
 (29824,44065,29785,44037)
 (31613,12565,31557,12543)
 (42692,29000,42652,28996)
+\N
 (40680,22219,40603,22140)
+\N
 (33575,27661,33488,27644)
 (46194,1385,46184,1355)
 (38442,48501,38407,48426)
 (25305,21544,25236,21523)
 (15562,8226,15561,8208)
+\N
 (20844,43614,20752,43558)
 (22566,30541,22554,30532)
 (2760,47802,2672,47789)
 (25515,30745,25433,30675)
 (48382,45134,48382,45093)
 (9940,27094,9871,27087)
+\N
 (48690,44361,48610,44338)
 (18992,11585,18899,11582)
 (21551,49983,21492,49885)
 (5583,46538,5495,46531)
 (6084,35950,6079,35895)
 (3503,23096,3437,23024)
+\N
 (45275,8420,45244,8418)
 (13514,45251,13491,45249)
 (42112,2748,42047,2668)
+\N
 (7810,21907,7806,21878)
 (48378,36029,48303,35979)
 (32568,48605,32510,48563)
 (859,18915,810,18915)
 (41963,17950,41939,17915)
+\N
 (42723,8031,42685,7955)
+\N
 (19587,5965,19556,5961)
 (8713,33083,8629,32996)
 (21243,7769,21226,7740)
 (1912,23580,1840,23504)
 (38165,16185,38076,16154)
 (6729,1179,6637,1177)
+\N
 (6994,45406,6983,45325)
 (2912,21327,2908,21305)
 (14678,14244,14659,14222)
 (24790,27196,24695,27118)
 (38806,1961,38795,1906)
 (23290,4487,23212,4416)
+\N
 (35035,24337,34990,24297)
 (5549,38948,5549,38891)
 (24558,15492,24501,15425)
 (45803,20406,45710,20371)
 (34730,17672,34658,17606)
 (8809,6323,8798,6232)
+\N
 (39471,23837,39390,23749)
+\N
 (34078,17435,33987,17433)
 (9133,4544,9041,4509)
 (47274,29126,47242,29060)
 (45277,47456,45240,47422)
 (26482,46607,26482,46570)
 (41400,33898,41397,33802)
+\N
 (49853,18504,49848,18503)
 (11528,25165,11476,25080)
 (49902,41752,49818,41746)
 (1956,47506,1922,47424)
 (21834,22058,21802,21964)
+\N
 (19414,21842,19386,21822)
 (34801,13722,34744,13681)
 (13924,29243,13835,29160)
 (16158,27510,16099,27467)
 (41184,6400,41148,6317)
 (1847,42471,1829,42426)
+\N
 (14409,48602,14320,48555)
+\N
 (38137,42951,38045,42918)
 (42875,2312,42832,2243)
 (27242,30617,27181,30535)
 (6575,33949,6484,33900)
 (44812,35980,44800,35913)
 (37577,13064,37495,13019)
+\N
 (30891,29967,30814,29884)
 (15829,28836,15753,28807)
 (11128,34180,11126,34117)
 (31609,49393,31512,49366)
 (26183,32888,26135,32824)
 (46198,26153,46180,26149)
+\N
 (45383,16904,45353,16888)
 (7132,11408,7091,11338)
 (48262,43227,48236,43159)
 (31722,12861,31675,12810)
+\N
 (41695,48924,41691,48921)
 (48318,12877,48287,12802)
 (12069,32241,11978,32231)
 (39497,48412,39413,48318)
 (1058,11132,979,11051)
 (45623,31417,45548,31381)
+\N
 (23887,31921,23876,31891)
 (7797,1244,7785,1155)
 (23679,43650,23594,43644)
 (36101,41895,36085,41810)
 (39617,39211,39544,39191)
 (37437,6604,37434,6585)
+\N
 (7749,32601,7740,32515)
 (26203,34991,26159,34946)
 (31856,39006,31783,39003)
 (45828,24767,45788,24723)
+\N
 (49836,35965,49757,35871)
 (44113,49024,44033,48995)
 (38237,22326,38187,22253)
 (39256,7697,39225,7604)
 (25908,32801,25854,32770)
 (25215,40109,25201,40106)
+\N
 (23280,4613,23190,4596)
 (32440,30879,32405,30807)
 (49156,4224,49126,4126)
 (20978,8226,20930,8170)
 (32127,22611,32126,22579)
 (21764,26509,21701,26455)
+\N
 (32923,2834,32914,2830)
 (7499,25331,7426,25300)
 (6163,36942,6107,36908)
 (24898,40195,24855,40174)
 (43029,982,43004,952)
 (26266,7962,26252,7950)
+\N
 (11308,44367,11210,44322)
 (8902,28402,8808,28334)
 (11671,19619,11665,19549)
 (10043,12479,10009,12391)
 (27584,2345,27578,2257)
 (30889,8253,30866,8167)
+\N
 (5176,48928,5107,48838)
 (9781,21023,9745,20976)
 (32430,27908,32404,27859)
 (42375,33603,42350,33539)
 (3184,8308,3129,8238)
 (26667,15813,26661,15785)
+\N
 (5760,49617,5730,49546)
 (794,27001,777,26992)
 (13518,45289,13459,45235)
+\N
 (34430,29754,34363,29736)
 (37912,24574,37880,24543)
 (8130,2270,8083,2258)
+\N
 (26930,21516,26848,21455)
 (3634,33511,3592,33489)
 (33080,5036,33035,4972)
 (48389,13942,48316,13915)
 (9231,5298,9150,5232)
 (1357,10601,1321,10548)
+\N
 (35175,15295,35091,15269)
 (33917,36863,33879,36784)
 (8279,12052,8239,12021)
 (40782,11648,40763,11631)
 (18516,10143,18423,10137)
 (39068,551,39005,491)
+\N
 (39672,12000,39575,11913)
 (18508,37761,18464,37712)
 (19083,35318,19079,35280)
 (22126,27444,22062,27366)
 (15105,8717,15078,8660)
 (43987,33145,43940,33083)
+\N
 (46833,38652,46755,38612)
 (47768,27202,47681,27169)
 (22792,1183,22731,1152)
 (25650,43310,25562,43247)
 (37084,20116,37045,20057)
 (47461,32556,47423,32555)
+\N
 (41225,18124,41215,18117)
 (17623,25218,17553,25158)
 (13770,21703,13770,21700)
 (45118,22318,45049,22224)
 (42287,26616,42281,26560)
 (25525,6327,25468,6244)
+\N
 (40756,31634,40713,31568)
 (23105,26565,23078,26565)
 (48268,39862,48265,39827)
 (22301,46291,22291,46274)
 (34142,14181,34078,14158)
 (11258,29748,11198,29742)
+\N
 (37450,6943,37398,6882)
 (41675,27207,41643,27130)
 (13578,49562,13573,49479)
 (45738,35524,45706,35496)
 (21575,5151,21493,5092)
 (2194,10052,2172,9960)
+\N
 (47735,24472,47682,24460)
 (46740,35700,46695,35609)
 (24647,42807,24568,42779)
 (38576,35408,38539,35392)
 (16776,46244,16700,46176)
 (38251,25969,38168,25948)
+\N
 (3512,32256,3417,32242)
 (31923,31225,31832,31197)
 (5144,4969,5124,4937)
 (34499,46164,34430,46162)
+\N
 (39432,31907,39388,31828)
 (17316,24606,17221,24533)
 (20751,49352,20709,49323)
 (21929,30617,21894,30598)
 (35539,12421,35536,12355)
 (24938,45583,24870,45525)
+\N
 (27442,33090,27353,33064)
 (23949,12046,23949,12036)
 (11399,377,11360,294)
 (47099,9989,47023,9942)
 (641,33118,639,33084)
 (13687,41308,13682,41290)
+\N
 (3682,17727,3645,17660)
 (13262,19396,13185,19357)
 (18791,389,18774,366)
 (12489,45384,12403,45369)
+\N
 (12065,6364,12015,6325)
+\N
 (32705,23886,32619,23827)
+\N
 (7004,37333,6911,37240)
 (28594,38078,28530,38050)
 (5805,21797,5710,21701)
 (5387,39087,5326,38994)
 (11703,14003,11671,13912)
 (4093,10472,4091,10470)
+\N
 (14110,49740,14063,49695)
 (4170,470,4097,463)
 (22219,17296,22164,17221)
 (2505,20879,2446,20842)
+\N
 (47235,24744,47151,24667)
 (30035,23234,30013,23197)
 (3489,11659,3461,11607)
 (1785,28248,1771,28219)
 (21553,36307,21505,36257)
 (7552,18199,7527,18119)
+\N
 (14410,30977,14349,30944)
+\N
 (20940,49142,20901,49069)
 (36892,5522,36810,5478)
 (40192,20926,40179,20926)
 (39859,932,39829,840)
 (33995,10888,33902,10793)
 (32972,22342,32951,22340)
+\N
 (19951,10161,19932,10111)
 (26779,45188,26745,45151)
 (11235,13593,11184,13589)
 (9326,14927,9295,14848)
 (41340,11312,41311,11303)
 (6500,44553,6454,44515)
+\N
 (8198,26841,8104,26749)
 (47761,34183,47702,34140)
 (43637,17912,43577,17910)
 (22684,266,22656,181)
 (13299,17075,13241,17074)
 (6924,30196,6851,30113)
+\N
 (4367,13150,4298,13053)
 (37381,6101,37380,6046)
 (10307,28383,10270,28349)
 (38924,41305,38872,41285)
 (49981,34876,49898,34786)
 (30501,35099,30418,35011)
+\N
 (45862,41438,45854,41434)
 (38448,31878,38391,31822)
 (8278,43463,8274,43378)
 (49501,40346,49447,40275)
 (31651,43116,31560,43106)
 (44244,32940,44244,32926)
+\N
 (17941,18079,17938,18035)
 (9518,32524,9470,32511)
 (30707,43469,30686,43457)
 (26194,47446,26194,47407)
 (30386,24675,30333,24652)
 (42707,44466,42688,44456)
+\N
 (43395,18525,43320,18467)
 (28346,32259,28276,32196)
 (45106,40786,45026,40767)
 (32511,24029,32482,23970)
 (22593,34444,22519,34399)
 (41534,15495,41518,15455)
+\N
 (35862,19997,35818,19928)
 (31419,8323,31404,8285)
 (31036,19023,30978,19000)
 (44492,45607,44483,45532)
 (22699,4301,22628,4240)
 (27407,24241,27335,24158)
+\N
 (38424,34460,38403,34458)
 (46572,48456,46554,48402)
 (39676,29056,39643,28981)
 (35060,28561,34965,28553)
 (23970,47522,23887,47428)
 (46803,19155,46790,19131)
+\N
 (46151,49848,46058,49830)
 (45266,40766,45209,40738)
 (31041,32195,31007,32110)
 (27907,2695,27830,2596)
 (16309,44972,16222,44966)
 (6230,22262,6214,22249)
+\N
 (9266,39458,9175,39447)
 (33120,33548,33087,33538)
 (43659,11416,43599,11375)
 (34913,7234,34894,7220)
 (15758,26445,15738,26421)
 (23710,7272,23705,7270)
+\N
 (33679,13468,33628,13415)
+\N
 (31271,40495,31178,40461)
 (759,187,662,163)
 (14419,40434,14402,40381)
 (30333,5952,30331,5886)
 (444,12587,430,12497)
 (7592,22353,7541,22287)
+\N
 (13387,37414,13329,37318)
+\N
 (21504,35227,21449,35210)
 (18533,12909,18438,12848)
 (41049,27148,41048,27088)
 (14854,5819,14785,5798)
 (19142,44414,19085,44406)
 (31179,27081,31145,27005)
+\N
 (19692,8711,19659,8642)
 (39689,14082,39603,14051)
 (11181,39091,11119,39002)
 (49820,7990,49771,7967)
 (26424,29698,26339,29693)
 (35146,6820,35071,6817)
+\N
 (15438,18788,15435,18729)
 (47115,5235,47096,5143)
 (33982,9002,33915,8925)
 (14206,37041,14174,36955)
 (24300,36616,24232,36613)
 (44658,1788,44580,1769)
+\N
 (31539,43550,31463,43464)
+\N
 (16722,9673,16633,9652)
 (44813,20573,44733,20544)
+\N
 (42114,32559,42040,32552)
 (41561,36244,41477,36241)
 (39589,33796,39548,33716)
 (20365,26770,20329,26709)
 (28511,208,28479,114)
 (10010,25524,9930,25508)
+\N
 (1549,45666,1512,45621)
 (16193,1927,16166,1869)
 (34486,11500,34421,11401)
 (48720,40687,48623,40610)
 (21161,30970,21146,30896)
 (9507,36316,9411,36261)
+\N
 (36643,18136,36614,18106)
 (1858,7457,1851,7402)
 (24452,44306,24372,44252)
+\N
 (3292,807,3205,806)
 (6845,30694,6792,30627)
 (21333,25786,21237,25751)
 (1746,40342,1736,40333)
 (49187,29737,49139,29681)
 (27657,44952,27581,44917)
+\N
 (35407,30177,35345,30151)
 (4071,40568,4058,40544)
 (25998,30513,25965,30452)
 (8195,45403,8097,45310)
 (8276,41689,8183,41670)
+\N
 (48435,28550,48355,28455)
+\N
 (8139,25449,8136,25380)
 (20302,25574,20297,25531)
+\N
 (22055,46659,22034,46567)
 (3531,49962,3463,49934)
 (46828,46938,46739,46902)
 (30078,48975,30021,48970)
 (2847,32036,2819,31966)
 (25250,10147,25165,10140)
+\N
 (15643,38953,15585,38947)
 (40792,29798,40731,29731)
 (43249,26858,43215,26835)
 (27119,25969,27094,25884)
 (36155,11420,36120,11405)
 (41880,47111,41808,47049)
+\N
 (17554,20379,17482,20374)
 (38848,5936,38763,5869)
 (28324,31019,28276,30944)
 (21237,31901,21188,31849)
 (23340,38537,23253,38472)
 (17269,3682,17183,3586)
+\N
 (48200,15377,48110,15369)
 (16546,22195,16477,22142)
 (21436,8460,21378,8449)
+\N
 (46598,17235,46577,17138)
+\N
 (30212,36184,30152,36092)
 (18037,155,17941,109)
 (4945,29201,4933,29184)
 (1801,15549,1710,15461)
 (48988,34819,48951,34764)
 (20904,32547,20856,32497)
+\N
 (32654,35183,32606,35144)
 (14336,11763,14328,11712)
 (30546,23808,30463,23773)
 (6813,21006,6781,20924)
+\N
 (14199,22030,14185,21934)
 (3783,14709,3747,14658)
 (49428,47052,49422,46973)
 (29170,37260,29151,37181)
 (48924,24689,48894,24680)
 (48497,34052,48453,33966)
+\N
 (21263,8203,21242,8176)
 (46537,3797,46462,3735)
 (18406,14579,18393,14563)
+\N
 (11583,16529,11536,16471)
 (10564,46257,10478,46228)
 (49769,34513,49761,34458)
+\N
 (9202,6482,9138,6391)
 (40387,37411,40357,37360)
 (11966,11802,11888,11751)
 (15551,47438,15486,47406)
 (12017,43288,11969,43230)
 (9717,22574,9701,22495)
+\N
 (35083,49443,35075,49355)
 (33857,9320,33813,9269)
 (32106,10581,32012,10560)
 (35399,40707,35359,40646)
 (29585,25576,29493,25556)
 (24919,7829,24911,7753)
+\N
 (17049,48390,17022,48304)
 (25224,35012,25217,34922)
 (47397,20853,47346,20779)
 (17505,36822,17418,36763)
 (36686,33534,36641,33476)
 (11347,9454,11289,9436)
+\N
 (27816,34752,27745,34736)
 (44213,8559,44162,8461)
 (45359,26789,45315,26776)
 (9606,45253,9582,45174)
 (30005,24521,29910,24496)
 (49332,35375,49309,35299)
+\N
 (12164,33871,12075,33820)
 (19598,43327,19593,43314)
+\N
 (3818,28584,3815,28504)
+\N
 (35579,8611,35541,8604)
 (8811,20986,8750,20954)
 (16139,44777,16128,44686)
 (7030,40790,7029,40711)
 (11676,23009,11665,22915)
 (33990,22561,33953,22474)
+\N
 (30366,9447,30284,9353)
 (37626,32913,37596,32853)
 (7730,42561,7665,42470)
 (25562,9849,25535,9802)
 (13348,46719,13260,46689)
 (30022,42196,30005,42160)
+\N
 (22263,45954,22243,45950)
 (18918,18890,18820,18795)
 (31918,12003,31852,11989)
 (33930,21090,33918,21009)
 (10444,2606,10407,2553)
 (28700,29782,28665,29703)
+\N
 (1402,13497,1397,13465)
+\N
 (24155,3075,24083,3062)
 (38378,1864,38339,1849)
 (29261,49910,29247,49818)
 (38139,37073,38098,37057)
+\N
 (24468,41130,24418,41053)
 (9989,1015,9959,939)
 (47001,33561,46994,33518)
 (42423,26477,42349,26434)
 (10039,920,9952,833)
 (16851,21338,16846,21314)
+\N
 (23104,7700,23062,7688)
 (5619,2079,5611,2075)
 (31471,49632,31375,49549)
 (25793,12526,25783,12456)
 (3935,29528,3866,29513)
+\N
 (5957,1646,5947,1595)
 (2467,22376,2429,22349)
 (43715,32673,43664,32595)
 (49061,14516,49008,14442)
 (43996,6129,43955,6074)
 (7728,33802,7670,33703)
+\N
 (6131,36766,6053,36749)
 (35791,16361,35696,16329)
 (45759,8935,45675,8886)
 (12975,3706,12913,3637)
 (30925,21660,30826,21649)
 (1455,14229,1410,14156)
+\N
 (17583,16486,17562,16474)
 (33377,3387,33333,3381)
 (784,6177,750,6095)
 (14257,11549,14242,11522)
 (14990,15217,14904,15211)
 (21395,21533,21307,21520)
+\N
 (31948,33725,31885,33694)
 (433,49033,390,48961)
 (45205,609,45173,523)
 (24913,13361,24868,13268)
 (13824,40177,13792,40130)
 (25671,13555,25585,13494)
+\N
 (20133,37769,20105,37679)
+\N
 (26368,16734,26288,16726)
 (30545,35438,30458,35376)
 (48816,22926,48812,22831)
 (11003,10859,10950,10765)
 (17288,8570,17247,8485)
 (38377,31415,38331,31379)
+\N
 (19085,23425,19059,23326)
 (40059,17068,40052,17006)
 (18811,13493,18734,13394)
 (12104,33531,12014,33501)
 (22311,41113,22215,41066)
 (25073,18721,25047,18656)
+\N
 (14524,13486,14510,13390)
 (40040,36688,40000,36599)
 (21594,11473,21563,11436)
 (28239,41377,28222,41308)
 (26404,11922,26317,11843)
 (41660,34586,41585,34501)
+\N
 (21128,2384,21101,2368)
 (30209,16952,30156,16858)
 (39078,24963,39045,24898)
 (5598,1348,5499,1294)
+\N
 (38474,7436,38450,7364)
 (15117,45734,15024,45693)
+\N
 (23909,39853,23888,39780)
 (24292,30183,24282,30148)
 (48871,17661,48868,17637)
 (918,18752,847,18708)
+\N
 (43615,16162,43606,16104)
 (33763,47410,33751,47409)
 (4798,6485,4773,6388)
+\N
 (18524,41539,18433,41518)
 (47745,42449,47651,42364)
 (38936,21237,38864,21204)
+\N
 (5251,3516,5194,3475)
 (22269,36269,22183,36228)
 (18736,40983,18685,40947)
 (7045,18782,7028,18764)
 (41840,32018,41768,31938)
 (38416,17158,38330,17060)
+\N
 (8605,39015,8605,38933)
 (5764,43548,5719,43496)
+\N
 (20789,29902,20696,29843)
+\N
 (36104,47896,36079,47816)
 (31736,13834,31722,13832)
 (32617,19701,32597,19684)
 (35450,9580,35368,9563)
 (29281,37276,29247,37255)
 (6225,17192,6200,17135)
+\N
 (43689,8119,43670,8028)
 (41917,49601,41835,49563)
 (44295,13116,44205,13078)
 (22721,44772,22667,44748)
 (32640,11107,32636,11050)
 (20639,28851,20613,28839)
+\N
 (32479,10159,32446,10061)
 (27251,16978,27196,16959)
 (41401,33148,41339,33074)
+\N
 (49001,8538,48989,8444)
 (37958,35843,37874,35802)
 (46969,41229,46903,41138)
 (42688,11681,42666,11641)
 (47525,25005,47443,24907)
 (32439,14438,32397,14400)
+\N
 (39667,19626,39622,19542)
 (1212,44525,1169,44516)
 (29766,4433,29668,4401)
 (33859,17356,33827,17263)
 (28989,45953,28904,45854)
 (37211,30830,37113,30819)
+\N
 (45220,26382,45219,26340)
 (12312,43250,12234,43246)
 (37775,41504,37762,41421)
 (12019,4907,12015,4818)
 (38258,17973,38229,17923)
 (40575,29566,40477,29521)
+\N
 (29715,45919,29697,45891)
 (11694,9510,11670,9490)
 (7053,44257,7012,44231)
 (1023,23378,933,23317)
 (30051,46118,29966,46039)
 (43499,46488,43496,46409)
+\N
 (43531,2412,43447,2396)
+\N
 (16034,32285,15976,32220)
 (12817,21365,12740,21298)
 (7607,47293,7585,47293)
 (1848,21496,1839,21439)
 (17567,23073,17478,23046)
 (35813,31847,35807,31792)
+\N
 (563,30859,540,30842)
 (13145,15488,13063,15433)
 (36754,37479,36731,37411)
 (47678,41396,47668,41365)
 (6837,25974,6799,25892)
 (13355,11174,13304,11161)
+\N
 (37243,25548,37158,25471)
 (12528,30208,12441,30205)
 (14929,1672,14886,1607)
 (33072,20995,32980,20903)
 (47091,30055,47080,30037)
 (45753,12998,45686,12992)
+\N
 (11528,7826,11509,7794)
 (21104,13921,21060,13836)
 (16768,15491,16747,15470)
 (35088,1813,35080,1732)
 (38461,34839,38410,34838)
 (34358,11540,34285,11506)
+\N
 (26969,7078,26953,6989)
 (12629,40352,12617,40264)
 (33800,7037,33731,6992)
 (44343,16339,44248,16318)
 (2374,28839,2336,28798)
 (22913,40710,22819,40688)
+\N
 (47747,684,47658,627)
 (16043,46011,16021,45984)
 (34958,32168,34903,32092)
 (32544,25845,32538,25779)
 (44047,6957,43951,6942)
 (36465,588,36382,503)
+\N
 (28167,26679,28150,26673)
 (16065,4268,15975,4180)
 (12950,23494,12893,23494)
 (18407,28362,18309,28303)
 (21393,41872,21328,41816)
 (46040,26497,45996,26408)
+\N
 (49944,25163,49902,25153)
+\N
 (16195,11843,16159,11831)
 (44257,15270,44254,15214)
 (49760,4791,49699,4713)
 (28584,956,28575,868)
 (5538,9962,5465,9870)
 (34183,44102,34175,44085)
+\N
 (42507,10289,42441,10288)
 (12671,19936,12594,19920)
 (24835,12179,24770,12173)
 (31837,33705,31803,33681)
 (24403,27711,24383,27705)
 (4431,2748,4337,2656)
+\N
 (3036,2887,3014,2826)
 (37664,16118,37615,16022)
 (8606,18063,8587,18038)
 (12207,24266,12173,24235)
 (40643,49770,40574,49687)
 (32833,35686,32815,35674)
+\N
 (14545,18143,14541,18098)
 (33892,42783,33884,42707)
 (33933,8381,33921,8369)
 (13397,19369,13340,19288)
 (30879,43562,30785,43545)
 (21995,48224,21920,48143)
+\N
 (11871,47569,11809,47568)
 (29366,22196,29280,22154)
 (26243,28176,26203,28116)
 (49603,30877,49579,30840)
 (32261,45876,32206,45865)
 (35104,41659,35048,41587)
+\N
 (5457,35844,5376,35782)
 (29423,3977,29354,3959)
 (18059,3001,17965,2961)
 (8509,5691,8463,5620)
+\N
 (27118,5762,27083,5747)
 (2991,48605,2939,48559)
 (44482,3484,44425,3459)
 (45143,16439,45046,16365)
 (2236,37531,2147,37530)
 (41561,3217,41490,3210)
+\N
 (6270,27200,6171,27166)
 (49195,24871,49138,24798)
+\N
 (46985,38881,46897,38845)
 (37486,23522,37404,23441)
 (26907,14490,26900,14391)
 (30829,16111,30756,16056)
 (3644,17291,3587,17262)
 (20508,49775,20472,49680)
+\N
 (43279,8972,43198,8936)
 (33744,7470,33734,7439)
 (46303,20538,46284,20498)
 (8222,8907,8123,8848)
 (45698,28860,45698,28770)
 (26958,1748,26924,1726)
+\N
 (26735,35073,26659,35025)
 (48370,40813,48293,40737)
 (13140,993,13108,934)
 (47886,34532,47851,34500)
 (23777,10549,23735,10495)
 (1291,16913,1194,16873)
+\N
 (29239,30554,29202,30500)
+\N
 (36485,30007,36454,29924)
 (7067,11320,7045,11229)
 (16939,30482,16904,30462)
 (32894,32519,32880,32485)
 (604,13413,509,13401)
 (18396,19712,18355,19646)
+\N
 (26657,28234,26597,28191)
 (24240,47211,24154,47191)
 (41778,10741,41766,10730)
 (13962,39307,13921,39220)
 (11094,19151,11092,19143)
 (32289,23776,32258,23760)
+\N
 (36044,17356,35956,17273)
 (46304,38692,46232,38675)
 (10934,42999,10922,42909)
 (25537,36605,25477,36584)
 (22161,14999,22079,14962)
 (5127,31243,5074,31213)
+\N
 (14904,40664,14838,40593)
 (29308,8480,29268,8438)
 (17731,7410,17699,7352)
 (3530,23456,3440,23390)
 (4699,6889,4603,6796)
 (47405,48524,47389,48514)
+\N
 (23357,43160,23305,43156)
 (16923,1995,16860,1937)
 (47592,33853,47537,33758)
 (13950,28652,13932,28566)
 (38996,41070,38919,40993)
 (31759,45246,31676,45215)
+\N
 (5424,34145,5382,34106)
 (14727,45600,14699,45547)
+\N
 (31429,21537,31414,21499)
 (14740,3420,14650,3323)
 (21793,39498,21743,39471)
 (45403,42533,45389,42464)
 (46531,36947,46531,36850)
 (36943,32817,36865,32737)
+\N
 (37984,43763,37888,43748)
 (20593,10650,20557,10610)
 (5387,40595,5326,40585)
 (15606,9048,15596,9028)
 (14687,19309,14637,19263)
 (4568,15461,4499,15428)
+\N
 (43938,7429,43923,7391)
+\N
 (2168,50012,2108,49914)
 (16022,8934,15963,8928)
 (24567,39147,24561,39102)
+\N
 (42781,14149,42765,14088)
 (39501,21084,39468,21078)
 (6697,29628,6693,29584)
 (11441,16164,11364,16125)
 (39946,1920,39868,1844)
+\N
 (18138,45512,18111,45438)
+\N
 (20799,41217,20718,41138)
 (30264,16697,30240,16639)
+\N
 (30746,50040,30727,49992)
 (37429,43273,37423,43205)
 (22854,28863,22789,28810)
 (318,31489,235,31404)
 (1140,7007,1113,6945)
 (36574,9291,36484,9275)
+\N
 (40320,40937,40246,40866)
 (588,25849,552,25801)
 (6728,42539,6645,42507)
 (45344,21540,45297,21496)
 (27269,16787,27246,16763)
 (18070,4469,18022,4423)
+\N
 (12668,16367,12645,16295)
 (13823,17276,13730,17251)
 (20555,45544,20511,45498)
 (27662,17407,27570,17313)
 (9845,29346,9807,29321)
 (43855,38669,43790,38599)
+\N
 (20461,44189,20397,44158)
 (11627,17368,11581,17289)
 (2971,38855,2938,38807)
 (12958,30737,12912,30712)
 (44432,46521,44333,46443)
 (16124,2948,16113,2852)
+\N
 (24704,25422,24635,25340)
 (30833,46152,30790,46122)
 (4487,37006,4473,36968)
 (6079,17258,6068,17195)
 (40458,15752,40364,15728)
 (23340,7879,23313,7806)
+\N
 (31819,15096,31762,15059)
 (31159,40864,31158,40780)
 (26975,32144,26915,32113)
 (24338,19293,24291,19277)
 (27566,17576,27544,17545)
 (23041,38384,22970,38320)
+\N
 (12786,8485,12702,8435)
 (13876,49473,13813,49448)
 (31585,46998,31490,46929)
+\N
 (30227,8768,30206,8715)
 (32062,39306,32023,39292)
 (25003,35753,24921,35687)
 (3281,6758,3232,6704)
+\N
 (11395,30299,11376,30220)
 (5088,15275,5007,15203)
 (31100,39538,31003,39444)
 (21554,3507,21528,3476)
 (9350,32326,9273,32275)
 (16455,8874,16420,8793)
+\N
 (7346,34235,7330,34224)
 (16417,48134,16352,48066)
+\N
 (41916,4971,41849,4886)
 (15856,1522,15807,1521)
 (41549,40218,41494,40144)
+\N
 (9978,16226,9972,16181)
 (14856,13312,14808,13283)
 (38490,41641,38428,41583)
 (25828,7438,25807,7378)
 (21876,30633,21796,30587)
 (1908,14279,1825,14247)
+\N
 (32207,10251,32121,10184)
 (370,9493,328,9441)
 (42072,17634,41974,17600)
+\N
 (47298,9910,47235,9846)
 (17856,11266,17782,11225)
 (35009,21400,34956,21396)
 (18337,11145,18335,11133)
+\N
 (25425,9139,25381,9085)
 (35642,27783,35621,27782)
 (3629,33164,3575,33163)
 (7119,48224,7117,48152)
 (15233,26480,15138,26430)
 (37468,1526,37466,1513)
+\N
 (20855,2786,20828,2711)
 (30538,44084,30480,44061)
 (42231,41527,42149,41454)
 (26590,19483,26503,19442)
 (21741,46259,21723,46226)
 (8822,34700,8760,34693)
+\N
 (2710,33521,2675,33505)
 (26067,19998,26026,19989)
 (12244,34509,12202,34489)
+\N
 (47162,598,47119,499)
 (33093,49382,33068,49359)
 (35170,26340,35153,26264)
 (22552,35785,22490,35735)
 (36791,23032,36781,22976)
 (22857,10857,22833,10797)
+\N
 (47207,37405,47138,37365)
 (21867,2836,21854,2811)
 (3387,31487,3311,31456)
 (47568,27149,47521,27088)
 (24695,12827,24661,12796)
 (26259,14077,26168,14019)
+\N
 (48478,36135,48425,36092)
 (5230,39250,5206,39174)
 (3488,18562,3423,18489)
 (39502,16331,39460,16275)
 (18296,1478,18233,1471)
+\N
 (28627,12430,28559,12410)
 (25257,21981,25206,21954)
+\N
 (2410,41192,2325,41142)
 (43681,9631,43587,9538)
+\N
 (15086,45309,15064,45270)
 (13824,40807,13759,40787)
 (7090,2207,7062,2159)
 (10815,35985,10734,35908)
 (44891,24067,44794,23979)
 (48626,1900,48595,1850)
+\N
 (40659,35541,40659,35489)
 (22231,26628,22210,26579)
 (37408,23016,37375,22919)
 (5920,15916,5906,15895)
+\N
 (33125,9952,33037,9880)
 (12142,29705,12141,29670)
 (3672,20995,3649,20899)
 (39147,31967,39101,31907)
+\N
 (33812,48458,33748,48399)
 (25038,14639,24978,14586)
 (3859,16010,3857,15994)
 (26866,42395,26822,42332)
 (48195,1784,48101,1734)
 (46201,14109,46112,14097)
+\N
 (2415,9975,2354,9914)
 (30485,9581,30415,9558)
 (6385,36838,6305,36838)
 (34244,32352,34204,32342)
 (35595,23728,35533,23672)
 (1122,13581,1119,13538)
+\N
 (388,21716,296,21678)
 (48782,11064,48701,11005)
 (40293,12997,40213,12927)
+\N
 (28194,46428,28113,46414)
 (4791,18118,4708,18105)
 (471,29808,448,29775)
 (36406,26879,36374,26872)
 (16821,48925,16758,48914)
 (23692,48163,23595,48160)
+\N
 (4803,10619,4759,10522)
 (46600,33581,46553,33518)
 (41349,11767,41310,11710)
 (47282,34302,47277,34269)
 (35603,33558,35557,33495)
 (44764,32189,44700,32175)
+\N
 (46488,23965,46449,23868)
 (46314,15047,46216,15013)
 (6348,25381,6286,25363)
 (8772,45981,8692,45973)
 (11028,1351,10986,1278)
 (26684,21668,26641,21656)
+\N
 (37262,26005,37260,25947)
 (14899,44069,14814,44066)
+\N
 (39635,18701,39587,18698)
 (28528,22948,28457,22857)
 (7755,36528,7681,36454)
 (32461,1172,32427,1106)
+\N
 (18775,27359,18736,27329)
 (15379,20031,15337,19934)
 (45888,33592,45881,33544)
 (44013,24694,43962,24645)
+\N
 (43347,10699,43343,10699)
 (49999,27218,49908,27176)
 (13698,17326,13630,17317)
 (18935,26757,18865,26682)
 (42659,48284,42562,48244)
 (30185,23350,30146,23291)
+\N
 (16496,11970,16441,11919)
 (162,26040,120,25963)
 (24238,47784,24185,47746)
 (26141,13423,26051,13407)
 (40132,22815,40089,22812)
 (21151,48794,21056,48740)
+\N
 (22044,28358,22031,28334)
 (6680,14746,6605,14669)
 (40686,25139,40632,25070)
 (36316,27787,36218,27728)
 (554,35489,540,35441)
 (536,30674,534,30609)
+\N
 (25385,38468,25295,38416)
 (19467,47386,19437,47317)
 (22425,38591,22387,38536)
 (40115,47315,40109,47235)
 (25002,2107,24963,2104)
 (3901,9790,3898,9706)
+\N
 (40316,1721,40315,1658)
 (40089,3454,40074,3443)
 (793,17897,761,17897)
 (6490,43552,6434,43522)
 (10825,487,10820,405)
 (47703,36067,47641,36011)
+\N
 (4480,11671,4468,11653)
 (37713,10642,37711,10615)
 (12315,5302,12273,5203)
+\N
 (8709,6617,8647,6557)
 (24467,30535,24455,30494)
 (40440,32757,40369,32668)
 (24951,47758,24900,47679)
 (32917,35771,32847,35753)
 (5428,27773,5343,27769)
+\N
 (19650,142,19630,51)
 (39769,17276,39743,17229)
 (5171,24562,5119,24470)
 (32976,35249,32917,35199)
+\N
 (4174,24603,4099,24504)
 (38565,36960,38535,36926)
 (39084,4328,39031,4301)
 (22290,7841,22283,7810)
 (22414,38398,22404,38319)
 (9011,18177,8932,18150)
+\N
 (154,4019,138,3990)
 (20447,4998,20383,4970)
 (38867,35757,38795,35659)
 (32322,15845,32227,15804)
+\N
 (29889,12142,29852,12055)
 (36235,36918,36217,36897)
 (41620,6581,41568,6581)
 (48505,4407,48408,4373)
 (21859,37217,21763,37217)
 (39393,14422,39335,14364)
+\N
 (19905,1154,19841,1098)
 (25946,10388,25906,10366)
 (10104,13748,10027,13746)
 (326,18837,285,18817)
 (49611,47078,49533,47052)
 (48233,18850,48150,18842)
+\N
 (29239,9962,29208,9875)
 (40062,44554,39973,44460)
 (19135,20729,19059,20643)
 (31969,40664,31896,40643)
+\N
 (3725,9191,3711,9095)
 (44280,40158,44264,40108)
 (37236,42756,37160,42694)
 (20610,36765,20533,36742)
 (46520,33082,46433,32983)
 (21406,20902,21311,20895)
+\N
 (37913,42300,37814,42269)
 (18216,8177,18161,8173)
 (32967,8258,32899,8244)
 (14978,40230,14971,40149)
 (30343,39152,30266,39101)
 (25917,5835,25843,5806)
+\N
 (5169,45366,5141,45314)
+\N
 (16221,20898,16209,20875)
 (13151,19869,13145,19811)
 (44399,2801,44337,2713)
+\N
 (10959,48311,10957,48230)
 (4794,11711,4732,11661)
 (764,10149,762,10091)
 (7782,13424,7694,13398)
 (25088,36224,25059,36150)
 (46325,48722,46241,48631)
+\N
 (11042,33125,11011,33071)
 (22347,13460,22290,13375)
 (3508,20538,3483,20536)
 (5331,42945,5272,42875)
+\N
 (2368,15537,2339,15503)
 (45314,31830,45254,31817)
 (34358,2649,34319,2589)
+\N
 (17576,30407,17572,30323)
 (29836,41324,29746,41287)
 (21036,39996,21014,39899)
 (37415,15979,37414,15911)
 (47761,16860,47728,16813)
 (35814,48252,35755,48173)
+\N
 (28559,20810,28496,20715)
 (12034,11921,12002,11905)
 (1818,27450,1805,27406)
 (37670,41904,37616,41840)
 (12614,15027,12555,14969)
 (43301,75,43227,43)
+\N
 (27526,15096,27450,15088)
 (26947,33409,26853,33333)
 (1537,43572,1471,43499)
+\N
 (21607,35452,21605,35375)
 (24869,46565,24818,46531)
 (4774,30335,4723,30257)
 (47267,22574,47203,22518)
 (22287,49538,22203,49511)
 (43010,16270,43010,16202)
+\N
 (1623,8350,1578,8254)
 (21220,43808,21137,43748)
 (40397,16471,40358,16434)
+\N
 (34839,1377,34744,1327)
 (17096,5730,17090,5637)
+\N
 (28156,37782,28155,37723)
 (3672,5686,3586,5638)
 (21856,48656,21840,48638)
 (37793,13461,37784,13381)
 (14740,49655,14709,49604)
 (21690,6337,21593,6289)
+\N
 (10423,33548,10364,33498)
+\N
 (39187,23274,39136,23197)
+\N
 (21882,37247,21835,37167)
+\N
 (11343,16957,11281,16914)
 (38279,43400,38264,43352)
 (23167,30271,23086,30224)
 (46278,6037,46180,5964)
 (28626,31165,28605,31095)
+\N
 (31018,367,30946,333)
 (23541,12541,23530,12523)
 (49741,14535,49691,14511)
 (31444,12702,31425,12612)
+\N
 (22406,26536,22316,26534)
 (6807,9761,6758,9723)
 (15698,1941,15687,1848)
 (26872,3646,26804,3594)
 (24575,42883,24530,42883)
 (11823,5755,11771,5721)
+\N
 (2553,46189,2513,46174)
 (24993,14552,24898,14470)
 (28453,1719,28419,1665)
 (47635,15380,47546,15378)
 (35378,18112,35324,18058)
 (27347,22264,27293,22200)
+\N
 (44323,29044,44273,28958)
 (41538,38324,41484,38290)
 (19128,49932,19112,49849)
 (37845,30953,37759,30926)
 (27452,12732,27411,12652)
 (38196,32186,38114,32116)
+\N
 (6527,49356,6508,49315)
 (43891,29789,43856,29723)
 (6146,37192,6085,37107)
+\N
 (42012,28897,41939,28808)
+\N
 (14909,13815,14846,13757)
 (11120,24095,11035,24049)
 (3132,41545,3053,41526)
 (47134,44803,47055,44761)
 (41360,16573,41326,16503)
 (10464,1071,10457,998)
+\N
 (23515,47517,23451,47499)
 (9308,8452,9238,8392)
 (28695,5657,28671,5644)
 (337,455,240,359)
 (11562,45479,11472,45428)
 (11952,18466,11931,18425)
+\N
 (35789,5154,35775,5128)
 (19024,18299,18979,18230)
 (43056,38113,42975,38067)
 (28906,48630,28818,48568)
 (28886,38905,28861,38832)
 (34786,22285,34740,22240)
+\N
 (46513,46780,46425,46780)
+\N
 (26626,31759,26551,31677)
 (19792,25967,19763,25933)
 (20432,14394,20388,14365)
 (19181,8120,19089,8098)
 (24376,19983,24294,19925)
 (18297,18375,18202,18292)
+\N
 (31608,6215,31575,6168)
 (12788,49510,12784,49468)
 (46071,13013,46035,12991)
 (27647,8218,27582,8201)
 (49580,11076,49537,11050)
+\N
 (35501,33782,35501,33687)
 (19969,3148,19964,3082)
 (37728,49153,37726,49152)
 (38907,43619,38827,43553)
 (29149,20773,29070,20698)
 (17006,1543,16970,1497)
+\N
 (11737,18808,11714,18788)
 (13019,30534,13005,30481)
 (39224,31729,39191,31683)
 (4942,41680,4907,41596)
 (12287,37187,12188,37172)
 (30758,29579,30725,29531)
+\N
 (16604,17963,16581,17912)
 (19459,15888,19409,15812)
 (34696,24783,34600,24725)
 (32914,15360,32879,15290)
 (47825,21097,47747,21030)
 (10788,5131,10746,5086)
+\N
 (15497,9698,15481,9678)
 (10617,47195,10601,47117)
 (42392,10583,42340,10550)
 (44880,34228,44877,34169)
 (29146,49694,29143,49682)
 (28502,34886,28471,34832)
+\N
 (30662,5584,30604,5528)
 (12612,26081,12552,26001)
 (17166,49308,17098,49270)
 (49308,23780,49297,23760)
 (8667,32342,8592,32294)
 (37826,48560,37822,48485)
+\N
 (24493,18653,24486,18616)
 (17914,3850,17887,3775)
 (34270,43873,34231,43826)
 (44328,36364,44265,36350)
 (10146,3030,10111,2975)
 (35273,40106,35269,40062)
+\N
 (38566,43846,38547,43760)
 (12400,41394,12377,41378)
 (45196,38286,45153,38250)
 (14585,26111,14490,26035)
 (28743,49392,28664,49349)
 (26652,23359,26618,23297)
+\N
 (40129,33653,40102,33584)
 (41074,26393,41038,26389)
 (3869,33564,3869,33536)
 (13661,38184,13566,38154)
 (2389,40026,2317,39938)
 (35481,46379,35481,46320)
+\N
 (26917,45698,26864,45689)
 (23933,41617,23909,41539)
 (8912,8471,8862,8401)
 (9625,4747,9558,4692)
 (34743,35056,34721,34969)
 (39544,21762,39475,21717)
+\N
 (11741,26330,11656,26293)
 (39015,1315,38966,1285)
 (13418,44237,13326,44202)
 (17300,24847,17276,24825)
 (8823,8253,8793,8238)
 (3449,171,3354,108)
+\N
 (21650,23955,21605,23883)
 (13260,3234,13193,3214)
 (25361,10896,25305,10806)
 (25051,25042,25011,25001)
 (25044,25088,25015,25005)
+\N
 (25007,25061,25002,25013)
 (25066,25105,25003,25007)
 (25028,25012,25015,25011)
 (25015,25042,25004,25012)
 (25091,25049,25019,25019)
 (25023,25011,25000,25004)
+\N
 (25053,25104,25010,25012)
 (25058,25001,25018,25000)
 (25059,25051,25008,25016)
 (25054,25052,25019,25013)
 (25108,25077,25009,25018)
 (25007,25023,25003,25002)
+\N
 (25076,25098,25002,25016)
 (25030,25077,25012,25006)
index a7332c86716349891746a9170e2a59202e6eb5e0..1f5b8a06a7194245f40b4359a23711b6634963e8 100644 (file)
@@ -54,7 +54,28 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
 -- benchmark).
 --
 CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
--- there's no easy way to check that this command actually is using
+SET enable_seqscan = ON;
+SET enable_indexscan = OFF;
+SET enable_bitmapscan = OFF;
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+       home_base       
+-----------------------
+ (337,455),(240,359)
+ (1444,403),(1346,344)
+(2 rows)
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+ count 
+-------
+     2
+(1 row)
+
+SET enable_seqscan = OFF;
+SET enable_indexscan = ON;
+SET enable_bitmapscan = ON;
+-- there's no easy way to check that these commands actually use
 -- the index, unfortunately.  (EXPLAIN would work, but its output
 -- changes too often for me to want to put an EXPLAIN in the test...)
 SELECT * FROM fast_emp4000
@@ -66,6 +87,125 @@ SELECT * FROM fast_emp4000
  (1444,403),(1346,344)
 (2 rows)
 
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+ count 
+-------
+     2
+(1 row)
+
+DROP INDEX rect2ind;
+--
+-- GiST (rtree-equivalent opclasses only)
+--
+CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base);
+CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1);
+CREATE INDEX gcircleind ON circle_tbl USING gist (f1);
+CREATE TEMP TABLE gpolygon_tbl AS
+    SELECT polygon(home_base) AS f1 FROM slow_emp4000;
+CREATE TEMP TABLE gcircle_tbl AS
+    SELECT circle(home_base) AS f1 FROM slow_emp4000;
+CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1);
+CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1);
+SET enable_seqscan = ON;
+SET enable_indexscan = OFF;
+SET enable_bitmapscan = OFF;
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+       home_base       
+-----------------------
+ (337,455),(240,359)
+ (1444,403),(1346,344)
+(2 rows)
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+ count 
+-------
+     2
+(1 row)
+
+SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
+    ORDER BY f1 USING <<;
+         f1          
+---------------------
+ ((2,0),(2,4),(0,0))
+(1 row)
+
+SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
+    ORDER BY f1 USING <<;
+      f1       
+---------------
+ <(1,3),5>
+ <(1,2),100>
+ <(1,2),3>
+ <(100,1),115>
+(4 rows)
+
+SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
+ count 
+-------
+     2
+(1 row)
+
+SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
+ count 
+-------
+     2
+(1 row)
+
+SET enable_seqscan = OFF;
+SET enable_indexscan = ON;
+SET enable_bitmapscan = ON;
+-- there's no easy way to check that these commands actually use
+-- the index, unfortunately.  (EXPLAIN would work, but its output
+-- changes too often for me to want to put an EXPLAIN in the test...)
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+       home_base       
+-----------------------
+ (337,455),(240,359)
+ (1444,403),(1346,344)
+(2 rows)
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+ count 
+-------
+     2
+(1 row)
+
+SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
+    ORDER BY f1 USING <<;
+         f1          
+---------------------
+ ((2,0),(2,4),(0,0))
+(1 row)
+
+SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
+    ORDER BY f1 USING <<;
+      f1       
+---------------
+ <(1,3),5>
+ <(1,2),100>
+ <(1,2),3>
+ <(100,1),115>
+(4 rows)
+
+SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
+ count 
+-------
+     2
+(1 row)
+
+SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
+ count 
+-------
+     2
+(1 row)
+
+RESET enable_seqscan;
+RESET enable_indexscan;
+RESET enable_bitmapscan;
 --
 -- HASH
 --
index 05bfe054d7a4a35f91241b23157e0ebedb597da7..2904585883f83e910d275e85e08d366bf0f448fd 100644 (file)
@@ -765,9 +765,12 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
 -- Detect missing pg_amop entries: should have as many strategy operators
 -- as AM expects for each opclass for the AM.  When nondefault subtypes are
 -- present, enforce condition separately for each subtype.
+-- We have to exclude GiST, unfortunately, since it hasn't got any fixed
+-- requirements about strategy operators.
 SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
 FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
 WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amname != 'gist' AND
     p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
                         WHERE p4.amopclaid = p2.oid AND
                               p4.amopsubtype = p3.amopsubtype);
@@ -819,7 +822,19 @@ ORDER BY 1, 2, 3;
      403 |            5 | ~>~
      405 |            1 | =
      405 |            1 | ~=~
-(24 rows)
+     783 |            1 | <<
+     783 |            2 | &<
+     783 |            3 | &&
+     783 |            4 | &>
+     783 |            5 | >>
+     783 |            6 | ~=
+     783 |            7 | ~
+     783 |            8 | @
+     783 |            9 | &<|
+     783 |           10 | <<|
+     783 |           11 | |>>
+     783 |           12 | |&>
+(36 rows)
 
 -- Check that all operators linked to by opclass entries have selectivity
 -- estimators.  This is not absolutely required, but it seems a reasonable
index 581146bbd70b48a937e9ac6e13656c45a87351fb..3593bc356bd18adda4b4a881d1c552cbeeca9749 100644 (file)
@@ -14,6 +14,7 @@ SELECT relname, relhasindex
  bt_i4_heap          | t
  bt_name_heap        | t
  bt_txt_heap         | t
+ circle_tbl          | t
  fast_emp4000        | t
  func_index_heap     | t
  hash_f8_heap        | t
@@ -59,11 +60,12 @@ SELECT relname, relhasindex
  pg_tablespace       | t
  pg_trigger          | t
  pg_type             | t
+ polygon_tbl         | t
  road                | t
  shighway            | t
  tenk1               | t
  tenk2               | t
-(53 rows)
+(55 rows)
 
 --
 -- another sanity check: every system catalog that has OIDs should have
index 71c0b0c2b0add1464ae9e5c3a419b3ed9706b785..0e28ac0e1467bff29402db76abb046f2b43a9a92 100644 (file)
@@ -77,13 +77,98 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
 --
 CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
 
--- there's no easy way to check that this command actually is using
+SET enable_seqscan = ON;
+SET enable_indexscan = OFF;
+SET enable_bitmapscan = OFF;
+
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+
+SET enable_seqscan = OFF;
+SET enable_indexscan = ON;
+SET enable_bitmapscan = ON;
+
+-- there's no easy way to check that these commands actually use
+-- the index, unfortunately.  (EXPLAIN would work, but its output
+-- changes too often for me to want to put an EXPLAIN in the test...)
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+
+DROP INDEX rect2ind;
+
+
+--
+-- GiST (rtree-equivalent opclasses only)
+--
+CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base);
+
+CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1);
+
+CREATE INDEX gcircleind ON circle_tbl USING gist (f1);
+
+CREATE TEMP TABLE gpolygon_tbl AS
+    SELECT polygon(home_base) AS f1 FROM slow_emp4000;
+
+CREATE TEMP TABLE gcircle_tbl AS
+    SELECT circle(home_base) AS f1 FROM slow_emp4000;
+
+CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1);
+
+CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1);
+
+SET enable_seqscan = ON;
+SET enable_indexscan = OFF;
+SET enable_bitmapscan = OFF;
+
+SELECT * FROM fast_emp4000
+    WHERE home_base @ '(200,200),(2000,1000)'::box
+    ORDER BY home_base USING <<;
+
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+
+SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
+    ORDER BY f1 USING <<;
+
+SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
+    ORDER BY f1 USING <<;
+
+SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
+
+SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
+
+SET enable_seqscan = OFF;
+SET enable_indexscan = ON;
+SET enable_bitmapscan = ON;
+
+-- there's no easy way to check that these commands actually use
 -- the index, unfortunately.  (EXPLAIN would work, but its output
 -- changes too often for me to want to put an EXPLAIN in the test...)
 SELECT * FROM fast_emp4000
     WHERE home_base @ '(200,200),(2000,1000)'::box
     ORDER BY home_base USING <<;
 
+SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
+
+SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
+    ORDER BY f1 USING <<;
+
+SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
+    ORDER BY f1 USING <<;
+
+SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
+
+SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
+
+RESET enable_seqscan;
+RESET enable_indexscan;
+RESET enable_bitmapscan;
+
 --
 -- HASH
 --
index 3b74c1bbd7b94bad1846e2c0deffb1e671c6ad52..ea5bc5b4366f2cabe0b11e6d0a3480032100ac8d 100644 (file)
@@ -631,10 +631,13 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
 -- Detect missing pg_amop entries: should have as many strategy operators
 -- as AM expects for each opclass for the AM.  When nondefault subtypes are
 -- present, enforce condition separately for each subtype.
+-- We have to exclude GiST, unfortunately, since it hasn't got any fixed
+-- requirements about strategy operators.
 
 SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
 FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
 WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amname != 'gist' AND
     p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
                         WHERE p4.amopclaid = p2.oid AND
                               p4.amopsubtype = p3.amopsubtype);