~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/backend/access/rtree/rtproc.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * rtproc.c
 
4
 *        pg_amproc entries for rtrees.
 
5
 *
 
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.
 
12
 *
 
13
 *
 
14
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
 
15
 * Portions Copyright (c) 1994, Regents of the University of California
 
16
 *
 
17
 * IDENTIFICATION
 
18
 *        $PostgreSQL: pgsql/src/backend/access/rtree/rtproc.c,v 1.42 2004-12-31 21:59:26 pgsql Exp $
 
19
 *
 
20
 *-------------------------------------------------------------------------
 
21
 */
 
22
 
 
23
#include "postgres.h"
 
24
 
 
25
#include "utils/geo_decls.h"
 
26
 
 
27
 
 
28
Datum
 
29
rt_box_union(PG_FUNCTION_ARGS)
 
30
{
 
31
        BOX                *a = PG_GETARG_BOX_P(0);
 
32
        BOX                *b = PG_GETARG_BOX_P(1);
 
33
        BOX                *n;
 
34
 
 
35
        n = (BOX *) palloc(sizeof(BOX));
 
36
 
 
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);
 
41
 
 
42
        PG_RETURN_BOX_P(n);
 
43
}
 
44
 
 
45
Datum
 
46
rt_box_inter(PG_FUNCTION_ARGS)
 
47
{
 
48
        BOX                *a = PG_GETARG_BOX_P(0);
 
49
        BOX                *b = PG_GETARG_BOX_P(1);
 
50
        BOX                *n;
 
51
 
 
52
        n = (BOX *) palloc(sizeof(BOX));
 
53
 
 
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);
 
58
 
 
59
        if (n->high.x < n->low.x || n->high.y < n->low.y)
 
60
        {
 
61
                pfree(n);
 
62
                /* Indicate "no intersection" by returning NULL pointer */
 
63
                n = NULL;
 
64
        }
 
65
 
 
66
        PG_RETURN_BOX_P(n);
 
67
}
 
68
 
 
69
Datum
 
70
rt_box_size(PG_FUNCTION_ARGS)
 
71
{
 
72
        BOX                *a = PG_GETARG_BOX_P(0);
 
73
 
 
74
        /* NB: size is an output argument */
 
75
        float      *size = (float *) PG_GETARG_POINTER(1);
 
76
 
 
77
        if (a == NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
 
78
                *size = 0.0;
 
79
        else
 
80
                *size = (float) ((a->high.x - a->low.x) * (a->high.y - a->low.y));
 
81
 
 
82
        PG_RETURN_VOID();
 
83
}
 
84
 
 
85
Datum
 
86
rt_poly_union(PG_FUNCTION_ARGS)
 
87
{
 
88
        POLYGON    *a = PG_GETARG_POLYGON_P(0);
 
89
        POLYGON    *b = PG_GETARG_POLYGON_P(1);
 
90
        POLYGON    *p;
 
91
 
 
92
        p = (POLYGON *) palloc0(sizeof(POLYGON));       /* zero any holes */
 
93
        p->size = sizeof(POLYGON);
 
94
        p->npts = 0;
 
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);
 
99
 
 
100
        /* Avoid leaking memory when handed toasted input. */
 
101
        PG_FREE_IF_COPY(a, 0);
 
102
        PG_FREE_IF_COPY(b, 1);
 
103
 
 
104
        PG_RETURN_POLYGON_P(p);
 
105
}
 
106
 
 
107
Datum
 
108
rt_poly_inter(PG_FUNCTION_ARGS)
 
109
{
 
110
        POLYGON    *a = PG_GETARG_POLYGON_P(0);
 
111
        POLYGON    *b = PG_GETARG_POLYGON_P(1);
 
112
        POLYGON    *p;
 
113
 
 
114
        p = (POLYGON *) palloc0(sizeof(POLYGON));       /* zero any holes */
 
115
        p->size = sizeof(POLYGON);
 
116
        p->npts = 0;
 
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);
 
121
 
 
122
        if (p->boundbox.high.x < p->boundbox.low.x ||
 
123
                p->boundbox.high.y < p->boundbox.low.y)
 
124
        {
 
125
                pfree(p);
 
126
                /* Indicate "no intersection" by returning NULL pointer */
 
127
                p = NULL;
 
128
        }
 
129
 
 
130
        /* Avoid leaking memory when handed toasted input. */
 
131
        PG_FREE_IF_COPY(a, 0);
 
132
        PG_FREE_IF_COPY(b, 1);
 
133
 
 
134
        PG_RETURN_POLYGON_P(p);
 
135
}
 
136
 
 
137
Datum
 
138
rt_poly_size(PG_FUNCTION_ARGS)
 
139
{
 
140
        Pointer         aptr = PG_GETARG_POINTER(0);
 
141
 
 
142
        /* NB: size is an output argument */
 
143
        float      *size = (float *) PG_GETARG_POINTER(1);
 
144
        POLYGON    *a;
 
145
        double          xdim,
 
146
                                ydim;
 
147
 
 
148
        /*
 
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
 
151
         */
 
152
        if (aptr == NULL)
 
153
        {
 
154
                *size = 0.0;
 
155
                PG_RETURN_VOID();
 
156
        }
 
157
        /* Now safe to apply GETARG */
 
158
        a = PG_GETARG_POLYGON_P(0);
 
159
 
 
160
        if (a->boundbox.high.x <= a->boundbox.low.x ||
 
161
                a->boundbox.high.y <= a->boundbox.low.y)
 
162
                *size = 0.0;
 
163
        else
 
164
        {
 
165
                xdim = (a->boundbox.high.x - a->boundbox.low.x);
 
166
                ydim = (a->boundbox.high.y - a->boundbox.low.y);
 
167
 
 
168
                *size = (float) (xdim * ydim);
 
169
        }
 
170
 
 
171
        /* Avoid leaking memory when handed toasted input. */
 
172
        PG_FREE_IF_COPY(a, 0);
 
173
 
 
174
        PG_RETURN_VOID();
 
175
}