Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * spgproc.c
4 : : * Common supporting procedures for SP-GiST opclasses.
5 : : *
6 : : *
7 : : * Portions Copyright (c) 1996-2024, 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/float.h"
22 : : #include "utils/fmgrprotos.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
2034 akorotkov@postgresql 31 :CBC 47052 : point_box_distance(Point *point, BOX *box)
32 : : {
33 : : double dx,
34 : : dy;
35 : :
36 [ + - + - ]: 47052 : if (isnan(point->x) || isnan(box->low.x) ||
37 [ + - - + ]: 47052 : isnan(point->y) || isnan(box->low.y))
2034 akorotkov@postgresql 38 :UBC 0 : return get_float8_nan();
39 : :
2034 akorotkov@postgresql 40 [ + + ]:CBC 47052 : if (point->x < box->low.x)
41 : 42834 : dx = box->low.x - point->x;
42 [ + + ]: 4218 : else if (point->x > box->high.x)
43 : 3330 : dx = point->x - box->high.x;
44 : : else
45 : 888 : dx = 0.0;
46 : :
47 [ + + ]: 47052 : if (point->y < box->low.y)
48 : 22632 : dy = box->low.y - point->y;
49 [ + + ]: 24420 : else if (point->y > box->high.y)
50 : 23862 : dy = point->y - box->high.y;
51 : : else
52 : 558 : dy = 0.0;
53 : :
54 : 47052 : 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 *
63 : 186624 : spg_key_orderbys_distances(Datum key, bool isLeaf,
64 : : ScanKey orderbys, int norderbys)
65 : : {
66 : : int sk_num;
67 : 186624 : double *distances = (double *) palloc(norderbys * sizeof(double)),
68 : 186624 : *distance = distances;
69 : :
70 [ + + ]: 374202 : for (sk_num = 0; sk_num < norderbys; ++sk_num, ++orderbys, ++distance)
71 : : {
72 : 187578 : Point *point = DatumGetPointP(orderbys->sk_argument);
73 : :
74 : 187578 : *distance = isLeaf ? point_point_distance(point, DatumGetPointP(key))
75 [ + + ]: 187578 : : point_box_distance(point, DatumGetBoxP(key));
76 : : }
77 : :
78 : 186624 : return distances;
79 : : }
80 : :
81 : : BOX *
82 : 2001 : box_copy(BOX *orig)
83 : : {
84 : 2001 : BOX *result = palloc(sizeof(BOX));
85 : :
86 : 2001 : *result = *orig;
87 : 2001 : return result;
88 : : }
|