OmniSciDB  94e8789169
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RelAlgDagBuilder.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
22 #pragma once
23 
24 #include <atomic>
25 #include <iterator>
26 #include <memory>
27 #include <unordered_map>
28 
29 #include <rapidjson/document.h>
30 #include <boost/core/noncopyable.hpp>
31 
32 #include "Catalog/Catalog.h"
33 #include "QueryEngine/QueryHint.h"
37 #include "Shared/toString.h"
38 #include "Utils/FsiUtils.h"
39 
40 using ColumnNameList = std::vector<std::string>;
41 
42 class Rex {
43  public:
44  virtual std::string toString() const = 0;
45 
46  virtual ~Rex() {}
47 };
48 
49 class RexScalar : public Rex {};
50 // For internal use of the abstract interpreter only. The result after abstract
51 // interpretation will not have any references to 'RexAbstractInput' objects.
52 class RexAbstractInput : public RexScalar {
53  public:
54  RexAbstractInput(const unsigned in_index) : in_index_(in_index) {}
55 
56  unsigned getIndex() const { return in_index_; }
57 
58  void setIndex(const unsigned in_index) const { in_index_ = in_index; }
59 
60  std::string toString() const override {
61  return cat(::typeName(this), "(", std::to_string(in_index_), ")");
62  }
63 
64  private:
65  mutable unsigned in_index_;
66 };
67 
68 class RexLiteral : public RexScalar {
69  public:
70  RexLiteral(const int64_t val,
71  const SQLTypes type,
72  const SQLTypes target_type,
73  const unsigned scale,
74  const unsigned precision,
75  const unsigned type_scale,
76  const unsigned type_precision)
77  : literal_(val)
78  , type_(type)
79  , target_type_(target_type)
80  , scale_(scale)
81  , precision_(precision)
82  , type_scale_(type_scale)
83  , type_precision_(type_precision) {
84  CHECK(type == kDECIMAL || type == kINTERVAL_DAY_TIME ||
85  type == kINTERVAL_YEAR_MONTH || is_datetime(type) || type == kBIGINT ||
86  type == kINT);
87  }
88 
89  RexLiteral(const double val,
90  const SQLTypes type,
91  const SQLTypes target_type,
92  const unsigned scale,
93  const unsigned precision,
94  const unsigned type_scale,
95  const unsigned type_precision)
96  : literal_(val)
97  , type_(type)
98  , target_type_(target_type)
99  , scale_(scale)
100  , precision_(precision)
101  , type_scale_(type_scale)
102  , type_precision_(type_precision) {
103  CHECK_EQ(kDOUBLE, type);
104  }
105 
106  RexLiteral(const std::string& val,
107  const SQLTypes type,
108  const SQLTypes target_type,
109  const unsigned scale,
110  const unsigned precision,
111  const unsigned type_scale,
112  const unsigned type_precision)
113  : literal_(val)
114  , type_(type)
115  , target_type_(target_type)
116  , scale_(scale)
117  , precision_(precision)
118  , type_scale_(type_scale)
119  , type_precision_(type_precision) {
120  CHECK_EQ(kTEXT, type);
121  }
122 
123  RexLiteral(const bool val,
124  const SQLTypes type,
125  const SQLTypes target_type,
126  const unsigned scale,
127  const unsigned precision,
128  const unsigned type_scale,
129  const unsigned type_precision)
130  : literal_(val)
131  , type_(type)
132  , target_type_(target_type)
133  , scale_(scale)
134  , precision_(precision)
135  , type_scale_(type_scale)
136  , type_precision_(type_precision) {
137  CHECK_EQ(kBOOLEAN, type);
138  }
139 
140  RexLiteral(const SQLTypes target_type)
141  : literal_(nullptr)
142  , type_(kNULLT)
143  , target_type_(target_type)
144  , scale_(0)
145  , precision_(0)
146  , type_scale_(0)
147  , type_precision_(0) {}
148 
149  template <class T>
150  T getVal() const {
151  const auto ptr = boost::get<T>(&literal_);
152  CHECK(ptr);
153  return *ptr;
154  }
155 
156  SQLTypes getType() const { return type_; }
157 
158  SQLTypes getTargetType() const { return target_type_; }
159 
160  unsigned getScale() const { return scale_; }
161 
162  unsigned getPrecision() const { return precision_; }
163 
164  unsigned getTypeScale() const { return type_scale_; }
165 
166  unsigned getTypePrecision() const { return type_precision_; }
167 
168  std::string toString() const override {
169  return cat(::typeName(this),
170  "(",
171  boost::lexical_cast<std::string>(literal_),
172  ", type=",
173  (type_ == kNULLT ? "null" : ::toString(type_)),
174  ", target_type=",
175  (target_type_ == kNULLT ? "null" : ::toString(target_type_)),
176  ")");
177  }
178 
179  std::unique_ptr<RexLiteral> deepCopy() const {
180  switch (literal_.which()) {
181  case 0: {
182  int64_t val = getVal<int64_t>();
183  return std::make_unique<RexLiteral>(
185  }
186  case 1: {
187  double val = getVal<double>();
188  return std::make_unique<RexLiteral>(
190  }
191  case 2: {
192  auto val = getVal<std::string>();
193  return std::make_unique<RexLiteral>(
195  }
196  case 3: {
197  bool val = getVal<bool>();
198  return std::make_unique<RexLiteral>(
200  }
201  case 4: {
202  return std::make_unique<RexLiteral>(target_type_);
203  }
204  default:
205  CHECK(false);
206  }
207  return nullptr;
208  }
209 
210  private:
211  const boost::variant<int64_t, double, std::string, bool, void*> literal_;
214  const unsigned scale_;
215  const unsigned precision_;
216  const unsigned type_scale_;
217  const unsigned type_precision_;
218 };
219 
220 using RexLiteralArray = std::vector<RexLiteral>;
221 using TupleContentsArray = std::vector<RexLiteralArray>;
222 
223 class RexOperator : public RexScalar {
224  public:
225  RexOperator(const SQLOps op,
226  std::vector<std::unique_ptr<const RexScalar>>& operands,
227  const SQLTypeInfo& type)
228  : op_(op), operands_(std::move(operands)), type_(type) {}
229 
230  virtual std::unique_ptr<const RexOperator> getDisambiguated(
231  std::vector<std::unique_ptr<const RexScalar>>& operands) const {
232  return std::unique_ptr<const RexOperator>(new RexOperator(op_, operands, type_));
233  }
234 
235  size_t size() const { return operands_.size(); }
236 
237  const RexScalar* getOperand(const size_t idx) const {
238  CHECK(idx < operands_.size());
239  return operands_[idx].get();
240  }
241 
242  const RexScalar* getOperandAndRelease(const size_t idx) const {
243  CHECK(idx < operands_.size());
244  return operands_[idx].release();
245  }
246 
247  SQLOps getOperator() const { return op_; }
248 
249  const SQLTypeInfo& getType() const { return type_; }
250 
251  std::string toString() const override {
252  return cat(::typeName(this),
253  "(",
255  ", operands=",
256  ::toString(operands_),
257  ", type=",
258  type_.to_string(),
259  ")");
260  };
261 
262  protected:
263  const SQLOps op_;
264  mutable std::vector<std::unique_ptr<const RexScalar>> operands_;
266 };
267 
268 class RelAlgNode;
269 using RelAlgInputs = std::vector<std::shared_ptr<const RelAlgNode>>;
270 
271 class ExecutionResult;
272 
273 class RexSubQuery : public RexScalar {
274  public:
275  RexSubQuery(const std::shared_ptr<const RelAlgNode> ra)
276  : type_(new SQLTypeInfo(kNULLT, false))
277  , result_(new std::shared_ptr<const ExecutionResult>(nullptr))
278  , ra_(ra) {}
279 
280  // for deep copy
281  RexSubQuery(std::shared_ptr<SQLTypeInfo> type,
282  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result,
283  const std::shared_ptr<const RelAlgNode> ra)
284  : type_(type), result_(result), ra_(ra) {}
285 
286  RexSubQuery(const RexSubQuery&) = delete;
287 
288  RexSubQuery& operator=(const RexSubQuery&) = delete;
289 
290  RexSubQuery(RexSubQuery&&) = delete;
291 
292  RexSubQuery& operator=(RexSubQuery&&) = delete;
293 
294  const SQLTypeInfo& getType() const {
295  CHECK_NE(kNULLT, type_->get_type());
296  return *(type_.get());
297  }
298 
299  std::shared_ptr<const ExecutionResult> getExecutionResult() const {
300  CHECK(result_);
301  CHECK(result_.get());
302  return *(result_.get());
303  }
304 
305  unsigned getId() const;
306 
307  const RelAlgNode* getRelAlg() const { return ra_.get(); }
308 
309  std::string toString() const override;
310 
311  std::unique_ptr<RexSubQuery> deepCopy() const;
312 
313  void setExecutionResult(const std::shared_ptr<const ExecutionResult> result);
314 
315  private:
316  std::shared_ptr<SQLTypeInfo> type_;
317  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result_;
318  const std::shared_ptr<const RelAlgNode> ra_;
319 };
320 
321 // The actual input node understood by the Executor.
322 // The in_index_ is relative to the output of node_.
323 class RexInput : public RexAbstractInput {
324  public:
325  RexInput(const RelAlgNode* node, const unsigned in_index)
326  : RexAbstractInput(in_index), node_(node) {}
327 
328  const RelAlgNode* getSourceNode() const { return node_; }
329 
330  // This isn't great, but we need it for coalescing nodes to Compound since
331  // RexInput in descendents need to be rebound to the newly created Compound.
332  // Maybe create a fresh RA tree with the required changes after each coalescing?
333  void setSourceNode(const RelAlgNode* node) const { node_ = node; }
334 
335  bool operator==(const RexInput& that) const {
336  return getSourceNode() == that.getSourceNode() && getIndex() == that.getIndex();
337  }
338 
339  std::string toString() const override;
340 
341  std::unique_ptr<RexInput> deepCopy() const {
342  return std::make_unique<RexInput>(node_, getIndex());
343  }
344 
345  private:
346  mutable const RelAlgNode* node_;
347 };
348 
349 namespace std {
350 
351 template <>
352 struct hash<RexInput> {
353  size_t operator()(const RexInput& rex_in) const {
354  auto addr = rex_in.getSourceNode();
355  return *reinterpret_cast<const size_t*>(may_alias_ptr(&addr)) ^ rex_in.getIndex();
356  }
357 };
358 
359 } // namespace std
360 
361 // Not a real node created by Calcite. Created by us because CaseExpr is a node in our
362 // Analyzer.
363 class RexCase : public RexScalar {
364  public:
365  RexCase(std::vector<std::pair<std::unique_ptr<const RexScalar>,
366  std::unique_ptr<const RexScalar>>>& expr_pair_list,
367  std::unique_ptr<const RexScalar>& else_expr)
368  : expr_pair_list_(std::move(expr_pair_list)), else_expr_(std::move(else_expr)) {}
369 
370  size_t branchCount() const { return expr_pair_list_.size(); }
371 
372  const RexScalar* getWhen(const size_t idx) const {
373  CHECK(idx < expr_pair_list_.size());
374  return expr_pair_list_[idx].first.get();
375  }
376 
377  const RexScalar* getThen(const size_t idx) const {
378  CHECK(idx < expr_pair_list_.size());
379  return expr_pair_list_[idx].second.get();
380  }
381 
382  const RexScalar* getElse() const { return else_expr_.get(); }
383 
384  std::string toString() const override {
385  return cat(::typeName(this),
386  "(expr_pair_list=",
388  ", else_expr=",
389  (else_expr_ ? else_expr_->toString() : "null"),
390  ")");
391  }
392 
393  private:
394  std::vector<
395  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
397  std::unique_ptr<const RexScalar> else_expr_;
398 };
399 
401  public:
402  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
403  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
404 
405  RexFunctionOperator(const std::string& name,
406  ConstRexScalarPtrVector& operands,
407  const SQLTypeInfo& ti)
408  : RexOperator(kFUNCTION, operands, ti), name_(name) {}
409 
410  std::unique_ptr<const RexOperator> getDisambiguated(
411  std::vector<std::unique_ptr<const RexScalar>>& operands) const override {
412  return std::unique_ptr<const RexOperator>(
413  new RexFunctionOperator(name_, operands, getType()));
414  }
415 
416  const std::string& getName() const { return name_; }
417 
418  std::string toString() const override {
419  return cat(::typeName(this), "(", name_, ", operands=", ::toString(operands_), ")");
420  }
421 
422  private:
423  const std::string name_;
424 };
425 
427 
428 enum class NullSortedPosition { First, Last };
429 
430 class SortField {
431  public:
432  SortField(const size_t field,
433  const SortDirection sort_dir,
434  const NullSortedPosition nulls_pos)
435  : field_(field), sort_dir_(sort_dir), nulls_pos_(nulls_pos) {}
436 
437  bool operator==(const SortField& that) const {
438  return field_ == that.field_ && sort_dir_ == that.sort_dir_ &&
439  nulls_pos_ == that.nulls_pos_;
440  }
441 
442  size_t getField() const { return field_; }
443 
444  SortDirection getSortDir() const { return sort_dir_; }
445 
447 
448  std::string toString() const {
449  return cat(::typeName(this),
450  "(",
452  ", sort_dir=",
453  (sort_dir_ == SortDirection::Ascending ? "asc" : "desc"),
454  ", null_pos=",
455  (nulls_pos_ == NullSortedPosition::First ? "nulls_first" : "nulls_last"),
456  ")");
457  }
458 
459  private:
460  const size_t field_;
463 };
464 
466  public:
467  struct RexWindowBound {
468  bool unbounded;
469  bool preceding;
470  bool following;
472  std::shared_ptr<const RexScalar> offset;
474  };
475 
477  ConstRexScalarPtrVector& operands,
478  ConstRexScalarPtrVector& partition_keys,
479  ConstRexScalarPtrVector& order_keys,
480  const std::vector<SortField> collation,
483  const bool is_rows,
484  const SQLTypeInfo& ti)
485  : RexFunctionOperator(::toString(kind), operands, ti)
486  , kind_(kind)
487  , partition_keys_(std::move(partition_keys))
488  , order_keys_(std::move(order_keys))
489  , collation_(collation)
490  , lower_bound_(lower_bound)
491  , upper_bound_(upper_bound)
492  , is_rows_(is_rows) {}
493 
494  SqlWindowFunctionKind getKind() const { return kind_; }
495 
497 
499  return std::move(partition_keys_);
500  }
501 
503  return std::move(order_keys_);
504  }
505 
507 
508  const std::vector<SortField>& getCollation() const { return collation_; }
509 
510  const RexWindowBound& getLowerBound() const { return lower_bound_; }
511 
512  const RexWindowBound& getUpperBound() const { return upper_bound_; }
513 
514  bool isRows() const { return is_rows_; }
515 
516  std::unique_ptr<const RexOperator> disambiguatedOperands(
517  ConstRexScalarPtrVector& operands,
518  ConstRexScalarPtrVector& partition_keys,
519  ConstRexScalarPtrVector& order_keys,
520  const std::vector<SortField>& collation) const {
521  return std::unique_ptr<const RexOperator>(
523  operands,
524  partition_keys,
525  order_keys,
526  collation,
527  getLowerBound(),
528  getUpperBound(),
529  isRows(),
530  getType()));
531  }
532 
533  std::string toString() const override {
534  return cat(::typeName(this),
535  "(",
536  getName(),
537  ", operands=",
538  ::toString(operands_),
539  ", partition_keys=",
541  ", order_keys=",
543  ")");
544  }
545 
546  private:
550  const std::vector<SortField> collation_;
553  const bool is_rows_;
554 };
555 
556 // Not a real node created by Calcite. Created by us because targets of a query
557 // should reference the group by expressions instead of creating completely new one.
558 class RexRef : public RexScalar {
559  public:
560  RexRef(const size_t index) : index_(index) {}
561 
562  size_t getIndex() const { return index_; }
563 
564  std::string toString() const override {
565  return cat(::typeName(this), "(", std::to_string(index_), ")");
566  }
567 
568  std::unique_ptr<RexRef> deepCopy() const { return std::make_unique<RexRef>(index_); }
569 
570  private:
571  const size_t index_;
572 };
573 
574 class RexAgg : public Rex {
575  public:
576  RexAgg(const SQLAgg agg,
577  const bool distinct,
578  const SQLTypeInfo& type,
579  const std::vector<size_t>& operands)
580  : agg_(agg), distinct_(distinct), type_(type), operands_(operands) {}
581 
582  std::string toString() const override {
583  return cat(::typeName(this),
584  "(agg=",
586  ", distinct=",
588  ", type=",
590  ", operands=",
592  ")");
593  }
594 
595  SQLAgg getKind() const { return agg_; }
596 
597  bool isDistinct() const { return distinct_; }
598 
599  size_t size() const { return operands_.size(); }
600 
601  size_t getOperand(size_t idx) const { return operands_[idx]; }
602 
603  const SQLTypeInfo& getType() const { return type_; }
604 
605  std::unique_ptr<RexAgg> deepCopy() const {
606  return std::make_unique<RexAgg>(agg_, distinct_, type_, operands_);
607  }
608 
609  private:
610  const SQLAgg agg_;
611  const bool distinct_;
613  const std::vector<size_t> operands_;
614 };
615 
617  public:
618  HintExplained(std::string hint_name,
619  bool query_hint,
620  bool is_marker,
621  bool has_kv_type_options)
622  : hint_name_(hint_name)
623  , query_hint_(query_hint)
624  , is_marker_(is_marker)
625  , has_kv_type_options_(has_kv_type_options) {}
626 
627  HintExplained(std::string hint_name,
628  bool query_hint,
629  bool is_marker,
630  bool has_kv_type_options,
631  std::vector<std::string>& list_options)
632  : hint_name_(hint_name)
633  , query_hint_(query_hint)
634  , is_marker_(is_marker)
635  , has_kv_type_options_(has_kv_type_options)
636  , list_options_(std::move(list_options)) {}
637 
638  HintExplained(std::string hint_name,
639  bool query_hint,
640  bool is_marker,
641  bool has_kv_type_options,
642  std::unordered_map<std::string, std::string>& kv_options)
643  : hint_name_(hint_name)
644  , query_hint_(query_hint)
645  , is_marker_(is_marker)
646  , has_kv_type_options_(has_kv_type_options)
647  , kv_options_(std::move(kv_options)) {}
648 
649  void setListOptions(std::vector<std::string>& list_options) {
650  list_options_ = list_options;
651  }
652 
653  void setKVOptions(std::unordered_map<std::string, std::string>& kv_options) {
654  kv_options_ = kv_options;
655  }
656 
657  void setInheritPaths(std::vector<int>& interit_paths) {
658  inherit_paths_ = interit_paths;
659  }
660 
661  const std::vector<std::string>& getListOptions() { return list_options_; }
662 
663  const std::vector<int>& getInteritPath() { return inherit_paths_; }
664 
665  const std::unordered_map<std::string, std::string>& getKVOptions() {
666  return kv_options_;
667  }
668 
669  const std::string& getHintName() const { return hint_name_; }
670 
671  bool isQueryHint() const { return query_hint_; }
672 
673  bool hasOptions() const { return is_marker_; }
674 
675  bool hasKvOptions() const { return has_kv_type_options_; }
676 
677  private:
678  std::string hint_name_;
679  // Set true if this hint affects globally
680  // Otherwise it just affects the node which this hint is included (aka table hint)
682  // set true if this has no extra options (neither list_options nor kv_options)
684  // Set true if it is not a marker and has key-value type options
685  // Otherwise (it is not a marker but has list type options), we set this be false
687  std::vector<int> inherit_paths_; // currently not used
688  std::vector<std::string> list_options_;
689  std::unordered_map<std::string, std::string> kv_options_;
690 };
691 
692 // a map from hint_name to its detailed info
693 using Hints = std::unordered_map<std::string, HintExplained>;
694 
695 class RelAlgNode {
696  public:
698  : inputs_(std::move(inputs))
699  , id_(crt_id_++)
700  , context_data_(nullptr)
701  , is_nop_(false) {}
702 
703  virtual ~RelAlgNode() {}
704 
706  context_data_ = nullptr;
707  targets_metainfo_ = {};
708  }
709 
710  void setContextData(const void* context_data) const {
712  context_data_ = context_data;
713  }
714 
715  void setOutputMetainfo(const std::vector<TargetMetaInfo>& targets_metainfo) const {
716  targets_metainfo_ = targets_metainfo;
717  }
718 
719  const std::vector<TargetMetaInfo>& getOutputMetainfo() const {
720  return targets_metainfo_;
721  }
722 
723  unsigned getId() const { return id_; }
724 
725  bool hasContextData() const { return !(context_data_ == nullptr); }
726 
727  const void* getContextData() const {
729  return context_data_;
730  }
731 
732  const size_t inputCount() const { return inputs_.size(); }
733 
734  const RelAlgNode* getInput(const size_t idx) const {
735  CHECK_LT(idx, inputs_.size());
736  return inputs_[idx].get();
737  }
738 
739  std::shared_ptr<const RelAlgNode> getAndOwnInput(const size_t idx) const {
740  CHECK_LT(idx, inputs_.size());
741  return inputs_[idx];
742  }
743 
744  void addManagedInput(std::shared_ptr<const RelAlgNode> input) {
745  inputs_.push_back(input);
746  }
747 
748  bool hasInput(const RelAlgNode* needle) const {
749  for (auto& input_ptr : inputs_) {
750  if (input_ptr.get() == needle) {
751  return true;
752  }
753  }
754  return false;
755  }
756 
757  virtual void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
758  std::shared_ptr<const RelAlgNode> input) {
759  for (auto& input_ptr : inputs_) {
760  if (input_ptr == old_input) {
761  input_ptr = input;
762  break;
763  }
764  }
765  }
766 
767  bool isNop() const { return is_nop_; }
768 
769  void markAsNop() { is_nop_ = true; }
770 
771  virtual std::string toString() const = 0;
772 
773  virtual size_t size() const = 0;
774 
775  virtual std::shared_ptr<RelAlgNode> deepCopy() const = 0;
776 
777  static void resetRelAlgFirstId() noexcept;
778 
783  void clearContextData() const { context_data_ = nullptr; }
784 
785  protected:
787  const unsigned id_;
788 
789  private:
790  mutable const void* context_data_;
791  bool is_nop_;
792  mutable std::vector<TargetMetaInfo> targets_metainfo_;
793  static thread_local unsigned crt_id_;
794 };
795 
796 class RelScan : public RelAlgNode {
797  public:
798  RelScan(const TableDescriptor* td, const std::vector<std::string>& field_names)
799  : td_(td)
800  , field_names_(field_names)
802  , hints_(std::make_unique<Hints>()) {}
803 
804  size_t size() const override { return field_names_.size(); }
805 
806  const TableDescriptor* getTableDescriptor() const { return td_; }
807 
808  const std::vector<std::string>& getFieldNames() const { return field_names_; }
809 
810  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
811 
812  std::string toString() const override {
813  return cat(
814  ::typeName(this), "(", td_->tableName, ", ", ::toString(field_names_), ")");
815  }
816 
817  std::shared_ptr<RelAlgNode> deepCopy() const override {
818  CHECK(false);
819  return nullptr;
820  };
821 
822  void addHint(const HintExplained& hint_explained) {
823  if (!hint_applied_) {
824  hint_applied_ = true;
825  }
826  hints_->emplace(hint_explained.getHintName(), hint_explained);
827  }
828 
829  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
830  if (hint_applied_ && !hints_->empty()) {
831  return hints_->find(candidate_hint_name) != hints_->end();
832  }
833  return false;
834  }
835 
836  const HintExplained& getHintInfo(const std::string& hint_name) const {
838  CHECK(!hints_->empty());
839  CHECK(hasHintEnabled(hint_name));
840  return hints_->at(hint_name);
841  }
842 
843  bool hasDeliveredHint() { return !hints_->empty(); }
844 
845  Hints* getDeliveredHints() { return hints_.get(); }
846 
847  private:
849  const std::vector<std::string> field_names_;
851  std::unique_ptr<Hints> hints_;
852 };
853 
855  public:
856  ModifyManipulationTarget(bool const update_via_select = false,
857  bool const delete_via_select = false,
858  bool const varlen_update_required = false,
859  TableDescriptor const* table_descriptor = nullptr,
860  ColumnNameList target_columns = ColumnNameList())
861  : is_update_via_select_(update_via_select)
862  , is_delete_via_select_(delete_via_select)
863  , varlen_update_required_(varlen_update_required)
864  , table_descriptor_(table_descriptor)
865  , target_columns_(target_columns) {}
866 
871  }
872 
875  table_descriptor_ = td;
876  }
877 
878  auto const isUpdateViaSelect() const { return is_update_via_select_; }
879  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
880  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
881 
882  void setTargetColumns(ColumnNameList const& target_columns) const {
883  target_columns_ = target_columns;
884  }
886 
887  template <typename VALIDATION_FUNCTOR>
888  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
889  for (auto const& column_name : target_columns_) {
890  if (validator(column_name) == false) {
891  return false;
892  }
893  }
894  return true;
895  }
896 
897  private:
898  mutable bool is_update_via_select_ = false;
899  mutable bool is_delete_via_select_ = false;
900  mutable bool varlen_update_required_ = false;
901  mutable TableDescriptor const* table_descriptor_ = nullptr;
903 };
904 
906  public:
907  friend class RelModify;
908  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
909  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
910 
911  // Takes memory ownership of the expressions.
912  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
913  const std::vector<std::string>& fields,
914  std::shared_ptr<const RelAlgNode> input)
916  , scalar_exprs_(std::move(scalar_exprs))
917  , fields_(fields)
919  , hints_(std::make_unique<Hints>()) {
920  inputs_.push_back(input);
921  }
922 
923  RelProject(RelProject const&);
924 
925  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
926  scalar_exprs_ = std::move(exprs);
927  }
928 
929  // True iff all the projected expressions are inputs. If true,
930  // this node can be elided and merged into the previous node
931  // since it's just a subset and / or permutation of its outputs.
932  bool isSimple() const {
933  for (const auto& expr : scalar_exprs_) {
934  if (!dynamic_cast<const RexInput*>(expr.get())) {
935  return false;
936  }
937  }
938  return true;
939  }
940 
941  bool isIdentity() const;
942 
943  bool isRenaming() const;
944 
945  size_t size() const override { return scalar_exprs_.size(); }
946 
947  const RexScalar* getProjectAt(const size_t idx) const {
948  CHECK(idx < scalar_exprs_.size());
949  return scalar_exprs_[idx].get();
950  }
951 
952  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
953  CHECK(idx < scalar_exprs_.size());
954  return scalar_exprs_[idx].release();
955  }
956 
957  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
958  return std::move(scalar_exprs_);
959  }
960 
961  const std::vector<std::string>& getFields() const { return fields_; }
962  void setFields(std::vector<std::string>& fields) { fields_ = std::move(fields); }
963 
964  const std::string getFieldName(const size_t i) const { return fields_[i]; }
965 
966  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
967  std::shared_ptr<const RelAlgNode> input) override {
968  replaceInput(old_input, input, std::nullopt);
969  }
970 
971  void replaceInput(
972  std::shared_ptr<const RelAlgNode> old_input,
973  std::shared_ptr<const RelAlgNode> input,
974  std::optional<std::unordered_map<unsigned, unsigned>> old_to_new_index_map);
975 
976  void appendInput(std::string new_field_name,
977  std::unique_ptr<const RexScalar> new_input);
978 
979  std::string toString() const override {
980  return cat(
981  ::typeName(this), "(", ::toString(scalar_exprs_), ", ", ::toString(fields_), ")");
982  }
983 
984  std::shared_ptr<RelAlgNode> deepCopy() const override {
985  return std::make_shared<RelProject>(*this);
986  }
987 
988  bool hasWindowFunctionExpr() const;
989 
990  void addHint(const HintExplained& hint_explained) {
991  if (!hint_applied_) {
992  hint_applied_ = true;
993  }
994  hints_->emplace(hint_explained.getHintName(), hint_explained);
995  }
996 
997  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
998  if (hint_applied_ && !hints_->empty()) {
999  return hints_->find(candidate_hint_name) != hints_->end();
1000  }
1001  return false;
1002  }
1003 
1004  const HintExplained& getHintInfo(const std::string& hint_name) const {
1006  CHECK(!hints_->empty());
1007  CHECK(hasHintEnabled(hint_name));
1008  return hints_->at(hint_name);
1009  }
1010 
1011  bool hasDeliveredHint() { return !hints_->empty(); }
1012 
1013  Hints* getDeliveredHints() { return hints_.get(); }
1014 
1015  private:
1016  template <typename EXPR_VISITOR_FUNCTOR>
1017  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
1018  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
1019  visitor_functor(i);
1020  }
1021  }
1022 
1025  scalar_exprs_.emplace_back(std::make_unique<RexFunctionOperator const>(
1026  std::string("OFFSET_IN_FRAGMENT"), transient_vector, SQLTypeInfo(kINT, false)));
1027  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
1028  }
1029 
1030  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
1031  mutable std::vector<std::string> fields_;
1033  std::unique_ptr<Hints> hints_;
1034 };
1035 
1036 class RelAggregate : public RelAlgNode {
1037  public:
1038  // Takes ownership of the aggregate expressions.
1039  RelAggregate(const size_t groupby_count,
1040  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
1041  const std::vector<std::string>& fields,
1042  std::shared_ptr<const RelAlgNode> input)
1043  : groupby_count_(groupby_count)
1044  , agg_exprs_(std::move(agg_exprs))
1045  , fields_(fields)
1046  , hint_applied_(false)
1047  , hints_(std::make_unique<Hints>()) {
1048  inputs_.push_back(input);
1049  }
1050 
1051  RelAggregate(RelAggregate const&);
1052 
1053  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
1054 
1055  const size_t getGroupByCount() const { return groupby_count_; }
1056 
1057  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
1058 
1059  const std::vector<std::string>& getFields() const { return fields_; }
1060  void setFields(std::vector<std::string>& new_fields) {
1061  fields_ = std::move(new_fields);
1062  }
1063 
1064  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1065 
1066  std::vector<const RexAgg*> getAggregatesAndRelease() {
1067  std::vector<const RexAgg*> result;
1068  for (auto& agg_expr : agg_exprs_) {
1069  result.push_back(agg_expr.release());
1070  }
1071  return result;
1072  }
1073 
1074  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
1075  return std::move(agg_exprs_);
1076  }
1077 
1078  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
1079  return agg_exprs_;
1080  }
1081 
1082  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
1083  agg_exprs_ = std::move(agg_exprs);
1084  }
1085 
1086  std::string toString() const override {
1087  return cat(::typeName(this),
1088  "(",
1090  ", agg_exprs=",
1091  ::toString(agg_exprs_),
1092  ", fields=",
1093  ::toString(fields_),
1094  ", inputs=",
1095  ::toString(inputs_),
1096  ")");
1097  }
1098 
1099  std::shared_ptr<RelAlgNode> deepCopy() const override {
1100  return std::make_shared<RelAggregate>(*this);
1101  }
1102 
1103  void addHint(const HintExplained& hint_explained) {
1104  if (!hint_applied_) {
1105  hint_applied_ = true;
1106  }
1107  hints_->emplace(hint_explained.getHintName(), hint_explained);
1108  }
1109 
1110  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1111  if (hint_applied_ && !hints_->empty()) {
1112  return hints_->find(candidate_hint_name) != hints_->end();
1113  }
1114  return false;
1115  }
1116 
1117  const HintExplained& getHintInfo(const std::string& hint_name) const {
1119  CHECK(!hints_->empty());
1120  CHECK(hasHintEnabled(hint_name));
1121  return hints_->at(hint_name);
1122  }
1123 
1124  bool hasDeliveredHint() { return !hints_->empty(); }
1125 
1126  Hints* getDeliveredHints() { return hints_.get(); }
1127 
1128  private:
1129  const size_t groupby_count_;
1130  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1131  std::vector<std::string> fields_;
1133  std::unique_ptr<Hints> hints_;
1134 };
1135 
1136 class RelJoin : public RelAlgNode {
1137  public:
1138  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
1139  std::shared_ptr<const RelAlgNode> rhs,
1140  std::unique_ptr<const RexScalar>& condition,
1141  const JoinType join_type)
1142  : condition_(std::move(condition))
1143  , join_type_(join_type)
1144  , hint_applied_(false)
1145  , hints_(std::make_unique<Hints>()) {
1146  inputs_.push_back(lhs);
1147  inputs_.push_back(rhs);
1148  }
1149 
1150  RelJoin(RelJoin const&);
1151 
1152  JoinType getJoinType() const { return join_type_; }
1153 
1154  const RexScalar* getCondition() const { return condition_.get(); }
1155 
1156  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
1157 
1158  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1159  CHECK(condition);
1160  condition_ = std::move(condition);
1161  }
1162 
1163  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1164  std::shared_ptr<const RelAlgNode> input) override;
1165 
1166  std::string toString() const override {
1167  return cat(::typeName(this),
1168  "(",
1169  ::toString(inputs_),
1170  ", condition=",
1171  (condition_ ? condition_->toString() : "null"),
1172  ", join_type=",
1173  std::to_string(static_cast<int>(join_type_)));
1174  }
1175 
1176  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
1177 
1178  std::shared_ptr<RelAlgNode> deepCopy() const override {
1179  return std::make_shared<RelJoin>(*this);
1180  }
1181 
1182  void addHint(const HintExplained& hint_explained) {
1183  if (!hint_applied_) {
1184  hint_applied_ = true;
1185  }
1186  hints_->emplace(hint_explained.getHintName(), hint_explained);
1187  }
1188 
1189  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1190  if (hint_applied_ && !hints_->empty()) {
1191  return hints_->find(candidate_hint_name) != hints_->end();
1192  }
1193  return false;
1194  }
1195 
1196  const HintExplained& getHintInfo(const std::string& hint_name) const {
1198  CHECK(!hints_->empty());
1199  CHECK(hasHintEnabled(hint_name));
1200  return hints_->at(hint_name);
1201  }
1202 
1203  bool hasDeliveredHint() { return !hints_->empty(); }
1204 
1205  Hints* getDeliveredHints() { return hints_.get(); }
1206 
1207  private:
1208  mutable std::unique_ptr<const RexScalar> condition_;
1211  std::unique_ptr<Hints> hints_;
1212 };
1213 
1214 class RelFilter : public RelAlgNode {
1215  public:
1216  RelFilter(std::unique_ptr<const RexScalar>& filter,
1217  std::shared_ptr<const RelAlgNode> input)
1218  : filter_(std::move(filter)) {
1219  CHECK(filter_);
1220  inputs_.push_back(input);
1221  }
1222 
1223  RelFilter(RelFilter const&);
1224 
1225  const RexScalar* getCondition() const { return filter_.get(); }
1226 
1227  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
1228 
1229  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1230  CHECK(condition);
1231  filter_ = std::move(condition);
1232  }
1233 
1234  size_t size() const override { return inputs_[0]->size(); }
1235 
1236  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1237  std::shared_ptr<const RelAlgNode> input) override;
1238 
1239  std::string toString() const override {
1240  return cat(::typeName(this),
1241  "(",
1242  (filter_ ? filter_->toString() : "null"),
1243  ", ",
1244  ::toString(inputs_) + ")");
1245  }
1246 
1247  std::shared_ptr<RelAlgNode> deepCopy() const override {
1248  return std::make_shared<RelFilter>(*this);
1249  }
1250 
1251  private:
1252  std::unique_ptr<const RexScalar> filter_;
1253 };
1254 
1255 // Synthetic node to assist execution of left-deep join relational algebra.
1257  public:
1258  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1259  RelAlgInputs inputs,
1260  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1261 
1262  const RexScalar* getInnerCondition() const;
1263 
1264  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1265 
1266  std::string toString() const override;
1267 
1268  size_t size() const override;
1269 
1270  std::shared_ptr<RelAlgNode> deepCopy() const override;
1271 
1272  bool coversOriginalNode(const RelAlgNode* node) const;
1273 
1274  private:
1275  std::unique_ptr<const RexScalar> condition_;
1276  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
1277  const std::shared_ptr<RelFilter> original_filter_;
1278  const std::vector<std::shared_ptr<const RelJoin>> original_joins_;
1279 };
1280 
1281 // The 'RelCompound' node combines filter and on the fly aggregate computation.
1282 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
1283 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
1284 // which can be efficiently executed with no intermediate buffers.
1286  public:
1287  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
1288  // or aggregate expressions owned by 'agg_exprs_', with the arguments
1289  // owned by 'scalar_sources_'.
1290  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
1291  const std::vector<const Rex*>& target_exprs,
1292  const size_t groupby_count,
1293  const std::vector<const RexAgg*>& agg_exprs,
1294  const std::vector<std::string>& fields,
1295  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
1296  const bool is_agg,
1297  bool update_disguised_as_select = false,
1298  bool delete_disguised_as_select = false,
1299  bool varlen_update_required = false,
1300  TableDescriptor const* manipulation_target_table = nullptr,
1301  ColumnNameList target_columns = ColumnNameList())
1302  : ModifyManipulationTarget(update_disguised_as_select,
1303  delete_disguised_as_select,
1304  varlen_update_required,
1305  manipulation_target_table,
1306  target_columns)
1307  , filter_expr_(std::move(filter_expr))
1308  , groupby_count_(groupby_count)
1309  , fields_(fields)
1310  , is_agg_(is_agg)
1311  , scalar_sources_(std::move(scalar_sources))
1312  , target_exprs_(target_exprs)
1313  , hint_applied_(false)
1314  , hints_(std::make_unique<Hints>()) {
1315  CHECK_EQ(fields.size(), target_exprs.size());
1316  for (auto agg_expr : agg_exprs) {
1317  agg_exprs_.emplace_back(agg_expr);
1318  }
1319  }
1320 
1321  RelCompound(RelCompound const&);
1322 
1323  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1324  std::shared_ptr<const RelAlgNode> input) override;
1325 
1326  size_t size() const override { return target_exprs_.size(); }
1327 
1328  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
1329 
1330  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
1331  filter_expr_ = std::move(new_expr);
1332  }
1333 
1334  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
1335 
1336  const std::vector<std::string>& getFields() const { return fields_; }
1337 
1338  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1339 
1340  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
1341 
1342  const RexScalar* getScalarSource(const size_t i) const {
1343  return scalar_sources_[i].get();
1344  }
1345 
1346  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
1347  CHECK_EQ(new_sources.size(), scalar_sources_.size());
1348  scalar_sources_ = std::move(new_sources);
1349  }
1350 
1351  const size_t getGroupByCount() const { return groupby_count_; }
1352 
1353  bool isAggregate() const { return is_agg_; }
1354 
1355  std::string toString() const override;
1356 
1357  std::shared_ptr<RelAlgNode> deepCopy() const override {
1358  return std::make_shared<RelCompound>(*this);
1359  }
1360 
1361  void addHint(const HintExplained& hint_explained) {
1362  if (!hint_applied_) {
1363  hint_applied_ = true;
1364  }
1365  hints_->emplace(hint_explained.getHintName(), hint_explained);
1366  }
1367 
1368  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1369  if (hint_applied_ && !hints_->empty()) {
1370  return hints_->find(candidate_hint_name) != hints_->end();
1371  }
1372  return false;
1373  }
1374 
1375  const HintExplained& getHintInfo(const std::string& hint_name) const {
1377  CHECK(!hints_->empty());
1378  CHECK(hasHintEnabled(hint_name));
1379  return hints_->at(hint_name);
1380  }
1381 
1382  bool hasDeliveredHint() { return !hints_->empty(); }
1383 
1384  Hints* getDeliveredHints() { return hints_.get(); }
1385 
1386  private:
1387  std::unique_ptr<const RexScalar> filter_expr_;
1388  const size_t groupby_count_;
1389  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1390  const std::vector<std::string> fields_;
1391  const bool is_agg_;
1392  std::vector<std::unique_ptr<const RexScalar>>
1393  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not actually
1394  // projected, just owned
1395  const std::vector<const Rex*> target_exprs_;
1397  std::unique_ptr<Hints> hints_;
1398 };
1399 
1400 class RelSort : public RelAlgNode {
1401  public:
1402  RelSort(const std::vector<SortField>& collation,
1403  const size_t limit,
1404  const size_t offset,
1405  std::shared_ptr<const RelAlgNode> input)
1406  : collation_(collation), limit_(limit), offset_(offset) {
1407  inputs_.push_back(input);
1408  }
1409 
1410  bool operator==(const RelSort& that) const {
1411  return limit_ == that.limit_ && offset_ == that.offset_ &&
1413  }
1414 
1415  size_t collationCount() const { return collation_.size(); }
1416 
1417  SortField getCollation(const size_t i) const {
1418  CHECK_LT(i, collation_.size());
1419  return collation_[i];
1420  }
1421 
1422  void setCollation(std::vector<SortField>&& collation) {
1423  collation_ = std::move(collation);
1424  }
1425 
1426  void setEmptyResult(bool emptyResult) { empty_result_ = emptyResult; }
1427 
1428  bool isEmptyResult() const { return empty_result_; }
1429 
1430  size_t getLimit() const { return limit_; }
1431 
1432  size_t getOffset() const { return offset_; }
1433 
1434  std::string toString() const override {
1435  return cat(::typeName(this),
1436  "(",
1437  "collation=",
1438  ::toString(collation_),
1439  ", limit=",
1441  ", offset",
1443  ", inputs=",
1444  ::toString(inputs_),
1445  ")");
1446  }
1447 
1448  size_t size() const override { return inputs_[0]->size(); }
1449 
1450  std::shared_ptr<RelAlgNode> deepCopy() const override {
1451  return std::make_shared<RelSort>(*this);
1452  }
1453 
1454  private:
1455  std::vector<SortField> collation_;
1456  const size_t limit_;
1457  const size_t offset_;
1459 
1460  bool hasEquivCollationOf(const RelSort& that) const;
1461 };
1462 
1463 class RelModify : public RelAlgNode {
1464  public:
1466  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
1467  using TargetColumnList = std::vector<std::string>;
1468 
1469  static std::string yieldModifyOperationString(ModifyOperation const op) {
1470  switch (op) {
1472  return "DELETE";
1474  return "INSERT";
1476  return "UPDATE";
1477  default:
1478  break;
1479  }
1480  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
1481  }
1482 
1483  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
1484  if (op_string == "INSERT") {
1485  return ModifyOperation::Insert;
1486  } else if (op_string == "DELETE") {
1487  return ModifyOperation::Delete;
1488  } else if (op_string == "UPDATE") {
1489  return ModifyOperation::Update;
1490  }
1491 
1492  throw std::runtime_error(
1493  std::string("Unsupported logical modify operation encountered " + op_string));
1494  }
1495 
1497  TableDescriptor const* const td,
1498  bool flattened,
1499  std::string const& op_string,
1500  TargetColumnList const& target_column_list,
1501  RelAlgNodeInputPtr input)
1502  : catalog_(cat)
1503  , table_descriptor_(td)
1504  , flattened_(flattened)
1505  , operation_(yieldModifyOperationEnum(op_string))
1506  , target_column_list_(target_column_list) {
1508  inputs_.push_back(input);
1509  }
1510 
1512  TableDescriptor const* const td,
1513  bool flattened,
1514  ModifyOperation op,
1515  TargetColumnList const& target_column_list,
1516  RelAlgNodeInputPtr input)
1517  : catalog_(cat)
1518  , table_descriptor_(td)
1519  , flattened_(flattened)
1520  , operation_(op)
1521  , target_column_list_(target_column_list) {
1523  inputs_.push_back(input);
1524  }
1525 
1526  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
1527  bool const isFlattened() const { return flattened_; }
1530  int getUpdateColumnCount() const { return target_column_list_.size(); }
1531 
1532  size_t size() const override { return 0; }
1533  std::shared_ptr<RelAlgNode> deepCopy() const override {
1534  return std::make_shared<RelModify>(*this);
1535  }
1536 
1537  std::string toString() const override {
1538  return cat(::typeName(this),
1539  "(",
1541  ", flattened=",
1543  ", op=",
1545  ", target_column_list=",
1547  ", inputs=",
1548  ::toString(inputs_),
1549  ")");
1550  }
1551 
1553  RelProject const* previous_project_node =
1554  dynamic_cast<RelProject const*>(inputs_[0].get());
1555  CHECK(previous_project_node != nullptr);
1556 
1557  previous_project_node->setUpdateViaSelectFlag();
1558  // remove the offset column in the projection for update handling
1559  target_column_list_.pop_back();
1560 
1561  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1562  previous_project_node->setTargetColumns(target_column_list_);
1563 
1564  int target_update_column_expr_start = 0;
1565  int target_update_column_expr_end = (int)(target_column_list_.size() - 1);
1566  CHECK(target_update_column_expr_start >= 0);
1567  CHECK(target_update_column_expr_end >= 0);
1568 
1569  bool varlen_update_required = false;
1570 
1571  auto varlen_scan_visitor = [this,
1572  &varlen_update_required,
1573  target_update_column_expr_start,
1574  target_update_column_expr_end](int index) {
1575  if (index >= target_update_column_expr_start &&
1576  index <= target_update_column_expr_end) {
1577  auto target_index = index - target_update_column_expr_start;
1578 
1579  auto* column_desc = catalog_.getMetadataForColumn(
1581  CHECK(column_desc);
1582 
1583  if (table_descriptor_->nShards) {
1584  const auto shard_cd =
1586  CHECK(shard_cd);
1587  if ((column_desc->columnName == shard_cd->columnName)) {
1588  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
1589  }
1590  }
1591 
1592  // Check for valid types
1593  if (column_desc->columnType.is_varlen()) {
1594  varlen_update_required = true;
1595  }
1596  if (column_desc->columnType.is_geometry()) {
1597  throw std::runtime_error("UPDATE of a geo column is unsupported.");
1598  }
1599  }
1600  };
1601 
1602  previous_project_node->visitScalarExprs(varlen_scan_visitor);
1603  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
1604  }
1605 
1607  RelProject const* previous_project_node =
1608  dynamic_cast<RelProject const*>(inputs_[0].get());
1609  CHECK(previous_project_node != nullptr);
1610  previous_project_node->setDeleteViaSelectFlag();
1611  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1612  }
1613 
1614  private:
1620 };
1621 
1623  public:
1624  RelTableFunction(const std::string& function_name,
1625  RelAlgInputs inputs,
1626  std::vector<std::string>& fields,
1627  std::vector<const Rex*> col_inputs,
1628  std::vector<std::unique_ptr<const RexScalar>>& table_func_inputs,
1629  std::vector<std::unique_ptr<const RexScalar>>& target_exprs)
1630  : function_name_(function_name)
1631  , fields_(fields)
1632  , col_inputs_(col_inputs)
1633  , table_func_inputs_(std::move(table_func_inputs))
1634  , target_exprs_(std::move(target_exprs)) {
1635  for (const auto& input : inputs) {
1636  inputs_.emplace_back(input);
1637  }
1638  }
1639 
1641 
1642  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1643  std::shared_ptr<const RelAlgNode> input) override;
1644 
1645  std::string getFunctionName() const { return function_name_; }
1646 
1647  size_t size() const override { return target_exprs_.size(); }
1648 
1649  size_t getTableFuncInputsSize() const { return table_func_inputs_.size(); }
1650 
1651  size_t getColInputsSize() const { return col_inputs_.size(); }
1652 
1653  const RexScalar* getTableFuncInputAt(const size_t idx) const {
1654  CHECK_LT(idx, table_func_inputs_.size());
1655  return table_func_inputs_[idx].get();
1656  }
1657 
1658  const RexScalar* getTableFuncInputAtAndRelease(const size_t idx) {
1659  CHECK_LT(idx, table_func_inputs_.size());
1660  return table_func_inputs_[idx].release();
1661  }
1662 
1663  void setTableFuncInputs(std::vector<std::unique_ptr<const RexScalar>>& exprs) {
1664  table_func_inputs_ = std::move(exprs);
1665  }
1666 
1667  std::string getFieldName(const size_t idx) const {
1668  CHECK_LT(idx, fields_.size());
1669  return fields_[idx];
1670  }
1671 
1672  std::shared_ptr<RelAlgNode> deepCopy() const override {
1673  return std::make_shared<RelTableFunction>(*this);
1674  }
1675 
1676  std::string toString() const override {
1677  return cat(::typeName(this),
1678  "(",
1680  ", inputs=",
1681  ::toString(inputs_),
1682  ", fields=",
1683  ::toString(fields_),
1684  ", col_inputs=...",
1685  ", table_func_inputs=",
1687  ", target_exprs=",
1689  ")");
1690  }
1691 
1692  private:
1693  std::string function_name_;
1694  std::vector<std::string> fields_;
1695 
1696  std::vector<const Rex*>
1697  col_inputs_; // owned by `table_func_inputs_`, but allows picking out the specific
1698  // input columns vs other table function inputs (e.g. literals)
1699  std::vector<std::unique_ptr<const RexScalar>> table_func_inputs_;
1700 
1701  std::vector<std::unique_ptr<const RexScalar>>
1702  target_exprs_; // Note: these should all be RexRef but are stored as RexScalar for
1703  // consistency
1704 };
1705 
1707  public:
1708  using RowValues = std::vector<std::unique_ptr<const RexScalar>>;
1709 
1710  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type,
1711  std::vector<RowValues>& values)
1712  : tuple_type_(tuple_type), values_(std::move(values)) {}
1713 
1715 
1716  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
1717 
1718  std::string toString() const override {
1719  std::string ret = ::typeName(this) + "(";
1720  for (const auto& target_meta_info : tuple_type_) {
1721  ret += " (" + target_meta_info.get_resname() + " " +
1722  target_meta_info.get_type_info().get_type_name() + ")";
1723  }
1724  ret += ")";
1725  return ret;
1726  }
1727 
1728  const RexScalar* getValueAt(const size_t row_idx, const size_t col_idx) const {
1729  CHECK_LT(row_idx, values_.size());
1730  const auto& row = values_[row_idx];
1731  CHECK_LT(col_idx, row.size());
1732  return row[col_idx].get();
1733  }
1734 
1735  size_t getRowsSize() const {
1736  if (values_.empty()) {
1737  return 0;
1738  } else {
1739  return values_.front().size();
1740  }
1741  }
1742 
1743  size_t getNumRows() const { return values_.size(); }
1744 
1745  size_t size() const override { return tuple_type_.size(); }
1746 
1747  bool hasRows() const { return !values_.empty(); }
1748 
1749  std::shared_ptr<RelAlgNode> deepCopy() const override {
1750  return std::make_shared<RelLogicalValues>(*this);
1751  }
1752 
1753  private:
1754  const std::vector<TargetMetaInfo> tuple_type_;
1755  const std::vector<RowValues> values_;
1756 };
1757 
1758 class RelLogicalUnion : public RelAlgNode {
1759  public:
1760  RelLogicalUnion(RelAlgInputs, bool is_all);
1761  std::shared_ptr<RelAlgNode> deepCopy() const override {
1762  return std::make_shared<RelLogicalUnion>(*this);
1763  }
1764  size_t size() const override;
1765  std::string toString() const override;
1766 
1767  std::string getFieldName(const size_t i) const;
1768 
1769  inline bool isAll() const { return is_all_; }
1770  // Will throw a std::runtime_error if MetaInfo types don't match.
1771  void checkForMatchingMetaInfoTypes() const;
1772  RexScalar const* copyAndRedirectSource(RexScalar const*, size_t input_idx) const;
1773 
1774  // Not unique_ptr to allow for an easy deepCopy() implementation.
1775  mutable std::vector<std::shared_ptr<const RexScalar>> scalar_exprs_;
1776 
1777  private:
1778  bool const is_all_;
1779 };
1780 
1781 class QueryNotSupported : public std::runtime_error {
1782  public:
1783  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
1784 };
1785 
1795 class RelAlgDagBuilder : public boost::noncopyable {
1796  public:
1797  RelAlgDagBuilder() = delete;
1798 
1805  RelAlgDagBuilder(const std::string& query_ra,
1807  const RenderInfo* render_info);
1808 
1818  RelAlgDagBuilder(RelAlgDagBuilder& root_dag_builder,
1819  const rapidjson::Value& query_ast,
1820  const Catalog_Namespace::Catalog& cat,
1821  const RenderInfo* render_opts);
1822 
1823  void eachNode(std::function<void(RelAlgNode const*)> const&) const;
1824 
1828  const RelAlgNode& getRootNode() const {
1829  CHECK(nodes_.size());
1830  const auto& last_ptr = nodes_.back();
1831  CHECK(last_ptr);
1832  return *last_ptr;
1833  }
1834 
1835  std::shared_ptr<const RelAlgNode> getRootNodeShPtr() const {
1836  CHECK(nodes_.size());
1837  return nodes_.back();
1838  }
1839 
1844  void registerSubquery(std::shared_ptr<RexSubQuery> subquery) {
1845  subqueries_.push_back(subquery);
1846  }
1847 
1851  const std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries() const {
1852  return subqueries_;
1853  }
1854 
1855  void registerQueryHints(Hints* hints_delivered) {
1856  for (auto& kv : query_hint_.OMNISCI_SUPPORTED_HINT_CLASS) {
1857  auto target = hints_delivered->find(kv.first);
1858  if (target != hints_delivered->end()) {
1859  int target_hint_num = kv.second;
1860  switch (target_hint_num) {
1861  case 0: { // cpu_mode
1862  query_hint_.hint_delivered = true;
1863  query_hint_.cpu_mode = true;
1864  VLOG(1) << "A user forces to run the query on the CPU execution mode";
1865  break;
1866  }
1867  case 1: { // overlaps_bucket_threshold
1868  CHECK(target->second.getListOptions().size() == 1);
1869  double overlaps_bucket_threshold =
1870  std::stod(target->second.getListOptions()[0]);
1871  if (overlaps_bucket_threshold >= 0.0 && overlaps_bucket_threshold <= 90.0) {
1872  query_hint_.hint_delivered = true;
1873  query_hint_.overlaps_bucket_threshold = overlaps_bucket_threshold;
1874  } else {
1875  VLOG(1) << "Skip the given query hint \"overlaps_bucket_threshold\" ("
1876  << overlaps_bucket_threshold
1877  << ") : the hint value should be within 0.0 ~ 1.0";
1878  }
1879  break;
1880  }
1881  case 2: { // overlaps_max_size
1882  CHECK(target->second.getListOptions().size() == 1);
1883  std::stringstream ss(target->second.getListOptions()[0]);
1884  int overlaps_max_size;
1885  ss >> overlaps_max_size;
1886  if (overlaps_max_size >= 0) {
1887  query_hint_.hint_delivered = true;
1888  query_hint_.overlaps_max_size = (size_t)overlaps_max_size;
1889  } else {
1890  VLOG(1) << "Skip the query hint \"overlaps_max_size\" ("
1891  << overlaps_max_size
1892  << ") : the hint value should be larger than or equal to zero";
1893  }
1894  break;
1895  }
1896  case 3: { // overlaps_allow_gpu_build
1897  query_hint_.hint_delivered = true;
1899  VLOG(1) << "Allowing GPU hash table build for overlaps join.";
1900  break;
1901  }
1902  default:
1903  break;
1904  }
1905  }
1906  }
1907  }
1908 
1909  const QueryHint getQueryHints() const { return query_hint_; }
1910 
1914  void resetQueryExecutionState();
1915 
1916  private:
1917  void build(const rapidjson::Value& query_ast, RelAlgDagBuilder& root_dag_builder);
1918 
1920  std::vector<std::shared_ptr<RelAlgNode>> nodes_;
1921  std::vector<std::shared_ptr<RexSubQuery>> subqueries_;
1924 };
1925 
1926 using RANodeOutput = std::vector<RexInput>;
1927 
1928 RANodeOutput get_node_output(const RelAlgNode* ra_node);
1929 
1930 std::string tree_string(const RelAlgNode*, const size_t depth = 0);
std::vector< std::shared_ptr< const RexScalar > > scalar_exprs_
DEVICE auto upper_bound(ARGS &&...args)
Definition: gpu_enabled.h:123
const size_t getGroupByCount() const
bool hasRows() const
bool isAll() const
std::string toString() const override
std::string toString() const override
std::shared_ptr< const RelAlgNode > getRootNodeShPtr() const
bool is_agg(const Analyzer::Expr *expr)
void validate_non_foreign_table_write(const TableDescriptor *table_descriptor)
Definition: FsiUtils.h:22
SortField getCollation(const size_t i) const
std::unique_ptr< const RexScalar > condition_
const RexScalar * getThen(const size_t idx) const
SQLAgg
Definition: sqldefs.h:71
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::unique_ptr< const RexScalar > ConstRexScalarPtr
const std::unordered_map< std::string, std::string > & getKVOptions()
std::vector< std::unique_ptr< const RexScalar > > getExpressionsAndRelease()
size_t getOffset() const
void setFields(std::vector< std::string > &fields)
void setVarlenUpdateRequired(bool required) const
std::vector< std::unique_ptr< const RexScalar > > outer_conditions_per_level_
const size_t limit_
bool const isFlattened() const
std::unique_ptr< RexSubQuery > deepCopy() const
const HintExplained & getHintInfo(const std::string &hint_name) const
ConstRexScalarPtrVector getPartitionKeysAndRelease() const
const HintExplained & getHintInfo(const std::string &hint_name) const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
JoinType
Definition: sqldefs.h:108
std::string toString() const override
std::shared_ptr< RelAlgNode > deepCopy() const override
int getUpdateColumnCount() const
ColumnNameList target_columns_
std::vector< std::unique_ptr< const RexScalar > > table_func_inputs_
std::string toString() const override
std::string cat(Ts &&...args)
const Rex * getTargetExpr(const size_t i) const
RexLiteral(const std::string &val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
const bool hasHintEnabled(const std::string &candidate_hint_name) const
SQLAgg getKind() const
const std::shared_ptr< const RelAlgNode > ra_
RelAlgNode(RelAlgInputs inputs={})
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:101
Hints * getDeliveredHints()
size_t size() const override
const size_t index_
SQLTypes
Definition: sqltypes.h:37
std::shared_ptr< RelAlgNode > deepCopy() const override
std::vector< std::string > list_options_
std::string tableName
const std::string name_
bool coversOriginalNode(const RelAlgNode *node) const
const RexScalar * getFilterExpr() const
size_t size() const override
const unsigned type_scale_
size_t getOperand(size_t idx) const
std::string toString() const override
std::string toString() const override
const RexScalar * getElse() const
RexOperator(const SQLOps op, std::vector< std::unique_ptr< const RexScalar >> &operands, const SQLTypeInfo &type)
const QueryHint getQueryHints() const
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())
bool hasOptions() const
const HintExplained & getHintInfo(const std::string &hint_name) const
size_t getIndex() const
static thread_local unsigned crt_id_
void setCondition(std::unique_ptr< const RexScalar > &condition)
void setTargetColumns(ColumnNameList const &target_columns) const
std::string function_name_
const std::string getFieldName(const size_t i) const
std::unique_ptr< RexRef > deepCopy() const
void addHint(const HintExplained &hint_explained)
void setEmptyResult(bool emptyResult)
RexScalar const * copyAndRedirectSource(RexScalar const *, size_t input_idx) const
std::unique_ptr< const RexScalar > ConstRexScalarPtr
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
const RexScalar * getOuterCondition(const size_t nesting_level) const
const JoinType join_type_
const HintExplained & getHintInfo(const std::string &hint_name) const
NullSortedPosition
void applyDeleteModificationsToInputNode()
bool operator==(const SortField &that) const
std::vector< std::string > TargetColumnList
size_t size() const override
const SQLTypeInfo & getType() const
size_t size() const
Hints * getDeliveredHints()
const RexScalar * getOperand(const size_t idx) const
const RexWindowBound upper_bound_
const SqlWindowFunctionKind kind_
std::string toString() const override
size_t size() const override
std::vector< const Rex * > col_inputs_
bool hasEquivCollationOf(const RelSort &that) const
const std::vector< SortField > & getCollation() const
SQLOps
Definition: sqldefs.h:29
const std::vector< std::string > fields_
SortDirection getSortDir() const
size_t getNumRows() const
bool hasDeliveredHint()
const SQLTypeInfo & getType() const
std::string toString() const override
void applyUpdateModificationsToInputNode()
std::string toString() const override
const boost::variant< int64_t, double, std::string, bool, void * > literal_
std::unordered_map< std::string, std::string > kv_options_
std::string getFieldName(const size_t idx) const
void build(const rapidjson::Value &query_ast, RelAlgDagBuilder &root_dag_builder)
const RexScalar * getCondition() const
std::shared_ptr< std::shared_ptr< const ExecutionResult > > result_
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const
RexSubQuery & operator=(const RexSubQuery &)=delete
std::unique_ptr< const RexScalar > else_expr_
const std::vector< TargetMetaInfo > getTupleType() const
void addManagedInput(std::shared_ptr< const RelAlgNode > input)
unsigned getScale() const
bool hint_applied_
const std::vector< TargetMetaInfo > tuple_type_
RexSubQuery(std::shared_ptr< SQLTypeInfo > type, std::shared_ptr< std::shared_ptr< const ExecutionResult >> result, const std::shared_ptr< const RelAlgNode > ra)
size_t getField() const
std::vector< std::string > fields_
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
RexInput(const RelAlgNode *node, const unsigned in_index)
std::shared_ptr< RelAlgNode > deepCopy() const override
const RexScalar * getWhen(const size_t idx) const
void addHint(const HintExplained &hint_explained)
const void * context_data_
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
bool hasDeliveredHint()
void appendInput(std::string new_field_name, std::unique_ptr< const RexScalar > new_input)
const RexScalar * getCondition() const
std::shared_ptr< RelAlgNode > deepCopy() const override
std::string hint_name_
bool empty_result_
virtual ~Rex()
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
const TableDescriptor * td_
const Catalog_Namespace::Catalog & cat_
size_t operator()(const RexInput &rex_in) const
const RexScalar * getOperandAndRelease(const size_t idx) const
void checkForMatchingMetaInfoTypes() const
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
const ColumnDescriptor * getShardColumnMetadataForTable(const TableDescriptor *td) const
Definition: Catalog.cpp:3773
virtual std::shared_ptr< RelAlgNode > deepCopy() const =0
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
const SQLOps op_
HintExplained(std::string hint_name, bool query_hint, bool is_marker, bool has_kv_type_options, std::unordered_map< std::string, std::string > &kv_options)
const std::string getFieldName(const size_t i) const
void addHint(const HintExplained &hint_explained)
std::string to_string(char const *&&v)
void clearContextData() const
TableDescriptor const *const getTableDescriptor() const
const SQLAgg agg_
const size_t groupby_count_
std::string toString() const override
unsigned getTypePrecision() const
const std::string getFieldName(const size_t i) const
std::vector< SortField > collation_
std::string toString() const override
std::string toString() const override
size_t getRowsSize() const
size_t getColInputsSize() const
void addHint(const HintExplained &hint_explained)
std::vector< RexLiteral > RexLiteralArray
void setDeleteViaSelectFlag() const
This file contains the class specification and related data structures for Catalog.
const size_t getScalarSourcesSize() const
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
TargetColumnList const & getUpdateColumnNames()
const RenderInfo * render_info_
std::string to_string() const
Definition: sqltypes.h:446
RexLiteral(const double val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const unsigned precision_
unsigned getIndex() const
bool isNop() const
std::string toString() const override
virtual ~RelAlgNode()
SQLOps getOperator() const
std::vector< std::shared_ptr< RelAlgNode > > nodes_
std::shared_ptr< const RelAlgNode > RelAlgNodeInputPtr
void registerQueryHints(Hints *hints_delivered)
std::shared_ptr< RelAlgNode > deepCopy() const override
unsigned getId() const
bool hasDeliveredHint()
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
const SQLTypeInfo & getType() const
const bool distinct_
ColumnNameList const & getTargetColumns() const
std::unique_ptr< const RexOperator > disambiguatedOperands(ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > &collation) const
const NullSortedPosition nulls_pos_
const size_t offset_
#define CHECK_NE(x, y)
Definition: Logger.h:206
const std::vector< RowValues > values_
RexCase(std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar >>> &expr_pair_list, std::unique_ptr< const RexScalar > &else_expr)
NullSortedPosition getNullsPosition() const
bool isRenaming() const
void setIndex(const unsigned in_index) const
T getVal() const
Hints * getDeliveredHints()
const SQLTypeInfo type_
std::unique_ptr< Hints > hints_
const TableDescriptor * table_descriptor_
const std::vector< std::shared_ptr< const RelJoin > > original_joins_
std::shared_ptr< const RexScalar > offset
std::unique_ptr< Hints > hints_
std::vector< std::unique_ptr< const RexScalar > > scalar_exprs_
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t size() const override
std::shared_ptr< SQLTypeInfo > type_
size_t size() const override
const RexScalar * getAndReleaseCondition()
const ColumnDescriptor * getMetadataForColumn(int tableId, const std::string &colName) const
size_t branchCount() const
const std::string & getHintName() const
RexSubQuery(const std::shared_ptr< const RelAlgNode > ra)
const RelAlgNode * getInput(const size_t idx) const
RexAbstractInput(const unsigned in_index)
RelFilter(std::unique_ptr< const RexScalar > &filter, std::shared_ptr< const RelAlgNode > input)
bool cpu_mode
Definition: QueryHint.h:61
Catalog_Namespace::Catalog const & catalog_
const unsigned type_precision_
const RelAlgNode & getRootNode() const
std::string toString() const override
RelAggregate(const size_t groupby_count, std::vector< std::unique_ptr< const RexAgg >> &agg_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
std::unique_ptr< const RexScalar > filter_
void setCondition(std::unique_ptr< const RexScalar > &condition)
bool isSimple() const
std::vector< std::unique_ptr< const RexScalar > > operands_
const size_t groupby_count_
const std::vector< std::string > & getListOptions()
std::vector< std::string > fields_
std::shared_ptr< RelAlgNode > deepCopy() const override
RelSort(const std::vector< SortField > &collation, const size_t limit, const size_t offset, std::shared_ptr< const RelAlgNode > input)
const RexScalar * getProjectAtAndRelease(const size_t idx) const
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
unsigned getId() const
std::shared_ptr< RelAlgNode > deepCopy() const override
const RelAlgNode * node_
std::unique_ptr< Hints > hints_
void setInheritPaths(std::vector< int > &interit_paths)
size_t getTableFuncInputsSize() const
std::unique_ptr< RexLiteral > deepCopy() const
virtual void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input)
std::string toString() const
void eachNode(std::function< void(RelAlgNode const *)> const &) const
static std::string yieldModifyOperationString(ModifyOperation const op)
ModifyOperation getOperation() const
std::unique_ptr< RexInput > deepCopy() const
void setModifiedTableDescriptor(TableDescriptor const *td) const
size_t size() const override
const SQLTypes type_
static ModifyOperation yieldModifyOperationEnum(std::string const &op_string)
const bool hasHintEnabled(const std::string &candidate_hint_name) const
void setScalarSources(std::vector< std::unique_ptr< const RexScalar >> &new_sources)
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
std::vector< TargetMetaInfo > targets_metainfo_
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
Hints * getDeliveredHints()
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
bool isEmptyResult() const
std::unordered_map< std::string, HintExplained > Hints
const RelAlgNode * getRelAlg() const
size_t size() const override
SortDirection
RexWindowFunctionOperator(const SqlWindowFunctionKind kind, ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > collation, const RexWindowBound &lower_bound, const RexWindowBound &upper_bound, const bool is_rows, const SQLTypeInfo &ti)
const RexScalar * getProjectAt(const size_t idx) const
std::vector< std::shared_ptr< const RelAlgNode >> RelAlgInputs
const std::vector< SortField > collation_
const std::vector< std::string > & getFields() const
const HintExplained & getHintInfo(const std::string &hint_name) const
#define CHECK_LT(x, y)
Definition: Logger.h:207
Definition: sqltypes.h:51
bool hasInput(const RelAlgNode *needle) const
const std::vector< std::string > & getFieldNames() const
const std::vector< std::string > & getFields() const
const std::vector< int > & getInteritPath()
void setCollation(std::vector< SortField > &&collation)
std::unique_ptr< Hints > hints_
const ConstRexScalarPtrVector & getPartitionKeys() const
const RexWindowBound & getLowerBound() const
std::string tree_string(const RelAlgNode *ra, const size_t depth)
DEVICE auto lower_bound(ARGS &&...args)
Definition: gpu_enabled.h:78
std::string toString() const override
const void * getContextData() const
std::unique_ptr< Hints > hints_
const std::vector< const Rex * > target_exprs_
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
RelLogicalUnion(RelAlgInputs, bool is_all)
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
size_t overlaps_max_size
Definition: QueryHint.h:65
SortField(const size_t field, const SortDirection sort_dir, const NullSortedPosition nulls_pos)
std::unique_ptr< const RexScalar > filter_expr_
void setSourceNode(const RelAlgNode *node) const
void resetQueryExecutionState()
bool hasWindowFunctionExpr() const
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
ConstRexScalarPtrVector order_keys_
SqlWindowFunctionKind getKind() const
const size_t getGroupByCount() const
size_t collationCount() const
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, ModifyOperation op, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
virtual size_t size() const =0
const RelAlgNode * getSourceNode() const
auto const isDeleteViaSelect() const
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
void setExecutionResult(const std::shared_ptr< const ExecutionResult > result)
bool operator==(const RelSort &that) const
void setKVOptions(std::unordered_map< std::string, std::string > &kv_options)
bool isAggregate() const
size_t getLimit() const
std::shared_ptr< RelAlgNode > deepCopy() const override
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type, std::vector< RowValues > &values)
std::string toString() const override
std::string get_type_name() const
Definition: sqltypes.h:414
std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const override
RexLiteral(const bool val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
bool hint_applied_
bool hasDeliveredHint()
std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar > > > expr_pair_list_
RelAlgDagBuilder()=delete
SqlWindowFunctionKind
Definition: sqldefs.h:83
RexFunctionOperator(const std::string &name, ConstRexScalarPtrVector &operands, const SQLTypeInfo &ti)
const SQLTypes target_type_
std::unique_ptr< const RexScalar > condition_
const RexWindowBound & getUpperBound() const
const std::vector< std::string > field_names_
RelLeftDeepInnerJoin(const std::shared_ptr< RelFilter > &filter, RelAlgInputs inputs, std::vector< std::shared_ptr< const RelJoin >> &original_joins)
const RexScalar * getTableFuncInputAt(const size_t idx) const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
unsigned getPrecision() const
double overlaps_bucket_threshold
Definition: QueryHint.h:64
bool isQueryHint() const
RelTableFunction(const std::string &function_name, RelAlgInputs inputs, std::vector< std::string > &fields, std::vector< const Rex * > col_inputs, std::vector< std::unique_ptr< const RexScalar >> &table_func_inputs, std::vector< std::unique_ptr< const RexScalar >> &target_exprs)
std::string getFunctionName() const
std::string toString() const override
virtual std::string toString() const =0
const SortDirection sort_dir_
std::vector< const RexAgg * > getAggregatesAndRelease()
const std::vector< std::string > & getFields() const
bool isDistinct() const
std::string getFieldName(const size_t i) const
const RexScalar * getValueAt(const size_t row_idx, const size_t col_idx) const
bool g_enable_watchdog false
Definition: Execute.cpp:76
const RexScalar * getInnerCondition() const
virtual std::string toString() const =0
ModifyOperation operation_
#define CHECK(condition)
Definition: Logger.h:197
ConstRexScalarPtrVector getOrderKeysAndRelease() const
bool operator==(const RexInput &that) const
const ConstRexScalarPtrVector & getOrderKeys() const
RelProject(std::vector< std::unique_ptr< const RexScalar >> &scalar_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
auto const isUpdateViaSelect() const
HintExplained(std::string hint_name, bool query_hint, bool is_marker, bool has_kv_type_options)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
SQLTypes getTargetType() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
std::string toString() const override
size_t size() const
ConstRexScalarPtrVector partition_keys_
HintExplained(std::string hint_name, bool query_hint, bool is_marker, bool has_kv_type_options, std::vector< std::string > &list_options)
bool hasKvOptions() const
std::vector< RexLiteralArray > TupleContentsArray
const SQLTypeInfo type_
std::shared_ptr< RelAlgNode > deepCopy() const override
const std::vector< size_t > operands_
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
std::string toString() const override
std::shared_ptr< RelAlgNode > deepCopy() const override
const std::shared_ptr< RelFilter > original_filter_
void injectOffsetInFragmentExpr() const
bool overlaps_allow_gpu_build
Definition: QueryHint.h:66
std::vector< std::string > ColumnNameList
ModifyManipulationTarget(bool const update_via_select=false, bool const delete_via_select=false, bool const varlen_update_required=false, TableDescriptor const *table_descriptor=nullptr, ColumnNameList target_columns=ColumnNameList())
RexLiteral(const SQLTypes target_type)
QueryNotSupported(const std::string &reason)
Definition: sqltypes.h:44
size_t size() const override
std::vector< RexInput > RANodeOutput
std::vector< std::unique_ptr< const RexScalar >> RowValues
const size_t getAggExprsCount() const
const std::string & getName() const
const size_t inputCount() const
string name
Definition: setup.py:44
auto const isVarlenUpdateRequired() const
RexAgg(const SQLAgg agg, const bool distinct, const SQLTypeInfo &type, const std::vector< size_t > &operands)
unsigned getTypeScale() const
const RexScalar * getAndReleaseCondition() const
void setListOptions(std::vector< std::string > &list_options)
const size_t field_
std::string toString() const override
size_t size() const override
std::unique_ptr< RexAgg > deepCopy() const
const RexWindowBound lower_bound_
RexLiteral(const int64_t val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
void setUpdateViaSelectFlag() const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
RelScan(const TableDescriptor *td, const std::vector< std::string > &field_names)
bool hint_delivered
Definition: QueryHint.h:58
SQLTypes getType() const
size_t size() const override
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
const unsigned scale_
const TableDescriptor * getTableDescriptor() const
std::shared_ptr< const ExecutionResult > getExecutionResult() const
void setContextData(const void *context_data) const
TargetColumnList target_column_list_
TableDescriptor const * table_descriptor_
void setAggExprs(std::vector< std::unique_ptr< const RexAgg >> &agg_exprs)
std::vector< std::string > fields_
JoinType getJoinType() const
bool hasContextData() const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
std::shared_ptr< RelAlgNode > deepCopy() const override
#define VLOG(n)
Definition: Logger.h:291
RelJoin(std::shared_ptr< const RelAlgNode > lhs, std::shared_ptr< const RelAlgNode > rhs, std::unique_ptr< const RexScalar > &condition, const JoinType join_type)
void addHint(const HintExplained &hint_explained)
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, std::string const &op_string, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
RelAlgInputs inputs_
void setFields(std::vector< std::string > &new_fields)
RexRef(const size_t index)
std::string toString() const override
TableDescriptor const * getModifiedTableDescriptor() const
bool isIdentity() const
const std::string getFieldName(const size_t i) const
const RexScalar * getScalarSource(const size_t i) const
constexpr auto is_datetime(SQLTypes type)
Definition: sqltypes.h:254
std::vector< std::unique_ptr< const RexScalar > > target_exprs_
Hints * getDeliveredHints()
const bool is_agg_
std::vector< int > inherit_paths_
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
const unsigned id_
static void resetRelAlgFirstId() noexcept
std::unordered_map< std::string, int > OMNISCI_SUPPORTED_HINT_CLASS
Definition: QueryHint.h:68