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-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
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 */
30static 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 */
62double *
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))
76 }
77
78 return distances;
79}
80
81BOX *
83{
84 BOX *result = palloc(sizeof(BOX));
85
86 *result = *orig;
87 return result;
88}
static float8 get_float8_nan(void)
Definition: float.h:123
#define HYPOT(A, B)
Definition: geo_decls.h:91
static Point * DatumGetPointP(Datum X)
Definition: geo_decls.h:176
static BOX * DatumGetBoxP(Datum X)
Definition: geo_decls.h:234
void * palloc(Size size)
Definition: mcxt.c:1943
uintptr_t Datum
Definition: postgres.h:69
BOX * box_copy(BOX *orig)
Definition: spgproc.c:82
#define point_point_distance(p1, p2)
Definition: spgproc.c:25
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
Definition: geo_decls.h:141
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
Datum sk_argument
Definition: skey.h:72