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

Lines changed: 171 additions & 3 deletions
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

Lines changed: 11 additions & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 17 additions & 1 deletion
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

Lines changed: 8 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 7 additions & 6 deletions
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

Lines changed: 2 additions & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy