PostgreSQL Source Code git master
geo_spgist.c File Reference
#include "postgres.h"
#include "access/spgist.h"
#include "access/spgist_private.h"
#include "access/stratnum.h"
#include "catalog/pg_type.h"
#include "utils/float.h"
#include "utils/fmgroids.h"
#include "utils/fmgrprotos.h"
#include "utils/geo_decls.h"
Include dependency graph for geo_spgist.c:

Go to the source code of this file.

Data Structures

struct  Range
 
struct  RangeBox
 
struct  RectBox
 

Functions

static int compareDoubles (const void *a, const void *b)
 
static uint8 getQuadrant (BOX *centroid, BOX *inBox)
 
static RangeBoxgetRangeBox (BOX *box)
 
static RectBoxinitRectBox (void)
 
static RectBoxnextRectBox (RectBox *rect_box, RangeBox *centroid, uint8 quadrant)
 
static bool overlap2D (RangeBox *range_box, Range *query)
 
static bool overlap4D (RectBox *rect_box, RangeBox *query)
 
static bool contain2D (RangeBox *range_box, Range *query)
 
static bool contain4D (RectBox *rect_box, RangeBox *query)
 
static bool contained2D (RangeBox *range_box, Range *query)
 
static bool contained4D (RectBox *rect_box, RangeBox *query)
 
static bool lower2D (RangeBox *range_box, Range *query)
 
static bool overLower2D (RangeBox *range_box, Range *query)
 
static bool higher2D (RangeBox *range_box, Range *query)
 
static bool overHigher2D (RangeBox *range_box, Range *query)
 
static bool left4D (RectBox *rect_box, RangeBox *query)
 
static bool overLeft4D (RectBox *rect_box, RangeBox *query)
 
static bool right4D (RectBox *rect_box, RangeBox *query)
 
static bool overRight4D (RectBox *rect_box, RangeBox *query)
 
static bool below4D (RectBox *rect_box, RangeBox *query)
 
static bool overBelow4D (RectBox *rect_box, RangeBox *query)
 
static bool above4D (RectBox *rect_box, RangeBox *query)
 
static bool overAbove4D (RectBox *rect_box, RangeBox *query)
 
static double pointToRectBoxDistance (Point *point, RectBox *rect_box)
 
Datum spg_box_quad_config (PG_FUNCTION_ARGS)
 
Datum spg_box_quad_choose (PG_FUNCTION_ARGS)
 
Datum spg_box_quad_picksplit (PG_FUNCTION_ARGS)
 
static bool is_bounding_box_test_exact (StrategyNumber strategy)
 
static BOXspg_box_quad_get_scankey_bbox (ScanKey sk, bool *recheck)
 
Datum spg_box_quad_inner_consistent (PG_FUNCTION_ARGS)
 
Datum spg_box_quad_leaf_consistent (PG_FUNCTION_ARGS)
 
Datum spg_bbox_quad_config (PG_FUNCTION_ARGS)
 
Datum spg_poly_quad_compress (PG_FUNCTION_ARGS)
 

Function Documentation

◆ above4D()

static bool above4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 360 of file geo_spgist.c.

361{
362 return higher2D(&rect_box->range_box_y, &query->right);
363}
static bool higher2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:302
Range right
Definition: geo_spgist.c:112
RangeBox range_box_y
Definition: geo_spgist.c:118

References higher2D(), RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ below4D()

static bool below4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 346 of file geo_spgist.c.

347{
348 return lower2D(&rect_box->range_box_y, &query->right);
349}
static bool lower2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:286

References lower2D(), RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ compareDoubles()

static int compareDoubles ( const void *  a,
const void *  b 
)
static

Definition at line 93 of file geo_spgist.c.

94{
95 float8 x = *(float8 *) a;
96 float8 y = *(float8 *) b;
97
98 if (x == y)
99 return 0;
100 return (x > y) ? 1 : -1;
101}
double float8
Definition: c.h:587
int y
Definition: isn.c:71
int b
Definition: isn.c:69
int x
Definition: isn.c:70
int a
Definition: isn.c:68

References a, b, x, and y.

Referenced by spg_box_quad_picksplit().

◆ contain2D()

static bool contain2D ( RangeBox range_box,
Range query 
)
static

Definition at line 252 of file geo_spgist.c.

253{
254 return FPge(range_box->right.high, query->high) &&
255 FPle(range_box->left.low, query->low);
256}
static bool FPge(double A, double B)
Definition: geo_decls.h:77
static bool FPle(double A, double B)
Definition: geo_decls.h:65
Range left
Definition: geo_spgist.c:111
float8 high
Definition: geo_spgist.c:106
float8 low
Definition: geo_spgist.c:105

References FPge(), FPle(), Range::high, RangeBox::left, Range::low, and RangeBox::right.

Referenced by contain4D().

◆ contain4D()

static bool contain4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 260 of file geo_spgist.c.

261{
262 return contain2D(&rect_box->range_box_x, &query->left) &&
263 contain2D(&rect_box->range_box_y, &query->right);
264}
static bool contain2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:252
RangeBox range_box_x
Definition: geo_spgist.c:117

References contain2D(), RangeBox::left, RectBox::range_box_x, RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ contained2D()

static bool contained2D ( RangeBox range_box,
Range query 
)
static

Definition at line 268 of file geo_spgist.c.

269{
270 return FPle(range_box->left.low, query->high) &&
271 FPge(range_box->left.high, query->low) &&
272 FPle(range_box->right.low, query->high) &&
273 FPge(range_box->right.high, query->low);
274}

References FPge(), FPle(), Range::high, RangeBox::left, Range::low, and RangeBox::right.

Referenced by contained4D().

◆ contained4D()

static bool contained4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 278 of file geo_spgist.c.

279{
280 return contained2D(&rect_box->range_box_x, &query->left) &&
281 contained2D(&rect_box->range_box_y, &query->right);
282}
static bool contained2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:268

References contained2D(), RangeBox::left, RectBox::range_box_x, RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ getQuadrant()

static uint8 getQuadrant ( BOX centroid,
BOX inBox 
)
static

Definition at line 130 of file geo_spgist.c.

131{
132 uint8 quadrant = 0;
133
134 if (inBox->low.x > centroid->low.x)
135 quadrant |= 0x8;
136
137 if (inBox->high.x > centroid->high.x)
138 quadrant |= 0x4;
139
140 if (inBox->low.y > centroid->low.y)
141 quadrant |= 0x2;
142
143 if (inBox->high.y > centroid->high.y)
144 quadrant |= 0x1;
145
146 return quadrant;
147}
uint8_t uint8
Definition: c.h:486
Point low
Definition: geo_decls.h:143
Point high
Definition: geo_decls.h:142
float8 y
Definition: geo_decls.h:99
float8 x
Definition: geo_decls.h:98

References BOX::high, BOX::low, Point::x, and Point::y.

Referenced by spg_box_quad_choose(), and spg_box_quad_picksplit().

◆ getRangeBox()

static RangeBox * getRangeBox ( BOX box)
static

Definition at line 157 of file geo_spgist.c.

158{
159 RangeBox *range_box = (RangeBox *) palloc(sizeof(RangeBox));
160
161 range_box->left.low = box->low.x;
162 range_box->left.high = box->high.x;
163
164 range_box->right.low = box->low.y;
165 range_box->right.high = box->high.y;
166
167 return range_box;
168}
void * palloc(Size size)
Definition: mcxt.c:1317

References Range::high, BOX::high, RangeBox::left, Range::low, BOX::low, palloc(), RangeBox::right, Point::x, and Point::y.

Referenced by spg_box_quad_inner_consistent().

◆ higher2D()

static bool higher2D ( RangeBox range_box,
Range query 
)
static

Definition at line 302 of file geo_spgist.c.

303{
304 return FPgt(range_box->left.high, query->high) &&
305 FPgt(range_box->right.high, query->high);
306}
static bool FPgt(double A, double B)
Definition: geo_decls.h:71

References FPgt(), Range::high, RangeBox::left, and RangeBox::right.

Referenced by above4D(), and right4D().

◆ initRectBox()

static RectBox * initRectBox ( void  )
static

Definition at line 177 of file geo_spgist.c.

178{
179 RectBox *rect_box = (RectBox *) palloc(sizeof(RectBox));
180 float8 infinity = get_float8_infinity();
181
182 rect_box->range_box_x.left.low = -infinity;
183 rect_box->range_box_x.left.high = infinity;
184
185 rect_box->range_box_x.right.low = -infinity;
186 rect_box->range_box_x.right.high = infinity;
187
188 rect_box->range_box_y.left.low = -infinity;
189 rect_box->range_box_y.left.high = infinity;
190
191 rect_box->range_box_y.right.low = -infinity;
192 rect_box->range_box_y.right.high = infinity;
193
194 return rect_box;
195}
static float8 get_float8_infinity(void)
Definition: float.h:94

References get_float8_infinity(), Range::high, RangeBox::left, Range::low, palloc(), RectBox::range_box_x, RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ is_bounding_box_test_exact()

static bool is_bounding_box_test_exact ( StrategyNumber  strategy)
static

Definition at line 508 of file geo_spgist.c.

509{
510 switch (strategy)
511 {
520 return true;
521
522 default:
523 return false;
524 }
525}
#define RTLeftStrategyNumber
Definition: stratnum.h:51
#define RTOverRightStrategyNumber
Definition: stratnum.h:54
#define RTRightStrategyNumber
Definition: stratnum.h:55
#define RTOverAboveStrategyNumber
Definition: stratnum.h:62
#define RTOverBelowStrategyNumber
Definition: stratnum.h:59
#define RTBelowStrategyNumber
Definition: stratnum.h:60
#define RTAboveStrategyNumber
Definition: stratnum.h:61
#define RTOverLeftStrategyNumber
Definition: stratnum.h:52

References RTAboveStrategyNumber, RTBelowStrategyNumber, RTLeftStrategyNumber, RTOverAboveStrategyNumber, RTOverBelowStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, and RTRightStrategyNumber.

Referenced by spg_box_quad_get_scankey_bbox().

◆ left4D()

static bool left4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 318 of file geo_spgist.c.

319{
320 return lower2D(&rect_box->range_box_x, &query->left);
321}

References RangeBox::left, lower2D(), and RectBox::range_box_x.

Referenced by spg_box_quad_inner_consistent().

◆ lower2D()

static bool lower2D ( RangeBox range_box,
Range query 
)
static

Definition at line 286 of file geo_spgist.c.

287{
288 return FPlt(range_box->left.low, query->low) &&
289 FPlt(range_box->right.low, query->low);
290}
static bool FPlt(double A, double B)
Definition: geo_decls.h:59

References FPlt(), RangeBox::left, Range::low, and RangeBox::right.

Referenced by below4D(), and left4D().

◆ nextRectBox()

static RectBox * nextRectBox ( RectBox rect_box,
RangeBox centroid,
uint8  quadrant 
)
static

Definition at line 205 of file geo_spgist.c.

206{
207 RectBox *next_rect_box = (RectBox *) palloc(sizeof(RectBox));
208
209 memcpy(next_rect_box, rect_box, sizeof(RectBox));
210
211 if (quadrant & 0x8)
212 next_rect_box->range_box_x.left.low = centroid->left.low;
213 else
214 next_rect_box->range_box_x.left.high = centroid->left.low;
215
216 if (quadrant & 0x4)
217 next_rect_box->range_box_x.right.low = centroid->left.high;
218 else
219 next_rect_box->range_box_x.right.high = centroid->left.high;
220
221 if (quadrant & 0x2)
222 next_rect_box->range_box_y.left.low = centroid->right.low;
223 else
224 next_rect_box->range_box_y.left.high = centroid->right.low;
225
226 if (quadrant & 0x1)
227 next_rect_box->range_box_y.right.low = centroid->right.high;
228 else
229 next_rect_box->range_box_y.right.high = centroid->right.high;
230
231 return next_rect_box;
232}

References Range::high, RangeBox::left, Range::low, palloc(), RectBox::range_box_x, RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ overAbove4D()

static bool overAbove4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 367 of file geo_spgist.c.

368{
369 return overHigher2D(&rect_box->range_box_y, &query->right);
370}
static bool overHigher2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:310

References overHigher2D(), RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ overBelow4D()

static bool overBelow4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 353 of file geo_spgist.c.

354{
355 return overLower2D(&rect_box->range_box_y, &query->right);
356}
static bool overLower2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:294

References overLower2D(), RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ overHigher2D()

static bool overHigher2D ( RangeBox range_box,
Range query 
)
static

Definition at line 310 of file geo_spgist.c.

311{
312 return FPge(range_box->left.high, query->low) &&
313 FPge(range_box->right.high, query->low);
314}

References FPge(), Range::high, RangeBox::left, Range::low, and RangeBox::right.

Referenced by overAbove4D(), and overRight4D().

◆ overlap2D()

static bool overlap2D ( RangeBox range_box,
Range query 
)
static

Definition at line 236 of file geo_spgist.c.

237{
238 return FPge(range_box->right.high, query->low) &&
239 FPle(range_box->left.low, query->high);
240}

References FPge(), FPle(), Range::high, RangeBox::left, Range::low, and RangeBox::right.

Referenced by overlap4D().

◆ overlap4D()

static bool overlap4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 244 of file geo_spgist.c.

245{
246 return overlap2D(&rect_box->range_box_x, &query->left) &&
247 overlap2D(&rect_box->range_box_y, &query->right);
248}
static bool overlap2D(RangeBox *range_box, Range *query)
Definition: geo_spgist.c:236

References RangeBox::left, overlap2D(), RectBox::range_box_x, RectBox::range_box_y, and RangeBox::right.

Referenced by spg_box_quad_inner_consistent().

◆ overLeft4D()

static bool overLeft4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 325 of file geo_spgist.c.

326{
327 return overLower2D(&rect_box->range_box_x, &query->left);
328}

References RangeBox::left, overLower2D(), and RectBox::range_box_x.

Referenced by spg_box_quad_inner_consistent().

◆ overLower2D()

static bool overLower2D ( RangeBox range_box,
Range query 
)
static

Definition at line 294 of file geo_spgist.c.

295{
296 return FPle(range_box->left.low, query->high) &&
297 FPle(range_box->right.low, query->high);
298}

References FPle(), Range::high, RangeBox::left, Range::low, and RangeBox::right.

Referenced by overBelow4D(), and overLeft4D().

◆ overRight4D()

static bool overRight4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 339 of file geo_spgist.c.

340{
341 return overHigher2D(&rect_box->range_box_x, &query->left);
342}

References RangeBox::left, overHigher2D(), and RectBox::range_box_x.

Referenced by spg_box_quad_inner_consistent().

◆ pointToRectBoxDistance()

static double pointToRectBoxDistance ( Point point,
RectBox rect_box 
)
static

Definition at line 374 of file geo_spgist.c.

375{
376 double dx;
377 double dy;
378
379 if (point->x < rect_box->range_box_x.left.low)
380 dx = rect_box->range_box_x.left.low - point->x;
381 else if (point->x > rect_box->range_box_x.right.high)
382 dx = point->x - rect_box->range_box_x.right.high;
383 else
384 dx = 0;
385
386 if (point->y < rect_box->range_box_y.left.low)
387 dy = rect_box->range_box_y.left.low - point->y;
388 else if (point->y > rect_box->range_box_y.right.high)
389 dy = point->y - rect_box->range_box_y.right.high;
390 else
391 dy = 0;
392
393 return HYPOT(dx, dy);
394}
#define HYPOT(A, B)
Definition: geo_decls.h:91

References Range::high, HYPOT, RangeBox::left, Range::low, RectBox::range_box_x, RectBox::range_box_y, RangeBox::right, Point::x, and Point::y.

Referenced by spg_box_quad_inner_consistent().

◆ right4D()

static bool right4D ( RectBox rect_box,
RangeBox query 
)
static

Definition at line 332 of file geo_spgist.c.

333{
334 return higher2D(&rect_box->range_box_x, &query->left);
335}

References higher2D(), RangeBox::left, and RectBox::range_box_x.

Referenced by spg_box_quad_inner_consistent().

◆ spg_bbox_quad_config()

Datum spg_bbox_quad_config ( PG_FUNCTION_ARGS  )

Definition at line 859 of file geo_spgist.c.

860{
862
863 cfg->prefixType = BOXOID; /* A type represented by its bounding box */
864 cfg->labelType = VOIDOID; /* We don't need node labels. */
865 cfg->leafType = BOXOID;
866 cfg->canReturnData = false;
867 cfg->longValuesOK = false;
868
870}
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
Oid leafType
Definition: spgist.h:45
bool longValuesOK
Definition: spgist.h:47
bool canReturnData
Definition: spgist.h:46
Oid labelType
Definition: spgist.h:44
Oid prefixType
Definition: spgist.h:43

References spgConfigOut::canReturnData, spgConfigOut::labelType, spgConfigOut::leafType, spgConfigOut::longValuesOK, PG_GETARG_POINTER, PG_RETURN_VOID, and spgConfigOut::prefixType.

◆ spg_box_quad_choose()

Datum spg_box_quad_choose ( PG_FUNCTION_ARGS  )

Definition at line 417 of file geo_spgist.c.

418{
421 BOX *centroid = DatumGetBoxP(in->prefixDatum),
422 *box = DatumGetBoxP(in->leafDatum);
423
426
427 /* nodeN will be set by core, when allTheSame. */
428 if (!in->allTheSame)
429 out->result.matchNode.nodeN = getQuadrant(centroid, box);
430
432}
static BOX * DatumGetBoxP(Datum X)
Definition: geo_decls.h:234
static Datum BoxPGetDatum(const BOX *X)
Definition: geo_decls.h:239
static uint8 getQuadrant(BOX *centroid, BOX *inBox)
Definition: geo_spgist.c:130
@ spgMatchNode
Definition: spgist.h:69
Definition: geo_decls.h:141
Datum prefixDatum
Definition: spgist.h:62
Datum leafDatum
Definition: spgist.h:56
bool allTheSame
Definition: spgist.h:60
spgChooseResultType resultType
Definition: spgist.h:76
Datum restDatum
Definition: spgist.h:83
int nodeN
Definition: spgist.h:81
struct spgChooseOut::@51::@52 matchNode
union spgChooseOut::@51 result

References spgChooseIn::allTheSame, BoxPGetDatum(), DatumGetBoxP(), getQuadrant(), spgChooseIn::leafDatum, spgChooseOut::matchNode, spgChooseOut::nodeN, PG_GETARG_POINTER, PG_RETURN_VOID, spgChooseIn::prefixDatum, spgChooseOut::restDatum, spgChooseOut::result, spgChooseOut::resultType, and spgMatchNode.

◆ spg_box_quad_config()

Datum spg_box_quad_config ( PG_FUNCTION_ARGS  )

Definition at line 401 of file geo_spgist.c.

402{
404
405 cfg->prefixType = BOXOID;
406 cfg->labelType = VOIDOID; /* We don't need node labels. */
407 cfg->canReturnData = true;
408 cfg->longValuesOK = false;
409
411}

References spgConfigOut::canReturnData, spgConfigOut::labelType, spgConfigOut::longValuesOK, PG_GETARG_POINTER, PG_RETURN_VOID, and spgConfigOut::prefixType.

◆ spg_box_quad_get_scankey_bbox()

static BOX * spg_box_quad_get_scankey_bbox ( ScanKey  sk,
bool *  recheck 
)
static

Definition at line 531 of file geo_spgist.c.

532{
533 switch (sk->sk_subtype)
534 {
535 case BOXOID:
536 return DatumGetBoxP(sk->sk_argument);
537
538 case POLYGONOID:
539 if (recheck && !is_bounding_box_test_exact(sk->sk_strategy))
540 *recheck = true;
542
543 default:
544 elog(ERROR, "unrecognized scankey subtype: %d", sk->sk_subtype);
545 return NULL;
546 }
547}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static POLYGON * DatumGetPolygonP(Datum X)
Definition: geo_decls.h:247
static bool is_bounding_box_test_exact(StrategyNumber strategy)
Definition: geo_spgist.c:508
BOX boundbox
Definition: geo_decls.h:155
Datum sk_argument
Definition: skey.h:72
Oid sk_subtype
Definition: skey.h:69
StrategyNumber sk_strategy
Definition: skey.h:68

References POLYGON::boundbox, DatumGetBoxP(), DatumGetPolygonP(), elog, ERROR, is_bounding_box_test_exact(), ScanKeyData::sk_argument, ScanKeyData::sk_strategy, and ScanKeyData::sk_subtype.

Referenced by spg_box_quad_inner_consistent(), and spg_box_quad_leaf_consistent().

◆ spg_box_quad_inner_consistent()

Datum spg_box_quad_inner_consistent ( PG_FUNCTION_ARGS  )

Definition at line 553 of file geo_spgist.c.

554{
557 int i;
558 MemoryContext old_ctx;
559 RectBox *rect_box;
560 uint8 quadrant;
561 RangeBox *centroid,
562 **queries;
563
564 /*
565 * We are saving the traversal value or initialize it an unbounded one, if
566 * we have just begun to walk the tree.
567 */
568 if (in->traversalValue)
569 rect_box = in->traversalValue;
570 else
571 rect_box = initRectBox();
572
573 if (in->allTheSame)
574 {
575 /* Report that all nodes should be visited */
576 out->nNodes = in->nNodes;
577 out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes);
578 for (i = 0; i < in->nNodes; i++)
579 out->nodeNumbers[i] = i;
580
581 if (in->norderbys > 0 && in->nNodes > 0)
582 {
583 double *distances = palloc(sizeof(double) * in->norderbys);
584 int j;
585
586 for (j = 0; j < in->norderbys; j++)
587 {
589
590 distances[j] = pointToRectBoxDistance(pt, rect_box);
591 }
592
593 out->distances = (double **) palloc(sizeof(double *) * in->nNodes);
594 out->distances[0] = distances;
595
596 for (i = 1; i < in->nNodes; i++)
597 {
598 out->distances[i] = palloc(sizeof(double) * in->norderbys);
599 memcpy(out->distances[i], distances,
600 sizeof(double) * in->norderbys);
601 }
602 }
603
605 }
606
607 /*
608 * We are casting the prefix and queries to RangeBoxes for ease of the
609 * following operations.
610 */
611 centroid = getRangeBox(DatumGetBoxP(in->prefixDatum));
612 queries = (RangeBox **) palloc(in->nkeys * sizeof(RangeBox *));
613 for (i = 0; i < in->nkeys; i++)
614 {
615 BOX *box = spg_box_quad_get_scankey_bbox(&in->scankeys[i], NULL);
616
617 queries[i] = getRangeBox(box);
618 }
619
620 /* Allocate enough memory for nodes */
621 out->nNodes = 0;
622 out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes);
623 out->traversalValues = (void **) palloc(sizeof(void *) * in->nNodes);
624 if (in->norderbys > 0)
625 out->distances = (double **) palloc(sizeof(double *) * in->nNodes);
626
627 /*
628 * We switch memory context, because we want to allocate memory for new
629 * traversal values (next_rect_box) and pass these pieces of memory to
630 * further call of this function.
631 */
633
634 for (quadrant = 0; quadrant < in->nNodes; quadrant++)
635 {
636 RectBox *next_rect_box = nextRectBox(rect_box, centroid, quadrant);
637 bool flag = true;
638
639 for (i = 0; i < in->nkeys; i++)
640 {
641 StrategyNumber strategy = in->scankeys[i].sk_strategy;
642
643 switch (strategy)
644 {
646 flag = overlap4D(next_rect_box, queries[i]);
647 break;
648
650 flag = contain4D(next_rect_box, queries[i]);
651 break;
652
655 flag = contained4D(next_rect_box, queries[i]);
656 break;
657
659 flag = left4D(next_rect_box, queries[i]);
660 break;
661
663 flag = overLeft4D(next_rect_box, queries[i]);
664 break;
665
667 flag = right4D(next_rect_box, queries[i]);
668 break;
669
671 flag = overRight4D(next_rect_box, queries[i]);
672 break;
673
675 flag = above4D(next_rect_box, queries[i]);
676 break;
677
679 flag = overAbove4D(next_rect_box, queries[i]);
680 break;
681
683 flag = below4D(next_rect_box, queries[i]);
684 break;
685
687 flag = overBelow4D(next_rect_box, queries[i]);
688 break;
689
690 default:
691 elog(ERROR, "unrecognized strategy: %d", strategy);
692 }
693
694 /* If any check is failed, we have found our answer. */
695 if (!flag)
696 break;
697 }
698
699 if (flag)
700 {
701 out->traversalValues[out->nNodes] = next_rect_box;
702 out->nodeNumbers[out->nNodes] = quadrant;
703
704 if (in->norderbys > 0)
705 {
706 double *distances = palloc(sizeof(double) * in->norderbys);
707 int j;
708
709 out->distances[out->nNodes] = distances;
710
711 for (j = 0; j < in->norderbys; j++)
712 {
714
715 distances[j] = pointToRectBoxDistance(pt, next_rect_box);
716 }
717 }
718
719 out->nNodes++;
720 }
721 else
722 {
723 /*
724 * If this node is not selected, we don't need to keep the next
725 * traversal value in the memory context.
726 */
727 pfree(next_rect_box);
728 }
729 }
730
731 /* Switch back */
732 MemoryContextSwitchTo(old_ctx);
733
735}
static Point * DatumGetPointP(Datum X)
Definition: geo_decls.h:176
static bool right4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:332
static double pointToRectBoxDistance(Point *point, RectBox *rect_box)
Definition: geo_spgist.c:374
static bool contain4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:260
static bool overRight4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:339
static RectBox * initRectBox(void)
Definition: geo_spgist.c:177
static RangeBox * getRangeBox(BOX *box)
Definition: geo_spgist.c:157
static bool overLeft4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:325
static bool above4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:360
static BOX * spg_box_quad_get_scankey_bbox(ScanKey sk, bool *recheck)
Definition: geo_spgist.c:531
static bool contained4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:278
static bool overBelow4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:353
static bool overlap4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:244
static RectBox * nextRectBox(RectBox *rect_box, RangeBox *centroid, uint8 quadrant)
Definition: geo_spgist.c:205
static bool left4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:318
static bool overAbove4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:367
static bool below4D(RectBox *rect_box, RangeBox *query)
Definition: geo_spgist.c:346
int j
Definition: isn.c:73
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
void pfree(void *pointer)
Definition: mcxt.c:1521
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
uint16 StrategyNumber
Definition: stratnum.h:22
#define RTOverlapStrategyNumber
Definition: stratnum.h:53
#define RTSameStrategyNumber
Definition: stratnum.h:56
#define RTContainsStrategyNumber
Definition: stratnum.h:57
#define RTContainedByStrategyNumber
Definition: stratnum.h:58
void * traversalValue
Definition: spgist.h:141
ScanKey scankeys
Definition: spgist.h:134
ScanKey orderbys
Definition: spgist.h:135
MemoryContext traversalMemoryContext
Definition: spgist.h:142
void ** traversalValues
Definition: spgist.h:160
double ** distances
Definition: spgist.h:161
char * flag(int b)
Definition: test-ctype.c:33

References above4D(), spgInnerConsistentIn::allTheSame, below4D(), contain4D(), contained4D(), DatumGetBoxP(), DatumGetPointP(), spgInnerConsistentOut::distances, elog, ERROR, flag(), getRangeBox(), i, if(), initRectBox(), j, left4D(), MemoryContextSwitchTo(), nextRectBox(), spgInnerConsistentIn::nkeys, spgInnerConsistentIn::nNodes, spgInnerConsistentOut::nNodes, spgInnerConsistentOut::nodeNumbers, spgInnerConsistentIn::norderbys, spgInnerConsistentIn::orderbys, overAbove4D(), overBelow4D(), overlap4D(), overLeft4D(), overRight4D(), palloc(), pfree(), PG_GETARG_POINTER, PG_RETURN_VOID, pointToRectBoxDistance(), spgInnerConsistentIn::prefixDatum, right4D(), RTAboveStrategyNumber, RTBelowStrategyNumber, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTLeftStrategyNumber, RTOverAboveStrategyNumber, RTOverBelowStrategyNumber, RTOverlapStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, RTRightStrategyNumber, RTSameStrategyNumber, spgInnerConsistentIn::scankeys, ScanKeyData::sk_argument, ScanKeyData::sk_strategy, spg_box_quad_get_scankey_bbox(), spgInnerConsistentIn::traversalMemoryContext, spgInnerConsistentIn::traversalValue, and spgInnerConsistentOut::traversalValues.

◆ spg_box_quad_leaf_consistent()

Datum spg_box_quad_leaf_consistent ( PG_FUNCTION_ARGS  )

Definition at line 741 of file geo_spgist.c.

742{
745 Datum leaf = in->leafDatum;
746 bool flag = true;
747 int i;
748
749 /* All tests are exact. */
750 out->recheck = false;
751
752 /*
753 * Don't return leafValue unless told to; this is used for both box and
754 * polygon opclasses, and in the latter case the leaf datum is not even of
755 * the right type to return.
756 */
757 if (in->returnData)
758 out->leafValue = leaf;
759
760 /* Perform the required comparison(s) */
761 for (i = 0; i < in->nkeys; i++)
762 {
763 StrategyNumber strategy = in->scankeys[i].sk_strategy;
765 &out->recheck);
766 Datum query = BoxPGetDatum(box);
767
768 switch (strategy)
769 {
772 query));
773 break;
774
777 query));
778 break;
779
782 query));
783 break;
784
787 query));
788 break;
789
792 query));
793 break;
794
797 query));
798 break;
799
802 query));
803 break;
804
807 query));
808 break;
809
812 query));
813 break;
814
817 query));
818 break;
819
822 query));
823 break;
824
827 query));
828 break;
829
830 default:
831 elog(ERROR, "unrecognized strategy: %d", strategy);
832 }
833
834 /* If any check is failed, we have found our answer. */
835 if (!flag)
836 break;
837 }
838
839 if (flag && in->norderbys > 0)
840 {
841 Oid distfnoid = in->orderbys[0].sk_func.fn_oid;
842
843 out->distances = spg_key_orderbys_distances(leaf, false,
844 in->orderbys, in->norderbys);
845
846 /* Recheck is necessary when computing distance to polygon */
847 out->recheckDistances = distfnoid == F_DIST_POLYP;
848 }
849
851}
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum box_left(PG_FUNCTION_ARGS)
Definition: geo_ops.c:583
Datum box_right(PG_FUNCTION_ARGS)
Definition: geo_ops.c:609
Datum box_same(PG_FUNCTION_ARGS)
Definition: geo_ops.c:551
Datum box_below(PG_FUNCTION_ARGS)
Definition: geo_ops.c:635
Datum box_overright(PG_FUNCTION_ARGS)
Definition: geo_ops.c:624
Datum box_overabove(PG_FUNCTION_ARGS)
Definition: geo_ops.c:670
Datum box_overlap(PG_FUNCTION_ARGS)
Definition: geo_ops.c:563
Datum box_contain(PG_FUNCTION_ARGS)
Definition: geo_ops.c:692
Datum box_overbelow(PG_FUNCTION_ARGS)
Definition: geo_ops.c:647
Datum box_contained(PG_FUNCTION_ARGS)
Definition: geo_ops.c:681
Datum box_overleft(PG_FUNCTION_ARGS)
Definition: geo_ops.c:598
Datum box_above(PG_FUNCTION_ARGS)
Definition: geo_ops.c:658
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
uintptr_t Datum
Definition: postgres.h:69
unsigned int Oid
Definition: postgres_ext.h:32
double * spg_key_orderbys_distances(Datum key, bool isLeaf, ScanKey orderbys, int norderbys)
Definition: spgproc.c:63
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo sk_func
Definition: skey.h:71
ScanKey scankeys
Definition: spgist.h:169
ScanKey orderbys
Definition: spgist.h:170
double * distances
Definition: spgist.h:188

References box_above(), box_below(), box_contain(), box_contained(), box_left(), box_overabove(), box_overbelow(), box_overlap(), box_overleft(), box_overright(), box_right(), box_same(), BoxPGetDatum(), DatumGetBool(), DirectFunctionCall2, spgLeafConsistentOut::distances, elog, ERROR, flag(), FmgrInfo::fn_oid, i, spgLeafConsistentIn::leafDatum, spgLeafConsistentOut::leafValue, spgLeafConsistentIn::nkeys, spgLeafConsistentIn::norderbys, spgLeafConsistentIn::orderbys, PG_GETARG_POINTER, PG_RETURN_BOOL, spgLeafConsistentOut::recheck, spgLeafConsistentOut::recheckDistances, spgLeafConsistentIn::returnData, RTAboveStrategyNumber, RTBelowStrategyNumber, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTLeftStrategyNumber, RTOverAboveStrategyNumber, RTOverBelowStrategyNumber, RTOverlapStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, RTRightStrategyNumber, RTSameStrategyNumber, spgLeafConsistentIn::scankeys, ScanKeyData::sk_func, ScanKeyData::sk_strategy, spg_box_quad_get_scankey_bbox(), and spg_key_orderbys_distances().

◆ spg_box_quad_picksplit()

Datum spg_box_quad_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 441 of file geo_spgist.c.

442{
445 BOX *centroid;
446 int median,
447 i;
448 float8 *lowXs = palloc(sizeof(float8) * in->nTuples);
449 float8 *highXs = palloc(sizeof(float8) * in->nTuples);
450 float8 *lowYs = palloc(sizeof(float8) * in->nTuples);
451 float8 *highYs = palloc(sizeof(float8) * in->nTuples);
452
453 /* Calculate median of all 4D coordinates */
454 for (i = 0; i < in->nTuples; i++)
455 {
456 BOX *box = DatumGetBoxP(in->datums[i]);
457
458 lowXs[i] = box->low.x;
459 highXs[i] = box->high.x;
460 lowYs[i] = box->low.y;
461 highYs[i] = box->high.y;
462 }
463
464 qsort(lowXs, in->nTuples, sizeof(float8), compareDoubles);
465 qsort(highXs, in->nTuples, sizeof(float8), compareDoubles);
466 qsort(lowYs, in->nTuples, sizeof(float8), compareDoubles);
467 qsort(highYs, in->nTuples, sizeof(float8), compareDoubles);
468
469 median = in->nTuples / 2;
470
471 centroid = palloc(sizeof(BOX));
472
473 centroid->low.x = lowXs[median];
474 centroid->high.x = highXs[median];
475 centroid->low.y = lowYs[median];
476 centroid->high.y = highYs[median];
477
478 /* Fill the output */
479 out->hasPrefix = true;
480 out->prefixDatum = BoxPGetDatum(centroid);
481
482 out->nNodes = 16;
483 out->nodeLabels = NULL; /* We don't need node labels. */
484
485 out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples);
486 out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples);
487
488 /*
489 * Assign ranges to corresponding nodes according to quadrants relative to
490 * the "centroid" range
491 */
492 for (i = 0; i < in->nTuples; i++)
493 {
494 BOX *box = DatumGetBoxP(in->datums[i]);
495 uint8 quadrant = getQuadrant(centroid, box);
496
497 out->leafTupleDatums[i] = BoxPGetDatum(box);
498 out->mapTuplesToNodes[i] = quadrant;
499 }
500
502}
static int compareDoubles(const void *a, const void *b)
Definition: geo_spgist.c:93
#define qsort(a, b, c, d)
Definition: port.h:474
Datum * datums
Definition: spgist.h:113
bool hasPrefix
Definition: spgist.h:119
int * mapTuplesToNodes
Definition: spgist.h:125
Datum * nodeLabels
Definition: spgist.h:123
Datum * leafTupleDatums
Definition: spgist.h:126
Datum prefixDatum
Definition: spgist.h:120

References BoxPGetDatum(), compareDoubles(), DatumGetBoxP(), spgPickSplitIn::datums, getQuadrant(), spgPickSplitOut::hasPrefix, BOX::high, i, spgPickSplitOut::leafTupleDatums, BOX::low, spgPickSplitOut::mapTuplesToNodes, spgPickSplitOut::nNodes, spgPickSplitOut::nodeLabels, spgPickSplitIn::nTuples, palloc(), PG_GETARG_POINTER, PG_RETURN_VOID, spgPickSplitOut::prefixDatum, qsort, Point::x, and Point::y.

◆ spg_poly_quad_compress()

Datum spg_poly_quad_compress ( PG_FUNCTION_ARGS  )

Definition at line 876 of file geo_spgist.c.

877{
878 POLYGON *polygon = PG_GETARG_POLYGON_P(0);
879 BOX *box;
880
881 box = (BOX *) palloc(sizeof(BOX));
882 *box = polygon->boundbox;
883
884 PG_RETURN_BOX_P(box);
885}
#define PG_RETURN_BOX_P(x)
Definition: geo_decls.h:244
#define PG_GETARG_POLYGON_P(n)
Definition: geo_decls.h:261

References POLYGON::boundbox, palloc(), PG_GETARG_POLYGON_P, and PG_RETURN_BOX_P.