]> granicus.if.org Git - postgresql/commitdiff
Add point_ops opclass for GiST.
authorTeodor Sigaev <teodor@sigaev.ru>
Thu, 14 Jan 2010 16:31:09 +0000 (16:31 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Thu, 14 Jan 2010 16:31:09 +0000 (16:31 +0000)
16 files changed:
src/backend/access/gist/gistproc.c
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_opfamily.h
src/include/catalog/pg_proc.h
src/include/utils/geo_decls.h
src/test/regress/expected/create_index.out
src/test/regress/expected/opr_sanity.out
src/test/regress/expected/point.out
src/test/regress/expected/sanity_check.out
src/test/regress/sql/create_index.sql
src/test/regress/sql/point.sql

index cf3442763ecaa993b380de257d137933db2f2321..18ee0259a59e0a9f611531cd7c770d06b6ae3d9c 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *     $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.19 2010/01/02 16:57:34 momjian Exp $
+ *     $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.20 2010/01/14 16:31:09 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -165,7 +165,8 @@ gist_box_compress(PG_FUNCTION_ARGS)
 }
 
 /*
- * GiST DeCompress method for boxes (also used for polygons and circles)
+ * GiST DeCompress method for boxes (also used for points, polygons
+ * and circles)
  *
  * do not do anything --- we just use the stored box as is.
  */
@@ -176,7 +177,7 @@ gist_box_decompress(PG_FUNCTION_ARGS)
 }
 
 /*
- * The GiST Penalty method for boxes
+ * The GiST Penalty method for boxes (also used for points)
  *
  * As in the R-tree paper, we use change in area as our penalty metric
  */
@@ -341,6 +342,8 @@ fallbackSplit(GistEntryVector *entryvec, GIST_SPLITVEC *v)
  *
  * New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree',
  * C.H.Ang and T.C.Tan
+ *
+ * This is used for both boxes and points.
  */
 Datum
 gist_box_picksplit(PG_FUNCTION_ARGS)
@@ -533,6 +536,8 @@ gist_box_picksplit(PG_FUNCTION_ARGS)
 
 /*
  * Equality method
+ *
+ * This is used for both boxes and points.
  */
 Datum
 gist_box_same(PG_FUNCTION_ARGS)
@@ -872,3 +877,166 @@ gist_circle_consistent(PG_FUNCTION_ARGS)
 
        PG_RETURN_BOOL(result);
 }
+
+/**************************************************
+ * Point ops
+ **************************************************/
+
+Datum
+gist_point_compress(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+       if (entry->leafkey)                     /* Point, actually */
+       {
+               BOX        *box = palloc(sizeof(BOX));
+               Point  *point = DatumGetPointP(entry->key);
+               GISTENTRY  *retval = palloc(sizeof(GISTENTRY));
+
+               box->high = box->low = *point;
+
+               gistentryinit(*retval, BoxPGetDatum(box),
+                                         entry->rel, entry->page, entry->offset, FALSE);
+
+               PG_RETURN_POINTER(retval);
+       }
+
+       PG_RETURN_POINTER(entry);
+}
+
+static bool
+gist_point_consistent_internal(StrategyNumber strategy,
+                                                                                  bool isLeaf, BOX *key, Point *query)
+{
+       bool result = false;
+
+       switch (strategy)
+       {
+               case RTLeftStrategyNumber:
+                       result = FPlt(key->low.x, query->x);
+                       break;
+               case RTRightStrategyNumber:
+                       result = FPgt(key->high.x, query->x);
+                       break;
+               case RTAboveStrategyNumber:
+                       result = FPgt(key->high.y, query->y);
+                       break;
+               case RTBelowStrategyNumber:
+                       result = FPlt(key->low.y, query->y);
+                       break;
+               case RTSameStrategyNumber:
+                       if (isLeaf)
+                       {
+                               result = FPeq(key->low.x, query->x)
+                                       && FPeq(key->low.y, query->y);
+                       }
+                       else
+                       {
+                               result = (query->x <= key->high.x && query->x >= key->low.x &&
+                                                 query->y <= key->high.y && query->y >= key->low.y);
+                       }
+                       break;
+               default:
+                       elog(ERROR, "unknown strategy number: %d", strategy);
+       }
+
+       return result;
+}
+
+#define GeoStrategyNumberOffset                20
+#define PointStrategyNumberGroup       0
+#define BoxStrategyNumberGroup         1
+#define PolygonStrategyNumberGroup     2
+#define CircleStrategyNumberGroup      3
+
+Datum
+gist_point_consistent(PG_FUNCTION_ARGS)
+{
+       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+       StrategyNumber  strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+       bool            result;
+       bool       *recheck = (bool *) PG_GETARG_POINTER(4);
+       StrategyNumber  strategyGroup = strategy / GeoStrategyNumberOffset;
+
+       switch (strategyGroup)
+       {
+               case PointStrategyNumberGroup:
+                       result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset,
+                                                                                                       GIST_LEAF(entry),
+                                                                                                       DatumGetBoxP(entry->key),
+                                                                                                       PG_GETARG_POINT_P(1));
+                       *recheck = false;
+                       break;
+               case BoxStrategyNumberGroup:
+                       result = DatumGetBool(DirectFunctionCall5(
+                                                                                       gist_box_consistent,
+                                                                                       PointerGetDatum(entry),
+                                                                                       PG_GETARG_DATUM(1),
+                                                                                       Int16GetDatum(RTOverlapStrategyNumber),
+                                                                                       0, PointerGetDatum(recheck)));
+                       break;
+               case PolygonStrategyNumberGroup:
+                       {
+                               POLYGON    *query = PG_GETARG_POLYGON_P(1);
+
+                               result = DatumGetBool(DirectFunctionCall5(
+                                                                                               gist_poly_consistent,
+                                                                                               PointerGetDatum(entry),
+                                                                                               PolygonPGetDatum(query),
+                                                                                               Int16GetDatum(RTOverlapStrategyNumber),
+                                                                                               0, PointerGetDatum(recheck)));
+
+                               if (GIST_LEAF(entry) && result)
+                               {
+                                       /*
+                                        * We are on leaf page and quick check shows overlapping
+                                        * of polygon's bounding box and point
+                                        */
+                                       BOX *box = DatumGetBoxP(entry->key);
+
+                                       Assert(box->high.x == box->low.x
+                                               && box->high.y == box->low.y);
+                                       result = DatumGetBool(DirectFunctionCall2(
+                                                                                               poly_contain_pt,
+                                                                                               PolygonPGetDatum(query),
+                                                                                               PointPGetDatum(&box->high)));
+                                       *recheck = false;
+                               }
+                       }
+                       break;
+               case CircleStrategyNumberGroup:
+                       {
+                               CIRCLE *query = PG_GETARG_CIRCLE_P(1);
+
+                               result = DatumGetBool(DirectFunctionCall5(
+                                                                                               gist_circle_consistent,
+                                                                                               PointerGetDatum(entry),
+                                                                                               CirclePGetDatum(query),
+                                                                                               Int16GetDatum(RTOverlapStrategyNumber),
+                                                                                               0, PointerGetDatum(recheck)));
+
+                               if (GIST_LEAF(entry) && result)
+                               {
+                                       /*
+                                        * We are on leaf page and quick check shows overlapping
+                                        * of polygon's bounding box and point
+                                        */
+                                       BOX *box = DatumGetBoxP(entry->key);
+
+                                       Assert(box->high.x == box->low.x
+                                               && box->high.y == box->low.y);
+                                       result = DatumGetBool(DirectFunctionCall2(
+                                                                                               circle_contain_pt,
+                                                                                               CirclePGetDatum(query),
+                                                                                               PointPGetDatum(&box->high)));
+                                       *recheck = false;
+                               }
+                       }
+                       break;
+               default:
+                       result = false;                 /* silence compiler warning */
+                       elog(ERROR, "unknown strategy number: %d", strategy);
+       }
+
+       PG_RETURN_BOOL(result);
+}
index 2eb724288196f2dcf2d3d4fd20ebb3c0782c3bab..35f1a13ab675ba6b21a354bd04e0a7969e8a4297 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.106 2010/01/02 16:57:54 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.107 2010/01/14 16:31:09 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3202,6 +3202,16 @@ on_pb(PG_FUNCTION_ARGS)
                                   pt->y <= box->high.y && pt->y >= box->low.y);
 }
 
+Datum
+box_contain_pt(PG_FUNCTION_ARGS) 
+{
+       BOX                *box = PG_GETARG_BOX_P(0);
+       Point      *pt = PG_GETARG_POINT_P(1);
+
+       PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x &&
+                                  pt->y <= box->high.y && pt->y >= box->low.y);
+}
+
 /* on_ppath -
  *             Whether a point lies within (on) a polyline.
  *             If open, we have to (groan) check each segment.
index 5217147f363a51c09af698ae6551cff42cd79f6f..e981823320c47627f47c00ec1a7dbcf04010f6c3 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.571 2010/01/12 02:42:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.572 2010/01/14 16:31:09 teodor Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201001111
+#define CATALOG_VERSION_NO     201001141
 
 #endif
index b107c6e4bae85774c97678862a00cd85d135c251..1f0c1d81d6bf8aeb18e443b6285594e1ad9f22b1 100644 (file)
@@ -29,7 +29,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.92 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.93 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *      the genbki.pl script reads this file and generates .bki
@@ -582,6 +582,22 @@ DATA(insert (      2593   603 603 12 2572  783 ));
 DATA(insert (  2593   603 603 13 2863  783 ));
 DATA(insert (  2593   603 603 14 2862  783 ));
 
+/*
+ * gist point_ops
+ */
+DATA(insert (  1029   600 600 11 506 783 ));
+DATA(insert (  1029   600 600 1  507 783 ));
+DATA(insert (  1029   600 600 5  508 783 ));
+DATA(insert (  1029   600 600 10 509 783 ));
+DATA(insert (  1029   600 600 6  510 783 ));
+DATA(insert (  1029   603 600 27  433 783 ));
+DATA(insert (  1029   600 603 28  511 783 ));
+DATA(insert (  1029   604 600 47 757 783 ));
+DATA(insert (  1029   600 604 48 756 783 ));
+DATA(insert (  1029   718 600 67 759 783 ));
+DATA(insert (  1029   600 718 68 758 783 ));
+
+
 /*
  *     gist poly_ops (supports polygons)
  */
index 739f2c4b64e52cf7ed0c72b3ff4a02084c9a12d4..0f0f6e1fe0b5c7e0d42039a5658e11b43ad2f87f 100644 (file)
@@ -22,7 +22,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.77 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.78 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *       the genbki.pl script reads this file and generates .bki
@@ -197,6 +197,13 @@ DATA(insert (      3702   3615 3615 4 3696 ));
 DATA(insert (  3702   3615 3615 5 3700 ));
 DATA(insert (  3702   3615 3615 6 3697 ));
 DATA(insert (  3702   3615 3615 7 3699 ));
+DATA(insert (  1029   600 600 1 2179 ));
+DATA(insert (  1029   600 600 2 2583 ));
+DATA(insert (  1029   600 600 3 1030 ));
+DATA(insert (  1029   600 600 4 2580 ));
+DATA(insert (  1029   600 600 5 2581 ));
+DATA(insert (  1029   600 600 6 2582 ));
+DATA(insert (  1029   600 600 7 2584 ));
 
 
 /* gin */
index e5f19c895a868220d50cbc0e2a132237b73ccc8a..62811213653fd0cf30edee6bfc78c1702c31100c 100644 (file)
@@ -28,7 +28,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.87 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.88 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *       the genbki.pl script reads this file and generates .bki
@@ -170,6 +170,7 @@ DATA(insert (       403             reltime_ops                     PGNSP PGUID 2233  703 t 0 ));
 DATA(insert (  403             tinterval_ops           PGNSP PGUID 2234  704 t 0 ));
 DATA(insert (  405             aclitem_ops                     PGNSP PGUID 2235 1033 t 0 ));
 DATA(insert (  783             box_ops                         PGNSP PGUID 2593  603 t 0 ));
+DATA(insert (  783             point_ops                       PGNSP PGUID 1029  600 t 603 ));
 DATA(insert (  783             poly_ops                        PGNSP PGUID 2594  604 t 603 ));
 DATA(insert (  783             circle_ops                      PGNSP PGUID 2595  718 t 603 ));
 DATA(insert (  2742    _int4_ops                       PGNSP PGUID 2745  1007 t 23 ));
index fd59882006d87349a011b18aca96869541558c18..25429cf1515bc98cb22876535288b5073bb184e7 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.169 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.170 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *       the genbki.pl script reads this file and generates .bki
@@ -171,7 +171,8 @@ DATA(insert OID = 507 (  "<<"          PGNSP PGUID b f f 600 600    16       0       0 point_left p
 DATA(insert OID = 508 (  ">>"     PGNSP PGUID b f f 600 600    16       0       0 point_right positionsel positionjoinsel ));
 DATA(insert OID = 509 (  "<^"     PGNSP PGUID b f f 600 600    16       0       0 point_below positionsel positionjoinsel ));
 DATA(insert OID = 510 (  "~="     PGNSP PGUID b f f 600 600    16 510 713 point_eq eqsel eqjoinsel ));
-DATA(insert OID = 511 (  "<@"     PGNSP PGUID b f f 600 603    16       0       0 on_pb - - ));
+DATA(insert OID = 511 (  "<@"     PGNSP PGUID b f f 600 603    16 433   0 on_pb contsel contjoinsel ));
+DATA(insert OID = 433 (  "@>"     PGNSP PGUID b f f 603 600    16 511   0 box_contain_pt contsel contjoinsel ));
 DATA(insert OID = 512 (  "<@"     PGNSP PGUID b f f 600 602    16 755   0 on_ppath - - ));
 DATA(insert OID = 513 (  "@@"     PGNSP PGUID l f f     0 603 600       0       0 box_center - - ));
 DATA(insert OID = 514 (  "*"      PGNSP PGUID b f f    23      23      23 514   0 int4mul - - ));
@@ -359,10 +360,10 @@ DATA(insert OID = 737 (  "-"         PGNSP PGUID b f f    602  600        602    0  0 path_sub_
 DATA(insert OID = 738 (  "*"      PGNSP PGUID b f f    602  600        602    0  0 path_mul_pt - - ));
 DATA(insert OID = 739 (  "/"      PGNSP PGUID b f f    602  600        602    0  0 path_div_pt - - ));
 DATA(insert OID = 755 (  "@>"     PGNSP PGUID b f f    602  600         16  512  0 path_contain_pt - - ));
-DATA(insert OID = 756 (  "<@"     PGNSP PGUID b f f    600  604         16  757  0 pt_contained_poly - - ));
-DATA(insert OID = 757 (  "@>"     PGNSP PGUID b f f    604  600         16  756  0 poly_contain_pt - - ));
-DATA(insert OID = 758 (  "<@"     PGNSP PGUID b f f    600  718         16  759  0 pt_contained_circle - - ));
-DATA(insert OID = 759 (  "@>"     PGNSP PGUID b f f    718  600         16  758  0 circle_contain_pt - - ));
+DATA(insert OID = 756 (  "<@"     PGNSP PGUID b f f    600  604         16  757  0 pt_contained_poly contsel contjoinsel ));
+DATA(insert OID = 757 (  "@>"     PGNSP PGUID b f f    604  600         16  756  0 poly_contain_pt contsel contjoinsel ));
+DATA(insert OID = 758 (  "<@"     PGNSP PGUID b f f    600  718         16  759  0 pt_contained_circle contsel contjoinsel ));
+DATA(insert OID = 759 (  "@>"     PGNSP PGUID b f f    718  600         16  758  0 circle_contain_pt contsel contjoinsel ));
 
 DATA(insert OID = 773 (  "@"      PGNSP PGUID l f f     0      23      23       0       0 int4abs - - ));
 
index aa93df8eca25d4b9aa686bbc045146e002254d6c..5db9cb6f68b9b40930b26f9594696f5eef973cb3 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.13 2010/01/05 01:06:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.14 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *       the genbki.pl script reads this file and generates .bki
@@ -127,6 +127,7 @@ DATA(insert OID = 2235 (    405             aclitem_ops             PGNSP PGUID ));
 DATA(insert OID = 2593 (       783             box_ops                 PGNSP PGUID ));
 DATA(insert OID = 2594 (       783             poly_ops                PGNSP PGUID ));
 DATA(insert OID = 2595 (       783             circle_ops              PGNSP PGUID ));
+DATA(insert OID = 1029 (       783             point_ops               PGNSP PGUID ));
 DATA(insert OID = 2745 (       2742    array_ops               PGNSP PGUID ));
 DATA(insert OID = 2968 (       403             uuid_ops                PGNSP PGUID ));
 DATA(insert OID = 2969 (       405             uuid_ops                PGNSP PGUID ));
index b39c02f7f288925ee7d620e8cd7e22982ab11063..7a16e3faa73c085c595c23fca5fc575644796796 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.560 2010/01/07 20:17:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.561 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTES
  *       The script catalog/genbki.pl reads this file and generates .bki
@@ -396,6 +396,8 @@ DATA(insert OID = 191 (  box_right             PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "
 DESCR("is right of");
 DATA(insert OID = 192 (  box_contained    PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "603 603" _null_ _null_ _null_ _null_ box_contained _null_ _null_ _null_ ));
 DESCR("is contained by?");
+DATA(insert OID = 193 (  box_contain_pt           PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "603 600" _null_ _null_ _null_ _null_ box_contain_pt _null_ _null_ _null_ ));
+DESCR("contains?");
 
 /* OIDS 200 - 299 */
 
@@ -4205,6 +4207,10 @@ DATA(insert OID = 2591 (  gist_circle_consistent PGNSP PGUID 12 1 0 0 f f f t f
 DESCR("GiST support");
 DATA(insert OID = 2592 (  gist_circle_compress PGNSP PGUID 12 1 0 0 f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_circle_compress _null_ _null_ _null_ ));
 DESCR("GiST support");
+DATA(insert OID = 1030 (  gist_point_compress  PGNSP PGUID 12 1 0 0 f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ gist_point_compress _null_ _null_ _null_ ));
+DESCR("GiST support");
+DATA(insert OID = 2179 (  gist_point_consistent        PGNSP PGUID 12 1 0 0 f f f t f i 5 0 16 "2281 603 23 26 2281" _null_ _null_ _null_ _null_       gist_point_consistent _null_ _null_ _null_ ));
+DESCR("GiST support");
 
 /* GIN */
 DATA(insert OID = 2731 (  gingetbitmap    PGNSP PGUID 12 1 0 0 f f f t f v 2 0 20 "2281 2281" _null_ _null_ _null_ _null_      gingetbitmap _null_ _null_ _null_ ));
index 7863f5e61996861df25b38544cbb6ab01e530528..f43d2d5fdcc4e360243d4ec316a934a57b73bd8b 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.56 2010/01/02 16:58:10 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.57 2010/01/14 16:31:09 teodor Exp $
  *
  * NOTE
  *       These routines do *not* use the float types from adt/.
@@ -290,6 +290,7 @@ extern Datum box_above(PG_FUNCTION_ARGS);
 extern Datum box_overabove(PG_FUNCTION_ARGS);
 extern Datum box_contained(PG_FUNCTION_ARGS);
 extern Datum box_contain(PG_FUNCTION_ARGS);
+extern Datum box_contain_pt(PG_FUNCTION_ARGS);
 extern Datum box_below_eq(PG_FUNCTION_ARGS);
 extern Datum box_above_eq(PG_FUNCTION_ARGS);
 extern Datum box_lt(PG_FUNCTION_ARGS);
@@ -420,6 +421,8 @@ 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);
+extern Datum gist_point_compress(PG_FUNCTION_ARGS);
+extern Datum gist_point_consistent(PG_FUNCTION_ARGS);
 
 /* geo_selfuncs.c */
 extern Datum areasel(PG_FUNCTION_ARGS);
index b67f4e06f39b8068da003c2371401102e1876b56..22753437040c091da871df2328ee3378e009f552 100644 (file)
@@ -51,6 +51,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
 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 INDEX gpointind ON point_tbl USING gist (f1);
 CREATE TEMP TABLE gpolygon_tbl AS
     SELECT polygon(home_base) AS f1 FROM slow_emp4000;
 INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' ); 
@@ -112,6 +113,60 @@ SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
      2
 (1 row)
 
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+ count 
+-------
+     1
+(1 row)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+ count 
+-------
+     2
+(1 row)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+ count 
+-------
+     1
+(1 row)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+ count 
+-------
+     3
+(1 row)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+ count 
+-------
+     1
+(1 row)
+
 SET enable_seqscan = OFF;
 SET enable_indexscan = ON;
 SET enable_bitmapscan = ON;
@@ -245,6 +300,141 @@ SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
      2
 (1 row)
 
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+                     QUERY PLAN                     
+----------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl
+         Index Cond: (f1 <@ '(100,100),(0,0)'::box)
+(3 rows)
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+ count 
+-------
+     3
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+                     QUERY PLAN                     
+----------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl
+         Index Cond: ('(100,100),(0,0)'::box @> f1)
+(3 rows)
+
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+ count 
+-------
+     3
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl
+         Index Cond: (f1 <@ '((0,0),(0,100),(100,100),(50,50),(100,0),(0,0))'::polygon)
+(3 rows)
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+ count 
+-------
+     3
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+                     QUERY PLAN                     
+----------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl
+         Index Cond: (f1 <@ '<(50,50),50>'::circle)
+(3 rows)
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+ count 
+-------
+     1
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+                   QUERY PLAN                    
+-------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl p
+         Index Cond: (f1 << '(0,0)'::point)
+(3 rows)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+ count 
+-------
+     3
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+                   QUERY PLAN                    
+-------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl p
+         Index Cond: (f1 >> '(0,0)'::point)
+(3 rows)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+ count 
+-------
+     2
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+                   QUERY PLAN                    
+-------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl p
+         Index Cond: (f1 <^ '(0,0)'::point)
+(3 rows)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+ count 
+-------
+     1
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+                   QUERY PLAN                    
+-------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl p
+         Index Cond: (f1 >^ '(0,0)'::point)
+(3 rows)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+ count 
+-------
+     3
+(1 row)
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+                   QUERY PLAN                    
+-------------------------------------------------
+ Aggregate
+   ->  Index Scan using gpointind on point_tbl p
+         Index Cond: (f1 ~= '(-5,-12)'::point)
+(3 rows)
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+ count 
+-------
+     1
+(1 row)
+
 RESET enable_seqscan;
 RESET enable_indexscan;
 RESET enable_bitmapscan;
index 24a2e8a8e63a7be6254e9551465bffb011d821b7..5e36d481dfbd0bf68948a49278b1ccd5119b3e58 100644 (file)
@@ -902,17 +902,25 @@ ORDER BY 1, 2, 3;
         783 |            8 | <@
         783 |            9 | &<|
         783 |           10 | <<|
+        783 |           10 | <^
+        783 |           11 | >^
         783 |           11 | |>>
         783 |           12 | |&>
         783 |           13 | ~
         783 |           14 | @
+        783 |           27 | @>
+        783 |           28 | <@
+        783 |           47 | @>
+        783 |           48 | <@
+        783 |           67 | @>
+        783 |           68 | <@
        2742 |            1 | &&
        2742 |            1 | @@
        2742 |            2 | @>
        2742 |            2 | @@@
        2742 |            3 | <@
        2742 |            4 | =
-(31 rows)
+(39 rows)
 
 -- Check that all operators linked to by opclass entries have selectivity
 -- estimators.  This is not absolutely required, but it seems a reasonable
index 9d1bd434e97f957655ed341c8ba632bf75f94abb..278837d091cd6c04fcb25788a02bce94aa7ed7b8 100644 (file)
@@ -81,6 +81,15 @@ SELECT '' AS three, p.* FROM POINT_TBL p
        | (10,10)
 (3 rows)
 
+SELECT '' AS three, p.* FROM POINT_TBL p
+   WHERE box '(0,0,100,100)' @> p.f1;
+ three |     f1     
+-------+------------
+       | (0,0)
+       | (5.1,34.5)
+       | (10,10)
+(3 rows)
+
 SELECT '' AS three, p.* FROM POINT_TBL p
    WHERE not p.f1 <@ box '(0,0,100,100)';
  three |    f1    
@@ -98,6 +107,15 @@ SELECT '' AS two, p.* FROM POINT_TBL p
      | (-10,0)
 (2 rows)
 
+SELECT '' AS three, p.* FROM POINT_TBL p
+   WHERE not box '(0,0,100,100)' @> p.f1;
+ three |    f1    
+-------+----------
+       | (-10,0)
+       | (-3,4)
+       | (-5,-12)
+(3 rows)
+
 SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist
    FROM POINT_TBL p
    ORDER BY dist;
index 2a4dc4755d74fbf70ce76d1fe482c219cae0e50a..4dc59d9b5def23c6031a1a983d9a0b94bf69d232 100644 (file)
@@ -127,7 +127,7 @@ SELECT relname, relhasindex
  pg_ts_template          | t
  pg_type                 | t
  pg_user_mapping         | t
- point_tbl               | f
+ point_tbl               | t
  polygon_tbl             | t
  ramp                    | f
  real_city               | f
index 519c3181a84d29da11949e16ab8d46ece2e8c55c..a4261c0f5e2cd608dce7a1a180b937dfc9492d9a 100644 (file)
@@ -76,6 +76,8 @@ CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1);
 
 CREATE INDEX gcircleind ON circle_tbl USING gist (f1);
 
+CREATE INDEX gpointind ON point_tbl USING gist (f1);
+
 CREATE TEMP TABLE gpolygon_tbl AS
     SELECT polygon(home_base) AS f1 FROM slow_emp4000;
 INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' ); 
@@ -110,6 +112,24 @@ SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
 
 SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
 
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+
 SET enable_seqscan = OFF;
 SET enable_indexscan = ON;
 SET enable_bitmapscan = ON;
@@ -150,6 +170,42 @@ EXPLAIN (COSTS OFF)
 SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
 SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
 
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
+
+EXPLAIN (COSTS OFF)
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
+
 RESET enable_seqscan;
 RESET enable_indexscan;
 RESET enable_bitmapscan;
index 8523c2ee9f8cd5c66e16b6b0a15ecec19e0768f7..40cd4ec022bc7134fda2514a946511e1f30d3e37 100644 (file)
@@ -45,12 +45,18 @@ SELECT '' AS one, p.* FROM POINT_TBL p WHERE p.f1 ~= '(5.1, 34.5)';
 SELECT '' AS three, p.* FROM POINT_TBL p
    WHERE p.f1 <@ box '(0,0,100,100)';
 
+SELECT '' AS three, p.* FROM POINT_TBL p
+   WHERE box '(0,0,100,100)' @> p.f1;
+
 SELECT '' AS three, p.* FROM POINT_TBL p
    WHERE not p.f1 <@ box '(0,0,100,100)';
 
 SELECT '' AS two, p.* FROM POINT_TBL p
    WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]';
 
+SELECT '' AS three, p.* FROM POINT_TBL p
+   WHERE not box '(0,0,100,100)' @> p.f1;
+
 SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist
    FROM POINT_TBL p
    ORDER BY dist;