OmniSciDB  21ac014ffc
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RelAlgDagBuilder.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, 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 
22 #pragma once
23 
24 #include <atomic>
25 #include <iterator>
26 #include <memory>
27 #include <unordered_map>
28 
29 #include <rapidjson/document.h>
30 #include <boost/core/noncopyable.hpp>
31 #include <boost/functional/hash.hpp>
32 
33 #include "Catalog/Catalog.h"
34 #include "QueryEngine/QueryHint.h"
38 #include "QueryHint.h"
39 #include "Shared/toString.h"
40 #include "Utils/FsiUtils.h"
41 
42 using ColumnNameList = std::vector<std::string>;
43 
44 class Rex {
45  public:
46  virtual std::string toString() const = 0;
47 
48  // return hashed value of string representation of this rex
49  virtual size_t toHash() const = 0;
50 
51  virtual ~Rex() {}
52 
53  protected:
54  mutable std::optional<size_t> hash_;
55 };
56 
57 class RexScalar : public Rex {};
58 // For internal use of the abstract interpreter only. The result after abstract
59 // interpretation will not have any references to 'RexAbstractInput' objects.
60 class RexAbstractInput : public RexScalar {
61  public:
62  RexAbstractInput(const unsigned in_index) : in_index_(in_index) {}
63 
64  unsigned getIndex() const { return in_index_; }
65 
66  void setIndex(const unsigned in_index) const { in_index_ = in_index; }
67 
68  std::string toString() const override {
69  return cat(::typeName(this), "(", std::to_string(in_index_), ")");
70  }
71 
72  size_t toHash() const override {
73  if (!hash_) {
74  hash_ = typeid(RexAbstractInput).hash_code();
75  boost::hash_combine(*hash_, in_index_);
76  }
77  return *hash_;
78  }
79 
80  private:
81  mutable unsigned in_index_;
82 };
83 
84 class RexLiteral : public RexScalar {
85  public:
86  RexLiteral(const int64_t val,
87  const SQLTypes type,
88  const SQLTypes target_type,
89  const unsigned scale,
90  const unsigned precision,
91  const unsigned type_scale,
92  const unsigned type_precision)
93  : literal_(val)
94  , type_(type)
95  , target_type_(target_type)
96  , scale_(scale)
97  , precision_(precision)
98  , type_scale_(type_scale)
99  , type_precision_(type_precision) {
100  CHECK(type == kDECIMAL || type == kINTERVAL_DAY_TIME ||
101  type == kINTERVAL_YEAR_MONTH || is_datetime(type) || type == kBIGINT ||
102  type == kINT);
103  }
104 
105  RexLiteral(const double val,
106  const SQLTypes type,
107  const SQLTypes target_type,
108  const unsigned scale,
109  const unsigned precision,
110  const unsigned type_scale,
111  const unsigned type_precision)
112  : literal_(val)
113  , type_(type)
114  , target_type_(target_type)
115  , scale_(scale)
116  , precision_(precision)
117  , type_scale_(type_scale)
118  , type_precision_(type_precision) {
119  CHECK_EQ(kDOUBLE, type);
120  }
121 
122  RexLiteral(const std::string& val,
123  const SQLTypes type,
124  const SQLTypes target_type,
125  const unsigned scale,
126  const unsigned precision,
127  const unsigned type_scale,
128  const unsigned type_precision)
129  : literal_(val)
130  , type_(type)
131  , target_type_(target_type)
132  , scale_(scale)
133  , precision_(precision)
134  , type_scale_(type_scale)
135  , type_precision_(type_precision) {
136  CHECK_EQ(kTEXT, type);
137  }
138 
139  RexLiteral(const bool val,
140  const SQLTypes type,
141  const SQLTypes target_type,
142  const unsigned scale,
143  const unsigned precision,
144  const unsigned type_scale,
145  const unsigned type_precision)
146  : literal_(val)
147  , type_(type)
148  , target_type_(target_type)
149  , scale_(scale)
150  , precision_(precision)
151  , type_scale_(type_scale)
152  , type_precision_(type_precision) {
153  CHECK_EQ(kBOOLEAN, type);
154  }
155 
156  RexLiteral(const SQLTypes target_type)
157  : literal_(nullptr)
158  , type_(kNULLT)
159  , target_type_(target_type)
160  , scale_(0)
161  , precision_(0)
162  , type_scale_(0)
163  , type_precision_(0) {}
164 
165  template <class T>
166  T getVal() const {
167  const auto ptr = boost::get<T>(&literal_);
168  CHECK(ptr);
169  return *ptr;
170  }
171 
172  SQLTypes getType() const { return type_; }
173 
174  SQLTypes getTargetType() const { return target_type_; }
175 
176  unsigned getScale() const { return scale_; }
177 
178  unsigned getPrecision() const { return precision_; }
179 
180  unsigned getTypeScale() const { return type_scale_; }
181 
182  unsigned getTypePrecision() const { return type_precision_; }
183 
184  std::string toString() const override {
185  return cat(::typeName(this),
186  "(",
187  boost::lexical_cast<std::string>(literal_),
188  ", type=",
189  (type_ == kNULLT ? "null" : ::toString(type_)),
190  ", target_type=",
191  (target_type_ == kNULLT ? "null" : ::toString(target_type_)),
192  ")");
193  }
194 
195  size_t toHash() const override {
196  if (!hash_) {
197  hash_ = typeid(RexLiteral).hash_code();
198  boost::hash_combine(*hash_, boost::lexical_cast<std::string>(literal_));
199  boost::hash_combine(*hash_, type_ == kNULLT ? "n" : ::toString(type_));
200  boost::hash_combine(*hash_,
201  target_type_ == kNULLT ? "n" : ::toString(target_type_));
202  }
203  return *hash_;
204  }
205 
206  std::unique_ptr<RexLiteral> deepCopy() const {
207  switch (literal_.which()) {
208  case 0: {
209  int64_t val = getVal<int64_t>();
210  return std::make_unique<RexLiteral>(
212  }
213  case 1: {
214  double val = getVal<double>();
215  return std::make_unique<RexLiteral>(
217  }
218  case 2: {
219  auto val = getVal<std::string>();
220  return std::make_unique<RexLiteral>(
222  }
223  case 3: {
224  bool val = getVal<bool>();
225  return std::make_unique<RexLiteral>(
227  }
228  case 4: {
229  return std::make_unique<RexLiteral>(target_type_);
230  }
231  default:
232  CHECK(false);
233  }
234  return nullptr;
235  }
236 
237  private:
238  const boost::variant<int64_t, double, std::string, bool, void*> literal_;
241  const unsigned scale_;
242  const unsigned precision_;
243  const unsigned type_scale_;
244  const unsigned type_precision_;
245 };
246 
247 using RexLiteralArray = std::vector<RexLiteral>;
248 using TupleContentsArray = std::vector<RexLiteralArray>;
249 
250 class RexOperator : public RexScalar {
251  public:
252  RexOperator(const SQLOps op,
253  std::vector<std::unique_ptr<const RexScalar>>& operands,
254  const SQLTypeInfo& type)
255  : op_(op), operands_(std::move(operands)), type_(type) {}
256 
257  virtual std::unique_ptr<const RexOperator> getDisambiguated(
258  std::vector<std::unique_ptr<const RexScalar>>& operands) const {
259  return std::unique_ptr<const RexOperator>(new RexOperator(op_, operands, type_));
260  }
261 
262  size_t size() const { return operands_.size(); }
263 
264  const RexScalar* getOperand(const size_t idx) const {
265  CHECK(idx < operands_.size());
266  return operands_[idx].get();
267  }
268 
269  const RexScalar* getOperandAndRelease(const size_t idx) const {
270  CHECK(idx < operands_.size());
271  return operands_[idx].release();
272  }
273 
274  SQLOps getOperator() const { return op_; }
275 
276  const SQLTypeInfo& getType() const { return type_; }
277 
278  std::string toString() const override {
279  return cat(::typeName(this),
280  "(",
282  ", operands=",
283  ::toString(operands_),
284  ", type=",
285  type_.to_string(),
286  ")");
287  };
288 
289  size_t toHash() const override {
290  if (!hash_) {
291  hash_ = typeid(RexOperator).hash_code();
292  boost::hash_combine(*hash_, op_);
293  for (auto& operand : operands_) {
294  boost::hash_combine(*hash_, operand->toHash());
295  }
296  boost::hash_combine(*hash_, getType().get_type_name());
297  }
298  return *hash_;
299  }
300 
301  protected:
302  const SQLOps op_;
303  mutable std::vector<std::unique_ptr<const RexScalar>> operands_;
305 };
306 
307 class RelAlgNode;
308 using RelAlgInputs = std::vector<std::shared_ptr<const RelAlgNode>>;
309 
310 class ExecutionResult;
311 
312 class RexSubQuery : public RexScalar {
313  public:
314  RexSubQuery(const std::shared_ptr<const RelAlgNode> ra)
315  : type_(new SQLTypeInfo(kNULLT, false))
316  , result_(new std::shared_ptr<const ExecutionResult>(nullptr))
317  , ra_(ra) {}
318 
319  // for deep copy
320  RexSubQuery(std::shared_ptr<SQLTypeInfo> type,
321  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result,
322  const std::shared_ptr<const RelAlgNode> ra)
323  : type_(type), result_(result), ra_(ra) {}
324 
325  RexSubQuery(const RexSubQuery&) = delete;
326 
327  RexSubQuery& operator=(const RexSubQuery&) = delete;
328 
329  RexSubQuery(RexSubQuery&&) = delete;
330 
331  RexSubQuery& operator=(RexSubQuery&&) = delete;
332 
333  const SQLTypeInfo& getType() const {
334  CHECK_NE(kNULLT, type_->get_type());
335  return *(type_.get());
336  }
337 
338  std::shared_ptr<const ExecutionResult> getExecutionResult() const {
339  CHECK(result_);
340  CHECK(result_.get());
341  return *(result_.get());
342  }
343 
344  unsigned getId() const;
345 
346  const RelAlgNode* getRelAlg() const { return ra_.get(); }
347 
348  std::string toString() const override;
349 
350  size_t toHash() const override;
351 
352  std::unique_ptr<RexSubQuery> deepCopy() const;
353 
354  void setExecutionResult(const std::shared_ptr<const ExecutionResult> result);
355 
356  private:
357  std::shared_ptr<SQLTypeInfo> type_;
358  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result_;
359  const std::shared_ptr<const RelAlgNode> ra_;
360 };
361 
362 // The actual input node understood by the Executor.
363 // The in_index_ is relative to the output of node_.
364 class RexInput : public RexAbstractInput {
365  public:
366  RexInput(const RelAlgNode* node, const unsigned in_index)
367  : RexAbstractInput(in_index), node_(node) {}
368 
369  const RelAlgNode* getSourceNode() const { return node_; }
370 
371  // This isn't great, but we need it for coalescing nodes to Compound since
372  // RexInput in descendents need to be rebound to the newly created Compound.
373  // Maybe create a fresh RA tree with the required changes after each coalescing?
374  void setSourceNode(const RelAlgNode* node) const { node_ = node; }
375 
376  bool operator==(const RexInput& that) const {
377  return getSourceNode() == that.getSourceNode() && getIndex() == that.getIndex();
378  }
379 
380  std::string toString() const override;
381 
382  size_t toHash() const override;
383 
384  std::unique_ptr<RexInput> deepCopy() const {
385  return std::make_unique<RexInput>(node_, getIndex());
386  }
387 
388  private:
389  mutable const RelAlgNode* node_;
390 };
391 
392 namespace std {
393 
394 template <>
395 struct hash<RexInput> {
396  size_t operator()(const RexInput& rex_in) const {
397  auto addr = rex_in.getSourceNode();
398  return *reinterpret_cast<const size_t*>(may_alias_ptr(&addr)) ^ rex_in.getIndex();
399  }
400 };
401 
402 } // namespace std
403 
404 // Not a real node created by Calcite. Created by us because CaseExpr is a node in our
405 // Analyzer.
406 class RexCase : public RexScalar {
407  public:
408  RexCase(std::vector<std::pair<std::unique_ptr<const RexScalar>,
409  std::unique_ptr<const RexScalar>>>& expr_pair_list,
410  std::unique_ptr<const RexScalar>& else_expr)
411  : expr_pair_list_(std::move(expr_pair_list)), else_expr_(std::move(else_expr)) {}
412 
413  size_t branchCount() const { return expr_pair_list_.size(); }
414 
415  const RexScalar* getWhen(const size_t idx) const {
416  CHECK(idx < expr_pair_list_.size());
417  return expr_pair_list_[idx].first.get();
418  }
419 
420  const RexScalar* getThen(const size_t idx) const {
421  CHECK(idx < expr_pair_list_.size());
422  return expr_pair_list_[idx].second.get();
423  }
424 
425  const RexScalar* getElse() const { return else_expr_.get(); }
426 
427  std::string toString() const override {
428  return cat(::typeName(this),
429  "(expr_pair_list=",
431  ", else_expr=",
432  (else_expr_ ? else_expr_->toString() : "null"),
433  ")");
434  }
435 
436  size_t toHash() const override {
437  if (!hash_) {
438  hash_ = typeid(RexCase).hash_code();
439  for (size_t i = 0; i < branchCount(); ++i) {
440  boost::hash_combine(*hash_, getWhen(i)->toHash());
441  boost::hash_combine(*hash_, getThen(i)->toHash());
442  }
443  boost::hash_combine(*hash_,
444  getElse() ? getElse()->toHash() : boost::hash_value("n"));
445  }
446  return *hash_;
447  }
448 
449  private:
450  std::vector<
451  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
453  std::unique_ptr<const RexScalar> else_expr_;
454 };
455 
457  public:
458  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
459  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
460 
461  RexFunctionOperator(const std::string& name,
462  ConstRexScalarPtrVector& operands,
463  const SQLTypeInfo& ti)
464  : RexOperator(kFUNCTION, operands, ti), name_(name) {}
465 
466  std::unique_ptr<const RexOperator> getDisambiguated(
467  std::vector<std::unique_ptr<const RexScalar>>& operands) const override {
468  return std::unique_ptr<const RexOperator>(
469  new RexFunctionOperator(name_, operands, getType()));
470  }
471 
472  const std::string& getName() const { return name_; }
473 
474  std::string toString() const override {
475  return cat(::typeName(this), "(", name_, ", operands=", ::toString(operands_), ")");
476  }
477 
478  size_t toHash() const override {
479  if (!hash_) {
480  hash_ = typeid(RexFunctionOperator).hash_code();
481  boost::hash_combine(*hash_, ::toString(op_));
482  boost::hash_combine(*hash_, getType().get_type_name());
483  for (auto& operand : operands_) {
484  boost::hash_combine(*hash_, operand->toHash());
485  }
486  boost::hash_combine(*hash_, name_);
487  }
488  return *hash_;
489  }
490 
491  private:
492  const std::string name_;
493 };
494 
496 
497 enum class NullSortedPosition { First, Last };
498 
499 class SortField {
500  public:
501  SortField(const size_t field,
502  const SortDirection sort_dir,
503  const NullSortedPosition nulls_pos)
504  : field_(field), sort_dir_(sort_dir), nulls_pos_(nulls_pos) {}
505 
506  bool operator==(const SortField& that) const {
507  return field_ == that.field_ && sort_dir_ == that.sort_dir_ &&
508  nulls_pos_ == that.nulls_pos_;
509  }
510 
511  size_t getField() const { return field_; }
512 
513  SortDirection getSortDir() const { return sort_dir_; }
514 
516 
517  std::string toString() const {
518  return cat(::typeName(this),
519  "(",
521  ", sort_dir=",
522  (sort_dir_ == SortDirection::Ascending ? "asc" : "desc"),
523  ", null_pos=",
524  (nulls_pos_ == NullSortedPosition::First ? "nulls_first" : "nulls_last"),
525  ")");
526  }
527 
528  size_t toHash() const {
529  auto hash = boost::hash_value(field_);
530  boost::hash_combine(hash, sort_dir_ == SortDirection::Ascending ? "a" : "d");
531  boost::hash_combine(hash, nulls_pos_ == NullSortedPosition::First ? "f" : "l");
532  return hash;
533  }
534 
535  private:
536  const size_t field_;
539 };
540 
542  public:
543  struct RexWindowBound {
544  bool unbounded;
545  bool preceding;
546  bool following;
548  std::shared_ptr<const RexScalar> offset;
550  };
551 
553  ConstRexScalarPtrVector& operands,
554  ConstRexScalarPtrVector& partition_keys,
555  ConstRexScalarPtrVector& order_keys,
556  const std::vector<SortField> collation,
559  const bool is_rows,
560  const SQLTypeInfo& ti)
561  : RexFunctionOperator(::toString(kind), operands, ti)
562  , kind_(kind)
563  , partition_keys_(std::move(partition_keys))
564  , order_keys_(std::move(order_keys))
565  , collation_(collation)
566  , lower_bound_(lower_bound)
567  , upper_bound_(upper_bound)
568  , is_rows_(is_rows) {}
569 
570  SqlWindowFunctionKind getKind() const { return kind_; }
571 
573 
575  return std::move(partition_keys_);
576  }
577 
579  return std::move(order_keys_);
580  }
581 
583 
584  const std::vector<SortField>& getCollation() const { return collation_; }
585 
586  const RexWindowBound& getLowerBound() const { return lower_bound_; }
587 
588  const RexWindowBound& getUpperBound() const { return upper_bound_; }
589 
590  bool isRows() const { return is_rows_; }
591 
592  std::unique_ptr<const RexOperator> disambiguatedOperands(
593  ConstRexScalarPtrVector& operands,
594  ConstRexScalarPtrVector& partition_keys,
595  ConstRexScalarPtrVector& order_keys,
596  const std::vector<SortField>& collation) const {
597  return std::unique_ptr<const RexOperator>(
599  operands,
600  partition_keys,
601  order_keys,
602  collation,
603  getLowerBound(),
604  getUpperBound(),
605  isRows(),
606  getType()));
607  }
608 
609  std::string toString() const override {
610  return cat(::typeName(this),
611  "(",
612  getName(),
613  ", operands=",
614  ::toString(operands_),
615  ", partition_keys=",
617  ", order_keys=",
619  ")");
620  }
621 
622  size_t toHash() const override {
623  if (!hash_) {
624  hash_ = typeid(RexWindowFunctionOperator).hash_code();
625  boost::hash_combine(*hash_, getType().get_type_name());
626  boost::hash_combine(*hash_, getName());
627  boost::hash_combine(*hash_, is_rows_);
628  for (auto& collation : collation_) {
629  boost::hash_combine(*hash_, collation.toHash());
630  }
631  for (auto& operand : operands_) {
632  boost::hash_combine(*hash_, operand->toHash());
633  }
634  for (auto& key : partition_keys_) {
635  boost::hash_combine(*hash_, key->toHash());
636  }
637  for (auto& key : order_keys_) {
638  boost::hash_combine(*hash_, key->toHash());
639  }
640  auto get_window_bound_hash =
642  auto h = boost::hash_value(bound.offset ? bound.offset->toHash()
643  : boost::hash_value("n"));
644  boost::hash_combine(h, bound.unbounded);
645  boost::hash_combine(h, bound.preceding);
646  boost::hash_combine(h, bound.following);
647  boost::hash_combine(h, bound.is_current_row);
648  boost::hash_combine(h, bound.order_key);
649  return h;
650  };
651  boost::hash_combine(*hash_, get_window_bound_hash(lower_bound_));
652  boost::hash_combine(*hash_, get_window_bound_hash(upper_bound_));
653  }
654  return *hash_;
655  }
656 
657  private:
661  const std::vector<SortField> collation_;
664  const bool is_rows_;
665 };
666 
667 // Not a real node created by Calcite. Created by us because targets of a query
668 // should reference the group by expressions instead of creating completely new one.
669 class RexRef : public RexScalar {
670  public:
671  RexRef(const size_t index) : index_(index) {}
672 
673  size_t getIndex() const { return index_; }
674 
675  std::string toString() const override {
676  return cat(::typeName(this), "(", std::to_string(index_), ")");
677  }
678 
679  size_t toHash() const override {
680  if (!hash_) {
681  hash_ = typeid(RexRef).hash_code();
682  boost::hash_combine(*hash_, index_);
683  }
684  return *hash_;
685  }
686 
687  std::unique_ptr<RexRef> deepCopy() const { return std::make_unique<RexRef>(index_); }
688 
689  private:
690  const size_t index_;
691 };
692 
693 class RexAgg : public Rex {
694  public:
695  RexAgg(const SQLAgg agg,
696  const bool distinct,
697  const SQLTypeInfo& type,
698  const std::vector<size_t>& operands)
699  : agg_(agg), distinct_(distinct), type_(type), operands_(operands) {}
700 
701  std::string toString() const override {
702  return cat(::typeName(this),
703  "(agg=",
705  ", distinct=",
707  ", type=",
709  ", operands=",
711  ")");
712  }
713 
714  size_t toHash() const override {
715  if (!hash_) {
716  hash_ = typeid(RexAgg).hash_code();
717  for (auto& operand : operands_) {
718  boost::hash_combine(*hash_, operand);
719  }
720  boost::hash_combine(*hash_, agg_);
721  boost::hash_combine(*hash_, distinct_);
722  boost::hash_combine(*hash_, type_.get_type_name());
723  }
724  return *hash_;
725  }
726 
727  SQLAgg getKind() const { return agg_; }
728 
729  bool isDistinct() const { return distinct_; }
730 
731  size_t size() const { return operands_.size(); }
732 
733  size_t getOperand(size_t idx) const { return operands_[idx]; }
734 
735  const SQLTypeInfo& getType() const { return type_; }
736 
737  std::unique_ptr<RexAgg> deepCopy() const {
738  return std::make_unique<RexAgg>(agg_, distinct_, type_, operands_);
739  }
740 
741  private:
742  const SQLAgg agg_;
743  const bool distinct_;
745  const std::vector<size_t> operands_;
746 };
747 
748 class RelAlgNode {
749  public:
751  : inputs_(std::move(inputs))
752  , id_(crt_id_++)
753  , context_data_(nullptr)
754  , is_nop_(false) {}
755 
756  virtual ~RelAlgNode() {}
757 
759  context_data_ = nullptr;
760  targets_metainfo_ = {};
761  }
762 
763  void setContextData(const void* context_data) const {
765  context_data_ = context_data;
766  }
767 
768  void setOutputMetainfo(const std::vector<TargetMetaInfo>& targets_metainfo) const {
769  targets_metainfo_ = targets_metainfo;
770  }
771 
772  const std::vector<TargetMetaInfo>& getOutputMetainfo() const {
773  return targets_metainfo_;
774  }
775 
776  unsigned getId() const { return id_; }
777 
778  bool hasContextData() const { return !(context_data_ == nullptr); }
779 
780  const void* getContextData() const {
782  return context_data_;
783  }
784 
785  const size_t inputCount() const { return inputs_.size(); }
786 
787  const RelAlgNode* getInput(const size_t idx) const {
788  CHECK_LT(idx, inputs_.size());
789  return inputs_[idx].get();
790  }
791 
792  std::shared_ptr<const RelAlgNode> getAndOwnInput(const size_t idx) const {
793  CHECK_LT(idx, inputs_.size());
794  return inputs_[idx];
795  }
796 
797  void addManagedInput(std::shared_ptr<const RelAlgNode> input) {
798  inputs_.push_back(input);
799  }
800 
801  bool hasInput(const RelAlgNode* needle) const {
802  for (auto& input_ptr : inputs_) {
803  if (input_ptr.get() == needle) {
804  return true;
805  }
806  }
807  return false;
808  }
809 
810  virtual void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
811  std::shared_ptr<const RelAlgNode> input) {
812  for (auto& input_ptr : inputs_) {
813  if (input_ptr == old_input) {
814  input_ptr = input;
815  break;
816  }
817  }
818  }
819 
820  // to keep an assigned DAG node id for data recycler
821  void setRelNodeDagId(const size_t id) const { dag_node_id_ = id; }
822 
823  size_t getRelNodeDagId() const { return dag_node_id_; }
824 
825  bool isNop() const { return is_nop_; }
826 
827  void markAsNop() { is_nop_ = true; }
828 
829  virtual std::string toString() const = 0;
830 
831  // return hashed value of a string representation of this rel node
832  virtual size_t toHash() const = 0;
833 
834  virtual size_t size() const = 0;
835 
836  virtual std::shared_ptr<RelAlgNode> deepCopy() const = 0;
837 
838  static void resetRelAlgFirstId() noexcept;
839 
844  void clearContextData() const { context_data_ = nullptr; }
845 
846  protected:
848  const unsigned id_;
849  mutable std::optional<size_t> hash_;
850 
851  private:
852  mutable const void* context_data_;
853  bool is_nop_;
854  mutable std::vector<TargetMetaInfo> targets_metainfo_;
855  static thread_local unsigned crt_id_;
856  mutable size_t dag_node_id_;
857 };
858 
859 class RelScan : public RelAlgNode {
860  public:
861  RelScan(const TableDescriptor* td, const std::vector<std::string>& field_names)
862  : td_(td)
863  , field_names_(field_names)
865  , hints_(std::make_unique<Hints>()) {}
866 
867  size_t size() const override { return field_names_.size(); }
868 
869  const TableDescriptor* getTableDescriptor() const { return td_; }
870 
871  const std::vector<std::string>& getFieldNames() const { return field_names_; }
872 
873  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
874 
875  std::string toString() const override {
876  return cat(
877  ::typeName(this), "(", td_->tableName, ", ", ::toString(field_names_), ")");
878  }
879 
880  size_t toHash() const override {
881  if (!hash_) {
882  hash_ = typeid(RelScan).hash_code();
883  boost::hash_combine(*hash_, td_->tableId);
884  boost::hash_combine(*hash_, td_->tableName);
885  boost::hash_combine(*hash_, ::toString(field_names_));
886  }
887  return *hash_;
888  }
889 
890  std::shared_ptr<RelAlgNode> deepCopy() const override {
891  CHECK(false);
892  return nullptr;
893  };
894 
895  void addHint(const ExplainedQueryHint& hint_explained) {
896  if (!hint_applied_) {
897  hint_applied_ = true;
898  }
899  hints_->emplace(hint_explained.getHint(), hint_explained);
900  }
901 
902  const bool hasHintEnabled(const QueryHint candidate_hint) const {
903  if (hint_applied_ && !hints_->empty()) {
904  return hints_->find(candidate_hint) != hints_->end();
905  }
906  return false;
907  }
908 
911  CHECK(!hints_->empty());
912  CHECK(hasHintEnabled(hint));
913  return hints_->at(hint);
914  }
915 
916  bool hasDeliveredHint() { return !hints_->empty(); }
917 
918  Hints* getDeliveredHints() { return hints_.get(); }
919 
920  private:
922  const std::vector<std::string> field_names_;
924  std::unique_ptr<Hints> hints_;
925 };
926 
928  public:
929  ModifyManipulationTarget(bool const update_via_select = false,
930  bool const delete_via_select = false,
931  bool const varlen_update_required = false,
932  TableDescriptor const* table_descriptor = nullptr,
933  ColumnNameList target_columns = ColumnNameList())
934  : is_update_via_select_(update_via_select)
935  , is_delete_via_select_(delete_via_select)
936  , varlen_update_required_(varlen_update_required)
937  , table_descriptor_(table_descriptor)
938  , target_columns_(target_columns) {}
939 
944  }
945 
948  table_descriptor_ = td;
949  }
950 
951  auto const isUpdateViaSelect() const { return is_update_via_select_; }
952  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
953  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
954 
955  void setTargetColumns(ColumnNameList const& target_columns) const {
956  target_columns_ = target_columns;
957  }
959 
960  template <typename VALIDATION_FUNCTOR>
961  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
962  for (auto const& column_name : target_columns_) {
963  if (validator(column_name) == false) {
964  return false;
965  }
966  }
967  return true;
968  }
969 
970  private:
971  mutable bool is_update_via_select_ = false;
972  mutable bool is_delete_via_select_ = false;
973  mutable bool varlen_update_required_ = false;
974  mutable TableDescriptor const* table_descriptor_ = nullptr;
976 };
977 
979  public:
980  friend class RelModify;
981  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
982  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
983 
984  // Takes memory ownership of the expressions.
985  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
986  const std::vector<std::string>& fields,
987  std::shared_ptr<const RelAlgNode> input)
989  , scalar_exprs_(std::move(scalar_exprs))
990  , fields_(fields)
992  , hints_(std::make_unique<Hints>()) {
993  inputs_.push_back(input);
994  }
995 
996  RelProject(RelProject const&);
997 
998  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
999  scalar_exprs_ = std::move(exprs);
1000  }
1001 
1002  // True iff all the projected expressions are inputs. If true,
1003  // this node can be elided and merged into the previous node
1004  // since it's just a subset and / or permutation of its outputs.
1005  bool isSimple() const {
1006  for (const auto& expr : scalar_exprs_) {
1007  if (!dynamic_cast<const RexInput*>(expr.get())) {
1008  return false;
1009  }
1010  }
1011  return true;
1012  }
1013 
1014  bool isIdentity() const;
1015 
1016  bool isRenaming() const;
1017 
1018  size_t size() const override { return scalar_exprs_.size(); }
1019 
1020  const RexScalar* getProjectAt(const size_t idx) const {
1021  CHECK(idx < scalar_exprs_.size());
1022  return scalar_exprs_[idx].get();
1023  }
1024 
1025  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
1026  CHECK(idx < scalar_exprs_.size());
1027  return scalar_exprs_[idx].release();
1028  }
1029 
1030  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
1031  return std::move(scalar_exprs_);
1032  }
1033 
1034  const std::vector<std::string>& getFields() const { return fields_; }
1035  void setFields(std::vector<std::string>& fields) { fields_ = std::move(fields); }
1036 
1037  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1038 
1039  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1040  std::shared_ptr<const RelAlgNode> input) override {
1041  replaceInput(old_input, input, std::nullopt);
1042  }
1043 
1044  void replaceInput(
1045  std::shared_ptr<const RelAlgNode> old_input,
1046  std::shared_ptr<const RelAlgNode> input,
1047  std::optional<std::unordered_map<unsigned, unsigned>> old_to_new_index_map);
1048 
1049  void appendInput(std::string new_field_name,
1050  std::unique_ptr<const RexScalar> new_input);
1051 
1052  std::string toString() const override {
1053  return cat(
1054  ::typeName(this), "(", ::toString(scalar_exprs_), ", ", ::toString(fields_), ")");
1055  }
1056 
1057  size_t toHash() const override {
1058  if (!hash_) {
1059  hash_ = typeid(RelProject).hash_code();
1060  for (auto& target_expr : scalar_exprs_) {
1061  boost::hash_combine(*hash_, target_expr->toHash());
1062  }
1063  boost::hash_combine(*hash_, ::toString(fields_));
1064  }
1065  return *hash_;
1066  }
1067 
1068  std::shared_ptr<RelAlgNode> deepCopy() const override {
1069  return std::make_shared<RelProject>(*this);
1070  }
1071 
1072  bool hasWindowFunctionExpr() const;
1073 
1074  void addHint(const ExplainedQueryHint& hint_explained) {
1075  if (!hint_applied_) {
1076  hint_applied_ = true;
1077  }
1078  hints_->emplace(hint_explained.getHint(), hint_explained);
1079  }
1080 
1081  const bool hasHintEnabled(QueryHint candidate_hint) const {
1082  if (hint_applied_ && !hints_->empty()) {
1083  return hints_->find(candidate_hint) != hints_->end();
1084  }
1085  return false;
1086  }
1087 
1090  CHECK(!hints_->empty());
1091  CHECK(hasHintEnabled(hint));
1092  return hints_->at(hint);
1093  }
1094 
1095  bool hasDeliveredHint() { return !hints_->empty(); }
1096 
1097  Hints* getDeliveredHints() { return hints_.get(); }
1098 
1099  private:
1100  template <typename EXPR_VISITOR_FUNCTOR>
1101  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
1102  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
1103  visitor_functor(i);
1104  }
1105  }
1106 
1109  scalar_exprs_.emplace_back(
1110  std::make_unique<RexFunctionOperator const>(std::string("OFFSET_IN_FRAGMENT"),
1111  transient_vector,
1112  SQLTypeInfo(kBIGINT, false)));
1113  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
1114  }
1115 
1116  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
1117  mutable std::vector<std::string> fields_;
1119  std::unique_ptr<Hints> hints_;
1120 };
1121 
1122 class RelAggregate : public RelAlgNode {
1123  public:
1124  // Takes ownership of the aggregate expressions.
1125  RelAggregate(const size_t groupby_count,
1126  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
1127  const std::vector<std::string>& fields,
1128  std::shared_ptr<const RelAlgNode> input)
1129  : groupby_count_(groupby_count)
1130  , agg_exprs_(std::move(agg_exprs))
1131  , fields_(fields)
1132  , hint_applied_(false)
1133  , hints_(std::make_unique<Hints>()) {
1134  inputs_.push_back(input);
1135  }
1136 
1137  RelAggregate(RelAggregate const&);
1138 
1139  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
1140 
1141  const size_t getGroupByCount() const { return groupby_count_; }
1142 
1143  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
1144 
1145  const std::vector<std::string>& getFields() const { return fields_; }
1146  void setFields(std::vector<std::string>& new_fields) {
1147  fields_ = std::move(new_fields);
1148  }
1149 
1150  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1151 
1152  std::vector<const RexAgg*> getAggregatesAndRelease() {
1153  std::vector<const RexAgg*> result;
1154  for (auto& agg_expr : agg_exprs_) {
1155  result.push_back(agg_expr.release());
1156  }
1157  return result;
1158  }
1159 
1160  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
1161  return std::move(agg_exprs_);
1162  }
1163 
1164  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
1165  return agg_exprs_;
1166  }
1167 
1168  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
1169  agg_exprs_ = std::move(agg_exprs);
1170  }
1171 
1172  std::string toString() const override {
1173  return cat(::typeName(this),
1174  "(",
1176  ", agg_exprs=",
1177  ::toString(agg_exprs_),
1178  ", fields=",
1179  ::toString(fields_),
1180  ", inputs=",
1181  ::toString(inputs_),
1182  ")");
1183  }
1184 
1185  size_t toHash() const override {
1186  if (!hash_) {
1187  hash_ = typeid(RelAggregate).hash_code();
1188  boost::hash_combine(*hash_, groupby_count_);
1189  for (auto& agg_expr : agg_exprs_) {
1190  boost::hash_combine(*hash_, agg_expr->toHash());
1191  }
1192  for (auto& node : inputs_) {
1193  boost::hash_combine(*hash_, node->toHash());
1194  }
1195  boost::hash_combine(*hash_, ::toString(fields_));
1196  }
1197  return *hash_;
1198  }
1199 
1200  std::shared_ptr<RelAlgNode> deepCopy() const override {
1201  return std::make_shared<RelAggregate>(*this);
1202  }
1203 
1204  void addHint(const ExplainedQueryHint& hint_explained) {
1205  if (!hint_applied_) {
1206  hint_applied_ = true;
1207  }
1208  hints_->emplace(hint_explained.getHint(), hint_explained);
1209  }
1210 
1211  const bool hasHintEnabled(QueryHint candidate_hint) const {
1212  if (hint_applied_ && !hints_->empty()) {
1213  return hints_->find(candidate_hint) != hints_->end();
1214  }
1215  return false;
1216  }
1217 
1220  CHECK(!hints_->empty());
1221  CHECK(hasHintEnabled(hint));
1222  return hints_->at(hint);
1223  }
1224 
1225  bool hasDeliveredHint() { return !hints_->empty(); }
1226 
1227  Hints* getDeliveredHints() { return hints_.get(); }
1228 
1229  private:
1230  const size_t groupby_count_;
1231  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1232  std::vector<std::string> fields_;
1234  std::unique_ptr<Hints> hints_;
1235 };
1236 
1237 class RelJoin : public RelAlgNode {
1238  public:
1239  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
1240  std::shared_ptr<const RelAlgNode> rhs,
1241  std::unique_ptr<const RexScalar>& condition,
1242  const JoinType join_type)
1243  : condition_(std::move(condition))
1244  , join_type_(join_type)
1245  , hint_applied_(false)
1246  , hints_(std::make_unique<Hints>()) {
1247  inputs_.push_back(lhs);
1248  inputs_.push_back(rhs);
1249  }
1250 
1251  RelJoin(RelJoin const&);
1252 
1253  JoinType getJoinType() const { return join_type_; }
1254 
1255  const RexScalar* getCondition() const { return condition_.get(); }
1256 
1257  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
1258 
1259  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1260  CHECK(condition);
1261  condition_ = std::move(condition);
1262  }
1263 
1264  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1265  std::shared_ptr<const RelAlgNode> input) override;
1266 
1267  std::string toString() const override {
1268  return cat(::typeName(this),
1269  "(",
1270  ::toString(inputs_),
1271  ", condition=",
1272  (condition_ ? condition_->toString() : "null"),
1273  ", join_type=",
1274  ::toString(join_type_));
1275  }
1276 
1277  size_t toHash() const override {
1278  if (!hash_) {
1279  hash_ = typeid(RelJoin).hash_code();
1280  boost::hash_combine(*hash_,
1281  condition_ ? condition_->toHash() : boost::hash_value("n"));
1282  for (auto& node : inputs_) {
1283  boost::hash_combine(*hash_, node->toHash());
1284  }
1285  boost::hash_combine(*hash_, ::toString(getJoinType()));
1286  }
1287  return *hash_;
1288  }
1289 
1290  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
1291 
1292  std::shared_ptr<RelAlgNode> deepCopy() const override {
1293  return std::make_shared<RelJoin>(*this);
1294  }
1295 
1296  void addHint(const ExplainedQueryHint& hint_explained) {
1297  if (!hint_applied_) {
1298  hint_applied_ = true;
1299  }
1300  hints_->emplace(hint_explained.getHint(), hint_explained);
1301  }
1302 
1303  const bool hasHintEnabled(QueryHint candidate_hint) const {
1304  if (hint_applied_ && !hints_->empty()) {
1305  return hints_->find(candidate_hint) != hints_->end();
1306  }
1307  return false;
1308  }
1309 
1312  CHECK(!hints_->empty());
1313  CHECK(hasHintEnabled(hint));
1314  return hints_->at(hint);
1315  }
1316 
1317  bool hasDeliveredHint() { return !hints_->empty(); }
1318 
1319  Hints* getDeliveredHints() { return hints_.get(); }
1320 
1321  private:
1322  mutable std::unique_ptr<const RexScalar> condition_;
1325  std::unique_ptr<Hints> hints_;
1326 };
1327 
1328 // a helper node that contains detailed information of each level of join qual
1329 // which is used when extracting query plan DAG
1331  public:
1333  const RelAlgNode* rhs,
1334  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols,
1335  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols,
1336  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops,
1337  const RexScalar* outer_join_cond,
1338  const bool nested_loop,
1339  const JoinType join_type,
1340  const std::string& op_type,
1341  const std::string& qualifier,
1342  const std::string& op_typeinfo)
1343  : lhs_(lhs)
1344  , rhs_(rhs)
1345  , lhs_join_cols_(lhs_join_cols)
1346  , rhs_join_cols_(rhs_join_cols)
1347  , filter_ops_(filter_ops)
1348  , outer_join_cond_(outer_join_cond)
1349  , nested_loop_(nested_loop)
1350  , join_type_(join_type)
1351  , op_type_(op_type)
1352  , qualifier_(qualifier)
1353  , op_typeinfo_(op_typeinfo) {
1354  CHECK_EQ(lhs_join_cols_.size(), rhs_join_cols_.size());
1355  }
1356 
1357  std::string toString() const override {
1358  return cat(::typeName(this),
1359  "( join_quals { lhs: ",
1361  ", rhs: ",
1363  " }, filter_quals: { ",
1364  ::toString(filter_ops_),
1365  " }, outer_join_cond: { ",
1367  " }, loop_join: ",
1369  ", join_type: ",
1370  ::toString(join_type_),
1371  ", op_type: ",
1372  ::toString(op_type_),
1373  ", qualifier: ",
1374  ::toString(qualifier_),
1375  ", op_type_info: ",
1377  ")");
1378  }
1379  size_t toHash() const override {
1380  if (!hash_) {
1381  hash_ = typeid(RelTranslatedJoin).hash_code();
1382  boost::hash_combine(*hash_, lhs_->toHash());
1383  boost::hash_combine(*hash_, rhs_->toHash());
1384  boost::hash_combine(
1385  *hash_, outer_join_cond_ ? outer_join_cond_->toHash() : boost::hash_value("n"));
1386  boost::hash_combine(*hash_, nested_loop_);
1387  boost::hash_combine(*hash_, ::toString(join_type_));
1388  boost::hash_combine(*hash_, op_type_);
1389  boost::hash_combine(*hash_, qualifier_);
1390  boost::hash_combine(*hash_, op_typeinfo_);
1391  for (auto& filter_op : filter_ops_) {
1392  boost::hash_combine(*hash_, filter_op->toString());
1393  }
1394  }
1395  return *hash_;
1396  }
1397  const RelAlgNode* getLHS() const { return lhs_; }
1398  const RelAlgNode* getRHS() const { return rhs_; }
1399  size_t getFilterCondSize() const { return filter_ops_.size(); }
1400  const std::vector<std::shared_ptr<const Analyzer::Expr>> getFilterCond() const {
1401  return filter_ops_;
1402  }
1403  const RexScalar* getOuterJoinCond() const { return outer_join_cond_; }
1404  std::string getOpType() const { return op_type_; }
1405  std::string getQualifier() const { return qualifier_; }
1406  std::string getOpTypeInfo() const { return op_typeinfo_; }
1407  size_t size() const override { return 0; }
1408  JoinType getJoinType() const { return join_type_; }
1409  const RexScalar* getCondition() const {
1410  CHECK(false);
1411  return nullptr;
1412  }
1414  CHECK(false);
1415  return nullptr;
1416  }
1417  void setCondition(std::unique_ptr<const RexScalar>& condition) { CHECK(false); }
1418  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1419  std::shared_ptr<const RelAlgNode> input) override {
1420  CHECK(false);
1421  }
1422  std::shared_ptr<RelAlgNode> deepCopy() const override {
1423  CHECK(false);
1424  return nullptr;
1425  }
1426  std::string getFieldName(const size_t i) const;
1427  std::vector<const Analyzer::ColumnVar*> getJoinCols(bool lhs) const {
1428  if (lhs) {
1429  return lhs_join_cols_;
1430  }
1431  return rhs_join_cols_;
1432  }
1433  bool isNestedLoopQual() const { return nested_loop_; }
1434 
1435  private:
1438  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols_;
1439  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols_;
1440  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops_;
1442  const bool nested_loop_;
1444  const std::string op_type_;
1445  const std::string qualifier_;
1446  const std::string op_typeinfo_;
1447 };
1448 
1449 class RelFilter : public RelAlgNode {
1450  public:
1451  RelFilter(std::unique_ptr<const RexScalar>& filter,
1452  std::shared_ptr<const RelAlgNode> input)
1453  : filter_(std::move(filter)) {
1454  CHECK(filter_);
1455  inputs_.push_back(input);
1456  }
1457 
1458  // for dummy filter node for data recycler
1459  RelFilter(std::unique_ptr<const RexScalar>& filter) : filter_(std::move(filter)) {
1460  CHECK(filter_);
1461  }
1462 
1463  RelFilter(RelFilter const&);
1464 
1465  const RexScalar* getCondition() const { return filter_.get(); }
1466 
1467  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
1468 
1469  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1470  CHECK(condition);
1471  filter_ = std::move(condition);
1472  }
1473 
1474  size_t size() const override { return inputs_[0]->size(); }
1475 
1476  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1477  std::shared_ptr<const RelAlgNode> input) override;
1478 
1479  std::string toString() const override {
1480  return cat(::typeName(this),
1481  "(",
1482  (filter_ ? filter_->toString() : "null"),
1483  ", ",
1484  ::toString(inputs_) + ")");
1485  }
1486 
1487  size_t toHash() const override {
1488  if (!hash_) {
1489  hash_ = typeid(RelFilter).hash_code();
1490  boost::hash_combine(*hash_, filter_ ? filter_->toHash() : boost::hash_value("n"));
1491  for (auto& node : inputs_) {
1492  boost::hash_combine(*hash_, node->toHash());
1493  }
1494  }
1495  return *hash_;
1496  }
1497 
1498  std::shared_ptr<RelAlgNode> deepCopy() const override {
1499  return std::make_shared<RelFilter>(*this);
1500  }
1501 
1502  private:
1503  std::unique_ptr<const RexScalar> filter_;
1504 };
1505 
1506 // Synthetic node to assist execution of left-deep join relational algebra.
1508  public:
1509  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1510  RelAlgInputs inputs,
1511  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1512 
1513  const RexScalar* getInnerCondition() const;
1514 
1515  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1516 
1517  std::string toString() const override;
1518 
1519  size_t toHash() const override;
1520 
1521  size_t size() const override;
1522 
1523  std::shared_ptr<RelAlgNode> deepCopy() const override;
1524 
1525  bool coversOriginalNode(const RelAlgNode* node) const;
1526 
1527  const RelFilter* getOriginalFilter() const;
1528 
1529  std::vector<std::shared_ptr<const RelJoin>> getOriginalJoins() const;
1530 
1531  private:
1532  std::unique_ptr<const RexScalar> condition_;
1533  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
1534  const std::shared_ptr<RelFilter> original_filter_;
1535  const std::vector<std::shared_ptr<const RelJoin>> original_joins_;
1536 };
1537 
1538 // The 'RelCompound' node combines filter and on the fly aggregate computation.
1539 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
1540 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
1541 // which can be efficiently executed with no intermediate buffers.
1543  public:
1544  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
1545  // or aggregate expressions owned by 'agg_exprs_', with the arguments
1546  // owned by 'scalar_sources_'.
1547  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
1548  const std::vector<const Rex*>& target_exprs,
1549  const size_t groupby_count,
1550  const std::vector<const RexAgg*>& agg_exprs,
1551  const std::vector<std::string>& fields,
1552  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
1553  const bool is_agg,
1554  bool update_disguised_as_select = false,
1555  bool delete_disguised_as_select = false,
1556  bool varlen_update_required = false,
1557  TableDescriptor const* manipulation_target_table = nullptr,
1558  ColumnNameList target_columns = ColumnNameList())
1559  : ModifyManipulationTarget(update_disguised_as_select,
1560  delete_disguised_as_select,
1561  varlen_update_required,
1562  manipulation_target_table,
1563  target_columns)
1564  , filter_expr_(std::move(filter_expr))
1565  , groupby_count_(groupby_count)
1566  , fields_(fields)
1567  , is_agg_(is_agg)
1568  , scalar_sources_(std::move(scalar_sources))
1569  , target_exprs_(target_exprs)
1570  , hint_applied_(false)
1571  , hints_(std::make_unique<Hints>()) {
1572  CHECK_EQ(fields.size(), target_exprs.size());
1573  for (auto agg_expr : agg_exprs) {
1574  agg_exprs_.emplace_back(agg_expr);
1575  }
1576  }
1577 
1578  RelCompound(RelCompound const&);
1579 
1580  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1581  std::shared_ptr<const RelAlgNode> input) override;
1582 
1583  size_t size() const override { return target_exprs_.size(); }
1584 
1585  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
1586 
1587  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
1588  filter_expr_ = std::move(new_expr);
1589  }
1590 
1591  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
1592 
1593  const std::vector<std::string>& getFields() const { return fields_; }
1594 
1595  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1596 
1597  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
1598 
1599  const RexScalar* getScalarSource(const size_t i) const {
1600  return scalar_sources_[i].get();
1601  }
1602 
1603  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
1604  CHECK_EQ(new_sources.size(), scalar_sources_.size());
1605  scalar_sources_ = std::move(new_sources);
1606  }
1607 
1608  const size_t getGroupByCount() const { return groupby_count_; }
1609 
1610  bool isAggregate() const { return is_agg_; }
1611 
1612  size_t getAggExprSize() const { return agg_exprs_.size(); }
1613 
1614  const RexAgg* getAggExpr(size_t i) const { return agg_exprs_[i].get(); }
1615 
1616  std::string toString() const override;
1617 
1618  size_t toHash() const override;
1619 
1620  std::shared_ptr<RelAlgNode> deepCopy() const override {
1621  return std::make_shared<RelCompound>(*this);
1622  }
1623 
1624  void addHint(const ExplainedQueryHint& hint_explained) {
1625  if (!hint_applied_) {
1626  hint_applied_ = true;
1627  }
1628  hints_->emplace(hint_explained.getHint(), hint_explained);
1629  }
1630 
1631  const bool hasHintEnabled(QueryHint candidate_hint) const {
1632  if (hint_applied_ && !hints_->empty()) {
1633  return hints_->find(candidate_hint) != hints_->end();
1634  }
1635  return false;
1636  }
1637 
1640  CHECK(!hints_->empty());
1641  CHECK(hasHintEnabled(hint));
1642  return hints_->at(hint);
1643  }
1644 
1645  bool hasDeliveredHint() { return !hints_->empty(); }
1646 
1647  Hints* getDeliveredHints() { return hints_.get(); }
1648 
1649  private:
1650  std::unique_ptr<const RexScalar> filter_expr_;
1651  const size_t groupby_count_;
1652  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1653  const std::vector<std::string> fields_;
1654  const bool is_agg_;
1655  std::vector<std::unique_ptr<const RexScalar>>
1656  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not actually
1657  // projected, just owned
1658  const std::vector<const Rex*> target_exprs_;
1660  std::unique_ptr<Hints> hints_;
1661 };
1662 
1663 class RelSort : public RelAlgNode {
1664  public:
1665  RelSort(const std::vector<SortField>& collation,
1666  const size_t limit,
1667  const size_t offset,
1668  std::shared_ptr<const RelAlgNode> input)
1669  : collation_(collation), limit_(limit), offset_(offset) {
1670  inputs_.push_back(input);
1671  }
1672 
1673  bool operator==(const RelSort& that) const {
1674  return limit_ == that.limit_ && offset_ == that.offset_ &&
1676  }
1677 
1678  size_t collationCount() const { return collation_.size(); }
1679 
1680  SortField getCollation(const size_t i) const {
1681  CHECK_LT(i, collation_.size());
1682  return collation_[i];
1683  }
1684 
1685  void setCollation(std::vector<SortField>&& collation) {
1686  collation_ = std::move(collation);
1687  }
1688 
1689  void setEmptyResult(bool emptyResult) { empty_result_ = emptyResult; }
1690 
1691  bool isEmptyResult() const { return empty_result_; }
1692 
1693  size_t getLimit() const { return limit_; }
1694 
1695  size_t getOffset() const { return offset_; }
1696 
1697  std::string toString() const override {
1698  return cat(::typeName(this),
1699  "(",
1700  "empty_result: ",
1702  ", collation=",
1703  ::toString(collation_),
1704  ", limit=",
1706  ", offset",
1708  ", inputs=",
1709  ::toString(inputs_),
1710  ")");
1711  }
1712 
1713  size_t toHash() const override {
1714  if (!hash_) {
1715  hash_ = typeid(RelSort).hash_code();
1716  for (auto& collation : collation_) {
1717  boost::hash_combine(*hash_, collation.toHash());
1718  }
1719  boost::hash_combine(*hash_, empty_result_);
1720  boost::hash_combine(*hash_, limit_);
1721  boost::hash_combine(*hash_, offset_);
1722  for (auto& node : inputs_) {
1723  boost::hash_combine(*hash_, node->toHash());
1724  }
1725  }
1726  return *hash_;
1727  }
1728 
1729  size_t size() const override { return inputs_[0]->size(); }
1730 
1731  std::shared_ptr<RelAlgNode> deepCopy() const override {
1732  return std::make_shared<RelSort>(*this);
1733  }
1734 
1735  private:
1736  std::vector<SortField> collation_;
1737  const size_t limit_;
1738  const size_t offset_;
1740 
1741  bool hasEquivCollationOf(const RelSort& that) const;
1742 };
1743 
1744 class RelModify : public RelAlgNode {
1745  public:
1747  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
1748  using TargetColumnList = std::vector<std::string>;
1749 
1750  static std::string yieldModifyOperationString(ModifyOperation const op) {
1751  switch (op) {
1753  return "DELETE";
1755  return "INSERT";
1757  return "UPDATE";
1758  default:
1759  break;
1760  }
1761  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
1762  }
1763 
1764  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
1765  if (op_string == "INSERT") {
1766  return ModifyOperation::Insert;
1767  } else if (op_string == "DELETE") {
1768  return ModifyOperation::Delete;
1769  } else if (op_string == "UPDATE") {
1770  return ModifyOperation::Update;
1771  }
1772 
1773  throw std::runtime_error(
1774  std::string("Unsupported logical modify operation encountered " + op_string));
1775  }
1776 
1778  TableDescriptor const* const td,
1779  bool flattened,
1780  std::string const& op_string,
1781  TargetColumnList const& target_column_list,
1782  RelAlgNodeInputPtr input)
1783  : catalog_(cat)
1784  , table_descriptor_(td)
1785  , flattened_(flattened)
1786  , operation_(yieldModifyOperationEnum(op_string))
1787  , target_column_list_(target_column_list) {
1789  inputs_.push_back(input);
1790  }
1791 
1793  TableDescriptor const* const td,
1794  bool flattened,
1795  ModifyOperation op,
1796  TargetColumnList const& target_column_list,
1797  RelAlgNodeInputPtr input)
1798  : catalog_(cat)
1799  , table_descriptor_(td)
1800  , flattened_(flattened)
1801  , operation_(op)
1802  , target_column_list_(target_column_list) {
1804  inputs_.push_back(input);
1805  }
1806 
1807  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
1808  bool const isFlattened() const { return flattened_; }
1811  int getUpdateColumnCount() const { return target_column_list_.size(); }
1812 
1813  size_t size() const override { return 0; }
1814  std::shared_ptr<RelAlgNode> deepCopy() const override {
1815  return std::make_shared<RelModify>(*this);
1816  }
1817 
1818  std::string toString() const override {
1819  return cat(::typeName(this),
1820  "(",
1822  ", flattened=",
1824  ", op=",
1826  ", target_column_list=",
1828  ", inputs=",
1829  ::toString(inputs_),
1830  ")");
1831  }
1832 
1833  size_t toHash() const override {
1834  if (!hash_) {
1835  hash_ = typeid(RelModify).hash_code();
1836  boost::hash_combine(*hash_, table_descriptor_->tableName);
1837  boost::hash_combine(*hash_, flattened_);
1838  boost::hash_combine(*hash_, yieldModifyOperationString(operation_));
1839  boost::hash_combine(*hash_, ::toString(target_column_list_));
1840  for (auto& node : inputs_) {
1841  boost::hash_combine(*hash_, node->toHash());
1842  }
1843  }
1844  return *hash_;
1845  }
1846 
1848  RelProject const* previous_project_node =
1849  dynamic_cast<RelProject const*>(inputs_[0].get());
1850  CHECK(previous_project_node != nullptr);
1851 
1852  previous_project_node->setUpdateViaSelectFlag();
1853  // remove the offset column in the projection for update handling
1854  target_column_list_.pop_back();
1855 
1856  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1857  previous_project_node->setTargetColumns(target_column_list_);
1858 
1859  int target_update_column_expr_start = 0;
1860  int target_update_column_expr_end = (int)(target_column_list_.size() - 1);
1861  CHECK(target_update_column_expr_start >= 0);
1862  CHECK(target_update_column_expr_end >= 0);
1863 
1864  bool varlen_update_required = false;
1865 
1866  auto varlen_scan_visitor = [this,
1867  &varlen_update_required,
1868  target_update_column_expr_start,
1869  target_update_column_expr_end](int index) {
1870  if (index >= target_update_column_expr_start &&
1871  index <= target_update_column_expr_end) {
1872  auto target_index = index - target_update_column_expr_start;
1873 
1874  auto* column_desc = catalog_.getMetadataForColumn(
1876  CHECK(column_desc);
1877 
1878  if (table_descriptor_->nShards) {
1879  const auto shard_cd =
1881  CHECK(shard_cd);
1882  if ((column_desc->columnName == shard_cd->columnName)) {
1883  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
1884  }
1885  }
1886 
1887  // Check for valid types
1888  if (column_desc->columnType.is_varlen()) {
1889  varlen_update_required = true;
1890  }
1891  if (column_desc->columnType.is_geometry()) {
1892  throw std::runtime_error("UPDATE of a geo column is unsupported.");
1893  }
1894  }
1895  };
1896 
1897  previous_project_node->visitScalarExprs(varlen_scan_visitor);
1898  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
1899  }
1900 
1902  RelProject const* previous_project_node =
1903  dynamic_cast<RelProject const*>(inputs_[0].get());
1904  CHECK(previous_project_node != nullptr);
1905  previous_project_node->setDeleteViaSelectFlag();
1906  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1907  }
1908 
1909  private:
1915 };
1916 
1918  public:
1919  RelTableFunction(const std::string& function_name,
1920  RelAlgInputs inputs,
1921  std::vector<std::string>& fields,
1922  std::vector<const Rex*> col_inputs,
1923  std::vector<std::unique_ptr<const RexScalar>>& table_func_inputs,
1924  std::vector<std::unique_ptr<const RexScalar>>& target_exprs)
1925  : function_name_(function_name)
1926  , fields_(fields)
1927  , col_inputs_(col_inputs)
1928  , table_func_inputs_(std::move(table_func_inputs))
1929  , target_exprs_(std::move(target_exprs)) {
1930  for (const auto& input : inputs) {
1931  inputs_.emplace_back(input);
1932  }
1933  }
1934 
1936 
1937  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1938  std::shared_ptr<const RelAlgNode> input) override;
1939 
1940  std::string getFunctionName() const { return function_name_; }
1941 
1942  size_t size() const override { return target_exprs_.size(); }
1943 
1944  const RexScalar* getTargetExpr(size_t idx) const {
1945  CHECK_LT(idx, target_exprs_.size());
1946  return target_exprs_[idx].get();
1947  }
1948 
1949  size_t getTableFuncInputsSize() const { return table_func_inputs_.size(); }
1950 
1951  size_t getColInputsSize() const { return col_inputs_.size(); }
1952 
1953  int32_t countRexLiteralArgs() const;
1954 
1955  const RexScalar* getTableFuncInputAt(const size_t idx) const {
1956  CHECK_LT(idx, table_func_inputs_.size());
1957  return table_func_inputs_[idx].get();
1958  }
1959 
1960  const RexScalar* getTableFuncInputAtAndRelease(const size_t idx) {
1961  CHECK_LT(idx, table_func_inputs_.size());
1962  return table_func_inputs_[idx].release();
1963  }
1964 
1965  void setTableFuncInputs(std::vector<std::unique_ptr<const RexScalar>>& exprs) {
1966  table_func_inputs_ = std::move(exprs);
1967  }
1968 
1969  std::string getFieldName(const size_t idx) const {
1970  CHECK_LT(idx, fields_.size());
1971  return fields_[idx];
1972  }
1973 
1974  const std::vector<std::string>& getFields() const { return fields_; }
1975 
1976  std::shared_ptr<RelAlgNode> deepCopy() const override {
1977  return std::make_shared<RelTableFunction>(*this);
1978  }
1979 
1980  std::string toString() const override {
1981  return cat(::typeName(this),
1982  "(",
1984  ", inputs=",
1985  ::toString(inputs_),
1986  ", fields=",
1987  ::toString(fields_),
1988  ", col_inputs=...",
1989  ", table_func_inputs=",
1991  ", target_exprs=",
1993  ")");
1994  }
1995 
1996  size_t toHash() const override {
1997  if (!hash_) {
1998  hash_ = typeid(RelTableFunction).hash_code();
1999  for (auto& table_func_input : table_func_inputs_) {
2000  boost::hash_combine(*hash_, table_func_input->toHash());
2001  }
2002  for (auto& target_expr : target_exprs_) {
2003  boost::hash_combine(*hash_, target_expr->toHash());
2004  }
2005  boost::hash_combine(*hash_, function_name_);
2006  boost::hash_combine(*hash_, ::toString(fields_));
2007  for (auto& node : inputs_) {
2008  boost::hash_combine(*hash_, node->toHash());
2009  }
2010  }
2011  return *hash_;
2012  }
2013 
2014  private:
2015  std::string function_name_;
2016  std::vector<std::string> fields_;
2017 
2018  std::vector<const Rex*>
2019  col_inputs_; // owned by `table_func_inputs_`, but allows picking out the specific
2020  // input columns vs other table function inputs (e.g. literals)
2021  std::vector<std::unique_ptr<const RexScalar>> table_func_inputs_;
2022 
2023  std::vector<std::unique_ptr<const RexScalar>>
2024  target_exprs_; // Note: these should all be RexRef but are stored as RexScalar for
2025  // consistency
2026 };
2027 
2029  public:
2030  using RowValues = std::vector<std::unique_ptr<const RexScalar>>;
2031 
2032  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type,
2033  std::vector<RowValues>& values)
2034  : tuple_type_(tuple_type), values_(std::move(values)) {}
2035 
2037 
2038  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
2039 
2040  std::string toString() const override {
2041  std::string ret = ::typeName(this) + "(";
2042  for (const auto& target_meta_info : tuple_type_) {
2043  ret += " (" + target_meta_info.get_resname() + " " +
2044  target_meta_info.get_type_info().get_type_name() + ")";
2045  }
2046  ret += ")";
2047  return ret;
2048  }
2049 
2050  size_t toHash() const override {
2051  if (!hash_) {
2052  hash_ = typeid(RelLogicalValues).hash_code();
2053  for (auto& target_meta_info : tuple_type_) {
2054  boost::hash_combine(*hash_, target_meta_info.get_resname());
2055  boost::hash_combine(*hash_, target_meta_info.get_type_info().get_type_name());
2056  }
2057  }
2058  return *hash_;
2059  }
2060 
2061  const RexScalar* getValueAt(const size_t row_idx, const size_t col_idx) const {
2062  CHECK_LT(row_idx, values_.size());
2063  const auto& row = values_[row_idx];
2064  CHECK_LT(col_idx, row.size());
2065  return row[col_idx].get();
2066  }
2067 
2068  size_t getRowsSize() const {
2069  if (values_.empty()) {
2070  return 0;
2071  } else {
2072  return values_.front().size();
2073  }
2074  }
2075 
2076  size_t getNumRows() const { return values_.size(); }
2077 
2078  size_t size() const override { return tuple_type_.size(); }
2079 
2080  bool hasRows() const { return !values_.empty(); }
2081 
2082  std::shared_ptr<RelAlgNode> deepCopy() const override {
2083  return std::make_shared<RelLogicalValues>(*this);
2084  }
2085 
2086  private:
2087  const std::vector<TargetMetaInfo> tuple_type_;
2088  const std::vector<RowValues> values_;
2089 };
2090 
2091 class RelLogicalUnion : public RelAlgNode {
2092  public:
2093  RelLogicalUnion(RelAlgInputs, bool is_all);
2094  std::shared_ptr<RelAlgNode> deepCopy() const override {
2095  return std::make_shared<RelLogicalUnion>(*this);
2096  }
2097  size_t size() const override;
2098  std::string toString() const override;
2099  size_t toHash() const override;
2100 
2101  std::string getFieldName(const size_t i) const;
2102 
2103  inline bool isAll() const { return is_all_; }
2104  // Will throw a std::runtime_error if MetaInfo types don't match.
2105  void checkForMatchingMetaInfoTypes() const;
2106  RexScalar const* copyAndRedirectSource(RexScalar const*, size_t input_idx) const;
2107 
2108  // Not unique_ptr to allow for an easy deepCopy() implementation.
2109  mutable std::vector<std::shared_ptr<const RexScalar>> scalar_exprs_;
2110 
2111  private:
2112  bool const is_all_;
2113 };
2114 
2115 class QueryNotSupported : public std::runtime_error {
2116  public:
2117  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
2118 };
2119 
2129 class RelAlgDagBuilder : public boost::noncopyable {
2130  public:
2131  RelAlgDagBuilder() = delete;
2132 
2139  RelAlgDagBuilder(const std::string& query_ra,
2141  const RenderInfo* render_info);
2142 
2152  RelAlgDagBuilder(RelAlgDagBuilder& root_dag_builder,
2153  const rapidjson::Value& query_ast,
2154  const Catalog_Namespace::Catalog& cat,
2155  const RenderInfo* render_opts);
2156 
2157  void eachNode(std::function<void(RelAlgNode const*)> const&) const;
2158 
2162  const RelAlgNode& getRootNode() const {
2163  CHECK(nodes_.size());
2164  const auto& last_ptr = nodes_.back();
2165  CHECK(last_ptr);
2166  return *last_ptr;
2167  }
2168 
2169  std::shared_ptr<const RelAlgNode> getRootNodeShPtr() const {
2170  CHECK(nodes_.size());
2171  return nodes_.back();
2172  }
2173 
2178  void registerSubquery(std::shared_ptr<RexSubQuery> subquery) {
2179  subqueries_.push_back(subquery);
2180  }
2181 
2185  const std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries() const {
2186  return subqueries_;
2187  }
2188 
2189  void registerQueryHints(Hints* hints_delivered) {
2190  for (auto it = hints_delivered->begin(); it != hints_delivered->end(); it++) {
2191  auto target = it->second;
2192  auto hint_type = it->first;
2193  switch (hint_type) {
2194  case QueryHint::kCpuMode: {
2196  query_hint_.cpu_mode = true;
2197  VLOG(1) << "A user forces to run the query on the CPU execution mode";
2198  break;
2199  }
2201  CHECK(target.getListOptions().size() == 1);
2202  double overlaps_bucket_threshold = std::stod(target.getListOptions()[0]);
2203  if (overlaps_bucket_threshold >= 0.0 && overlaps_bucket_threshold <= 90.0) {
2205  query_hint_.overlaps_bucket_threshold = overlaps_bucket_threshold;
2206  } else {
2207  VLOG(1) << "Skip the given query hint \"overlaps_bucket_threshold\" ("
2208  << overlaps_bucket_threshold
2209  << ") : the hint value should be within 0.0 ~ 90.0";
2210  }
2211  break;
2212  }
2214  CHECK(target.getListOptions().size() == 1);
2215  std::stringstream ss(target.getListOptions()[0]);
2216  int overlaps_max_size;
2217  ss >> overlaps_max_size;
2218  if (overlaps_max_size >= 0) {
2220  query_hint_.overlaps_max_size = (size_t)overlaps_max_size;
2221  } else {
2222  VLOG(1) << "Skip the query hint \"overlaps_max_size\" (" << overlaps_max_size
2223  << ") : the hint value should be larger than or equal to zero";
2224  }
2225  break;
2226  }
2230  VLOG(1) << "Allowing GPU hash table build for overlaps join.";
2231  break;
2232  }
2236  VLOG(1) << "Skip auto tuner and hashtable caching for overlaps join.";
2237  break;
2238  }
2240  CHECK(target.getListOptions().size() == 1);
2241  double overlaps_keys_per_bin = std::stod(target.getListOptions()[0]);
2242  if (overlaps_keys_per_bin > 0.0 &&
2243  overlaps_keys_per_bin < std::numeric_limits<double>::max()) {
2245  query_hint_.overlaps_keys_per_bin = overlaps_keys_per_bin;
2246  } else {
2247  VLOG(1) << "Skip the given query hint \"overlaps_keys_per_bin\" ("
2248  << overlaps_keys_per_bin
2249  << ") : the hint value should be larger than zero";
2250  }
2251  break;
2252  }
2253  default:
2254  break;
2255  }
2256  }
2257  }
2258 
2260 
2264  void resetQueryExecutionState();
2265 
2266  private:
2267  void build(const rapidjson::Value& query_ast, RelAlgDagBuilder& root_dag_builder);
2268 
2270  std::vector<std::shared_ptr<RelAlgNode>> nodes_;
2271  std::vector<std::shared_ptr<RexSubQuery>> subqueries_;
2274 };
2275 
2276 using RANodeOutput = std::vector<RexInput>;
2277 
2278 RANodeOutput get_node_output(const RelAlgNode* ra_node);
2279 
2280 std::string tree_string(const RelAlgNode*, const size_t depth = 0);
std::vector< std::shared_ptr< const RexScalar > > scalar_exprs_
DEVICE auto upper_bound(ARGS &&...args)
Definition: gpu_enabled.h:123
std::shared_ptr< RelAlgNode > deepCopy() const override
const size_t getGroupByCount() const
bool hasRows() const
bool isAll() const
std::string toString() const override
std::string toString() const override
std::shared_ptr< const RelAlgNode > getRootNodeShPtr() const
bool is_agg(const Analyzer::Expr *expr)
void validate_non_foreign_table_write(const TableDescriptor *table_descriptor)
Definition: FsiUtils.h:22
SortField getCollation(const size_t i) const
std::unique_ptr< const RexScalar > condition_
const RexScalar * getThen(const size_t idx) const
SQLAgg
Definition: sqldefs.h:71
bool isNestedLoopQual() const
#define CHECK_EQ(x, y)
Definition: Logger.h:214
std::unique_ptr< const RexScalar > ConstRexScalarPtr
std::vector< std::unique_ptr< const RexScalar > > getExpressionsAndRelease()
size_t getOffset() const
void setFields(std::vector< std::string > &fields)
void setVarlenUpdateRequired(bool required) const
std::vector< std::unique_ptr< const RexScalar > > outer_conditions_per_level_
const size_t limit_
bool const isFlattened() const
std::unique_ptr< RexSubQuery > deepCopy() const
ConstRexScalarPtrVector getPartitionKeysAndRelease() const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
JoinType
Definition: sqldefs.h:108
std::string toString() const override
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t toHash() const
int getUpdateColumnCount() const
ColumnNameList target_columns_
const bool hasHintEnabled(QueryHint candidate_hint) const
std::vector< std::unique_ptr< const RexScalar > > table_func_inputs_
std::string toString() const override
size_t toHash() const override
std::string cat(Ts &&...args)
const Rex * getTargetExpr(const size_t i) const
RexLiteral(const std::string &val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
SQLAgg getKind() const
size_t toHash() const override
const std::shared_ptr< const RelAlgNode > ra_
RelAlgNode(RelAlgInputs inputs={})
std::string getOpTypeInfo() const
size_t size() const override
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:102
Hints * getDeliveredHints()
const std::vector< std::shared_ptr< const Analyzer::Expr > > getFilterCond() const
size_t size() const override
const size_t index_
SQLTypes
Definition: sqltypes.h:37
std::shared_ptr< RelAlgNode > deepCopy() const override
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
void addHint(const ExplainedQueryHint &hint_explained)
std::string tableName
const std::string name_
bool coversOriginalNode(const RelAlgNode *node) const
const RexScalar * getFilterExpr() const
size_t size() const override
const unsigned type_scale_
size_t getOperand(size_t idx) const
size_t toHash() const override
TargetColumnList const & getUpdateColumnNames() const
std::string toString() const override
std::string toString() const override
const RexScalar * getElse() const
RexOperator(const SQLOps op, std::vector< std::unique_ptr< const RexScalar >> &operands, const SQLTypeInfo &type)
RelCompound(std::unique_ptr< const RexScalar > &filter_expr, const std::vector< const Rex * > &target_exprs, const size_t groupby_count, const std::vector< const RexAgg * > &agg_exprs, const std::vector< std::string > &fields, std::vector< std::unique_ptr< const RexScalar >> &scalar_sources, const bool is_agg, bool update_disguised_as_select=false, bool delete_disguised_as_select=false, bool varlen_update_required=false, TableDescriptor const *manipulation_target_table=nullptr, ColumnNameList target_columns=ColumnNameList())
size_t getIndex() const
static thread_local unsigned crt_id_
void setCondition(std::unique_ptr< const RexScalar > &condition)
void setTargetColumns(ColumnNameList const &target_columns) const
std::string function_name_
const std::string getFieldName(const size_t i) const
std::unique_ptr< RexRef > deepCopy() const
const RexScalar * outer_join_cond_
void setEmptyResult(bool emptyResult)
bool overlaps_allow_gpu_build
Definition: QueryHint.h:169
RexScalar const * copyAndRedirectSource(RexScalar const *, size_t input_idx) const
std::unique_ptr< const RexScalar > ConstRexScalarPtr
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
const RexScalar * getOuterCondition(const size_t nesting_level) const
#define const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
const JoinType join_type_
NullSortedPosition
void applyDeleteModificationsToInputNode()
bool operator==(const SortField &that) const
std::vector< std::string > TargetColumnList
size_t size() const override
const SQLTypeInfo & getType() const
size_t size() const
Hints * getDeliveredHints()
const RexScalar * getOperand(const size_t idx) const
const RexWindowBound upper_bound_
const SqlWindowFunctionKind kind_
std::string toString() const override
size_t size() const override
std::vector< const Rex * > col_inputs_
const JoinType join_type_
bool hasEquivCollationOf(const RelSort &that) const
const std::vector< SortField > & getCollation() const
SQLOps
Definition: sqldefs.h:29
const std::vector< std::string > fields_
SortDirection getSortDir() const
size_t getNumRows() const
bool hasDeliveredHint()
const SQLTypeInfo & getType() const
size_t toHash() const override
const bool hasHintEnabled(QueryHint candidate_hint) const
void setRelNodeDagId(const size_t id) const
std::string toString() const override
const std::vector< const Analyzer::ColumnVar * > lhs_join_cols_
void applyUpdateModificationsToInputNode()
std::string toString() const override
const boost::variant< int64_t, double, std::string, bool, void * > literal_
std::string getFieldName(const size_t idx) const
void build(const rapidjson::Value &query_ast, RelAlgDagBuilder &root_dag_builder)
const RexScalar * getCondition() const
string name
Definition: setup.in.py:72
std::shared_ptr< std::shared_ptr< const ExecutionResult > > result_
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const
RexSubQuery & operator=(const RexSubQuery &)=delete
std::unique_ptr< const RexScalar > else_expr_
const std::vector< TargetMetaInfo > getTupleType() const
size_t toHash() const override
const std::vector< std::string > & getFields() const
void addManagedInput(std::shared_ptr< const RelAlgNode > input)
unsigned getScale() const
bool hint_applied_
const std::vector< TargetMetaInfo > tuple_type_
RexSubQuery(std::shared_ptr< SQLTypeInfo > type, std::shared_ptr< std::shared_ptr< const ExecutionResult >> result, const std::shared_ptr< const RelAlgNode > ra)
size_t getField() const
std::string toString() const override
std::vector< std::string > fields_
size_t toHash() const override
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
RexInput(const RelAlgNode *node, const unsigned in_index)
void addHint(const ExplainedQueryHint &hint_explained)
std::shared_ptr< RelAlgNode > deepCopy() const override
const RexScalar * getWhen(const size_t idx) const
const void * context_data_
double overlaps_keys_per_bin
Definition: QueryHint.h:171
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
std::vector< const Analyzer::ColumnVar * > getJoinCols(bool lhs) const
bool hasDeliveredHint()
void appendInput(std::string new_field_name, std::unique_ptr< const RexScalar > new_input)
const RexScalar * getCondition() const
std::string getOpType() const
std::shared_ptr< RelAlgNode > deepCopy() const override
bool empty_result_
void addHint(const ExplainedQueryHint &hint_explained)
const RelAlgNode * rhs_
virtual ~Rex()
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
RelFilter(std::unique_ptr< const RexScalar > &filter)
const TableDescriptor * td_
const Catalog_Namespace::Catalog & cat_
size_t operator()(const RexInput &rex_in) const
const std::string op_type_
const RexScalar * getOperandAndRelease(const size_t idx) const
void checkForMatchingMetaInfoTypes() const
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:4101
virtual std::shared_ptr< RelAlgNode > deepCopy() const =0
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
const SQLOps op_
size_t toHash() const override
const std::string getFieldName(const size_t i) const
std::string to_string(char const *&&v)
void clearContextData() const
TableDescriptor const *const getTableDescriptor() const
const SQLAgg agg_
const size_t groupby_count_
std::string toString() const override
unsigned getTypePrecision() const
const std::string getFieldName(const size_t i) const
const std::string qualifier_
std::vector< SortField > collation_
const RegisteredQueryHint getQueryHints() const
std::string toString() const override
std::string toString() const override
size_t getRowsSize() const
size_t getColInputsSize() const
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
std::vector< RexLiteral > RexLiteralArray
void setDeleteViaSelectFlag() const
This file contains the class specification and related data structures for Catalog.
const size_t getScalarSourcesSize() const
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
const RenderInfo * render_info_
std::string to_string() const
Definition: sqltypes.h:466
RexLiteral(const double val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
const RelAlgNode * getRHS() const
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const unsigned precision_
unsigned getIndex() const
bool isNop() const
std::string toString() const override
size_t toHash() const override
virtual ~RelAlgNode()
SQLOps getOperator() const
std::vector< std::shared_ptr< RelAlgNode > > nodes_
std::shared_ptr< const RelAlgNode > RelAlgNodeInputPtr
const RexScalar * getCondition() const
void registerQueryHints(Hints *hints_delivered)
std::shared_ptr< RelAlgNode > deepCopy() const override
unsigned getId() const
bool hasDeliveredHint()
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
const SQLTypeInfo & getType() const
const bool hasHintEnabled(const QueryHint candidate_hint) const
const bool distinct_
ColumnNameList const & getTargetColumns() const
size_t dag_node_id_
std::unique_ptr< const RexOperator > disambiguatedOperands(ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > &collation) const
const NullSortedPosition nulls_pos_
const size_t offset_
#define CHECK_NE(x, y)
Definition: Logger.h:215
const std::vector< RowValues > values_
RexCase(std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar >>> &expr_pair_list, std::unique_ptr< const RexScalar > &else_expr)
NullSortedPosition getNullsPosition() const
bool isRenaming() const
void setIndex(const unsigned in_index) const
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
T getVal() const
size_t toHash() const override
Hints * getDeliveredHints()
const SQLTypeInfo type_
const RexScalar * getAndReleaseCondition() const
std::unique_ptr< Hints > hints_
const TableDescriptor * table_descriptor_
const std::vector< std::shared_ptr< const RelJoin > > original_joins_
std::shared_ptr< const RexScalar > offset
std::unique_ptr< Hints > hints_
std::vector< std::unique_ptr< const RexScalar > > scalar_exprs_
void registerHint(const QueryHint hint)
Definition: QueryHint.h:196
const RelAlgNode * lhs_
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t toHash() const override
size_t size() const override
std::shared_ptr< SQLTypeInfo > type_
size_t size() const override
const RexScalar * getAndReleaseCondition()
std::string getFieldName(const size_t i) const
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
void addHint(const ExplainedQueryHint &hint_explained)
size_t branchCount() const
RexSubQuery(const std::shared_ptr< const RelAlgNode > ra)
const RelAlgNode * getInput(const size_t idx) const
RexAbstractInput(const unsigned in_index)
RelFilter(std::unique_ptr< const RexScalar > &filter, std::shared_ptr< const RelAlgNode > input)
const std::vector< std::shared_ptr< const Analyzer::Expr > > filter_ops_
std::vector< std::shared_ptr< const RelJoin > > getOriginalJoins() const
Catalog_Namespace::Catalog const & catalog_
const unsigned type_precision_
const RelAlgNode & getRootNode() const
std::string toString() const override
RelAggregate(const size_t groupby_count, std::vector< std::unique_ptr< const RexAgg >> &agg_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
std::unique_ptr< const RexScalar > filter_
void setCondition(std::unique_ptr< const RexScalar > &condition)
bool isSimple() const
std::vector< std::unique_ptr< const RexScalar > > operands_
std::optional< size_t > hash_
const size_t groupby_count_
size_t toHash() const override
std::vector< std::string > fields_
std::shared_ptr< RelAlgNode > deepCopy() const override
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
std::optional< size_t > hash_
RelSort(const std::vector< SortField > &collation, const size_t limit, const size_t offset, std::shared_ptr< const RelAlgNode > input)
const RexScalar * getProjectAtAndRelease(const size_t idx) const
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
unsigned getId() const
std::shared_ptr< RelAlgNode > deepCopy() const override
const RelAlgNode * node_
std::unique_ptr< Hints > hints_
size_t getTableFuncInputsSize() const
std::unique_ptr< RexLiteral > deepCopy() const
virtual void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input)
std::string toString() const
void eachNode(std::function< void(RelAlgNode const *)> const &) const
static std::string yieldModifyOperationString(ModifyOperation const op)
ModifyOperation getOperation() const
std::unique_ptr< RexInput > deepCopy() const
void setModifiedTableDescriptor(TableDescriptor const *td) const
size_t size() const override
const SQLTypes type_
static ModifyOperation yieldModifyOperationEnum(std::string const &op_string)
void setScalarSources(std::vector< std::unique_ptr< const RexScalar >> &new_sources)
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
std::vector< TargetMetaInfo > targets_metainfo_
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Hints * getDeliveredHints()
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
bool isEmptyResult() const
const RelAlgNode * getRelAlg() const
size_t size() const override
size_t toHash() const override
size_t size() const override
SortDirection
RexWindowFunctionOperator(const SqlWindowFunctionKind kind, ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > collation, const RexWindowBound &lower_bound, const RexWindowBound &upper_bound, const bool is_rows, const SQLTypeInfo &ti)
const RexScalar * getProjectAt(const size_t idx) const
std::vector< std::shared_ptr< const RelAlgNode >> RelAlgInputs
const std::vector< SortField > collation_
const std::vector< std::string > & getFields() const
#define CHECK_LT(x, y)
Definition: Logger.h:216
Definition: sqltypes.h:51
bool hasInput(const RelAlgNode *needle) const
const std::vector< std::string > & getFieldNames() const
const std::vector< std::string > & getFields() const
const std::vector< const Analyzer::ColumnVar * > rhs_join_cols_
void setCollation(std::vector< SortField > &&collation)
int32_t countRexLiteralArgs() const
std::unique_ptr< Hints > hints_
size_t overlaps_max_size
Definition: QueryHint.h:168
const ConstRexScalarPtrVector & getPartitionKeys() const
const RexWindowBound & getLowerBound() const
const RelAlgNode * getLHS() const
std::string tree_string(const RelAlgNode *ra, const size_t depth)
DEVICE auto lower_bound(ARGS &&...args)
Definition: gpu_enabled.h:78
std::string toString() const override
const void * getContextData() const
std::unique_ptr< Hints > hints_
const std::vector< const Rex * > target_exprs_
void addHint(const ExplainedQueryHint &hint_explained)
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
const RexScalar * getOuterJoinCond() const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
RelLogicalUnion(RelAlgInputs, bool is_all)
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
SortField(const size_t field, const SortDirection sort_dir, const NullSortedPosition nulls_pos)
std::unique_ptr< const RexScalar > filter_expr_
void setSourceNode(const RelAlgNode *node) const
void resetQueryExecutionState()
bool hasWindowFunctionExpr() const
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
ConstRexScalarPtrVector order_keys_
SqlWindowFunctionKind getKind() const
const size_t getGroupByCount() const
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:213
size_t toHash() const override
RegisteredQueryHint query_hint_
size_t collationCount() const
QueryHint
Definition: QueryHint.h:28
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, ModifyOperation op, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
virtual size_t size() const =0
const RelAlgNode * getSourceNode() const
auto const isDeleteViaSelect() const
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
void setExecutionResult(const std::shared_ptr< const ExecutionResult > result)
bool operator==(const RelSort &that) const
bool isAggregate() const
const RelFilter * getOriginalFilter() const
size_t getLimit() const
std::shared_ptr< RelAlgNode > deepCopy() const override
JoinType getJoinType() const
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type, std::vector< RowValues > &values)
std::string toString() const override
std::string get_type_name() const
Definition: sqltypes.h:426
std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const override
RexLiteral(const bool val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
bool hint_applied_
bool hasDeliveredHint()
std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar > > > expr_pair_list_
std::string typeName(const T *v)
Definition: toString.h:85
RelAlgDagBuilder()=delete
SqlWindowFunctionKind
Definition: sqldefs.h:83
size_t toHash() const override
RexFunctionOperator(const std::string &name, ConstRexScalarPtrVector &operands, const SQLTypeInfo &ti)
const SQLTypes target_type_
std::unique_ptr< const RexScalar > condition_
const RexWindowBound & getUpperBound() const
const std::vector< std::string > field_names_
RelLeftDeepInnerJoin(const std::shared_ptr< RelFilter > &filter, RelAlgInputs inputs, std::vector< std::shared_ptr< const RelJoin >> &original_joins)
const RexScalar * getTableFuncInputAt(const size_t idx) const
unsigned getPrecision() const
RelTableFunction(const std::string &function_name, RelAlgInputs inputs, std::vector< std::string > &fields, std::vector< const Rex * > col_inputs, std::vector< std::unique_ptr< const RexScalar >> &table_func_inputs, std::vector< std::unique_ptr< const RexScalar >> &target_exprs)
std::string getFunctionName() const
std::string toString() const override
virtual std::string toString() const =0
const SortDirection sort_dir_
std::vector< const RexAgg * > getAggregatesAndRelease()
const std::vector< std::string > & getFields() const
bool isDistinct() const
std::string getFieldName(const size_t i) const
const RexScalar * getValueAt(const size_t row_idx, const size_t col_idx) const
size_t toHash() const override
bool g_enable_watchdog false
Definition: Execute.cpp:75
const RexScalar * getInnerCondition() const
virtual std::string toString() const =0
ModifyOperation operation_
#define CHECK(condition)
Definition: Logger.h:206
ConstRexScalarPtrVector getOrderKeysAndRelease() const
bool operator==(const RexInput &that) const
const ConstRexScalarPtrVector & getOrderKeys() const
RelProject(std::vector< std::unique_ptr< const RexScalar >> &scalar_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
auto const isUpdateViaSelect() const
const std::string op_typeinfo_
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
SQLTypes getTargetType() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::string toString() const override
size_t size() const
ConstRexScalarPtrVector partition_keys_
std::vector< RexLiteralArray > TupleContentsArray
const RexAgg * getAggExpr(size_t i) const
const SQLTypeInfo type_
std::shared_ptr< RelAlgNode > deepCopy() const override
const std::vector< size_t > operands_
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
std::string toString() const override
std::shared_ptr< RelAlgNode > deepCopy() const override
const std::shared_ptr< RelFilter > original_filter_
void injectOffsetInFragmentExpr() const
size_t getAggExprSize() const
virtual size_t toHash() const =0
std::string getQualifier() const
std::vector< std::string > ColumnNameList
ModifyManipulationTarget(bool const update_via_select=false, bool const delete_via_select=false, bool const varlen_update_required=false, TableDescriptor const *table_descriptor=nullptr, ColumnNameList target_columns=ColumnNameList())
RexLiteral(const SQLTypes target_type)
QueryNotSupported(const std::string &reason)
Definition: sqltypes.h:44
size_t size() const override
std::vector< RexInput > RANodeOutput
std::vector< std::unique_ptr< const RexScalar >> RowValues
size_t toHash() const override
const size_t getAggExprsCount() const
const std::string & getName() const
const size_t inputCount() const
size_t getRelNodeDagId() const
auto const isVarlenUpdateRequired() const
double overlaps_bucket_threshold
Definition: QueryHint.h:167
size_t toHash() const override
RexAgg(const SQLAgg agg, const bool distinct, const SQLTypeInfo &type, const std::vector< size_t > &operands)
unsigned getTypeScale() const
const RexScalar * getAndReleaseCondition() const
const size_t field_
std::string toString() const override
size_t toHash() const override
size_t size() const override
std::unique_ptr< RexAgg > deepCopy() const
size_t toHash() const override
const RexWindowBound lower_bound_
const QueryHint getHint() const
Definition: QueryHint.h:104
RexLiteral(const int64_t val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
void setUpdateViaSelectFlag() const
RelScan(const TableDescriptor *td, const std::vector< std::string > &field_names)
SQLTypes getType() const
size_t size() const override
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
const unsigned scale_
const TableDescriptor * getTableDescriptor() const
std::shared_ptr< const ExecutionResult > getExecutionResult() const
void setContextData(const void *context_data) const
TargetColumnList target_column_list_
TableDescriptor const * table_descriptor_
void setAggExprs(std::vector< std::unique_ptr< const RexAgg >> &agg_exprs)
std::vector< std::string > fields_
JoinType getJoinType() const
bool hasContextData() const
RelTranslatedJoin(const RelAlgNode *lhs, const RelAlgNode *rhs, const std::vector< const Analyzer::ColumnVar * > lhs_join_cols, const std::vector< const Analyzer::ColumnVar * > rhs_join_cols, const std::vector< std::shared_ptr< const Analyzer::Expr >> filter_ops, const RexScalar *outer_join_cond, const bool nested_loop, const JoinType join_type, const std::string &op_type, const std::string &qualifier, const std::string &op_typeinfo)
size_t getFilterCondSize() const
const bool hasHintEnabled(QueryHint candidate_hint) const
size_t toHash() const override
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
std::shared_ptr< RelAlgNode > deepCopy() const override
virtual size_t toHash() const =0
#define VLOG(n)
Definition: Logger.h:300
RelJoin(std::shared_ptr< const RelAlgNode > lhs, std::shared_ptr< const RelAlgNode > rhs, std::unique_ptr< const RexScalar > &condition, const JoinType join_type)
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, std::string const &op_string, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
RelAlgInputs inputs_
void setFields(std::vector< std::string > &new_fields)
const RexScalar * getTargetExpr(size_t idx) const
RexRef(const size_t index)
std::string toString() const override
TableDescriptor const * getModifiedTableDescriptor() const
void setCondition(std::unique_ptr< const RexScalar > &condition)
bool isIdentity() const
const std::string getFieldName(const size_t i) const
const RexScalar * getScalarSource(const size_t i) const
constexpr auto is_datetime(SQLTypes type)
Definition: sqltypes.h:257
const bool hasHintEnabled(QueryHint candidate_hint) const
size_t toHash() const override
std::vector< std::unique_ptr< const RexScalar > > target_exprs_
Hints * getDeliveredHints()
const bool is_agg_
size_t toHash() const override
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
const unsigned id_
static void resetRelAlgFirstId() noexcept