/src/postgres/src/backend/access/spgist/spgproc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * spgproc.c |
4 | | * Common supporting procedures for SP-GiST opclasses. |
5 | | * |
6 | | * |
7 | | * Portions Copyright (c) 1996-2025, 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 | 0 | DatumGetFloat8(DirectFunctionCall2(point_distance, \ |
27 | 0 | PointPGetDatum(p1), PointPGetDatum(p2))) |
28 | | |
29 | | /* Point-box distance in the assumption that box is aligned by axis */ |
30 | | static double |
31 | | point_box_distance(Point *point, BOX *box) |
32 | 0 | { |
33 | 0 | double dx, |
34 | 0 | dy; |
35 | |
|
36 | 0 | if (isnan(point->x) || isnan(box->low.x) || |
37 | 0 | isnan(point->y) || isnan(box->low.y)) |
38 | 0 | return get_float8_nan(); |
39 | | |
40 | 0 | if (point->x < box->low.x) |
41 | 0 | dx = box->low.x - point->x; |
42 | 0 | else if (point->x > box->high.x) |
43 | 0 | dx = point->x - box->high.x; |
44 | 0 | else |
45 | 0 | dx = 0.0; |
46 | |
|
47 | 0 | if (point->y < box->low.y) |
48 | 0 | dy = box->low.y - point->y; |
49 | 0 | else if (point->y > box->high.y) |
50 | 0 | dy = point->y - box->high.y; |
51 | 0 | else |
52 | 0 | dy = 0.0; |
53 | |
|
54 | 0 | return HYPOT(dx, dy); |
55 | 0 | } |
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 | | spg_key_orderbys_distances(Datum key, bool isLeaf, |
64 | | ScanKey orderbys, int norderbys) |
65 | 0 | { |
66 | 0 | int sk_num; |
67 | 0 | double *distances = (double *) palloc(norderbys * sizeof(double)), |
68 | 0 | *distance = distances; |
69 | |
|
70 | 0 | for (sk_num = 0; sk_num < norderbys; ++sk_num, ++orderbys, ++distance) |
71 | 0 | { |
72 | 0 | Point *point = DatumGetPointP(orderbys->sk_argument); |
73 | |
|
74 | 0 | *distance = isLeaf ? point_point_distance(point, DatumGetPointP(key)) |
75 | 0 | : point_box_distance(point, DatumGetBoxP(key)); |
76 | 0 | } |
77 | |
|
78 | 0 | return distances; |
79 | 0 | } |
80 | | |
81 | | BOX * |
82 | | box_copy(BOX *orig) |
83 | 0 | { |
84 | 0 | BOX *result = palloc(sizeof(BOX)); |
85 | |
|
86 | 0 | *result = *orig; |
87 | 0 | return result; |
88 | 0 | } |