mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Add point_ops opclass for GiST.
This commit is contained in:
parent
e99767bc28
commit
4cbe473938
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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 ));
|
||||
|
@ -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 - - ));
|
||||
|
||||
|
@ -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 ));
|
||||
|
@ -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_ ));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user