OmniSciDB  2e3a973ef4
ResultSetGeoSerialization.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 MapD Technologies, 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 
24 #ifndef QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
25 #define QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
26 
27 #include "Geospatial/Compression.h"
28 #include "Geospatial/Types.h"
29 #include "QueryEngine/ResultSet.h"
31 #include "Shared/sqltypes.h"
32 
33 using VarlenDatumPtr = std::unique_ptr<VarlenDatum>;
34 
35 using namespace Geospatial;
36 
37 template <SQLTypes GEO_SOURCE_TYPE>
39  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for target value serializer.");
40 };
41 
42 template <SQLTypes GEO_SOURCE_TYPE>
44  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for wkt serializer.");
45 };
46 
47 template <SQLTypes GEO_SOURCE_TYPE>
49  static_assert(IS_GEO(GEO_SOURCE_TYPE),
50  "Invalid geo type for target value ptr serializer.");
51 };
52 
53 template <ResultSet::GeoReturnType GEO_RETURN_TYPE, SQLTypes GEO_SOURCE_TYPE>
55  static_assert(GEO_RETURN_TYPE == ResultSet::GeoReturnType::GeoTargetValue ||
56  GEO_RETURN_TYPE == ResultSet::GeoReturnType::WktString ||
58  "ResultSet: Unrecognized Geo Return Type encountered.");
59 };
60 
61 template <SQLTypes GEO_SOURCE_TYPE>
62 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValue, GEO_SOURCE_TYPE> {
64 };
65 
66 template <SQLTypes GEO_SOURCE_TYPE>
67 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::WktString, GEO_SOURCE_TYPE> {
69 };
70 
71 template <SQLTypes GEO_SOURCE_TYPE>
72 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValuePtr, GEO_SOURCE_TYPE> {
74 };
75 
76 // Point
77 template <>
79  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
80  std::array<VarlenDatumPtr, 1>& vals) {
81  if (!geo_ti.get_notnull() && vals[0]->is_null) {
82  // Alternatively, could decompress vals[0] and check for NULL array sentinel
83  return GeoTargetValue(boost::optional<GeoPointTargetValue>{});
84  }
85  return GeoTargetValue(
86  boost::optional<GeoPointTargetValue>{*decompress_coords<double, SQLTypeInfo>(
87  geo_ti, vals[0]->pointer, vals[0]->length)});
88  }
89 };
90 
91 template <>
93  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
94  std::array<VarlenDatumPtr, 1>& vals) {
95  // TODO: support EMPTY geo and serialize it as GEOMETRYCOLLECTION EMPTY
96  if (!geo_ti.get_notnull() && vals[0]->is_null) {
97  return NullableString("NULL");
98  }
100  geo_ti, vals[0]->pointer, vals[0]->length));
101  return NullableString(point.getWktString());
102  }
103 };
104 
105 template <>
107  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
108  std::array<VarlenDatumPtr, 1>& vals) {
109  if (!geo_ti.get_notnull() && vals[0]->is_null) {
110  // NULL geo
111  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
112  // return GeoTargetValuePtr();
113  }
114  return GeoPointTargetValuePtr({std::move(vals[0])});
115  }
116 };
117 
118 // LineString
119 template <>
121  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
122  std::array<VarlenDatumPtr, 1>& vals) {
123  if (!geo_ti.get_notnull() && vals[0]->is_null) {
124  return GeoTargetValue(boost::optional<GeoLineStringTargetValue>{});
125  }
126  return GeoTargetValue(
127  boost::optional<GeoLineStringTargetValue>{*decompress_coords<double, SQLTypeInfo>(
128  geo_ti, vals[0]->pointer, vals[0]->length)});
129  }
130 };
131 
132 template <>
134  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
135  std::array<VarlenDatumPtr, 1>& vals) {
136  if (!geo_ti.get_notnull() && vals[0]->is_null) {
137  // May need to generate "LINESTRING EMPTY" instead of NULL
138  return NullableString("NULL");
139  }
141  geo_ti, vals[0]->pointer, vals[0]->length));
142  return NullableString(linestring.getWktString());
143  }
144 };
145 
146 template <>
148  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
149  std::array<VarlenDatumPtr, 1>& vals) {
150  if (!geo_ti.get_notnull() && vals[0]->is_null) {
151  // NULL geo
152  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
153  // return GeoTargetValuePtr();
154  }
155  return GeoLineStringTargetValuePtr({std::move(vals[0])});
156  }
157 };
158 
159 // Polygon
160 template <>
162  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
163  std::array<VarlenDatumPtr, 2>& vals) {
164  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
165  return GeoTargetValue(boost::optional<GeoPolyTargetValue>{});
166  }
167  std::vector<int32_t> ring_sizes_vec;
168  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
170  geo_ti, vals[0]->pointer, vals[0]->length),
171  ring_sizes_vec);
172  return GeoTargetValue(gtv);
173  }
174 };
175 
176 template <>
178  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
179  std::array<VarlenDatumPtr, 2>& vals) {
180  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
181  // May need to generate "POLYGON EMPTY" instead of NULL
182  return NullableString("NULL");
183  }
184  std::vector<int32_t> ring_sizes_vec;
185  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
187  geo_ti, vals[0]->pointer, vals[0]->length),
188  ring_sizes_vec);
189  return NullableString(poly.getWktString());
190  };
191 };
192 
193 template <>
195  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
196  std::array<VarlenDatumPtr, 2>& vals) {
197  if (!geo_ti.get_notnull() && (vals[0]->is_null || vals[1]->is_null)) {
198  // NULL geo
199  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
200  // return GeoTargetValuePtr();
201  }
202  return GeoPolyTargetValuePtr({std::move(vals[0]), std::move(vals[1])});
203  }
204 };
205 
206 // MultiPolygon
207 template <>
209  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
210  std::array<VarlenDatumPtr, 3>& vals) {
211  if (!geo_ti.get_notnull() &&
212  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
213  return GeoTargetValue(boost::optional<GeoMultiPolyTargetValue>{});
214  }
215  std::vector<int32_t> ring_sizes_vec;
216  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
217  std::vector<int32_t> poly_rings_vec;
218  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
220  geo_ti, vals[0]->pointer, vals[0]->length),
221  ring_sizes_vec,
222  poly_rings_vec);
223  return GeoTargetValue(gtv);
224  }
225 };
226 
227 template <>
229  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
230  std::array<VarlenDatumPtr, 3>& vals) {
231  if (!geo_ti.get_notnull() &&
232  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
233  // May need to generate "MULTIPOLYGON EMPTY" instead of NULL
234  return NullableString("NULL");
235  }
236  std::vector<int32_t> ring_sizes_vec;
237  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
238  std::vector<int32_t> poly_rings_vec;
239  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
241  geo_ti, vals[0]->pointer, vals[0]->length),
242  ring_sizes_vec,
243  poly_rings_vec);
244  return NullableString(mpoly.getWktString());
245  }
246 };
247 
248 template <>
250  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
251  std::array<VarlenDatumPtr, 3>& vals) {
252  if (!geo_ti.get_notnull() &&
253  (vals[0]->is_null || vals[1]->is_null || vals[2]->is_null)) {
254  // NULL geo
255  // Pass along null datum, instead of an empty/null GeoTargetValuePtr
256  // return GeoTargetValuePtr();
257  }
259  {std::move(vals[0]), std::move(vals[1]), std::move(vals[2])});
260  }
261 };
262 
263 #endif // QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
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, 3 > &vals)
boost::optional< boost::variant< GeoPointTargetValue, GeoLineStringTargetValue, GeoPolyTargetValue, GeoMultiPolyTargetValue > > GeoTargetValue
Definition: TargetValue.h:161
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
Constants for Builtin SQL Types supported by OmniSci.
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
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)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
std::string getWktString() const
Definition: Types.cpp:158
boost::variant< std::string, void * > NullableString
Definition: TargetValue.h:155
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
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:167
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::unique_ptr< VarlenDatum > VarlenDatumPtr
#define IS_GEO(T)
Definition: sqltypes.h:174
boost::variant< GeoPointTargetValuePtr, GeoLineStringTargetValuePtr, GeoPolyTargetValuePtr, GeoMultiPolyTargetValuePtr > GeoTargetValuePtr
Definition: TargetValue.h:165
void unpack_geo_vector(std::vector< T > &output, const int8_t *input_ptr, const size_t sz)