diff options
author | Pavan Deolasee | 2011-05-20 15:06:06 +0000 |
---|---|---|
committer | Pavan Deolasee | 2011-05-20 15:06:06 +0000 |
commit | f65ae81fa4c6436093915410222dc962ec657b33 (patch) | |
tree | a7aa88a822cda01d1447ef46c68f369b7f81ff64 /src/backend/access/gist/gistproc.c | |
parent | 9bf28d03c9ca4f8a791b5e455f77b39d092dfa6c (diff) | |
parent | 1084f317702e1a039696ab8a37caf900e55ec8f2 (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.c | 180 |
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); +} |