OmniSciDB  4201147b46
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AreaPerimeter.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 #pragma once
17 
19 
20 #include "Geospatial/Compression.h"
21 
22 namespace spatial_type {
23 
24 class AreaPerimeter : public Codegen {
25  public:
26  AreaPerimeter(const Analyzer::GeoOperator* geo_operator,
27  const Catalog_Namespace::Catalog* catalog)
28  : Codegen(geo_operator, catalog) {
29  CHECK_EQ(operator_->size(), size_t(1));
30  const auto& ti = operator_->get_type_info();
31  is_nullable_ = !ti.get_notnull();
32  }
33 
34  size_t size() const final { return 1; }
35 
36  SQLTypeInfo getNullType() const final { return SQLTypeInfo(kINT); }
37 
38  std::tuple<std::vector<llvm::Value*>, llvm::Value*> codegenLoads(
39  const std::vector<llvm::Value*>& arg_lvs,
40  const std::vector<llvm::Value*>& pos_lvs,
41  CgenState* cgen_state) final {
42  CHECK_EQ(pos_lvs.size(), size());
43  const auto operand = getOperand(0);
44  CHECK(operand);
45  const auto& operand_ti = operand->get_type_info();
46 
47  std::string size_fn_name = "array_size";
48  if (is_nullable_) {
49  size_fn_name += "_nullable";
50  }
51 
52  const uint32_t coords_elem_sz_bytes =
53  operand_ti.get_compression() == kENCODING_GEOINT ? 1 : 8;
54 
55  std::vector<llvm::Value*> operand_lvs;
56  // iterate over column inputs
57  if (dynamic_cast<const Analyzer::ColumnVar*>(operand)) {
58  for (size_t i = 0; i < arg_lvs.size(); i++) {
59  auto lv = arg_lvs[i];
60  operand_lvs.push_back(
61  cgen_state->emitExternalCall("array_buff",
62  llvm::Type::getInt8PtrTy(cgen_state->context_),
63  {lv, pos_lvs.front()}));
64  const auto ptr_type = llvm::dyn_cast_or_null<llvm::PointerType>(lv->getType());
65  CHECK(ptr_type);
66  const auto elem_type = ptr_type->getElementType();
67  CHECK(elem_type);
68  std::vector<llvm::Value*> array_sz_args{
69  lv,
70  pos_lvs.front(),
71  cgen_state->llInt(log2_bytes(i == 0 ? coords_elem_sz_bytes : 4))};
72  if (is_nullable_) { // TODO: should we do this for all arguments, or just points?
73  array_sz_args.push_back(
74  cgen_state->llInt(static_cast<int32_t>(inline_int_null_value<int32_t>())));
75  }
76  operand_lvs.push_back(cgen_state->emitExternalCall(
77  size_fn_name, get_int_type(32, cgen_state->context_), array_sz_args));
78  }
79  } else {
80  operand_lvs = arg_lvs;
81  }
82  CHECK_EQ(operand_lvs.size(),
83  size_t(2 * operand_ti.get_physical_coord_cols())); // array ptr and size
84 
85  // use the points array size argument for nullability
86  return std::make_tuple(operand_lvs, is_nullable_ ? operand_lvs[1] : nullptr);
87  }
88 
89  std::vector<llvm::Value*> codegen(const std::vector<llvm::Value*>& args,
90  CodeGenerator::NullCheckCodegen* nullcheck_codegen,
91  CgenState* cgen_state,
92  const CompilationOptions& co) final {
93  auto operand_lvs = args;
94 
95  const auto& operand_ti = getOperand(0)->get_type_info();
96  CHECK(operand_ti.get_type() == kPOLYGON || operand_ti.get_type() == kMULTIPOLYGON);
97  const bool is_geodesic =
98  operand_ti.get_subtype() == kGEOGRAPHY && operand_ti.get_output_srid() == 4326;
99 
100  std::string func_name = getName() + suffix(operand_ti.get_type());
101  if (is_geodesic && getName() == "ST_Perimeter") {
102  func_name += "_Geodesic";
103  }
104 
105  // push back ic, isr, osr for now
106  operand_lvs.push_back(
107  cgen_state->llInt(Geospatial::get_compression_scheme(operand_ti))); // ic
108  operand_lvs.push_back(cgen_state->llInt(operand_ti.get_input_srid())); // in srid
109  auto output_srid = operand_ti.get_output_srid();
110  if (const auto srid_override = operator_->getOutputSridOverride()) {
111  output_srid = *srid_override;
112  }
113  operand_lvs.push_back(cgen_state->llInt(output_srid)); // out srid
114 
115  const auto& ret_ti = operator_->get_type_info();
116  CHECK(ret_ti.get_type() == kDOUBLE || ret_ti.get_type() == kFLOAT);
117 
118  auto ret = cgen_state->emitExternalCall(
119  func_name,
120  ret_ti.get_type() == kDOUBLE ? llvm::Type::getDoubleTy(cgen_state->context_)
121  : llvm::Type::getFloatTy(cgen_state->context_),
122  operand_lvs);
123  if (is_nullable_) {
124  CHECK(nullcheck_codegen);
125  ret = nullcheck_codegen->finalize(cgen_state->inlineFpNull(ret_ti), ret);
126  }
127  return {ret};
128  }
129 };
130 
131 } // namespace spatial_type
#define CHECK_EQ(x, y)
Definition: Logger.h:230
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:113
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
std::string suffix(SQLTypes type)
Definition: Codegen.cpp:68
std::tuple< std::vector< llvm::Value * >, llvm::Value * > codegenLoads(const std::vector< llvm::Value * > &arg_lvs, const std::vector< llvm::Value * > &pos_lvs, CgenState *cgen_state) final
Definition: AreaPerimeter.h:38
std::vector< llvm::Value * > codegen(const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
Definition: AreaPerimeter.h:89
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:81
size_t size() const final
Definition: AreaPerimeter.h:34
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:70
size_t size() const
Definition: Analyzer.cpp:3805
#define CHECK(condition)
Definition: Logger.h:222
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:63
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:176
Definition: sqltypes.h:45
SQLTypeInfo getNullType() const final
Definition: AreaPerimeter.h:36
AreaPerimeter(const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
Definition: AreaPerimeter.h:26