OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RelAlgDag.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
22 #pragma once
23 
24 #include <atomic>
25 #include <iterator>
26 #include <memory>
27 #include <optional>
28 #include <unordered_map>
29 
30 #include <rapidjson/document.h>
31 #include <boost/core/noncopyable.hpp>
32 #include <boost/functional/hash.hpp>
33 
34 #include "Catalog/Catalog.h"
35 #include "QueryEngine/QueryHint.h"
39 #include "QueryHint.h"
40 #include "Shared/toString.h"
41 #include "Utils/FsiUtils.h"
42 
43 class RelAggregate;
44 class RelAlgNode;
45 class RelCompound;
46 class RelFilter;
47 class RelJoin;
49 class RelLogicalUnion;
50 class RelLogicalValues;
51 class RelModify;
52 class RelProject;
53 class RelScan;
54 class RelSort;
55 class RelTableFunction;
56 class RelTranslatedJoin;
57 class Rex;
58 class RexAbstractInput;
59 class RexAgg;
60 class RexCase;
62 class RexInput;
63 class RexLiteral;
64 class RexOperator;
65 class RexRef;
66 class RexScalar;
67 class RexSubQuery;
69 class SortField;
70 
71 using RelAlgInputs = std::vector<std::shared_ptr<const RelAlgNode>>;
72 using ColumnNameList = std::vector<std::string>;
73 
75  bool skip_input_nodes{true};
76  bool attributes_only{false};
77 
79 };
80 
82  public:
83  class Visitor {
84  public:
85  virtual ~Visitor() {}
86  virtual bool visit(RelAggregate const* n, std::string s) { return v(n, s); }
87  virtual bool visit(RelCompound const* n, std::string s) { return v(n, s); }
88  virtual bool visit(RelFilter const* n, std::string s) { return v(n, s); }
89  virtual bool visit(RelJoin const* n, std::string s) { return v(n, s); }
90  virtual bool visit(RelLeftDeepInnerJoin const* n, std::string s) { return v(n, s); }
91  virtual bool visit(RelLogicalUnion const* n, std::string s) { return v(n, s); }
92  virtual bool visit(RelLogicalValues const* n, std::string s) { return v(n, s); }
93  virtual bool visit(RelModify const* n, std::string s) { return v(n, s); }
94  virtual bool visit(RelProject const* n, std::string s) { return v(n, s); }
95  virtual bool visit(RelScan const* n, std::string s) { return v(n, s); }
96  virtual bool visit(RelSort const* n, std::string s) { return v(n, s); }
97  virtual bool visit(RelTableFunction const* n, std::string s) { return v(n, s); }
98  virtual bool visit(RelTranslatedJoin const* n, std::string s) { return v(n, s); }
99  virtual bool visit(RexAbstractInput const* n, std::string s) { return v(n, s); }
100  virtual bool visit(RexCase const* n, std::string s) { return v(n, s); }
101  virtual bool visit(RexFunctionOperator const* n, std::string s) { return v(n, s); }
102  virtual bool visit(RexInput const* n, std::string s) { return v(n, s); }
103  virtual bool visit(RexLiteral const* n, std::string s) { return v(n, s); }
104  virtual bool visit(RexOperator const* n, std::string s) { return v(n, s); }
105  virtual bool visit(RexRef const* n, std::string s) { return v(n, s); }
106  virtual bool visit(RexAgg const* n, std::string s) { return v(n, s); }
107  virtual bool visit(RexSubQuery const* n, std::string s) { return v(n, s); }
108  virtual bool visit(RexWindowFunctionOperator const* n, std::string s) {
109  return v(n, s);
110  }
111 
112  protected:
113  virtual bool visitAny(RelAlgDagNode const* n, std::string s) {
114  return /*recurse=*/true;
115  }
116 
117  private:
118  template <typename T>
119  bool v(T const* n, std::string s) {
120  return visitAny(static_cast<RelAlgDagNode const*>(n), s);
121  }
122  };
123 
124  RelAlgDagNode() : id_in_plan_tree_(std::nullopt) {}
125 
126  virtual void accept(Visitor& v, std::string name) const = 0;
127  virtual void acceptChildren(Visitor& v) const = 0;
128  virtual std::string toString(
130 
131  virtual size_t getStepNumber() const { return step_; }
132  virtual void setStepNumber(size_t step) const { step_ = step; }
133 
134  std::optional<size_t> getIdInPlanTree() const { return id_in_plan_tree_; }
135  void setIdInPlanTree(size_t id) const { id_in_plan_tree_ = id; }
136 
137  protected:
138  mutable size_t step_{0};
139  mutable std::optional<size_t> id_in_plan_tree_;
140 };
141 
142 class Rex : public RelAlgDagNode {
143  public:
144  virtual ~Rex() {}
145 
146  virtual size_t getStepNumber() const { return 0; }
147 
148  virtual size_t toHash() const = 0;
149 
150  protected:
151  mutable std::optional<size_t> hash_;
152 
153  friend struct RelAlgDagSerializer;
154 };
155 
156 class RexScalar : public Rex {};
157 
158 // For internal use of the abstract interpreter only. The result after abstract
159 // interpretation will not have any references to 'RexAbstractInput' objects.
160 class RexAbstractInput : public RexScalar {
161  public:
162  // default constructor used for deserialization only
164 
165  RexAbstractInput(const unsigned in_index) : in_index_(in_index) {}
166 
167  virtual void acceptChildren(Visitor& v) const override {}
168  virtual void accept(Visitor& v, std::string name) const override {
169  if (v.visit(this, std::move(name))) {
170  acceptChildren(v);
171  }
172  }
173 
174  unsigned getIndex() const { return in_index_; }
175 
176  void setIndex(const unsigned in_index) const { in_index_ = in_index; }
177 
178  std::string toString(
179  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
180  return cat(::typeName(this), "(", std::to_string(in_index_), ")");
181  }
182 
183  virtual size_t toHash() const override { return hash_value(*this); }
184 
185  private:
186  friend std::size_t hash_value(RexAbstractInput const&);
187 
188  mutable unsigned in_index_;
189 
190  friend struct RelAlgDagSerializer;
191 };
192 
193 class RexLiteral : public RexScalar {
194  public:
195  // default constructor used for deserialization only
198 
199  RexLiteral(const int64_t val,
200  const SQLTypes type,
201  const SQLTypes target_type,
202  const unsigned scale,
203  const unsigned precision,
204  const unsigned target_scale,
205  const unsigned target_precision)
206  : literal_(val)
207  , type_(type)
208  , target_type_(target_type)
209  , scale_(scale)
210  , precision_(precision)
211  , target_scale_(target_scale)
212  , target_precision_(target_precision) {
213  CHECK(type == kDECIMAL || type == kINTERVAL_DAY_TIME ||
214  type == kINTERVAL_YEAR_MONTH || is_datetime(type) || type == kBIGINT ||
215  type == kINT);
216  }
217 
218  RexLiteral(const double val,
219  const SQLTypes type,
220  const SQLTypes target_type,
221  const unsigned scale,
222  const unsigned precision,
223  const unsigned target_scale,
224  const unsigned target_precision)
225  : literal_(val)
226  , type_(type)
227  , target_type_(target_type)
228  , scale_(scale)
229  , precision_(precision)
230  , target_scale_(target_scale)
231  , target_precision_(target_precision) {
232  CHECK_EQ(kDOUBLE, type);
233  }
234 
235  RexLiteral(const std::string& val,
236  const SQLTypes type,
237  const SQLTypes target_type,
238  const unsigned scale,
239  const unsigned precision,
240  const unsigned target_scale,
241  const unsigned target_precision)
242  : literal_(val)
243  , type_(type)
244  , target_type_(target_type)
245  , scale_(scale)
246  , precision_(precision)
247  , target_scale_(target_scale)
248  , target_precision_(target_precision) {
249  CHECK_EQ(kTEXT, type);
250  }
251 
252  RexLiteral(const bool val,
253  const SQLTypes type,
254  const SQLTypes target_type,
255  const unsigned scale,
256  const unsigned precision,
257  const unsigned target_scale,
258  const unsigned target_precision)
259  : literal_(val)
260  , type_(type)
261  , target_type_(target_type)
262  , scale_(scale)
263  , precision_(precision)
264  , target_scale_(target_scale)
265  , target_precision_(target_precision) {
266  CHECK_EQ(kBOOLEAN, type);
267  }
268 
269  RexLiteral(const SQLTypes target_type)
270  : literal_()
271  , type_(kNULLT)
272  , target_type_(target_type)
273  , scale_(0)
274  , precision_(0)
275  , target_scale_(0)
276  , target_precision_(0) {}
277 
278  virtual void acceptChildren(Visitor& v) const override {}
279  virtual void accept(Visitor& v, std::string name) const override {
280  if (v.visit(this, std::move(name))) {
281  acceptChildren(v);
282  }
283  }
284 
285  template <class T>
286  T getVal() const {
287  const auto ptr = boost::get<T>(&literal_);
288  CHECK(ptr);
289  return *ptr;
290  }
291 
292  SQLTypes getType() const { return type_; }
293 
294  SQLTypes getTargetType() const { return target_type_; }
295 
296  unsigned getScale() const { return scale_; }
297 
298  unsigned getPrecision() const { return precision_; }
299 
300  unsigned getTargetScale() const { return target_scale_; }
301 
302  unsigned getTargetPrecision() const { return target_precision_; }
303 
304  std::string toString(
305  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
306  std::ostringstream oss;
307  oss << "RexLiteral(" << literal_ << " type=" << type_ << '(' << precision_ << ','
308  << scale_ << ") target_type=" << target_type_ << '(' << target_precision_ << ','
309  << target_scale_ << "))";
310  return oss.str();
311  }
312 
313  std::unique_ptr<RexLiteral> deepCopy() const {
314  return std::make_unique<RexLiteral>(*this);
315  }
316 
317  virtual size_t toHash() const override { return hash_value(*this); }
318 
319  private:
320  friend std::size_t hash_value(RexLiteral const&);
321 
322  boost::variant<boost::blank, int64_t, double, std::string, bool> literal_;
325  unsigned scale_;
326  unsigned precision_;
327  unsigned target_scale_;
329 
330  friend struct RelAlgDagSerializer;
331 };
332 
333 using RexLiteralArray = std::vector<RexLiteral>;
334 using TupleContentsArray = std::vector<RexLiteralArray>;
335 
336 class RexOperator : public RexScalar {
337  public:
338  // default constructor for deserialization only
340 
341  RexOperator(const SQLOps op,
342  std::vector<std::unique_ptr<const RexScalar>>& operands,
343  const SQLTypeInfo& type)
344  : op_(op), operands_(std::move(operands)), type_(type) {}
345 
346  virtual void acceptChildren(Visitor& v) const override {
347  for (size_t i = 0; i < size(); ++i) {
348  if (getOperand(i)) {
349  getOperand(i)->accept(v, "operand");
350  }
351  }
352  }
353  virtual void accept(Visitor& v, std::string name) const override {
354  if (v.visit(this, std::move(name))) {
355  acceptChildren(v);
356  }
357  }
358 
359  virtual std::unique_ptr<const RexOperator> getDisambiguated(
360  std::vector<std::unique_ptr<const RexScalar>>& operands) const {
361  return std::unique_ptr<const RexOperator>(new RexOperator(op_, operands, type_));
362  }
363 
364  size_t size() const { return operands_.size(); }
365 
366  const RexScalar* getOperand(const size_t idx) const {
367  CHECK(idx < operands_.size());
368  return operands_[idx].get();
369  }
370 
371  const RexScalar* getOperandAndRelease(const size_t idx) const {
372  CHECK(idx < operands_.size());
373  return operands_[idx].release();
374  }
375 
376  SQLOps getOperator() const { return op_; }
377 
378  const SQLTypeInfo& getType() const { return type_; }
379 
380  std::string toString(
381  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
382  if (!config.attributes_only) {
383  auto ret = cat(::typeName(this), "(", std::to_string(op_), ", operands=");
384  for (auto& operand : operands_) {
385  ret += operand->toString(config) + " ";
386  }
387  return cat(ret, ", type=", type_.to_string(), ")");
388  } else {
389  return cat(
390  ::typeName(this), "(", ::toString(op_), ", type=", type_.get_type(), ")");
391  }
392  };
393 
394  virtual size_t toHash() const override { return hash_value(*this); }
395 
396  protected:
397  friend std::size_t hash_value(RexOperator const&);
398 
400  mutable std::vector<std::unique_ptr<const RexScalar>> operands_;
402 
403  friend struct RelAlgDagSerializer;
404 };
405 
406 // Not a real node created by Calcite. Created by us because CaseExpr is a node in our
407 // Analyzer.
408 class RexCase : public RexScalar {
409  public:
410  // default constructor used for deserialization only
411  RexCase() = default;
412 
413  RexCase(std::vector<std::pair<std::unique_ptr<const RexScalar>,
414  std::unique_ptr<const RexScalar>>>& expr_pair_list,
415  std::unique_ptr<const RexScalar>& else_expr)
416  : expr_pair_list_(std::move(expr_pair_list)), else_expr_(std::move(else_expr)) {}
417 
418  virtual void acceptChildren(Visitor& v) const override {
419  for (size_t i = 0; i < branchCount(); ++i) {
420  getWhen(i)->accept(v, "when");
421  getThen(i)->accept(v, "then");
422  }
423  if (getElse()) {
424  getElse()->accept(v, "else");
425  }
426  }
427  virtual void accept(Visitor& v, std::string name) const override {
428  if (v.visit(this, std::move(name))) {
429  acceptChildren(v);
430  }
431  }
432 
433  size_t branchCount() const { return expr_pair_list_.size(); }
434 
435  const RexScalar* getWhen(const size_t idx) const {
436  CHECK(idx < expr_pair_list_.size());
437  return expr_pair_list_[idx].first.get();
438  }
439 
440  const RexScalar* getThen(const size_t idx) const {
441  CHECK(idx < expr_pair_list_.size());
442  return expr_pair_list_[idx].second.get();
443  }
444 
445  const RexScalar* getElse() const { return else_expr_.get(); }
446 
447  std::string toString(
448  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
449  if (!config.attributes_only) {
450  auto ret = cat(::typeName(this), "(expr_pair_list=");
451  for (auto& expr : expr_pair_list_) {
452  ret += expr.first->toString(config) + " " + expr.second->toString(config) + " ";
453  }
454  return cat(
455  ret, ", else_expr=", (else_expr_ ? else_expr_->toString(config) : "null"), ")");
456  } else {
457  return ::typeName(this);
458  }
459  }
460 
461  virtual size_t toHash() const override { return hash_value(*this); }
462 
463  private:
464  friend std::size_t hash_value(RexCase const&);
465 
466  std::vector<
467  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
469  std::unique_ptr<const RexScalar> else_expr_;
470 
471  friend struct RelAlgDagSerializer;
472 };
473 
475  public:
476  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
477  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
478 
479  // default constructor used for deserialization only
480  RexFunctionOperator() = default;
481 
482  RexFunctionOperator(const std::string& name,
483  ConstRexScalarPtrVector& operands,
484  const SQLTypeInfo& ti)
485  : RexOperator(kFUNCTION, operands, ti), name_(name) {}
486 
487  std::unique_ptr<const RexOperator> getDisambiguated(
488  std::vector<std::unique_ptr<const RexScalar>>& operands) const override {
489  return std::unique_ptr<const RexOperator>(
490  new RexFunctionOperator(name_, operands, getType()));
491  }
492 
493  virtual void acceptChildren(Visitor& v) const override {
494  for (size_t i = 0; i < size(); ++i) {
495  if (getOperand(i)) {
496  getOperand(i)->accept(v, "operand");
497  }
498  }
499  }
500  virtual void accept(Visitor& v, std::string name) const override {
501  if (v.visit(this, std::move(name))) {
502  acceptChildren(v);
503  }
504  }
505 
506  const std::string& getName() const { return name_; }
507 
508  std::string toString(
509  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
510  if (!config.attributes_only) {
511  auto ret = cat(::typeName(this), "(", name_, ", operands=");
512  for (auto& operand : operands_) {
513  ret += operand->toString(config) + " ";
514  }
515  return cat(ret, ")");
516  } else {
517  return cat(::typeName(this), "(", name_, ")");
518  }
519  }
520 
521  virtual size_t toHash() const override { return hash_value(*this); }
522 
523  private:
524  friend std::size_t hash_value(RexFunctionOperator const&);
525 
526  std::string name_;
527 
528  friend struct RelAlgDagSerializer;
529 };
530 
532 
533 enum class NullSortedPosition { First, Last };
534 
535 class SortField {
536  public:
537  SortField(const size_t field,
538  const SortDirection sort_dir,
539  const NullSortedPosition nulls_pos)
540  : field_(field), sort_dir_(sort_dir), nulls_pos_(nulls_pos) {}
541 
542  bool operator==(const SortField& that) const {
543  return field_ == that.field_ && sort_dir_ == that.sort_dir_ &&
544  nulls_pos_ == that.nulls_pos_;
545  }
546 
547  size_t getField() const { return field_; }
548 
549  SortDirection getSortDir() const { return sort_dir_; }
550 
552 
553  std::string toString() const {
554  return cat(::typeName(this),
555  "(",
557  ", sort_dir=",
558  (sort_dir_ == SortDirection::Ascending ? "asc" : "desc"),
559  ", null_pos=",
560  (nulls_pos_ == NullSortedPosition::First ? "nulls_first" : "nulls_last"),
561  ")");
562  }
563 
564  virtual size_t toHash() const { return hash_value(*this); }
565 
566  private:
567  friend std::size_t hash_value(SortField const&);
568 
569  size_t field_;
572 };
573 
575  public:
576  struct RexWindowBound {
577  bool unbounded{false};
578  bool preceding{false};
579  bool following{false};
580  bool is_current_row{false};
581  std::shared_ptr<const RexScalar> bound_expr;
582  int order_key{0};
583 
584  bool isUnboundedPreceding() const { return unbounded && preceding && !bound_expr; }
585 
586  bool isUnboundedFollowing() const { return unbounded && following && !bound_expr; }
587 
588  bool isRowOffsetPreceding() const { return !unbounded && preceding && bound_expr; }
589 
590  bool isRowOffsetFollowing() const { return !unbounded && following && bound_expr; }
591 
592  bool isCurrentRow() const {
593  return !unbounded && is_current_row && !preceding && !following && !bound_expr;
594  }
595 
596  bool hasNoFraming() const {
597  return !unbounded && !preceding && !following && !is_current_row && !bound_expr;
598  }
599  };
600 
601  // default constructor used for deserialization only
604 
606  ConstRexScalarPtrVector& operands,
607  ConstRexScalarPtrVector& partition_keys,
608  ConstRexScalarPtrVector& order_keys,
609  const std::vector<SortField> collation,
610  const RexWindowBound& frame_start_bound,
611  const RexWindowBound& frame_end_bound,
612  const bool is_rows,
613  const SQLTypeInfo& ti)
614  : RexFunctionOperator(::toString(kind), operands, ti)
615  , kind_(kind)
616  , partition_keys_(std::move(partition_keys))
617  , order_keys_(std::move(order_keys))
618  , collation_(collation)
619  , frame_start_bound_(frame_start_bound)
620  , frame_end_bound_(frame_end_bound)
621  , is_rows_(is_rows) {}
622 
623  virtual void acceptChildren(Visitor& v) const override {
624  for (auto const& partition_key : getPartitionKeys()) {
625  if (partition_key) {
626  partition_key->accept(v, "partition");
627  }
628  }
629  for (auto const& order_key : getOrderKeys()) {
630  if (order_key) {
631  order_key->accept(v, "order");
632  }
633  }
634  }
635  virtual void accept(Visitor& v, std::string name) const override {
636  if (v.visit(this, std::move(name))) {
637  acceptChildren(v);
638  }
639  }
640 
641  SqlWindowFunctionKind getKind() const { return kind_; }
642 
644 
646  return std::move(partition_keys_);
647  }
648 
650  return std::move(order_keys_);
651  }
652 
654 
655  void replacePartitionKey(size_t offset,
656  std::unique_ptr<const RexScalar>&& new_partition_key) {
657  CHECK_LT(offset, partition_keys_.size());
658  partition_keys_[offset] = std::move(new_partition_key);
659  }
660 
661  void replaceOrderKey(size_t offset, std::unique_ptr<const RexScalar>&& new_order_key) {
662  CHECK_LT(offset, order_keys_.size());
663  order_keys_[offset] = std::move(new_order_key);
664  }
665 
666  void replaceOperands(std::vector<std::unique_ptr<const RexScalar>>&& new_operands) {
667  operands_ = std::move(new_operands);
668  }
669 
670  const std::vector<SortField>& getCollation() const { return collation_; }
671 
673 
675 
676  bool isRows() const { return is_rows_; }
677 
678  std::unique_ptr<const RexOperator> disambiguatedOperands(
679  ConstRexScalarPtrVector& operands,
680  ConstRexScalarPtrVector& partition_keys,
681  ConstRexScalarPtrVector& order_keys,
682  const std::vector<SortField>& collation) const {
683  return std::unique_ptr<const RexOperator>(
685  operands,
686  partition_keys,
687  order_keys,
688  collation,
691  isRows(),
692  getType()));
693  }
694 
695  std::string toString(
696  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
697  if (!config.attributes_only) {
698  auto ret = cat(::typeName(this), "(", getName(), ", operands=");
699  for (auto& operand : operands_) {
700  ret += operand->toString(config) + " ";
701  }
702  ret += ", partition_keys=";
703  for (auto& key : partition_keys_) {
704  ret += key->toString(config) + " ";
705  }
706  ret += ", order_keys=";
707  for (auto& key : order_keys_) {
708  ret += key->toString(config) + " ";
709  }
710  return cat(ret, ")");
711  } else {
712  return cat(::typeName(this), "(", getName(), ")");
713  }
714  }
715 
716  virtual size_t toHash() const override { return hash_value(*this); }
717 
718  private:
719  friend std::size_t hash_value(RexWindowFunctionOperator const&);
720 
724  std::vector<SortField> collation_;
727  bool is_rows_;
728 
729  friend struct RelAlgDagSerializer;
730 };
731 
732 // Not a real node created by Calcite. Created by us because targets of a query
733 // should reference the group by expressions instead of creating completely new one.
734 class RexRef : public RexScalar {
735  public:
736  // default constructor used for deserialization only
737  RexRef() : index_{0} {}
738 
739  RexRef(const size_t index) : index_(index) {}
740 
741  size_t getIndex() const { return index_; }
742 
743  virtual void acceptChildren(Visitor& v) const override {}
744  virtual void accept(Visitor& v, std::string name) const override {
745  if (v.visit(this, std::move(name))) {
746  acceptChildren(v);
747  }
748  }
749 
750  std::string toString(
751  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
752  return cat(::typeName(this), "(", std::to_string(index_), ")");
753  }
754 
755  std::unique_ptr<RexRef> deepCopy() const { return std::make_unique<RexRef>(index_); }
756 
757  virtual size_t toHash() const override { return hash_value(*this); }
758 
759  private:
760  friend std::size_t hash_value(RexRef const&);
761 
762  size_t index_;
763 
764  friend struct RelAlgDagSerializer;
765 };
766 
767 class RexAgg : public Rex {
768  public:
769  // default constructor, used for deserialization only
771 
772  RexAgg(const SQLAgg agg,
773  const bool distinct,
774  const SQLTypeInfo& type,
775  const std::vector<size_t>& operands)
776  : agg_(agg), distinct_(distinct), type_(type), operands_(operands) {}
777 
778  virtual void acceptChildren(Visitor& v) const override {}
779  virtual void accept(Visitor& v, std::string name) const override {
780  if (v.visit(this, std::move(name))) {
781  acceptChildren(v);
782  }
783  }
784 
785  std::string toString(
786  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
787  return cat(::typeName(this),
788  "(agg=",
790  ", distinct=",
792  ", type=",
794  ", operands=",
796  ")");
797  }
798 
799  SQLAgg getKind() const { return agg_; }
800 
801  bool isDistinct() const { return distinct_; }
802 
803  size_t size() const { return operands_.size(); }
804 
805  size_t getOperand(size_t idx) const { return operands_[idx]; }
806 
807  const SQLTypeInfo& getType() const { return type_; }
808 
809  std::unique_ptr<RexAgg> deepCopy() const {
810  return std::make_unique<RexAgg>(agg_, distinct_, type_, operands_);
811  }
812 
813  virtual size_t toHash() const override { return hash_value(*this); }
814 
815  private:
816  friend std::size_t hash_value(RexAgg const&);
817 
819  bool distinct_;
821  std::vector<size_t> operands_;
822 
823  friend struct RelAlgDagSerializer;
824 };
825 
826 class RaExecutionDesc;
827 
828 class RelAlgNode : public RelAlgDagNode {
829  public:
831  : inputs_(std::move(inputs))
832  , id_(crt_id_++)
833  , context_data_(nullptr)
834  , is_nop_(false)
835  , query_plan_dag_("")
836  , query_plan_dag_hash_(0) {}
837 
838  virtual ~RelAlgNode() {}
839 
841  context_data_ = nullptr;
842  targets_metainfo_ = {};
843  }
844 
845  void setContextData(const RaExecutionDesc* context_data) const {
847  context_data_ = context_data;
848  }
849 
850  void setOutputMetainfo(std::vector<TargetMetaInfo> targets_metainfo) const {
851  targets_metainfo_ = std::move(targets_metainfo);
852  }
853 
854  void setQueryPlanDag(const std::string& extracted_query_plan_dag) const {
855  if (!extracted_query_plan_dag.empty()) {
856  query_plan_dag_ = extracted_query_plan_dag;
857  query_plan_dag_hash_ = boost::hash_value(extracted_query_plan_dag);
858  }
859  }
860 
861  std::string getQueryPlanDag() const { return query_plan_dag_; }
862 
863  size_t getQueryPlanDagHash() const { return query_plan_dag_hash_; }
864 
865  const std::vector<TargetMetaInfo>& getOutputMetainfo() const {
866  return targets_metainfo_;
867  }
868 
869  unsigned getId() const { return id_; }
870 
871  bool hasContextData() const { return !(context_data_ == nullptr); }
872 
873  const RaExecutionDesc* getContextData() const { return context_data_; }
874 
875  const size_t inputCount() const { return inputs_.size(); }
876 
877  const RelAlgNode* getInput(const size_t idx) const {
878  CHECK_LT(idx, inputs_.size());
879  return inputs_[idx].get();
880  }
881 
882  const std::vector<RelAlgNode const*> getInputs() const {
883  std::vector<RelAlgNode const*> ret;
884  for (auto& n : inputs_) {
885  ret.push_back(n.get());
886  }
887  return ret;
888  }
889 
890  std::shared_ptr<const RelAlgNode> getAndOwnInput(const size_t idx) const {
891  CHECK_LT(idx, inputs_.size());
892  return inputs_[idx];
893  }
894 
895  void addManagedInput(std::shared_ptr<const RelAlgNode> input) {
896  inputs_.push_back(input);
897  }
898 
899  bool hasInput(const RelAlgNode* needle) const {
900  for (auto& input_ptr : inputs_) {
901  if (input_ptr.get() == needle) {
902  return true;
903  }
904  }
905  return false;
906  }
907 
908  virtual void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
909  std::shared_ptr<const RelAlgNode> input) {
910  for (auto& input_ptr : inputs_) {
911  if (input_ptr == old_input) {
912  input_ptr = input;
913  break;
914  }
915  }
916  }
917 
918  // to keep an assigned DAG node id for data recycler
919  void setRelNodeDagId(const size_t id) const { dag_node_id_ = id; }
920 
921  size_t getRelNodeDagId() const { return dag_node_id_; }
922 
923  bool isNop() const { return is_nop_; }
924 
925  void markAsNop() { is_nop_ = true; }
926 
927  virtual std::string toString(
929 
930  virtual size_t size() const = 0;
931 
932  virtual std::shared_ptr<RelAlgNode> deepCopy() const = 0;
933 
934  static void resetRelAlgFirstId() noexcept;
935 
940  void clearContextData() const { context_data_ = nullptr; }
941 
942  virtual size_t toHash() const = 0;
943 
944  protected:
946  unsigned id_;
947  mutable std::optional<size_t> hash_;
948 
949  private:
951  bool is_nop_;
952  mutable std::vector<TargetMetaInfo> targets_metainfo_;
953  static thread_local unsigned crt_id_;
954  mutable size_t dag_node_id_;
955  mutable std::string query_plan_dag_;
956  mutable size_t query_plan_dag_hash_;
957 
958  friend struct RelAlgDagSerializer;
959 };
960 
961 class ExecutionResult;
962 
963 class RexSubQuery : public RexScalar {
964  public:
965  using ExecutionResultShPtr = std::shared_ptr<const ExecutionResult>;
966 
967  // default constructor used for deserialization only
968  // NOTE: the result_ member needs to be pointing to a shared_ptr
970 
971  RexSubQuery(const std::shared_ptr<const RelAlgNode> ra)
972  : type_(new SQLTypeInfo(kNULLT, false))
973  , result_(new ExecutionResultShPtr(nullptr))
974  , ra_(ra) {}
975 
976  // for deep copy
977  RexSubQuery(std::shared_ptr<SQLTypeInfo> type,
978  std::shared_ptr<ExecutionResultShPtr> result,
979  const std::shared_ptr<const RelAlgNode> ra)
980  : type_(type), result_(result), ra_(ra) {}
981 
982  RexSubQuery(const RexSubQuery&) = delete;
983 
984  RexSubQuery& operator=(const RexSubQuery&) = delete;
985 
986  RexSubQuery(RexSubQuery&&) = delete;
987 
988  RexSubQuery& operator=(RexSubQuery&&) = delete;
989 
990  virtual void acceptChildren(Visitor& v) const override {
991  if (getRelAlg()) {
992  getRelAlg()->accept(v, "node");
993  }
994  }
995  virtual void accept(Visitor& v, std::string name) const override {
996  if (v.visit(this, std::move(name))) {
997  acceptChildren(v);
998  }
999  }
1000 
1001  const SQLTypeInfo& getType() const {
1002  CHECK_NE(kNULLT, type_->get_type());
1003  return *(type_.get());
1004  }
1005 
1007  CHECK(result_);
1008  CHECK(result_.get());
1009  return *(result_.get());
1010  }
1011 
1012  unsigned getId() const;
1013 
1014  const RelAlgNode* getRelAlg() const { return ra_.get(); }
1015 
1016  std::string toString(
1017  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
1018 
1019  std::unique_ptr<RexSubQuery> deepCopy() const;
1020 
1022 
1023  virtual size_t toHash() const override { return hash_value(*this); }
1024 
1025  private:
1026  friend std::size_t hash_value(RexSubQuery const&);
1027 
1028  std::shared_ptr<SQLTypeInfo> type_;
1029  std::shared_ptr<ExecutionResultShPtr> result_;
1030  std::shared_ptr<const RelAlgNode> ra_;
1031 
1032  friend struct RelAlgDagSerializer;
1033 };
1034 
1035 // The actual input node understood by the Executor.
1036 // The in_index_ is relative to the output of node_.
1037 class RexInput : public RexAbstractInput {
1038  public:
1039  // default constructor used for deserialization only
1040  RexInput() : node_{nullptr} {}
1041 
1042  RexInput(const RelAlgNode* node, const unsigned in_index)
1043  : RexAbstractInput(in_index), node_(node) {}
1044 
1045  virtual void acceptChildren(Visitor& v) const override {
1046  if (getSourceNode()) {
1047  getSourceNode()->accept(v, "source");
1048  }
1049  }
1050  virtual void accept(Visitor& v, std::string name) const override {
1051  if (v.visit(this, std::move(name))) {
1052  acceptChildren(v);
1053  }
1054  }
1055 
1056  const RelAlgNode* getSourceNode() const { return node_; }
1057 
1058  // This isn't great, but we need it for coalescing nodes to Compound since
1059  // RexInput in descendents need to be rebound to the newly created Compound.
1060  // Maybe create a fresh RA tree with the required changes after each coalescing?
1061  void setSourceNode(const RelAlgNode* node) const { node_ = node; }
1062 
1063  bool operator==(const RexInput& that) const {
1064  return getSourceNode() == that.getSourceNode() && getIndex() == that.getIndex();
1065  }
1066 
1067  std::string toString(
1068  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
1069 
1070  std::unique_ptr<RexInput> deepCopy() const {
1071  return std::make_unique<RexInput>(node_, getIndex());
1072  }
1073 
1074  virtual size_t toHash() const override { return hash_value(*this); }
1075 
1076  private:
1077  friend std::size_t hash_value(RexInput const&);
1078 
1079  mutable const RelAlgNode* node_;
1080 
1081  friend struct RelAlgDagSerializer;
1082 };
1083 
1084 namespace std {
1085 
1086 template <>
1087 struct hash<RexInput> {
1088  size_t operator()(const RexInput& rex_in) const { return rex_in.toHash(); }
1089 };
1090 
1091 } // namespace std
1092 
1093 class RelScan : public RelAlgNode {
1094  public:
1095  // constructor used for deserialization only
1097  : td_{td}, hint_applied_{false}, catalog_(catalog) {}
1098 
1100  const std::vector<std::string>& field_names,
1101  const Catalog_Namespace::Catalog& catalog)
1102  : td_(td)
1103  , field_names_(field_names)
1104  , hint_applied_(false)
1105  , hints_(std::make_unique<Hints>())
1106  , catalog_(catalog) {}
1107 
1108  virtual void acceptChildren(Visitor& v) const override {}
1109  virtual void accept(Visitor& v, std::string name) const override {
1110  if (v.visit(this, std::move(name))) {
1111  acceptChildren(v);
1112  }
1113  }
1114 
1115  size_t size() const override { return field_names_.size(); }
1116 
1117  const TableDescriptor* getTableDescriptor() const { return td_; }
1118 
1120 
1121  const size_t getNumFragments() const { return td_->fragmenter->getNumFragments(); }
1122 
1123  const size_t getNumShards() const { return td_->nShards; }
1124 
1125  const std::vector<std::string>& getFieldNames() const { return field_names_; }
1126 
1127  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
1128 
1129  std::string toString(
1130  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1131  if (!config.attributes_only) {
1132  return cat(
1133  ::typeName(this), "(", td_->tableName, ", ", ::toString(field_names_), ")");
1134  } else {
1135  return cat(::typeName(this), "(", td_->tableName, ")");
1136  }
1137  }
1138 
1139  std::shared_ptr<RelAlgNode> deepCopy() const override {
1140  CHECK(false);
1141  return nullptr;
1142  };
1143 
1144  void addHint(const ExplainedQueryHint& hint_explained) {
1145  if (!hint_applied_) {
1146  hint_applied_ = true;
1147  }
1148  hints_->emplace(hint_explained.getHint(), hint_explained);
1149  }
1150 
1151  const bool hasHintEnabled(const QueryHint candidate_hint) const {
1152  if (hint_applied_ && !hints_->empty()) {
1153  return hints_->find(candidate_hint) != hints_->end();
1154  }
1155  return false;
1156  }
1157 
1160  CHECK(!hints_->empty());
1161  CHECK(hasHintEnabled(hint));
1162  return hints_->at(hint);
1163  }
1164 
1165  bool hasDeliveredHint() { return !hints_->empty(); }
1166 
1167  Hints* getDeliveredHints() { return hints_.get(); }
1168 
1169  virtual size_t toHash() const override { return hash_value(*this); }
1170 
1171  private:
1172  friend std::size_t hash_value(RelScan const&);
1173 
1175  std::vector<std::string> field_names_;
1177  std::unique_ptr<Hints> hints_;
1179 
1180  friend struct RelAlgDagSerializer;
1181 };
1182 
1184  public:
1185  ModifyManipulationTarget(bool const update_via_select = false,
1186  bool const delete_via_select = false,
1187  bool const varlen_update_required = false,
1188  TableDescriptor const* table_descriptor = nullptr,
1189  ColumnNameList target_columns = ColumnNameList(),
1190  const Catalog_Namespace::Catalog* catalog = nullptr)
1191  : is_update_via_select_(update_via_select)
1192  , is_delete_via_select_(delete_via_select)
1193  , varlen_update_required_(varlen_update_required)
1194  , table_descriptor_(table_descriptor)
1195  , target_columns_(target_columns)
1196  , catalog_(catalog) {}
1197 
1202  }
1204 
1208  table_descriptor_ = td;
1209  }
1210 
1212 
1214  catalog_ = catalog;
1215  }
1216 
1217  auto const isUpdateViaSelect() const { return is_update_via_select_; }
1218  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
1219  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
1220  auto const isProjectForUpdate() const {
1222  }
1223  auto const isRowwiseOutputForced() const { return force_rowwise_output_; }
1224 
1225  void setTargetColumns(ColumnNameList const& target_columns) const {
1226  target_columns_ = target_columns;
1227  }
1229 
1230  void invalidateTargetColumns() const { target_columns_.clear(); }
1231 
1232  template <typename VALIDATION_FUNCTOR>
1233  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
1234  for (auto const& column_name : target_columns_) {
1235  if (validator(column_name) == false) {
1236  return false;
1237  }
1238  }
1239  return true;
1240  }
1241 
1242  private:
1243  mutable bool is_update_via_select_ = false;
1244  mutable bool is_delete_via_select_ = false;
1245  mutable bool varlen_update_required_ = false;
1246  mutable TableDescriptor const* table_descriptor_ = nullptr;
1248  mutable bool force_rowwise_output_ = false;
1249  mutable const Catalog_Namespace::Catalog* catalog_{nullptr};
1250 
1251  friend struct RelAlgDagSerializer;
1252 };
1253 
1255  public:
1256  friend class RelModify;
1257  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
1258  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
1259 
1260  // constructor used for deserialization only
1263  , hint_applied_{false}
1265 
1266  // Takes memory ownership of the expressions.
1267  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
1268  const std::vector<std::string>& fields,
1269  std::shared_ptr<const RelAlgNode> input)
1271  , scalar_exprs_(std::move(scalar_exprs))
1272  , fields_(fields)
1273  , hint_applied_(false)
1274  , hints_(std::make_unique<Hints>())
1276  CHECK_EQ(scalar_exprs_.size(), fields_.size());
1277  inputs_.push_back(input);
1278  }
1279 
1280  RelProject(RelProject const&);
1281 
1282  virtual void acceptChildren(Visitor& v) const override {
1283  for (size_t i = 0; i < size(); ++i) {
1284  if (getProjectAt(i)) {
1285  getProjectAt(i)->accept(v, "\"" + getFieldName(i) + "\"");
1286  }
1287  }
1288  for (auto& n : getInputs()) {
1289  if (n) {
1290  n->accept(v, "input");
1291  }
1292  }
1293  }
1294  virtual void accept(Visitor& v, std::string name) const override {
1295  if (v.visit(this, std::move(name))) {
1296  acceptChildren(v);
1297  }
1298  }
1299 
1300  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
1301  scalar_exprs_ = std::move(exprs);
1302  }
1303 
1304  // True iff all the projected expressions are inputs. If true,
1305  // this node can be elided and merged into the previous node
1306  // since it's just a subset and / or permutation of its outputs.
1307  bool isSimple() const {
1308  for (const auto& expr : scalar_exprs_) {
1309  if (!dynamic_cast<const RexInput*>(expr.get())) {
1310  return false;
1311  }
1312  }
1313  return true;
1314  }
1315 
1316  bool isIdentity() const;
1317 
1318  bool isRenaming() const;
1319 
1320  size_t size() const override { return scalar_exprs_.size(); }
1321 
1323  std::shared_ptr<RelProject> new_project_node) const {
1324  if (isUpdateViaSelect()) {
1325  new_project_node->setUpdateViaSelectFlag(true);
1326  }
1327  if (isDeleteViaSelect()) {
1328  new_project_node->setDeleteViaSelectFlag(true);
1329  }
1330  if (isVarlenUpdateRequired()) {
1331  new_project_node->setVarlenUpdateRequired(true);
1332  }
1333  new_project_node->setModifiedTableDescriptor(getModifiedTableDescriptor());
1334  new_project_node->setTargetColumns(getTargetColumns());
1335  new_project_node->setModifiedTableCatalog(getModifiedTableCatalog());
1337  }
1338 
1340  setModifiedTableDescriptor(nullptr);
1341  setModifiedTableCatalog(nullptr);
1342  setUpdateViaSelectFlag(false);
1343  setDeleteViaSelectFlag(false);
1344  setVarlenUpdateRequired(false);
1346  }
1347 
1349 
1351 
1352  const RexScalar* getProjectAt(const size_t idx) const {
1353  CHECK(idx < scalar_exprs_.size());
1354  return scalar_exprs_[idx].get();
1355  }
1356 
1357  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
1358  CHECK(idx < scalar_exprs_.size());
1359  return scalar_exprs_[idx].release();
1360  }
1361 
1362  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
1363  return std::move(scalar_exprs_);
1364  }
1365 
1366  const std::vector<std::string>& getFields() const { return fields_; }
1367  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
1368 
1369  const std::string getFieldName(const size_t idx) const {
1370  CHECK(idx < fields_.size());
1371  return fields_[idx];
1372  }
1373 
1374  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1375  std::shared_ptr<const RelAlgNode> input) override {
1376  replaceInput(old_input, input, std::nullopt);
1377  }
1378 
1379  void replaceInput(
1380  std::shared_ptr<const RelAlgNode> old_input,
1381  std::shared_ptr<const RelAlgNode> input,
1382  std::optional<std::unordered_map<unsigned, unsigned>> old_to_new_index_map);
1383 
1384  void appendInput(std::string new_field_name,
1385  std::unique_ptr<const RexScalar> new_input);
1386 
1387  std::string toString(
1388  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1389  if (!config.attributes_only) {
1390  auto ret = cat(::typeName(this), "(");
1391  for (auto& expr : scalar_exprs_) {
1392  ret += expr->toString(config) + " ";
1393  }
1394  return cat(ret, ", ", ::toString(fields_), ")");
1395  } else {
1396  return cat(::typeName(this), "(", ::toString(fields_), ")");
1397  }
1398  }
1399 
1400  std::shared_ptr<RelAlgNode> deepCopy() const override {
1401  auto copied_project_node = std::make_shared<RelProject>(*this);
1402  if (isProjectForUpdate()) {
1403  propagateModifyManipulationTarget(copied_project_node);
1404  }
1406  copied_project_node->setPushedDownWindowExpr();
1407  }
1408  return copied_project_node;
1409  }
1410 
1411  bool hasWindowFunctionExpr() const;
1412 
1413  void addHint(const ExplainedQueryHint& hint_explained) {
1414  if (!hint_applied_) {
1415  hint_applied_ = true;
1416  }
1417  hints_->emplace(hint_explained.getHint(), hint_explained);
1418  }
1419 
1420  const bool hasHintEnabled(QueryHint candidate_hint) const {
1421  if (hint_applied_ && !hints_->empty()) {
1422  return hints_->find(candidate_hint) != hints_->end();
1423  }
1424  return false;
1425  }
1426 
1429  CHECK(!hints_->empty());
1430  CHECK(hasHintEnabled(hint));
1431  return hints_->at(hint);
1432  }
1433 
1434  bool hasDeliveredHint() { return !hints_->empty(); }
1435 
1436  Hints* getDeliveredHints() { return hints_.get(); }
1437 
1438  virtual size_t toHash() const override { return hash_value(*this); }
1439 
1440  private:
1441  friend std::size_t hash_value(RelProject const&);
1442 
1443  template <typename EXPR_VISITOR_FUNCTOR>
1444  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
1445  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
1446  visitor_functor(i);
1447  }
1448  }
1449 
1452  scalar_exprs_.emplace_back(
1453  std::make_unique<RexFunctionOperator const>(std::string("OFFSET_IN_FRAGMENT"),
1454  transient_vector,
1455  SQLTypeInfo(kBIGINT, false)));
1456  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
1457  }
1458 
1459  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
1460  mutable std::vector<std::string> fields_;
1462  std::unique_ptr<Hints> hints_;
1464 
1465  friend struct RelAlgDagSerializer;
1466 };
1467 
1468 class RelAggregate : public RelAlgNode {
1469  public:
1470  // default constructor, for deserialization only
1472 
1473  // Takes ownership of the aggregate expressions.
1474  RelAggregate(const size_t groupby_count,
1475  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
1476  const std::vector<std::string>& fields,
1477  std::shared_ptr<const RelAlgNode> input)
1478  : groupby_count_(groupby_count)
1479  , agg_exprs_(std::move(agg_exprs))
1480  , fields_(fields)
1481  , hint_applied_(false)
1482  , hints_(std::make_unique<Hints>()) {
1483  inputs_.push_back(input);
1484  }
1485 
1486  RelAggregate(RelAggregate const&);
1487 
1488  virtual void acceptChildren(Visitor& v) const override {
1489  for (auto const& n : getAggExprs()) {
1490  if (n) {
1491  n.get()->accept(v, "aggregate");
1492  }
1493  }
1494  for (auto& n : getInputs()) {
1495  if (n) {
1496  n->accept(v, "input");
1497  }
1498  }
1499  }
1500  virtual void accept(Visitor& v, std::string name) const override {
1501  if (v.visit(this, std::move(name))) {
1502  acceptChildren(v);
1503  }
1504  }
1505 
1506  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
1507 
1508  const size_t getGroupByCount() const { return groupby_count_; }
1509 
1510  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
1511 
1512  const std::vector<std::string>& getFields() const { return fields_; }
1513  void setFields(std::vector<std::string>&& new_fields) {
1514  fields_ = std::move(new_fields);
1515  }
1516 
1517  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1518 
1519  std::vector<const RexAgg*> getAggregatesAndRelease() {
1520  std::vector<const RexAgg*> result;
1521  for (auto& agg_expr : agg_exprs_) {
1522  result.push_back(agg_expr.release());
1523  }
1524  return result;
1525  }
1526 
1527  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
1528  return std::move(agg_exprs_);
1529  }
1530 
1531  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
1532  return agg_exprs_;
1533  }
1534 
1535  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
1536  agg_exprs_ = std::move(agg_exprs);
1537  }
1538 
1539  std::string toString(
1540  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1541  if (!config.attributes_only) {
1542  auto ret = cat(::typeName(this),
1543  "(",
1545  ", agg_exprs=",
1546  ::toString(agg_exprs_),
1547  ", fields=",
1548  ::toString(fields_));
1549  if (!config.skip_input_nodes) {
1550  ret += ::toString(inputs_);
1551  } else {
1552  ret += ", input node id={";
1553  for (auto& input : inputs_) {
1554  auto node_id_in_plan = input->getIdInPlanTree();
1555  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1556  : std::to_string(input->getId());
1557  ret += node_id_str + " ";
1558  }
1559  ret += "}";
1560  }
1561  return cat(ret, ")");
1562  } else {
1563  return cat(::typeName(this),
1564  "(",
1566  ", fields=",
1567  ::toString(fields_),
1568  ")");
1569  }
1570  }
1571 
1572  std::shared_ptr<RelAlgNode> deepCopy() const override {
1573  return std::make_shared<RelAggregate>(*this);
1574  }
1575 
1576  void addHint(const ExplainedQueryHint& hint_explained) {
1577  if (!hint_applied_) {
1578  hint_applied_ = true;
1579  }
1580  hints_->emplace(hint_explained.getHint(), hint_explained);
1581  }
1582 
1583  const bool hasHintEnabled(QueryHint candidate_hint) const {
1584  if (hint_applied_ && !hints_->empty()) {
1585  return hints_->find(candidate_hint) != hints_->end();
1586  }
1587  return false;
1588  }
1589 
1592  CHECK(!hints_->empty());
1593  CHECK(hasHintEnabled(hint));
1594  return hints_->at(hint);
1595  }
1596 
1597  bool hasDeliveredHint() { return !hints_->empty(); }
1598 
1599  Hints* getDeliveredHints() { return hints_.get(); }
1600 
1601  virtual size_t toHash() const override { return hash_value(*this); }
1602 
1603  private:
1604  friend std::size_t hash_value(RelAggregate const&);
1605 
1607  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1608  std::vector<std::string> fields_;
1610  std::unique_ptr<Hints> hints_;
1611 
1612  friend struct RelAlgDagSerializer;
1613 };
1614 
1615 class RelJoin : public RelAlgNode {
1616  public:
1617  // default constructor used for deserialization only
1619 
1620  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
1621  std::shared_ptr<const RelAlgNode> rhs,
1622  std::unique_ptr<const RexScalar>& condition,
1623  const JoinType join_type)
1624  : condition_(std::move(condition))
1625  , join_type_(join_type)
1626  , hint_applied_(false)
1627  , hints_(std::make_unique<Hints>()) {
1628  inputs_.push_back(lhs);
1629  inputs_.push_back(rhs);
1630  }
1631 
1632  RelJoin(RelJoin const&);
1633 
1634  virtual void acceptChildren(Visitor& v) const override {
1635  if (getCondition()) {
1636  getCondition()->accept(v, "condition");
1637  }
1638  for (auto& n : getInputs()) {
1639  if (n) {
1640  n->accept(v, "input");
1641  }
1642  }
1643  }
1644  virtual void accept(Visitor& v, std::string name) const override {
1645  if (v.visit(this, std::move(name))) {
1646  acceptChildren(v);
1647  }
1648  }
1649 
1650  JoinType getJoinType() const { return join_type_; }
1651 
1652  const RexScalar* getCondition() const { return condition_.get(); }
1653 
1654  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
1655 
1656  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1657  CHECK(condition);
1658  condition_ = std::move(condition);
1659  }
1660 
1661  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1662  std::shared_ptr<const RelAlgNode> input) override;
1663 
1664  std::string toString(
1665  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1666  if (!config.attributes_only) {
1667  auto ret = cat(::typeName(this), "(");
1668  if (!config.skip_input_nodes) {
1669  ret += ::toString(inputs_);
1670  } else {
1671  ret += ", input node id={";
1672  for (auto& input : inputs_) {
1673  auto node_id_in_plan = input->getIdInPlanTree();
1674  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1675  : std::to_string(input->getId());
1676  ret += node_id_str + " ";
1677  }
1678  ret += "}";
1679  }
1680  return cat(ret,
1681  ", condition=",
1682  (condition_ ? condition_->toString(config) : "null"),
1683  ", join_type=",
1684  ::toString(join_type_));
1685  } else {
1686  return cat(::typeName(this),
1687  "(condition=",
1688  (condition_ ? condition_->toString(config) : "null"),
1689  ", join_type=",
1690  ::toString(join_type_),
1691  ")");
1692  }
1693  }
1694 
1695  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
1696 
1697  std::shared_ptr<RelAlgNode> deepCopy() const override {
1698  return std::make_shared<RelJoin>(*this);
1699  }
1700 
1701  void addHint(const ExplainedQueryHint& hint_explained) {
1702  if (!hint_applied_) {
1703  hint_applied_ = true;
1704  }
1705  hints_->emplace(hint_explained.getHint(), hint_explained);
1706  }
1707 
1708  const bool hasHintEnabled(QueryHint candidate_hint) const {
1709  if (hint_applied_ && !hints_->empty()) {
1710  return hints_->find(candidate_hint) != hints_->end();
1711  }
1712  return false;
1713  }
1714 
1717  CHECK(!hints_->empty());
1718  CHECK(hasHintEnabled(hint));
1719  return hints_->at(hint);
1720  }
1721 
1722  bool hasDeliveredHint() { return !hints_->empty(); }
1723 
1724  Hints* getDeliveredHints() { return hints_.get(); }
1725 
1726  virtual size_t toHash() const override { return hash_value(*this); }
1727 
1728  private:
1729  friend std::size_t hash_value(RelJoin const&);
1730 
1731  mutable std::unique_ptr<const RexScalar> condition_;
1734  std::unique_ptr<Hints> hints_;
1735 
1736  friend struct RelAlgDagSerializer;
1737 };
1738 
1739 // a helper node that contains detailed information of each level of join qual
1740 // which is used when extracting query plan DAG
1742  public:
1744  const RelAlgNode* rhs,
1745  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols,
1746  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols,
1747  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops,
1748  const RexScalar* outer_join_cond,
1749  const bool nested_loop,
1750  const JoinType join_type,
1751  const std::string& op_type,
1752  const std::string& qualifier,
1753  const std::string& op_typeinfo)
1754  : lhs_(lhs)
1755  , rhs_(rhs)
1756  , lhs_join_cols_(lhs_join_cols)
1757  , rhs_join_cols_(rhs_join_cols)
1758  , filter_ops_(filter_ops)
1759  , outer_join_cond_(outer_join_cond)
1760  , nested_loop_(nested_loop)
1761  , join_type_(join_type)
1762  , op_type_(op_type)
1763  , qualifier_(qualifier)
1764  , op_typeinfo_(op_typeinfo) {}
1765 
1766  virtual void acceptChildren(Visitor& v) const override {
1767  if (getLHS()) {
1768  getLHS()->accept(v, "left");
1769  }
1770  if (getRHS()) {
1771  getRHS()->accept(v, "right");
1772  }
1773  if (getOuterJoinCond()) {
1774  getOuterJoinCond()->accept(v, "outer condition");
1775  }
1776  for (auto& n : getInputs()) {
1777  if (n) {
1778  n->accept(v, "input");
1779  }
1780  }
1781  }
1782  virtual void accept(Visitor& v, std::string name) const override {
1783  if (v.visit(this, std::move(name))) {
1784  acceptChildren(v);
1785  }
1786  }
1787 
1788  std::string toString(
1789  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1790  std::ostringstream oss;
1791  oss << ::typeName(this) << "( join_quals { lhs: " << ::toString(lhs_join_cols_);
1792  oss << "rhs: " << ::toString(rhs_join_cols_);
1793  oss << " }, filter_quals: { " << ::toString(filter_ops_);
1794  oss << " }, outer_join_cond: { ";
1795  if (outer_join_cond_) {
1796  oss << outer_join_cond_->toString(config);
1797  } else {
1798  oss << "N/A";
1799  }
1800  oss << " }, loop_join: " << ::toString(nested_loop_);
1801  oss << ", join_type: " << ::toString(join_type_);
1802  oss << ", op_type: " << ::toString(op_type_);
1803  oss << ", qualifier: " << ::toString(qualifier_);
1804  oss << ", op_type_info: " << ::toString(op_typeinfo_) << ")";
1805  return oss.str();
1806  }
1807  const RelAlgNode* getLHS() const { return lhs_; }
1808  const RelAlgNode* getRHS() const { return rhs_; }
1809  size_t getFilterCondSize() const { return filter_ops_.size(); }
1810  const std::vector<std::shared_ptr<const Analyzer::Expr>> getFilterCond() const {
1811  return filter_ops_;
1812  }
1813  const RexScalar* getOuterJoinCond() const { return outer_join_cond_; }
1814  std::string getOpType() const { return op_type_; }
1815  std::string getQualifier() const { return qualifier_; }
1816  std::string getOpTypeInfo() const { return op_typeinfo_; }
1817  size_t size() const override { return 0; }
1818  JoinType getJoinType() const { return join_type_; }
1819  const RexScalar* getCondition() const {
1820  CHECK(false);
1821  return nullptr;
1822  }
1824  CHECK(false);
1825  return nullptr;
1826  }
1827  void setCondition(std::unique_ptr<const RexScalar>& condition) { CHECK(false); }
1828  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1829  std::shared_ptr<const RelAlgNode> input) override {
1830  CHECK(false);
1831  }
1832  std::shared_ptr<RelAlgNode> deepCopy() const override {
1833  CHECK(false);
1834  return nullptr;
1835  }
1836  std::string getFieldName(const size_t i) const;
1837  std::vector<const Analyzer::ColumnVar*> getJoinCols(bool lhs) const {
1838  if (lhs) {
1839  return lhs_join_cols_;
1840  }
1841  return rhs_join_cols_;
1842  }
1843  bool isNestedLoopQual() const { return nested_loop_; }
1844 
1845  virtual size_t toHash() const override { return hash_value(*this); }
1846 
1847  private:
1848  friend std::size_t hash_value(RelTranslatedJoin const&);
1849 
1852  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols_;
1853  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols_;
1854  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops_;
1856  const bool nested_loop_;
1858  const std::string op_type_;
1859  const std::string qualifier_;
1860  const std::string op_typeinfo_;
1861 };
1862 
1863 class RelFilter : public RelAlgNode {
1864  public:
1865  // default constructor, used for deserialization only
1866  RelFilter() = default;
1867 
1868  RelFilter(std::unique_ptr<const RexScalar>& filter,
1869  std::shared_ptr<const RelAlgNode> input)
1870  : filter_(std::move(filter)) {
1871  CHECK(filter_);
1872  inputs_.push_back(input);
1873  }
1874 
1875  // for dummy filter node for data recycler
1876  RelFilter(std::unique_ptr<const RexScalar>& filter) : filter_(std::move(filter)) {
1877  CHECK(filter_);
1878  }
1879 
1880  RelFilter(RelFilter const&);
1881 
1882  virtual void acceptChildren(Visitor& v) const override {
1883  if (getCondition()) {
1884  getCondition()->accept(v, "condition");
1885  }
1886  for (auto& n : getInputs()) {
1887  if (n) {
1888  n->accept(v, "input");
1889  }
1890  }
1891  }
1892  virtual void accept(Visitor& v, std::string name) const override {
1893  if (v.visit(this, std::move(name))) {
1894  acceptChildren(v);
1895  }
1896  }
1897 
1898  const RexScalar* getCondition() const { return filter_.get(); }
1899 
1900  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
1901 
1902  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1903  CHECK(condition);
1904  filter_ = std::move(condition);
1905  }
1906 
1907  size_t size() const override { return inputs_[0]->size(); }
1908 
1909  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1910  std::shared_ptr<const RelAlgNode> input) override;
1911 
1912  std::string toString(
1913  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1914  if (!config.attributes_only) {
1915  auto ret = cat(
1916  ::typeName(this), "(", (filter_ ? filter_->toString(config) : "null"), ", ");
1917  if (!config.skip_input_nodes) {
1918  ret += ::toString(inputs_);
1919  } else {
1920  ret += ", input node id={";
1921  for (auto& input : inputs_) {
1922  auto node_id_in_plan = input->getIdInPlanTree();
1923  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1924  : std::to_string(input->getId());
1925  ret += node_id_str + " ";
1926  }
1927  ret += "}";
1928  }
1929  return cat(ret, ")");
1930  } else {
1931  return cat(
1932  ::typeName(this), "(", (filter_ ? filter_->toString(config) : "null"), ")");
1933  }
1934  }
1935 
1936  std::shared_ptr<RelAlgNode> deepCopy() const override {
1937  return std::make_shared<RelFilter>(*this);
1938  }
1939 
1940  virtual size_t toHash() const override { return hash_value(*this); }
1941 
1942  private:
1943  friend std::size_t hash_value(RelFilter const&);
1944 
1945  std::unique_ptr<const RexScalar> filter_;
1946 
1947  friend struct RelAlgDagSerializer;
1948 };
1949 
1950 // Synthetic node to assist execution of left-deep join relational algebra.
1952  public:
1953  // default constructor used for deserialization only
1954  RelLeftDeepInnerJoin() = default;
1955 
1956  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1957  RelAlgInputs inputs,
1958  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1959 
1960  virtual void acceptChildren(Visitor& v) const override {
1961  if (getInnerCondition()) {
1962  getInnerCondition()->accept(v, "inner condition");
1963  }
1964  for (size_t level = 1; level <= getOuterConditionsSize(); ++level) {
1965  if (getOuterCondition(level)) {
1966  getOuterCondition(level)->accept(v, "outer condition");
1967  }
1968  }
1969  for (auto& n : getInputs()) {
1970  if (n) {
1971  n->accept(v, "input");
1972  }
1973  }
1974  }
1975  virtual void accept(Visitor& v, std::string name) const override {
1976  if (v.visit(this, std::move(name))) {
1977  acceptChildren(v);
1978  }
1979  }
1980 
1981  const RexScalar* getInnerCondition() const;
1982 
1983  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1984 
1985  const JoinType getJoinType(const size_t nesting_level) const;
1986 
1987  std::string toString(
1988  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
1989 
1990  size_t size() const override;
1991  virtual size_t getOuterConditionsSize() const;
1992 
1993  std::shared_ptr<RelAlgNode> deepCopy() const override;
1994 
1995  bool coversOriginalNode(const RelAlgNode* node) const;
1996 
1997  const RelFilter* getOriginalFilter() const;
1998 
1999  std::vector<std::shared_ptr<const RelJoin>> getOriginalJoins() const;
2000 
2001  virtual size_t toHash() const override { return hash_value(*this); }
2002 
2003  private:
2004  friend std::size_t hash_value(RelLeftDeepInnerJoin const&);
2005 
2006  std::unique_ptr<const RexScalar> condition_;
2007  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
2008  std::shared_ptr<RelFilter> original_filter_;
2009  std::vector<std::shared_ptr<const RelJoin>> original_joins_;
2010 
2011  friend struct RelAlgDagSerializer;
2012 };
2013 
2014 // The 'RelCompound' node combines filter and on the fly aggregate computation.
2015 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
2016 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
2017 // which can be efficiently executed with no intermediate buffers.
2019  public:
2020  // constructor used for deserialization only
2024  , is_agg_{false}
2025  , hint_applied_{false} {}
2026 
2027  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
2028  // or aggregate expressions owned by 'agg_exprs_', with the arguments
2029  // owned by 'scalar_sources_'.
2030  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
2031  const std::vector<const Rex*>& target_exprs,
2032  const size_t groupby_count,
2033  const std::vector<const RexAgg*>& agg_exprs,
2034  const std::vector<std::string>& fields,
2035  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
2036  const bool is_agg,
2037  bool update_disguised_as_select = false,
2038  bool delete_disguised_as_select = false,
2039  bool varlen_update_required = false,
2040  TableDescriptor const* manipulation_target_table = nullptr,
2041  ColumnNameList target_columns = ColumnNameList(),
2042  const Catalog_Namespace::Catalog* catalog = nullptr)
2043  : ModifyManipulationTarget(update_disguised_as_select,
2044  delete_disguised_as_select,
2045  varlen_update_required,
2046  manipulation_target_table,
2047  target_columns,
2048  catalog)
2049  , filter_expr_(std::move(filter_expr))
2050  , groupby_count_(groupby_count)
2051  , fields_(fields)
2052  , is_agg_(is_agg)
2053  , scalar_sources_(std::move(scalar_sources))
2054  , target_exprs_(target_exprs)
2055  , hint_applied_(false)
2056  , hints_(std::make_unique<Hints>()) {
2057  CHECK_EQ(fields.size(), target_exprs.size());
2058  for (auto agg_expr : agg_exprs) {
2059  agg_exprs_.emplace_back(agg_expr);
2060  }
2061  }
2062 
2063  RelCompound(RelCompound const&);
2064 
2065  virtual void acceptChildren(Visitor& v) const override {
2066  if (getFilterExpr()) {
2067  getFilterExpr()->accept(v, "filter");
2068  }
2069  for (size_t i = 0; i < getScalarSourcesSize(); ++i) {
2070  if (getScalarSource(i)) {
2071  getScalarSource(i)->accept(v, "scalar");
2072  }
2073  }
2074  for (size_t i = 0; i < getAggExprSize(); ++i) {
2075  if (getAggExpr(i)) {
2076  getAggExpr(i)->accept(v, "aggregate");
2077  }
2078  }
2079  for (auto& n : getInputs()) {
2080  if (n) {
2081  n->accept(v, "input");
2082  }
2083  }
2084  }
2085  virtual void accept(Visitor& v, std::string name) const override {
2086  if (v.visit(this, std::move(name))) {
2087  acceptChildren(v);
2088  }
2089  }
2090 
2091  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
2092  std::shared_ptr<const RelAlgNode> input) override;
2093 
2094  size_t size() const override { return target_exprs_.size(); }
2095 
2096  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
2097 
2098  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
2099  filter_expr_ = std::move(new_expr);
2100  }
2101 
2102  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
2103 
2104  const std::vector<std::string>& getFields() const { return fields_; }
2105 
2106  const std::string getFieldName(const size_t i) const { return fields_[i]; }
2107 
2108  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
2109 
2110  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
2111 
2112  const RexScalar* getScalarSource(const size_t i) const {
2113  return scalar_sources_[i].get();
2114  }
2115 
2116  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
2117  CHECK_EQ(new_sources.size(), scalar_sources_.size());
2118  scalar_sources_ = std::move(new_sources);
2119  }
2120 
2121  const size_t getGroupByCount() const { return groupby_count_; }
2122 
2123  bool isAggregate() const { return is_agg_; }
2124 
2125  size_t getAggExprSize() const { return agg_exprs_.size(); }
2126 
2127  const RexAgg* getAggExpr(size_t i) const { return agg_exprs_[i].get(); }
2128 
2129  std::string toString(
2130  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
2131 
2132  std::shared_ptr<RelAlgNode> deepCopy() const override {
2133  return std::make_shared<RelCompound>(*this);
2134  }
2135 
2136  void addHint(const ExplainedQueryHint& hint_explained) {
2137  if (!hint_applied_) {
2138  hint_applied_ = true;
2139  }
2140  hints_->emplace(hint_explained.getHint(), hint_explained);
2141  }
2142 
2143  const bool hasHintEnabled(QueryHint candidate_hint) const {
2144  if (hint_applied_ && !hints_->empty()) {
2145  return hints_->find(candidate_hint) != hints_->end();
2146  }
2147  return false;
2148  }
2149 
2152  CHECK(!hints_->empty());
2153  CHECK(hasHintEnabled(hint));
2154  return hints_->at(hint);
2155  }
2156 
2157  bool hasDeliveredHint() { return !hints_->empty(); }
2158 
2159  Hints* getDeliveredHints() { return hints_.get(); }
2160 
2161  virtual size_t toHash() const override { return hash_value(*this); }
2162 
2163  private:
2164  friend std::size_t hash_value(RelCompound const&);
2165 
2166  std::unique_ptr<const RexScalar> filter_expr_;
2168  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
2169  std::vector<std::string> fields_;
2170  bool is_agg_;
2171  std::vector<std::unique_ptr<const RexScalar>>
2172  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not
2173  // actually projected, just owned
2174  std::vector<const Rex*> target_exprs_;
2176  std::unique_ptr<Hints> hints_;
2177 
2178  friend struct RelAlgDagSerializer;
2179 };
2180 
2181 class RelSort : public RelAlgNode {
2182  public:
2183  // default constructor used for deserialization only
2184  RelSort() : limit_(std::nullopt), offset_(0) {}
2185 
2186  RelSort(const std::vector<SortField>& collation,
2187  std::optional<size_t> limit,
2188  const size_t offset,
2189  std::shared_ptr<const RelAlgNode> input)
2190  : collation_(collation), limit_(limit), offset_(offset) {
2191  inputs_.push_back(input);
2192  }
2193 
2194  virtual void acceptChildren(Visitor& v) const override {
2195  for (auto& n : getInputs()) {
2196  if (n) {
2197  n->accept(v, "input");
2198  }
2199  }
2200  }
2201  virtual void accept(Visitor& v, std::string name) const override {
2202  if (v.visit(this, std::move(name))) {
2203  acceptChildren(v);
2204  }
2205  }
2206 
2207  bool operator==(const RelSort& that) const {
2208  return limit_ == that.limit_ && offset_ == that.offset_ && hasEquivCollationOf(that);
2209  }
2210 
2211  size_t collationCount() const { return collation_.size(); }
2212 
2213  SortField getCollation(const size_t i) const {
2214  CHECK_LT(i, collation_.size());
2215  return collation_[i];
2216  }
2217 
2218  void setCollation(std::vector<SortField>&& collation) {
2219  collation_ = std::move(collation);
2220  }
2221 
2222  bool isEmptyResult() const { return limit_.value_or(-1) == 0; }
2223 
2224  bool isLimitDelivered() const { return limit_.has_value(); }
2225 
2226  std::optional<size_t> getLimit() const { return limit_; }
2227 
2228  size_t getOffset() const { return offset_; }
2229 
2230  std::string toString(
2231  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2232  const std::string limit_info = limit_ ? std::to_string(*limit_) : "N/A";
2233  auto ret = cat(::typeName(this),
2234  "(",
2235  "collation=",
2236  ::toString(collation_),
2237  ", limit=",
2238  limit_info,
2239  ", offset",
2240  std::to_string(offset_));
2241  if (!config.skip_input_nodes) {
2242  ret += ", inputs=", ::toString(inputs_);
2243  } else {
2244  ret += ", input node id={";
2245  for (auto& input : inputs_) {
2246  auto node_id_in_plan = input->getIdInPlanTree();
2247  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
2248  : std::to_string(input->getId());
2249  ret += node_id_str + " ";
2250  }
2251  ret += "}";
2252  }
2253  return cat(ret, ")");
2254  }
2255 
2256  size_t size() const override { return inputs_[0]->size(); }
2257 
2258  std::shared_ptr<RelAlgNode> deepCopy() const override {
2259  return std::make_shared<RelSort>(*this);
2260  }
2261 
2262  virtual size_t toHash() const override { return hash_value(*this); }
2263 
2264  std::list<Analyzer::OrderEntry> getOrderEntries() const {
2265  std::list<Analyzer::OrderEntry> result;
2266  for (size_t i = 0; i < collation_.size(); ++i) {
2267  const auto sort_field = collation_[i];
2268  result.emplace_back(sort_field.getField() + 1,
2269  sort_field.getSortDir() == SortDirection::Descending,
2270  sort_field.getNullsPosition() == NullSortedPosition::First);
2271  }
2272  return result;
2273  }
2274 
2275  private:
2276  friend std::size_t hash_value(RelSort const&);
2277 
2278  std::vector<SortField> collation_;
2279  std::optional<size_t> limit_;
2280  size_t offset_;
2281 
2282  bool hasEquivCollationOf(const RelSort& that) const;
2283 
2284  friend struct RelAlgDagSerializer;
2285 };
2286 
2287 class RelModify : public RelAlgNode {
2288  public:
2290  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
2291  using TargetColumnList = std::vector<std::string>;
2292 
2293  static std::string yieldModifyOperationString(ModifyOperation const op) {
2294  switch (op) {
2296  return "DELETE";
2298  return "INSERT";
2300  return "UPDATE";
2301  default:
2302  break;
2303  }
2304  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
2305  }
2306 
2307  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
2308  if (op_string == "INSERT") {
2309  return ModifyOperation::Insert;
2310  } else if (op_string == "DELETE") {
2311  return ModifyOperation::Delete;
2312  } else if (op_string == "UPDATE") {
2313  return ModifyOperation::Update;
2314  }
2315 
2316  throw std::runtime_error(
2317  std::string("Unsupported logical modify operation encountered " + op_string));
2318  }
2319 
2320  // constructor used for deserialization only
2322  : catalog_{cat}
2323  , table_descriptor_{td}
2324  , flattened_{false}
2326 
2328  TableDescriptor const* const td,
2329  bool flattened,
2330  std::string const& op_string,
2331  TargetColumnList const& target_column_list,
2332  RelAlgNodeInputPtr input)
2333  : catalog_(cat)
2334  , table_descriptor_(td)
2335  , flattened_(flattened)
2336  , operation_(yieldModifyOperationEnum(op_string))
2337  , target_column_list_(target_column_list) {
2339  inputs_.push_back(input);
2340  }
2341 
2343  TableDescriptor const* const td,
2344  bool flattened,
2345  ModifyOperation op,
2346  TargetColumnList const& target_column_list,
2347  RelAlgNodeInputPtr input)
2348  : catalog_(cat)
2349  , table_descriptor_(td)
2350  , flattened_(flattened)
2351  , operation_(op)
2352  , target_column_list_(target_column_list) {
2354  inputs_.push_back(input);
2355  }
2356 
2357  virtual void acceptChildren(Visitor& v) const override {
2358  for (auto& n : getInputs()) {
2359  if (n) {
2360  n->accept(v, "input");
2361  }
2362  }
2363  }
2364  virtual void accept(Visitor& v, std::string name) const override {
2365  if (v.visit(this, std::move(name))) {
2366  acceptChildren(v);
2367  }
2368  }
2369 
2370  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
2371 
2373 
2374  bool const isFlattened() const { return flattened_; }
2377  int getUpdateColumnCount() const { return target_column_list_.size(); }
2378 
2379  size_t size() const override { return 0; }
2380  std::shared_ptr<RelAlgNode> deepCopy() const override {
2381  return std::make_shared<RelModify>(*this);
2382  }
2383 
2384  std::string toString(
2385  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2386  auto ret = cat(::typeName(this),
2387  "(",
2389  ", flattened=",
2391  ", op=",
2393  ", target_column_list=",
2395 
2396  if (!config.skip_input_nodes) {
2397  ret += ", inputs=", ::toString(inputs_);
2398  } else {
2399  ret += ", input node id={";
2400  for (auto& input : inputs_) {
2401  auto node_id_in_plan = input->getIdInPlanTree();
2402  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
2403  : std::to_string(input->getId());
2404  ret += node_id_str + " ";
2405  }
2406  ret += "}";
2407  }
2408  return cat(ret, ")");
2409  }
2410 
2412  auto previous_node = dynamic_cast<RelProject const*>(inputs_[0].get());
2413  CHECK(previous_node != nullptr);
2414  auto previous_project_node = const_cast<RelProject*>(previous_node);
2415 
2416  if (previous_project_node->hasWindowFunctionExpr()) {
2417  if (table_descriptor_->fragmenter->getNumFragments() > 1) {
2418  throw std::runtime_error(
2419  "UPDATE of a column of multi-fragmented table using window function not "
2420  "currently supported.");
2421  }
2422  if (table_descriptor_->nShards > 0) {
2423  throw std::runtime_error(
2424  "UPDATE of a column of sharded table using window function not "
2425  "currently supported.");
2426  }
2427  }
2428 
2429  previous_project_node->setUpdateViaSelectFlag(true);
2430  // remove the offset column in the projection for update handling
2431  target_column_list_.pop_back();
2432 
2433  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
2434  previous_project_node->setTargetColumns(target_column_list_);
2435  previous_project_node->setModifiedTableCatalog(&catalog_);
2436 
2437  int target_update_column_expr_start = 0;
2438  int target_update_column_expr_end = (int)(target_column_list_.size() - 1);
2439  CHECK(target_update_column_expr_start >= 0);
2440  CHECK(target_update_column_expr_end >= 0);
2441 
2442  bool varlen_update_required = false;
2443 
2444  auto varlen_scan_visitor = [this,
2445  &varlen_update_required,
2446  target_update_column_expr_start,
2447  target_update_column_expr_end](int index) {
2448  if (index >= target_update_column_expr_start &&
2449  index <= target_update_column_expr_end) {
2450  auto target_index = index - target_update_column_expr_start;
2451 
2452  auto* column_desc = catalog_.getMetadataForColumn(
2454  CHECK(column_desc);
2455 
2456  if (table_descriptor_->nShards) {
2457  const auto shard_cd =
2459  CHECK(shard_cd);
2460  if ((column_desc->columnName == shard_cd->columnName)) {
2461  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
2462  }
2463  }
2464 
2465  // Check for valid types
2466  if (column_desc->columnType.is_varlen()) {
2467  varlen_update_required = true;
2468  }
2469  if (column_desc->columnType.is_geometry()) {
2470  throw std::runtime_error("UPDATE of a geo column is unsupported.");
2471  }
2472  }
2473  };
2474 
2475  previous_project_node->visitScalarExprs(varlen_scan_visitor);
2476  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
2477  }
2478 
2480  auto previous_node = dynamic_cast<RelProject const*>(inputs_[0].get());
2481  CHECK(previous_node != nullptr);
2482  auto previous_project_node = const_cast<RelProject*>(previous_node);
2483  previous_project_node->setDeleteViaSelectFlag(true);
2484  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
2485  previous_project_node->setModifiedTableCatalog(&catalog_);
2486  }
2487 
2488  virtual size_t toHash() const override { return hash_value(*this); }
2489 
2490  private:
2491  friend std::size_t hash_value(RelModify const&);
2492 
2498 
2499  friend struct RelAlgDagSerializer;
2500 };
2501 
2503  public:
2504  // default constructor used for deserialization only
2505  RelTableFunction() = default;
2506 
2507  RelTableFunction(const std::string& function_name,
2508  RelAlgInputs inputs,
2509  std::vector<std::string>& fields,
2510  std::vector<const Rex*> col_inputs,
2511  std::vector<std::unique_ptr<const RexScalar>>& table_func_inputs,
2512  std::vector<std::unique_ptr<const RexScalar>>& target_exprs)
2513  : function_name_(function_name)
2514  , fields_(fields)
2515  , col_inputs_(col_inputs)
2516  , table_func_inputs_(std::move(table_func_inputs))
2517  , target_exprs_(std::move(target_exprs)) {
2518  for (const auto& input : inputs) {
2519  inputs_.emplace_back(input);
2520  }
2521  }
2522 
2524 
2525  virtual void acceptChildren(Visitor& v) const override {
2526  for (size_t i = 0; i < getTableFuncInputsSize(); ++i) {
2527  if (getTableFuncInputAt(i)) {
2528  getTableFuncInputAt(i)->accept(v, "argument");
2529  }
2530  }
2531  for (size_t i = 0; i < size(); ++i) {
2532  if (getTargetExpr(i)) {
2533  getTargetExpr(i)->accept(v, "target");
2534  }
2535  }
2536  for (auto& n : getInputs()) {
2537  if (n) {
2538  n->accept(v, "input");
2539  }
2540  }
2541  }
2542  virtual void accept(Visitor& v, std::string name) const override {
2543  if (v.visit(this, std::move(name))) {
2544  acceptChildren(v);
2545  }
2546  }
2547 
2548  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
2549  std::shared_ptr<const RelAlgNode> input) override;
2550 
2551  std::string getFunctionName() const { return function_name_; }
2552 
2553  size_t size() const override { return target_exprs_.size(); }
2554 
2555  const RexScalar* getTargetExpr(size_t idx) const {
2556  CHECK_LT(idx, target_exprs_.size());
2557  return target_exprs_[idx].get();
2558  }
2559 
2560  size_t getTableFuncInputsSize() const { return table_func_inputs_.size(); }
2561 
2562  size_t getColInputsSize() const { return col_inputs_.size(); }
2563 
2564  int32_t countRexLiteralArgs() const;
2565 
2566  const RexScalar* getTableFuncInputAt(const size_t idx) const {
2567  CHECK_LT(idx, table_func_inputs_.size());
2568  return table_func_inputs_[idx].get();
2569  }
2570 
2571  const RexScalar* getTableFuncInputAtAndRelease(const size_t idx) {
2572  // NOTE: as of 08/06/22, this appears to only be called by the bind_inputs free
2573  // function in RelAlgDag.cpp to disambituate inputs. If you follow the bind_inputs
2574  // path, it eventually could call this method in a bind_table_func_to_input lambda
2575  // According to that lambda, the released pointer released here is be immediately be
2576  // placed in a new vector of RexScalar unique_ptrs which is then ultimatey used as an
2577  // argument for the setTableFuncInputs method below. As such, if a table_func_input_
2578  // is released here that is being pointed to by one of the col_inputs_, then we can
2579  // keep that col_inputs_ pointer as that table_func_input_ should be returned back.
2580  CHECK_LT(idx, table_func_inputs_.size());
2581  return table_func_inputs_[idx].release();
2582  }
2583 
2584  void setTableFuncInputs(std::vector<std::unique_ptr<const RexScalar>>&& exprs);
2585 
2586  std::string getFieldName(const size_t idx) const {
2587  CHECK_LT(idx, fields_.size());
2588  return fields_[idx];
2589  }
2590 
2591  const std::vector<std::string>& getFields() const { return fields_; }
2592  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
2593 
2594  std::shared_ptr<RelAlgNode> deepCopy() const override {
2595  return std::make_shared<RelTableFunction>(*this);
2596  }
2597 
2598  std::string toString(
2599  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2600  if (!config.attributes_only) {
2601  auto ret = cat(::typeName(this), "(", function_name_);
2602  if (!config.skip_input_nodes) {
2603  ret += ", inputs=", ::toString(inputs_);
2604  } else {
2605  ret += ", input node id={";
2606  for (auto& input : inputs_) {
2607  auto node_id_in_plan = input->getIdInPlanTree();
2608  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
2609  : std::to_string(input->getId());
2610  ret += node_id_str + " ";
2611  }
2612  ret += "}";
2613  }
2614  ret += cat(
2615  ", fields=", ::toString(fields_), ", col_inputs=...", ", table_func_inputs=");
2616  if (!config.skip_input_nodes) {
2618  } else {
2619  for (auto& expr : table_func_inputs_) {
2620  ret += expr->toString(config) + " ";
2621  }
2622  }
2623  ret += ", target_exprs=";
2624  for (auto& expr : target_exprs_) {
2625  ret += expr->toString(config) + " ";
2626  }
2627  return cat(ret, ")");
2628  } else {
2629  return cat(
2630  ::typeName(this), "(", function_name_, ", fields=", ::toString(fields_), ")");
2631  }
2632  }
2633 
2634  virtual size_t toHash() const override { return hash_value(*this); }
2635 
2636  private:
2637  friend std::size_t hash_value(RelTableFunction const&);
2638 
2639  std::string function_name_;
2640  std::vector<std::string> fields_;
2641 
2642  std::vector<const Rex*> col_inputs_; // owned by `table_func_inputs_`, but allows
2643  // picking out the specific input columns vs
2644  // other table function inputs (e.g. literals)
2645  std::vector<std::unique_ptr<const RexScalar>> table_func_inputs_;
2646 
2647  std::vector<std::unique_ptr<const RexScalar>>
2648  target_exprs_; // Note: these should all be RexRef but are stored as RexScalar
2649  // for consistency
2650 
2651  friend struct RelAlgDagSerializer;
2652 };
2653 
2655  public:
2656  using RowValues = std::vector<std::unique_ptr<const RexScalar>>;
2657 
2658  // default constructor used for deserialization only
2659  RelLogicalValues() = default;
2660 
2661  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type,
2662  std::vector<RowValues>& values)
2663  : tuple_type_(tuple_type), values_(std::move(values)) {}
2664 
2666 
2667  virtual void acceptChildren(Visitor& v) const override {
2668  for (size_t row_idx = 0; row_idx < getNumRows(); ++row_idx) {
2669  for (size_t col_idx = 0; col_idx < getRowsSize(); ++col_idx) {
2670  if (getValueAt(row_idx, col_idx)) {
2671  getValueAt(row_idx, col_idx)->accept(v, "value");
2672  }
2673  }
2674  }
2675  for (auto& n : getInputs()) {
2676  if (n) {
2677  n->accept(v, "input");
2678  }
2679  }
2680  }
2681  virtual void accept(Visitor& v, std::string name) const override {
2682  if (v.visit(this, std::move(name))) {
2683  acceptChildren(v);
2684  }
2685  }
2686 
2687  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
2688 
2689  std::string toString(
2690  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2691  std::string ret = ::typeName(this) + "(";
2692  for (const auto& target_meta_info : tuple_type_) {
2693  ret += "(" + target_meta_info.get_resname() + " " +
2694  target_meta_info.get_type_info().get_type_name() + ")";
2695  }
2696  ret += ")";
2697  return ret;
2698  }
2699 
2700  std::string getFieldName(const size_t col_idx) const {
2701  CHECK_LT(col_idx, size());
2702  return tuple_type_[col_idx].get_resname();
2703  }
2704 
2705  const RexScalar* getValueAt(const size_t row_idx, const size_t col_idx) const {
2706  CHECK_LT(row_idx, values_.size());
2707  const auto& row = values_[row_idx];
2708  CHECK_LT(col_idx, row.size());
2709  return row[col_idx].get();
2710  }
2711 
2712  size_t getRowsSize() const {
2713  if (values_.empty()) {
2714  return 0;
2715  } else {
2716  return values_.front().size();
2717  }
2718  }
2719 
2720  size_t getNumRows() const { return values_.size(); }
2721 
2722  size_t size() const override { return tuple_type_.size(); }
2723 
2724  bool hasRows() const { return !values_.empty(); }
2725 
2726  std::shared_ptr<RelAlgNode> deepCopy() const override {
2727  return std::make_shared<RelLogicalValues>(*this);
2728  }
2729 
2730  virtual size_t toHash() const override { return hash_value(*this); }
2731 
2732  private:
2733  friend std::size_t hash_value(RelLogicalValues const&);
2734 
2735  std::vector<TargetMetaInfo> tuple_type_;
2736  std::vector<RowValues> values_;
2737 
2738  friend struct RelAlgDagSerializer;
2739 };
2740 
2741 class RelLogicalUnion : public RelAlgNode {
2742  public:
2743  // default constructor used for deserialization only
2744  RelLogicalUnion() : is_all_{false} {}
2745 
2746  RelLogicalUnion(RelAlgInputs, bool is_all);
2747 
2748  virtual void acceptChildren(Visitor& v) const override {
2749  for (auto& n : getInputs()) {
2750  if (n) {
2751  n->accept(v, "input");
2752  }
2753  }
2754  }
2755  virtual void accept(Visitor& v, std::string name) const override {
2756  if (v.visit(this, std::move(name))) {
2757  acceptChildren(v);
2758  }
2759  }
2760 
2761  std::shared_ptr<RelAlgNode> deepCopy() const override {
2762  return std::make_shared<RelLogicalUnion>(*this);
2763  }
2764  size_t size() const override;
2765  std::string toString(
2766  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
2767 
2768  std::string getFieldName(const size_t i) const;
2769 
2770  inline bool isAll() const { return is_all_; }
2771  // Will throw a std::runtime_error if MetaInfo types don't match.
2772  std::vector<TargetMetaInfo> getCompatibleMetainfoTypes() const;
2773  RexScalar const* copyAndRedirectSource(RexScalar const*, size_t input_idx) const;
2774 
2775  // Not unique_ptr to allow for an easy deepCopy() implementation.
2776  mutable std::vector<std::shared_ptr<const RexScalar>> scalar_exprs_;
2777 
2778  virtual size_t toHash() const override { return hash_value(*this); }
2779 
2780  private:
2781  friend std::size_t hash_value(RelLogicalUnion const&);
2783 
2784  bool is_all_;
2785 
2786  friend struct RelAlgDagSerializer;
2787 };
2788 
2789 class QueryNotSupported : public std::runtime_error {
2790  public:
2791  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
2792 };
2793 
2799 class RelAlgDag : public boost::noncopyable {
2800  public:
2802 
2804 
2806 
2807  void eachNode(std::function<void(RelAlgNode const*)> const&) const;
2808 
2812  const RelAlgNode& getRootNode() const {
2813  CHECK(nodes_.size());
2814  const auto& last_ptr = nodes_.back();
2815  CHECK(last_ptr);
2816  return *last_ptr;
2817  }
2818 
2819  std::shared_ptr<const RelAlgNode> getRootNodeShPtr() const {
2820  CHECK(nodes_.size());
2821  return nodes_.back();
2822  }
2823 
2824  std::vector<std::shared_ptr<RelAlgNode>>& getNodes() { return nodes_; }
2825 
2830  void registerSubquery(std::shared_ptr<RexSubQuery> subquery) {
2831  subqueries_.push_back(subquery);
2832  }
2833 
2837  const std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries() const {
2838  return subqueries_;
2839  }
2840 
2841  // todo(yoonmin): simplify and improve query register logic
2842  void registerQueryHints(std::shared_ptr<RelAlgNode> node,
2843  Hints* hints_delivered,
2844  RegisteredQueryHint& global_query_hint) {
2845  std::optional<bool> has_global_columnar_output_hint = std::nullopt;
2846  std::optional<bool> has_global_rowwise_output_hint = std::nullopt;
2847  RegisteredQueryHint query_hint;
2848  for (auto it = hints_delivered->begin(); it != hints_delivered->end(); it++) {
2849  auto target = it->second;
2850  auto hint_type = it->first;
2851  switch (hint_type) {
2852  case QueryHint::kCpuMode: {
2853  query_hint.registerHint(QueryHint::kCpuMode);
2854  query_hint.cpu_mode = true;
2855  if (target.isGlobalHint()) {
2856  global_query_hint.registerHint(QueryHint::kCpuMode);
2857  global_query_hint.cpu_mode = true;
2858  }
2859  break;
2860  }
2862  has_global_columnar_output_hint = target.isGlobalHint();
2863  break;
2864  }
2866  has_global_rowwise_output_hint = target.isGlobalHint();
2867  break;
2868  }
2870  if (target.getListOptions().size() != 1) {
2871  VLOG(1) << "Skip the given query hint \"bbox_intersect_bucket_threshold\" ("
2872  << target.getListOptions()[0]
2873  << ") : invalid # hint options are given";
2874  break;
2875  }
2876  double bbox_intersect_bucket_threshold = std::stod(target.getListOptions()[0]);
2877  if (bbox_intersect_bucket_threshold >= 0.0 &&
2878  bbox_intersect_bucket_threshold <= 90.0) {
2880  query_hint.bbox_intersect_bucket_threshold = bbox_intersect_bucket_threshold;
2881  if (target.isGlobalHint()) {
2883  global_query_hint.bbox_intersect_bucket_threshold =
2884  bbox_intersect_bucket_threshold;
2885  }
2886  } else {
2887  VLOG(1) << "Skip the given query hint \"bbox_intersect_bucket_threshold\" ("
2888  << bbox_intersect_bucket_threshold
2889  << ") : the hint value should be within 0.0 ~ 90.0";
2890  }
2891  break;
2892  }
2894  if (target.getListOptions().size() != 1) {
2895  VLOG(1) << "Skip the given query hint \"bbox_intersect_max_size\" ("
2896  << target.getListOptions()[0]
2897  << ") : invalid # hint options are given";
2898  break;
2899  }
2900  std::stringstream ss(target.getListOptions()[0]);
2901  int bbox_intersect_max_size;
2902  ss >> bbox_intersect_max_size;
2903  if (bbox_intersect_max_size >= 0) {
2905  query_hint.bbox_intersect_max_size = (size_t)bbox_intersect_max_size;
2906  if (target.isGlobalHint()) {
2908  global_query_hint.bbox_intersect_max_size = (size_t)bbox_intersect_max_size;
2909  }
2910  } else {
2911  VLOG(1) << "Skip the query hint \"bbox_intersect_max_size\" ("
2912  << bbox_intersect_max_size
2913  << ") : the hint value should be larger than or equal to zero";
2914  }
2915  break;
2916  }
2919  query_hint.bbox_intersect_allow_gpu_build = true;
2920  if (target.isGlobalHint()) {
2922  global_query_hint.bbox_intersect_allow_gpu_build = true;
2923  }
2924  break;
2925  }
2928  query_hint.bbox_intersect_no_cache = true;
2929  if (target.isGlobalHint()) {
2931  global_query_hint.bbox_intersect_no_cache = true;
2932  }
2933  VLOG(1) << "Skip auto tuner and hashtable caching for bbox_intersect join.";
2934  break;
2935  }
2937  if (target.getListOptions().size() != 1) {
2938  VLOG(1) << "Skip the given query hint \"bbox_intersect_keys_per_bin\" ("
2939  << target.getListOptions()[0]
2940  << ") : invalid # hint options are given";
2941  break;
2942  }
2943  double bbox_intersect_keys_per_bin = std::stod(target.getListOptions()[0]);
2944  if (bbox_intersect_keys_per_bin > 0.0 &&
2945  bbox_intersect_keys_per_bin < std::numeric_limits<double>::max()) {
2947  query_hint.bbox_intersect_keys_per_bin = bbox_intersect_keys_per_bin;
2948  if (target.isGlobalHint()) {
2950  global_query_hint.bbox_intersect_keys_per_bin = bbox_intersect_keys_per_bin;
2951  }
2952  } else {
2953  VLOG(1) << "Skip the given query hint \"bbox_intersect_keys_per_bin\" ("
2954  << bbox_intersect_keys_per_bin
2955  << ") : the hint value should be larger than zero";
2956  }
2957  break;
2958  }
2959  case QueryHint::kKeepResult: {
2961  VLOG(1) << "Skip query hint \'keep_result\' because neither data recycler "
2962  "nor query resultset recycler is enabled";
2963  } else {
2965  query_hint.keep_result = true;
2966  if (target.isGlobalHint()) {
2967  global_query_hint.registerHint(QueryHint::kKeepResult);
2968  global_query_hint.keep_result = true;
2969  }
2970  }
2971  break;
2972  }
2975  VLOG(1) << "Skip query hint \'keep_table_function_result\' because neither "
2976  "data recycler "
2977  "nor query resultset recycler is enabled";
2978  } else {
2979  // we assume table function's hint is handled as global hint by default
2980  global_query_hint.registerHint(QueryHint::kKeepTableFuncResult);
2981  global_query_hint.keep_table_function_result = true;
2982  }
2983  break;
2984  }
2986  if (target.getListOptions().size() != 1u) {
2987  VLOG(1) << "Skip the given query hint \"aggregate_tree_fanout\" ("
2988  << target.getListOptions()[0]
2989  << ") : invalid # hint options are given";
2990  break;
2991  }
2992  int aggregate_tree_fanout = std::stoi(target.getListOptions()[0]);
2993  if (aggregate_tree_fanout < 0) {
2994  VLOG(1) << "A fan-out of an aggregate tree should be larger than zero";
2995  } else if (aggregate_tree_fanout > 1024) {
2996  VLOG(1) << "Too large fanout is provided (i.e., fanout < 1024)";
2997  } else {
2999  query_hint.aggregate_tree_fanout = aggregate_tree_fanout;
3000  if (target.isGlobalHint()) {
3001  global_query_hint.registerHint(QueryHint::kAggregateTreeFanout);
3002  global_query_hint.aggregate_tree_fanout = aggregate_tree_fanout;
3003  }
3004  }
3005  break;
3006  }
3008  CHECK_EQ(1u, target.getListOptions().size());
3009  int cuda_block_size = std::stoi(target.getListOptions()[0]);
3010  if (cuda_block_size <= 0) {
3011  VLOG(1) << "CUDA block size should be larger than zero";
3012  } else if (cuda_block_size > 1024) {
3013  VLOG(1) << "CUDA block size should be less or equal to 1024";
3014  } else {
3016  query_hint.cuda_block_size = cuda_block_size;
3017  if (target.isGlobalHint()) {
3018  global_query_hint.registerHint(QueryHint::kCudaBlockSize);
3019  global_query_hint.cuda_block_size = cuda_block_size;
3020  }
3021  }
3022  break;
3023  }
3024  case QueryHint::kCudaGridSize: {
3025  CHECK_EQ(1u, target.getListOptions().size());
3026  double cuda_grid_size_multiplier = std::stod(target.getListOptions()[0]);
3027  double min_grid_size_multiplier{0};
3028  double max_grid_size_multiplier{1024};
3029  if (cuda_grid_size_multiplier <= min_grid_size_multiplier) {
3030  VLOG(1) << "CUDA grid size multiplier should be larger than zero";
3031  } else if (cuda_grid_size_multiplier > max_grid_size_multiplier) {
3032  VLOG(1) << "CUDA grid size multiplier should be less than 1024";
3033  } else {
3035  query_hint.cuda_grid_size_multiplier = cuda_grid_size_multiplier;
3036  if (target.isGlobalHint()) {
3037  global_query_hint.registerHint(QueryHint::kCudaGridSize);
3038  global_query_hint.cuda_grid_size_multiplier = cuda_grid_size_multiplier;
3039  }
3040  }
3041  break;
3042  }
3045  query_hint.opt_cuda_grid_and_block_size = true;
3046  if (target.isGlobalHint()) {
3048  global_query_hint.opt_cuda_grid_and_block_size = true;
3049  }
3050  break;
3051  }
3052  case QueryHint::kWatchdog: {
3053  if (g_enable_watchdog) {
3054  VLOG(1) << "Skip the given query hint \"watchdog\": already enabled";
3055  } else {
3056  query_hint.registerHint(QueryHint::kWatchdog);
3057  query_hint.watchdog = true;
3058  if (target.isGlobalHint()) {
3059  global_query_hint.registerHint(QueryHint::kWatchdog);
3060  global_query_hint.watchdog = true;
3061  }
3062  }
3063  break;
3064  }
3065  case QueryHint::kWatchdogOff: {
3066  if (!g_enable_watchdog) {
3067  VLOG(1) << "Skip the given query hint \"watchdog_off\": already disabled";
3068  } else {
3070  query_hint.watchdog = false;
3071  if (target.isGlobalHint()) {
3072  global_query_hint.registerHint(QueryHint::kWatchdogOff);
3073  global_query_hint.watchdog = false;
3074  }
3075  }
3076 
3077  break;
3078  }
3081  VLOG(1) << "Skip the given query hint \"dynamic_watchdog\": already enabled";
3082  } else {
3084  query_hint.dynamic_watchdog = true;
3085  if (target.isGlobalHint()) {
3086  global_query_hint.registerHint(QueryHint::kDynamicWatchdog);
3087  global_query_hint.dynamic_watchdog = true;
3088  }
3089  }
3090  break;
3091  }
3094  VLOG(1)
3095  << "Skip the given query hint \"dynamic_watchdog_off\": already disabled";
3096  } else {
3098  query_hint.dynamic_watchdog = false;
3099  if (target.isGlobalHint()) {
3100  global_query_hint.registerHint(QueryHint::kDynamicWatchdogOff);
3101  global_query_hint.dynamic_watchdog = false;
3102  }
3103  }
3104  break;
3105  }
3107  if (hints_delivered->find(QueryHint::kDynamicWatchdogOff) !=
3108  hints_delivered->end()) {
3109  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
3110  << target.getListOptions()[0]
3111  << ") : cannot use it with \"dynamic_watchdog_off\" hint";
3112  break;
3113  }
3114  if (target.getListOptions().size() != 1) {
3115  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
3116  << target.getListOptions()[0]
3117  << ") : invalid # hint options are given";
3118  break;
3119  }
3120  double query_time_limit = std::stoi(target.getListOptions()[0]);
3121  if (query_time_limit <= 0) {
3122  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
3123  << target.getListOptions()[0]
3124  << ") : the hint value should be larger than zero";
3125  break;
3126  }
3128  query_hint.query_time_limit = query_time_limit;
3129  if (target.isGlobalHint()) {
3130  global_query_hint.registerHint(QueryHint::kQueryTimeLimit);
3131  global_query_hint.query_time_limit = query_time_limit;
3132  }
3133  break;
3134  }
3137  query_hint.use_loop_join = true;
3138  if (target.isGlobalHint()) {
3139  global_query_hint.registerHint(QueryHint::kAllowLoopJoin);
3140  global_query_hint.use_loop_join = true;
3141  }
3142  break;
3143  }
3146  query_hint.use_loop_join = false;
3147  if (target.isGlobalHint()) {
3148  global_query_hint.registerHint(QueryHint::kDisableLoopJoin);
3149  global_query_hint.use_loop_join = false;
3150  }
3151  break;
3152  }
3154  CHECK_EQ(1u, target.getListOptions().size());
3155  int loop_size_threshold = std::stoi(target.getListOptions()[0]);
3156  if (loop_size_threshold <= 0) {
3157  VLOG(1)
3158  << "Skip the given query hint \"loop_join_inner_table_max_num_rows\" ("
3159  << target.getListOptions()[0]
3160  << ") : the hint value should be larger than zero";
3161  } else {
3163  query_hint.loop_join_inner_table_max_num_rows = loop_size_threshold;
3164  if (target.isGlobalHint()) {
3166  global_query_hint.loop_join_inner_table_max_num_rows = loop_size_threshold;
3167  }
3168  }
3169  break;
3170  }
3172  CHECK_EQ(1u, target.getListOptions().size());
3173  int max_join_hash_table_size = std::stoi(target.getListOptions()[0]);
3174  if (max_join_hash_table_size <= 0) {
3175  VLOG(1) << "Skip the given query hint \"max_join_hashtable_size\" ("
3176  << target.getListOptions()[0]
3177  << ") : the hint value should be larger than zero";
3178  } else {
3180  query_hint.max_join_hash_table_size = max_join_hash_table_size;
3181  if (target.isGlobalHint()) {
3183  global_query_hint.max_join_hash_table_size = max_join_hash_table_size;
3184  }
3185  }
3186  break;
3187  }
3190  query_hint.force_baseline_hash_join = true;
3191  if (target.isGlobalHint()) {
3193  global_query_hint.force_baseline_hash_join = true;
3194  }
3195  break;
3196  }
3199  query_hint.force_one_to_many_hash_join = true;
3200  if (target.isGlobalHint()) {
3202  global_query_hint.force_one_to_many_hash_join = true;
3203  }
3204  break;
3205  }
3207  CHECK_EQ(1u, target.getListOptions().size());
3208  int watchdog_max_projected_rows_per_device =
3209  std::stoi(target.getListOptions()[0]);
3210  if (watchdog_max_projected_rows_per_device <= 0) {
3211  VLOG(1) << "Skip the given query hint "
3212  "\"watchdog_max_projected_rows_per_device\" ("
3213  << target.getListOptions()[0]
3214  << ") : the hint value should be larger than zero";
3215  } else {
3218  watchdog_max_projected_rows_per_device;
3219  if (target.isGlobalHint()) {
3220  global_query_hint.registerHint(
3222  global_query_hint.watchdog_max_projected_rows_per_device =
3223  watchdog_max_projected_rows_per_device;
3224  }
3225  }
3226  break;
3227  }
3229  CHECK_EQ(1u, target.getListOptions().size());
3230  int preflight_count_query_threshold = std::stoi(target.getListOptions()[0]);
3231  if (preflight_count_query_threshold <= 0) {
3232  VLOG(1) << "Skip the given query hint \"preflight_count_query_threshold\" ("
3233  << target.getListOptions()[0]
3234  << ") : the hint value should be larger than zero";
3235  } else {
3237  query_hint.preflight_count_query_threshold = preflight_count_query_threshold;
3238  if (target.isGlobalHint()) {
3240  global_query_hint.preflight_count_query_threshold =
3241  preflight_count_query_threshold;
3242  }
3243  }
3244  break;
3245  }
3246  default:
3247  break;
3248  }
3249  }
3250  // we have four cases depending on 1) g_enable_columnar_output flag
3251  // and 2) query hint status: columnar_output and rowwise_output
3252  // case 1. g_enable_columnar_output = true
3253  // case 1.a) columnar_output = true (so rowwise_output = false);
3254  // case 1.b) rowwise_output = true (so columnar_output = false);
3255  // case 2. g_enable_columnar_output = false
3256  // case 2.a) columnar_output = true (so rowwise_output = false);
3257  // case 2.b) rowwise_output = true (so columnar_output = false);
3258  // case 1.a --> use columnar output
3259  // case 1.b --> use rowwise output
3260  // case 2.a --> use columnar output
3261  // case 2.b --> use rowwise output
3262  if (has_global_columnar_output_hint.has_value() &&
3263  has_global_rowwise_output_hint.has_value()) {
3264  VLOG(1)
3265  << "Two hints 1) columnar output and 2) rowwise output are enabled together, "
3266  << "so skip them and use the runtime configuration "
3267  "\"g_enable_columnar_output\"";
3268  } else if (has_global_columnar_output_hint.has_value() &&
3269  !has_global_rowwise_output_hint.has_value()) {
3271  VLOG(1) << "We already enable columnar output by default "
3272  "(g_enable_columnar_output = true), so skip this columnar output hint";
3273  } else {
3275  query_hint.columnar_output = true;
3276  if (*has_global_columnar_output_hint) {
3277  global_query_hint.registerHint(QueryHint::kColumnarOutput);
3278  global_query_hint.columnar_output = true;
3279  }
3280  }
3281  } else if (!has_global_columnar_output_hint.has_value() &&
3282  has_global_rowwise_output_hint.has_value()) {
3283  if (!g_enable_columnar_output) {
3284  VLOG(1) << "We already use the default rowwise output (g_enable_columnar_output "
3285  "= false), so skip this rowwise output hint";
3286  } else {
3288  query_hint.rowwise_output = true;
3289  if (*has_global_rowwise_output_hint) {
3290  global_query_hint.registerHint(QueryHint::kRowwiseOutput);
3291  global_query_hint.rowwise_output = true;
3292  }
3293  }
3294  }
3295  registerQueryHint(node.get(), query_hint);
3296  }
3297 
3298  void registerQueryHint(const RelAlgNode* node, const RegisteredQueryHint& query_hint) {
3299  auto node_key = node->toHash();
3300  auto it = query_hint_.find(node_key);
3301  if (it == query_hint_.end()) {
3302  std::unordered_map<unsigned, RegisteredQueryHint> hint_map;
3303  hint_map.emplace(node->getId(), query_hint);
3304  query_hint_.emplace(node_key, hint_map);
3305  } else {
3306  it->second.emplace(node->getId(), query_hint);
3307  }
3308  }
3309 
3310  std::optional<RegisteredQueryHint> getQueryHint(const RelAlgNode* node) const {
3311  auto node_it = query_hint_.find(node->toHash());
3312  if (node_it != query_hint_.end()) {
3313  auto const& registered_query_hint_map = node_it->second;
3314  auto hint_it = registered_query_hint_map.find(node->getId());
3315  if (hint_it != registered_query_hint_map.end()) {
3316  auto const& registered_query_hint = hint_it->second;
3318  // apply global hint to the registered query hint for this query block
3319  return std::make_optional(registered_query_hint || global_hints_);
3320  } else {
3321  return std::make_optional(registered_query_hint);
3322  }
3323  }
3324  }
3326  // if no hint is registered from this query block
3327  // we return global hint instead
3328  return std::make_optional(global_hints_);
3329  }
3330  return std::nullopt;
3331  }
3332 
3333  std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>&
3335  return query_hint_;
3336  }
3337 
3339 
3340  void setGlobalQueryHints(const RegisteredQueryHint& global_hints) {
3341  global_hints_ = global_hints;
3342  }
3343 
3347  void resetQueryExecutionState();
3348 
3349  private:
3351 
3352  std::vector<std::shared_ptr<RelAlgNode>> nodes_;
3353  std::vector<std::shared_ptr<RexSubQuery>> subqueries_;
3354 
3355  // node hash --> {node id --> registered hint}
3356  // we additionally consider node id to recognize corresponding hint correctly
3357  // i.e., to recognize the correct hint when two subqueries are identical
3358  std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>
3361 
3362  friend struct RelAlgDagSerializer;
3363  friend struct RelAlgDagModifier;
3364 };
3365 
3374  protected:
3375  static std::vector<std::shared_ptr<RelAlgNode>>& getNodes(RelAlgDag& rel_alg_dag) {
3376  return rel_alg_dag.nodes_;
3377  }
3378 
3379  static std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries(
3380  RelAlgDag& rel_alg_dag) {
3381  return rel_alg_dag.subqueries_;
3382  }
3383 
3384  static std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>&
3385  getQueryHints(RelAlgDag& rel_alg_dag) {
3386  return rel_alg_dag.query_hint_;
3387  }
3388 
3389  static void setBuildState(RelAlgDag& rel_alg_dag,
3390  const RelAlgDag::BuildState build_state) {
3391  rel_alg_dag.build_state_ = build_state;
3392  }
3393 };
3394 
3409  static std::unique_ptr<RelAlgDag> buildDag(const std::string& query_ra,
3410  const bool optimize_dag);
3411 
3420  static std::unique_ptr<RelAlgDag> buildDagForSubquery(
3421  RelAlgDag& root_dag,
3422  const rapidjson::Value& query_ast);
3423 
3424  static void optimizeDag(RelAlgDag& rel_alg_dag);
3425 
3426  private:
3427  static std::unique_ptr<RelAlgDag> build(const rapidjson::Value& query_ast,
3428  RelAlgDag* root_dag,
3429  const bool optimize_dag);
3430 };
3431 
3432 using RANodeOutput = std::vector<RexInput>;
3433 
3434 RANodeOutput get_node_output(const RelAlgNode* ra_node);
3435 
3436 std::string tree_string(const RelAlgNode*, const size_t depth = 0);
3437 
3438 namespace boost {
3439 // boost::hash_value(T*) by default will hash just the address.
3440 // Specialize this function template for each type so that the object itself is hashed.
3441 constexpr size_t HASH_NULLPTR{0u};
3442 #define HEAVYAI_SPECIALIZE_HASH_VALUE_OF_POINTER(T) \
3443  template <> \
3444  inline std::size_t hash_value(T const* const& ptr) { \
3445  return ptr ? ptr->toHash() : HASH_NULLPTR; \
3446  } \
3447  template <> \
3448  inline std::size_t hash_value(T* const& ptr) { \
3449  return ptr ? ptr->toHash() : HASH_NULLPTR; \
3450  }
3451 
3479 #undef HEAVYAI_SPECIALIZE_HASH_VALUE_OF_POINTER
3480 } // namespace boost
std::vector< std::shared_ptr< const RexScalar > > scalar_exprs_
Definition: RelAlgDag.h:2776
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1832
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:2230
bool is_nop_
Definition: RelAlgDag.h:951
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1508
bool hasRows() const
Definition: RelAlgDag.h:2724
void setGlobalQueryHints(const RegisteredQueryHint &global_hints)
Definition: RelAlgDag.h:3340
bool isAll() const
Definition: RelAlgDag.h:2770
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
Definition: RelAlgDag.h:2213
std::unique_ptr< const RexScalar > condition_
Definition: RelAlgDag.h:1731
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:500
friend std::size_t hash_value(RelLeftDeepInnerJoin const &)
Definition: RelAlgDag.cpp:3740
RexWindowBound frame_start_bound_
Definition: RelAlgDag.h:725
RelCompound(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
Definition: RelAlgDag.h:2021
const RexScalar * getThen(const size_t idx) const
Definition: RelAlgDag.h:440
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:2667
void setOutputMetainfo(std::vector< TargetMetaInfo > targets_metainfo) const
Definition: RelAlgDag.h:850
virtual bool visit(RelScan const *n, std::string s)
Definition: RelAlgDag.h:95
SQLAgg
Definition: sqldefs.h:73
bool isNestedLoopQual() const
Definition: RelAlgDag.h:1843
virtual size_t toHash() const override
Definition: RelAlgDag.h:2488
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::unique_ptr< const RexScalar > ConstRexScalarPtr
Definition: RelAlgDag.h:1257
std::vector< std::unique_ptr< const RexScalar > > getExpressionsAndRelease()
Definition: RelAlgDag.h:1362
size_t groupby_count_
Definition: RelAlgDag.h:2167
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:278
size_t getOffset() const
Definition: RelAlgDag.h:2228
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1788
void setVarlenUpdateRequired(bool required) const
Definition: RelAlgDag.h:1200
RexLiteral(const bool val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned target_scale, const unsigned target_precision)
Definition: RelAlgDag.h:252
std::vector< std::unique_ptr< const RexScalar > > outer_conditions_per_level_
Definition: RelAlgDag.h:2007
bool const isFlattened() const
Definition: RelAlgDag.h:2374
std::unique_ptr< RexSubQuery > deepCopy() const
Definition: RelAlgDag.cpp:60
ConstRexScalarPtrVector getPartitionKeysAndRelease() const
Definition: RelAlgDag.h:645
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:1488
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
unsigned in_index_
Definition: RelAlgDag.h:188
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.h:1374
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const
Definition: RelAlgDag.h:2837
JoinType
Definition: sqldefs.h:174
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1572
virtual size_t toHash() const override
Definition: RelAlgDag.h:2001
int getUpdateColumnCount() const
Definition: RelAlgDag.h:2377
static std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > & getQueryHints(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3385
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > query_hint_
Definition: RelAlgDag.h:3359
ColumnNameList target_columns_
Definition: RelAlgDag.h:1247
bool g_use_query_resultset_cache
Definition: Execute.cpp:156
const bool hasHintEnabled(QueryHint candidate_hint) const
Definition: RelAlgDag.h:1708
std::vector< std::unique_ptr< const RexScalar > > table_func_inputs_
Definition: RelAlgDag.h:2645
std::string cat(Ts &&...args)
void replacePartitionKey(size_t offset, std::unique_ptr< const RexScalar > &&new_partition_key)
Definition: RelAlgDag.h:655
const Rex * getTargetExpr(const size_t i) const
Definition: RelAlgDag.h:2102
virtual bool visit(RexInput const *n, std::string s)
Definition: RelAlgDag.h:102
virtual size_t toHash() const override
Definition: RelAlgDag.h:2778
SQLAgg getKind() const
Definition: RelAlgDag.h:799
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:2755
TableDescriptor const * getTableDescriptor() const
Definition: RelAlgDag.h:1206
RelAlgNode(RelAlgInputs inputs={})
Definition: RelAlgDag.h:830
std::string getOpTypeInfo() const
Definition: RelAlgDag.h:1816
virtual bool visit(RexAbstractInput const *n, std::string s)
Definition: RelAlgDag.h:99
size_t size() const override
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:168
friend std::size_t hash_value(RelModify const &)
Definition: RelAlgDag.cpp:3781
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:143
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1167
RexFunctionOperator()=default
const std::vector< std::shared_ptr< const Analyzer::Expr > > getFilterCond() const
Definition: RelAlgDag.h:1810
size_t size() const override
Definition: RelAlgDag.h:1320
SQLTypes
Definition: sqltypes.h:65
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1139
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1427
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:2136
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1892
std::string tableName
const bool nested_loop_
Definition: RelAlgDag.h:1856
bool coversOriginalNode(const RelAlgNode *node) const
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:2096
size_t size() const override
Definition: RelAlgDag.h:2722
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:779
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:2085
size_t groupby_count_
Definition: RelAlgDag.h:1606
friend std::size_t hash_value(RelJoin const &)
Definition: RelAlgDag.cpp:3702
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:2364
virtual bool visit(RexWindowFunctionOperator const *n, std::string s)
Definition: RelAlgDag.h:108
std::list< Analyzer::OrderEntry > getOrderEntries() const
Definition: RelAlgDag.h:2264
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1539
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.cpp:3488
size_t getOperand(size_t idx) const
Definition: RelAlgDag.h:805
virtual size_t toHash() const override
Definition: RelAlgDag.h:1438
TargetColumnList const & getUpdateColumnNames() const
Definition: RelAlgDag.h:2376
virtual size_t toHash() const override
Definition: RelAlgDag.h:757
std::vector< RexInput > RANodeOutput
Definition: RelAlgDag.h:3432
const RexScalar * getElse() const
Definition: RelAlgDag.h:445
RexOperator(const SQLOps op, std::vector< std::unique_ptr< const RexScalar >> &operands, const SQLTypeInfo &type)
Definition: RelAlgDag.h:341
RelSort(const std::vector< SortField > &collation, std::optional< size_t > limit, const size_t offset, std::shared_ptr< const RelAlgNode > input)
Definition: RelAlgDag.h:2186
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1500
void setPushedDownWindowExpr()
Definition: RelAlgDag.h:1350
size_t getIndex() const
Definition: RelAlgDag.h:741
static thread_local unsigned crt_id_
Definition: RelAlgDag.h:953
NullSortedPosition nulls_pos_
Definition: RelAlgDag.h:571
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:427
void setCondition(std::unique_ptr< const RexScalar > &condition)
Definition: RelAlgDag.h:1902
friend std::size_t hash_value(RexAbstractInput const &)
Definition: RelAlgDag.cpp:3525
void setTargetColumns(ColumnNameList const &target_columns) const
Definition: RelAlgDag.h:1225
std::string function_name_
Definition: RelAlgDag.h:2639
const std::string getFieldName(const size_t i) const
Definition: RelAlgDag.h:2106
std::unique_ptr< RexRef > deepCopy() const
Definition: RelAlgDag.h:755
const RexScalar * outer_join_cond_
Definition: RelAlgDag.h:1855
const Catalog_Namespace::Catalog & getCatalog() const
Definition: RelAlgDag.h:1119
RelProject(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
Definition: RelAlgDag.h:1261
RexScalar const * copyAndRedirectSource(RexScalar const *, size_t input_idx) const
Definition: RelAlgDag.cpp:944
std::unique_ptr< const RexScalar > ConstRexScalarPtr
Definition: RelAlgDag.h:476
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.cpp:686
const RexScalar * getOuterCondition(const size_t nesting_level) const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.h:1828
double bbox_intersect_keys_per_bin
Definition: QueryHint.h:353
void setQueryPlanDag(const std::string &extracted_query_plan_dag) const
Definition: RelAlgDag.h:854
unsigned getTargetScale() const
Definition: RelAlgDag.h:300
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:1108
bool hasDeliveredHint()
Definition: RelAlgDag.h:1597
void applyDeleteModificationsToInputNode()
Definition: RelAlgDag.h:2479
bool operator==(const SortField &that) const
Definition: RelAlgDag.h:542
std::vector< std::string > TargetColumnList
Definition: RelAlgDag.h:2291
size_t size() const override
Definition: RelAlgDag.h:2094
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:378
size_t size() const
Definition: RelAlgDag.h:364
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1436
const RexScalar * getOperand(const size_t idx) const
Definition: RelAlgDag.h:366
size_t size() const override
Definition: RelAlgDag.h:1695
std::vector< const Rex * > col_inputs_
Definition: RelAlgDag.h:2642
const JoinType join_type_
Definition: RelAlgDag.h:1857
bool hasEquivCollationOf(const RelSort &that) const
Definition: RelAlgDag.cpp:803
const std::vector< SortField > & getCollation() const
Definition: RelAlgDag.h:670
SQLTypes target_type_
Definition: RelAlgDag.h:324
virtual bool visit(RexAgg const *n, std::string s)
Definition: RelAlgDag.h:106
SQLOps
Definition: sqldefs.h:28
void resetQueryExecutionState()
Definition: RelAlgDag.cpp:3448
SortDirection getSortDir() const
Definition: RelAlgDag.h:549
size_t getNumRows() const
Definition: RelAlgDag.h:2720
std::shared_ptr< RelFilter > original_filter_
Definition: RelAlgDag.h:2008
bool hasDeliveredHint()
Definition: RelAlgDag.h:2157
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:807
const bool hasHintEnabled(QueryHint candidate_hint) const
Definition: RelAlgDag.h:1583
void setRelNodeDagId(const size_t id) const
Definition: RelAlgDag.h:919
const std::vector< const Analyzer::ColumnVar * > lhs_join_cols_
Definition: RelAlgDag.h:1852
virtual bool visit(RelTranslatedJoin const *n, std::string s)
Definition: RelAlgDag.h:98
void applyUpdateModificationsToInputNode()
Definition: RelAlgDag.h:2411
virtual size_t toHash() const override
Definition: RelAlgDag.h:716
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:743
std::string getFieldName(const size_t idx) const
Definition: RelAlgDag.h:2586
const RexScalar * getCondition() const
Definition: RelAlgDag.h:1898
RexSubQuery & operator=(const RexSubQuery &)=delete
std::unique_ptr< const RexScalar > else_expr_
Definition: RelAlgDag.h:469
friend std::size_t hash_value(RelScan const &)
Definition: RelAlgDag.cpp:3668
virtual size_t toHash() const override
Definition: RelAlgDag.h:317
std::vector< std::shared_ptr< RelAlgNode > > nodes_
Definition: RelAlgDag.h:3352
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:1045
const std::vector< TargetMetaInfo > getTupleType() const
Definition: RelAlgDag.h:2687
friend std::size_t hash_value(RexFunctionOperator const &)
Definition: RelAlgDag.cpp:3579
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:2591
void addManagedInput(std::shared_ptr< const RelAlgNode > input)
Definition: RelAlgDag.h:895
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:635
unsigned getScale() const
Definition: RelAlgDag.h:296
bool hint_applied_
Definition: RelAlgDag.h:1733
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:2384
SortDirection
Definition: RelAlgDag.h:531
virtual bool visit(RelModify const *n, std::string s)
Definition: RelAlgDag.h:93
size_t getField() const
Definition: RelAlgDag.h:547
void invalidateTargetColumns() const
Definition: RelAlgDag.h:1230
void registerQueryHint(const RelAlgNode *node, const RegisteredQueryHint &query_hint)
Definition: RelAlgDag.h:3298
std::vector< std::string > fields_
Definition: RelAlgDag.h:1460
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
Definition: RelAlgDag.h:1527
RexInput(const RelAlgNode *node, const unsigned in_index)
Definition: RelAlgDag.h:1042
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1701
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1400
unsigned target_scale_
Definition: RelAlgDag.h:327
void setDeleteViaSelectFlag(bool required) const
Definition: RelAlgDag.h:1199
const RexScalar * getWhen(const size_t idx) const
Definition: RelAlgDag.h:435
virtual bool visit(RexFunctionOperator const *n, std::string s)
Definition: RelAlgDag.h:101
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:2525
const RegisteredQueryHint & getGlobalHints() const
Definition: RelAlgDag.h:3338
void setFields(std::vector< std::string > &&fields)
Definition: RelAlgDag.h:2108
auto const isProjectForUpdate() const
Definition: RelAlgDag.h:1220
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
Definition: RelAlgDag.h:2098
std::optional< bool > dynamic_watchdog
Definition: QueryHint.h:334
std::vector< const Analyzer::ColumnVar * > getJoinCols(bool lhs) const
Definition: RelAlgDag.h:1837
bool hasDeliveredHint()
Definition: RelAlgDag.h:1434
void appendInput(std::string new_field_name, std::unique_ptr< const RexScalar > new_input)
Definition: RelAlgDag.cpp:365
double cuda_grid_size_multiplier
Definition: QueryHint.h:341
const RexScalar * getCondition() const
Definition: RelAlgDag.h:1652
std::string getOpType() const
Definition: RelAlgDag.h:1814
size_t cuda_block_size
Definition: QueryHint.h:340
bool has_pushed_down_window_expr_
Definition: RelAlgDag.h:1463
std::string query_plan_dag_
Definition: RelAlgDag.h:955
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:2380
#define HEAVYAI_SPECIALIZE_HASH_VALUE_OF_POINTER(T)
Definition: RelAlgDag.h:3442
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:81
virtual size_t toHash() const override
Definition: RelAlgDag.h:1845
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1576
const RelAlgNode * rhs_
Definition: RelAlgDag.h:1851
virtual ~Rex()
Definition: RelAlgDag.h:144
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:279
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
Definition: RelAlgDag.h:1258
void forceRowwiseOutput() const
Definition: RelAlgDag.h:1203
friend std::size_t hash_value(RexWindowFunctionOperator const &)
Definition: RelAlgDag.cpp:3599
RelFilter(std::unique_ptr< const RexScalar > &filter)
Definition: RelAlgDag.h:1876
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
const TableDescriptor * td_
Definition: RelAlgDag.h:1174
size_t operator()(const RexInput &rex_in) const
Definition: RelAlgDag.h:1088
std::optional< size_t > getIdInPlanTree() const
Definition: RelAlgDag.h:134
RexLiteral(const std::string &val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned target_scale, const unsigned target_precision)
Definition: RelAlgDag.h:235
virtual size_t getOuterConditionsSize() const
const std::string op_type_
Definition: RelAlgDag.h:1858
const RexScalar * getOperandAndRelease(const size_t idx) const
Definition: RelAlgDag.h:371
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
Definition: RelAlgDag.h:2172
std::vector< std::shared_ptr< const RelJoin > > original_joins_
Definition: RelAlgDag.h:2009
virtual size_t toHash() const override
Definition: RelAlgDag.h:1023
bool g_enable_data_recycler
Definition: Execute.cpp:154
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:995
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:4851
friend std::size_t hash_value(SortField const &)
Definition: RelAlgDag.cpp:3591
virtual bool visit(RelTableFunction const *n, std::string s)
Definition: RelAlgDag.h:97
virtual bool visit(RelAggregate const *n, std::string s)
Definition: RelAlgDag.h:86
virtual std::shared_ptr< RelAlgNode > deepCopy() const =0
std::shared_ptr< const RexScalar > bound_expr
Definition: RelAlgDag.h:581
static std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3379
const RaExecutionDesc * context_data_
Definition: RelAlgDag.h:950
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
Definition: RelAlgDag.h:890
std::vector< std::string > field_names_
Definition: RelAlgDag.h:1175
friend std::size_t hash_value(RelFilter const &)
Definition: RelAlgDag.cpp:3730
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
Definition: RelAlgDag.h:359
size_t max_join_hash_table_size
Definition: QueryHint.h:358
bool hint_applied_
Definition: RelAlgDag.h:2175
bool flattened_
Definition: RelAlgDag.h:2495
bool hasPushedDownWindowExpr() const
Definition: RelAlgDag.h:1348
std::string to_string(char const *&&v)
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > & getQueryHints()
Definition: RelAlgDag.h:3334
std::vector< std::shared_ptr< RelAlgNode > > & getNodes()
Definition: RelAlgDag.h:2824
void clearContextData() const
Definition: RelAlgDag.h:940
TableDescriptor const *const getTableDescriptor() const
Definition: RelAlgDag.h:2370
virtual bool visitAny(RelAlgDagNode const *n, std::string s)
Definition: RelAlgDag.h:113
std::shared_ptr< const RelAlgNode > getRootNodeShPtr() const
Definition: RelAlgDag.h:2819
bool opt_cuda_grid_and_block_size
Definition: QueryHint.h:342
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:1282
RexWindowFunctionOperator(const SqlWindowFunctionKind kind, ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > collation, const RexWindowBound &frame_start_bound, const RexWindowBound &frame_end_bound, const bool is_rows, const SQLTypeInfo &ti)
Definition: RelAlgDag.h:605
boost::variant< boost::blank, int64_t, double, std::string, bool > literal_
Definition: RelAlgDag.h:322
const std::string getFieldName(const size_t i) const
Definition: RelAlgDag.h:1127
size_t getQueryPlanDagHash() const
Definition: RelAlgDag.h:863
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:1634
const std::string qualifier_
Definition: RelAlgDag.h:1859
Definition: RelAlgDag.h:142
std::vector< SortField > collation_
Definition: RelAlgDag.h:2278
const RelAlgNode & getRootNode() const
Definition: RelAlgDag.h:2812
RelLogicalValues()=default
virtual size_t getStepNumber() const
Definition: RelAlgDag.h:131
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1664
size_t getRowsSize() const
Definition: RelAlgDag.h:2712
size_t getColInputsSize() const
Definition: RelAlgDag.h:2562
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:2748
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:2150
void setUpdateViaSelectFlag(bool required) const
Definition: RelAlgDag.h:1198
This file contains the class specification and related data structures for Catalog.
RelScan(const TableDescriptor *td, const Catalog_Namespace::Catalog &catalog)
Definition: RelAlgDag.h:1096
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:2110
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
Definition: RelAlgDag.h:1300
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1975
std::optional< size_t > id_in_plan_tree_
Definition: RelAlgDag.h:139
unsigned precision_
Definition: RelAlgDag.h:326
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:778
std::string to_string() const
Definition: sqltypes.h:526
const RelAlgNode * getRHS() const
Definition: RelAlgDag.h:1808
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:33
bool g_enable_columnar_output
Definition: Execute.cpp:102
virtual bool visit(RelCompound const *n, std::string s)
Definition: RelAlgDag.h:87
virtual bool visit(RexCase const *n, std::string s)
Definition: RelAlgDag.h:100
unsigned getIndex() const
Definition: RelAlgDag.h:174
size_t field_
Definition: RelAlgDag.h:569
bool isNop() const
Definition: RelAlgDag.h:923
void markAsNop()
Definition: RelAlgDag.h:925
auto const isRowwiseOutputForced() const
Definition: RelAlgDag.h:1223
unsigned scale_
Definition: RelAlgDag.h:325
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:750
virtual ~RelAlgNode()
Definition: RelAlgDag.h:838
SQLOps getOperator() const
Definition: RelAlgDag.h:376
void setExecutionResult(const ExecutionResultShPtr result)
Definition: RelAlgDag.cpp:51
virtual bool visit(RexLiteral const *n, std::string s)
Definition: RelAlgDag.h:103
std::shared_ptr< const RelAlgNode > RelAlgNodeInputPtr
Definition: RelAlgDag.h:2290
friend std::size_t hash_value(RelProject const &)
Definition: RelAlgDag.cpp:3679
const RexScalar * getCondition() const
Definition: RelAlgDag.h:1819
virtual size_t toHash() const override
Definition: RelAlgDag.h:2262
bool keep_table_function_result
Definition: QueryHint.h:332
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1697
const Catalog_Namespace::Catalog * catalog_
Definition: RelAlgDag.h:1249
virtual size_t toHash() const override
Definition: RelAlgDag.h:461
unsigned getId() const
Definition: RelAlgDag.h:869
bool hasDeliveredHint()
Definition: RelAlgDag.h:1165
friend std::size_t hash_value(RexAgg const &)
Definition: RelAlgDag.cpp:3637
RelLeftDeepInnerJoin()=default
static std::unique_ptr< RelAlgDag > buildDagForSubquery(RelAlgDag &root_dag, const rapidjson::Value &query_ast)
Definition: RelAlgDag.cpp:3355
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
Definition: RelAlgDag.h:2571
SqlWindowFunctionKind kind_
Definition: RelAlgDag.h:721
size_t query_time_limit
Definition: QueryHint.h:335
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td)
Definition: RelAlgDag.h:2321
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:744
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:1001
const bool hasHintEnabled(const QueryHint candidate_hint) const
Definition: RelAlgDag.h:1151
ColumnNameList const & getTargetColumns() const
Definition: RelAlgDag.h:1228
size_t dag_node_id_
Definition: RelAlgDag.h:954
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
Definition: RelAlgDag.h:3353
std::unique_ptr< const RexOperator > disambiguatedOperands(ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > &collation) const
Definition: RelAlgDag.h:678
size_t index_
Definition: RelAlgDag.h:762
#define CHECK_NE(x, y)
Definition: Logger.h:302
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)
Definition: RelAlgDag.h:413
NullSortedPosition getNullsPosition() const
Definition: RelAlgDag.h:551
bool isRenaming() const
Definition: RelAlgDag.cpp:513
SQLTypeInfo type_
Definition: RelAlgDag.h:401
void setIndex(const unsigned in_index) const
Definition: RelAlgDag.h:176
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1158
T getVal() const
Definition: RelAlgDag.h:286
std::vector< size_t > operands_
Definition: RelAlgDag.h:821
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1599
std::vector< std::string > fields_
Definition: RelAlgDag.h:2169
virtual void acceptChildren(Visitor &v) const =0
RelScan(const TableDescriptor *td, const std::vector< std::string > &field_names, const Catalog_Namespace::Catalog &catalog)
Definition: RelAlgDag.h:1099
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:2357
const RexScalar * getAndReleaseCondition() const
Definition: RelAlgDag.h:1823
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1610
double bbox_intersect_bucket_threshold
Definition: QueryHint.h:348
RexLiteral(const int64_t val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned target_scale, const unsigned target_precision)
Definition: RelAlgDag.h:199
const TableDescriptor * table_descriptor_
Definition: RelAlgDag.h:2494
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1734
std::vector< std::shared_ptr< const RelAlgNode >> RelAlgInputs
Definition: RelAlgDag.h:71
std::optional< RegisteredQueryHint > getQueryHint(const RelAlgNode *node) const
Definition: RelAlgDag.h:3310
std::vector< std::unique_ptr< const RexScalar > > scalar_exprs_
Definition: RelAlgDag.h:1459
void registerHint(const QueryHint hint)
Definition: QueryHint.h:378
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:346
const RelAlgNode * lhs_
Definition: RelAlgDag.h:1850
virtual bool visit(RexSubQuery const *n, std::string s)
Definition: RelAlgDag.h:107
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t size() const override
Definition: RelAlgDag.h:2379
std::shared_ptr< SQLTypeInfo > type_
Definition: RelAlgDag.h:1028
size_t size() const override
Definition: RelAlgDag.h:1506
const RexScalar * getAndReleaseCondition()
Definition: RelAlgDag.h:1900
std::string getFieldName(const size_t i) const
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1413
size_t branchCount() const
Definition: RelAlgDag.h:433
virtual bool visit(RelProject const *n, std::string s)
Definition: RelAlgDag.h:94
RexSubQuery(const std::shared_ptr< const RelAlgNode > ra)
Definition: RelAlgDag.h:971
const RelAlgNode * getInput(const size_t idx) const
Definition: RelAlgDag.h:877
RexAbstractInput(const unsigned in_index)
Definition: RelAlgDag.h:165
RelFilter(std::unique_ptr< const RexScalar > &filter, std::shared_ptr< const RelAlgNode > input)
Definition: RelAlgDag.h:1868
const std::vector< std::shared_ptr< const Analyzer::Expr > > filter_ops_
Definition: RelAlgDag.h:1854
std::vector< std::shared_ptr< const RelJoin > > getOriginalJoins() const
bool g_enable_watchdog
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:353
size_t step_
Definition: RelAlgDag.h:138
Catalog_Namespace::Catalog const & catalog_
Definition: RelAlgDag.h:2493
size_t watchdog_max_projected_rows_per_device
Definition: QueryHint.h:336
virtual size_t toHash() const override
Definition: RelAlgDag.h:521
std::string getQueryPlanDag() const
Definition: RelAlgDag.h:861
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)
Definition: RelAlgDag.h:1474
std::unique_ptr< const RexScalar > filter_
Definition: RelAlgDag.h:1945
void setCondition(std::unique_ptr< const RexScalar > &condition)
Definition: RelAlgDag.h:1656
bool isSimple() const
Definition: RelAlgDag.h:1307
std::vector< std::unique_ptr< const RexScalar > > operands_
Definition: RelAlgDag.h:400
std::optional< size_t > hash_
Definition: RelAlgDag.h:151
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1050
void setContextData(const RaExecutionDesc *context_data) const
Definition: RelAlgDag.h:845
std::vector< std::string > fields_
Definition: RelAlgDag.h:2640
virtual size_t toHash() const override
Definition: RelAlgDag.h:1169
friend std::size_t hash_value(RexInput const &)
Definition: RelAlgDag.cpp:3658
size_t query_plan_dag_hash_
Definition: RelAlgDag.h:956
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:2761
std::vector< const Rex * > target_exprs_
Definition: RelAlgDag.h:2174
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1715
std::optional< size_t > hash_
Definition: RelAlgDag.h:947
const RexScalar * getProjectAtAndRelease(const size_t idx) const
Definition: RelAlgDag.h:1357
const RexWindowBound & getFrameEndBound() const
Definition: RelAlgDag.h:674
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
Definition: RelAlgDag.h:1444
unsigned getId() const
Definition: RelAlgDag.cpp:64
std::shared_ptr< ExecutionResultShPtr > result_
Definition: RelAlgDag.h:1029
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:2726
const RelAlgNode * node_
Definition: RelAlgDag.h:1079
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1177
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1782
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:2201
std::string getFieldName(const size_t col_idx) const
Definition: RelAlgDag.h:2700
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2560
std::unique_ptr< RexLiteral > deepCopy() const
Definition: RelAlgDag.h:313
virtual void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input)
Definition: RelAlgDag.h:908
std::string toString() const
Definition: RelAlgDag.h:553
static std::string yieldModifyOperationString(ModifyOperation const op)
Definition: RelAlgDag.h:2293
ModifyOperation getOperation() const
Definition: RelAlgDag.h:2375
std::unique_ptr< RexInput > deepCopy() const
Definition: RelAlgDag.h:1070
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:623
bool distinct_
Definition: RelAlgDag.h:819
std::vector< TargetMetaInfo > getCompatibleMetainfoTypes() const
Definition: RelAlgDag.cpp:911
void setModifiedTableDescriptor(TableDescriptor const *td) const
Definition: RelAlgDag.h:1207
void setFields(std::vector< std::string > &&fields)
Definition: RelAlgDag.h:2592
size_t size() const override
Definition: RelAlgDag.h:2553
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
virtual std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const =0
static std::unique_ptr< RelAlgDag > buildDag(const std::string &query_ra, const bool optimize_dag)
Definition: RelAlgDag.cpp:3335
std::string tree_string(const RelAlgNode *ra, const size_t depth)
Definition: RelAlgDag.cpp:3457
static ModifyOperation yieldModifyOperationEnum(std::string const &op_string)
Definition: RelAlgDag.h:2307
virtual void acceptChildren(Visitor &v) const override
Definition: RelAlgDag.h:990
void setScalarSources(std::vector< std::unique_ptr< const RexScalar >> &new_sources)
Definition: RelAlgDag.h:2116
std::vector< RowValues > values_
Definition: RelAlgDag.h:2736
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
Definition: RelAlgDag.h:1607
std::vector< TargetMetaInfo > targets_metainfo_
Definition: RelAlgDag.h:952
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1531
Hints * getDeliveredHints()
Definition: RelAlgDag.h:2159
SQLAgg agg_
Definition: RelAlgDag.h:818
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &&exprs)
Definition: RelAlgDag.cpp:730
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.cpp:537
std::optional< bool > watchdog
Definition: QueryHint.h:333
bool isEmptyResult() const
Definition: RelAlgDag.h:2222
const RelAlgNode * getRelAlg() const
Definition: RelAlgDag.h:1014
size_t size() const override
Definition: RelAlgDag.h:1817
size_t size() const override
Definition: RelAlgDag.h:2256
virtual size_t toHash() const override
Definition: RelAlgDag.h:2634
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:785
virtual size_t getStepNumber() const
Definition: RelAlgDag.h:146
size_t preflight_count_query_threshold
Definition: QueryHint.h:337
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1352
bool hint_applied_
Definition: RelAlgDag.h:1609
virtual bool visit(RelJoin const *n, std::string s)
Definition: RelAlgDag.h:89
size_t offset_
Definition: RelAlgDag.h:2280
const RaExecutionDesc * getContextData() const
Definition: RelAlgDag.h:873
virtual size_t toHash() const override
Definition: RelAlgDag.h:1726
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:1512
#define CHECK_LT(x, y)
Definition: Logger.h:303
Definition: sqltypes.h:79
bool hasInput(const RelAlgNode *needle) const
Definition: RelAlgDag.h:899
const std::vector< std::string > & getFieldNames() const
Definition: RelAlgDag.h:1125
friend std::size_t hash_value(RelAggregate const &)
Definition: RelAlgDag.cpp:3690
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:2104
const std::vector< const Analyzer::ColumnVar * > rhs_join_cols_
Definition: RelAlgDag.h:1853
static std::unique_ptr< RelAlgDag > build(const rapidjson::Value &query_ast, RelAlgDag *root_dag, const bool optimize_dag)
Definition: RelAlgDag.cpp:3361
void setCollation(std::vector< SortField > &&collation)
Definition: RelAlgDag.h:2218
friend std::size_t hash_value(RexRef const &)
Definition: RelAlgDag.cpp:3628
int32_t countRexLiteralArgs() const
Definition: RelAlgDag.cpp:698
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:2176
unsigned target_precision_
Definition: RelAlgDag.h:328
const ConstRexScalarPtrVector & getPartitionKeys() const
Definition: RelAlgDag.h:643
virtual std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const =0
bool allStringCastsAreToDictionaryEncodedStrings() const
Definition: RelAlgDag.cpp:955
const RelAlgNode * getLHS() const
Definition: RelAlgDag.h:1807
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1129
virtual void accept(Visitor &v, std::string name) const =0
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1294
const RexWindowBound & getFrameStartBound() const
Definition: RelAlgDag.h:672
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1462
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1144
const RexScalar * getOuterJoinCond() const
Definition: RelAlgDag.h:1813
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
Definition: RelAlgDag.cpp:544
std::vector< RexLiteral > RexLiteralArray
Definition: RelAlgDag.h:333
void resetModifyManipulationTarget() const
Definition: RelAlgDag.h:1339
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
Definition: RelAlgDag.h:2830
JoinType join_type_
Definition: RelAlgDag.h:1732
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
Definition: RelAlgDag.h:2168
virtual bool visit(RexOperator const *n, std::string s)
Definition: RelAlgDag.h:104
virtual void setStepNumber(size_t step) const
Definition: RelAlgDag.h:132
std::shared_ptr< const RelAlgNode > ra_
Definition: RelAlgDag.h:1030
static RelRexToStringConfig defaults()
Definition: RelAlgDag.h:78
SortField(const size_t field, const SortDirection sort_dir, const NullSortedPosition nulls_pos)
Definition: RelAlgDag.h:537
std::unique_ptr< const RexScalar > filter_expr_
Definition: RelAlgDag.h:2166
static std::vector< std::shared_ptr< RelAlgNode > > & getNodes(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3375
void setSourceNode(const RelAlgNode *node) const
Definition: RelAlgDag.h:1061
void resetQueryExecutionState()
Definition: RelAlgDag.h:840
virtual bool visit(RelFilter const *n, std::string s)
Definition: RelAlgDag.h:88
bool hasWindowFunctionExpr() const
Definition: RelAlgDag.cpp:2857
RelFilter()=default
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
Definition: RelAlgDag.h:477
virtual bool visit(RelLogicalUnion const *n, std::string s)
Definition: RelAlgDag.h:91
ConstRexScalarPtrVector order_keys_
Definition: RelAlgDag.h:723
SqlWindowFunctionKind getKind() const
Definition: RelAlgDag.h:641
const size_t getGroupByCount() const
Definition: RelAlgDag.h:2121
bool hint_applied_
Definition: RelAlgDag.h:1461
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:390
size_t collationCount() const
Definition: RelAlgDag.h:2211
bool is_agg_
Definition: RelAlgDag.h:2170
virtual bool visit(RelLeftDeepInnerJoin const *n, std::string s)
Definition: RelAlgDag.h:90
QueryHint
Definition: QueryHint.h:29
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, ModifyOperation op, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
Definition: RelAlgDag.h:2342
virtual size_t size() const =0
const RelAlgNode * getSourceNode() const
Definition: RelAlgDag.h:1056
std::vector< SortField > collation_
Definition: RelAlgDag.h:724
auto const isDeleteViaSelect() const
Definition: RelAlgDag.h:1218
bool operator==(const RelSort &that) const
Definition: RelAlgDag.h:2207
RexWindowBound frame_end_bound_
Definition: RelAlgDag.h:726
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.cpp:856
bool isAggregate() const
Definition: RelAlgDag.h:2123
const RelFilter * getOriginalFilter() const
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1936
SQLTypeInfo type_
Definition: RelAlgDag.h:820
JoinType getJoinType() const
Definition: RelAlgDag.h:1818
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type, std::vector< RowValues > &values)
Definition: RelAlgDag.h:2661
std::string get_type_name() const
Definition: sqltypes.h:482
std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const override
Definition: RelAlgDag.h:487
virtual size_t toHash() const override
Definition: RelAlgDag.h:1074
bool hint_applied_
Definition: RelAlgDag.h:1176
size_t bbox_intersect_max_size
Definition: QueryHint.h:350
const std::vector< RelAlgNode const * > getInputs() const
Definition: RelAlgDag.h:882
void replaceOrderKey(size_t offset, std::unique_ptr< const RexScalar > &&new_order_key)
Definition: RelAlgDag.h:661
friend std::size_t hash_value(RelCompound const &)
Definition: RelAlgDag.cpp:3752
bool hasDeliveredHint()
Definition: RelAlgDag.h:1722
const size_t getNumShards() const
Definition: RelAlgDag.h:1123
std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar > > > expr_pair_list_
Definition: RelAlgDag.h:468
std::string typeName(const T *v)
Definition: toString.h:106
SqlWindowFunctionKind
Definition: sqldefs.h:122
RexFunctionOperator(const std::string &name, ConstRexScalarPtrVector &operands, const SQLTypeInfo &ti)
Definition: RelAlgDag.h:482
const std::string getFieldName(const size_t idx) const
Definition: RelAlgDag.h:1369
virtual size_t toHash() const override
Definition: RelAlgDag.h:1940
std::unique_ptr< const RexScalar > condition_
Definition: RelAlgDag.h:2006
void replaceOperands(std::vector< std::unique_ptr< const RexScalar >> &&new_operands)
Definition: RelAlgDag.h:666
const Catalog_Namespace::Catalog & getCatalog() const
Definition: RelAlgDag.h:2372
SortDirection sort_dir_
Definition: RelAlgDag.h:570
RexCase()=default
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2566
virtual void accept(Visitor &v, std::string name) const override
Definition: RelAlgDag.h:1109
std::vector< RexLiteralArray > TupleContentsArray
Definition: RelAlgDag.h:334
void eachNode(std::function< void(RelAlgNode const *)> const &) const
Definition: RelAlgDag.cpp:3440
bool force_baseline_hash_join
Definition: QueryHint.h:359
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:380
unsigned getPrecision() const
Definition: RelAlgDag.h:298
const JoinType getJoinType(const size_t nesting_level) const
friend std::size_t hash_value(RelLogicalValues const &)
Definition: RelAlgDag.cpp:3809
std::size_t hash_value(RexAbstractInput const &rex_ab_input)
Definition: Rel