OmniSciDB  ba1bac9284
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PointAccessors.h
Go to the documentation of this file.
1 /*
2  * Copyright 2021 OmniSci, 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 #pragma once
18 
20 
21 namespace spatial_type {
22 
23 // ST_X and ST_Y
24 class PointAccessors : public Codegen {
25  public:
27  const Catalog_Namespace::Catalog* catalog)
28  : Codegen(geo_operator, catalog) {}
29 
30  size_t size() const final { return 1; }
31 
33 
35  return operator_->getOperand(0);
36  }
37 
38  const Analyzer::Expr* getOperand(const size_t index) final {
39  CHECK_EQ(operator_->size(), size_t(1));
40  CHECK_EQ(index, size_t(0));
41  return operator_->getOperand(0);
42  }
43 
44  // returns arguments lvs and null lv
45  std::tuple<std::vector<llvm::Value*>, llvm::Value*> codegenLoads(
46  const std::vector<llvm::Value*>& arg_lvs,
47  llvm::Value* pos_lv,
48  CgenState* cgen_state) final {
49  auto operand = getOperand(0);
50  CHECK(operand);
51  const auto& geo_ti = operand->get_type_info();
52  CHECK(geo_ti.is_geometry());
53  auto& builder = cgen_state->ir_builder_;
54 
55  llvm::Value* array_buff_ptr{nullptr};
56  llvm::Value* is_null{nullptr};
57  if (arg_lvs.size() == 1) {
58  // col byte stream, get the array buffer ptr and is null attributes and cache
60  arg_lvs.front(), pos_lv, geo_ti, cgen_state);
61  array_buff_ptr = arr_load_lvs.buffer;
62  is_null = arr_load_lvs.is_null;
63  } else {
64  // ptr and size
65  CHECK_EQ(arg_lvs.size(), size_t(2));
66  if (dynamic_cast<const Analyzer::GeoOperator*>(operand)) {
67  // null check will be if the ptr is a nullptr
68  is_null = builder.CreateICmp(
69  llvm::CmpInst::ICMP_EQ,
70  arg_lvs.front(),
71  llvm::ConstantPointerNull::get(
72  geo_ti.get_compression() == kENCODING_GEOINT
73  ? llvm::Type::getInt32PtrTy(cgen_state->context_)
74  : llvm::Type::getDoublePtrTy(cgen_state->context_)));
75  }
76 
77  // TODO: nulls from other types not yet supported
78  array_buff_ptr = arg_lvs.front();
79  }
80  CHECK(array_buff_ptr) << operator_->toString();
81  if (!is_null) {
82  is_nullable_ = false;
83  }
84  return std::make_tuple(std::vector<llvm::Value*>{array_buff_ptr}, is_null);
85  }
86 
87  std::vector<llvm::Value*> codegen(const std::vector<llvm::Value*>& args,
88  CodeGenerator::NullCheckCodegen* nullcheck_codegen,
89  CgenState* cgen_state) final {
90  CHECK_EQ(args.size(), size_t(1));
91  const auto array_buff_ptr = args.front();
92 
93  const auto& geo_ti = getOperand(0)->get_type_info();
94  CHECK(geo_ti.is_geometry());
95  auto& builder = cgen_state->ir_builder_;
96 
97  const bool is_x = operator_->getName() == "ST_X";
98  const std::string expr_name = is_x ? "x" : "y";
99 
100  llvm::Value* coord_lv;
101  if (geo_ti.get_compression() == kENCODING_GEOINT) {
102  auto compressed_arr_ptr = builder.CreateBitCast(
103  array_buff_ptr, llvm::Type::getInt32PtrTy(cgen_state->context_));
104  auto coord_index = is_x ? cgen_state->llInt(0) : cgen_state->llInt(1);
105  auto coord_lv_ptr =
106  builder.CreateGEP(compressed_arr_ptr, coord_index, expr_name + "_coord_ptr");
107  auto compressed_coord_lv =
108  builder.CreateLoad(coord_lv_ptr, expr_name + "_coord_compressed");
109 
110  coord_lv =
111  cgen_state->emitExternalCall("decompress_" + expr_name + "_coord_geoint",
112  llvm::Type::getDoubleTy(cgen_state->context_),
113  {compressed_coord_lv});
114  } else {
115  auto coord_arr_ptr = builder.CreateBitCast(
116  array_buff_ptr, llvm::Type::getDoublePtrTy(cgen_state->context_));
117  auto coord_index = is_x ? cgen_state->llInt(0) : cgen_state->llInt(1);
118  auto coord_lv_ptr =
119  builder.CreateGEP(coord_arr_ptr, coord_index, expr_name + "_coord_ptr");
120  coord_lv = builder.CreateLoad(coord_lv_ptr, expr_name + "_coord");
121  }
122 
123  // TODO: do this with transformation nodes explicitly
124  if (geo_ti.get_input_srid() != geo_ti.get_output_srid()) {
125  if (geo_ti.get_input_srid() == 4326) {
126  if (geo_ti.get_output_srid() == 900913) {
127  // convert WGS 84 -> Web mercator
128  coord_lv =
129  cgen_state->emitExternalCall("conv_4326_900913_" + expr_name,
130  llvm::Type::getDoubleTy(cgen_state->context_),
131  {coord_lv});
132  coord_lv->setName(expr_name + "_coord_transformed");
133  } else {
134  throw std::runtime_error("Unsupported geo transformation: " +
135  std::to_string(geo_ti.get_input_srid()) + " to " +
136  std::to_string(geo_ti.get_output_srid()));
137  }
138  } else {
139  throw std::runtime_error(
140  "Unsupported geo transformation: " + std::to_string(geo_ti.get_input_srid()) +
141  " to " + std::to_string(geo_ti.get_output_srid()));
142  }
143  }
144 
145  auto ret = coord_lv;
146  if (is_nullable_) {
147  CHECK(nullcheck_codegen);
148  ret = nullcheck_codegen->finalize(cgen_state->inlineFpNull(SQLTypeInfo(kDOUBLE)),
149  ret);
150  }
151  const auto key = operator_->toString();
152  CHECK(cgen_state->geo_target_cache_.insert(std::make_pair(key, ret)).second);
153  return {ret};
154  }
155 };
156 
157 } // namespace spatial_type
#define CHECK_EQ(x, y)
Definition: Logger.h:214
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:102
size_t size() const final
#define const
const Analyzer::Expr * getOperand(const size_t index) final
std::string toString() const final
Definition: Analyzer.cpp:3417
llvm::Value * buffer
Definition: CgenState.h:32
std::string to_string(char const *&&v)
std::tuple< std::vector< llvm::Value * >, llvm::Value * > codegenLoads(const std::vector< llvm::Value * > &arg_lvs, llvm::Value *pos_lv, CgenState *cgen_state) final
CONSTEXPR DEVICE bool is_null(const T &value)
const std::string & getName() const
Definition: Analyzer.h:1749
SQLTypeInfo getNullType() const final
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
static ArrayLoadCodegen codegenGeoArrayLoadAndNullcheck(llvm::Value *byte_stream, llvm::Value *pos, const SQLTypeInfo &ti, CgenState *cgen_state)
Definition: GeoIR.cpp:23
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:64
size_t size() const
Definition: Analyzer.cpp:3445
std::vector< llvm::Value * > codegen(const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state) final
#define CHECK(condition)
Definition: Logger.h:206
Analyzer::Expr * getOperand(const size_t index) const
Definition: Analyzer.cpp:3449
PointAccessors(const Analyzer::GeoOperator *geo_operator, const Catalog_Namespace::Catalog *catalog)
const Analyzer::Expr * getPositionOperand() const final