PostGIS  3.7.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 #include "utils/sortsupport.h" /* SortSupport */
33 
34 #include "../postgis_config.h"
35 #include "liblwgeom.h"
36 #include "lwgeom_pg.h"
37 
38 #include <math.h>
39 #include <float.h>
40 #include <string.h>
41 #include <stdio.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_neq(PG_FUNCTION_ARGS);
47 Datum lwgeom_ge(PG_FUNCTION_ARGS);
48 Datum lwgeom_gt(PG_FUNCTION_ARGS);
49 Datum lwgeom_cmp(PG_FUNCTION_ARGS);
50 
52 Datum lwgeom_lt(PG_FUNCTION_ARGS)
53 {
54  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
55  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
56  int cmp = gserialized_cmp(g1, g2);
57  PG_FREE_IF_COPY(g1, 0);
58  PG_FREE_IF_COPY(g2, 1);
59  PG_RETURN_BOOL(cmp < 0);
60 }
61 
63 Datum lwgeom_le(PG_FUNCTION_ARGS)
64 {
65  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
66  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
67  int cmp = gserialized_cmp(g1, g2);
68  PG_FREE_IF_COPY(g1, 0);
69  PG_FREE_IF_COPY(g2, 1);
70  PG_RETURN_BOOL(cmp <= 0);
71 }
72 
74 Datum lwgeom_eq(PG_FUNCTION_ARGS)
75 {
76  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
77  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
78  int cmp = gserialized_cmp(g1, g2);
79  PG_FREE_IF_COPY(g1, 0);
80  PG_FREE_IF_COPY(g2, 1);
81  PG_RETURN_BOOL(cmp == 0);
82 }
83 
85 Datum lwgeom_neq(PG_FUNCTION_ARGS)
86 {
87  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
88  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
89  int cmp = gserialized_cmp(g1, g2);
90  PG_FREE_IF_COPY(g1, 0);
91  PG_FREE_IF_COPY(g2, 1);
92  PG_RETURN_BOOL(cmp != 0);
93 }
94 
96 Datum lwgeom_ge(PG_FUNCTION_ARGS)
97 {
98  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
99  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
100  int cmp = gserialized_cmp(g1, g2);
101  PG_FREE_IF_COPY(g1, 0);
102  PG_FREE_IF_COPY(g2, 1);
103  PG_RETURN_BOOL(cmp >= 0);
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  PG_RETURN_BOOL(cmp > 0);
115 }
116 
118 Datum lwgeom_cmp(PG_FUNCTION_ARGS)
119 {
120  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
121  GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
122  int ret = gserialized_cmp(g1, g2);
123  PG_FREE_IF_COPY(g1, 0);
124  PG_FREE_IF_COPY(g2, 1);
125  PG_RETURN_INT32(ret);
126 }
127 
129 Datum lwgeom_hash(PG_FUNCTION_ARGS)
130 {
131  GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
132 
133  int32_t hval = gserialized_hash(g1);
134  PG_FREE_IF_COPY(g1, 0);
135  PG_RETURN_INT32(hval);
136 }
137 
138 static int
139 lwgeom_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
140 {
141  /* Empty is a special case */
142  if (x == 0 || y == 0 || x == y)
143  return 0; /* 0 means "ask bigger comparator" and not equality*/
144  else if (x > y)
145  return 1;
146  else
147  return -1;
148 }
149 
150 static int
151 lwgeom_cmp_full(Datum x, Datum y, SortSupport ssup)
152 {
153  GSERIALIZED *g1 = (GSERIALIZED *)PG_DETOAST_DATUM(x);
154  GSERIALIZED *g2 = (GSERIALIZED *)PG_DETOAST_DATUM(y);
155  int ret = gserialized_cmp(g1, g2);
158  return ret;
159 }
160 
161 static bool
162 lwgeom_abbrev_abort(int memtupcount, SortSupport ssup)
163 {
164  return LW_FALSE;
165 }
166 
167 static Datum
168 lwgeom_abbrev_convert(Datum original, SortSupport ssup)
169 {
170  GSERIALIZED *g = (GSERIALIZED *)PG_DETOAST_DATUM(original);
171  uint64_t hash = gserialized_get_sortable_hash(g);
172  POSTGIS_FREE_IF_COPY_P(g, original);
173  return hash;
174 }
175 
176 /*
177  * Sort support strategy routine
178  */
180 Datum lwgeom_sortsupport(PG_FUNCTION_ARGS)
181 {
182  SortSupport ssup = (SortSupport)PG_GETARG_POINTER(0);
183 
184  ssup->comparator = lwgeom_cmp_full;
185  ssup->ssup_extra = NULL;
186  /* Enable sortsupport only on 64 bit Datum */
187  if (ssup->abbreviate && sizeof(Datum) == 8)
188  {
189  ssup->comparator = lwgeom_cmp_abbrev;
190  ssup->abbrev_converter = lwgeom_abbrev_convert;
191  ssup->abbrev_abort = lwgeom_abbrev_abort;
192  ssup->abbrev_full_comparator = lwgeom_cmp_full;
193  }
194 
195  PG_RETURN_VOID();
196 }
uint64_t gserialized_get_sortable_hash(const GSERIALIZED *g)
Return a sortable key based on gserialized.
Definition: gserialized.c:419
int32_t gserialized_hash(const GSERIALIZED *g)
Returns a hash code for the srid/type/geometry information in the GSERIALIZED.
Definition: gserialized.c:143
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: gserialized.c:342
#define LW_FALSE
Definition: liblwgeom.h:94
This library is the generic geometry handling section of PostGIS.
Datum lwgeom_sortsupport(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:180
Datum lwgeom_lt(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:52
PG_FUNCTION_INFO_V1(lwgeom_lt)
Datum lwgeom_cmp(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:118
Datum lwgeom_ge(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:96
Datum lwgeom_gt(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:107
Datum lwgeom_neq(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:85
static bool lwgeom_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: lwgeom_btree.c:162
static int lwgeom_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
Definition: lwgeom_btree.c:139
Datum lwgeom_eq(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:74
Datum lwgeom_le(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:63
static Datum lwgeom_abbrev_convert(Datum original, SortSupport ssup)
Definition: lwgeom_btree.c:168
static int lwgeom_cmp_full(Datum x, Datum y, SortSupport ssup)
Definition: lwgeom_btree.c:151
Datum lwgeom_hash(PG_FUNCTION_ARGS)
Definition: lwgeom_btree.c:129
#define POSTGIS_FREE_IF_COPY_P(ptrsrc, ptrori)
Definition: lwinline.h:340