OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GeoIR.cpp
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 
17 #include "Geospatial/Compression.h"
19 #include "QueryEngine/Execute.h"
22 
24  llvm::Value* pos,
25  const SQLTypeInfo& ti,
26  CgenState* cgen_state) {
27  CHECK(byte_stream);
28 
29  const auto key = std::make_pair(byte_stream, pos);
30  auto cache_itr = cgen_state->array_load_cache_.find(key);
31  if (cache_itr != cgen_state->array_load_cache_.end()) {
32  return cache_itr->second;
33  }
34  const bool is_nullable = !ti.get_notnull();
35  CHECK(ti.get_type() == kPOINT); // TODO: lift this
36 
37  auto pt_arr_buf =
38  cgen_state->emitExternalCall("array_buff",
39  llvm::Type::getInt8PtrTy(cgen_state->context_),
40  {key.first, key.second});
41  llvm::Value* pt_is_null{nullptr};
42  if (is_nullable) {
43  pt_is_null = cgen_state->emitExternalCall("point_coord_array_is_null",
44  llvm::Type::getInt1Ty(cgen_state->context_),
45  {key.first, key.second});
46  }
47  ArrayLoadCodegen arr_load{pt_arr_buf, nullptr, pt_is_null};
48  cgen_state->array_load_cache_.insert(std::make_pair(key, arr_load));
49  return arr_load;
50 }
51 
52 std::vector<llvm::Value*> CodeGenerator::codegenGeoColumnVar(
53  const Analyzer::GeoColumnVar* geo_col_var,
54  const bool fetch_columns,
55  const CompilationOptions& co) {
56  const auto catalog = executor()->getCatalog();
57  CHECK(catalog);
58 
59  auto generate_column_lvs = [this, catalog, geo_col_var, &co](const int column_id) {
60  auto cd = get_column_descriptor(column_id, geo_col_var->get_table_id(), *catalog);
61  CHECK(cd);
62 
63  const auto col_var = Analyzer::ColumnVar(cd->columnType,
64  geo_col_var->get_table_id(),
65  column_id,
66  geo_col_var->get_rte_idx());
67  const auto lv_vec = codegen(&col_var, /*fetch_columns=*/true, co);
68  CHECK_EQ(lv_vec.size(), size_t(1)); // ptr
69  return lv_vec;
70  };
71 
72  const auto& ti = geo_col_var->get_type_info();
73  switch (ti.get_type()) {
74  case kPOINT:
75  case kLINESTRING:
76  case kMULTILINESTRING:
77  case kPOLYGON:
78  case kMULTIPOLYGON: {
79  std::vector<llvm::Value*> geo_lvs;
80  // iterate over physical columns
81  for (int i = 0; i < ti.get_physical_coord_cols(); i++) {
82  const auto column_id = geo_col_var->get_column_id() + 1 + i;
83  const auto lvs = generate_column_lvs(column_id);
84  CHECK_EQ(lvs.size(), size_t(1)); // expecting ptr for each column
85  geo_lvs.insert(geo_lvs.end(), lvs.begin(), lvs.end());
86  }
87 
88  return geo_lvs;
89  }
90  default:
91  UNREACHABLE() << geo_col_var->toString();
92  }
93  UNREACHABLE();
94  return {};
95 }
96 
97 std::vector<llvm::Value*> CodeGenerator::codegenGeoExpr(const Analyzer::GeoExpr* expr,
98  const CompilationOptions& co) {
99  auto geo_constant = dynamic_cast<const Analyzer::GeoConstant*>(expr);
100  if (geo_constant) {
101  return codegenGeoConstant(geo_constant, co);
102  }
103  auto geo_operator = dynamic_cast<const Analyzer::GeoOperator*>(expr);
104  if (geo_operator) {
105  return codegenGeoOperator(geo_operator, co);
106  }
107  UNREACHABLE() << expr->toString();
108  return {};
109 }
110 
111 std::vector<llvm::Value*> CodeGenerator::codegenGeoConstant(
112  const Analyzer::GeoConstant* geo_constant,
113  const CompilationOptions& co) {
115 
116  std::vector<llvm::Value*> ret;
117  for (size_t i = 0; i < geo_constant->physicalCols(); i++) {
118  auto physical_constant = geo_constant->makePhysicalConstant(i);
119  auto operand_lvs = codegen(physical_constant.get(), /*fetch_columns=*/true, co);
120  CHECK_EQ(operand_lvs.size(), size_t(2));
121  auto array_buff_lv = operand_lvs[0];
122  if (i > 0) {
123  array_buff_lv = cgen_state_->ir_builder_.CreateBitCast(
124  operand_lvs[0], llvm::Type::getInt8PtrTy(cgen_state_->context_));
125  }
126  ret.push_back(array_buff_lv);
127  ret.push_back(operand_lvs[1]);
128  }
129  return ret;
130 }
131 
132 std::vector<llvm::Value*> CodeGenerator::codegenGeoOperator(
133  const Analyzer::GeoOperator* geo_operator,
134  const CompilationOptions& co) {
136 
137  if (geo_operator->getName() == "ST_X" || geo_operator->getName() == "ST_Y") {
138  const auto key = geo_operator->toString();
139  auto geo_target_cache_it = cgen_state_->geo_target_cache_.find(key);
140  if (geo_target_cache_it != cgen_state_->geo_target_cache_.end()) {
141  return {geo_target_cache_it->second};
142  }
143  }
144 
145  const auto catalog = executor()->getCatalog();
146  CHECK(catalog);
147 
148  auto op_codegen = spatial_type::Codegen::init(geo_operator, catalog);
149  CHECK(op_codegen);
150 
151  std::vector<llvm::Value*> load_lvs;
152  std::vector<llvm::Value*> pos_lvs;
153  for (size_t i = 0; i < op_codegen->size(); i++) {
154  auto intermediate_lvs =
155  codegen(op_codegen->getOperand(i), /*fetch_columns=*/true, co);
156  load_lvs.insert(load_lvs.end(), intermediate_lvs.begin(), intermediate_lvs.end());
157  pos_lvs.push_back(posArg(op_codegen->getOperand(i)));
158  }
159 
160  auto [arg_lvs, null_lv] = op_codegen->codegenLoads(load_lvs, pos_lvs, cgen_state_);
161 
162  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen =
163  op_codegen->getNullCheckCodegen(null_lv, cgen_state_, executor());
164  return op_codegen->codegen(arg_lvs, nullcheck_codegen.get(), cgen_state_, co);
165 }
166 
167 std::vector<llvm::Value*> CodeGenerator::codegenGeoUOper(
168  const Analyzer::GeoUOper* geo_expr,
169  const CompilationOptions& co) {
172  if (geo_expr->getOp() != Geospatial::GeoBase::GeoOp::kPROJECTION) {
173  throw QueryMustRunOnCpu();
174  }
175  }
176 
177  auto argument_list = codegenGeoArgs(geo_expr->getArgs0(), co);
178 
179  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kPROJECTION) {
180  return argument_list;
181  }
182 
183 #ifndef ENABLE_GEOS
184  throw std::runtime_error("Geo operation requires GEOS support.");
185 #endif
186 
187  // Basic set of arguments is currently common to all Geos_* func invocations:
188  // op kind, type of the first geo arg0, geo arg0 components
189  std::string func = "Geos_Wkb"s;
190 
191  if (geo_expr->getTypeInfo0().transforms() || geo_expr->get_type_info().transforms()) {
192  // If there is a transform on the argument and/or on the result of the operation,
193  // verify that the argument's output srid is equal to result's input srid
194  if (geo_expr->getTypeInfo0().get_output_srid() !=
195  geo_expr->get_type_info().get_input_srid()) {
196  throw std::runtime_error("GEOS runtime: input/output srids have to match.");
197  }
198  }
199  // Prepend arg0 geo SQLType
200  argument_list.insert(
201  argument_list.begin(),
202  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_type())));
203  // Prepend geo expr op
204  argument_list.insert(argument_list.begin(),
205  cgen_state_->llInt(static_cast<int>(geo_expr->getOp())));
206  for (auto i = 3; i > geo_expr->getTypeInfo0().get_physical_coord_cols(); i--) {
207  argument_list.insert(argument_list.end(),
208  llvm::ConstantPointerNull::get(
209  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
210  argument_list.insert(argument_list.end(), cgen_state_->llInt(int64_t(0)));
211  }
212  // Append geo expr compression
213  argument_list.insert(
214  argument_list.end(),
215  cgen_state_->llInt(static_cast<int>(
217  // Append geo expr input srid
218  argument_list.insert(
219  argument_list.end(),
220  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_input_srid())));
221  // Append geo expr output srid
222  argument_list.insert(
223  argument_list.end(),
224  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_output_srid())));
225 
226  // Deal with unary geo predicates
227  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kISEMPTY ||
229  return codegenGeosPredicateCall(func, argument_list, co);
230  }
231 
232  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kCONVEXHULL) {
233  func += "_double"s; // Use same interface as ST_ConcaveHull, with a dummy double
234 
235  // Insert that dummy double arg
236  argument_list.insert(argument_list.end(), cgen_state_->llFp(double(0)));
237 
238  auto result_srid = cgen_state_->llInt(geo_expr->get_type_info().get_output_srid());
239 
240  return codegenGeosConstructorCall(func, argument_list, result_srid, co);
241  }
242 
243  throw std::runtime_error("Unsupported unary geo operation.");
244  return {};
245 }
246 
247 std::vector<llvm::Value*> CodeGenerator::codegenGeoBinOper(
248  Analyzer::GeoBinOper const* geo_expr,
249  CompilationOptions const& co) {
252  throw QueryMustRunOnCpu();
253  }
254 #ifndef ENABLE_GEOS
255  throw std::runtime_error("Geo operation requires GEOS support.");
256 #endif
257 
258  auto argument_list = codegenGeoArgs(geo_expr->getArgs0(), co);
259 
260  // Basic set of arguments is currently common to all Geos_* func invocations:
261  // op kind, type of the first geo arg0, geo arg0 components
262  std::string func = "Geos_Wkb"s;
263  if (geo_expr->getTypeInfo0().transforms() || geo_expr->get_type_info().transforms()) {
264  // If there is a transform on the argument and/or on the result of the operation,
265  // verify that the argument's output srid is equal to result's input srid
266  if (geo_expr->getTypeInfo0().get_output_srid() !=
267  geo_expr->get_type_info().get_input_srid()) {
268  throw std::runtime_error("GEOS runtime: input/output srids have to match.");
269  }
270  }
271  // Prepend arg0 geo SQLType
272  argument_list.insert(
273  argument_list.begin(),
274  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_type())));
275  // Prepend geo expr op
276  argument_list.insert(argument_list.begin(),
277  cgen_state_->llInt(static_cast<int>(geo_expr->getOp())));
278  for (auto i = 3; i > geo_expr->getTypeInfo0().get_physical_coord_cols(); i--) {
279  argument_list.insert(argument_list.end(),
280  llvm::ConstantPointerNull::get(
281  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
282  argument_list.insert(argument_list.end(), cgen_state_->llInt(int64_t(0)));
283  }
284  // Append geo expr compression
285  argument_list.insert(
286  argument_list.end(),
287  cgen_state_->llInt(static_cast<int>(
289  // Append geo expr input srid
290  argument_list.insert(
291  argument_list.end(),
292  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_input_srid())));
293  // Append geo expr output srid
294  argument_list.insert(
295  argument_list.end(),
296  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo0().get_output_srid())));
297 
298  auto arg1_list = codegenGeoArgs(geo_expr->getArgs1(), co);
299 
300  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kDIFFERENCE ||
302  geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kUNION ||
304  func += "_Wkb"s;
305  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kEQUALS) {
306  func += "_Predicate"s;
307  }
308  // Prepend arg1 geo SQLType
309  arg1_list.insert(
310  arg1_list.begin(),
311  cgen_state_->llInt(static_cast<int>(geo_expr->getTypeInfo1().get_type())));
312  for (auto i = 3; i > geo_expr->getTypeInfo1().get_physical_coord_cols(); i--) {
313  arg1_list.insert(arg1_list.end(),
314  llvm::ConstantPointerNull::get(
315  llvm::Type::getInt32PtrTy(cgen_state_->context_, 0)));
316  arg1_list.insert(arg1_list.end(), cgen_state_->llInt(int64_t(0)));
317  }
318  // Append geo expr compression
319  arg1_list.insert(arg1_list.end(),
320  cgen_state_->llInt(static_cast<int>(
322  // Append geo expr input srid
323  arg1_list.insert(arg1_list.end(),
324  cgen_state_->llInt(geo_expr->getTypeInfo1().get_input_srid()));
325  // Append geo expr output srid
326  arg1_list.insert(arg1_list.end(),
328  } else if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kBUFFER) {
329  // Extra argument in this case is double
330  func += "_double"s;
331  } else if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kCONCAVEHULL) {
332 #if (GEOS_VERSION_MAJOR > 3) || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11)
333  // Extra argument in this case is double
334  func += "_double"s;
335 #else
336  throw std::runtime_error("ST_ConcaveHull requires GEOS 3.11 or newer");
337 #endif
338  } else {
339  throw std::runtime_error("Unsupported binary geo operation.");
340  }
341 
342  // Append arg1 to the list
343  argument_list.insert(argument_list.end(), arg1_list.begin(), arg1_list.end());
344 
345  // Deal with binary geo predicates
346  if (geo_expr->getOp() == Geospatial::GeoBase::GeoOp::kEQUALS) {
347  return codegenGeosPredicateCall(func, argument_list, co);
348  }
349 
350  auto result_srid = cgen_state_->llInt(geo_expr->get_type_info().get_output_srid());
351 
352  return codegenGeosConstructorCall(func, argument_list, result_srid, co);
353 }
354 
355 std::vector<llvm::Value*> CodeGenerator::codegenGeoArgs(
356  const std::vector<std::shared_ptr<Analyzer::Expr>>& geo_args,
357  const CompilationOptions& co) {
359  std::vector<llvm::Value*> argument_list;
360  bool coord_col = true;
361  for (const auto& geo_arg : geo_args) {
362  const auto arg = geo_arg.get();
363  const auto& arg_ti = arg->get_type_info();
364  const auto elem_ti = arg_ti.get_elem_type();
365  const auto arg_lvs = codegen(arg, true, co);
366  if (arg_ti.is_number()) {
367  argument_list.emplace_back(arg_lvs.front());
368  continue;
369  }
370  if (arg_ti.is_geometry()) {
371  argument_list.insert(argument_list.end(), arg_lvs.begin(), arg_lvs.end());
372  continue;
373  }
374  CHECK(arg_ti.is_array());
375  if (arg_lvs.size() > 1) {
376  CHECK_EQ(size_t(2), arg_lvs.size());
377  auto ptr_lv = arg_lvs.front();
378  if (coord_col) {
379  coord_col = false;
380  } else {
381  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
382  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
383  }
384  argument_list.emplace_back(ptr_lv);
385  auto cast_len_lv = cgen_state_->ir_builder_.CreateZExt(
386  arg_lvs.back(), get_int_type(64, cgen_state_->context_));
387  argument_list.emplace_back(cast_len_lv);
388  } else {
389  CHECK_EQ(size_t(1), arg_lvs.size());
390  if (arg_ti.get_size() > 0) {
391  // Set up the pointer lv for a dynamically generated point
392  auto ptr_lv = arg_lvs.front();
393  auto col_var = dynamic_cast<const Analyzer::ColumnVar*>(arg);
394  // Override for point coord column access
395  if (col_var) {
396  ptr_lv = cgen_state_->emitExternalCall(
397  "fast_fixlen_array_buff",
398  llvm::Type::getInt8PtrTy(cgen_state_->context_),
399  {arg_lvs.front(), posArg(arg)});
400  }
401  if (coord_col) {
402  coord_col = false;
403  } else {
404  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
405  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
406  }
407  argument_list.emplace_back(ptr_lv);
408  argument_list.emplace_back(cgen_state_->llInt<int64_t>(arg_ti.get_size()));
409  } else {
410  auto ptr_lv =
411  cgen_state_->emitExternalCall("array_buff",
412  llvm::Type::getInt8PtrTy(cgen_state_->context_),
413  {arg_lvs.front(), posArg(arg)});
414  if (coord_col) {
415  coord_col = false;
416  } else {
417  ptr_lv = cgen_state_->ir_builder_.CreatePointerCast(
418  ptr_lv, llvm::Type::getInt32PtrTy(cgen_state_->context_));
419  }
420  argument_list.emplace_back(ptr_lv);
421  const auto len_lv = cgen_state_->emitExternalCall(
422  "array_size",
424  {arg_lvs.front(),
425  posArg(arg),
426  cgen_state_->llInt(log2_bytes(elem_ti.get_logical_size()))});
427  auto cast_len_lv = cgen_state_->ir_builder_.CreateZExt(
428  len_lv, get_int_type(64, cgen_state_->context_));
429  argument_list.emplace_back(cast_len_lv);
430  }
431  }
432  }
433  return argument_list;
434 }
435 
436 std::vector<llvm::Value*> CodeGenerator::codegenGeosPredicateCall(
437  const std::string& func,
438  std::vector<llvm::Value*> argument_list,
439  const CompilationOptions& co) {
441  auto i8_type = get_int_type(8, cgen_state_->context_);
442  auto result = cgen_state_->ir_builder_.CreateAlloca(i8_type, nullptr, "result");
443  argument_list.emplace_back(result);
444 
445  // Generate call to GEOS wrapper
446  cgen_state_->needs_geos_ = true;
447  auto status_lv = cgen_state_->emitExternalCall(
448  func, llvm::Type::getInt1Ty(cgen_state_->context_), argument_list);
449  // Need to check the status and throw an error if this call has failed.
450  llvm::BasicBlock* geos_pred_ok_bb{nullptr};
451  llvm::BasicBlock* geos_pred_fail_bb{nullptr};
452  geos_pred_ok_bb = llvm::BasicBlock::Create(
453  cgen_state_->context_, "geos_pred_ok_bb", cgen_state_->current_func_);
454  geos_pred_fail_bb = llvm::BasicBlock::Create(
455  cgen_state_->context_, "geos_pred_fail_bb", cgen_state_->current_func_);
456  if (!status_lv) {
457  status_lv = cgen_state_->llBool(false);
458  }
459  cgen_state_->ir_builder_.CreateCondBr(status_lv, geos_pred_ok_bb, geos_pred_fail_bb);
460  cgen_state_->ir_builder_.SetInsertPoint(geos_pred_fail_bb);
463  cgen_state_->ir_builder_.SetInsertPoint(geos_pred_ok_bb);
464  auto res = cgen_state_->ir_builder_.CreateLoad(
465  result->getType()->getPointerElementType(), result);
466  return {res};
467 }
468 
470  const std::string& func,
471  std::vector<llvm::Value*> argument_list,
472  llvm::Value* result_srid,
473  const CompilationOptions& co) {
475  // Create output buffer pointers, append pointers to output args to
476  auto i8_type = get_int_type(8, cgen_state_->context_);
477  auto i32_type = get_int_type(32, cgen_state_->context_);
478  auto i64_type = get_int_type(64, cgen_state_->context_);
479  auto pi8_type = llvm::PointerType::get(i8_type, 0);
480  auto pi32_type = llvm::PointerType::get(i32_type, 0);
481 
482  auto result_type =
483  cgen_state_->ir_builder_.CreateAlloca(i32_type, nullptr, "result_type");
484  auto result_coords =
485  cgen_state_->ir_builder_.CreateAlloca(pi8_type, nullptr, "result_coords");
486  auto result_coords_size =
487  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_coords_size");
488  auto result_ring_sizes =
489  cgen_state_->ir_builder_.CreateAlloca(pi32_type, nullptr, "result_ring_sizes");
490  auto result_ring_sizes_size =
491  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_ring_sizes_size");
492  auto result_poly_rings =
493  cgen_state_->ir_builder_.CreateAlloca(pi32_type, nullptr, "result_poly_rings");
494  auto result_poly_rings_size =
495  cgen_state_->ir_builder_.CreateAlloca(i64_type, nullptr, "result_poly_rings_size");
496 
497  argument_list.emplace_back(result_type);
498  argument_list.emplace_back(result_coords);
499  argument_list.emplace_back(result_coords_size);
500  argument_list.emplace_back(result_ring_sizes);
501  argument_list.emplace_back(result_ring_sizes_size);
502  argument_list.emplace_back(result_poly_rings);
503  argument_list.emplace_back(result_poly_rings_size);
504  argument_list.emplace_back(result_srid);
505 
506  // Generate call to GEOS wrapper
507  cgen_state_->needs_geos_ = true;
508  auto status_lv = cgen_state_->emitExternalCall(
509  func, llvm::Type::getInt1Ty(cgen_state_->context_), argument_list);
510  // Need to check the status and throw an error if this call has failed.
511  llvm::BasicBlock* geos_ok_bb{nullptr};
512  llvm::BasicBlock* geos_fail_bb{nullptr};
513  geos_ok_bb = llvm::BasicBlock::Create(
514  cgen_state_->context_, "geos_ok_bb", cgen_state_->current_func_);
515  geos_fail_bb = llvm::BasicBlock::Create(
516  cgen_state_->context_, "geos_fail_bb", cgen_state_->current_func_);
517  if (!status_lv) {
518  status_lv = cgen_state_->llBool(false);
519  }
520  cgen_state_->ir_builder_.CreateCondBr(status_lv, geos_ok_bb, geos_fail_bb);
521  cgen_state_->ir_builder_.SetInsertPoint(geos_fail_bb);
524  cgen_state_->ir_builder_.SetInsertPoint(geos_ok_bb);
525 
526  // TODO: Currently forcing the output to MULTIPOLYGON, but need to handle
527  // other possible geometries that geos may return, e.g. a POINT, a LINESTRING
528  // Need to handle empty result, e.g. empty intersection.
529  // The type of result is returned in `result_type`
530 
531  // Load return values
532  auto buf1 = cgen_state_->ir_builder_.CreateLoad(
533  result_coords->getType()->getPointerElementType(), result_coords);
534  auto buf1s = cgen_state_->ir_builder_.CreateLoad(
535  result_coords_size->getType()->getPointerElementType(), result_coords_size);
536  auto buf2 = cgen_state_->ir_builder_.CreateLoad(
537  result_ring_sizes->getType()->getPointerElementType(), result_ring_sizes);
538  auto buf2s = cgen_state_->ir_builder_.CreateLoad(
539  result_ring_sizes_size->getType()->getPointerElementType(), result_ring_sizes_size);
540  auto buf3 = cgen_state_->ir_builder_.CreateLoad(
541  result_poly_rings->getType()->getPointerElementType(), result_poly_rings);
542  auto buf3s = cgen_state_->ir_builder_.CreateLoad(
543  result_poly_rings_size->getType()->getPointerElementType(), result_poly_rings_size);
544 
545  // generate register_buffer_with_executor_rsm() calls to register all output buffers
547  "register_buffer_with_executor_rsm",
548  llvm::Type::getVoidTy(cgen_state_->context_),
549  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
550  cgen_state_->ir_builder_.CreatePointerCast(buf1, pi8_type)});
551  cgen_state_->emitExternalCall(
552  "register_buffer_with_executor_rsm",
553  llvm::Type::getVoidTy(cgen_state_->context_),
554  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
555  cgen_state_->ir_builder_.CreatePointerCast(buf2, pi8_type)});
556  cgen_state_->emitExternalCall(
557  "register_buffer_with_executor_rsm",
558  llvm::Type::getVoidTy(cgen_state_->context_),
559  {cgen_state_->llInt(reinterpret_cast<int64_t>(executor())),
560  cgen_state_->ir_builder_.CreatePointerCast(buf3, pi8_type)});
561 
562  return {cgen_state_->ir_builder_.CreatePointerCast(buf1, pi8_type),
563  buf1s,
564  cgen_state_->ir_builder_.CreatePointerCast(buf2, pi32_type),
565  buf2s,
566  cgen_state_->ir_builder_.CreatePointerCast(buf3, pi32_type),
567  buf3s};
568 }
#define CHECK_EQ(x, y)
Definition: Logger.h:230
const SQLTypeInfo getTypeInfo0() const
Definition: Analyzer.h:2559
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs0() const
Definition: Analyzer.h:2561
const SQLTypeInfo getTypeInfo0() const
Definition: Analyzer.h:2530
CgenState * cgen_state_
std::map< std::pair< llvm::Value *, llvm::Value * >, ArrayLoadCodegen > array_load_cache_
Definition: CgenState.h:459
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.h:217
llvm::IRBuilder ir_builder_
Definition: CgenState.h:441
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
llvm::Value * posArg(const Analyzer::Expr *) const
Definition: ColumnIR.cpp:550
#define UNREACHABLE()
Definition: Logger.h:266
const SQLTypeInfo getTypeInfo1() const
Definition: Analyzer.h:2560
llvm::ConstantInt * llBool(const bool v) const
Definition: CgenState.h:320
bool needs_geos_
Definition: CgenState.h:462
static const int32_t ERR_GEOS
Definition: Execute.h:1384
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:404
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::vector< llvm::Value * > codegenGeoBinOper(const Analyzer::GeoBinOper *, const CompilationOptions &)
Definition: GeoIR.cpp:247
std::unordered_map< std::string, llvm::Value * > geo_target_cache_
Definition: CgenState.h:460
std::vector< llvm::Value * > codegenGeoExpr(const Analyzer::GeoExpr *, const CompilationOptions &)
Definition: GeoIR.cpp:97
llvm::LLVMContext & context_
Definition: CgenState.h:439
llvm::Function * current_func_
Definition: CgenState.h:433
std::vector< llvm::Value * > codegenGeoOperator(const Analyzer::GeoOperator *, const CompilationOptions &)
Definition: GeoIR.cpp:132
std::vector< llvm::Value * > codegenGeoUOper(const Analyzer::GeoUOper *, const CompilationOptions &)
Definition: GeoIR.cpp:167
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs0() const
Definition: Analyzer.h:2531
const std::string & getName() const
Definition: Analyzer.h:2775
bool needs_error_check_
Definition: CgenState.h:461
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:310
#define AUTOMATIC_IR_METADATA(CGENSTATE)
std::vector< llvm::Value * > codegenGeosConstructorCall(const std::string &, std::vector< llvm::Value * >, llvm::Value *, const CompilationOptions &)
Definition: GeoIR.cpp:469
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:82
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:30
virtual std::string toString() const =0
std::vector< llvm::Value * > codegenGeosPredicateCall(const std::string &, std::vector< llvm::Value * >, const CompilationOptions &)
Definition: GeoIR.cpp:436
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck(llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
Definition: GeoIR.cpp:23
std::vector< llvm::Value * > codegenGeoColumnVar(const Analyzer::GeoColumnVar *, const bool fetch_columns, const CompilationOptions &co)
Definition: GeoIR.cpp:52
HOST DEVICE int get_input_srid() const
Definition: sqltypes.h:408
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:306
std::vector< llvm::Value * > codegenGeoArgs(const std::vector< std::shared_ptr< Analyzer::Expr >> &, const CompilationOptions &)
Definition: GeoIR.cpp:355
#define CHECK(condition)
Definition: Logger.h:222
Geospatial::GeoBase::GeoOp getOp() const
Definition: Analyzer.h:2529
std::vector< llvm::Value * > codegenGeoConstant(const Analyzer::GeoConstant *, const CompilationOptions &)
Definition: GeoIR.cpp:111
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:176
std::shared_ptr< Analyzer::Constant > makePhysicalConstant(const size_t index) const
Definition: Analyzer.cpp:3801
bool transforms() const
Definition: sqltypes.h:635
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:411
static std::unique_ptr< Codegen > init(const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
Definition: Codegen.cpp:22
std::string toString() const override
Definition: Analyzer.cpp:3885
int get_physical_coord_cols() const
Definition: sqltypes.h:454
size_t physicalCols() const
Definition: Analyzer.cpp:3796
Geospatial::GeoBase::GeoOp getOp() const
Definition: Analyzer.h:2558
const std::vector< std::shared_ptr< Analyzer::Expr > > & getArgs1() const
Definition: Analyzer.h:2562
const ColumnDescriptor * get_column_descriptor(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:191
HOST DEVICE int get_output_srid() const
Definition: sqltypes.h:410
Executor * executor() const