summaryrefslogtreecommitdiff
path: root/src/backend/access/gist/gistproc.c
diff options
context:
space:
mode:
authorPavan Deolasee2011-05-20 15:06:06 +0000
committerPavan Deolasee2011-05-20 15:06:06 +0000
commitf65ae81fa4c6436093915410222dc962ec657b33 (patch)
treea7aa88a822cda01d1447ef46c68f369b7f81ff64 /src/backend/access/gist/gistproc.c
parent9bf28d03c9ca4f8a791b5e455f77b39d092dfa6c (diff)
parent1084f317702e1a039696ab8a37caf900e55ec8f2 (diff)
Merge commit '1084f317702e1a039696ab8a37caf900e55ec8f2' into int-pgxc
Merge 9.0 PostgreSQL release into PGXC. Resolve conflicts thrown by git and fix some issues raised during compilation. We still don't compile fine at this point, but we should have resolved many conflicts to make further progress. Some of the changes in the regression tests are merged to reflect whats there in 9.0 release. Those are easy to fix later when we run regressions Conflicts: contrib/Makefile contrib/pgbench/pgbench.c src/Makefile src/backend/Makefile src/backend/access/transam/varsup.c src/backend/catalog/Makefile src/backend/catalog/dependency.c src/backend/catalog/genbki.sh src/backend/commands/dbcommands.c src/backend/commands/explain.c src/backend/commands/vacuum.c src/backend/executor/execMain.c src/backend/executor/execProcnode.c src/backend/executor/execTuples.c src/backend/parser/analyze.c src/backend/parser/gram.y src/backend/parser/parse_utilcmd.c src/backend/postmaster/postmaster.c src/backend/rewrite/rewriteHandler.c src/backend/storage/ipc/procarray.c src/backend/storage/lmgr/proc.c src/backend/tcop/postgres.c src/backend/tcop/utility.c src/backend/utils/cache/relcache.c src/backend/utils/init/postinit.c src/backend/utils/misc/guc.c src/bin/pg_ctl/pg_ctl.c src/include/Makefile src/include/access/twophase.h src/include/bootstrap/bootstrap.h src/include/catalog/catversion.h src/include/catalog/dependency.h src/include/catalog/indexing.h src/include/catalog/pg_proc.h src/include/nodes/nodes.h src/include/storage/lwlock.h src/include/storage/proc.h src/include/storage/procarray.h src/include/utils/lsyscache.h src/test/regress/expected/delete.out src/test/regress/expected/float4.out src/test/regress/expected/float8.out src/test/regress/expected/geometry.out src/test/regress/expected/join.out src/test/regress/expected/point.out src/test/regress/expected/rowtypes.out src/test/regress/expected/timestamp.out src/test/regress/expected/timestamptz.out src/test/regress/expected/tsearch.out src/test/regress/sql/numeric.sql src/test/regress/sql/point.sql
Diffstat (limited to 'src/backend/access/gist/gistproc.c')
-rw-r--r--src/backend/access/gist/gistproc.c180
1 files changed, 174 insertions, 6 deletions
diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index ef44380e77..cb34b26113 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -6,11 +6,11 @@
* This gives R-tree behavior, with Guttman's poly-time split algorithm.
*
*
- * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.17 2009/06/11 14:48:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.21 2010/02/26 02:00:33 momjian 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
*/
@@ -234,9 +235,9 @@ chooseLR(GIST_SPLITVEC *v,
NULL, NULL, InvalidOffsetNumber, FALSE);
gistentryinit(addon, BoxPGetDatum(union1), NULL, NULL, InvalidOffsetNumber, FALSE);
- DirectFunctionCall3(gist_box_penalty, PointerGetDatum(&oldUnion), PointerGetDatum(&union1), PointerGetDatum(&p1));
+ DirectFunctionCall3(gist_box_penalty, PointerGetDatum(&oldUnion), PointerGetDatum(&addon), PointerGetDatum(&p1));
gistentryinit(addon, BoxPGetDatum(union2), NULL, NULL, InvalidOffsetNumber, FALSE);
- DirectFunctionCall3(gist_box_penalty, PointerGetDatum(&oldUnion), PointerGetDatum(&union2), PointerGetDatum(&p2));
+ DirectFunctionCall3(gist_box_penalty, PointerGetDatum(&oldUnion), PointerGetDatum(&addon), PointerGetDatum(&p2));
if ((v->spl_ldatum_exists && p1 > p2) || (v->spl_rdatum_exists && p1 < p2))
firstToLeft = false;
@@ -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);
+}