PostGIS  2.5.0dev-r@@SVN_REVISION@@
lwgeom_btree.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright (C) 2010 Olivier Courtin <olivier.courtin@oslandia.com>
22  * Copyright (C) 2010 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
23  * Copyright (C) 2009-2011 Paul Ramsey <pramsey@cleverelephant.ca>
24  *
25  **********************************************************************/
26 
27 
28 #include "postgres.h"
29 #include "fmgr.h"
30 #include "access/hash.h"
31 #include "utils/geo_decls.h"
32 
33 #include "../postgis_config.h"
34 #include "liblwgeom.h"
35 #include "lwgeom_pg.h"
36 
37 #include <math.h>
38 #include <float.h>
39 #include <string.h>
40 #include <stdio.h>
41 #include <errno.h>
42 
43 Datum lwgeom_lt(PG_FUNCTION_ARGS);
44 Datum lwgeom_le(PG_FUNCTION_ARGS);
45 Datum lwgeom_eq(PG_FUNCTION_ARGS);
46 Datum lwgeom_ge(PG_FUNCTION_ARGS);
47 Datum lwgeom_gt(PG_FUNCTION_ARGS);
48 Datum lwgeom_cmp(PG_FUNCTION_ARGS);
49 
51 Datum lwgeom_lt(PG_FUNCTION_ARGS)
52 {
53  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
54  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
55  int cmp = gserialized_cmp(g1, g2);
56  PG_FREE_IF_COPY(g1, 0);
57  PG_FREE_IF_COPY(g2, 1);
58  if (cmp < 0)
59  PG_RETURN_BOOL(true);
60  else
61  PG_RETURN_BOOL(false);
62 }
63 
65 Datum lwgeom_le(PG_FUNCTION_ARGS)
66 {
67  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
68  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
69  int cmp = gserialized_cmp(g1, g2);
70  PG_FREE_IF_COPY(g1, 0);
71  PG_FREE_IF_COPY(g2, 1);
72  if (cmp == 0)
73  PG_RETURN_BOOL(true);
74  else
75  PG_RETURN_BOOL(false);
76 }
77 
79 Datum lwgeom_eq(PG_FUNCTION_ARGS)
80 {
81  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
82  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
83  int cmp = gserialized_cmp(g1, g2);
84  PG_FREE_IF_COPY(g1, 0);
85  PG_FREE_IF_COPY(g2, 1);
86  if (cmp == 0)
87  PG_RETURN_BOOL(true);
88  else
89  PG_RETURN_BOOL(false);
90 }
91 
93 Datum lwgeom_ge(PG_FUNCTION_ARGS)
94 {
95  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
96  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
97  int cmp = gserialized_cmp(g1, g2);
98  PG_FREE_IF_COPY(g1, 0);
99  PG_FREE_IF_COPY(g2, 1);
100  if (cmp >= 0)
101  PG_RETURN_BOOL(true);
102  else
103  PG_RETURN_BOOL(false);
104 }
105 
107 Datum lwgeom_gt(PG_FUNCTION_ARGS)
108 {
109  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
110  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
111  int cmp = gserialized_cmp(g1, g2);
112  PG_FREE_IF_COPY(g1, 0);
113  PG_FREE_IF_COPY(g2, 1);
114  if (cmp > 0)
115  PG_RETURN_BOOL(true);
116  else
117  PG_RETURN_BOOL(false);
118 }
119 
121 Datum lwgeom_cmp(PG_FUNCTION_ARGS)
122 {
123  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
124  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
125  int ret = gserialized_cmp(g1, g2);
126  PG_FREE_IF_COPY(g1, 0);
127  PG_FREE_IF_COPY(g2, 1);
128  PG_RETURN_INT32(ret);
129 }
130 
132 Datum lwgeom_hash(PG_FUNCTION_ARGS)
133 {
134  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
135  /* Point to just the type/coordinate part of buffer */
136  size_t hsz1 = gserialized_header_size(g1);
137  uint8_t *b1 = (uint8_t*)g1 + hsz1;
138  /* Calculate size of type/coordinate buffer */
139  size_t sz1 = VARSIZE(g1);
140  size_t bsz1 = sz1 - hsz1;
141  /* Calculate size of srid/type/coordinate buffer */
142  int srid = gserialized_get_srid(g1);
143  size_t bsz2 = bsz1 + sizeof(int);
144  uint8_t *b2 = palloc(bsz2);
145  /* Copy srid into front of combined buffer */
146  memcpy(b2, &srid, sizeof(int));
147  /* Copy type/coordinates into rest of combined buffer */
148  memcpy(b2+sizeof(int), b1, bsz1);
149  /* Hash combined buffer */
150  Datum hval = hash_any(b2, bsz2);
151  pfree(b2);
152  PG_FREE_IF_COPY(g1, 0);
153  PG_RETURN_DATUM(hval);
154 }
155 
156 
157 
int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2)
Return -1 if g1 is "less than" g2, 1 if g1 is "greater than" g2 and 0 if g1 and g2 are the "same"...
Definition: g_serialized.c:293
Datum lwgeom_eq(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:79
Datum lwgeom_hash(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:132
Datum lwgeom_le(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:65
Datum lwgeom_lt(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:51
Datum lwgeom_cmp(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:121
Datum lwgeom_gt(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:107
uint32_t gserialized_header_size(const GSERIALIZED *gser)
Returns the size in bytes of the header, from the start of the object up to the type number...
Definition: g_serialized.c:76
unsigned char uint8_t
Definition: uthash.h:79
PG_FUNCTION_INFO_V1(lwgeom_lt)
Datum lwgeom_ge(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:93
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: g_serialized.c:99
This library is the generic geometry handling section of PostGIS.