OmniSciDB  c1a53651b2
 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
973  : td_{td}, hint_applied_{false}, catalog_(catalog) {}
974 
976  const std::vector<std::string>& field_names,
977  const Catalog_Namespace::Catalog& catalog)
978  : td_(td)
979  , field_names_(field_names)
981  , hints_(std::make_unique<Hints>())
982  , catalog_(catalog) {}
983 
984  size_t size() const override { return field_names_.size(); }
985 
986  const TableDescriptor* getTableDescriptor() const { return td_; }
987 
988  const Catalog_Namespace::Catalog& getCatalog() const { return catalog_; }
989 
990  const size_t getNumFragments() const { return td_->fragmenter->getNumFragments(); }
991 
992  const size_t getNumShards() const { return td_->nShards; }
993 
994  const std::vector<std::string>& getFieldNames() const { return field_names_; }
995 
996  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
997 
998  std::string toString(
999  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1000  return cat(
1001  ::typeName(this), "(", td_->tableName, ", ", ::toString(field_names_), ")");
1002  }
1003 
1004  size_t toHash() const override {
1005  if (!hash_) {
1006  hash_ = typeid(RelScan).hash_code();
1007  boost::hash_combine(*hash_, td_->tableId);
1008  boost::hash_combine(*hash_, td_->tableName);
1009  boost::hash_combine(*hash_, ::toString(field_names_));
1010  }
1011  return *hash_;
1012  }
1013 
1014  std::shared_ptr<RelAlgNode> deepCopy() const override {
1015  CHECK(false);
1016  return nullptr;
1017  };
1018 
1019  void addHint(const ExplainedQueryHint& hint_explained) {
1020  if (!hint_applied_) {
1021  hint_applied_ = true;
1022  }
1023  hints_->emplace(hint_explained.getHint(), hint_explained);
1024  }
1025 
1026  const bool hasHintEnabled(const QueryHint candidate_hint) const {
1027  if (hint_applied_ && !hints_->empty()) {
1028  return hints_->find(candidate_hint) != hints_->end();
1029  }
1030  return false;
1031  }
1032 
1035  CHECK(!hints_->empty());
1036  CHECK(hasHintEnabled(hint));
1037  return hints_->at(hint);
1038  }
1039 
1040  bool hasDeliveredHint() { return !hints_->empty(); }
1041 
1042  Hints* getDeliveredHints() { return hints_.get(); }
1043 
1044  private:
1046  std::vector<std::string> field_names_;
1048  std::unique_ptr<Hints> hints_;
1050 
1051  friend struct RelAlgDagSerializer;
1052 };
1053 
1055  public:
1056  ModifyManipulationTarget(bool const update_via_select = false,
1057  bool const delete_via_select = false,
1058  bool const varlen_update_required = false,
1059  TableDescriptor const* table_descriptor = nullptr,
1060  ColumnNameList target_columns = ColumnNameList(),
1061  const Catalog_Namespace::Catalog* catalog = nullptr)
1062  : is_update_via_select_(update_via_select)
1063  , is_delete_via_select_(delete_via_select)
1064  , varlen_update_required_(varlen_update_required)
1065  , table_descriptor_(table_descriptor)
1066  , target_columns_(target_columns)
1067  , catalog_(catalog) {}
1068 
1073  }
1075 
1079  table_descriptor_ = td;
1080  }
1081 
1083 
1085  catalog_ = catalog;
1086  }
1087 
1088  auto const isUpdateViaSelect() const { return is_update_via_select_; }
1089  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
1090  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
1091  auto const isProjectForUpdate() const {
1093  }
1094  auto const isRowwiseOutputForced() const { return force_rowwise_output_; }
1095 
1096  void setTargetColumns(ColumnNameList const& target_columns) const {
1097  target_columns_ = target_columns;
1098  }
1100 
1101  void invalidateTargetColumns() const { target_columns_.clear(); }
1102 
1103  template <typename VALIDATION_FUNCTOR>
1104  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
1105  for (auto const& column_name : target_columns_) {
1106  if (validator(column_name) == false) {
1107  return false;
1108  }
1109  }
1110  return true;
1111  }
1112 
1113  private:
1114  mutable bool is_update_via_select_ = false;
1115  mutable bool is_delete_via_select_ = false;
1116  mutable bool varlen_update_required_ = false;
1117  mutable TableDescriptor const* table_descriptor_ = nullptr;
1119  mutable bool force_rowwise_output_ = false;
1120  mutable const Catalog_Namespace::Catalog* catalog_{nullptr};
1121 
1122  friend struct RelAlgDagSerializer;
1123 };
1124 
1126  public:
1127  friend class RelModify;
1128  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
1129  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
1130 
1131  // constructor used for deserialization only
1134  , hint_applied_{false}
1136 
1137  // Takes memory ownership of the expressions.
1138  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
1139  const std::vector<std::string>& fields,
1140  std::shared_ptr<const RelAlgNode> input)
1142  , scalar_exprs_(std::move(scalar_exprs))
1143  , fields_(fields)
1144  , hint_applied_(false)
1145  , hints_(std::make_unique<Hints>())
1147  inputs_.push_back(input);
1148  }
1149 
1150  RelProject(RelProject const&);
1151 
1152  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
1153  scalar_exprs_ = std::move(exprs);
1154  }
1155 
1156  // True iff all the projected expressions are inputs. If true,
1157  // this node can be elided and merged into the previous node
1158  // since it's just a subset and / or permutation of its outputs.
1159  bool isSimple() const {
1160  for (const auto& expr : scalar_exprs_) {
1161  if (!dynamic_cast<const RexInput*>(expr.get())) {
1162  return false;
1163  }
1164  }
1165  return true;
1166  }
1167 
1168  bool isIdentity() const;
1169 
1170  bool isRenaming() const;
1171 
1172  size_t size() const override { return scalar_exprs_.size(); }
1173 
1175  std::shared_ptr<RelProject> new_project_node) const {
1176  if (isUpdateViaSelect()) {
1177  new_project_node->setUpdateViaSelectFlag(true);
1178  }
1179  if (isDeleteViaSelect()) {
1180  new_project_node->setDeleteViaSelectFlag(true);
1181  }
1182  if (isVarlenUpdateRequired()) {
1183  new_project_node->setVarlenUpdateRequired(true);
1184  }
1185  new_project_node->setModifiedTableDescriptor(getModifiedTableDescriptor());
1186  new_project_node->setTargetColumns(getTargetColumns());
1187  new_project_node->setModifiedTableCatalog(getModifiedTableCatalog());
1189  }
1190 
1192  setModifiedTableDescriptor(nullptr);
1193  setModifiedTableCatalog(nullptr);
1194  setUpdateViaSelectFlag(false);
1195  setDeleteViaSelectFlag(false);
1196  setVarlenUpdateRequired(false);
1198  }
1199 
1201 
1203 
1204  const RexScalar* getProjectAt(const size_t idx) const {
1205  CHECK(idx < scalar_exprs_.size());
1206  return scalar_exprs_[idx].get();
1207  }
1208 
1209  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
1210  CHECK(idx < scalar_exprs_.size());
1211  return scalar_exprs_[idx].release();
1212  }
1213 
1214  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
1215  return std::move(scalar_exprs_);
1216  }
1217 
1218  const std::vector<std::string>& getFields() const { return fields_; }
1219  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
1220 
1221  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1222 
1223  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1224  std::shared_ptr<const RelAlgNode> input) override {
1225  replaceInput(old_input, input, std::nullopt);
1226  }
1227 
1228  void replaceInput(
1229  std::shared_ptr<const RelAlgNode> old_input,
1230  std::shared_ptr<const RelAlgNode> input,
1231  std::optional<std::unordered_map<unsigned, unsigned>> old_to_new_index_map);
1232 
1233  void appendInput(std::string new_field_name,
1234  std::unique_ptr<const RexScalar> new_input);
1235 
1236  std::string toString(
1237  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1238  auto ret = cat(::typeName(this), "(");
1239  for (auto& expr : scalar_exprs_) {
1240  ret += expr->toString(config) + " ";
1241  }
1242  return cat(ret, ", ", ::toString(fields_), ")");
1243  }
1244 
1245  size_t toHash() const override {
1246  if (!hash_) {
1247  hash_ = typeid(RelProject).hash_code();
1248  for (auto& target_expr : scalar_exprs_) {
1249  boost::hash_combine(*hash_, target_expr->toHash());
1250  }
1251  boost::hash_combine(*hash_, ::toString(fields_));
1252  }
1253  return *hash_;
1254  }
1255 
1256  std::shared_ptr<RelAlgNode> deepCopy() const override {
1257  auto copied_project_node = std::make_shared<RelProject>(*this);
1258  if (isProjectForUpdate()) {
1259  propagateModifyManipulationTarget(copied_project_node);
1260  }
1262  copied_project_node->setPushedDownWindowExpr();
1263  }
1264  return copied_project_node;
1265  }
1266 
1267  bool hasWindowFunctionExpr() const;
1268 
1269  void addHint(const ExplainedQueryHint& hint_explained) {
1270  if (!hint_applied_) {
1271  hint_applied_ = true;
1272  }
1273  hints_->emplace(hint_explained.getHint(), hint_explained);
1274  }
1275 
1276  const bool hasHintEnabled(QueryHint candidate_hint) const {
1277  if (hint_applied_ && !hints_->empty()) {
1278  return hints_->find(candidate_hint) != hints_->end();
1279  }
1280  return false;
1281  }
1282 
1285  CHECK(!hints_->empty());
1286  CHECK(hasHintEnabled(hint));
1287  return hints_->at(hint);
1288  }
1289 
1290  bool hasDeliveredHint() { return !hints_->empty(); }
1291 
1292  Hints* getDeliveredHints() { return hints_.get(); }
1293 
1294  private:
1295  template <typename EXPR_VISITOR_FUNCTOR>
1296  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
1297  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
1298  visitor_functor(i);
1299  }
1300  }
1301 
1304  scalar_exprs_.emplace_back(
1305  std::make_unique<RexFunctionOperator const>(std::string("OFFSET_IN_FRAGMENT"),
1306  transient_vector,
1307  SQLTypeInfo(kBIGINT, false)));
1308  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
1309  }
1310 
1311  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
1312  mutable std::vector<std::string> fields_;
1314  std::unique_ptr<Hints> hints_;
1316 
1317  friend struct RelAlgDagSerializer;
1318 };
1319 
1320 class RelAggregate : public RelAlgNode {
1321  public:
1322  // default constructor, for deserialization only
1324 
1325  // Takes ownership of the aggregate expressions.
1326  RelAggregate(const size_t groupby_count,
1327  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
1328  const std::vector<std::string>& fields,
1329  std::shared_ptr<const RelAlgNode> input)
1330  : groupby_count_(groupby_count)
1331  , agg_exprs_(std::move(agg_exprs))
1332  , fields_(fields)
1333  , hint_applied_(false)
1334  , hints_(std::make_unique<Hints>()) {
1335  inputs_.push_back(input);
1336  }
1337 
1338  RelAggregate(RelAggregate const&);
1339 
1340  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
1341 
1342  const size_t getGroupByCount() const { return groupby_count_; }
1343 
1344  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
1345 
1346  const std::vector<std::string>& getFields() const { return fields_; }
1347  void setFields(std::vector<std::string>&& new_fields) {
1348  fields_ = std::move(new_fields);
1349  }
1350 
1351  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1352 
1353  std::vector<const RexAgg*> getAggregatesAndRelease() {
1354  std::vector<const RexAgg*> result;
1355  for (auto& agg_expr : agg_exprs_) {
1356  result.push_back(agg_expr.release());
1357  }
1358  return result;
1359  }
1360 
1361  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
1362  return std::move(agg_exprs_);
1363  }
1364 
1365  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
1366  return agg_exprs_;
1367  }
1368 
1369  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
1370  agg_exprs_ = std::move(agg_exprs);
1371  }
1372 
1373  std::string toString(
1374  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1375  auto ret = cat(::typeName(this),
1376  "(",
1378  ", agg_exprs=",
1379  ::toString(agg_exprs_),
1380  ", fields=",
1381  ::toString(fields_));
1382  if (!config.skip_input_nodes) {
1383  ret += ::toString(inputs_);
1384  } else {
1385  ret += ", input node id={";
1386  for (auto& input : inputs_) {
1387  auto node_id_in_plan = input->getIdInPlanTree();
1388  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1389  : std::to_string(input->getId());
1390  ret += node_id_str + " ";
1391  }
1392  ret += "}";
1393  }
1394  return cat(ret, ")");
1395  }
1396 
1397  size_t toHash() const override {
1398  if (!hash_) {
1399  hash_ = typeid(RelAggregate).hash_code();
1400  boost::hash_combine(*hash_, groupby_count_);
1401  for (auto& agg_expr : agg_exprs_) {
1402  boost::hash_combine(*hash_, agg_expr->toHash());
1403  }
1404  for (auto& node : inputs_) {
1405  boost::hash_combine(*hash_, node->toHash());
1406  }
1407  boost::hash_combine(*hash_, ::toString(fields_));
1408  }
1409  return *hash_;
1410  }
1411 
1412  std::shared_ptr<RelAlgNode> deepCopy() const override {
1413  return std::make_shared<RelAggregate>(*this);
1414  }
1415 
1416  void addHint(const ExplainedQueryHint& hint_explained) {
1417  if (!hint_applied_) {
1418  hint_applied_ = true;
1419  }
1420  hints_->emplace(hint_explained.getHint(), hint_explained);
1421  }
1422 
1423  const bool hasHintEnabled(QueryHint candidate_hint) const {
1424  if (hint_applied_ && !hints_->empty()) {
1425  return hints_->find(candidate_hint) != hints_->end();
1426  }
1427  return false;
1428  }
1429 
1432  CHECK(!hints_->empty());
1433  CHECK(hasHintEnabled(hint));
1434  return hints_->at(hint);
1435  }
1436 
1437  bool hasDeliveredHint() { return !hints_->empty(); }
1438 
1439  Hints* getDeliveredHints() { return hints_.get(); }
1440 
1441  private:
1443  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1444  std::vector<std::string> fields_;
1446  std::unique_ptr<Hints> hints_;
1447 
1448  friend struct RelAlgDagSerializer;
1449 };
1450 
1451 class RelJoin : public RelAlgNode {
1452  public:
1453  // default constructor used for deserialization only
1455 
1456  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
1457  std::shared_ptr<const RelAlgNode> rhs,
1458  std::unique_ptr<const RexScalar>& condition,
1459  const JoinType join_type)
1460  : condition_(std::move(condition))
1461  , join_type_(join_type)
1462  , hint_applied_(false)
1463  , hints_(std::make_unique<Hints>()) {
1464  inputs_.push_back(lhs);
1465  inputs_.push_back(rhs);
1466  }
1467 
1468  RelJoin(RelJoin const&);
1469 
1470  JoinType getJoinType() const { return join_type_; }
1471 
1472  const RexScalar* getCondition() const { return condition_.get(); }
1473 
1474  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
1475 
1476  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1477  CHECK(condition);
1478  condition_ = std::move(condition);
1479  }
1480 
1481  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1482  std::shared_ptr<const RelAlgNode> input) override;
1483 
1484  std::string toString(
1485  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1486  auto ret = cat(::typeName(this), "(");
1487  if (!config.skip_input_nodes) {
1488  ret += ::toString(inputs_);
1489  } else {
1490  ret += ", input node id={";
1491  for (auto& input : inputs_) {
1492  auto node_id_in_plan = input->getIdInPlanTree();
1493  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1494  : std::to_string(input->getId());
1495  ret += node_id_str + " ";
1496  }
1497  ret += "}";
1498  }
1499  return cat(ret,
1500  ", condition=",
1501  (condition_ ? condition_->toString(config) : "null"),
1502  ", join_type=",
1503  ::toString(join_type_));
1504  }
1505 
1506  size_t toHash() const override {
1507  if (!hash_) {
1508  hash_ = typeid(RelJoin).hash_code();
1509  boost::hash_combine(*hash_, condition_ ? condition_->toHash() : HASH_N);
1510  for (auto& node : inputs_) {
1511  boost::hash_combine(*hash_, node->toHash());
1512  }
1513  boost::hash_combine(*hash_, ::toString(getJoinType()));
1514  }
1515  return *hash_;
1516  }
1517 
1518  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
1519 
1520  std::shared_ptr<RelAlgNode> deepCopy() const override {
1521  return std::make_shared<RelJoin>(*this);
1522  }
1523 
1524  void addHint(const ExplainedQueryHint& hint_explained) {
1525  if (!hint_applied_) {
1526  hint_applied_ = true;
1527  }
1528  hints_->emplace(hint_explained.getHint(), hint_explained);
1529  }
1530 
1531  const bool hasHintEnabled(QueryHint candidate_hint) const {
1532  if (hint_applied_ && !hints_->empty()) {
1533  return hints_->find(candidate_hint) != hints_->end();
1534  }
1535  return false;
1536  }
1537 
1540  CHECK(!hints_->empty());
1541  CHECK(hasHintEnabled(hint));
1542  return hints_->at(hint);
1543  }
1544 
1545  bool hasDeliveredHint() { return !hints_->empty(); }
1546 
1547  Hints* getDeliveredHints() { return hints_.get(); }
1548 
1549  private:
1550  mutable std::unique_ptr<const RexScalar> condition_;
1553  std::unique_ptr<Hints> hints_;
1554 
1555  friend struct RelAlgDagSerializer;
1556 };
1557 
1558 // a helper node that contains detailed information of each level of join qual
1559 // which is used when extracting query plan DAG
1561  public:
1563  const RelAlgNode* rhs,
1564  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols,
1565  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols,
1566  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops,
1567  const RexScalar* outer_join_cond,
1568  const bool nested_loop,
1569  const JoinType join_type,
1570  const std::string& op_type,
1571  const std::string& qualifier,
1572  const std::string& op_typeinfo)
1573  : lhs_(lhs)
1574  , rhs_(rhs)
1575  , lhs_join_cols_(lhs_join_cols)
1576  , rhs_join_cols_(rhs_join_cols)
1577  , filter_ops_(filter_ops)
1578  , outer_join_cond_(outer_join_cond)
1579  , nested_loop_(nested_loop)
1580  , join_type_(join_type)
1581  , op_type_(op_type)
1582  , qualifier_(qualifier)
1583  , op_typeinfo_(op_typeinfo) {}
1584 
1585  std::string toString(
1586  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1587  return cat(::typeName(this),
1588  "( join_quals { lhs: ",
1590  ", rhs: ",
1592  " }, filter_quals: { ",
1593  ::toString(filter_ops_),
1594  " }, outer_join_cond: { ",
1595  outer_join_cond_->toString(config),
1596  " }, loop_join: ",
1598  ", join_type: ",
1600  ", op_type: ",
1602  ", qualifier: ",
1604  ", op_type_info: ",
1606  ")");
1607  }
1608  size_t toHash() const override {
1609  if (!hash_) {
1610  hash_ = typeid(RelTranslatedJoin).hash_code();
1611  boost::hash_combine(*hash_, lhs_->toHash());
1612  boost::hash_combine(*hash_, rhs_->toHash());
1613  boost::hash_combine(*hash_, outer_join_cond_ ? outer_join_cond_->toHash() : HASH_N);
1614  boost::hash_combine(*hash_, nested_loop_);
1615  boost::hash_combine(*hash_, ::toString(join_type_));
1616  boost::hash_combine(*hash_, op_type_);
1617  boost::hash_combine(*hash_, qualifier_);
1618  boost::hash_combine(*hash_, op_typeinfo_);
1619  for (auto& filter_op : filter_ops_) {
1620  boost::hash_combine(*hash_, filter_op->toString());
1621  }
1622  }
1623  return *hash_;
1624  }
1625  const RelAlgNode* getLHS() const { return lhs_; }
1626  const RelAlgNode* getRHS() const { return rhs_; }
1627  size_t getFilterCondSize() const { return filter_ops_.size(); }
1628  const std::vector<std::shared_ptr<const Analyzer::Expr>> getFilterCond() const {
1629  return filter_ops_;
1630  }
1631  const RexScalar* getOuterJoinCond() const { return outer_join_cond_; }
1632  std::string getOpType() const { return op_type_; }
1633  std::string getQualifier() const { return qualifier_; }
1634  std::string getOpTypeInfo() const { return op_typeinfo_; }
1635  size_t size() const override { return 0; }
1636  JoinType getJoinType() const { return join_type_; }
1637  const RexScalar* getCondition() const {
1638  CHECK(false);
1639  return nullptr;
1640  }
1642  CHECK(false);
1643  return nullptr;
1644  }
1645  void setCondition(std::unique_ptr<const RexScalar>& condition) { CHECK(false); }
1646  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1647  std::shared_ptr<const RelAlgNode> input) override {
1648  CHECK(false);
1649  }
1650  std::shared_ptr<RelAlgNode> deepCopy() const override {
1651  CHECK(false);
1652  return nullptr;
1653  }
1654  std::string getFieldName(const size_t i) const;
1655  std::vector<const Analyzer::ColumnVar*> getJoinCols(bool lhs) const {
1656  if (lhs) {
1657  return lhs_join_cols_;
1658  }
1659  return rhs_join_cols_;
1660  }
1661  bool isNestedLoopQual() const { return nested_loop_; }
1662 
1663  private:
1666  const std::vector<const Analyzer::ColumnVar*> lhs_join_cols_;
1667  const std::vector<const Analyzer::ColumnVar*> rhs_join_cols_;
1668  const std::vector<std::shared_ptr<const Analyzer::Expr>> filter_ops_;
1670  const bool nested_loop_;
1672  const std::string op_type_;
1673  const std::string qualifier_;
1674  const std::string op_typeinfo_;
1675 };
1676 
1677 class RelFilter : public RelAlgNode {
1678  public:
1679  // default constructor, used for deserialization only
1680  RelFilter() = default;
1681 
1682  RelFilter(std::unique_ptr<const RexScalar>& filter,
1683  std::shared_ptr<const RelAlgNode> input)
1684  : filter_(std::move(filter)) {
1685  CHECK(filter_);
1686  inputs_.push_back(input);
1687  }
1688 
1689  // for dummy filter node for data recycler
1690  RelFilter(std::unique_ptr<const RexScalar>& filter) : filter_(std::move(filter)) {
1691  CHECK(filter_);
1692  }
1693 
1694  RelFilter(RelFilter const&);
1695 
1696  const RexScalar* getCondition() const { return filter_.get(); }
1697 
1698  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
1699 
1700  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1701  CHECK(condition);
1702  filter_ = std::move(condition);
1703  }
1704 
1705  size_t size() const override { return inputs_[0]->size(); }
1706 
1707  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1708  std::shared_ptr<const RelAlgNode> input) override;
1709 
1710  std::string toString(
1711  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1712  auto ret =
1713  cat(::typeName(this), "(", (filter_ ? filter_->toString(config) : "null"), ", ");
1714  if (!config.skip_input_nodes) {
1715  ret += ::toString(inputs_);
1716  } else {
1717  ret += ", input node id={";
1718  for (auto& input : inputs_) {
1719  auto node_id_in_plan = input->getIdInPlanTree();
1720  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1721  : std::to_string(input->getId());
1722  ret += node_id_str + " ";
1723  }
1724  ret += "}";
1725  }
1726  return cat(ret, ")");
1727  }
1728 
1729  size_t toHash() const override {
1730  if (!hash_) {
1731  hash_ = typeid(RelFilter).hash_code();
1732  boost::hash_combine(*hash_, filter_ ? filter_->toHash() : HASH_N);
1733  for (auto& node : inputs_) {
1734  boost::hash_combine(*hash_, node->toHash());
1735  }
1736  }
1737  return *hash_;
1738  }
1739 
1740  std::shared_ptr<RelAlgNode> deepCopy() const override {
1741  return std::make_shared<RelFilter>(*this);
1742  }
1743 
1744  private:
1745  std::unique_ptr<const RexScalar> filter_;
1746 
1747  friend struct RelAlgDagSerializer;
1748 };
1749 
1750 // Synthetic node to assist execution of left-deep join relational algebra.
1752  public:
1753  // default constructor used for deserialization only
1754  RelLeftDeepInnerJoin() = default;
1755 
1756  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1757  RelAlgInputs inputs,
1758  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1759 
1760  const RexScalar* getInnerCondition() const;
1761 
1762  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1763 
1764  const JoinType getJoinType(const size_t nesting_level) const;
1765 
1766  std::string toString(
1767  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
1768 
1769  size_t toHash() const override;
1770 
1771  size_t size() const override;
1772 
1773  std::shared_ptr<RelAlgNode> deepCopy() const override;
1774 
1775  bool coversOriginalNode(const RelAlgNode* node) const;
1776 
1777  const RelFilter* getOriginalFilter() const;
1778 
1779  std::vector<std::shared_ptr<const RelJoin>> getOriginalJoins() const;
1780 
1781  private:
1782  std::unique_ptr<const RexScalar> condition_;
1783  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
1784  std::shared_ptr<RelFilter> original_filter_;
1785  std::vector<std::shared_ptr<const RelJoin>> original_joins_;
1786 
1787  friend struct RelAlgDagSerializer;
1788 };
1789 
1790 // The 'RelCompound' node combines filter and on the fly aggregate computation.
1791 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
1792 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
1793 // which can be efficiently executed with no intermediate buffers.
1795  public:
1796  // constructor used for deserialization only
1800  , is_agg_{false}
1801  , hint_applied_{false} {}
1802 
1803  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
1804  // or aggregate expressions owned by 'agg_exprs_', with the arguments
1805  // owned by 'scalar_sources_'.
1806  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
1807  const std::vector<const Rex*>& target_exprs,
1808  const size_t groupby_count,
1809  const std::vector<const RexAgg*>& agg_exprs,
1810  const std::vector<std::string>& fields,
1811  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
1812  const bool is_agg,
1813  bool update_disguised_as_select = false,
1814  bool delete_disguised_as_select = false,
1815  bool varlen_update_required = false,
1816  TableDescriptor const* manipulation_target_table = nullptr,
1817  ColumnNameList target_columns = ColumnNameList(),
1818  const Catalog_Namespace::Catalog* catalog = nullptr)
1819  : ModifyManipulationTarget(update_disguised_as_select,
1820  delete_disguised_as_select,
1821  varlen_update_required,
1822  manipulation_target_table,
1823  target_columns,
1824  catalog)
1825  , filter_expr_(std::move(filter_expr))
1826  , groupby_count_(groupby_count)
1827  , fields_(fields)
1828  , is_agg_(is_agg)
1829  , scalar_sources_(std::move(scalar_sources))
1830  , target_exprs_(target_exprs)
1831  , hint_applied_(false)
1832  , hints_(std::make_unique<Hints>()) {
1833  CHECK_EQ(fields.size(), target_exprs.size());
1834  for (auto agg_expr : agg_exprs) {
1835  agg_exprs_.emplace_back(agg_expr);
1836  }
1837  }
1838 
1839  RelCompound(RelCompound const&);
1840 
1841  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1842  std::shared_ptr<const RelAlgNode> input) override;
1843 
1844  size_t size() const override { return target_exprs_.size(); }
1845 
1846  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
1847 
1848  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
1849  filter_expr_ = std::move(new_expr);
1850  }
1851 
1852  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
1853 
1854  const std::vector<std::string>& getFields() const { return fields_; }
1855 
1856  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1857 
1858  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
1859 
1860  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
1861 
1862  const RexScalar* getScalarSource(const size_t i) const {
1863  return scalar_sources_[i].get();
1864  }
1865 
1866  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
1867  CHECK_EQ(new_sources.size(), scalar_sources_.size());
1868  scalar_sources_ = std::move(new_sources);
1869  }
1870 
1871  const size_t getGroupByCount() const { return groupby_count_; }
1872 
1873  bool isAggregate() const { return is_agg_; }
1874 
1875  size_t getAggExprSize() const { return agg_exprs_.size(); }
1876 
1877  const RexAgg* getAggExpr(size_t i) const { return agg_exprs_[i].get(); }
1878 
1879  std::string toString(
1880  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
1881 
1882  size_t toHash() const override;
1883 
1884  std::shared_ptr<RelAlgNode> deepCopy() const override {
1885  return std::make_shared<RelCompound>(*this);
1886  }
1887 
1888  void addHint(const ExplainedQueryHint& hint_explained) {
1889  if (!hint_applied_) {
1890  hint_applied_ = true;
1891  }
1892  hints_->emplace(hint_explained.getHint(), hint_explained);
1893  }
1894 
1895  const bool hasHintEnabled(QueryHint candidate_hint) const {
1896  if (hint_applied_ && !hints_->empty()) {
1897  return hints_->find(candidate_hint) != hints_->end();
1898  }
1899  return false;
1900  }
1901 
1904  CHECK(!hints_->empty());
1905  CHECK(hasHintEnabled(hint));
1906  return hints_->at(hint);
1907  }
1908 
1909  bool hasDeliveredHint() { return !hints_->empty(); }
1910 
1911  Hints* getDeliveredHints() { return hints_.get(); }
1912 
1913  private:
1914  std::unique_ptr<const RexScalar> filter_expr_;
1916  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1917  std::vector<std::string> fields_;
1918  bool is_agg_;
1919  std::vector<std::unique_ptr<const RexScalar>>
1920  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not
1921  // actually projected, just owned
1922  std::vector<const Rex*> target_exprs_;
1924  std::unique_ptr<Hints> hints_;
1925 
1926  friend struct RelAlgDagSerializer;
1927 };
1928 
1929 class RelSort : public RelAlgNode {
1930  public:
1931  // default constructor used for deserialization only
1932  RelSort() : limit_{0}, offset_{0}, empty_result_{false}, limit_delivered_{false} {}
1933 
1934  RelSort(const std::vector<SortField>& collation,
1935  const size_t limit,
1936  const size_t offset,
1937  std::shared_ptr<const RelAlgNode> input,
1938  bool limit_delivered)
1939  : collation_(collation)
1940  , limit_(limit)
1941  , offset_(offset)
1942  , limit_delivered_(limit_delivered) {
1943  inputs_.push_back(input);
1944  }
1945 
1946  bool operator==(const RelSort& that) const {
1947  return limit_ == that.limit_ && offset_ == that.offset_ &&
1948  empty_result_ == that.empty_result_ &&
1950  }
1951 
1952  size_t collationCount() const { return collation_.size(); }
1953 
1954  SortField getCollation(const size_t i) const {
1955  CHECK_LT(i, collation_.size());
1956  return collation_[i];
1957  }
1958 
1959  void setCollation(std::vector<SortField>&& collation) {
1960  collation_ = std::move(collation);
1961  }
1962 
1963  void setEmptyResult(bool emptyResult) { empty_result_ = emptyResult; }
1964 
1965  bool isEmptyResult() const { return empty_result_; }
1966 
1967  bool isLimitDelivered() const { return limit_delivered_; }
1968 
1969  size_t getLimit() const { return limit_; }
1970 
1971  size_t getOffset() const { return offset_; }
1972 
1973  std::string toString(
1974  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
1975  const std::string limit_info = limit_delivered_ ? std::to_string(limit_) : "N/A";
1976  auto ret = cat(::typeName(this),
1977  "(",
1978  "empty_result: ",
1980  ", collation=",
1981  ::toString(collation_),
1982  ", limit=",
1983  limit_info,
1984  ", offset",
1985  std::to_string(offset_));
1986  if (!config.skip_input_nodes) {
1987  ret += ", inputs=", ::toString(inputs_);
1988  } else {
1989  ret += ", input node id={";
1990  for (auto& input : inputs_) {
1991  auto node_id_in_plan = input->getIdInPlanTree();
1992  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
1993  : std::to_string(input->getId());
1994  ret += node_id_str + " ";
1995  }
1996  ret += "}";
1997  }
1998  return cat(ret, ")");
1999  }
2000 
2001  size_t toHash() const override {
2002  if (!hash_) {
2003  hash_ = typeid(RelSort).hash_code();
2004  for (auto& collation : collation_) {
2005  boost::hash_combine(*hash_, collation.toHash());
2006  }
2007  boost::hash_combine(*hash_, empty_result_);
2008  boost::hash_combine(*hash_, limit_delivered_);
2009  if (limit_delivered_) {
2010  boost::hash_combine(*hash_, limit_);
2011  }
2012  boost::hash_combine(*hash_, offset_);
2013  for (auto& node : inputs_) {
2014  boost::hash_combine(*hash_, node->toHash());
2015  }
2016  }
2017  return *hash_;
2018  }
2019 
2020  size_t size() const override { return inputs_[0]->size(); }
2021 
2022  std::shared_ptr<RelAlgNode> deepCopy() const override {
2023  return std::make_shared<RelSort>(*this);
2024  }
2025 
2026  private:
2027  std::vector<SortField> collation_;
2028  size_t limit_;
2029  size_t offset_;
2032 
2033  bool hasEquivCollationOf(const RelSort& that) const;
2034 
2035  friend struct RelAlgDagSerializer;
2036 };
2037 
2038 class RelModify : public RelAlgNode {
2039  public:
2041  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
2042  using TargetColumnList = std::vector<std::string>;
2043 
2044  static std::string yieldModifyOperationString(ModifyOperation const op) {
2045  switch (op) {
2047  return "DELETE";
2049  return "INSERT";
2051  return "UPDATE";
2052  default:
2053  break;
2054  }
2055  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
2056  }
2057 
2058  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
2059  if (op_string == "INSERT") {
2060  return ModifyOperation::Insert;
2061  } else if (op_string == "DELETE") {
2062  return ModifyOperation::Delete;
2063  } else if (op_string == "UPDATE") {
2064  return ModifyOperation::Update;
2065  }
2066 
2067  throw std::runtime_error(
2068  std::string("Unsupported logical modify operation encountered " + op_string));
2069  }
2070 
2071  // constructor used for deserialization only
2073  : catalog_{cat}
2074  , table_descriptor_{td}
2075  , flattened_{false}
2077 
2079  TableDescriptor const* const td,
2080  bool flattened,
2081  std::string const& op_string,
2082  TargetColumnList const& target_column_list,
2083  RelAlgNodeInputPtr input)
2084  : catalog_(cat)
2085  , table_descriptor_(td)
2086  , flattened_(flattened)
2087  , operation_(yieldModifyOperationEnum(op_string))
2088  , target_column_list_(target_column_list) {
2090  inputs_.push_back(input);
2091  }
2092 
2094  TableDescriptor const* const td,
2095  bool flattened,
2096  ModifyOperation op,
2097  TargetColumnList const& target_column_list,
2098  RelAlgNodeInputPtr input)
2099  : catalog_(cat)
2100  , table_descriptor_(td)
2101  , flattened_(flattened)
2102  , operation_(op)
2103  , target_column_list_(target_column_list) {
2105  inputs_.push_back(input);
2106  }
2107 
2108  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
2109 
2111 
2112  bool const isFlattened() const { return flattened_; }
2115  int getUpdateColumnCount() const { return target_column_list_.size(); }
2116 
2117  size_t size() const override { return 0; }
2118  std::shared_ptr<RelAlgNode> deepCopy() const override {
2119  return std::make_shared<RelModify>(*this);
2120  }
2121 
2122  std::string toString(
2123  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2124  auto ret = cat(::typeName(this),
2125  "(",
2127  ", flattened=",
2129  ", op=",
2131  ", target_column_list=",
2133  if (!config.skip_input_nodes) {
2134  ret += ", inputs=", ::toString(inputs_);
2135  } else {
2136  ret += ", input node id={";
2137  for (auto& input : inputs_) {
2138  auto node_id_in_plan = input->getIdInPlanTree();
2139  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
2140  : std::to_string(input->getId());
2141  ret += node_id_str + " ";
2142  }
2143  ret += "}";
2144  }
2145  return cat(ret, ")");
2146  }
2147 
2148  size_t toHash() const override {
2149  if (!hash_) {
2150  hash_ = typeid(RelModify).hash_code();
2151  boost::hash_combine(*hash_, table_descriptor_->tableName);
2152  boost::hash_combine(*hash_, flattened_);
2153  boost::hash_combine(*hash_, yieldModifyOperationString(operation_));
2154  boost::hash_combine(*hash_, ::toString(target_column_list_));
2155  for (auto& node : inputs_) {
2156  boost::hash_combine(*hash_, node->toHash());
2157  }
2158  }
2159  return *hash_;
2160  }
2161 
2163  auto previous_node = dynamic_cast<RelProject const*>(inputs_[0].get());
2164  CHECK(previous_node != nullptr);
2165  auto previous_project_node = const_cast<RelProject*>(previous_node);
2166 
2167  if (previous_project_node->hasWindowFunctionExpr()) {
2168  if (table_descriptor_->fragmenter->getNumFragments() > 1) {
2169  throw std::runtime_error(
2170  "UPDATE of a column of multi-fragmented table using window function not "
2171  "currently supported.");
2172  }
2173  if (table_descriptor_->nShards > 0) {
2174  throw std::runtime_error(
2175  "UPDATE of a column of sharded table using window function not "
2176  "currently supported.");
2177  }
2178  }
2179 
2180  previous_project_node->setUpdateViaSelectFlag(true);
2181  // remove the offset column in the projection for update handling
2182  target_column_list_.pop_back();
2183 
2184  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
2185  previous_project_node->setTargetColumns(target_column_list_);
2186  previous_project_node->setModifiedTableCatalog(&catalog_);
2187 
2188  int target_update_column_expr_start = 0;
2189  int target_update_column_expr_end = (int)(target_column_list_.size() - 1);
2190  CHECK(target_update_column_expr_start >= 0);
2191  CHECK(target_update_column_expr_end >= 0);
2192 
2193  bool varlen_update_required = false;
2194 
2195  auto varlen_scan_visitor = [this,
2196  &varlen_update_required,
2197  target_update_column_expr_start,
2198  target_update_column_expr_end](int index) {
2199  if (index >= target_update_column_expr_start &&
2200  index <= target_update_column_expr_end) {
2201  auto target_index = index - target_update_column_expr_start;
2202 
2203  auto* column_desc = catalog_.getMetadataForColumn(
2205  CHECK(column_desc);
2206 
2207  if (table_descriptor_->nShards) {
2208  const auto shard_cd =
2210  CHECK(shard_cd);
2211  if ((column_desc->columnName == shard_cd->columnName)) {
2212  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
2213  }
2214  }
2215 
2216  // Check for valid types
2217  if (column_desc->columnType.is_varlen()) {
2218  varlen_update_required = true;
2219  }
2220  if (column_desc->columnType.is_geometry()) {
2221  throw std::runtime_error("UPDATE of a geo column is unsupported.");
2222  }
2223  }
2224  };
2225 
2226  previous_project_node->visitScalarExprs(varlen_scan_visitor);
2227  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
2228  }
2229 
2231  auto previous_node = dynamic_cast<RelProject const*>(inputs_[0].get());
2232  CHECK(previous_node != nullptr);
2233  auto previous_project_node = const_cast<RelProject*>(previous_node);
2234  previous_project_node->setDeleteViaSelectFlag(true);
2235  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
2236  previous_project_node->setModifiedTableCatalog(&catalog_);
2237  }
2238 
2239  private:
2245 
2246  friend struct RelAlgDagSerializer;
2247 };
2248 
2250  public:
2251  // default constructor used for deserialization only
2252  RelTableFunction() = default;
2253 
2254  RelTableFunction(const std::string& function_name,
2255  RelAlgInputs inputs,
2256  std::vector<std::string>& fields,
2257  std::vector<const Rex*> col_inputs,
2258  std::vector<std::unique_ptr<const RexScalar>>& table_func_inputs,
2259  std::vector<std::unique_ptr<const RexScalar>>& target_exprs)
2260  : function_name_(function_name)
2261  , fields_(fields)
2262  , col_inputs_(col_inputs)
2263  , table_func_inputs_(std::move(table_func_inputs))
2264  , target_exprs_(std::move(target_exprs)) {
2265  for (const auto& input : inputs) {
2266  inputs_.emplace_back(input);
2267  }
2268  }
2269 
2271 
2272  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
2273  std::shared_ptr<const RelAlgNode> input) override;
2274 
2275  std::string getFunctionName() const { return function_name_; }
2276 
2277  size_t size() const override { return target_exprs_.size(); }
2278 
2279  const RexScalar* getTargetExpr(size_t idx) const {
2280  CHECK_LT(idx, target_exprs_.size());
2281  return target_exprs_[idx].get();
2282  }
2283 
2284  size_t getTableFuncInputsSize() const { return table_func_inputs_.size(); }
2285 
2286  size_t getColInputsSize() const { return col_inputs_.size(); }
2287 
2288  int32_t countRexLiteralArgs() const;
2289 
2290  const RexScalar* getTableFuncInputAt(const size_t idx) const {
2291  CHECK_LT(idx, table_func_inputs_.size());
2292  return table_func_inputs_[idx].get();
2293  }
2294 
2295  const RexScalar* getTableFuncInputAtAndRelease(const size_t idx) {
2296  // NOTE: as of 08/06/22, this appears to only be called by the bind_inputs free
2297  // function in RelAlgDag.cpp to disambituate inputs. If you follow the bind_inputs
2298  // path, it eventually could call this method in a bind_table_func_to_input lambda
2299  // According to that lambda, the released pointer released here is be immediately be
2300  // placed in a new vector of RexScalar unique_ptrs which is then ultimatey used as an
2301  // argument for the setTableFuncInputs method below. As such, if a table_func_input_
2302  // is released here that is being pointed to by one of the col_inputs_, then we can
2303  // keep that col_inputs_ pointer as that table_func_input_ should be returned back.
2304  CHECK_LT(idx, table_func_inputs_.size());
2305  return table_func_inputs_[idx].release();
2306  }
2307 
2308  void setTableFuncInputs(std::vector<std::unique_ptr<const RexScalar>>&& exprs);
2309 
2310  std::string getFieldName(const size_t idx) const {
2311  CHECK_LT(idx, fields_.size());
2312  return fields_[idx];
2313  }
2314 
2315  const std::vector<std::string>& getFields() const { return fields_; }
2316  void setFields(std::vector<std::string>&& fields) { fields_ = std::move(fields); }
2317 
2318  std::shared_ptr<RelAlgNode> deepCopy() const override {
2319  return std::make_shared<RelTableFunction>(*this);
2320  }
2321 
2322  std::string toString(
2323  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2324  auto ret = cat(::typeName(this), "(", function_name_);
2325  if (!config.skip_input_nodes) {
2326  ret += ", inputs=", ::toString(inputs_);
2327  } else {
2328  ret += ", input node id={";
2329  for (auto& input : inputs_) {
2330  auto node_id_in_plan = input->getIdInPlanTree();
2331  auto node_id_str = node_id_in_plan ? std::to_string(*node_id_in_plan)
2332  : std::to_string(input->getId());
2333  ret += node_id_str + " ";
2334  }
2335  ret += "}";
2336  }
2337  ret +=
2338  cat(", fields=", ::toString(fields_), ", col_inputs=...", ", table_func_inputs=");
2339  if (!config.skip_input_nodes) {
2341  } else {
2342  for (auto& expr : table_func_inputs_) {
2343  ret += expr->toString(config) + " ";
2344  }
2345  }
2346  ret += ", target_exprs=";
2347  for (auto& expr : target_exprs_) {
2348  ret += expr->toString(config) + " ";
2349  }
2350  return cat(ret, ")");
2351  }
2352 
2353  size_t toHash() const override {
2354  if (!hash_) {
2355  hash_ = typeid(RelTableFunction).hash_code();
2356  for (auto& table_func_input : table_func_inputs_) {
2357  boost::hash_combine(*hash_, table_func_input->toHash());
2358  }
2359  for (auto& target_expr : target_exprs_) {
2360  boost::hash_combine(*hash_, target_expr->toHash());
2361  }
2362  boost::hash_combine(*hash_, function_name_);
2363  boost::hash_combine(*hash_, ::toString(fields_));
2364  for (auto& node : inputs_) {
2365  boost::hash_combine(*hash_, node->toHash());
2366  }
2367  }
2368  return *hash_;
2369  }
2370 
2371  private:
2372  std::string function_name_;
2373  std::vector<std::string> fields_;
2374 
2375  std::vector<const Rex*> col_inputs_; // owned by `table_func_inputs_`, but allows
2376  // picking out the specific input columns vs
2377  // other table function inputs (e.g. literals)
2378  std::vector<std::unique_ptr<const RexScalar>> table_func_inputs_;
2379 
2380  std::vector<std::unique_ptr<const RexScalar>>
2381  target_exprs_; // Note: these should all be RexRef but are stored as RexScalar
2382  // for consistency
2383 
2384  friend struct RelAlgDagSerializer;
2385 };
2386 
2388  public:
2389  using RowValues = std::vector<std::unique_ptr<const RexScalar>>;
2390 
2391  // default constructor used for deserialization only
2392  RelLogicalValues() = default;
2393 
2394  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type,
2395  std::vector<RowValues>& values)
2396  : tuple_type_(tuple_type), values_(std::move(values)) {}
2397 
2399 
2400  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
2401 
2402  std::string toString(
2403  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override {
2404  std::string ret = ::typeName(this) + "(";
2405  for (const auto& target_meta_info : tuple_type_) {
2406  ret += " (" + target_meta_info.get_resname() + " " +
2407  target_meta_info.get_type_info().get_type_name() + ")";
2408  }
2409  ret += ")";
2410  return ret;
2411  }
2412 
2413  size_t toHash() const override {
2414  if (!hash_) {
2415  hash_ = typeid(RelLogicalValues).hash_code();
2416  for (auto& target_meta_info : tuple_type_) {
2417  boost::hash_combine(*hash_, target_meta_info.get_resname());
2418  boost::hash_combine(*hash_, target_meta_info.get_type_info().get_type_name());
2419  }
2420  }
2421  return *hash_;
2422  }
2423 
2424  std::string getFieldName(const size_t col_idx) const {
2425  CHECK_LT(col_idx, size());
2426  return tuple_type_[col_idx].get_resname();
2427  }
2428 
2429  const RexScalar* getValueAt(const size_t row_idx, const size_t col_idx) const {
2430  CHECK_LT(row_idx, values_.size());
2431  const auto& row = values_[row_idx];
2432  CHECK_LT(col_idx, row.size());
2433  return row[col_idx].get();
2434  }
2435 
2436  size_t getRowsSize() const {
2437  if (values_.empty()) {
2438  return 0;
2439  } else {
2440  return values_.front().size();
2441  }
2442  }
2443 
2444  size_t getNumRows() const { return values_.size(); }
2445 
2446  size_t size() const override { return tuple_type_.size(); }
2447 
2448  bool hasRows() const { return !values_.empty(); }
2449 
2450  std::shared_ptr<RelAlgNode> deepCopy() const override {
2451  return std::make_shared<RelLogicalValues>(*this);
2452  }
2453 
2454  private:
2455  std::vector<TargetMetaInfo> tuple_type_;
2456  std::vector<RowValues> values_;
2457 
2458  friend struct RelAlgDagSerializer;
2459 };
2460 
2461 class RelLogicalUnion : public RelAlgNode {
2462  public:
2463  // default constructor used for deserialization only
2464  RelLogicalUnion() : is_all_{false} {}
2465 
2466  RelLogicalUnion(RelAlgInputs, bool is_all);
2467  std::shared_ptr<RelAlgNode> deepCopy() const override {
2468  return std::make_shared<RelLogicalUnion>(*this);
2469  }
2470  size_t size() const override;
2471  std::string toString(
2472  RelRexToStringConfig config = RelRexToStringConfig::defaults()) const override;
2473  size_t toHash() const override;
2474 
2475  std::string getFieldName(const size_t i) const;
2476 
2477  inline bool isAll() const { return is_all_; }
2478  // Will throw a std::runtime_error if MetaInfo types don't match.
2479  std::vector<TargetMetaInfo> getCompatibleMetainfoTypes() const;
2480  RexScalar const* copyAndRedirectSource(RexScalar const*, size_t input_idx) const;
2481 
2482  // Not unique_ptr to allow for an easy deepCopy() implementation.
2483  mutable std::vector<std::shared_ptr<const RexScalar>> scalar_exprs_;
2484 
2485  private:
2486  bool is_all_;
2487 
2488  friend struct RelAlgDagSerializer;
2489 };
2490 
2491 class QueryNotSupported : public std::runtime_error {
2492  public:
2493  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
2494 };
2495 
2501 class RelAlgDag : public boost::noncopyable {
2502  public:
2504 
2506 
2508 
2509  void eachNode(std::function<void(RelAlgNode const*)> const&) const;
2510 
2514  const RelAlgNode& getRootNode() const {
2515  CHECK(nodes_.size());
2516  const auto& last_ptr = nodes_.back();
2517  CHECK(last_ptr);
2518  return *last_ptr;
2519  }
2520 
2521  std::shared_ptr<const RelAlgNode> getRootNodeShPtr() const {
2522  CHECK(nodes_.size());
2523  return nodes_.back();
2524  }
2525 
2530  void registerSubquery(std::shared_ptr<RexSubQuery> subquery) {
2531  subqueries_.push_back(subquery);
2532  }
2533 
2537  const std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries() const {
2538  return subqueries_;
2539  }
2540 
2541  // todo(yoonmin): simplify and improve query register logic
2542  void registerQueryHints(std::shared_ptr<RelAlgNode> node,
2543  Hints* hints_delivered,
2544  RegisteredQueryHint& global_query_hint) {
2545  std::optional<bool> has_global_columnar_output_hint = std::nullopt;
2546  std::optional<bool> has_global_rowwise_output_hint = std::nullopt;
2547  RegisteredQueryHint query_hint;
2548  for (auto it = hints_delivered->begin(); it != hints_delivered->end(); it++) {
2549  auto target = it->second;
2550  auto hint_type = it->first;
2551  switch (hint_type) {
2552  case QueryHint::kCpuMode: {
2553  query_hint.registerHint(QueryHint::kCpuMode);
2554  query_hint.cpu_mode = true;
2555  if (target.isGlobalHint()) {
2556  global_query_hint.registerHint(QueryHint::kCpuMode);
2557  global_query_hint.cpu_mode = true;
2558  }
2559  break;
2560  }
2562  has_global_columnar_output_hint = target.isGlobalHint();
2563  break;
2564  }
2566  has_global_rowwise_output_hint = target.isGlobalHint();
2567  break;
2568  }
2570  if (target.getListOptions().size() != 1) {
2571  VLOG(1) << "Skip the given query hint \"overlaps_bucket_threshold\" ("
2572  << target.getListOptions()[0]
2573  << ") : invalid # hint options are given";
2574  break;
2575  }
2576  double overlaps_bucket_threshold = std::stod(target.getListOptions()[0]);
2577  if (overlaps_bucket_threshold >= 0.0 && overlaps_bucket_threshold <= 90.0) {
2579  query_hint.overlaps_bucket_threshold = overlaps_bucket_threshold;
2580  if (target.isGlobalHint()) {
2582  global_query_hint.overlaps_bucket_threshold = overlaps_bucket_threshold;
2583  }
2584  } else {
2585  VLOG(1) << "Skip the given query hint \"overlaps_bucket_threshold\" ("
2586  << overlaps_bucket_threshold
2587  << ") : the hint value should be within 0.0 ~ 90.0";
2588  }
2589  break;
2590  }
2592  if (target.getListOptions().size() != 1) {
2593  VLOG(1) << "Skip the given query hint \"overlaps_max_size\" ("
2594  << target.getListOptions()[0]
2595  << ") : invalid # hint options are given";
2596  break;
2597  }
2598  std::stringstream ss(target.getListOptions()[0]);
2599  int overlaps_max_size;
2600  ss >> overlaps_max_size;
2601  if (overlaps_max_size >= 0) {
2603  query_hint.overlaps_max_size = (size_t)overlaps_max_size;
2604  if (target.isGlobalHint()) {
2605  global_query_hint.registerHint(QueryHint::kOverlapsMaxSize);
2606  global_query_hint.overlaps_max_size = (size_t)overlaps_max_size;
2607  }
2608  } else {
2609  VLOG(1) << "Skip the query hint \"overlaps_max_size\" (" << overlaps_max_size
2610  << ") : the hint value should be larger than or equal to zero";
2611  }
2612  break;
2613  }
2616  query_hint.overlaps_allow_gpu_build = true;
2617  if (target.isGlobalHint()) {
2619  global_query_hint.overlaps_allow_gpu_build = true;
2620  }
2621  break;
2622  }
2625  query_hint.overlaps_no_cache = true;
2626  if (target.isGlobalHint()) {
2627  global_query_hint.registerHint(QueryHint::kOverlapsNoCache);
2628  global_query_hint.overlaps_no_cache = true;
2629  }
2630  VLOG(1) << "Skip auto tuner and hashtable caching for overlaps join.";
2631  break;
2632  }
2634  if (target.getListOptions().size() != 1) {
2635  VLOG(1) << "Skip the given query hint \"overlaps_keys_per_bin\" ("
2636  << target.getListOptions()[0]
2637  << ") : invalid # hint options are given";
2638  break;
2639  }
2640  double overlaps_keys_per_bin = std::stod(target.getListOptions()[0]);
2641  if (overlaps_keys_per_bin > 0.0 &&
2642  overlaps_keys_per_bin < std::numeric_limits<double>::max()) {
2644  query_hint.overlaps_keys_per_bin = overlaps_keys_per_bin;
2645  if (target.isGlobalHint()) {
2646  global_query_hint.registerHint(QueryHint::kOverlapsKeysPerBin);
2647  global_query_hint.overlaps_keys_per_bin = overlaps_keys_per_bin;
2648  }
2649  } else {
2650  VLOG(1) << "Skip the given query hint \"overlaps_keys_per_bin\" ("
2651  << overlaps_keys_per_bin
2652  << ") : the hint value should be larger than zero";
2653  }
2654  break;
2655  }
2656  case QueryHint::kKeepResult: {
2658  VLOG(1) << "Skip query hint \'keep_result\' because neither data recycler "
2659  "nor query resultset recycler is enabled";
2660  } else {
2662  query_hint.keep_result = true;
2663  if (target.isGlobalHint()) {
2664  global_query_hint.registerHint(QueryHint::kKeepResult);
2665  global_query_hint.keep_result = true;
2666  }
2667  }
2668  break;
2669  }
2672  VLOG(1) << "Skip query hint \'keep_table_function_result\' because neither "
2673  "data recycler "
2674  "nor query resultset recycler is enabled";
2675  } else {
2676  // we assume table function's hint is handled as global hint by default
2677  global_query_hint.registerHint(QueryHint::kKeepTableFuncResult);
2678  global_query_hint.keep_table_function_result = true;
2679  }
2680  break;
2681  }
2683  if (target.getListOptions().size() != 1u) {
2684  VLOG(1) << "Skip the given query hint \"aggregate_tree_fanout\" ("
2685  << target.getListOptions()[0]
2686  << ") : invalid # hint options are given";
2687  break;
2688  }
2689  int aggregate_tree_fanout = std::stoi(target.getListOptions()[0]);
2690  if (aggregate_tree_fanout < 0) {
2691  VLOG(1) << "A fan-out of an aggregate tree should be larger than zero";
2692  } else if (aggregate_tree_fanout > 1024) {
2693  VLOG(1) << "Too large fanout is provided (i.e., fanout < 1024)";
2694  } else {
2696  query_hint.aggregate_tree_fanout = aggregate_tree_fanout;
2697  if (target.isGlobalHint()) {
2698  global_query_hint.registerHint(QueryHint::kAggregateTreeFanout);
2699  global_query_hint.aggregate_tree_fanout = aggregate_tree_fanout;
2700  }
2701  }
2702  break;
2703  }
2705  CHECK_EQ(1u, target.getListOptions().size());
2706  int cuda_block_size = std::stoi(target.getListOptions()[0]);
2707  if (cuda_block_size <= 0) {
2708  VLOG(1) << "CUDA block size should be larger than zero";
2709  } else if (cuda_block_size > 1024) {
2710  VLOG(1) << "CUDA block size should be less or equal to 1024";
2711  } else {
2713  query_hint.cuda_block_size = cuda_block_size;
2714  if (target.isGlobalHint()) {
2715  global_query_hint.registerHint(QueryHint::kCudaBlockSize);
2716  global_query_hint.cuda_block_size = cuda_block_size;
2717  }
2718  }
2719  break;
2720  }
2721  case QueryHint::kCudaGridSize: {
2722  CHECK_EQ(1u, target.getListOptions().size());
2723  double cuda_grid_size_multiplier = std::stod(target.getListOptions()[0]);
2724  double min_grid_size_multiplier{0};
2725  double max_grid_size_multiplier{1024};
2726  if (cuda_grid_size_multiplier <= min_grid_size_multiplier) {
2727  VLOG(1) << "CUDA grid size multiplier should be larger than zero";
2728  } else if (cuda_grid_size_multiplier > max_grid_size_multiplier) {
2729  VLOG(1) << "CUDA grid size multiplier should be less than 1024";
2730  } else {
2732  query_hint.cuda_grid_size_multiplier = cuda_grid_size_multiplier;
2733  if (target.isGlobalHint()) {
2734  global_query_hint.registerHint(QueryHint::kCudaGridSize);
2735  global_query_hint.cuda_grid_size_multiplier = cuda_grid_size_multiplier;
2736  }
2737  }
2738  break;
2739  }
2742  query_hint.opt_cuda_grid_and_block_size = true;
2743  if (target.isGlobalHint()) {
2745  global_query_hint.opt_cuda_grid_and_block_size = true;
2746  }
2747  break;
2748  }
2749  case QueryHint::kWatchdog: {
2750  if (g_enable_watchdog) {
2751  VLOG(1) << "Skip the given query hint \"watchdog\": already enabled";
2752  } else {
2753  query_hint.registerHint(QueryHint::kWatchdog);
2754  query_hint.watchdog = true;
2755  if (target.isGlobalHint()) {
2756  global_query_hint.registerHint(QueryHint::kWatchdog);
2757  global_query_hint.watchdog = true;
2758  }
2759  }
2760  break;
2761  }
2762  case QueryHint::kWatchdogOff: {
2763  if (!g_enable_watchdog) {
2764  VLOG(1) << "Skip the given query hint \"watchdog_off\": already disabled";
2765  } else {
2767  query_hint.watchdog = false;
2768  if (target.isGlobalHint()) {
2769  global_query_hint.registerHint(QueryHint::kWatchdogOff);
2770  global_query_hint.watchdog = false;
2771  }
2772  }
2773 
2774  break;
2775  }
2778  VLOG(1) << "Skip the given query hint \"dynamic_watchdog\": already enabled";
2779  } else {
2781  query_hint.dynamic_watchdog = true;
2782  if (target.isGlobalHint()) {
2783  global_query_hint.registerHint(QueryHint::kDynamicWatchdog);
2784  global_query_hint.dynamic_watchdog = true;
2785  }
2786  }
2787  break;
2788  }
2791  VLOG(1)
2792  << "Skip the given query hint \"dynamic_watchdog_off\": already disabled";
2793  } else {
2795  query_hint.dynamic_watchdog = false;
2796  if (target.isGlobalHint()) {
2797  global_query_hint.registerHint(QueryHint::kDynamicWatchdogOff);
2798  global_query_hint.dynamic_watchdog = false;
2799  }
2800  }
2801  break;
2802  }
2804  if (hints_delivered->find(QueryHint::kDynamicWatchdogOff) !=
2805  hints_delivered->end()) {
2806  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
2807  << target.getListOptions()[0]
2808  << ") : cannot use it with \"dynamic_watchdog_off\" hint";
2809  break;
2810  }
2811  if (target.getListOptions().size() != 1) {
2812  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
2813  << target.getListOptions()[0]
2814  << ") : invalid # hint options are given";
2815  break;
2816  }
2817  double query_time_limit = std::stoi(target.getListOptions()[0]);
2818  if (query_time_limit <= 0) {
2819  VLOG(1) << "Skip the given query hint \"query_time_limit\" ("
2820  << target.getListOptions()[0]
2821  << ") : the hint value should be larger than zero";
2822  break;
2823  }
2825  query_hint.query_time_limit = query_time_limit;
2826  if (target.isGlobalHint()) {
2827  global_query_hint.registerHint(QueryHint::kQueryTimeLimit);
2828  global_query_hint.query_time_limit = query_time_limit;
2829  }
2830  break;
2831  }
2834  query_hint.use_loop_join = true;
2835  if (target.isGlobalHint()) {
2836  global_query_hint.registerHint(QueryHint::kAllowLoopJoin);
2837  global_query_hint.use_loop_join = true;
2838  }
2839  break;
2840  }
2843  query_hint.use_loop_join = false;
2844  if (target.isGlobalHint()) {
2845  global_query_hint.registerHint(QueryHint::kDisableLoopJoin);
2846  global_query_hint.use_loop_join = false;
2847  }
2848  break;
2849  }
2851  CHECK_EQ(1u, target.getListOptions().size());
2852  int loop_size_threshold = std::stoi(target.getListOptions()[0]);
2853  if (loop_size_threshold <= 0) {
2854  VLOG(1) << "The loop size threshold should be larger than zero";
2855  } else {
2857  query_hint.loop_join_inner_table_max_num_rows = loop_size_threshold;
2858  if (target.isGlobalHint()) {
2860  global_query_hint.loop_join_inner_table_max_num_rows = loop_size_threshold;
2861  }
2862  }
2863  break;
2864  }
2866  CHECK_EQ(1u, target.getListOptions().size());
2867  int max_join_hash_table_size = std::stoi(target.getListOptions()[0]);
2868  if (max_join_hash_table_size <= 0) {
2869  VLOG(1) << "The maximum hash table size should be larger than zero";
2870  } else {
2872  query_hint.max_join_hash_table_size = max_join_hash_table_size;
2873  if (target.isGlobalHint()) {
2875  global_query_hint.max_join_hash_table_size = max_join_hash_table_size;
2876  }
2877  }
2878  break;
2879  }
2880  default:
2881  break;
2882  }
2883  }
2884  // we have four cases depending on 1) g_enable_columnar_output flag
2885  // and 2) query hint status: columnar_output and rowwise_output
2886  // case 1. g_enable_columnar_output = true
2887  // case 1.a) columnar_output = true (so rowwise_output = false);
2888  // case 1.b) rowwise_output = true (so columnar_output = false);
2889  // case 2. g_enable_columnar_output = false
2890  // case 2.a) columnar_output = true (so rowwise_output = false);
2891  // case 2.b) rowwise_output = true (so columnar_output = false);
2892  // case 1.a --> use columnar output
2893  // case 1.b --> use rowwise output
2894  // case 2.a --> use columnar output
2895  // case 2.b --> use rowwise output
2896  if (has_global_columnar_output_hint.has_value() &&
2897  has_global_rowwise_output_hint.has_value()) {
2898  VLOG(1)
2899  << "Two hints 1) columnar output and 2) rowwise output are enabled together, "
2900  << "so skip them and use the runtime configuration "
2901  "\"g_enable_columnar_output\"";
2902  } else if (has_global_columnar_output_hint.has_value() &&
2903  !has_global_rowwise_output_hint.has_value()) {
2905  VLOG(1) << "We already enable columnar output by default "
2906  "(g_enable_columnar_output = true), so skip this columnar output hint";
2907  } else {
2909  query_hint.columnar_output = true;
2910  if (*has_global_columnar_output_hint) {
2911  global_query_hint.registerHint(QueryHint::kColumnarOutput);
2912  global_query_hint.columnar_output = true;
2913  }
2914  }
2915  } else if (!has_global_columnar_output_hint.has_value() &&
2916  has_global_rowwise_output_hint.has_value()) {
2917  if (!g_enable_columnar_output) {
2918  VLOG(1) << "We already use the default rowwise output (g_enable_columnar_output "
2919  "= false), so skip this rowwise output hint";
2920  } else {
2922  query_hint.rowwise_output = true;
2923  if (*has_global_rowwise_output_hint) {
2924  global_query_hint.registerHint(QueryHint::kRowwiseOutput);
2925  global_query_hint.rowwise_output = true;
2926  }
2927  }
2928  }
2929  registerQueryHint(node.get(), query_hint);
2930  }
2931 
2932  void registerQueryHint(const RelAlgNode* node, const RegisteredQueryHint& query_hint) {
2933  auto node_key = node->toHash();
2934  auto it = query_hint_.find(node_key);
2935  if (it == query_hint_.end()) {
2936  std::unordered_map<unsigned, RegisteredQueryHint> hint_map;
2937  hint_map.emplace(node->getId(), query_hint);
2938  query_hint_.emplace(node_key, hint_map);
2939  } else {
2940  it->second.emplace(node->getId(), query_hint);
2941  }
2942  }
2943 
2944  std::optional<RegisteredQueryHint> getQueryHint(const RelAlgNode* node) const {
2945  auto node_it = query_hint_.find(node->toHash());
2946  if (node_it != query_hint_.end()) {
2947  auto const& registered_query_hint_map = node_it->second;
2948  auto hint_it = registered_query_hint_map.find(node->getId());
2949  if (hint_it != registered_query_hint_map.end()) {
2950  auto const& registered_query_hint = hint_it->second;
2952  // apply global hint to the registered query hint for this query block
2953  return std::make_optional(registered_query_hint || global_hints_);
2954  } else {
2955  return std::make_optional(registered_query_hint);
2956  }
2957  }
2958  }
2960  // if no hint is registered from this query block
2961  // we return global hint instead
2962  return std::make_optional(global_hints_);
2963  }
2964  return std::nullopt;
2965  }
2966 
2967  std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>&
2969  return query_hint_;
2970  }
2971 
2973 
2974  void setGlobalQueryHints(const RegisteredQueryHint& global_hints) {
2975  global_hints_ = global_hints;
2976  }
2977 
2981  void resetQueryExecutionState();
2982 
2983  private:
2985 
2986  std::vector<std::shared_ptr<RelAlgNode>> nodes_;
2987  std::vector<std::shared_ptr<RexSubQuery>> subqueries_;
2988 
2989  // node hash --> {node id --> registered hint}
2990  // we additionally consider node id to recognize corresponding hint correctly
2991  // i.e., to recognize the correct hint when two subqueries are identical
2992  std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>
2995 
2996  friend struct RelAlgDagSerializer;
2997  friend struct RelAlgDagModifier;
2998 };
2999 
3008  protected:
3009  static std::vector<std::shared_ptr<RelAlgNode>>& getNodes(RelAlgDag& rel_alg_dag) {
3010  return rel_alg_dag.nodes_;
3011  }
3012 
3013  static std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries(
3014  RelAlgDag& rel_alg_dag) {
3015  return rel_alg_dag.subqueries_;
3016  }
3017 
3018  static std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>&
3019  getQueryHints(RelAlgDag& rel_alg_dag) {
3020  return rel_alg_dag.query_hint_;
3021  }
3022 
3023  static void setBuildState(RelAlgDag& rel_alg_dag,
3024  const RelAlgDag::BuildState build_state) {
3025  rel_alg_dag.build_state_ = build_state;
3026  }
3027 };
3028 
3043  static std::unique_ptr<RelAlgDag> buildDag(const std::string& query_ra,
3044  const bool optimize_dag);
3045 
3054  static std::unique_ptr<RelAlgDag> buildDagForSubquery(
3055  RelAlgDag& root_dag,
3056  const rapidjson::Value& query_ast);
3057 
3058  static void optimizeDag(RelAlgDag& rel_alg_dag);
3059 
3060  private:
3061  static std::unique_ptr<RelAlgDag> build(const rapidjson::Value& query_ast,
3062  RelAlgDag* root_dag,
3063  const bool optimize_dag);
3064 };
3065 
3066 using RANodeOutput = std::vector<RexInput>;
3067 
3068 RANodeOutput get_node_output(const RelAlgNode* ra_node);
3069 
3070 std::string tree_string(const RelAlgNode*, const size_t depth = 0);
std::vector< std::shared_ptr< const RexScalar > > scalar_exprs_
Definition: RelAlgDag.h:2483
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1650
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1973
bool is_nop_
Definition: RelAlgDag.h:959
const size_t getGroupByCount() const
Definition: RelAlgDag.h:1342
bool hasRows() const
Definition: RelAlgDag.h:2448
void setGlobalQueryHints(const RegisteredQueryHint &global_hints)
Definition: RelAlgDag.h:2974
bool isAll() const
Definition: RelAlgDag.h:2477
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:1954
std::unique_ptr< const RexScalar > condition_
Definition: RelAlgDag.h:1550
RexWindowBound frame_start_bound_
Definition: RelAlgDag.h:736
RelCompound(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
Definition: RelAlgDag.h:1797
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:1661
#define CHECK_EQ(x, y)
Definition: Logger.h:301
std::unique_ptr< const RexScalar > ConstRexScalarPtr
Definition: RelAlgDag.h:1128
std::vector< std::unique_ptr< const RexScalar > > getExpressionsAndRelease()
Definition: RelAlgDag.h:1214
size_t groupby_count_
Definition: RelAlgDag.h:1915
size_t getOffset() const
Definition: RelAlgDag.h:1971
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1585
void setVarlenUpdateRequired(bool required) const
Definition: RelAlgDag.h:1071
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:1783
bool const isFlattened() const
Definition: RelAlgDag.h:2112
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:1223
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const
Definition: RelAlgDag.h:2537
JoinType
Definition: sqldefs.h:165
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1412
size_t toHash() const
Definition: RelAlgDag.h:563
int getUpdateColumnCount() const
Definition: RelAlgDag.h:2115
static std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > & getQueryHints(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3019
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > query_hint_
Definition: RelAlgDag.h:2993
ColumnNameList target_columns_
Definition: RelAlgDag.h:1118
bool g_use_query_resultset_cache
Definition: Execute.cpp:148
const bool hasHintEnabled(QueryHint candidate_hint) const
Definition: RelAlgDag.h:1531
std::vector< std::unique_ptr< const RexScalar > > table_func_inputs_
Definition: RelAlgDag.h:2378
size_t toHash() const override
Definition: RelAlgDag.h:1608
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:1852
SQLAgg getKind() const
Definition: RelAlgDag.h:813
size_t toHash() const override
Definition: RelAlgDag.h:1004
TableDescriptor const * getTableDescriptor() const
Definition: RelAlgDag.h:1077
RelAlgNode(RelAlgInputs inputs={})
Definition: RelAlgDag.h:840
std::string getOpTypeInfo() const
Definition: RelAlgDag.h:1634
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:1042
RexFunctionOperator()=default
const std::vector< std::shared_ptr< const Analyzer::Expr > > getFilterCond() const
Definition: RelAlgDag.h:1628
size_t size() const override
Definition: RelAlgDag.h:1172
SQLTypes
Definition: sqltypes.h:55
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1014
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1283
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1888
std::string tableName
const bool nested_loop_
Definition: RelAlgDag.h:1670
bool coversOriginalNode(const RelAlgNode *node) const
const RexScalar * getFilterExpr() const
Definition: RelAlgDag.h:1846
size_t size() const override
Definition: RelAlgDag.h:2446
size_t groupby_count_
Definition: RelAlgDag.h:1442
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1373
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.cpp:3401
size_t getOperand(size_t idx) const
Definition: RelAlgDag.h:819
size_t toHash() const override
Definition: RelAlgDag.cpp:3392
TargetColumnList const & getUpdateColumnNames() const
Definition: RelAlgDag.h:2114
std::vector< RexInput > RANodeOutput
Definition: RelAlgDag.h:3066
bool limit_delivered_
Definition: RelAlgDag.h:2031
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
void setPushedDownWindowExpr()
Definition: RelAlgDag.h:1202
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:1700
void setTargetColumns(ColumnNameList const &target_columns) const
Definition: RelAlgDag.h:1096
std::string function_name_
Definition: RelAlgDag.h:2372
const std::string getFieldName(const size_t i) const
Definition: RelAlgDag.h:1856
std::unique_ptr< RexRef > deepCopy() const
Definition: RelAlgDag.h:767
const RexScalar * outer_join_cond_
Definition: RelAlgDag.h:1669
void setEmptyResult(bool emptyResult)
Definition: RelAlgDag.h:1963
bool overlaps_allow_gpu_build
Definition: QueryHint.h:318
const Catalog_Namespace::Catalog & getCatalog() const
Definition: RelAlgDag.h:988
RelProject(const TableDescriptor *td, const Catalog_Namespace::Catalog *catalog)
Definition: RelAlgDag.h:1132
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:1646
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:1437
void applyDeleteModificationsToInputNode()
Definition: RelAlgDag.h:2230
bool operator==(const SortField &that) const
Definition: RelAlgDag.h:541
std::vector< std::string > TargetColumnList
Definition: RelAlgDag.h:2042
size_t size() const override
Definition: RelAlgDag.h:1844
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:284
size_t size() const
Definition: RelAlgDag.h:270
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1292
const RexScalar * getOperand(const size_t idx) const
Definition: RelAlgDag.h:272
size_t size() const override
Definition: RelAlgDag.h:1518
std::vector< const Rex * > col_inputs_
Definition: RelAlgDag.h:2375
const JoinType join_type_
Definition: RelAlgDag.h:1671
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:3348
SortDirection getSortDir() const
Definition: RelAlgDag.h:548
size_t getNumRows() const
Definition: RelAlgDag.h:2444
std::shared_ptr< RelFilter > original_filter_
Definition: RelAlgDag.h:1784
bool hasDeliveredHint()
Definition: RelAlgDag.h:1909
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:1423
void setRelNodeDagId(const size_t id) const
Definition: RelAlgDag.h:926
const std::vector< const Analyzer::ColumnVar * > lhs_join_cols_
Definition: RelAlgDag.h:1666
void applyUpdateModificationsToInputNode()
Definition: RelAlgDag.h:2162
std::string getFieldName(const size_t idx) const
Definition: RelAlgDag.h:2310
const RexScalar * getCondition() const
Definition: RelAlgDag.h:1696
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:2986
const std::vector< TargetMetaInfo > getTupleType() const
Definition: RelAlgDag.h:2400
size_t toHash() const override
Definition: RelAlgDag.h:213
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:2315
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:1552
RexInput()
Definition: RelAlgDag.h:384
size_t limit_
Definition: RelAlgDag.h:2028
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:2122
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:1101
void registerQueryHint(const RelAlgNode *node, const RegisteredQueryHint &query_hint)
Definition: RelAlgDag.h:2932
std::vector< std::string > fields_
Definition: RelAlgDag.h:1312
size_t toHash() const override
Definition: RelAlgDag.h:1729
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
Definition: RelAlgDag.h:1361
RexInput(const RelAlgNode *node, const unsigned in_index)
Definition: RelAlgDag.h:386
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1524
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1256
unsigned target_scale_
Definition: RelAlgDag.h:246
void setDeleteViaSelectFlag(bool required) const
Definition: RelAlgDag.h:1070
const RexScalar * getWhen(const size_t idx) const
Definition: RelAlgDag.h:438
const RegisteredQueryHint & getGlobalHints() const
Definition: RelAlgDag.h:2972
double overlaps_keys_per_bin
Definition: QueryHint.h:320
void setFields(std::vector< std::string > &&fields)
Definition: RelAlgDag.h:1858
auto const isProjectForUpdate() const
Definition: RelAlgDag.h:1091
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
Definition: RelAlgDag.h:1848
std::optional< bool > dynamic_watchdog
Definition: QueryHint.h:304
std::vector< const Analyzer::ColumnVar * > getJoinCols(bool lhs) const
Definition: RelAlgDag.h:1655
bool hasDeliveredHint()
Definition: RelAlgDag.h:1290
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:1472
std::string getOpType() const
Definition: RelAlgDag.h:1632
size_t cuda_block_size
Definition: QueryHint.h:308
bool has_pushed_down_window_expr_
Definition: RelAlgDag.h:1315
std::string query_plan_dag_
Definition: RelAlgDag.h:963
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:2118
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:80
bool empty_result_
Definition: RelAlgDag.h:2030
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1416
const RelAlgNode * rhs_
Definition: RelAlgDag.h:1665
virtual ~Rex()
Definition: RelAlgDag.h:59
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
Definition: RelAlgDag.h:1129
void forceRowwiseOutput() const
Definition: RelAlgDag.h:1074
RelFilter(std::unique_ptr< const RexScalar > &filter)
Definition: RelAlgDag.h:1690
const TableDescriptor * td_
Definition: RelAlgDag.h:1045
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:1672
const RexScalar * getOperandAndRelease(const size_t idx) const
Definition: RelAlgDag.h:277
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
Definition: RelAlgDag.h:1920
std::vector< std::shared_ptr< const RelJoin > > original_joins_
Definition: RelAlgDag.h:1785
bool g_enable_data_recycler
Definition: Execute.cpp:146
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:4682
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:3013
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:1046
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:1923
size_t toHash() const override
Definition: RelAlgDag.h:800
const std::string getFieldName(const size_t i) const
Definition: RelAlgDag.h:1221
bool flattened_
Definition: RelAlgDag.h:2242
bool hasPushedDownWindowExpr() const
Definition: RelAlgDag.h:1200
std::string to_string(char const *&&v)
std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > & getQueryHints()
Definition: RelAlgDag.h:2968
void clearContextData() const
Definition: RelAlgDag.h:949
TableDescriptor const *const getTableDescriptor() const
Definition: RelAlgDag.h:2108
std::shared_ptr< const RelAlgNode > getRootNodeShPtr() const
Definition: RelAlgDag.h:2521
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:996
size_t getQueryPlanDagHash() const
Definition: RelAlgDag.h:874
const std::string qualifier_
Definition: RelAlgDag.h:1673
Definition: RelAlgDag.h:52
std::vector< SortField > collation_
Definition: RelAlgDag.h:2027
const RelAlgNode & getRootNode() const
Definition: RelAlgDag.h:2514
RelLogicalValues()=default
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1484
size_t getRowsSize() const
Definition: RelAlgDag.h:2436
size_t getColInputsSize() const
Definition: RelAlgDag.h:2286
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1902
void setUpdateViaSelectFlag(bool required) const
Definition: RelAlgDag.h:1069
void setIdInPlanTree(size_t id) const
Definition: RelAlgDag.h:882
This file contains the class specification and related data structures for Catalog.
RelScan(const TableDescriptor *td, const Catalog_Namespace::Catalog &catalog)
Definition: RelAlgDag.h:972
const size_t getScalarSourcesSize() const
Definition: RelAlgDag.h:1860
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
Definition: RelAlgDag.h:1152
unsigned precision_
Definition: RelAlgDag.h:245
std::string to_string() const
Definition: sqltypes.h:547
const RelAlgNode * getRHS() const
Definition: RelAlgDag.h:1626
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:1094
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:1245
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:2041
const RexScalar * getCondition() const
Definition: RelAlgDag.h:1637
bool keep_table_function_result
Definition: QueryHint.h:302
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1520
const Catalog_Namespace::Catalog * catalog_
Definition: RelAlgDag.h:1120
unsigned getId() const
Definition: RelAlgDag.h:880
bool hasDeliveredHint()
Definition: RelAlgDag.h:1040
RelLeftDeepInnerJoin()=default
static std::unique_ptr< RelAlgDag > buildDagForSubquery(RelAlgDag &root_dag, const rapidjson::Value &query_ast)
Definition: RelAlgDag.cpp:3257
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
Definition: RelAlgDag.h:2295
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:2072
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:347
const bool hasHintEnabled(const QueryHint candidate_hint) const
Definition: RelAlgDag.h:1026
ColumnNameList const & getTargetColumns() const
Definition: RelAlgDag.h:1099
size_t dag_node_id_
Definition: RelAlgDag.h:962
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
Definition: RelAlgDag.h:2987
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:302
RexCase(std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar >>> &expr_pair_list, std::unique_ptr< const RexScalar > &else_expr)
Definition: RelAlgDag.h: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:1033
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:1934
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:1439
std::vector< std::string > fields_
Definition: RelAlgDag.h:1917
RelScan(const TableDescriptor *td, const std::vector< std::string > &field_names, const Catalog_Namespace::Catalog &catalog)
Definition: RelAlgDag.h:975
const RexScalar * getAndReleaseCondition() const
Definition: RelAlgDag.h:1641
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1446
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:2241
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1553
std::vector< std::shared_ptr< const RelAlgNode >> RelAlgInputs
Definition: RelAlgDag.h:316
std::optional< RegisteredQueryHint > getQueryHint(const RelAlgNode *node) const
Definition: RelAlgDag.h:2944
std::vector< std::unique_ptr< const RexScalar > > scalar_exprs_
Definition: RelAlgDag.h:1311
void registerHint(const QueryHint hint)
Definition: QueryHint.h:343
const RelAlgNode * lhs_
Definition: RelAlgDag.h:1664
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t toHash() const override
Definition: RelAlgDag.h:86
size_t size() const override
Definition: RelAlgDag.h:2117
std::shared_ptr< SQLTypeInfo > type_
Definition: RelAlgDag.h:372
size_t size() const override
Definition: RelAlgDag.h:1340
const RexScalar * getAndReleaseCondition()
Definition: RelAlgDag.h:1698
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:1269
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:1682
const std::vector< std::shared_ptr< const Analyzer::Expr > > filter_ops_
Definition: RelAlgDag.h:1668
std::vector< std::shared_ptr< const RelJoin > > getOriginalJoins() const
bool g_enable_watchdog
Catalog_Namespace::Catalog const & catalog_
Definition: RelAlgDag.h:2240
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:1326
std::unique_ptr< const RexScalar > filter_
Definition: RelAlgDag.h:1745
void setCondition(std::unique_ptr< const RexScalar > &condition)
Definition: RelAlgDag.h:1476
bool isSimple() const
Definition: RelAlgDag.h:1159
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:2373
size_t query_plan_dag_hash_
Definition: RelAlgDag.h:964
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:2467
std::vector< const Rex * > target_exprs_
Definition: RelAlgDag.h:1922
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1538
std::optional< size_t > hash_
Definition: RelAlgDag.h:955
const RexScalar * getProjectAtAndRelease(const size_t idx) const
Definition: RelAlgDag.h:1209
const RexWindowBound & getFrameEndBound() const
Definition: RelAlgDag.h:658
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
Definition: RelAlgDag.h:1296
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:2450
const RelAlgNode * node_
Definition: RelAlgDag.h:410
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1048
std::string getFieldName(const size_t col_idx) const
Definition: RelAlgDag.h:2424
size_t getTableFuncInputsSize() const
Definition: RelAlgDag.h:2284
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:2044
ModifyOperation getOperation() const
Definition: RelAlgDag.h:2113
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:1078
void setFields(std::vector< std::string > &&fields)
Definition: RelAlgDag.h:2316
size_t size() const override
Definition: RelAlgDag.h:2277
std::shared_ptr< Fragmenter_Namespace::AbstractFragmenter > fragmenter
static std::unique_ptr< RelAlgDag > buildDag(const std::string &query_ra, const bool optimize_dag)
Definition: RelAlgDag.cpp:3237
std::string tree_string(const RelAlgNode *ra, const size_t depth)
Definition: RelAlgDag.cpp:3357
static ModifyOperation yieldModifyOperationEnum(std::string const &op_string)
Definition: RelAlgDag.h:2058
void setScalarSources(std::vector< std::unique_ptr< const RexScalar >> &new_sources)
Definition: RelAlgDag.h:1866
std::vector< RowValues > values_
Definition: RelAlgDag.h:2456
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
Definition: RelAlgDag.h:1443
std::vector< TargetMetaInfo > targets_metainfo_
Definition: RelAlgDag.h:960
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Definition: RelAlgDag.h:1365
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1911
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:1965
const RelAlgNode * getRelAlg() const
Definition: RelAlgDag.h:360
size_t size() const override
Definition: RelAlgDag.h:1635
size_t toHash() const override
Definition: RelAlgDag.h:460
size_t size() const override
Definition: RelAlgDag.h:2020
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:786
const RexScalar * getProjectAt(const size_t idx) const
Definition: RelAlgDag.h:1204
bool hint_applied_
Definition: RelAlgDag.h:1445
size_t offset_
Definition: RelAlgDag.h:2029
const RaExecutionDesc * getContextData() const
Definition: RelAlgDag.h:888
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:1346
#define CHECK_LT(x, y)
Definition: Logger.h:303
Definition: sqltypes.h:69
bool hasInput(const RelAlgNode *needle) const
Definition: RelAlgDag.h:906
const std::vector< std::string > & getFieldNames() const
Definition: RelAlgDag.h:994
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:1854
const std::vector< const Analyzer::ColumnVar * > rhs_join_cols_
Definition: RelAlgDag.h:1667
static std::unique_ptr< RelAlgDag > build(const rapidjson::Value &query_ast, RelAlgDag *root_dag, const bool optimize_dag)
Definition: RelAlgDag.cpp:3263
void setCollation(std::vector< SortField > &&collation)
Definition: RelAlgDag.h:1959
int32_t countRexLiteralArgs() const
Definition: RelAlgDag.cpp:697
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1924
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:1625
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:998
const RexWindowBound & getFrameStartBound() const
Definition: RelAlgDag.h:656
std::unique_ptr< Hints > hints_
Definition: RelAlgDag.h:1314
void addHint(const ExplainedQueryHint &hint_explained)
Definition: RelAlgDag.h:1019
const RexScalar * getOuterJoinCond() const
Definition: RelAlgDag.h:1631
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:1191
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
Definition: RelAlgDag.h:2530
JoinType join_type_
Definition: RelAlgDag.h:1551
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
Definition: RelAlgDag.h:1916
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:1914
static std::vector< std::shared_ptr< RelAlgNode > > & getNodes(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3009
void setSourceNode(const RelAlgNode *node) const
Definition: RelAlgDag.h:394
void resetQueryExecutionState()
Definition: RelAlgDag.h:851
bool hasWindowFunctionExpr() const
Definition: RelAlgDag.cpp:2761
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:1871
bool hint_applied_
Definition: RelAlgDag.h:1313
std::unordered_map< QueryHint, ExplainedQueryHint > Hints
Definition: QueryHint.h:355
size_t toHash() const override
Definition: RelAlgDag.h:2413
size_t collationCount() const
Definition: RelAlgDag.h:1952
bool is_agg_
Definition: RelAlgDag.h:1918
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:2093
virtual size_t size() const =0
const RelAlgNode * getSourceNode() const
Definition: RelAlgDag.h:389
std::vector< SortField > collation_
Definition: RelAlgDag.h:735
auto const isDeleteViaSelect() const
Definition: RelAlgDag.h:1089
bool operator==(const RelSort &that) const
Definition: RelAlgDag.h:1946
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:1873
const RelFilter * getOriginalFilter() const
size_t getLimit() const
Definition: RelAlgDag.h:1969
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1740
SQLTypeInfo type_
Definition: RelAlgDag.h:830
JoinType getJoinType() const
Definition: RelAlgDag.h:1636
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type, std::vector< RowValues > &values)
Definition: RelAlgDag.h:2394
std::string get_type_name() const
Definition: sqltypes.h:507
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:1047
void replaceOrderKey(size_t offset, std::unique_ptr< const RexScalar > &&new_order_key)
Definition: RelAlgDag.h:645
bool hasDeliveredHint()
Definition: RelAlgDag.h:1545
const size_t getNumShards() const
Definition: RelAlgDag.h:992
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:1397
RexFunctionOperator(const std::string &name, ConstRexScalarPtrVector &operands, const SQLTypeInfo &ti)
Definition: RelAlgDag.h:489
std::unique_ptr< const RexScalar > condition_
Definition: RelAlgDag.h:1782
void replaceOperands(std::vector< std::unique_ptr< const RexScalar >> &&new_operands)
Definition: RelAlgDag.h:650
const Catalog_Namespace::Catalog & getCatalog() const
Definition: RelAlgDag.h:2110
SortDirection sort_dir_
Definition: RelAlgDag.h:572
RexCase()=default
const RexScalar * getTableFuncInputAt(const size_t idx) const
Definition: RelAlgDag.h:2290
std::vector< RexLiteralArray > TupleContentsArray
Definition: RelAlgDag.h:253
void eachNode(std::function< void(RelAlgNode const *)> const &) const
Definition: RelAlgDag.cpp:3340
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:2254
std::string getFunctionName() const
Definition: RelAlgDag.h:2275
void propagateModifyManipulationTarget(std::shared_ptr< RelProject > new_project_node) const
Definition: RelAlgDag.h:1174
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1236
std::optional< bool > use_loop_join
Definition: QueryHint.h:323
std::vector< const RexAgg * > getAggregatesAndRelease()
Definition: RelAlgDag.h:1353
const std::vector< std::string > & getFields() const
Definition: RelAlgDag.h:1218
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:3290
const RexScalar * getValueAt(const size_t row_idx, const size_t col_idx) const
Definition: RelAlgDag.h:2429
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:2243
#define CHECK(condition)
Definition: Logger.h:291
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
auto const isUpdateViaSelect() const
Definition: RelAlgDag.h:1088
RexRef()
Definition: RelAlgDag.h:748
const std::string op_typeinfo_
Definition: RelAlgDag.h:1674
unsigned id_
Definition: RelAlgDag.h:953
std::string name_
Definition: RelAlgDag.h:525
const Catalog_Namespace::Catalog & catalog_
Definition: RelAlgDag.h:1049
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:2402
void setModifiedTableCatalog(const Catalog_Namespace::Catalog *catalog) const
Definition: RelAlgDag.h:1084
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:1219
const RexAgg * getAggExpr(size_t i) const
Definition: RelAlgDag.h:1877
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:2994
std::shared_ptr< RelAlgNode > deepCopy() const override
Definition: RelAlgDag.h:1884
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:2022
bool isRows() const
Definition: RelAlgDag.h:660
void injectOffsetInFragmentExpr() const
Definition: RelAlgDag.h:1302
const size_t getNumFragments() const
Definition: RelAlgDag.h:990
size_t getAggExprSize() const
Definition: RelAlgDag.h:1875
virtual size_t toHash() const =0
std::string getQualifier() const
Definition: RelAlgDag.h:1633
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:502
RexLiteral(const SQLTypes target_type)
Definition: RelAlgDag.h:176
QueryNotSupported(const std::string &reason)
Definition: RelAlgDag.h:2493
RexAgg()
Definition: RelAlgDag.h:778
SQLTypes type_
Definition: RelAlgDag.h:242
Definition: sqltypes.h:62
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.cpp:3377
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:1710
size_t size() const override
Definition: RelAlgDag.h:984
std::vector< std::unique_ptr< const RexScalar >> RowValues
Definition: RelAlgDag.h:2389
size_t toHash() const override
Definition: RelAlgDag.h:2001
const size_t getAggExprsCount() const
Definition: RelAlgDag.h:1344
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:1090
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:1474
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:1506
void setFields(std::vector< std::string > &&new_fields)
Definition: RelAlgDag.h:1347
const QueryHint getHint() const
Definition: QueryHint.h:154
SQLTypes getType() const
Definition: RelAlgDag.h:192
size_t size() const override
Definition: RelAlgDag.h:1705
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
Definition: RelAlgDag.h:876
const TableDescriptor * getTableDescriptor() const
Definition: RelAlgDag.h:986
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:2244
TableDescriptor const * table_descriptor_
Definition: RelAlgDag.h:1117
void setAggExprs(std::vector< std::unique_ptr< const RexAgg >> &agg_exprs)
Definition: RelAlgDag.h:1369
std::vector< std::string > fields_
Definition: RelAlgDag.h:1444
JoinType getJoinType() const
Definition: RelAlgDag.h:1470
bool hasContextData() const
Definition: RelAlgDag.h:886
bool isLimitDelivered() const
Definition: RelAlgDag.h:1967
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:1562
BuildState build_state_
Definition: RelAlgDag.h:2984
size_t getFilterCondSize() const
Definition: RelAlgDag.h:1627
const bool hasHintEnabled(QueryHint candidate_hint) const
Definition: RelAlgDag.h:1276
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:679
has_pushed_down_window_expr_
Definition: RelAlgDag.h:1135
size_t toHash() const override
Definition: RelAlgDag.cpp:3427
NullSortedPosition
Definition: RelAlgDag.h:532
const ExplainedQueryHint & getHintInfo(QueryHint hint) const
Definition: RelAlgDag.h:1430
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:2318
unsigned getTargetPrecision() const
Definition: RelAlgDag.h:202
virtual size_t toHash() const =0
#define VLOG(n)
Definition: Logger.h:387
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(), const Catalog_Namespace::Catalog *catalog=nullptr)
Definition: RelAlgDag.h:1056
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:1456
BuildState getBuildState() const
Definition: RelAlgDag.h:2507
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:2078
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:2279
std::string toString(RelRexToStringConfig config=RelRexToStringConfig::defaults()) const override
Definition: RelAlgDag.h:2322
RexRef(const size_t index)
Definition: RelAlgDag.h:750
std::vector< TargetMetaInfo > tuple_type_
Definition: RelAlgDag.h:2455
TableDescriptor const * getModifiedTableDescriptor() const
Definition: RelAlgDag.h:1076
void registerQueryHints(std::shared_ptr< RelAlgNode > node, Hints *hints_delivered, RegisteredQueryHint &global_query_hint)
Definition: RelAlgDag.h:2542
void setCondition(std::unique_ptr< const RexScalar > &condition)
Definition: RelAlgDag.h:1645
bool isIdentity() const
Definition: RelAlgDag.cpp:439
const std::string getFieldName(const size_t i) const
Definition: RelAlgDag.h:1351
const RexScalar * getScalarSource(const size_t i) const
Definition: RelAlgDag.h:1862
constexpr auto is_datetime(SQLTypes type)
Definition: sqltypes.h:315
const bool hasHintEnabled(QueryHint candidate_hint) const
Definition: RelAlgDag.h:1895
size_t toHash() const override
Definition: RelAlgDag.h:2148
std::vector< std::unique_ptr< const RexScalar > > target_exprs_
Definition: RelAlgDag.h:2381
Hints * getDeliveredHints()
Definition: RelAlgDag.h:1547
const Catalog_Namespace::Catalog * getModifiedTableCatalog() const
Definition: RelAlgDag.h:1082
size_t toHash() const override
Definition: RelAlgDag.h:2353
static void setBuildState(RelAlgDag &rel_alg_dag, const RelAlgDag::BuildState build_state)
Definition: RelAlgDag.h:3023
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
Definition: RelAlgDag.h:1104
static void resetRelAlgFirstId() noexcept
Definition: RelAlgDag.cpp:46