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