Add point_ops opclass for GiST.

This commit is contained in:
Teodor Sigaev 2010-01-14 16:31:09 +00:00
parent e99767bc28
commit 4cbe473938
16 changed files with 511 additions and 20 deletions

View 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);
}

View 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.

View 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

View 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)
*/

View 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 */

View 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 ));

View 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 - - ));

View 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 ));

View 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_ ));

View 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);

View 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;

View 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

View 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;

View 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

View 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;

View 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;