PostgreSQL Source Code  git master
spgproc.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * spgproc.c
4  * Common supporting procedures for SP-GiST opclasses.
5  *
6  *
7  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * IDENTIFICATION
11  * src/backend/access/spgist/spgproc.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include <math.h>
19 
20 #include "access/spgist_private.h"
21 #include "utils/builtins.h"
22 #include "utils/float.h"
23 #include "utils/geo_decls.h"
24 
25 #define point_point_distance(p1,p2) \
26  DatumGetFloat8(DirectFunctionCall2(point_distance, \
27  PointPGetDatum(p1), PointPGetDatum(p2)))
28 
29 /* Point-box distance in the assumption that box is aligned by axis */
30 static double
32 {
33  double dx,
34  dy;
35 
36  if (isnan(point->x) || isnan(box->low.x) ||
37  isnan(point->y) || isnan(box->low.y))
38  return get_float8_nan();
39 
40  if (point->x < box->low.x)
41  dx = box->low.x - point->x;
42  else if (point->x > box->high.x)
43  dx = point->x - box->high.x;
44  else
45  dx = 0.0;
46 
47  if (point->y < box->low.y)
48  dy = box->low.y - point->y;
49  else if (point->y > box->high.y)
50  dy = point->y - box->high.y;
51  else
52  dy = 0.0;
53 
54  return HYPOT(dx, dy);
55 }
56 
57 /*
58  * Returns distances from given key to array of ordering scan keys. Leaf key
59  * is expected to be point, non-leaf key is expected to be box. Scan key
60  * arguments are expected to be points.
61  */
62 double *
64  ScanKey orderbys, int norderbys)
65 {
66  int sk_num;
67  double *distances = (double *) palloc(norderbys * sizeof(double)),
68  *distance = distances;
69 
70  for (sk_num = 0; sk_num < norderbys; ++sk_num, ++orderbys, ++distance)
71  {
72  Point *point = DatumGetPointP(orderbys->sk_argument);
73 
74  *distance = isLeaf ? point_point_distance(point, DatumGetPointP(key))
75  : point_box_distance(point, DatumGetBoxP(key));
76  }
77 
78  return distances;
79 }
80 
81 BOX *
82 box_copy(BOX *orig)
83 {
84  BOX *result = palloc(sizeof(BOX));
85 
86  *result = *orig;
87  return result;
88 }
Definition: geo_decls.h:99
float8 x
Definition: geo_decls.h:57
static float8 get_float8_nan(void)
Definition: float.h:119
#define point_point_distance(p1, p2)
Definition: spgproc.c:25
Point low
Definition: geo_decls.h:101
uintptr_t Datum
Definition: postgres.h:367
#define HYPOT(A, B)
Definition: geo_decls.h:50
BOX * box_copy(BOX *orig)
Definition: spgproc.c:82
float8 y
Definition: geo_decls.h:57
#define DatumGetPointP(X)
Definition: geo_decls.h:134
#define DatumGetBoxP(X)
Definition: geo_decls.h:156
Point high
Definition: geo_decls.h:101
void * palloc(Size size)
Definition: mcxt.c:949
double * spg_key_orderbys_distances(Datum key, bool isLeaf, ScanKey orderbys, int norderbys)
Definition: spgproc.c:63
static double point_box_distance(Point *point, BOX *box)
Definition: spgproc.c:31