OmniSciDB  8a228a1076
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"
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 
51 // For internal use of the abstract interpreter only. The result after abstract
52 // interpretation will not have any references to 'RexAbstractInput' objects.
53 class RexAbstractInput : public RexScalar {
54  public:
55  RexAbstractInput(const unsigned in_index) : in_index_(in_index) {}
56 
57  unsigned getIndex() const { return in_index_; }
58 
59  void setIndex(const unsigned in_index) const { in_index_ = in_index; }
60 
61  std::string toString() const override {
62  return "(RexAbstractInput " + std::to_string(in_index_) + ")";
63  }
64 
65  private:
66  mutable unsigned in_index_;
67 };
68 
69 class RexLiteral : public RexScalar {
70  public:
71  RexLiteral(const int64_t val,
72  const SQLTypes type,
73  const SQLTypes target_type,
74  const unsigned scale,
75  const unsigned precision,
76  const unsigned type_scale,
77  const unsigned type_precision)
78  : literal_(val)
79  , type_(type)
80  , target_type_(target_type)
81  , scale_(scale)
82  , precision_(precision)
83  , type_scale_(type_scale)
84  , type_precision_(type_precision) {
85  CHECK(type == kDECIMAL || type == kINTERVAL_DAY_TIME ||
86  type == kINTERVAL_YEAR_MONTH || is_datetime(type));
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 "(RexLiteral " + boost::lexical_cast<std::string>(literal_) + ")";
170  }
171 
172  std::unique_ptr<RexLiteral> deepCopy() const {
173  switch (literal_.which()) {
174  case 0: {
175  int64_t val = getVal<int64_t>();
176  return std::make_unique<RexLiteral>(
177  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
178  }
179  case 1: {
180  double val = getVal<double>();
181  return std::make_unique<RexLiteral>(
182  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
183  }
184  case 2: {
185  auto val = getVal<std::string>();
186  return std::make_unique<RexLiteral>(
187  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
188  }
189  case 3: {
190  bool val = getVal<bool>();
191  return std::make_unique<RexLiteral>(
192  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
193  }
194  case 4: {
195  return std::make_unique<RexLiteral>(target_type_);
196  }
197  default:
198  CHECK(false);
199  }
200  return nullptr;
201  }
202 
203  private:
204  const boost::variant<int64_t, double, std::string, bool, void*> literal_;
207  const unsigned scale_;
208  const unsigned precision_;
209  const unsigned type_scale_;
210  const unsigned type_precision_;
211 };
212 
213 using RexLiteralArray = std::vector<RexLiteral>;
214 using TupleContentsArray = std::vector<RexLiteralArray>;
215 
216 class RexOperator : public RexScalar {
217  public:
218  RexOperator(const SQLOps op,
219  std::vector<std::unique_ptr<const RexScalar>>& operands,
220  const SQLTypeInfo& type)
221  : op_(op), operands_(std::move(operands)), type_(type) {}
222 
223  virtual std::unique_ptr<const RexOperator> getDisambiguated(
224  std::vector<std::unique_ptr<const RexScalar>>& operands) const {
225  return std::unique_ptr<const RexOperator>(new RexOperator(op_, operands, type_));
226  }
227 
228  size_t size() const { return operands_.size(); }
229 
230  const RexScalar* getOperand(const size_t idx) const {
231  CHECK(idx < operands_.size());
232  return operands_[idx].get();
233  }
234 
235  const RexScalar* getOperandAndRelease(const size_t idx) const {
236  CHECK(idx < operands_.size());
237  return operands_[idx].release();
238  }
239 
240  SQLOps getOperator() const { return op_; }
241 
242  const SQLTypeInfo& getType() const { return type_; }
243 
244  std::string toString() const override {
245  std::string result = "(RexOperator " + std::to_string(op_);
246  for (const auto& operand : operands_) {
247  result += " " + operand->toString();
248  }
249  return result + ")";
250  };
251 
252  protected:
253  const SQLOps op_;
254  mutable std::vector<std::unique_ptr<const RexScalar>> operands_;
256 };
257 
258 class RelAlgNode;
259 using RelAlgInputs = std::vector<std::shared_ptr<const RelAlgNode>>;
260 
261 class ExecutionResult;
262 
263 class RexSubQuery : public RexScalar {
264  public:
265  RexSubQuery(const std::shared_ptr<const RelAlgNode> ra)
266  : type_(new SQLTypeInfo(kNULLT, false))
267  , result_(new std::shared_ptr<const ExecutionResult>(nullptr))
268  , ra_(ra) {}
269 
270  // for deep copy
271  RexSubQuery(std::shared_ptr<SQLTypeInfo> type,
272  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result,
273  const std::shared_ptr<const RelAlgNode> ra)
274  : type_(type), result_(result), ra_(ra) {}
275 
276  RexSubQuery(const RexSubQuery&) = delete;
277 
278  RexSubQuery& operator=(const RexSubQuery&) = delete;
279 
280  RexSubQuery(RexSubQuery&&) = delete;
281 
282  RexSubQuery& operator=(RexSubQuery&&) = delete;
283 
284  const SQLTypeInfo& getType() const {
285  CHECK_NE(kNULLT, type_->get_type());
286  return *(type_.get());
287  }
288 
289  std::shared_ptr<const ExecutionResult> getExecutionResult() const {
290  CHECK(result_);
291  CHECK(result_.get());
292  return *(result_.get());
293  }
294 
295  unsigned getId() const;
296 
297  const RelAlgNode* getRelAlg() const { return ra_.get(); }
298 
299  std::string toString() const override {
300  return "(RexSubQuery " + std::to_string(reinterpret_cast<const uint64_t>(this)) +
301  " id(" + std::to_string(getId()) + "))";
302  }
303 
304  std::unique_ptr<RexSubQuery> deepCopy() const;
305 
306  void setExecutionResult(const std::shared_ptr<const ExecutionResult> result);
307 
308  private:
309  std::shared_ptr<SQLTypeInfo> type_;
310  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result_;
311  const std::shared_ptr<const RelAlgNode> ra_;
312 };
313 
314 // The actual input node understood by the Executor.
315 // The in_index_ is relative to the output of node_.
316 class RexInput : public RexAbstractInput {
317  public:
318  RexInput(const RelAlgNode* node, const unsigned in_index)
319  : RexAbstractInput(in_index), node_(node) {}
320 
321  const RelAlgNode* getSourceNode() const { return node_; }
322 
323  // This isn't great, but we need it for coalescing nodes to Compound since
324  // RexInput in descendents need to be rebound to the newly created Compound.
325  // Maybe create a fresh RA tree with the required changes after each coalescing?
326  void setSourceNode(const RelAlgNode* node) const { node_ = node; }
327 
328  bool operator==(const RexInput& that) const {
329  return getSourceNode() == that.getSourceNode() && getIndex() == that.getIndex();
330  }
331 
332  std::string toString() const override {
333  return "(RexInput " + std::to_string(getIndex()) + " " +
334  std::to_string(reinterpret_cast<const uint64_t>(node_)) + ")";
335  }
336 
337  std::unique_ptr<RexInput> deepCopy() const {
338  return std::make_unique<RexInput>(node_, getIndex());
339  }
340 
341  private:
342  mutable const RelAlgNode* node_;
343 };
344 
345 namespace std {
346 
347 template <>
348 struct hash<RexInput> {
349  size_t operator()(const RexInput& rex_in) const {
350  auto addr = rex_in.getSourceNode();
351  return *reinterpret_cast<const size_t*>(may_alias_ptr(&addr)) ^ rex_in.getIndex();
352  }
353 };
354 
355 } // namespace std
356 
357 // Not a real node created by Calcite. Created by us because CaseExpr is a node in our
358 // Analyzer.
359 class RexCase : public RexScalar {
360  public:
361  RexCase(std::vector<std::pair<std::unique_ptr<const RexScalar>,
362  std::unique_ptr<const RexScalar>>>& expr_pair_list,
363  std::unique_ptr<const RexScalar>& else_expr)
364  : expr_pair_list_(std::move(expr_pair_list)), else_expr_(std::move(else_expr)) {}
365 
366  size_t branchCount() const { return expr_pair_list_.size(); }
367 
368  const RexScalar* getWhen(const size_t idx) const {
369  CHECK(idx < expr_pair_list_.size());
370  return expr_pair_list_[idx].first.get();
371  }
372 
373  const RexScalar* getThen(const size_t idx) const {
374  CHECK(idx < expr_pair_list_.size());
375  return expr_pair_list_[idx].second.get();
376  }
377 
378  const RexScalar* getElse() const { return else_expr_.get(); }
379 
380  std::string toString() const override {
381  std::string ret = "(RexCase";
382  for (const auto& expr_pair : expr_pair_list_) {
383  ret += " " + expr_pair.first->toString() + " -> " + expr_pair.second->toString();
384  }
385  if (else_expr_) {
386  ret += " else " + else_expr_->toString();
387  }
388  ret += ")";
389  return ret;
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  auto result = "(RexFunctionOperator " + name_;
419  for (const auto& operand : operands_) {
420  result += (" " + operand->toString());
421  }
422  return result + ")";
423  }
424 
425  private:
426  const std::string name_;
427 };
428 
430 
431 enum class NullSortedPosition { First, Last };
432 
433 class SortField {
434  public:
435  SortField(const size_t field,
436  const SortDirection sort_dir,
437  const NullSortedPosition nulls_pos)
438  : field_(field), sort_dir_(sort_dir), nulls_pos_(nulls_pos) {}
439 
440  bool operator==(const SortField& that) const {
441  return field_ == that.field_ && sort_dir_ == that.sort_dir_ &&
442  nulls_pos_ == that.nulls_pos_;
443  }
444 
445  size_t getField() const { return field_; }
446 
447  SortDirection getSortDir() const { return sort_dir_; }
448 
449  NullSortedPosition getNullsPosition() const { return nulls_pos_; }
450 
451  std::string toString() const {
452  return "(" + std::to_string(field_) + " " +
453  (sort_dir_ == SortDirection::Ascending ? "asc" : "desc") + " " +
454  (nulls_pos_ == NullSortedPosition::First ? "nulls_first" : "nulls_last") + ")";
455  }
456 
457  private:
458  const size_t field_;
461 };
462 
464  public:
465  struct RexWindowBound {
466  bool unbounded;
467  bool preceding;
468  bool following;
470  std::shared_ptr<const RexScalar> offset;
472  };
473 
475  ConstRexScalarPtrVector& operands,
476  ConstRexScalarPtrVector& partition_keys,
477  ConstRexScalarPtrVector& order_keys,
478  const std::vector<SortField> collation,
479  const RexWindowBound& lower_bound,
480  const RexWindowBound& upper_bound,
481  const bool is_rows,
482  const SQLTypeInfo& ti)
483  : RexFunctionOperator(sql_window_function_to_str(kind), operands, ti)
484  , kind_(kind)
485  , partition_keys_(std::move(partition_keys))
486  , order_keys_(std::move(order_keys))
487  , collation_(collation)
488  , lower_bound_(lower_bound)
489  , upper_bound_(upper_bound)
490  , is_rows_(is_rows) {}
491 
492  SqlWindowFunctionKind getKind() const { return kind_; }
493 
494  const ConstRexScalarPtrVector& getPartitionKeys() const { return partition_keys_; }
495 
496  ConstRexScalarPtrVector getPartitionKeysAndRelease() const {
497  return std::move(partition_keys_);
498  }
499 
500  ConstRexScalarPtrVector getOrderKeysAndRelease() const {
501  return std::move(order_keys_);
502  }
503 
504  const ConstRexScalarPtrVector& getOrderKeys() const { return order_keys_; }
505 
506  const std::vector<SortField>& getCollation() const { return collation_; }
507 
508  const RexWindowBound& getLowerBound() const { return lower_bound_; }
509 
510  const RexWindowBound& getUpperBound() const { return upper_bound_; }
511 
512  bool isRows() const { return is_rows_; }
513 
514  std::unique_ptr<const RexOperator> disambiguatedOperands(
515  ConstRexScalarPtrVector& operands,
516  ConstRexScalarPtrVector& partition_keys,
517  ConstRexScalarPtrVector& order_keys,
518  const std::vector<SortField>& collation) const {
519  return std::unique_ptr<const RexOperator>(
520  new RexWindowFunctionOperator(kind_,
521  operands,
522  partition_keys,
523  order_keys,
524  collation,
525  getLowerBound(),
526  getUpperBound(),
527  isRows(),
528  getType()));
529  }
530 
531  std::string toString() const override {
532  auto result = "(RexWindowFunctionOperator " + getName();
533  for (const auto& operand : operands_) {
534  result += (" " + operand->toString());
535  }
536  result += " partition[";
537  for (const auto& partition_key : partition_keys_) {
538  result += (" " + partition_key->toString());
539  }
540  result += "]";
541  result += " order[";
542  for (const auto& order_key : order_keys_) {
543  result += (" " + order_key->toString());
544  }
545  result += "]";
546  return result + ")";
547  }
548 
549  private:
551  mutable ConstRexScalarPtrVector partition_keys_;
552  mutable ConstRexScalarPtrVector order_keys_;
553  const std::vector<SortField> collation_;
556  const bool is_rows_;
557 };
558 
559 // Not a real node created by Calcite. Created by us because targets of a query
560 // should reference the group by expressions instead of creating completely new one.
561 class RexRef : public RexScalar {
562  public:
563  RexRef(const size_t index) : index_(index) {}
564 
565  size_t getIndex() const { return index_; }
566 
567  std::string toString() const override {
568  return "(RexRef " + std::to_string(index_) + ")";
569  }
570 
571  std::unique_ptr<RexRef> deepCopy() const { return std::make_unique<RexRef>(index_); }
572 
573  private:
574  const size_t index_;
575 };
576 
577 class RexAgg : public Rex {
578  public:
579  RexAgg(const SQLAgg agg,
580  const bool distinct,
581  const SQLTypeInfo& type,
582  const std::vector<size_t>& operands)
583  : agg_(agg), distinct_(distinct), type_(type), operands_(operands) {}
584 
585  std::string toString() const override {
586  auto result = "(RexAgg " + std::to_string(agg_) + " " + std::to_string(distinct_) +
587  " " + type_.get_type_name() + " " + type_.get_compression_name();
588  for (auto operand : operands_) {
589  result += " " + std::to_string(operand);
590  }
591  return result + ")";
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 {
710  CHECK(!context_data_);
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 {
727  CHECK(context_data_);
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 
778  protected:
780  const unsigned id_;
781 
782  private:
783  mutable const void* context_data_;
784  bool is_nop_;
785  mutable std::vector<TargetMetaInfo> targets_metainfo_;
786  static thread_local unsigned crt_id_;
787 };
788 
789 class RelScan : public RelAlgNode {
790  public:
791  RelScan(const TableDescriptor* td, const std::vector<std::string>& field_names)
792  : td_(td)
793  , field_names_(field_names)
794  , hint_applied_(false)
795  , hints_(std::make_unique<Hints>()) {}
796 
797  size_t size() const override { return field_names_.size(); }
798 
799  const TableDescriptor* getTableDescriptor() const { return td_; }
800 
801  const std::vector<std::string>& getFieldNames() const { return field_names_; }
802 
803  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
804 
805  std::string toString() const override {
806  return "(RelScan<" + std::to_string(reinterpret_cast<uint64_t>(this)) + "> " +
807  td_->tableName + ")";
808  }
809 
810  std::shared_ptr<RelAlgNode> deepCopy() const override {
811  CHECK(false);
812  return nullptr;
813  };
814 
815  void addHint(const HintExplained& hint_explained) {
816  if (!hint_applied_) {
817  hint_applied_ = true;
818  }
819  hints_->emplace(hint_explained.getHintName(), hint_explained);
820  }
821 
822  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
823  if (hint_applied_ && !hints_->empty()) {
824  return hints_->find(candidate_hint_name) != hints_->end();
825  }
826  return false;
827  }
828 
829  const HintExplained& getHintInfo(const std::string& hint_name) const {
830  CHECK(hint_applied_);
831  CHECK(!hints_->empty());
832  CHECK(hasHintEnabled(hint_name));
833  return hints_->at(hint_name);
834  }
835 
836  private:
838  const std::vector<std::string> field_names_;
840  std::unique_ptr<Hints> hints_;
841 };
842 
844  public:
845  ModifyManipulationTarget(bool const update_via_select = false,
846  bool const delete_via_select = false,
847  bool const varlen_update_required = false,
848  TableDescriptor const* table_descriptor = nullptr,
849  ColumnNameList target_columns = ColumnNameList())
850  : is_update_via_select_(update_via_select)
851  , is_delete_via_select_(delete_via_select)
852  , varlen_update_required_(varlen_update_required)
853  , table_descriptor_(table_descriptor)
854  , target_columns_(target_columns) {}
855 
856  void setUpdateViaSelectFlag() const { is_update_via_select_ = true; }
857  void setDeleteViaSelectFlag() const { is_delete_via_select_ = true; }
859  varlen_update_required_ = required;
860  }
861 
862  TableDescriptor const* getModifiedTableDescriptor() const { return table_descriptor_; }
864  table_descriptor_ = td;
865  }
866 
867  auto const isUpdateViaSelect() const { return is_update_via_select_; }
868  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
869  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
870 
871  void setTargetColumns(ColumnNameList const& target_columns) const {
872  target_columns_ = target_columns;
873  }
874  ColumnNameList const& getTargetColumns() const { return target_columns_; }
875 
876  template <typename VALIDATION_FUNCTOR>
877  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
878  for (auto const& column_name : target_columns_) {
879  if (validator(column_name) == false) {
880  return false;
881  }
882  }
883  return true;
884  }
885 
886  private:
887  mutable bool is_update_via_select_ = false;
888  mutable bool is_delete_via_select_ = false;
889  mutable bool varlen_update_required_ = false;
890  mutable TableDescriptor const* table_descriptor_ = nullptr;
892 };
893 
895  public:
896  friend class RelModify;
897  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
898  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
899 
900  // Takes memory ownership of the expressions.
901  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
902  const std::vector<std::string>& fields,
903  std::shared_ptr<const RelAlgNode> input)
904  : ModifyManipulationTarget(false, false, false, nullptr)
905  , scalar_exprs_(std::move(scalar_exprs))
906  , fields_(fields)
907  , hint_applied_(false)
908  , hints_(std::make_unique<Hints>()) {
909  inputs_.push_back(input);
910  }
911 
912  RelProject(RelProject const&);
913 
914  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
915  scalar_exprs_ = std::move(exprs);
916  }
917 
918  // True iff all the projected expressions are inputs. If true,
919  // this node can be elided and merged into the previous node
920  // since it's just a subset and / or permutation of its outputs.
921  bool isSimple() const {
922  for (const auto& expr : scalar_exprs_) {
923  if (!dynamic_cast<const RexInput*>(expr.get())) {
924  return false;
925  }
926  }
927  return true;
928  }
929 
930  bool isIdentity() const;
931 
932  bool isRenaming() const;
933 
934  size_t size() const override { return scalar_exprs_.size(); }
935 
936  const RexScalar* getProjectAt(const size_t idx) const {
937  CHECK(idx < scalar_exprs_.size());
938  return scalar_exprs_[idx].get();
939  }
940 
941  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
942  CHECK(idx < scalar_exprs_.size());
943  return scalar_exprs_[idx].release();
944  }
945 
946  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
947  return std::move(scalar_exprs_);
948  }
949 
950  const std::vector<std::string>& getFields() const { return fields_; }
951  void setFields(std::vector<std::string>& fields) { fields_ = std::move(fields); }
952 
953  const std::string getFieldName(const size_t i) const { return fields_[i]; }
954 
955  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
956  std::shared_ptr<const RelAlgNode> input) override {
957  replaceInput(old_input, input, std::nullopt);
958  }
959 
960  void replaceInput(
961  std::shared_ptr<const RelAlgNode> old_input,
962  std::shared_ptr<const RelAlgNode> input,
963  std::optional<std::unordered_map<unsigned, unsigned>> old_to_new_index_map);
964 
965  void appendInput(std::string new_field_name,
966  std::unique_ptr<const RexScalar> new_input);
967 
968  std::string toString() const override {
969  std::string result =
970  "(RelProject<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">";
971  for (const auto& scalar_expr : scalar_exprs_) {
972  result += " " + scalar_expr->toString();
973  }
974  return result + ")";
975  }
976 
977  std::shared_ptr<RelAlgNode> deepCopy() const override {
978  return std::make_shared<RelProject>(*this);
979  }
980 
981  bool hasWindowFunctionExpr() const;
982 
983  void addHint(const HintExplained& hint_explained) {
984  if (!hint_applied_) {
985  hint_applied_ = true;
986  }
987  hints_->emplace(hint_explained.getHintName(), hint_explained);
988  }
989 
990  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
991  if (hint_applied_ && !hints_->empty()) {
992  return hints_->find(candidate_hint_name) != hints_->end();
993  }
994  return false;
995  }
996 
997  const HintExplained& getHintInfo(const std::string& hint_name) const {
998  CHECK(hint_applied_);
999  CHECK(!hints_->empty());
1000  CHECK(hasHintEnabled(hint_name));
1001  return hints_->at(hint_name);
1002  }
1003 
1004  private:
1005  template <typename EXPR_VISITOR_FUNCTOR>
1006  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
1007  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
1008  visitor_functor(i);
1009  }
1010  }
1011 
1014  scalar_exprs_.emplace_back(std::make_unique<RexFunctionOperator const>(
1015  std::string("OFFSET_IN_FRAGMENT"), transient_vector, SQLTypeInfo(kINT, false)));
1016  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
1017  }
1018 
1019  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
1020  mutable std::vector<std::string> fields_;
1022  std::unique_ptr<Hints> hints_;
1023 };
1024 
1025 class RelAggregate : public RelAlgNode {
1026  public:
1027  // Takes ownership of the aggregate expressions.
1028  RelAggregate(const size_t groupby_count,
1029  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
1030  const std::vector<std::string>& fields,
1031  std::shared_ptr<const RelAlgNode> input)
1032  : groupby_count_(groupby_count)
1033  , agg_exprs_(std::move(agg_exprs))
1034  , fields_(fields)
1035  , hint_applied_(false)
1036  , hints_(std::make_unique<Hints>()) {
1037  inputs_.push_back(input);
1038  }
1039 
1040  RelAggregate(RelAggregate const&);
1041 
1042  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
1043 
1044  const size_t getGroupByCount() const { return groupby_count_; }
1045 
1046  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
1047 
1048  const std::vector<std::string>& getFields() const { return fields_; }
1049  void setFields(std::vector<std::string>& new_fields) {
1050  fields_ = std::move(new_fields);
1051  }
1052 
1053  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1054 
1055  std::vector<const RexAgg*> getAggregatesAndRelease() {
1056  std::vector<const RexAgg*> result;
1057  for (auto& agg_expr : agg_exprs_) {
1058  result.push_back(agg_expr.release());
1059  }
1060  return result;
1061  }
1062 
1063  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
1064  return std::move(agg_exprs_);
1065  }
1066 
1067  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
1068  return agg_exprs_;
1069  }
1070 
1071  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
1072  agg_exprs_ = std::move(agg_exprs);
1073  }
1074 
1075  std::string toString() const override {
1076  std::string result = "(RelAggregate<" +
1077  std::to_string(reinterpret_cast<uint64_t>(this)) + ">(groups: [";
1078  for (size_t group_index = 0; group_index < groupby_count_; ++group_index) {
1079  result += " " + std::to_string(group_index);
1080  }
1081  result += " ] aggs: [";
1082  for (const auto& agg_expr : agg_exprs_) {
1083  result += " " + agg_expr->toString();
1084  }
1085  return result + " ]))";
1086  }
1087 
1088  std::shared_ptr<RelAlgNode> deepCopy() const override {
1089  return std::make_shared<RelAggregate>(*this);
1090  }
1091 
1092  void addHint(const HintExplained& hint_explained) {
1093  if (!hint_applied_) {
1094  hint_applied_ = true;
1095  }
1096  hints_->emplace(hint_explained.getHintName(), hint_explained);
1097  }
1098 
1099  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1100  if (hint_applied_ && !hints_->empty()) {
1101  return hints_->find(candidate_hint_name) != hints_->end();
1102  }
1103  return false;
1104  }
1105 
1106  const HintExplained& getHintInfo(const std::string& hint_name) const {
1107  CHECK(hint_applied_);
1108  CHECK(!hints_->empty());
1109  CHECK(hasHintEnabled(hint_name));
1110  return hints_->at(hint_name);
1111  }
1112 
1113  private:
1114  const size_t groupby_count_;
1115  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1116  std::vector<std::string> fields_;
1118  std::unique_ptr<Hints> hints_;
1119 };
1120 
1121 class RelJoin : public RelAlgNode {
1122  public:
1123  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
1124  std::shared_ptr<const RelAlgNode> rhs,
1125  std::unique_ptr<const RexScalar>& condition,
1126  const JoinType join_type)
1127  : condition_(std::move(condition))
1128  , join_type_(join_type)
1129  , hint_applied_(false)
1130  , hints_(std::make_unique<Hints>()) {
1131  inputs_.push_back(lhs);
1132  inputs_.push_back(rhs);
1133  }
1134 
1135  RelJoin(RelJoin const&);
1136 
1137  JoinType getJoinType() const { return join_type_; }
1138 
1139  const RexScalar* getCondition() const { return condition_.get(); }
1140 
1141  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
1142 
1143  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1144  CHECK(condition);
1145  condition_ = std::move(condition);
1146  }
1147 
1148  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1149  std::shared_ptr<const RelAlgNode> input) override;
1150 
1151  std::string toString() const override {
1152  std::string result =
1153  "(RelJoin<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1154  result += condition_ ? condition_->toString() : "null";
1155  result += " " + std::to_string(static_cast<int>(join_type_));
1156  return result + "))";
1157  }
1158 
1159  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
1160 
1161  std::shared_ptr<RelAlgNode> deepCopy() const override {
1162  return std::make_shared<RelJoin>(*this);
1163  }
1164 
1165  void addHint(const HintExplained& hint_explained) {
1166  if (!hint_applied_) {
1167  hint_applied_ = true;
1168  }
1169  hints_->emplace(hint_explained.getHintName(), hint_explained);
1170  }
1171 
1172  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1173  if (hint_applied_ && !hints_->empty()) {
1174  return hints_->find(candidate_hint_name) != hints_->end();
1175  }
1176  return false;
1177  }
1178 
1179  const HintExplained& getHintInfo(const std::string& hint_name) const {
1180  CHECK(hint_applied_);
1181  CHECK(!hints_->empty());
1182  CHECK(hasHintEnabled(hint_name));
1183  return hints_->at(hint_name);
1184  }
1185 
1186  private:
1187  mutable std::unique_ptr<const RexScalar> condition_;
1190  std::unique_ptr<Hints> hints_;
1191 };
1192 
1193 class RelFilter : public RelAlgNode {
1194  public:
1195  RelFilter(std::unique_ptr<const RexScalar>& filter,
1196  std::shared_ptr<const RelAlgNode> input)
1197  : filter_(std::move(filter)) {
1198  CHECK(filter_);
1199  inputs_.push_back(input);
1200  }
1201 
1202  RelFilter(RelFilter const&);
1203 
1204  const RexScalar* getCondition() const { return filter_.get(); }
1205 
1206  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
1207 
1208  void setCondition(std::unique_ptr<const RexScalar>& condition) {
1209  CHECK(condition);
1210  filter_ = std::move(condition);
1211  }
1212 
1213  size_t size() const override { return inputs_[0]->size(); }
1214 
1215  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1216  std::shared_ptr<const RelAlgNode> input) override;
1217 
1218  std::string toString() const override {
1219  std::string result =
1220  "(RelFilter<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1221  result += filter_ ? filter_->toString() : "null";
1222  return result + "))";
1223  }
1224 
1225  std::shared_ptr<RelAlgNode> deepCopy() const override {
1226  return std::make_shared<RelFilter>(*this);
1227  }
1228 
1229  private:
1230  std::unique_ptr<const RexScalar> filter_;
1231 };
1232 
1233 // Synthetic node to assist execution of left-deep join relational algebra.
1235  public:
1236  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1237  RelAlgInputs inputs,
1238  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1239 
1240  const RexScalar* getInnerCondition() const;
1241 
1242  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1243 
1244  std::string toString() const override;
1245 
1246  size_t size() const override;
1247 
1248  std::shared_ptr<RelAlgNode> deepCopy() const override;
1249 
1250  bool coversOriginalNode(const RelAlgNode* node) const;
1251 
1252  private:
1253  std::unique_ptr<const RexScalar> condition_;
1254  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
1255  const std::shared_ptr<RelFilter> original_filter_;
1256  const std::vector<std::shared_ptr<const RelJoin>> original_joins_;
1257 };
1258 
1259 // The 'RelCompound' node combines filter and on the fly aggregate computation.
1260 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
1261 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
1262 // which can be efficiently executed with no intermediate buffers.
1264  public:
1265  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
1266  // or aggregate expressions owned by 'agg_exprs_', with the arguments
1267  // owned by 'scalar_sources_'.
1268  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
1269  const std::vector<const Rex*>& target_exprs,
1270  const size_t groupby_count,
1271  const std::vector<const RexAgg*>& agg_exprs,
1272  const std::vector<std::string>& fields,
1273  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
1274  const bool is_agg,
1275  bool update_disguised_as_select = false,
1276  bool delete_disguised_as_select = false,
1277  bool varlen_update_required = false,
1278  TableDescriptor const* manipulation_target_table = nullptr,
1279  ColumnNameList target_columns = ColumnNameList())
1280  : ModifyManipulationTarget(update_disguised_as_select,
1281  delete_disguised_as_select,
1282  varlen_update_required,
1283  manipulation_target_table,
1284  target_columns)
1285  , filter_expr_(std::move(filter_expr))
1286  , groupby_count_(groupby_count)
1287  , fields_(fields)
1288  , is_agg_(is_agg)
1289  , scalar_sources_(std::move(scalar_sources))
1290  , target_exprs_(target_exprs)
1291  , hint_applied_(false)
1292  , hints_(std::make_unique<Hints>()) {
1293  CHECK_EQ(fields.size(), target_exprs.size());
1294  for (auto agg_expr : agg_exprs) {
1295  agg_exprs_.emplace_back(agg_expr);
1296  }
1297  }
1298 
1299  RelCompound(RelCompound const&);
1300 
1301  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1302  std::shared_ptr<const RelAlgNode> input) override;
1303 
1304  size_t size() const override { return target_exprs_.size(); }
1305 
1306  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
1307 
1308  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
1309  filter_expr_ = std::move(new_expr);
1310  }
1311 
1312  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
1313 
1314  const std::vector<std::string>& getFields() const { return fields_; }
1315 
1316  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1317 
1318  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
1319 
1320  const RexScalar* getScalarSource(const size_t i) const {
1321  return scalar_sources_[i].get();
1322  }
1323 
1324  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
1325  CHECK_EQ(new_sources.size(), scalar_sources_.size());
1326  scalar_sources_ = std::move(new_sources);
1327  }
1328 
1329  const size_t getGroupByCount() const { return groupby_count_; }
1330 
1331  bool isAggregate() const { return is_agg_; }
1332 
1333  std::string toString() const override {
1334  std::string result =
1335  "(RelCompound<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1336  result += (filter_expr_ ? filter_expr_->toString() : "null") + " ";
1337  for (const auto target_expr : target_exprs_) {
1338  result += target_expr->toString() + " ";
1339  }
1340  result += "groups: [";
1341  for (size_t group_index = 0; group_index < groupby_count_; ++group_index) {
1342  result += " " + std::to_string(group_index);
1343  }
1344  result += " ] sources: [";
1345  for (const auto& scalar_source : scalar_sources_) {
1346  result += " " + scalar_source->toString();
1347  }
1348  return result + " ]))";
1349  }
1350 
1351  std::shared_ptr<RelAlgNode> deepCopy() const override {
1352  return std::make_shared<RelCompound>(*this);
1353  }
1354 
1355  void addHint(const HintExplained& hint_explained) {
1356  if (!hint_applied_) {
1357  hint_applied_ = true;
1358  }
1359  hints_->emplace(hint_explained.getHintName(), hint_explained);
1360  }
1361 
1362  const bool hasHintEnabled(const std::string& candidate_hint_name) const {
1363  if (hint_applied_ && !hints_->empty()) {
1364  return hints_->find(candidate_hint_name) != hints_->end();
1365  }
1366  return false;
1367  }
1368 
1369  const HintExplained& getHintInfo(const std::string& hint_name) const {
1370  CHECK(hint_applied_);
1371  CHECK(!hints_->empty());
1372  CHECK(hasHintEnabled(hint_name));
1373  return hints_->at(hint_name);
1374  }
1375 
1376  private:
1377  std::unique_ptr<const RexScalar> filter_expr_;
1378  const size_t groupby_count_;
1379  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1380  const std::vector<std::string> fields_;
1381  const bool is_agg_;
1382  std::vector<std::unique_ptr<const RexScalar>>
1383  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not actually
1384  // projected, just owned
1385  const std::vector<const Rex*> target_exprs_;
1387  std::unique_ptr<Hints> hints_;
1388 };
1389 
1390 class RelSort : public RelAlgNode {
1391  public:
1392  RelSort(const std::vector<SortField>& collation,
1393  const size_t limit,
1394  const size_t offset,
1395  std::shared_ptr<const RelAlgNode> input)
1396  : collation_(collation), limit_(limit), offset_(offset) {
1397  inputs_.push_back(input);
1398  }
1399 
1400  bool operator==(const RelSort& that) const {
1401  return limit_ == that.limit_ && offset_ == that.offset_ &&
1402  empty_result_ == that.empty_result_ && hasEquivCollationOf(that);
1403  }
1404 
1405  size_t collationCount() const { return collation_.size(); }
1406 
1407  SortField getCollation(const size_t i) const {
1408  CHECK_LT(i, collation_.size());
1409  return collation_[i];
1410  }
1411 
1412  void setCollation(std::vector<SortField>&& collation) {
1413  collation_ = std::move(collation);
1414  }
1415 
1416  void setEmptyResult(bool emptyResult) { empty_result_ = emptyResult; }
1417 
1418  bool isEmptyResult() const { return empty_result_; }
1419 
1420  size_t getLimit() const { return limit_; }
1421 
1422  size_t getOffset() const { return offset_; }
1423 
1424  std::string toString() const override {
1425  std::string result =
1426  "(RelSort<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1427  result += "limit: " + std::to_string(limit_) + " ";
1428  result += "offset: " + std::to_string(offset_) + " ";
1429  result += "empty_result: " + std::to_string(empty_result_) + " ";
1430  result += "collation: [ ";
1431  for (const auto& sort_field : collation_) {
1432  result += sort_field.toString() + " ";
1433  }
1434  result += "]";
1435  return result + "))";
1436  }
1437 
1438  size_t size() const override { return inputs_[0]->size(); }
1439 
1440  std::shared_ptr<RelAlgNode> deepCopy() const override {
1441  return std::make_shared<RelSort>(*this);
1442  }
1443 
1444  private:
1445  std::vector<SortField> collation_;
1446  const size_t limit_;
1447  const size_t offset_;
1449 
1450  bool hasEquivCollationOf(const RelSort& that) const;
1451 };
1452 
1453 class RelModify : public RelAlgNode {
1454  public:
1455  enum class ModifyOperation { Insert, Delete, Update };
1456  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
1457  using TargetColumnList = std::vector<std::string>;
1458 
1459  static std::string yieldModifyOperationString(ModifyOperation const op) {
1460  switch (op) {
1461  case ModifyOperation::Delete:
1462  return "DELETE";
1463  case ModifyOperation::Insert:
1464  return "INSERT";
1465  case ModifyOperation::Update:
1466  return "UPDATE";
1467  default:
1468  break;
1469  }
1470  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
1471  }
1472 
1473  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
1474  if (op_string == "INSERT") {
1475  return ModifyOperation::Insert;
1476  } else if (op_string == "DELETE") {
1477  return ModifyOperation::Delete;
1478  } else if (op_string == "UPDATE") {
1479  return ModifyOperation::Update;
1480  }
1481 
1482  throw std::runtime_error(
1483  std::string("Unsupported logical modify operation encountered " + op_string));
1484  }
1485 
1487  TableDescriptor const* const td,
1488  bool flattened,
1489  std::string const& op_string,
1490  TargetColumnList const& target_column_list,
1491  RelAlgNodeInputPtr input)
1492  : catalog_(cat)
1493  , table_descriptor_(td)
1494  , flattened_(flattened)
1495  , operation_(yieldModifyOperationEnum(op_string))
1496  , target_column_list_(target_column_list) {
1498  inputs_.push_back(input);
1499  }
1500 
1502  TableDescriptor const* const td,
1503  bool flattened,
1504  ModifyOperation op,
1505  TargetColumnList const& target_column_list,
1506  RelAlgNodeInputPtr input)
1507  : catalog_(cat)
1508  , table_descriptor_(td)
1509  , flattened_(flattened)
1510  , operation_(op)
1511  , target_column_list_(target_column_list) {
1513  inputs_.push_back(input);
1514  }
1515 
1516  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
1517  bool const isFlattened() const { return flattened_; }
1518  ModifyOperation getOperation() const { return operation_; }
1519  TargetColumnList const& getUpdateColumnNames() { return target_column_list_; }
1520  int getUpdateColumnCount() const { return target_column_list_.size(); }
1521 
1522  size_t size() const override { return 0; }
1523  std::shared_ptr<RelAlgNode> deepCopy() const override {
1524  return std::make_shared<RelModify>(*this);
1525  }
1526 
1527  std::string toString() const override {
1528  std::ostringstream result_stream;
1529  result_stream << std::boolalpha
1530  << "(RelModify<" + std::to_string(reinterpret_cast<uint64_t>(this)) +
1531  "> "
1532  << table_descriptor_->tableName << " flattened= " << flattened_
1533  << " operation= " << yieldModifyOperationString(operation_) << ")";
1534 
1535  return result_stream.str();
1536  }
1537 
1539  RelProject const* previous_project_node =
1540  dynamic_cast<RelProject const*>(inputs_[0].get());
1541  CHECK(previous_project_node != nullptr);
1542 
1543  previous_project_node->setUpdateViaSelectFlag();
1544  // remove the offset column in the projection for update handling
1545  target_column_list_.pop_back();
1546 
1547  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1548  previous_project_node->setTargetColumns(target_column_list_);
1549 
1550  int target_update_column_expr_start = 0;
1551  int target_update_column_expr_end = (int)(target_column_list_.size() - 1);
1552  CHECK(target_update_column_expr_start >= 0);
1553  CHECK(target_update_column_expr_end >= 0);
1554 
1555  bool varlen_update_required = false;
1556 
1557  auto varlen_scan_visitor = [this,
1558  &varlen_update_required,
1559  target_update_column_expr_start,
1560  target_update_column_expr_end](int index) {
1561  if (index >= target_update_column_expr_start &&
1562  index <= target_update_column_expr_end) {
1563  auto target_index = index - target_update_column_expr_start;
1564 
1565  auto* column_desc = catalog_.getMetadataForColumn(
1566  table_descriptor_->tableId, target_column_list_[target_index]);
1567  CHECK(column_desc);
1568 
1569  if (table_descriptor_->nShards) {
1570  const auto shard_cd =
1571  catalog_.getShardColumnMetadataForTable(table_descriptor_);
1572  CHECK(shard_cd);
1573  if ((column_desc->columnName == shard_cd->columnName)) {
1574  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
1575  }
1576  }
1577 
1578  // Check for valid types
1579  if (column_desc->columnType.is_varlen()) {
1580  varlen_update_required = true;
1581  }
1582  if (column_desc->columnType.is_geometry()) {
1583  throw std::runtime_error("UPDATE of a geo column is unsupported.");
1584  }
1585  }
1586  };
1587 
1588  previous_project_node->visitScalarExprs(varlen_scan_visitor);
1589  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
1590  }
1591 
1593  RelProject const* previous_project_node =
1594  dynamic_cast<RelProject const*>(inputs_[0].get());
1595  CHECK(previous_project_node != nullptr);
1596  previous_project_node->setDeleteViaSelectFlag();
1597  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1598  }
1599 
1600  private:
1606 };
1607 
1609  public:
1610  RelTableFunction(const std::string& function_name,
1611  RelAlgInputs inputs,
1612  std::vector<std::string>& fields,
1613  std::vector<const Rex*> col_inputs,
1614  std::vector<std::unique_ptr<const RexScalar>>& table_func_inputs,
1615  std::vector<std::unique_ptr<const RexScalar>>& target_exprs)
1616  : function_name_(function_name)
1617  , fields_(fields)
1618  , col_inputs_(col_inputs)
1619  , table_func_inputs_(std::move(table_func_inputs))
1620  , target_exprs_(std::move(target_exprs)) {
1621  for (const auto& input : inputs) {
1622  inputs_.emplace_back(input);
1623  }
1624  }
1625 
1627 
1628  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1629  std::shared_ptr<const RelAlgNode> input) override;
1630 
1631  std::string getFunctionName() const { return function_name_; }
1632 
1633  size_t size() const override { return target_exprs_.size(); }
1634 
1635  size_t getTableFuncInputsSize() const { return table_func_inputs_.size(); }
1636 
1637  size_t getColInputsSize() const { return col_inputs_.size(); }
1638 
1639  const RexScalar* getTableFuncInputAt(const size_t idx) const {
1640  CHECK_LT(idx, table_func_inputs_.size());
1641  return table_func_inputs_[idx].get();
1642  }
1643 
1644  const RexScalar* getTableFuncInputAtAndRelease(const size_t idx) {
1645  CHECK_LT(idx, table_func_inputs_.size());
1646  return table_func_inputs_[idx].release();
1647  }
1648 
1649  void setTableFuncInputs(std::vector<std::unique_ptr<const RexScalar>>& exprs) {
1650  table_func_inputs_ = std::move(exprs);
1651  }
1652 
1653  std::string getFieldName(const size_t idx) const {
1654  CHECK_LT(idx, fields_.size());
1655  return fields_[idx];
1656  }
1657 
1658  std::shared_ptr<RelAlgNode> deepCopy() const override {
1659  return std::make_shared<RelTableFunction>(*this);
1660  }
1661 
1662  std::string toString() const override {
1663  std::string result = "RelTableFunction<" +
1664  std::to_string(reinterpret_cast<uint64_t>(this)) + ">(" +
1665  function_name_ + ", ";
1666 
1667  result += "inputs=[";
1668  for (size_t i = 0; i < inputs_.size(); ++i) {
1669  result += inputs_[i]->toString();
1670  if (i < inputs_.size() - 1) {
1671  result += ", ";
1672  }
1673  }
1674  result += "], ";
1675 
1676  result += "target_exprs=[";
1677  for (size_t i = 0; i < target_exprs_.size(); ++i) {
1678  result += target_exprs_[i]->toString();
1679  if (i < target_exprs_.size() - 1) {
1680  result += ", ";
1681  }
1682  }
1683  result += "], ";
1684 
1685  result += "table_func_inputs=[";
1686  for (size_t i = 0; i < table_func_inputs_.size(); ++i) {
1687  result += table_func_inputs_[i]->toString();
1688  if (i < table_func_inputs_.size() - 1) {
1689  result += ", ";
1690  }
1691  }
1692  result += "], ";
1693 
1694  result += "col_inputs=[";
1695  for (size_t i = 0; i < col_inputs_.size(); ++i) {
1696  result += std::to_string((size_t)col_inputs_[i]);
1697  if (i < col_inputs_.size() - 1) {
1698  result += ", ";
1699  }
1700  }
1701  result += "], ";
1702 
1703  result += "fields=[";
1704  for (size_t i = 0; i < fields_.size(); ++i) {
1705  result += fields_[i];
1706  if (i < fields_.size() - 1) {
1707  result += ", ";
1708  }
1709  }
1710  result += "])";
1711 
1712  return result;
1713  }
1714 
1715  private:
1716  std::string function_name_;
1717  std::vector<std::string> fields_;
1718 
1719  std::vector<const Rex*>
1720  col_inputs_; // owned by `table_func_inputs_`, but allows picking out the specific
1721  // input columns vs other table function inputs (e.g. literals)
1722  std::vector<std::unique_ptr<const RexScalar>> table_func_inputs_;
1723 
1724  std::vector<std::unique_ptr<const RexScalar>>
1725  target_exprs_; // Note: these should all be RexRef but are stored as RexScalar for
1726  // consistency
1727 };
1728 
1730  public:
1731  using RowValues = std::vector<std::unique_ptr<const RexScalar>>;
1732 
1733  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type,
1734  std::vector<RowValues>& values)
1735  : tuple_type_(tuple_type), values_(std::move(values)) {}
1736 
1738 
1739  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
1740 
1741  std::string toString() const override {
1742  std::string ret =
1743  "(RelLogicalValues<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">";
1744  for (const auto& target_meta_info : tuple_type_) {
1745  ret += " (" + target_meta_info.get_resname() + " " +
1746  target_meta_info.get_type_info().get_type_name() + ")";
1747  }
1748  ret += " )";
1749  return ret;
1750  }
1751 
1752  const RexScalar* getValueAt(const size_t row_idx, const size_t col_idx) const {
1753  CHECK_LT(row_idx, values_.size());
1754  const auto& row = values_[row_idx];
1755  CHECK_LT(col_idx, row.size());
1756  return row[col_idx].get();
1757  }
1758 
1759  size_t getRowsSize() const {
1760  if (values_.empty()) {
1761  return 0;
1762  } else {
1763  return values_.front().size();
1764  }
1765  }
1766 
1767  size_t getNumRows() const { return values_.size(); }
1768 
1769  size_t size() const override { return tuple_type_.size(); }
1770 
1771  bool hasRows() const { return !values_.empty(); }
1772 
1773  std::shared_ptr<RelAlgNode> deepCopy() const override {
1774  return std::make_shared<RelLogicalValues>(*this);
1775  }
1776 
1777  private:
1778  const std::vector<TargetMetaInfo> tuple_type_;
1779  const std::vector<RowValues> values_;
1780 };
1781 
1782 class RelLogicalUnion : public RelAlgNode {
1783  public:
1784  RelLogicalUnion(RelAlgInputs, bool is_all);
1785  std::shared_ptr<RelAlgNode> deepCopy() const override {
1786  return std::make_shared<RelLogicalUnion>(*this);
1787  }
1788  size_t size() const override;
1789  std::string toString() const override;
1790 
1791  std::string getFieldName(const size_t i) const;
1792 
1793  inline bool isAll() const { return is_all_; }
1794  // Will throw a std::runtime_error if MetaInfo types don't match.
1795  void checkForMatchingMetaInfoTypes() const;
1796  RexScalar const* copyAndRedirectSource(RexScalar const*, size_t input_idx) const;
1797 
1798  // Not unique_ptr to allow for an easy deepCopy() implementation.
1799  mutable std::vector<std::shared_ptr<const RexScalar>> scalar_exprs_;
1800 
1801  private:
1802  bool const is_all_;
1803 };
1804 
1805 class QueryNotSupported : public std::runtime_error {
1806  public:
1807  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
1808 };
1809 
1819 class RelAlgDagBuilder : public boost::noncopyable {
1820  public:
1821  RelAlgDagBuilder() = delete;
1822 
1829  RelAlgDagBuilder(const std::string& query_ra,
1831  const RenderInfo* render_info);
1832 
1842  RelAlgDagBuilder(RelAlgDagBuilder& root_dag_builder,
1843  const rapidjson::Value& query_ast,
1844  const Catalog_Namespace::Catalog& cat,
1845  const RenderInfo* render_opts);
1846 
1847  void eachNode(std::function<void(RelAlgNode const*)> const&) const;
1848 
1852  const RelAlgNode& getRootNode() const {
1853  CHECK(nodes_.size());
1854  const auto& last_ptr = nodes_.back();
1855  CHECK(last_ptr);
1856  return *last_ptr;
1857  }
1858 
1859  std::shared_ptr<const RelAlgNode> getRootNodeShPtr() const {
1860  CHECK(nodes_.size());
1861  return nodes_.back();
1862  }
1863 
1868  void registerSubquery(std::shared_ptr<RexSubQuery> subquery) {
1869  subqueries_.push_back(subquery);
1870  }
1871 
1875  const std::vector<std::shared_ptr<RexSubQuery>>& getSubqueries() const {
1876  return subqueries_;
1877  }
1878 
1879  void registerQueryHints(QueryHint& query_hint) { query_hint_ = query_hint; }
1880 
1881  const QueryHint getQueryHints() const { return query_hint_; }
1882 
1886  void resetQueryExecutionState();
1887 
1888  private:
1889  void build(const rapidjson::Value& query_ast, RelAlgDagBuilder& root_dag_builder);
1890 
1892  std::vector<std::shared_ptr<RelAlgNode>> nodes_;
1893  std::vector<std::shared_ptr<RexSubQuery>> subqueries_;
1896 };
1897 
1898 using RANodeOutput = std::vector<RexInput>;
1899 
1900 RANodeOutput get_node_output(const RelAlgNode* ra_node);
1901 
1902 std::string tree_string(const RelAlgNode*, const size_t depth = 0);
std::vector< std::shared_ptr< const RexScalar > > scalar_exprs_
std::string toString() const override
std::string toString() const override
std::string getFunctionName() const
bool is_agg(const Analyzer::Expr *expr)
void validate_non_foreign_table_write(const TableDescriptor *table_descriptor)
Definition: FsiUtils.h:22
std::unique_ptr< const RexOperator > disambiguatedOperands(ConstRexScalarPtrVector &operands, ConstRexScalarPtrVector &partition_keys, ConstRexScalarPtrVector &order_keys, const std::vector< SortField > &collation) const
std::unique_ptr< const RexScalar > condition_
const std::vector< TargetMetaInfo > getTupleType() const
SQLOps getOperator() const
SQLAgg
Definition: sqldefs.h:71
const bool hasHintEnabled(const std::string &candidate_hint_name) const
size_t size() const
#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()
const std::vector< SortField > & getCollation() const
const ConstRexScalarPtrVector & getPartitionKeys() const
void setFields(std::vector< std::string > &fields)
std::vector< std::unique_ptr< const RexScalar > > outer_conditions_per_level_
const size_t limit_
const std::vector< std::string > & getFields() const
const QueryHint getQueryHints() const
void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input) override
const size_t getGroupByCount() const
JoinType
Definition: sqldefs.h:107
std::string toString() const override
void setSourceNode(const RelAlgNode *node) const
std::shared_ptr< RelAlgNode > deepCopy() const override
const RelAlgNode * getRelAlg() const
ColumnNameList target_columns_
void setIndex(const unsigned in_index) const
std::vector< std::unique_ptr< const RexScalar > > table_func_inputs_
const TableDescriptor * getTableDescriptor() const
std::string toString() const override
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 std::shared_ptr< const RelAlgNode > ra_
RelAlgNode(RelAlgInputs inputs={})
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:86
size_t collationCount() const
SqlWindowFunctionKind getKind() const
bool isQueryHint() const
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_
const std::string name_
size_t size() const override
unsigned getId() const
const unsigned type_scale_
std::string toString() const override
std::string toString() const override
std::string tree_string(const RelAlgNode *, const size_t depth=0)
const bool hasHintEnabled(const std::string &candidate_hint_name) const
RexOperator(const SQLOps op, std::vector< std::unique_ptr< const RexScalar >> &operands, const SQLTypeInfo &type)
static thread_local unsigned crt_id_
const RelAlgNode & getRootNode() const
void setCondition(std::unique_ptr< const RexScalar > &condition)
std::string function_name_
void addHint(const HintExplained &hint_explained)
T getVal() const
void setEmptyResult(bool emptyResult)
std::unique_ptr< const RexScalar > ConstRexScalarPtr
const RexWindowBound & getLowerBound() const
const JoinType join_type_
size_t getColInputsSize() const
SortDirection getSortDir() const
NullSortedPosition
void applyDeleteModificationsToInputNode()
std::vector< std::string > TargetColumnList
size_t size() const override
void setTargetColumns(ColumnNameList const &target_columns) const
unsigned getPrecision() const
const RexWindowBound upper_bound_
auto const isDeleteViaSelect() const
const SqlWindowFunctionKind kind_
std::unique_ptr< RexLiteral > deepCopy() const
std::string toString() const override
size_t size() const override
std::vector< const Rex * > col_inputs_
SQLOps
Definition: sqldefs.h:29
const RexScalar * getProjectAt(const size_t idx) const
const std::vector< std::string > fields_
const ConstRexScalarPtrVector & getOrderKeys() const
bool isAll() const
const Rex * getTargetExpr(const size_t i) const
size_t getOperand(size_t idx) const
std::string toString() const override
void applyUpdateModificationsToInputNode()
bool operator==(const RelSort &that) const
std::shared_ptr< const RelAlgNode > getAndOwnInput(const size_t idx) const
std::string toString() const override
const boost::variant< int64_t, double, std::string, bool, void * > literal_
size_t branchCount() const
std::unordered_map< std::string, std::string > kv_options_
std::shared_ptr< std::shared_ptr< const ExecutionResult > > result_
std::unique_ptr< const RexScalar > else_expr_
void addManagedInput(std::shared_ptr< const RelAlgNode > input)
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)
std::vector< std::string > fields_
const RexScalar * getTableFuncInputAt(const size_t idx) const
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
RexInput(const RelAlgNode *node, const unsigned in_index)
std::shared_ptr< RelAlgNode > deepCopy() const override
void setModifiedTableDescriptor(TableDescriptor const *td) const
void addHint(const HintExplained &hint_explained)
const HintExplained & getHintInfo(const std::string &hint_name) const
const void * context_data_
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
std::shared_ptr< const RelAlgNode > getRootNodeShPtr() const
std::shared_ptr< RelAlgNode > deepCopy() const override
std::string hint_name_
std::string getFieldName(const size_t idx) const
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
bool empty_result_
virtual ~Rex()
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
TableDescriptor const * getModifiedTableDescriptor() const
const TableDescriptor * td_
const Catalog_Namespace::Catalog & cat_
void setUpdateViaSelectFlag() const
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
const std::vector< std::string > & getFields() 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)
void addHint(const HintExplained &hint_explained)
std::string to_string(char const *&&v)
const SQLAgg agg_
const size_t groupby_count_
const RexScalar * getCondition() const
auto const isUpdateViaSelect() const
std::unique_ptr< RexInput > deepCopy() const
const std::string getFieldName(const size_t i) const
std::vector< SortField > collation_
SortField getCollation(const size_t i) const
const RexScalar * getWhen(const size_t idx) const
std::string toString() const override
std::string toString() const override
size_t getIndex() const
const std::string getFieldName(const size_t i) const
const RexWindowBound & getUpperBound() const
void addHint(const HintExplained &hint_explained)
std::vector< RexLiteral > RexLiteralArray
This file contains the class specification and related data structures for Catalog.
std::vector< std::shared_ptr< RexSubQuery > > subqueries_
TargetColumnList const & getUpdateColumnNames()
const RenderInfo * render_info_
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_
auto const isVarlenUpdateRequired() const
std::string toString() const override
TableDescriptor const *const getTableDescriptor() const
bool operator==(const RexInput &that) const
bool hasInput(const RelAlgNode *needle) const
virtual ~RelAlgNode()
std::string cat(Ts &&... args)
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
std::vector< std::shared_ptr< RelAlgNode > > nodes_
std::shared_ptr< const RelAlgNode > RelAlgNodeInputPtr
const RexScalar * getThen(const size_t idx) const
std::shared_ptr< RelAlgNode > deepCopy() const override
bool isSimple() const
ConstRexScalarPtrVector getPartitionKeysAndRelease() const
const RelAlgNode * getSourceNode() const
const std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries() const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
const RexScalar * getTableFuncInputAtAndRelease(const size_t idx)
bool hasContextData() const
const bool distinct_
const NullSortedPosition nulls_pos_
const size_t offset_
#define CHECK_NE(x, y)
Definition: Logger.h:206
const std::vector< RowValues > values_
const RexScalar * getProjectAtAndRelease(const size_t idx) const
ColumnNameList const & getTargetColumns() const
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)
bool hasRows() const
void setDeleteViaSelectFlag() 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_
const size_t getAggExprsCount() const
const SQLTypeInfo & getType() const
std::vector< std::unique_ptr< const RexScalar > > scalar_exprs_
const size_t getScalarSourcesSize() const
size_t size() const override
std::shared_ptr< SQLTypeInfo > type_
JoinType getJoinType() const
size_t size() const override
const RexScalar * getAndReleaseCondition()
bool isNop() const
std::string sql_window_function_to_str(const SqlWindowFunctionKind kind)
RexSubQuery(const std::shared_ptr< const RelAlgNode > ra)
ModifyOperation getOperation() 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_
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)
std::vector< std::unique_ptr< const RexScalar > > operands_
const size_t groupby_count_
const std::vector< std::string > & getListOptions()
std::vector< std::string > fields_
const std::string & getHintName() const
std::shared_ptr< RelAlgNode > deepCopy() const override
virtual std::unique_ptr< const RexOperator > getDisambiguated(std::vector< std::unique_ptr< const RexScalar >> &operands) const
RelSort(const std::vector< SortField > &collation, const size_t limit, const size_t offset, std::shared_ptr< const RelAlgNode > input)
RANodeOutput get_node_output(const RelAlgNode *ra_node)
unsigned getTypeScale() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< RelAlgNode > deepCopy() const override
const RelAlgNode * node_
std::unique_ptr< Hints > hints_
SQLTypes getType() const
void setInheritPaths(std::vector< int > &interit_paths)
virtual void replaceInput(std::shared_ptr< const RelAlgNode > old_input, std::shared_ptr< const RelAlgNode > input)
static std::string yieldModifyOperationString(ModifyOperation const op)
size_t getOffset() const
size_t size() const override
const SQLTypes type_
static ModifyOperation yieldModifyOperationEnum(std::string const &op_string)
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())
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::string getFieldName(const size_t i) const
std::unique_ptr< RexAgg > deepCopy() const
std::unordered_map< std::string, HintExplained > Hints
void setContextData(const void *context_data) const
const HintExplained & getHintInfo(const std::string &hint_name) const
const void * getContextData() 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)
std::vector< std::shared_ptr< const RelAlgNode > > RelAlgInputs
const std::vector< SortField > collation_
#define CHECK_LT(x, y)
Definition: Logger.h:207
Definition: sqltypes.h:54
NullSortedPosition getNullsPosition() const
const HintExplained & getHintInfo(const std::string &hint_name) const
const std::vector< int > & getInteritPath()
void setCollation(std::vector< SortField > &&collation)
bool hasOptions() const
std::unique_ptr< Hints > hints_
const HintExplained & getHintInfo(const std::string &hint_name) const
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
const RexScalar * getCondition() const
const size_t getGroupByCount() const
std::string toString() const override
std::unique_ptr< Hints > hints_
const std::string getFieldName(const size_t i) const
const std::vector< const Rex * > target_exprs_
unsigned getIndex() const
void setTableFuncInputs(std::vector< std::unique_ptr< const RexScalar >> &exprs)
const HintExplained & getHintInfo(const std::string &hint_name) const
size_t getLimit() const
std::vector< std::unique_ptr< const RexScalar > > RowValues
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
const RexScalar * getScalarSource(const size_t i) const
void injectOffsetInFragmentExpr() const
const RexScalar * getAndReleaseCondition() const
void registerQueryHints(QueryHint &query_hint)
SQLAgg getKind() const
const size_t inputCount() const
SortField(const size_t field, const SortDirection sort_dir, const NullSortedPosition nulls_pos)
std::unique_ptr< const RexScalar > filter_expr_
const RexScalar * getOperandAndRelease(const size_t idx) const
void resetQueryExecutionState()
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
bool isAggregate() const
ConstRexScalarPtrVector order_keys_
bool operator==(const SortField &that) const
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, ModifyOperation op, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
void registerSubquery(std::shared_ptr< RexSubQuery > subquery)
void setKVOptions(std::unordered_map< std::string, std::string > &kv_options)
std::shared_ptr< RelAlgNode > deepCopy() const override
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type, std::vector< RowValues > &values)
std::string toString() const override
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_
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::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar > > > expr_pair_list_
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 std::vector< std::string > field_names_
const std::vector< std::string > & getFieldNames() const
std::string toString() const override
virtual std::string toString() const =0
const SortDirection sort_dir_
std::vector< const RexAgg * > getAggregatesAndRelease()
const RexScalar * getValueAt(const size_t row_idx, const size_t col_idx) const
const RexScalar * getFilterExpr() const
ModifyOperation operation_
#define CHECK(condition)
Definition: Logger.h:197
RelProject(std::vector< std::unique_ptr< const RexScalar >> &scalar_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
HintExplained(std::string hint_name, bool query_hint, bool is_marker, bool has_kv_type_options)
bool const isFlattened() const
std::string toString() const override
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)
std::unique_ptr< RexRef > deepCopy() const
const RelAlgNode * getInput(const size_t idx) const
const SQLTypeInfo & getType() const
std::vector< RexLiteralArray > TupleContentsArray
const std::vector< std::string > & getFields() const
const SQLTypeInfo type_
std::shared_ptr< RelAlgNode > deepCopy() const override
const std::vector< size_t > operands_
std::string toString() const override
std::shared_ptr< RelAlgNode > deepCopy() const override
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
const std::shared_ptr< RelFilter > original_filter_
unsigned getScale() const
std::vector< std::string > ColumnNameList
size_t getRowsSize() const
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
void setVarlenUpdateRequired(bool required) const
int getUpdateColumnCount() const
size_t size() const override
std::vector< RexInput > RANodeOutput
std::shared_ptr< const ExecutionResult > getExecutionResult() const
specifies the content in-memory of a row in the table metadata table
const std::string & getName() const
RexAgg(const SQLAgg agg, const bool distinct, const SQLTypeInfo &type, const std::vector< size_t > &operands)
const std::vector< std::unique_ptr< const RexAgg > > & getAggExprs() const
void setListOptions(std::vector< std::string > &list_options)
std::string toString() const
const size_t field_
std::string toString() const override
size_t operator()(const RexInput &rex_in) const
const RexWindowBound lower_bound_
SQLTypes getTargetType() const
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)
RelScan(const TableDescriptor *td, const std::vector< std::string > &field_names)
size_t size() const override
bool isEmptyResult() const
const unsigned scale_
size_t getTableFuncInputsSize() const
TargetColumnList target_column_list_
void setAggExprs(std::vector< std::unique_ptr< const RexAgg >> &agg_exprs)
std::vector< std::string > fields_
size_t getNumRows() const
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
ConstRexScalarPtrVector getOrderKeysAndRelease() const
unsigned getTypePrecision() const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t size() const
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)
bool hasKvOptions() const
RexRef(const size_t index)
const SQLTypeInfo & getType() const
size_t getField() const
const bool hasHintEnabled(const std::string &candidate_hint_name) const
constexpr auto is_datetime(SQLTypes type)
Definition: sqltypes.h:202
std::vector< std::unique_ptr< const RexScalar > > target_exprs_
const bool is_agg_
std::vector< int > inherit_paths_
bool isDistinct() const
std::string toString() const override
const unsigned id_
const RexScalar * getElse() const