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