OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetBuilder.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 
23 #include "ResultSetBuilder.h"
24 #include "RelAlgTranslator.h"
25 
27  const std::vector<TargetInfo>& targets,
28  const ExecutorDeviceType device_type,
30  const std::shared_ptr<RowSetMemoryOwner> row_set_mem_owner,
31  const Executor* executor) {
32  return new ResultSet(targets,
33  device_type,
34  query_mem_desc,
35  row_set_mem_owner,
36  executor ? executor->blockSize() : 0,
37  executor ? executor->gridSize() : 0);
38 }
39 
40 void ResultSetBuilder::addVarlenBuffer(ResultSet* result_set,
41  std::vector<std::string>& varlen_storage) {
42  CHECK(result_set->serialized_varlen_buffer_.size() == 0);
43 
44  // init with an empty vector
45  result_set->serialized_varlen_buffer_.emplace_back(std::vector<std::string>());
46 
47  // copy the values into the empty vector
48  result_set->serialized_varlen_buffer_.front().assign(varlen_storage.begin(),
49  varlen_storage.end());
50 }
51 
53  const QueryMemoryDescriptor& _query_mem_desc,
54  const std::shared_ptr<RowSetMemoryOwner> _row_set_mem_owner)
55  : query_mem_desc(_query_mem_desc), row_set_mem_owner(_row_set_mem_owner) {}
56 
58  ResultSet* st = ResultSetBuilder::makeResultSet(std::vector<TargetInfo>{},
62  nullptr);
63  return st;
64 }
65 
67  const std::vector<TargetInfo>& _targets,
68  const QueryMemoryDescriptor& _query_mem_desc,
69  const std::shared_ptr<RowSetMemoryOwner> _row_set_mem_owner)
70  : logical_values(nullptr)
71  , targets(_targets)
72  , device_type(ExecutorDeviceType::CPU)
73  , query_mem_desc(_query_mem_desc)
74  , row_set_mem_owner(_row_set_mem_owner)
75  , executor(nullptr) {}
76 
78  const RelLogicalValues* _logical_values,
79  const std::vector<TargetInfo>& _targets,
80  const ExecutorDeviceType _device_type,
81  const QueryMemoryDescriptor& _query_mem_desc,
82  const std::shared_ptr<RowSetMemoryOwner> _row_set_mem_owner,
83  const Executor* _executor)
84  : logical_values(_logical_values)
85  , targets(_targets)
86  , device_type(_device_type)
87  , query_mem_desc(_query_mem_desc)
88  , row_set_mem_owner(_row_set_mem_owner)
89  , executor(_executor) {}
90 
92  ResultSet* rs = ResultSetBuilder::makeResultSet(
94 
97 
98  std::vector<std::string> separate_varlen_storage;
99 
100  auto storage = rs->allocateStorage();
101  auto buff = storage->getUnderlyingBuffer();
102 
103  for (size_t i = 0; i < logical_values->getNumRows(); i++) {
104  std::vector<std::shared_ptr<Analyzer::Expr>> row_literals;
105  int8_t* ptr = buff + i * query_mem_desc.getRowSize();
106 
107  for (size_t j = 0; j < logical_values->getRowsSize(); j++) {
108  auto rex_literal =
109  dynamic_cast<const RexLiteral*>(logical_values->getValueAt(i, j));
110  CHECK(rex_literal);
111  const auto expr = RelAlgTranslator::translateLiteral(rex_literal);
112  const auto constant = std::dynamic_pointer_cast<Analyzer::Constant>(expr);
113  CHECK(constant);
114 
115  if (constant->get_is_null()) {
116  CHECK(!targets[j].sql_type.is_varlen());
117  *reinterpret_cast<int64_t*>(ptr) = inline_int_null_val(targets[j].sql_type);
118  } else {
119  const auto ti = constant->get_type_info();
120  const auto datum = constant->get_constval();
121 
122  if (ti.is_string()) {
123  CHECK(ti.is_none_encoded_string());
124  if (targets[j].sql_type.is_dict_encoded_string()) {
125  // Translate none-encoded string literal to entry in transient string
126  // dictionary. All proper DML queries go down this path
127  CHECK_EQ(targets[j].sql_type.get_comp_param(), TRANSIENT_DICT_ID);
128  CHECK_EQ(targets[j].sql_type.get_size(), 4);
129  const auto sdp = executor->getStringDictionaryProxy(
131  executor->getRowSetMemoryOwner(),
132  true);
133  const auto string_id = sdp->getOrAddTransient(*datum.stringval);
134  // Initialize the entire 8-byte slot
135  std::memset(ptr, 0, 8);
136  std::memcpy(ptr, &string_id, 4);
137  } else {
138  // Project none-encoded string - used for various psuedo-query
139  // outputs like SHOW TABLE, SHOW TABLE DETAILS, etc
140  CHECK(targets[j].sql_type.is_none_encoded_string());
141  // get string from datum and push to vector
142  separate_varlen_storage.push_back(*(datum.stringval));
143  // store the index/offset in ResultSet's storage
144  // (the # of the string in the varlen_storage, not strLen)
145  *reinterpret_cast<int64_t*>(ptr) =
146  static_cast<int64_t>(separate_varlen_storage.size() - 1);
147  }
148  } else {
149  // Initialize the entire 8-byte slot
150  std::memset(ptr, 0, 8);
151  const auto sz = ti.get_size();
152  CHECK_GE(sz, int(0));
153  std::memcpy(ptr, &datum, sz);
154  }
155  }
156  ptr += 8;
157  }
158  }
159 
160  // store the varlen data (ex. strings) into the ResultSet
161  if (separate_varlen_storage.size()) {
162  ResultSetBuilder::addVarlenBuffer(rs, separate_varlen_storage);
163  rs->setSeparateVarlenStorageValid(true);
164  }
165  }
166 
167  return rs;
168 }
169 
170 // static
172  std::vector<TargetMetaInfo>& label_infos,
173  std::vector<RelLogicalValues::RowValues>& logical_values) {
174  // check to see if number of columns matches (at least the first row)
175  size_t numCols =
176  logical_values.size() ? logical_values.front().size() : label_infos.size();
177  CHECK_EQ(label_infos.size(), numCols);
178 
179  size_t numRows = logical_values.size();
180 
181  QueryMemoryDescriptor query_mem_desc(/*executor=*/nullptr,
182  /*entry_count=*/numRows,
184 
185  // target_infos -> defines the table columns
186  std::vector<TargetInfo> target_infos;
187  SQLTypeInfo str_ti(kTEXT, true, kENCODING_NONE);
188  for (size_t col = 0; col < numCols; col++) {
189  SQLTypeInfo colType = label_infos[col].get_type_info();
190  target_infos.push_back(TargetInfo{
191  false, kSAMPLE, colType, colType, true, false, /*is_varlen_projection=*/false});
192  query_mem_desc.addColSlotInfo({std::make_tuple(colType.get_size(), 8)});
193  }
194 
195  std::shared_ptr<RelLogicalValues> rel_logical_values =
196  std::make_shared<RelLogicalValues>(label_infos, logical_values);
197 
198  const auto row_set_mem_owner =
199  std::make_shared<RowSetMemoryOwner>(Executor::getArenaBlockSize(), 0);
200 
201  // Construct ResultSet
202  ResultSet* rsp(ResultSetLogicalValuesBuilder(rel_logical_values.get(),
203  target_infos,
207  nullptr)
208  .build());
209 
210  return rsp;
211 }
bool hasRows() const
Definition: RelAlgDag.h:2724
#define CHECK_EQ(x, y)
Definition: Logger.h:301
HOST DEVICE int get_size() const
Definition: sqltypes.h:403
size_t size() const override
Definition: RelAlgDag.h:2722
const std::vector< TargetInfo > & targets
size_t getNumRows() const
Definition: RelAlgDag.h:2720
#define CHECK_GE(x, y)
Definition: Logger.h:306
#define TRANSIENT_DICT_DB_ID
Definition: DbObjectKeys.h:25
#define TRANSIENT_DICT_ID
Definition: DbObjectKeys.h:24
ExecutorDeviceType
ResultSet * makeResultSet(const std::vector< TargetInfo > &targets, const ExecutorDeviceType device_type, const QueryMemoryDescriptor &query_mem_desc, const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner, const Executor *executor)
size_t getRowsSize() const
Definition: RelAlgDag.h:2712
static std::shared_ptr< Analyzer::Expr > translateLiteral(const RexLiteral *)
const ExecutorDeviceType device_type
const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner
static ResultSet * create(std::vector< TargetMetaInfo > &label_infos, std::vector< RelLogicalValues::RowValues > &logical_values)
Definition: sqltypes.h:79
Basic constructors and methods of the row set interface.
const QueryMemoryDescriptor & query_mem_desc
ResultSetDefaultBuilder(const QueryMemoryDescriptor &query_mem_desc, const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner)
const RelLogicalValues * logical_values
const RexScalar * getValueAt(const size_t row_idx, const size_t col_idx) const
Definition: RelAlgDag.h:2705
#define CHECK(condition)
Definition: Logger.h:291
ResultSetLogicalValuesBuilder(const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc, const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
ResultSet * build() override
void addColSlotInfo(const std::vector< std::tuple< int8_t, int8_t >> &slots_for_col)
static size_t getArenaBlockSize()
Definition: Execute.cpp:558
ResultSet * build() override
void addVarlenBuffer(ResultSet *result_set, std::vector< std::string > &varlen_storage)
const std::shared_ptr< RowSetMemoryOwner > row_set_mem_owner
const QueryMemoryDescriptor & query_mem_desc