Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4cbe473

Browse files
committed
Add point_ops opclass for GiST.
1 parent e99767b commit 4cbe473

File tree

16 files changed

+511
-20
lines changed

16 files changed

+511
-20
lines changed

src/backend/access/gist/gistproc.c

+171-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.19 2010/01/02 16:57:34 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.20 2010/01/14 16:31:09 teodor Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -165,7 +165,8 @@ gist_box_compress(PG_FUNCTION_ARGS)
165165
}
166166

167167
/*
168-
* GiST DeCompress method for boxes (also used for polygons and circles)
168+
* GiST DeCompress method for boxes (also used for points, polygons
169+
* and circles)
169170
*
170171
* do not do anything --- we just use the stored box as is.
171172
*/
@@ -176,7 +177,7 @@ gist_box_decompress(PG_FUNCTION_ARGS)
176177
}
177178

178179
/*
179-
* The GiST Penalty method for boxes
180+
* The GiST Penalty method for boxes (also used for points)
180181
*
181182
* As in the R-tree paper, we use change in area as our penalty metric
182183
*/
@@ -341,6 +342,8 @@ fallbackSplit(GistEntryVector *entryvec, GIST_SPLITVEC *v)
341342
*
342343
* New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree',
343344
* C.H.Ang and T.C.Tan
345+
*
346+
* This is used for both boxes and points.
344347
*/
345348
Datum
346349
gist_box_picksplit(PG_FUNCTION_ARGS)
@@ -533,6 +536,8 @@ gist_box_picksplit(PG_FUNCTION_ARGS)
533536

534537
/*
535538
* Equality method
539+
*
540+
* This is used for both boxes and points.
536541
*/
537542
Datum
538543
gist_box_same(PG_FUNCTION_ARGS)
@@ -872,3 +877,166 @@ gist_circle_consistent(PG_FUNCTION_ARGS)
872877

873878
PG_RETURN_BOOL(result);
874879
}
880+
881+
/**************************************************
882+
* Point ops
883+
**************************************************/
884+
885+
Datum
886+
gist_point_compress(PG_FUNCTION_ARGS)
887+
{
888+
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
889+
890+
if (entry->leafkey) /* Point, actually */
891+
{
892+
BOX *box = palloc(sizeof(BOX));
893+
Point *point = DatumGetPointP(entry->key);
894+
GISTENTRY *retval = palloc(sizeof(GISTENTRY));
895+
896+
box->high = box->low = *point;
897+
898+
gistentryinit(*retval, BoxPGetDatum(box),
899+
entry->rel, entry->page, entry->offset, FALSE);
900+
901+
PG_RETURN_POINTER(retval);
902+
}
903+
904+
PG_RETURN_POINTER(entry);
905+
}
906+
907+
static bool
908+
gist_point_consistent_internal(StrategyNumber strategy,
909+
bool isLeaf, BOX *key, Point *query)
910+
{
911+
bool result = false;
912+
913+
switch (strategy)
914+
{
915+
case RTLeftStrategyNumber:
916+
result = FPlt(key->low.x, query->x);
917+
break;
918+
case RTRightStrategyNumber:
919+
result = FPgt(key->high.x, query->x);
920+
break;
921+
case RTAboveStrategyNumber:
922+
result = FPgt(key->high.y, query->y);
923+
break;
924+
case RTBelowStrategyNumber:
925+
result = FPlt(key->low.y, query->y);
926+
break;
927+
case RTSameStrategyNumber:
928+
if (isLeaf)
929+
{
930+
result = FPeq(key->low.x, query->x)
931+
&& FPeq(key->low.y, query->y);
932+
}
933+
else
934+
{
935+
result = (query->x <= key->high.x && query->x >= key->low.x &&
936+
query->y <= key->high.y && query->y >= key->low.y);
937+
}
938+
break;
939+
default:
940+
elog(ERROR, "unknown strategy number: %d", strategy);
941+
}
942+
943+
return result;
944+
}
945+
946+
#define GeoStrategyNumberOffset 20
947+
#define PointStrategyNumberGroup 0
948+
#define BoxStrategyNumberGroup 1
949+
#define PolygonStrategyNumberGroup 2
950+
#define CircleStrategyNumberGroup 3
951+
952+
Datum
953+
gist_point_consistent(PG_FUNCTION_ARGS)
954+
{
955+
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
956+
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
957+
bool result;
958+
bool *recheck = (bool *) PG_GETARG_POINTER(4);
959+
StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset;
960+
961+
switch (strategyGroup)
962+
{
963+
case PointStrategyNumberGroup:
964+
result = gist_point_consistent_internal(strategy % GeoStrategyNumberOffset,
965+
GIST_LEAF(entry),
966+
DatumGetBoxP(entry->key),
967+
PG_GETARG_POINT_P(1));
968+
*recheck = false;
969+
break;
970+
case BoxStrategyNumberGroup:
971+
result = DatumGetBool(DirectFunctionCall5(
972+
gist_box_consistent,
973+
PointerGetDatum(entry),
974+
PG_GETARG_DATUM(1),
975+
Int16GetDatum(RTOverlapStrategyNumber),
976+
0, PointerGetDatum(recheck)));
977+
break;
978+
case PolygonStrategyNumberGroup:
979+
{
980+
POLYGON *query = PG_GETARG_POLYGON_P(1);
981+
982+
result = DatumGetBool(DirectFunctionCall5(
983+
gist_poly_consistent,
984+
PointerGetDatum(entry),
985+
PolygonPGetDatum(query),
986+
Int16GetDatum(RTOverlapStrategyNumber),
987+
0, PointerGetDatum(recheck)));
988+
989+
if (GIST_LEAF(entry) && result)
990+
{
991+
/*
992+
* We are on leaf page and quick check shows overlapping
993+
* of polygon's bounding box and point
994+
*/
995+
BOX *box = DatumGetBoxP(entry->key);
996+
997+
Assert(box->high.x == box->low.x
998+
&& box->high.y == box->low.y);
999+
result = DatumGetBool(DirectFunctionCall2(
1000+
poly_contain_pt,
1001+
PolygonPGetDatum(query),
1002+
PointPGetDatum(&box->high)));
1003+
*recheck = false;
1004+
}
1005+
}
1006+
break;
1007+
case CircleStrategyNumberGroup:
1008+
{
1009+
CIRCLE *query = PG_GETARG_CIRCLE_P(1);
1010+
1011+
result = DatumGetBool(DirectFunctionCall5(
1012+
gist_circle_consistent,
1013+
PointerGetDatum(entry),
1014+
CirclePGetDatum(query),
1015+
Int16GetDatum(RTOverlapStrategyNumber),
1016+
0, PointerGetDatum(recheck)));
1017+
1018+
if (GIST_LEAF(entry) && result)
1019+
{
1020+
/*
1021+
* We are on leaf page and quick check shows overlapping
1022+
* of polygon's bounding box and point
1023+
*/
1024+
BOX *box = DatumGetBoxP(entry->key);
1025+
1026+
Assert(box->high.x == box->low.x
1027+
&& box->high.y == box->low.y);
1028+
result = DatumGetBool(DirectFunctionCall2(
1029+
circle_contain_pt,
1030+
CirclePGetDatum(query),
1031+
PointPGetDatum(&box->high)));
1032+
*recheck = false;
1033+
}
1034+
}
1035+
break;
1036+
default:
1037+
result = false; /* silence compiler warning */
1038+
elog(ERROR, "unknown strategy number: %d", strategy);
1039+
}
1040+
1041+
PG_RETURN_BOOL(result);
1042+
}

src/backend/utils/adt/geo_ops.c

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.106 2010/01/02 16:57:54 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.107 2010/01/14 16:31:09 teodor Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -3202,6 +3202,16 @@ on_pb(PG_FUNCTION_ARGS)
32023202
pt->y <= box->high.y && pt->y >= box->low.y);
32033203
}
32043204

3205+
Datum
3206+
box_contain_pt(PG_FUNCTION_ARGS)
3207+
{
3208+
BOX *box = PG_GETARG_BOX_P(0);
3209+
Point *pt = PG_GETARG_POINT_P(1);
3210+
3211+
PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x &&
3212+
pt->y <= box->high.y && pt->y >= box->low.y);
3213+
}
3214+
32053215
/* on_ppath -
32063216
* Whether a point lies within (on) a polyline.
32073217
* If open, we have to (groan) check each segment.

src/include/catalog/catversion.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.571 2010/01/12 02:42:52 momjian Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.572 2010/01/14 16:31:09 teodor Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201001111
56+
#define CATALOG_VERSION_NO 201001141
5757

5858
#endif

src/include/catalog/pg_amop.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
3030
* Portions Copyright (c) 1994, Regents of the University of California
3131
*
32-
* $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.92 2010/01/05 01:06:56 tgl Exp $
32+
* $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.93 2010/01/14 16:31:09 teodor Exp $
3333
*
3434
* NOTES
3535
* the genbki.pl script reads this file and generates .bki
@@ -582,6 +582,22 @@ DATA(insert ( 2593 603 603 12 2572 783 ));
582582
DATA(insert ( 2593 603 603 13 2863 783 ));
583583
DATA(insert ( 2593 603 603 14 2862 783 ));
584584

585+
/*
586+
* gist point_ops
587+
*/
588+
DATA(insert ( 1029 600 600 11 506 783 ));
589+
DATA(insert ( 1029 600 600 1 507 783 ));
590+
DATA(insert ( 1029 600 600 5 508 783 ));
591+
DATA(insert ( 1029 600 600 10 509 783 ));
592+
DATA(insert ( 1029 600 600 6 510 783 ));
593+
DATA(insert ( 1029 603 600 27 433 783 ));
594+
DATA(insert ( 1029 600 603 28 511 783 ));
595+
DATA(insert ( 1029 604 600 47 757 783 ));
596+
DATA(insert ( 1029 600 604 48 756 783 ));
597+
DATA(insert ( 1029 718 600 67 759 783 ));
598+
DATA(insert ( 1029 600 718 68 758 783 ));
599+
600+
585601
/*
586602
* gist poly_ops (supports polygons)
587603
*/

src/include/catalog/pg_amproc.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
2323
* Portions Copyright (c) 1994, Regents of the University of California
2424
*
25-
* $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.77 2010/01/05 01:06:56 tgl Exp $
25+
* $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.78 2010/01/14 16:31:09 teodor Exp $
2626
*
2727
* NOTES
2828
* the genbki.pl script reads this file and generates .bki
@@ -197,6 +197,13 @@ DATA(insert ( 3702 3615 3615 4 3696 ));
197197
DATA(insert ( 3702 3615 3615 5 3700 ));
198198
DATA(insert ( 3702 3615 3615 6 3697 ));
199199
DATA(insert ( 3702 3615 3615 7 3699 ));
200+
DATA(insert ( 1029 600 600 1 2179 ));
201+
DATA(insert ( 1029 600 600 2 2583 ));
202+
DATA(insert ( 1029 600 600 3 1030 ));
203+
DATA(insert ( 1029 600 600 4 2580 ));
204+
DATA(insert ( 1029 600 600 5 2581 ));
205+
DATA(insert ( 1029 600 600 6 2582 ));
206+
DATA(insert ( 1029 600 600 7 2584 ));
200207

201208

202209
/* gin */

src/include/catalog/pg_opclass.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
2929
* Portions Copyright (c) 1994, Regents of the University of California
3030
*
31-
* $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.87 2010/01/05 01:06:56 tgl Exp $
31+
* $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.88 2010/01/14 16:31:09 teodor Exp $
3232
*
3333
* NOTES
3434
* 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 ));
170170
DATA(insert ( 403 tinterval_ops PGNSP PGUID 2234 704 t 0 ));
171171
DATA(insert ( 405 aclitem_ops PGNSP PGUID 2235 1033 t 0 ));
172172
DATA(insert ( 783 box_ops PGNSP PGUID 2593 603 t 0 ));
173+
DATA(insert ( 783 point_ops PGNSP PGUID 1029 600 t 603 ));
173174
DATA(insert ( 783 poly_ops PGNSP PGUID 2594 604 t 603 ));
174175
DATA(insert ( 783 circle_ops PGNSP PGUID 2595 718 t 603 ));
175176
DATA(insert ( 2742 _int4_ops PGNSP PGUID 2745 1007 t 23 ));

src/include/catalog/pg_operator.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.169 2010/01/05 01:06:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.170 2010/01/14 16:31:09 teodor Exp $
1212
*
1313
* NOTES
1414
* 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
171171
DATA(insert OID = 508 ( ">>" PGNSP PGUID b f f 600 600 16 0 0 point_right positionsel positionjoinsel ));
172172
DATA(insert OID = 509 ( "<^" PGNSP PGUID b f f 600 600 16 0 0 point_below positionsel positionjoinsel ));
173173
DATA(insert OID = 510 ( "~=" PGNSP PGUID b f f 600 600 16 510 713 point_eq eqsel eqjoinsel ));
174-
DATA(insert OID = 511 ( "<@" PGNSP PGUID b f f 600 603 16 0 0 on_pb - - ));
174+
DATA(insert OID = 511 ( "<@" PGNSP PGUID b f f 600 603 16 433 0 on_pb contsel contjoinsel ));
175+
DATA(insert OID = 433 ( "@>" PGNSP PGUID b f f 603 600 16 511 0 box_contain_pt contsel contjoinsel ));
175176
DATA(insert OID = 512 ( "<@" PGNSP PGUID b f f 600 602 16 755 0 on_ppath - - ));
176177
DATA(insert OID = 513 ( "@@" PGNSP PGUID l f f 0 603 600 0 0 box_center - - ));
177178
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_
359360
DATA(insert OID = 738 ( "*" PGNSP PGUID b f f 602 600 602 0 0 path_mul_pt - - ));
360361
DATA(insert OID = 739 ( "/" PGNSP PGUID b f f 602 600 602 0 0 path_div_pt - - ));
361362
DATA(insert OID = 755 ( "@>" PGNSP PGUID b f f 602 600 16 512 0 path_contain_pt - - ));
362-
DATA(insert OID = 756 ( "<@" PGNSP PGUID b f f 600 604 16 757 0 pt_contained_poly - - ));
363-
DATA(insert OID = 757 ( "@>" PGNSP PGUID b f f 604 600 16 756 0 poly_contain_pt - - ));
364-
DATA(insert OID = 758 ( "<@" PGNSP PGUID b f f 600 718 16 759 0 pt_contained_circle - - ));
365-
DATA(insert OID = 759 ( "@>" PGNSP PGUID b f f 718 600 16 758 0 circle_contain_pt - - ));
363+
DATA(insert OID = 756 ( "<@" PGNSP PGUID b f f 600 604 16 757 0 pt_contained_poly contsel contjoinsel ));
364+
DATA(insert OID = 757 ( "@>" PGNSP PGUID b f f 604 600 16 756 0 poly_contain_pt contsel contjoinsel ));
365+
DATA(insert OID = 758 ( "<@" PGNSP PGUID b f f 600 718 16 759 0 pt_contained_circle contsel contjoinsel ));
366+
DATA(insert OID = 759 ( "@>" PGNSP PGUID b f f 718 600 16 758 0 circle_contain_pt contsel contjoinsel ));
366367

367368
DATA(insert OID = 773 ( "@" PGNSP PGUID l f f 0 23 23 0 0 int4abs - - ));
368369

src/include/catalog/pg_opfamily.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.13 2010/01/05 01:06:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.14 2010/01/14 16:31:09 teodor Exp $
1212
*
1313
* NOTES
1414
* the genbki.pl script reads this file and generates .bki
@@ -127,6 +127,7 @@ DATA(insert OID = 2235 ( 405 aclitem_ops PGNSP PGUID ));
127127
DATA(insert OID = 2593 ( 783 box_ops PGNSP PGUID ));
128128
DATA(insert OID = 2594 ( 783 poly_ops PGNSP PGUID ));
129129
DATA(insert OID = 2595 ( 783 circle_ops PGNSP PGUID ));
130+
DATA(insert OID = 1029 ( 783 point_ops PGNSP PGUID ));
130131
DATA(insert OID = 2745 ( 2742 array_ops PGNSP PGUID ));
131132
DATA(insert OID = 2968 ( 403 uuid_ops PGNSP PGUID ));
132133
DATA(insert OID = 2969 ( 405 uuid_ops PGNSP PGUID ));

0 commit comments

Comments
 (0)