1
/*-------------------------------------------------------------------------
4
* pg_amproc entries for rtrees.
6
* NOTE: for largely-historical reasons, the intersection functions should
7
* return a NULL pointer (*not* an SQL null value) to indicate "no
8
* intersection". The size functions must be prepared to accept such
9
* a pointer and return 0. This convention means that only pass-by-reference
10
* data types can be used as the output of the union and intersection
11
* routines, but that's not a big problem.
14
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
15
* Portions Copyright (c) 1994, Regents of the University of California
18
* $PostgreSQL: pgsql/src/backend/access/rtree/rtproc.c,v 1.42 2004-12-31 21:59:26 pgsql Exp $
20
*-------------------------------------------------------------------------
25
#include "utils/geo_decls.h"
29
rt_box_union(PG_FUNCTION_ARGS)
31
BOX *a = PG_GETARG_BOX_P(0);
32
BOX *b = PG_GETARG_BOX_P(1);
35
n = (BOX *) palloc(sizeof(BOX));
37
n->high.x = Max(a->high.x, b->high.x);
38
n->high.y = Max(a->high.y, b->high.y);
39
n->low.x = Min(a->low.x, b->low.x);
40
n->low.y = Min(a->low.y, b->low.y);
46
rt_box_inter(PG_FUNCTION_ARGS)
48
BOX *a = PG_GETARG_BOX_P(0);
49
BOX *b = PG_GETARG_BOX_P(1);
52
n = (BOX *) palloc(sizeof(BOX));
54
n->high.x = Min(a->high.x, b->high.x);
55
n->high.y = Min(a->high.y, b->high.y);
56
n->low.x = Max(a->low.x, b->low.x);
57
n->low.y = Max(a->low.y, b->low.y);
59
if (n->high.x < n->low.x || n->high.y < n->low.y)
62
/* Indicate "no intersection" by returning NULL pointer */
70
rt_box_size(PG_FUNCTION_ARGS)
72
BOX *a = PG_GETARG_BOX_P(0);
74
/* NB: size is an output argument */
75
float *size = (float *) PG_GETARG_POINTER(1);
77
if (a == NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
80
*size = (float) ((a->high.x - a->low.x) * (a->high.y - a->low.y));
86
rt_poly_union(PG_FUNCTION_ARGS)
88
POLYGON *a = PG_GETARG_POLYGON_P(0);
89
POLYGON *b = PG_GETARG_POLYGON_P(1);
92
p = (POLYGON *) palloc0(sizeof(POLYGON)); /* zero any holes */
93
p->size = sizeof(POLYGON);
95
p->boundbox.high.x = Max(a->boundbox.high.x, b->boundbox.high.x);
96
p->boundbox.high.y = Max(a->boundbox.high.y, b->boundbox.high.y);
97
p->boundbox.low.x = Min(a->boundbox.low.x, b->boundbox.low.x);
98
p->boundbox.low.y = Min(a->boundbox.low.y, b->boundbox.low.y);
100
/* Avoid leaking memory when handed toasted input. */
101
PG_FREE_IF_COPY(a, 0);
102
PG_FREE_IF_COPY(b, 1);
104
PG_RETURN_POLYGON_P(p);
108
rt_poly_inter(PG_FUNCTION_ARGS)
110
POLYGON *a = PG_GETARG_POLYGON_P(0);
111
POLYGON *b = PG_GETARG_POLYGON_P(1);
114
p = (POLYGON *) palloc0(sizeof(POLYGON)); /* zero any holes */
115
p->size = sizeof(POLYGON);
117
p->boundbox.high.x = Min(a->boundbox.high.x, b->boundbox.high.x);
118
p->boundbox.high.y = Min(a->boundbox.high.y, b->boundbox.high.y);
119
p->boundbox.low.x = Max(a->boundbox.low.x, b->boundbox.low.x);
120
p->boundbox.low.y = Max(a->boundbox.low.y, b->boundbox.low.y);
122
if (p->boundbox.high.x < p->boundbox.low.x ||
123
p->boundbox.high.y < p->boundbox.low.y)
126
/* Indicate "no intersection" by returning NULL pointer */
130
/* Avoid leaking memory when handed toasted input. */
131
PG_FREE_IF_COPY(a, 0);
132
PG_FREE_IF_COPY(b, 1);
134
PG_RETURN_POLYGON_P(p);
138
rt_poly_size(PG_FUNCTION_ARGS)
140
Pointer aptr = PG_GETARG_POINTER(0);
142
/* NB: size is an output argument */
143
float *size = (float *) PG_GETARG_POINTER(1);
149
* Can't just use GETARG because of possibility that input is NULL;
150
* since POLYGON is toastable, GETARG will try to inspect its value
157
/* Now safe to apply GETARG */
158
a = PG_GETARG_POLYGON_P(0);
160
if (a->boundbox.high.x <= a->boundbox.low.x ||
161
a->boundbox.high.y <= a->boundbox.low.y)
165
xdim = (a->boundbox.high.x - a->boundbox.low.x);
166
ydim = (a->boundbox.high.y - a->boundbox.low.y);
168
*size = (float) (xdim * ydim);
171
/* Avoid leaking memory when handed toasted input. */
172
PG_FREE_IF_COPY(a, 0);