OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetGeoSerialization.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
23 #ifndef QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
24 #define QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
25 
26 #include "Geospatial/Compression.h"
27 #include "Geospatial/Types.h"
28 #include "QueryEngine/ResultSet.h"
30 #include "Shared/sqltypes.h"
31 
32 using VarlenDatumPtr = std::unique_ptr<VarlenDatum>;
33 
34 using namespace Geospatial;
35 
36 template <SQLTypes GEO_SOURCE_TYPE>
38  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for target value serializer.");
39 };
40 
41 template <SQLTypes GEO_SOURCE_TYPE>
43  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for wkt serializer.");
44 };
45 
46 template <SQLTypes GEO_SOURCE_TYPE>
48  static_assert(IS_GEO(GEO_SOURCE_TYPE),
49  "Invalid geo type for target value ptr serializer.");
50 };
51 
52 template <ResultSet::GeoReturnType GEO_RETURN_TYPE, SQLTypes GEO_SOURCE_TYPE>
54  static_assert(GEO_RETURN_TYPE == ResultSet::GeoReturnType::GeoTargetValue ||
55  GEO_RETURN_TYPE == ResultSet::GeoReturnType::WktString ||
57  "ResultSet: Unrecognized Geo Return Type encountered.");
58 };
59 
60 template <SQLTypes GEO_SOURCE_TYPE>
61 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValue, GEO_SOURCE_TYPE> {
63 };
64 
65 template <SQLTypes GEO_SOURCE_TYPE>
66 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::WktString, GEO_SOURCE_TYPE> {
68 };
69 
70 template <SQLTypes GEO_SOURCE_TYPE>
71 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValuePtr, GEO_SOURCE_TYPE> {
73 };
74 
75 // Point
76 template <>
78  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
79  std::array<VarlenDatumPtr, 1>& vals) {
80  if (!geo_ti.get_notnull() && vals[0]->is_null) {
81  // Alternatively, could decompress vals[0] and check for NULL array sentinel
82  return GeoTargetValue(boost::optional<GeoPointTargetValue>{});
83  }
84  return GeoTargetValue(
85  boost::optional<GeoPointTargetValue>{*decompress_coords<double, SQLTypeInfo>(
86  geo_ti, vals[0]->pointer, vals[0]->length)});
87  }
88 };
89 
90 template <>
92  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
93  std::array<VarlenDatumPtr, 1>& vals) {
94  // TODO: support EMPTY geo and serialize it as GEOMETRYCOLLECTION EMPTY
95  if (!geo_ti.get_notnull() && vals[0]->is_null) {
96  return NullableString("NULL");
97  }
99  geo_ti, vals[0]->pointer, vals[0]->length));
100  return NullableString(point.getWktString());
101  }
102 };
103 
104 template <>
106  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
107  std::array<VarlenDatumPtr, 1>& vals) {
108  if (!geo_ti.get_notnull() && vals[0]->is_null) {
109  // NULL geo
110  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
111  // return GeoTargetValuePtr();
112  }
113  return GeoPointTargetValuePtr({std::move(vals[0])});
114  }
115 };
116 
117 // MultiPoint
118 template <>
120  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
121  std::array<VarlenDatumPtr, 1>& vals) {
122  if (!geo_ti.get_notnull() && vals[0]->is_null) {
123  return GeoTargetValue(boost::optional<GeoMultiPointTargetValue>{});
124  }
125  return GeoTargetValue(
126  boost::optional<GeoMultiPointTargetValue>{*decompress_coords<double, SQLTypeInfo>(
127  geo_ti, vals[0]->pointer, vals[0]->length)});
128  }
129 };
130 
131 template <>
133  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
134  std::array<VarlenDatumPtr, 1>& vals) {
135  if (!geo_ti.get_notnull() && vals[0]->is_null) {
136  // May need to generate "MULTIPOINT EMPTY" instead of NULL
137  return NullableString("NULL");
138  }
140  geo_ti, vals[0]->pointer, vals[0]->length));
141  return NullableString(multipoint.getWktString());
142  }
143 };
144 
145 template <>
147  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
148  std::array<VarlenDatumPtr, 1>& vals) {
149  if (!geo_ti.get_notnull() && vals[0]->is_null) {
150  // NULL geo
151  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
152  // return GeoTargetValuePtr();
153  }
154  return GeoMultiPointTargetValuePtr({std::move(vals[0])});
155  }
156 };
157 
158 // LineString
159 template <>
161  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
162  std::array<VarlenDatumPtr, 1>& vals) {
163  if (!geo_ti.get_notnull() && vals[0]->is_null) {
164  return GeoTargetValue(boost::optional<GeoLineStringTargetValue>{});
165  }
166  return GeoTargetValue(
167  boost::optional<GeoLineStringTargetValue>{*decompress_coords<double, SQLTypeInfo>(
168  geo_ti, vals[0]->pointer, vals[0]->length)});
169  }
170 };
171 
172 template <>
174  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
175  std::array<VarlenDatumPtr, 1>& vals) {
176  if (!geo_ti.get_notnull() && vals[0]->is_null) {
177  // May need to generate "LINESTRING EMPTY" instead of NULL
178  return NullableString("NULL");
179  }
181  geo_ti, vals[0]->pointer, vals[0]->length));
182  return NullableString(linestring.getWktString());
183  }
184 };
185 
186 template <>
188  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
189  std::array<VarlenDatumPtr, 1>& vals) {
190  if (!geo_ti.get_notnull() && vals[0]->is_null) {
191  // NULL geo
192  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
193  // return GeoTargetValuePtr();
194  }
195  return GeoLineStringTargetValuePtr({std::move(vals[0])});
196  }
197 };
198 
199 // MultiLineString
200 template <>
202  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
203  std::array<VarlenDatumPtr, 2>& vals) {
204  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
205  return GeoTargetValue(boost::optional<GeoMultiLineStringTargetValue>{});
206  }
207  std::vector<int32_t> linestring_sizes_vec;
208  unpack_geo_vector(linestring_sizes_vec, vals[1]->pointer, vals[1]->length);
209  auto gtv =
211  geo_ti, vals[0]->pointer, vals[0]->length),
212  linestring_sizes_vec);
213  return GeoTargetValue(gtv);
214  }
215 };
216 
217 template <>
219  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
220  std::array<VarlenDatumPtr, 2>& vals) {
221  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
222  // May need to generate "MULTILINESTRING EMPTY" instead of NULL
223  return NullableString("NULL");
224  }
225  std::vector<int32_t> linestring_sizes_vec;
226  unpack_geo_vector(linestring_sizes_vec, vals[1]->pointer, vals[1]->length);
228  geo_ti, vals[0]->pointer, vals[0]->length),
229  linestring_sizes_vec);
230  return NullableString(mls.getWktString());
231  };
232 };
233 
234 template <>
236  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
237  std::array<VarlenDatumPtr, 2>& vals) {
238  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
239  // NULL geo
240  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
241  // return GeoTargetValuePtr();
242  }
243  return GeoMultiLineStringTargetValuePtr({std::move(vals[0]), std::move(vals[1])});
244  }
245 };
246 
247 // Polygon
248 template <>
250  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
251  std::array<VarlenDatumPtr, 2>& vals) {
252  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
253  return GeoTargetValue(boost::optional<GeoPolyTargetValue>{});
254  }
255  std::vector<int32_t> ring_sizes_vec;
256  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
258  geo_ti, vals[0]->pointer, vals[0]->length),
259  ring_sizes_vec);
260  return GeoTargetValue(gtv);
261  }
262 };
263 
264 template <>
266  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
267  std::array<VarlenDatumPtr, 2>& vals) {
268  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
269  // May need to generate "POLYGON EMPTY" instead of NULL
270  return NullableString("NULL");
271  }
272  std::vector<int32_t> ring_sizes_vec;
273  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
275  geo_ti, vals[0]->pointer, vals[0]->length),
276  ring_sizes_vec);
277  return NullableString(poly.getWktString());
278  };
279 };
280 
281 template <>
283  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
284  std::array<VarlenDatumPtr, 2>& vals) {
285  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
286  // NULL geo
287  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
288  // return GeoTargetValuePtr();
289  }
290  return GeoPolyTargetValuePtr({std::move(vals[0]), std::move(vals[1])});
291  }
292 };
293 
294 // MultiPolygon
295 template <>
297  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
298  std::array<VarlenDatumPtr, 3>& vals) {
299  if (!geo_ti.get_notnull() &&
300  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
301  return GeoTargetValue(boost::optional<GeoMultiPolyTargetValue>{});
302  }
303  std::vector<int32_t> ring_sizes_vec;
304  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
305  std::vector<int32_t> poly_rings_vec;
306  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
308  geo_ti, vals[0]->pointer, vals[0]->length),
309  ring_sizes_vec,
310  poly_rings_vec);
311  return GeoTargetValue(gtv);
312  }
313 };
314 
315 template <>
317  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
318  std::array<VarlenDatumPtr, 3>& vals) {
319  if (!geo_ti.get_notnull() &&
320  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
321  // May need to generate "MULTIPOLYGON EMPTY" instead of NULL
322  return NullableString("NULL");
323  }
324  std::vector<int32_t> ring_sizes_vec;
325  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
326  std::vector<int32_t> poly_rings_vec;
327  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
329  geo_ti, vals[0]->pointer, vals[0]->length),
330  ring_sizes_vec,
331  poly_rings_vec);
332  return NullableString(mpoly.getWktString());
333  }
334 };
335 
336 template <>
338  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
339  std::array<VarlenDatumPtr, 3>& vals) {
340  if (!geo_ti.get_notnull() &&
341  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
342  // NULL geo
343  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
344  // return GeoTargetValuePtr();
345  }
347  {std::move(vals[0]), std::move(vals[1]), std::move(vals[2])});
348  }
349 };
350 
351 #endif // QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
High-level representation of SQL values.
Constants for Builtin SQL Types supported by HEAVY.AI.
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::shared_ptr< std::vector< double > > decompress_coords< double, SQLTypeInfo >(const SQLTypeInfo &geo_ti, const int8_t *coords, const size_t coords_sz)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
boost::optional< boost::variant< GeoPointTargetValue, GeoMultiPointTargetValue, GeoLineStringTargetValue, GeoMultiLineStringTargetValue, GeoPolyTargetValue, GeoMultiPolyTargetValue >> GeoTargetValue
Definition: TargetValue.h:187
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
boost::variant< GeoPointTargetValuePtr, GeoMultiPointTargetValuePtr, GeoLineStringTargetValuePtr, GeoMultiLineStringTargetValuePtr, GeoPolyTargetValuePtr, GeoMultiPolyTargetValuePtr > GeoTargetValuePtr
Definition: TargetValue.h:193
boost::variant< std::string, void * > NullableString
Definition: TargetValue.h:179
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::string getWktString() const
Definition: Types.cpp:165
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
Basic constructors and methods of the row set interface.
boost::variant< ScalarTargetValue, ArrayTargetValue, GeoTargetValue, GeoTargetValuePtr > TargetValue
Definition: TargetValue.h:195
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::unique_ptr< VarlenDatum > VarlenDatumPtr
#define IS_GEO(T)
Definition: sqltypes.h:310
void unpack_geo_vector(std::vector< T > &output, const int8_t *input_ptr, const size_t sz)