mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add polygon opclass for SP-GiST
Polygon opclass uses compress method feature of SP-GiST added earlier. For now it's a single operator class which uses this feature. SP-GiST actually indexes a bounding boxes of input polygons, so part of supported operations are lossy. Opclass uses most methods of corresponding opclass over boxes of SP-GiST and treats bounding boxes as point in 4D-space. Bump catalog version. Authors: Nikita Glukhov, Alexander Korotkov with minor editorization by me Reviewed-By: all authors + Darafei Praliaskouski Discussion: https://www.postgresql.org/message-id/flat/54907069.1030506@sigaev.ru
This commit is contained in:
@ -391,7 +391,7 @@ spg_box_quad_choose(PG_FUNCTION_ARGS)
|
||||
spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
|
||||
spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);
|
||||
BOX *centroid = DatumGetBoxP(in->prefixDatum),
|
||||
*box = DatumGetBoxP(in->datum);
|
||||
*box = DatumGetBoxP(in->leafDatum);
|
||||
|
||||
out->resultType = spgMatchNode;
|
||||
out->result.matchNode.restDatum = BoxPGetDatum(box);
|
||||
@ -473,6 +473,51 @@ spg_box_quad_picksplit(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if result of consistent method based on bounding box is exact.
|
||||
*/
|
||||
static bool
|
||||
is_bounding_box_test_exact(StrategyNumber strategy)
|
||||
{
|
||||
switch (strategy)
|
||||
{
|
||||
case RTLeftStrategyNumber:
|
||||
case RTOverLeftStrategyNumber:
|
||||
case RTOverRightStrategyNumber:
|
||||
case RTRightStrategyNumber:
|
||||
case RTOverBelowStrategyNumber:
|
||||
case RTBelowStrategyNumber:
|
||||
case RTAboveStrategyNumber:
|
||||
case RTOverAboveStrategyNumber:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get bounding box for ScanKey.
|
||||
*/
|
||||
static BOX *
|
||||
spg_box_quad_get_scankey_bbox(ScanKey sk, bool *recheck)
|
||||
{
|
||||
switch (sk->sk_subtype)
|
||||
{
|
||||
case BOXOID:
|
||||
return DatumGetBoxP(sk->sk_argument);
|
||||
|
||||
case POLYGONOID:
|
||||
if (recheck && !is_bounding_box_test_exact(sk->sk_strategy))
|
||||
*recheck = true;
|
||||
return &DatumGetPolygonP(sk->sk_argument)->boundbox;
|
||||
|
||||
default:
|
||||
elog(ERROR, "unrecognized scankey subtype: %d", sk->sk_subtype);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SP-GiST inner consistent function
|
||||
*/
|
||||
@ -515,7 +560,11 @@ spg_box_quad_inner_consistent(PG_FUNCTION_ARGS)
|
||||
centroid = getRangeBox(DatumGetBoxP(in->prefixDatum));
|
||||
queries = (RangeBox **) palloc(in->nkeys * sizeof(RangeBox *));
|
||||
for (i = 0; i < in->nkeys; i++)
|
||||
queries[i] = getRangeBox(DatumGetBoxP(in->scankeys[i].sk_argument));
|
||||
{
|
||||
BOX *box = spg_box_quad_get_scankey_bbox(&in->scankeys[i], NULL);
|
||||
|
||||
queries[i] = getRangeBox(box);
|
||||
}
|
||||
|
||||
/* Allocate enough memory for nodes */
|
||||
out->nNodes = 0;
|
||||
@ -637,8 +686,10 @@ spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS)
|
||||
/* Perform the required comparison(s) */
|
||||
for (i = 0; i < in->nkeys; i++)
|
||||
{
|
||||
StrategyNumber strategy = in->scankeys[i].sk_strategy;
|
||||
Datum query = in->scankeys[i].sk_argument;
|
||||
StrategyNumber strategy = in->scankeys[i].sk_strategy;
|
||||
BOX *box = spg_box_quad_get_scankey_bbox(&in->scankeys[i],
|
||||
&out->recheck);
|
||||
Datum query = BoxPGetDatum(box);
|
||||
|
||||
switch (strategy)
|
||||
{
|
||||
@ -713,3 +764,36 @@ spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS)
|
||||
|
||||
PG_RETURN_BOOL(flag);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SP-GiST config function for 2-D types that are lossy represented by their
|
||||
* bounding boxes
|
||||
*/
|
||||
Datum
|
||||
spg_bbox_quad_config(PG_FUNCTION_ARGS)
|
||||
{
|
||||
spgConfigOut *cfg = (spgConfigOut *) PG_GETARG_POINTER(1);
|
||||
|
||||
cfg->prefixType = BOXOID; /* A type represented by its bounding box */
|
||||
cfg->labelType = VOIDOID; /* We don't need node labels. */
|
||||
cfg->leafType = BOXOID;
|
||||
cfg->canReturnData = false;
|
||||
cfg->longValuesOK = false;
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* SP-GiST compress function for polygons
|
||||
*/
|
||||
Datum
|
||||
spg_poly_quad_compress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
POLYGON *polygon = PG_GETARG_POLYGON_P(0);
|
||||
BOX *box;
|
||||
|
||||
box = box_copy(&polygon->boundbox);
|
||||
|
||||
PG_RETURN_BOX_P(box);
|
||||
}
|
||||
|
Reference in New Issue
Block a user