OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InsertDataLoader.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 <algorithm>
18 #include <numeric>
19 #include <vector>
20 
21 #include "../Shared/shard_key.h"
22 #include "Geospatial/Types.h"
23 #include "InsertDataLoader.h"
25 
26 namespace Fragmenter_Namespace {
27 
29  std::vector<std::vector<uint8_t>> rawData;
30  std::vector<std::vector<std::string>> stringData;
31  std::vector<std::vector<ArrayDatum>> arrayData;
32 };
33 
34 template <typename SRC>
35 std::vector<std::vector<size_t>> compute_row_indices_of_shards(
36  size_t shard_count,
37  size_t leaf_count,
38  size_t row_count,
39  SRC* src,
40  bool duplicated_key_value) {
41  const auto n_shard_tables = shard_count * leaf_count;
42  std::vector<std::vector<size_t>> row_indices_of_shards(n_shard_tables);
43  if (!duplicated_key_value) {
44  for (size_t row = 0; row < row_count; row++) {
45  // expecting unsigned data
46  // thus, no need for double remainder
47  auto shard_id = (std::is_unsigned<SRC>::value)
48  ? src[row] % n_shard_tables
49  : SHARD_FOR_KEY(src[row], n_shard_tables);
50  row_indices_of_shards[shard_id].push_back(row);
51  }
52  } else {
53  auto shard_id = (std::is_unsigned<SRC>::value)
54  ? src[0] % n_shard_tables
55  : SHARD_FOR_KEY(src[0], n_shard_tables);
56  row_indices_of_shards[shard_id].reserve(row_count);
57  for (size_t row = 0; row < row_count; row++) {
58  row_indices_of_shards[shard_id].push_back(row);
59  }
60  }
61 
62  return row_indices_of_shards;
63 }
64 
65 template <typename T>
66 size_t indexOf(std::vector<T>& vec, T val) {
67  typename std::vector<T>::iterator it = std::find(vec.begin(), vec.end(), val);
68  CHECK(it != vec.end());
69  return std::distance(vec.begin(), it);
70 }
71 
73  return (cd->columnType.is_geometry()) ||
74  (cd->columnType.is_string() &&
76 }
77 
79  return cd->columnType.is_array();
80 }
81 
83  const ColumnDescriptor* cd,
84  const bool get_logical_size = true) {
85  switch (cd->columnType.get_type()) {
86  case kPOINT:
87  case kMULTIPOINT:
88  case kLINESTRING:
89  case kMULTILINESTRING:
90  case kPOLYGON:
91  case kMULTIPOLYGON:
92  case kARRAY:
93  throw std::runtime_error("geo and array columns have variable length elements");
94  case kBOOLEAN:
95  case kTINYINT:
96  case kSMALLINT:
97  case kINT:
98  case kBIGINT:
99  case kNUMERIC:
100  case kDECIMAL:
101  case kFLOAT:
102  case kDOUBLE:
103  case kTIMESTAMP:
104  case kTIME:
105  case kINTERVAL_DAY_TIME:
107  case kDATE:
108  return get_logical_size ? cd->columnType.get_logical_size()
109  : cd->columnType.get_size();
110  case kTEXT:
111  case kVARCHAR:
112  case kCHAR:
114  throw std::runtime_error(
115  "non encoded string columns have variable length elements");
116  }
117  return cd->columnType.get_size();
118  default:
119  throw std::runtime_error("not supported column type: " + cd->columnName + " (" +
120  cd->columnType.get_type_name() + ")");
121  }
122 }
123 
124 std::vector<std::vector<size_t>> compute_row_indices_of_shards(
126  size_t leaf_count,
127  const InsertChunks& insert_chunks) {
128  const auto* td = cat.getMetadataForTable(insert_chunks.table_id);
129  const auto* shard_cd = cat.getShardColumnMetadataForTable(td);
130  auto find_it = insert_chunks.chunks.find(shard_cd->columnId);
131  CHECK(find_it != insert_chunks.chunks.end());
132  Chunk_NS::Chunk& shard_chunk = *find_it->second;
133  auto row_count = shard_chunk.getBuffer()->getEncoder()->getNumElems();
134  auto shard_count = td->nShards;
135 
136  CHECK(!isStringVectorData(shard_cd));
137  CHECK(!isDatumVectorData(shard_cd));
138 
139  auto memory_ptr = shard_chunk.getBuffer()->getMemoryPtr();
140  CHECK(memory_ptr);
141  switch (size_of_raw_column(cat, shard_cd, false)) {
142  case 1:
143  return compute_row_indices_of_shards(shard_count,
144  leaf_count,
145  row_count,
146  reinterpret_cast<uint8_t*>(memory_ptr),
147  false);
148  case 2:
149  return compute_row_indices_of_shards(shard_count,
150  leaf_count,
151  row_count,
152  reinterpret_cast<uint16_t*>(memory_ptr),
153  false);
154  case 4:
155  return compute_row_indices_of_shards(shard_count,
156  leaf_count,
157  row_count,
158  reinterpret_cast<uint32_t*>(memory_ptr),
159  false);
160  case 8:
161  return compute_row_indices_of_shards(shard_count,
162  leaf_count,
163  row_count,
164  reinterpret_cast<uint64_t*>(memory_ptr),
165  false);
166  default:
167  UNREACHABLE() << "unexpected data element size of column";
168  }
169  return {};
170 }
171 
172 std::vector<std::vector<size_t>> computeRowIndicesOfShards(
174  size_t leafCount,
175  InsertData& insert_data) {
176  const auto* td = cat.getMetadataForTable(insert_data.tableId);
177  const auto* shard_cd = cat.getShardColumnMetadataForTable(td);
178  auto shardDataBlockIndex = indexOf(insert_data.columnIds, shard_cd->columnId);
179  DataBlockPtr& shardDataBlock = insert_data.data[shardDataBlockIndex];
180  auto rowCount = insert_data.numRows;
181  auto shardCount = td->nShards;
182 
183  CHECK(!isStringVectorData(shard_cd));
184  CHECK(!isDatumVectorData(shard_cd));
185 
186  CHECK(insert_data.is_default.size() == insert_data.columnIds.size());
187  bool is_default = insert_data.is_default[shardDataBlockIndex];
188  switch (size_of_raw_column(cat, shard_cd)) {
189  case 1:
191  shardCount,
192  leafCount,
193  rowCount,
194  reinterpret_cast<uint8_t*>(shardDataBlock.numbersPtr),
195  is_default);
196  case 2:
198  shardCount,
199  leafCount,
200  rowCount,
201  reinterpret_cast<uint16_t*>(shardDataBlock.numbersPtr),
202  is_default);
203  case 4:
205  shardCount,
206  leafCount,
207  rowCount,
208  reinterpret_cast<uint32_t*>(shardDataBlock.numbersPtr),
209  is_default);
210  case 8:
212  shardCount,
213  leafCount,
214  rowCount,
215  reinterpret_cast<uint64_t*>(shardDataBlock.numbersPtr),
216  is_default);
217  }
218  throw std::runtime_error("Unexpected data block element size");
219 }
220 
221 template <typename T>
222 void copyColumnDataOfShard(const std::vector<size_t>& rowIndices, T* src, T* dst) {
223  for (size_t row = 0; row < rowIndices.size(); row++) {
224  auto srcRowIndex = rowIndices[row];
225  dst[row] = src[srcRowIndex];
226  }
227 }
228 
230  int columnId;
233 };
234 
236  ShardDataOwner& dataOwner,
237  const std::vector<size_t>& rowIndices,
238  const ColumnDescriptor* pCol,
239  size_t columnIndex,
240  DataBlockPtr dataBlock,
241  bool is_default) {
242  DataBlockPtr ret;
243  std::vector<size_t> single_row_idx({0ul});
244  const std::vector<size_t>& rows = is_default ? single_row_idx : rowIndices;
245  if (isStringVectorData(pCol)) {
246  auto& data = dataOwner.stringData[columnIndex];
247  data.resize(rows.size());
248  copyColumnDataOfShard(rows, &(*(dataBlock.stringsPtr))[0], &data[0]);
249  ret.stringsPtr = &data;
250 
251  } else if (isDatumVectorData(pCol)) {
252  auto& data = dataOwner.arrayData[columnIndex];
253  data.resize(rows.size());
254  copyColumnDataOfShard(rows, &(*(dataBlock.arraysPtr))[0], &data[0]);
255  ret.arraysPtr = &data;
256 
257  } else {
258  auto rawArrayElementSize = size_of_raw_column(cat, pCol);
259  auto& data = dataOwner.rawData[columnIndex];
260  data.resize(rows.size() * rawArrayElementSize);
261 
262  switch (rawArrayElementSize) {
263  case 1: {
265  reinterpret_cast<uint8_t*>(dataBlock.numbersPtr),
266  reinterpret_cast<uint8_t*>(&data[0]));
267  break;
268  }
269  case 2: {
271  reinterpret_cast<uint16_t*>(dataBlock.numbersPtr),
272  reinterpret_cast<uint16_t*>(&data[0]));
273  break;
274  }
275  case 4: {
277  reinterpret_cast<uint32_t*>(dataBlock.numbersPtr),
278  reinterpret_cast<uint32_t*>(&data[0]));
279  break;
280  }
281  case 8: {
283  reinterpret_cast<uint64_t*>(dataBlock.numbersPtr),
284  reinterpret_cast<uint64_t*>(&data[0]));
285  break;
286  }
287  default:
288  throw std::runtime_error("Unexpected data block element size");
289  }
290 
291  ret.numbersPtr = reinterpret_cast<int8_t*>(&data[0]);
292  }
293 
294  return {pCol->columnId, ret, is_default};
295 }
296 
297 std::pair<std::list<std::unique_ptr<foreign_storage::ForeignStorageBuffer>>, InsertChunks>
299  const InsertChunks& insert_chunks,
300  int shardTableIndex,
301  const std::vector<size_t>& rowIndices) {
302  const auto* table = cat.getMetadataForTable(insert_chunks.table_id);
303  const auto* physical_table = cat.getPhysicalTablesDescriptors(table)[shardTableIndex];
304 
305  InsertChunks insert_chunks_for_shard{
306  physical_table->tableId, insert_chunks.db_id, {}, {}};
307 
308  std::list<std::unique_ptr<foreign_storage::ForeignStorageBuffer>> buffers;
309 
310  for (const auto& [column_id, chunk] : insert_chunks.chunks) {
311  auto column = chunk->getColumnDesc();
312  insert_chunks_for_shard.chunks[column_id] = std::make_shared<Chunk_NS::Chunk>(column);
313  auto& chunk_for_shard = *insert_chunks_for_shard.chunks[column_id];
314  chunk_for_shard.setBuffer(
315  buffers.emplace_back(std::make_unique<foreign_storage::ForeignStorageBuffer>())
316  .get());
317  if (column->columnType.is_varlen_indeed()) { // requires an index buffer
318  chunk_for_shard.setIndexBuffer(
319  buffers.emplace_back(std::make_unique<foreign_storage::ForeignStorageBuffer>())
320  .get());
321  }
322  chunk_for_shard.initEncoder();
323  chunk_for_shard.appendEncodedDataAtIndices(*chunk, rowIndices);
324  CHECK_EQ(chunk_for_shard.getBuffer()->getEncoder()->getNumElems(), rowIndices.size());
325  }
326 
327  // mark which row indices are valid for import
328  auto row_count = rowIndices.size();
329  insert_chunks_for_shard.valid_row_indices.reserve(row_count);
330  for (size_t irow = 0; irow < row_count; ++irow) {
331  auto row_index = rowIndices[irow];
332  if (std::binary_search(insert_chunks.valid_row_indices.begin(),
333  insert_chunks.valid_row_indices.end(),
334  row_index)) {
335  insert_chunks_for_shard.valid_row_indices.emplace_back(irow);
336  }
337  }
338 
339  return {std::move(buffers), insert_chunks_for_shard};
340 }
341 
343  ShardDataOwner& dataOwner,
344  InsertData& insert_data,
345  int shardTableIndex,
346  const std::vector<size_t>& rowIndices) {
347  const auto* td = cat.getMetadataForTable(insert_data.tableId);
348  const auto* ptd = cat.getPhysicalTablesDescriptors(td)[shardTableIndex];
349 
350  InsertData shardData;
351  shardData.databaseId = insert_data.databaseId;
352  shardData.tableId = ptd->tableId;
353  shardData.numRows = rowIndices.size();
354 
355  std::vector<const ColumnDescriptor*> pCols;
356  std::vector<int> lCols;
357 
358  {
359  auto logicalColumns = cat.getAllColumnMetadataForTable(td->tableId, true, true, true);
360  for (const auto& cd : logicalColumns) {
361  lCols.push_back(cd->columnId);
362  }
363 
364  auto physicalColumns =
365  cat.getAllColumnMetadataForTable(ptd->tableId, true, true, true);
366  for (const auto& cd : physicalColumns) {
367  pCols.push_back(cd);
368  }
369  }
370 
371  for (size_t col = 0; col < insert_data.columnIds.size(); col++) {
372  dataOwner.arrayData.emplace_back();
373  dataOwner.rawData.emplace_back();
374  dataOwner.stringData.emplace_back();
375  }
376 
377  auto copycat = [&cat, &dataOwner, &rowIndices, &lCols, &pCols, &insert_data](int col) {
378  const auto lColId = insert_data.columnIds[col];
379  const auto pCol = pCols[indexOf(lCols, lColId)];
380  return copyColumnDataOfShard(cat,
381  dataOwner,
382  rowIndices,
383  pCol,
384  col,
385  insert_data.data[col],
386  insert_data.is_default[col]);
387  };
388 
389  std::vector<std::future<BlockWithColumnId>> worker_threads;
390  for (size_t col = 0; col < insert_data.columnIds.size(); col++) {
391  worker_threads.push_back(std::async(std::launch::async, copycat, col));
392  }
393 
394  for (auto& child : worker_threads) {
395  child.wait();
396  }
397 
398  for (auto& child : worker_threads) {
399  auto shardColumnData = child.get();
400  shardData.columnIds.push_back(shardColumnData.columnId);
401  shardData.data.push_back(shardColumnData.block);
402  shardData.is_default.push_back(shardColumnData.is_default);
403  }
404 
405  return shardData;
406 }
407 
409  std::unique_lock current_leaf_index_lock(current_leaf_index_mutex_);
410  size_t starting_leaf_index = current_leaf_index_;
414  }
415  return starting_leaf_index;
416 }
417 
419  const InsertChunks& insert_chunks) {
420  const auto& cat = session_info.getCatalog();
421  const auto* td = cat.getMetadataForTable(insert_chunks.table_id);
422 
423  CHECK(td);
424  if (td->nShards == 0) {
425  connector_.insertChunksToLeaf(session_info, moveToNextLeaf(), insert_chunks);
426  } else {
427  // we have a sharded target table, start spreading to physical tables
428  auto row_indices_of_shards =
430 
431  auto insert_shard_data =
432  [this, &session_info, &insert_chunks, &cat, &td, &row_indices_of_shards](
433  size_t shardId) {
434  const auto shard_tables = cat.getPhysicalTablesDescriptors(td);
435  auto stard_table_idx = shardId % td->nShards;
436  auto shard_leaf_idx = shardId / td->nShards;
437 
438  const auto& row_indices_of_shard = row_indices_of_shards[shardId];
439 
440  auto [buffers, shard_insert_chunks] = copy_data_of_shard(
441  cat, insert_chunks, stard_table_idx, row_indices_of_shard);
443  session_info, shard_leaf_idx, shard_insert_chunks);
444  };
445 
446  std::vector<std::future<void>> worker_threads;
447  for (size_t shard_id = 0; shard_id < row_indices_of_shards.size(); shard_id++) {
448  if (row_indices_of_shards[shard_id].size() > 0) {
449  worker_threads.push_back(
450  std::async(std::launch::async, insert_shard_data, shard_id));
451  }
452  }
453  for (auto& child : worker_threads) {
454  child.wait();
455  }
456  for (auto& child : worker_threads) {
457  child.get();
458  }
459  }
460 }
461 
463  InsertData& insert_data) {
464  const auto& cat = session_info.getCatalog();
465  const auto* td = cat.getMetadataForTable(insert_data.tableId);
466 
467  CHECK(td);
468  if (td->nShards == 0) {
469  connector_.insertDataToLeaf(session_info, moveToNextLeaf(), insert_data);
470  } else {
471  // we have a sharded target table, start spreading to physical tables
472  auto rowIndicesOfShards =
474 
475  auto insertShardData =
476  [this, &session_info, &insert_data, &cat, &td, &rowIndicesOfShards](
477  size_t shardId) {
478  const auto shard_tables = cat.getPhysicalTablesDescriptors(td);
479  auto stardTableIdx = shardId % td->nShards;
480  auto shardLeafIdx = shardId / td->nShards;
481 
482  const auto& rowIndicesOfShard = rowIndicesOfShards[shardId];
483  ShardDataOwner shardDataOwner;
484 
485  InsertData shardData = copyDataOfShard(
486  cat, shardDataOwner, insert_data, stardTableIdx, rowIndicesOfShard);
487  CHECK(shardData.numRows > 0);
488  connector_.insertDataToLeaf(session_info, shardLeafIdx, shardData);
489  };
490 
491  std::vector<std::future<void>> worker_threads;
492  for (size_t shardId = 0; shardId < rowIndicesOfShards.size(); shardId++) {
493  if (rowIndicesOfShards[shardId].size() > 0) {
494  worker_threads.push_back(
495  std::async(std::launch::async, insertShardData, shardId));
496  }
497  }
498  for (auto& child : worker_threads) {
499  child.wait();
500  }
501  for (auto& child : worker_threads) {
502  child.get();
503  }
504  }
505 }
506 
508  const Catalog_Namespace::SessionInfo& session,
509  const size_t leaf_idx,
510  const Fragmenter_Namespace::InsertChunks& insert_chunks) {
511  CHECK(leaf_idx == 0);
512  auto& catalog = session.getCatalog();
513  auto created_td = catalog.getMetadataForTable(insert_chunks.table_id);
514  created_td->fragmenter->insertChunksNoCheckpoint(insert_chunks);
515 }
516 
518  const size_t leaf_idx,
519  InsertData& insert_data) {
520  CHECK(leaf_idx == 0);
521  auto& catalog = session.getCatalog();
522  auto created_td = catalog.getMetadataForTable(insert_data.tableId);
523  created_td->fragmenter->insertDataNoCheckpoint(insert_data);
524 }
525 
527  int table_id) {
528  auto& catalog = session.getCatalog();
529  catalog.checkpointWithAutoRollback(table_id);
530 }
531 
533  int table_id) {
534  auto& catalog = session.getCatalog();
535  auto db_id = catalog.getDatabaseId();
536  auto table_epochs = catalog.getTableEpochs(db_id, table_id);
537  catalog.setTableEpochs(db_id, table_epochs);
538 }
539 
540 } // namespace Fragmenter_Namespace
#define CHECK_EQ(x, y)
Definition: Logger.h:230
HOST DEVICE int get_size() const
Definition: sqltypes.h:414
std::string cat(Ts &&...args)
void insertChunks(const Catalog_Namespace::SessionInfo &session_info, const InsertChunks &insert_chunks)
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:132
Definition: sqltypes.h:63
std::vector< std::string > * stringsPtr
Definition: sqltypes.h:247
std::vector< ArrayDatum > * arraysPtr
Definition: sqltypes.h:248
std::pair< std::list< std::unique_ptr< foreign_storage::ForeignStorageBuffer > >, InsertChunks > copy_data_of_shard(const Catalog_Namespace::Catalog &cat, const InsertChunks &insert_chunks, int shardTableIndex, const std::vector< size_t > &rowIndices)
std::vector< std::vector< size_t > > computeRowIndicesOfShards(const Catalog_Namespace::Catalog &cat, size_t leafCount, InsertData &insert_data)
#define UNREACHABLE()
Definition: Logger.h:266
std::vector< bool > is_default
Definition: Fragmenter.h:75
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:404
virtual void insertDataToLeaf(const Catalog_Namespace::SessionInfo &parent_session_info, const size_t leaf_idx, Fragmenter_Namespace::InsertData &insert_data)=0
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:4612
bool isStringVectorData(const ColumnDescriptor *cd)
void insertData(const Catalog_Namespace::SessionInfo &session_info, InsertData &insert_data)
int tableId
identifies the database into which the data is being inserted
Definition: Fragmenter.h:70
size_t numRows
a vector of column ids for the row(s) being inserted
Definition: Fragmenter.h:72
void checkpoint(const Catalog_Namespace::SessionInfo &parent_session_info, int tableId) override
size_t size_of_raw_column(const Catalog_Namespace::Catalog &cat, const ColumnDescriptor *cd, const bool get_logical_size=true)
future< Result > async(Fn &&fn, Args &&...args)
int get_logical_size() const
Definition: sqltypes.h:424
void insertDataToLeaf(const Catalog_Namespace::SessionInfo &parent_session_info, const size_t leaf_idx, Fragmenter_Namespace::InsertData &insert_data) override
size_t getNumElems() const
Definition: Encoder.h:284
std::unique_lock< T > unique_lock
std::vector< std::vector< uint8_t > > rawData
int getDatabaseId() const
Definition: Catalog.h:298
specifies the content in-memory of a row in the column metadata table
std::vector< std::vector< size_t > > compute_row_indices_of_shards(size_t shard_count, size_t leaf_count, size_t row_count, SRC *src, bool duplicated_key_value)
void checkpointWithAutoRollback(const int logical_table_id) const
Definition: Catalog.cpp:4791
std::vector< const TableDescriptor * > getPhysicalTablesDescriptors(const TableDescriptor *logical_table_desc, bool populate_fragmenter=true) const
Definition: Catalog.cpp:4630
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
size_t indexOf(std::vector< T > &vec, T val)
Definition: sqltypes.h:66
Definition: sqltypes.h:67
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:412
std::vector< DataBlockPtr > data
the number of rows being inserted
Definition: Fragmenter.h:73
AbstractBuffer * getBuffer() const
Definition: Chunk.h:146
Catalog & getCatalog() const
Definition: SessionInfo.h:75
std::map< int, std::shared_ptr< Chunk_NS::Chunk > > chunks
Definition: Fragmenter.h:52
void insertChunksToLeaf(const Catalog_Namespace::SessionInfo &parent_session_info, const size_t leaf_idx, const Fragmenter_Namespace::InsertChunks &insert_chunks) override
std::list< const ColumnDescriptor * > getAllColumnMetadataForTable(const int tableId, const bool fetchSystemColumns, const bool fetchVirtualColumns, const bool fetchPhysicalColumns) const
Returns a list of pointers to constant ColumnDescriptor structs for all the columns from a particular...
Definition: Catalog.cpp:2228
void copyColumnDataOfShard(const std::vector< size_t > &rowIndices, T *src, T *dst)
std::vector< std::vector< ArrayDatum > > arrayData
std::string get_type_name() const
Definition: sqltypes.h:528
Definition: sqltypes.h:55
void rollback(const Catalog_Namespace::SessionInfo &parent_session_info, int tableId) override
std::vector< size_t > valid_row_indices
Definition: Fragmenter.h:53
bool isDatumVectorData(const ColumnDescriptor *cd)
std::vector< std::vector< std::string > > stringData
#define CHECK(condition)
Definition: Logger.h:222
bool is_geometry() const
Definition: sqltypes.h:612
The data to be inserted using the fragment manager.
Definition: Fragmenter.h:68
Definition: sqltypes.h:59
SQLTypeInfo columnType
InsertData copyDataOfShard(const Catalog_Namespace::Catalog &cat, ShardDataOwner &dataOwner, InsertData &insert_data, int shardTableIndex, const std::vector< size_t > &rowIndices)
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
bool is_string() const
Definition: sqltypes.h:600
int8_t * numbersPtr
Definition: sqltypes.h:246
std::vector< int > columnIds
identifies the table into which the data is being inserted
Definition: Fragmenter.h:71
virtual void insertChunksToLeaf(const Catalog_Namespace::SessionInfo &parent_session_info, const size_t leaf_idx, const Fragmenter_Namespace::InsertChunks &insert_chunks)=0
std::string columnName
#define SHARD_FOR_KEY(key, num_shards)
Definition: shard_key.h:20
bool is_array() const
Definition: sqltypes.h:608