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