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