OmniSciDB  04ee39c94c
RelAlgAbstractInterpreter.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 
17 #ifndef QUERYENGINE_RELALGABSTRACTINTERPRETER_H
18 #define QUERYENGINE_RELALGABSTRACTINTERPRETER_H
19 
20 #include "../Catalog/Catalog.h"
21 #include "../Shared/ConfigResolve.h"
22 #include "../Shared/Rendering/RenderQueryOptions.h"
23 #include "../Shared/sql_window_function_to_string.h"
24 
25 #include "TargetMetaInfo.h"
26 #include "TypePunning.h"
27 
28 #include <rapidjson/document.h>
29 #include <boost/make_unique.hpp>
30 #include <boost/utility.hpp>
31 #include <boost/variant.hpp>
32 
33 #include <iterator>
34 #include <memory>
35 #include <unordered_map>
36 
37 using ColumnNameList = std::vector<std::string>;
38 
39 class Rex {
40  public:
41  virtual std::string toString() const = 0;
42 
43  virtual ~Rex() {}
44 };
45 
46 class RexScalar : public Rex {};
47 
48 // For internal use of the abstract interpreter only. The result after abstract
49 // interpretation will not have any references to 'RexAbstractInput' objects.
50 class RexAbstractInput : public RexScalar {
51  public:
52  RexAbstractInput(const unsigned in_index) : in_index_(in_index) {}
53 
54  unsigned getIndex() const { return in_index_; }
55 
56  void setIndex(const unsigned in_index) const { in_index_ = in_index; }
57 
58  std::string toString() const override {
59  return "(RexAbstractInput " + std::to_string(in_index_) + ")";
60  }
61 
62  private:
63  mutable unsigned in_index_;
64 };
65 
66 class RexLiteral : public RexScalar {
67  public:
68  RexLiteral(const int64_t val,
69  const SQLTypes type,
70  const SQLTypes target_type,
71  const unsigned scale,
72  const unsigned precision,
73  const unsigned type_scale,
74  const unsigned type_precision)
75  : literal_(val)
76  , type_(type)
77  , target_type_(target_type)
78  , scale_(scale)
79  , precision_(precision)
80  , type_scale_(type_scale)
81  , type_precision_(type_precision) {
82  CHECK(type == kDECIMAL || type == kINTERVAL_DAY_TIME ||
83  type == kINTERVAL_YEAR_MONTH || is_datetime(type));
84  }
85 
86  RexLiteral(const double val,
87  const SQLTypes type,
88  const SQLTypes target_type,
89  const unsigned scale,
90  const unsigned precision,
91  const unsigned type_scale,
92  const unsigned type_precision)
93  : literal_(val)
94  , type_(type)
95  , target_type_(target_type)
96  , scale_(scale)
97  , precision_(precision)
98  , type_scale_(type_scale)
99  , type_precision_(type_precision) {
100  CHECK_EQ(kDOUBLE, type);
101  }
102 
103  RexLiteral(const std::string& val,
104  const SQLTypes type,
105  const SQLTypes target_type,
106  const unsigned scale,
107  const unsigned precision,
108  const unsigned type_scale,
109  const unsigned type_precision)
110  : literal_(val)
111  , type_(type)
112  , target_type_(target_type)
113  , scale_(scale)
114  , precision_(precision)
115  , type_scale_(type_scale)
116  , type_precision_(type_precision) {
117  CHECK_EQ(kTEXT, type);
118  }
119 
120  RexLiteral(const bool val,
121  const SQLTypes type,
122  const SQLTypes target_type,
123  const unsigned scale,
124  const unsigned precision,
125  const unsigned type_scale,
126  const unsigned type_precision)
127  : literal_(val)
128  , type_(type)
129  , target_type_(target_type)
130  , scale_(scale)
131  , precision_(precision)
132  , type_scale_(type_scale)
133  , type_precision_(type_precision) {
134  CHECK_EQ(kBOOLEAN, type);
135  }
136 
137  RexLiteral(const SQLTypes target_type)
138  : literal_(nullptr)
139  , type_(kNULLT)
140  , target_type_(target_type)
141  , scale_(0)
142  , precision_(0)
143  , type_scale_(0)
144  , type_precision_(0) {}
145 
146  template <class T>
147  T getVal() const {
148  const auto ptr = boost::get<T>(&literal_);
149  CHECK(ptr);
150  return *ptr;
151  }
152 
153  SQLTypes getType() const { return type_; }
154 
155  SQLTypes getTargetType() const { return target_type_; }
156 
157  unsigned getScale() const { return scale_; }
158 
159  unsigned getPrecision() const { return precision_; }
160 
161  unsigned getTypeScale() const { return type_scale_; }
162 
163  unsigned getTypePrecision() const { return type_precision_; }
164 
165  std::string toString() const override {
166  return "(RexLiteral " + boost::lexical_cast<std::string>(literal_) + ")";
167  }
168 
169  std::unique_ptr<RexLiteral> deepCopy() const {
170  switch (literal_.which()) {
171  case 0: {
172  int64_t val = getVal<int64_t>();
173  return boost::make_unique<RexLiteral>(
174  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
175  }
176  case 1: {
177  double val = getVal<double>();
178  return boost::make_unique<RexLiteral>(
179  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
180  }
181  case 2: {
182  auto val = getVal<std::string>();
183  return boost::make_unique<RexLiteral>(
184  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
185  }
186  case 3: {
187  bool val = getVal<bool>();
188  return boost::make_unique<RexLiteral>(
189  val, type_, target_type_, scale_, precision_, type_scale_, type_precision_);
190  }
191  case 4: {
192  return boost::make_unique<RexLiteral>(target_type_);
193  }
194  default:
195  CHECK(false);
196  }
197  return nullptr;
198  }
199 
200  private:
201  const boost::variant<int64_t, double, std::string, bool, void*> literal_;
204  const unsigned scale_;
205  const unsigned precision_;
206  const unsigned type_scale_;
207  const unsigned type_precision_;
208 };
209 
210 using RexLiteralArray = std::vector<RexLiteral>;
211 using TupleContentsArray = std::vector<RexLiteralArray>;
212 
213 class RexOperator : public RexScalar {
214  public:
215  RexOperator(const SQLOps op,
216  std::vector<std::unique_ptr<const RexScalar>>& operands,
217  const SQLTypeInfo& type)
218  : op_(op), operands_(std::move(operands)), type_(type) {}
219 
220  virtual std::unique_ptr<const RexOperator> getDisambiguated(
221  std::vector<std::unique_ptr<const RexScalar>>& operands) const {
222  return std::unique_ptr<const RexOperator>(new RexOperator(op_, operands, type_));
223  }
224 
225  size_t size() const { return operands_.size(); }
226 
227  const RexScalar* getOperand(const size_t idx) const {
228  CHECK(idx < operands_.size());
229  return operands_[idx].get();
230  }
231 
232  const RexScalar* getOperandAndRelease(const size_t idx) const {
233  CHECK(idx < operands_.size());
234  return operands_[idx].release();
235  }
236 
237  SQLOps getOperator() const { return op_; }
238 
239  const SQLTypeInfo& getType() const { return type_; }
240 
241  std::string toString() const override {
242  std::string result = "(RexOperator " + std::to_string(op_);
243  for (const auto& operand : operands_) {
244  result += " " + operand->toString();
245  }
246  return result + ")";
247  };
248 
249  protected:
250  const SQLOps op_;
251  mutable std::vector<std::unique_ptr<const RexScalar>> operands_;
253 };
254 
255 class RelAlgNode;
256 
257 class ExecutionResult;
258 
259 class RexSubQuery : public RexScalar {
260  public:
261  RexSubQuery(const std::shared_ptr<const RelAlgNode> ra)
262  : type_(new SQLTypeInfo(kNULLT, false))
263  , result_(new std::shared_ptr<const ExecutionResult>(nullptr))
264  , ra_(ra) {}
265 
266  // for deep copy
267  RexSubQuery(std::shared_ptr<SQLTypeInfo> type,
268  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result,
269  const std::shared_ptr<const RelAlgNode> ra)
270  : type_(type), result_(result), ra_(ra) {}
271 
272  RexSubQuery(const RexSubQuery&) = delete;
273 
274  RexSubQuery& operator=(const RexSubQuery&) = delete;
275 
276  RexSubQuery(RexSubQuery&&) = delete;
277 
278  RexSubQuery& operator=(RexSubQuery&&) = delete;
279 
280  const SQLTypeInfo& getType() const {
281  CHECK_NE(kNULLT, type_->get_type());
282  return *(type_.get());
283  }
284 
285  std::shared_ptr<const ExecutionResult> getExecutionResult() const {
286  CHECK(result_);
287  CHECK(result_.get());
288  return *(result_.get());
289  }
290 
291  const RelAlgNode* getRelAlg() const { return ra_.get(); }
292 
293  std::string toString() const override {
294  return "(RexSubQuery " + std::to_string(reinterpret_cast<const uint64_t>(this)) + ")";
295  }
296 
297  std::unique_ptr<RexSubQuery> deepCopy() const;
298 
299  void setExecutionResult(const std::shared_ptr<const ExecutionResult> result);
300 
301  private:
302  std::shared_ptr<SQLTypeInfo> type_;
303  std::shared_ptr<std::shared_ptr<const ExecutionResult>> result_;
304  const std::shared_ptr<const RelAlgNode> ra_;
305 };
306 
307 // The actual input node understood by the Executor.
308 // The in_index_ is relative to the output of node_.
309 class RexInput : public RexAbstractInput {
310  public:
311  RexInput(const RelAlgNode* node, const unsigned in_index)
312  : RexAbstractInput(in_index), node_(node) {}
313 
314  const RelAlgNode* getSourceNode() const { return node_; }
315 
316  // This isn't great, but we need it for coalescing nodes to Compound since
317  // RexInput in descendents need to be rebound to the newly created Compound.
318  // Maybe create a fresh RA tree with the required changes after each coalescing?
319  void setSourceNode(const RelAlgNode* node) const { node_ = node; }
320 
321  bool operator==(const RexInput& that) const {
322  return getSourceNode() == that.getSourceNode() && getIndex() == that.getIndex();
323  }
324 
325  std::string toString() const override {
326  return "(RexInput " + std::to_string(getIndex()) + " " +
327  std::to_string(reinterpret_cast<const uint64_t>(node_)) + ")";
328  }
329 
330  std::unique_ptr<RexInput> deepCopy() const {
331  return boost::make_unique<RexInput>(node_, getIndex());
332  }
333 
334  private:
335  mutable const RelAlgNode* node_;
336 };
337 
338 namespace std {
339 
340 template <>
341 struct hash<RexInput> {
342  size_t operator()(const RexInput& rex_in) const {
343  auto addr = rex_in.getSourceNode();
344  return *reinterpret_cast<const size_t*>(may_alias_ptr(&addr)) ^ rex_in.getIndex();
345  }
346 };
347 
348 } // namespace std
349 
350 // Not a real node created by Calcite. Created by us because CaseExpr is a node in our
351 // Analyzer.
352 class RexCase : public RexScalar {
353  public:
354  RexCase(std::vector<std::pair<std::unique_ptr<const RexScalar>,
355  std::unique_ptr<const RexScalar>>>& expr_pair_list,
356  std::unique_ptr<const RexScalar>& else_expr)
357  : expr_pair_list_(std::move(expr_pair_list)), else_expr_(std::move(else_expr)) {}
358 
359  size_t branchCount() const { return expr_pair_list_.size(); }
360 
361  const RexScalar* getWhen(const size_t idx) const {
362  CHECK(idx < expr_pair_list_.size());
363  return expr_pair_list_[idx].first.get();
364  }
365 
366  const RexScalar* getThen(const size_t idx) const {
367  CHECK(idx < expr_pair_list_.size());
368  return expr_pair_list_[idx].second.get();
369  }
370 
371  const RexScalar* getElse() const { return else_expr_.get(); }
372 
373  std::string toString() const override {
374  std::string ret = "(RexCase";
375  for (const auto& expr_pair : expr_pair_list_) {
376  ret += " " + expr_pair.first->toString() + " -> " + expr_pair.second->toString();
377  }
378  if (else_expr_) {
379  ret += " else " + else_expr_->toString();
380  }
381  ret += ")";
382  return ret;
383  }
384 
385  private:
386  std::vector<
387  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
389  std::unique_ptr<const RexScalar> else_expr_;
390 };
391 
393  public:
394  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
395  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
396 
397  RexFunctionOperator(const std::string& name,
398  ConstRexScalarPtrVector& operands,
399  const SQLTypeInfo& ti)
400  : RexOperator(kFUNCTION, operands, ti), name_(name) {}
401 
402  std::unique_ptr<const RexOperator> getDisambiguated(
403  std::vector<std::unique_ptr<const RexScalar>>& operands) const override {
404  return std::unique_ptr<const RexOperator>(
405  new RexFunctionOperator(name_, operands, getType()));
406  }
407 
408  const std::string& getName() const { return name_; }
409 
410  std::string toString() const override {
411  auto result = "(RexFunctionOperator " + name_;
412  for (const auto& operand : operands_) {
413  result += (" " + operand->toString());
414  }
415  return result + ")";
416  }
417 
418  private:
419  const std::string name_;
420 };
421 
423 
424 enum class NullSortedPosition { First, Last };
425 
426 class SortField {
427  public:
428  SortField(const size_t field,
429  const SortDirection sort_dir,
430  const NullSortedPosition nulls_pos)
431  : field_(field), sort_dir_(sort_dir), nulls_pos_(nulls_pos) {}
432 
433  bool operator==(const SortField& that) const {
434  return field_ == that.field_ && sort_dir_ == that.sort_dir_ &&
435  nulls_pos_ == that.nulls_pos_;
436  }
437 
438  size_t getField() const { return field_; }
439 
440  SortDirection getSortDir() const { return sort_dir_; }
441 
442  NullSortedPosition getNullsPosition() const { return nulls_pos_; }
443 
444  std::string toString() const {
445  return "(" + std::to_string(field_) + " " +
446  (sort_dir_ == SortDirection::Ascending ? "asc" : "desc") + " " +
447  (nulls_pos_ == NullSortedPosition::First ? "nulls_first" : "nulls_last") + ")";
448  }
449 
450  private:
451  const size_t field_;
454 };
455 
457  public:
458  struct RexWindowBound {
459  bool unbounded;
460  bool preceding;
461  bool following;
463  std::shared_ptr<const RexScalar> offset;
465  };
466 
468  ConstRexScalarPtrVector& operands,
469  ConstRexScalarPtrVector& partition_keys,
470  ConstRexScalarPtrVector& order_keys,
471  const std::vector<SortField> collation,
472  const RexWindowBound& lower_bound,
473  const RexWindowBound& upper_bound,
474  const bool is_rows,
475  const SQLTypeInfo& ti)
476  : RexFunctionOperator(sql_window_function_to_str(kind), operands, ti)
477  , kind_(kind)
478  , partition_keys_(std::move(partition_keys))
479  , order_keys_(std::move(order_keys))
480  , collation_(collation)
481  , lower_bound_(lower_bound)
482  , upper_bound_(upper_bound)
483  , is_rows_(is_rows) {}
484 
485  SqlWindowFunctionKind getKind() const { return kind_; }
486 
487  const ConstRexScalarPtrVector& getPartitionKeys() const { return partition_keys_; }
488 
489  ConstRexScalarPtrVector getPartitionKeysAndRelease() const {
490  return std::move(partition_keys_);
491  }
492 
493  ConstRexScalarPtrVector getOrderKeysAndRelease() const {
494  return std::move(order_keys_);
495  }
496 
497  const ConstRexScalarPtrVector& getOrderKeys() const { return order_keys_; }
498 
499  const std::vector<SortField>& getCollation() const { return collation_; }
500 
501  const RexWindowBound& getLowerBound() const { return lower_bound_; }
502 
503  const RexWindowBound& getUpperBound() const { return upper_bound_; }
504 
505  bool isRows() const { return is_rows_; }
506 
507  std::unique_ptr<const RexOperator> disambiguatedOperands(
508  ConstRexScalarPtrVector& operands,
509  ConstRexScalarPtrVector& partition_keys,
510  ConstRexScalarPtrVector& order_keys,
511  const std::vector<SortField>& collation) const {
512  return std::unique_ptr<const RexOperator>(
513  new RexWindowFunctionOperator(kind_,
514  operands,
515  partition_keys,
516  order_keys,
517  collation,
518  getLowerBound(),
519  getUpperBound(),
520  isRows(),
521  getType()));
522  }
523 
524  std::string toString() const override {
525  auto result = "(RexWindowFunctionOperator " + getName();
526  for (const auto& operand : operands_) {
527  result += (" " + operand->toString());
528  }
529  result += " partition[";
530  for (const auto& partition_key : partition_keys_) {
531  result += (" " + partition_key->toString());
532  }
533  result += "]";
534  result += " order[";
535  for (const auto& order_key : order_keys_) {
536  result += (" " + order_key->toString());
537  }
538  result += "]";
539  return result + ")";
540  }
541 
542  private:
544  mutable ConstRexScalarPtrVector partition_keys_;
545  mutable ConstRexScalarPtrVector order_keys_;
546  const std::vector<SortField> collation_;
549  const bool is_rows_;
550 };
551 
552 // Not a real node created by Calcite. Created by us because targets of a query
553 // should reference the group by expressions instead of creating completely new one.
554 class RexRef : public RexScalar {
555  public:
556  RexRef(const size_t index) : index_(index) {}
557 
558  size_t getIndex() const { return index_; }
559 
560  std::string toString() const override {
561  return "(RexRef " + std::to_string(index_) + ")";
562  }
563 
564  std::unique_ptr<RexRef> deepCopy() const { return boost::make_unique<RexRef>(index_); }
565 
566  private:
567  const size_t index_;
568 };
569 
570 class RexAgg : public Rex {
571  public:
572  RexAgg(const SQLAgg agg,
573  const bool distinct,
574  const SQLTypeInfo& type,
575  const std::vector<size_t>& operands)
576  : agg_(agg), distinct_(distinct), type_(type), operands_(operands) {}
577 
578  std::string toString() const override {
579  auto result = "(RexAgg " + std::to_string(agg_) + " " + std::to_string(distinct_) +
580  " " + type_.get_type_name() + " " + type_.get_compression_name();
581  for (auto operand : operands_) {
582  result += " " + std::to_string(operand);
583  }
584  return result + ")";
585  }
586 
587  SQLAgg getKind() const { return agg_; }
588 
589  bool isDistinct() const { return distinct_; }
590 
591  size_t size() const { return operands_.size(); }
592 
593  size_t getOperand(size_t idx) const { return operands_[idx]; }
594 
595  const SQLTypeInfo& getType() const { return type_; }
596 
597  std::unique_ptr<RexAgg> deepCopy() const {
598  return boost::make_unique<RexAgg>(agg_, distinct_, type_, operands_);
599  }
600 
601  private:
602  const SQLAgg agg_;
603  const bool distinct_;
605  const std::vector<size_t> operands_;
606 };
607 
608 class RelAlgNode {
609  public:
610  RelAlgNode() : id_(crt_id_++), context_data_(nullptr), is_nop_(false) {}
611 
612  virtual ~RelAlgNode() {}
613 
614  void setContextData(const void* context_data) const {
615  CHECK(!context_data_);
616  context_data_ = context_data;
617  }
618 
619  void setOutputMetainfo(const std::vector<TargetMetaInfo>& targets_metainfo) const {
620  targets_metainfo_ = targets_metainfo;
621  }
622 
623  const std::vector<TargetMetaInfo>& getOutputMetainfo() const {
624  return targets_metainfo_;
625  }
626 
627  unsigned getId() const { return id_; }
628 
629  bool hasContextData() const { return !(context_data_ == nullptr); }
630 
631  const void* getContextData() const {
632  CHECK(context_data_);
633  return context_data_;
634  }
635 
636  const size_t inputCount() const { return inputs_.size(); }
637 
638  const RelAlgNode* getInput(const size_t idx) const {
639  CHECK(idx < inputs_.size());
640  return inputs_[idx].get();
641  }
642 
643  std::shared_ptr<const RelAlgNode> getAndOwnInput(const size_t idx) const {
644  CHECK(idx < inputs_.size());
645  return inputs_[idx];
646  }
647 
648  void addManagedInput(std::shared_ptr<const RelAlgNode> input) {
649  inputs_.push_back(input);
650  }
651 
652  bool hasInput(const RelAlgNode* needle) const {
653  for (auto& input_ptr : inputs_) {
654  if (input_ptr.get() == needle) {
655  return true;
656  }
657  }
658  return false;
659  }
660 
661  virtual void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
662  std::shared_ptr<const RelAlgNode> input) {
663  for (auto& input_ptr : inputs_) {
664  if (input_ptr == old_input) {
665  input_ptr = input;
666  break;
667  }
668  }
669  }
670 
671  bool isNop() const { return is_nop_; }
672 
673  void markAsNop() { is_nop_ = true; }
674 
675  virtual std::string toString() const = 0;
676 
677  virtual size_t size() const = 0;
678 
679  virtual std::shared_ptr<RelAlgNode> deepCopy() const = 0;
680 
681  static void resetRelAlgFirstId() noexcept;
682 
683  protected:
684  std::vector<std::shared_ptr<const RelAlgNode>> inputs_;
685  const unsigned id_;
686 
687  private:
688  mutable const void* context_data_;
689  bool is_nop_;
690  mutable std::vector<TargetMetaInfo> targets_metainfo_;
691  static thread_local unsigned crt_id_;
692 };
693 
694 class RelScan : public RelAlgNode {
695  public:
696  RelScan(const TableDescriptor* td, const std::vector<std::string>& field_names)
697  : td_(td), field_names_(field_names) {}
698 
699  size_t size() const override { return field_names_.size(); }
700 
701  const TableDescriptor* getTableDescriptor() const { return td_; }
702 
703  const std::vector<std::string>& getFieldNames() const { return field_names_; }
704 
705  const std::string getFieldName(const size_t i) const { return field_names_[i]; }
706 
707  std::string toString() const override {
708  return "(RelScan<" + std::to_string(reinterpret_cast<uint64_t>(this)) + "> " +
709  td_->tableName + ")";
710  }
711 
712  std::shared_ptr<RelAlgNode> deepCopy() const override {
713  CHECK(false);
714  return nullptr;
715  };
716 
717  private:
718  const TableDescriptor* td_;
719  const std::vector<std::string> field_names_;
720 };
721 
723  public:
724  ModifyManipulationTarget(bool const update_via_select = false,
725  bool const delete_via_select = false,
726  bool const varlen_update_required = false,
727  TableDescriptor const* table_descriptor = nullptr,
728  ColumnNameList target_columns = ColumnNameList())
729  : is_update_via_select_(update_via_select)
730  , is_delete_via_select_(delete_via_select)
731  , varlen_update_required_(varlen_update_required)
732  , table_descriptor_(table_descriptor)
733  , target_columns_(target_columns) {}
734 
735  void setUpdateViaSelectFlag() const { is_update_via_select_ = true; }
736  void setDeleteViaSelectFlag() const { is_delete_via_select_ = true; }
738  varlen_update_required_ = required;
739  }
740 
741  TableDescriptor const* getModifiedTableDescriptor() const { return table_descriptor_; }
743  table_descriptor_ = td;
744  }
745 
746  auto const isUpdateViaSelect() const { return is_update_via_select_; }
747  auto const isDeleteViaSelect() const { return is_delete_via_select_; }
748  auto const isVarlenUpdateRequired() const { return varlen_update_required_; }
749 
750  int getTargetColumnCount() const { return target_columns_.size(); }
751  void setTargetColumns(ColumnNameList const& target_columns) const {
752  target_columns_ = target_columns;
753  }
754  ColumnNameList const& getTargetColumns() const { return target_columns_; }
755 
756  template <typename VALIDATION_FUNCTOR>
757  bool validateTargetColumns(VALIDATION_FUNCTOR validator) const {
758  for (auto const& column_name : target_columns_) {
759  if (validator(column_name) == false) {
760  return false;
761  }
762  }
763  return true;
764  }
765 
766  private:
767  mutable bool is_update_via_select_ = false;
768  mutable bool is_delete_via_select_ = false;
769  mutable bool varlen_update_required_ = false;
770  mutable TableDescriptor const* table_descriptor_ = nullptr;
772 };
773 
775  public:
776  friend class RelModify;
777  using ConstRexScalarPtr = std::unique_ptr<const RexScalar>;
778  using ConstRexScalarPtrVector = std::vector<ConstRexScalarPtr>;
779 
780  // Takes memory ownership of the expressions.
781  RelProject(std::vector<std::unique_ptr<const RexScalar>>& scalar_exprs,
782  const std::vector<std::string>& fields,
783  std::shared_ptr<const RelAlgNode> input)
784  : ModifyManipulationTarget(false, false, false, nullptr)
785  , scalar_exprs_(std::move(scalar_exprs))
786  , fields_(fields) {
787  inputs_.push_back(input);
788  }
789 
790  void setExpressions(std::vector<std::unique_ptr<const RexScalar>>& exprs) const {
791  scalar_exprs_ = std::move(exprs);
792  }
793 
794  // True iff all the projected expressions are inputs. If true,
795  // this node can be elided and merged into the previous node
796  // since it's just a subset and / or permutation of its outputs.
797  bool isSimple() const {
798  for (const auto& expr : scalar_exprs_) {
799  if (!dynamic_cast<const RexInput*>(expr.get())) {
800  return false;
801  }
802  }
803  return true;
804  }
805 
806  bool isIdentity() const;
807 
808  bool isRenaming() const;
809 
810  size_t size() const override { return scalar_exprs_.size(); }
811 
812  const RexScalar* getProjectAt(const size_t idx) const {
813  CHECK(idx < scalar_exprs_.size());
814  return scalar_exprs_[idx].get();
815  }
816 
817  const RexScalar* getProjectAtAndRelease(const size_t idx) const {
818  CHECK(idx < scalar_exprs_.size());
819  return scalar_exprs_[idx].release();
820  }
821 
822  std::vector<std::unique_ptr<const RexScalar>> getExpressionsAndRelease() {
823  return std::move(scalar_exprs_);
824  }
825 
826  const std::vector<std::string>& getFields() const { return fields_; }
827  void setFields(std::vector<std::string>& fields) { fields_ = std::move(fields); }
828 
829  const std::string getFieldName(const size_t i) const { return fields_[i]; }
830 
831  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
832  std::shared_ptr<const RelAlgNode> input) override;
833 
834  void appendInput(std::string new_field_name,
835  std::unique_ptr<const RexScalar> new_input);
836 
837  std::string toString() const override {
838  std::string result =
839  "(RelProject<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">";
840  for (const auto& scalar_expr : scalar_exprs_) {
841  result += " " + scalar_expr->toString();
842  }
843  return result + ")";
844  }
845 
846  std::shared_ptr<RelAlgNode> deepCopy() const override;
847 
848  private:
849  template <typename EXPR_VISITOR_FUNCTOR>
850  void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const {
851  for (int i = 0; i < static_cast<int>(scalar_exprs_.size()); i++) {
852  visitor_functor(i);
853  }
854  }
855 
858  scalar_exprs_.emplace_back(boost::make_unique<RexFunctionOperator const>(
859  std::string("OFFSET_IN_FRAGMENT"), transient_vector, SQLTypeInfo(kINT, false)));
860  fields_.emplace_back("EXPR$DELETE_OFFSET_IN_FRAGMENT");
861  }
862 
863  mutable std::vector<std::unique_ptr<const RexScalar>> scalar_exprs_;
864  mutable std::vector<std::string> fields_;
865 };
866 
867 class RelAggregate : public RelAlgNode {
868  public:
869  // Takes ownership of the aggregate expressions.
870  RelAggregate(const size_t groupby_count,
871  std::vector<std::unique_ptr<const RexAgg>>& agg_exprs,
872  const std::vector<std::string>& fields,
873  std::shared_ptr<const RelAlgNode> input)
874  : groupby_count_(groupby_count), agg_exprs_(std::move(agg_exprs)), fields_(fields) {
875  inputs_.push_back(input);
876  }
877 
878  size_t size() const override { return groupby_count_ + agg_exprs_.size(); }
879 
880  const size_t getGroupByCount() const { return groupby_count_; }
881 
882  const size_t getAggExprsCount() const { return agg_exprs_.size(); }
883 
884  const std::vector<std::string>& getFields() const { return fields_; }
885  void setFields(std::vector<std::string>& new_fields) {
886  fields_ = std::move(new_fields);
887  }
888 
889  const std::string getFieldName(const size_t i) const { return fields_[i]; }
890 
891  std::vector<const RexAgg*> getAggregatesAndRelease() {
892  std::vector<const RexAgg*> result;
893  for (auto& agg_expr : agg_exprs_) {
894  result.push_back(agg_expr.release());
895  }
896  return result;
897  }
898 
899  std::vector<std::unique_ptr<const RexAgg>> getAggExprsAndRelease() {
900  return std::move(agg_exprs_);
901  }
902 
903  const std::vector<std::unique_ptr<const RexAgg>>& getAggExprs() const {
904  return agg_exprs_;
905  }
906 
907  void setAggExprs(std::vector<std::unique_ptr<const RexAgg>>& agg_exprs) {
908  agg_exprs_ = std::move(agg_exprs);
909  }
910 
911  std::string toString() const override {
912  std::string result = "(RelAggregate<" +
913  std::to_string(reinterpret_cast<uint64_t>(this)) + ">(groups: [";
914  for (size_t group_index = 0; group_index < groupby_count_; ++group_index) {
915  result += " " + std::to_string(group_index);
916  }
917  result += " ] aggs: [";
918  for (const auto& agg_expr : agg_exprs_) {
919  result += " " + agg_expr->toString();
920  }
921  return result + " ])";
922  }
923 
924  std::shared_ptr<RelAlgNode> deepCopy() const override;
925 
926  private:
927  const size_t groupby_count_;
928  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
929  std::vector<std::string> fields_;
930 };
931 
932 class RelJoin : public RelAlgNode {
933  public:
934  RelJoin(std::shared_ptr<const RelAlgNode> lhs,
935  std::shared_ptr<const RelAlgNode> rhs,
936  std::unique_ptr<const RexScalar>& condition,
937  const JoinType join_type)
938  : condition_(std::move(condition)), join_type_(join_type) {
939  inputs_.push_back(lhs);
940  inputs_.push_back(rhs);
941  }
942 
943  JoinType getJoinType() const { return join_type_; }
944 
945  const RexScalar* getCondition() const { return condition_.get(); }
946 
947  const RexScalar* getAndReleaseCondition() const { return condition_.release(); }
948 
949  void setCondition(std::unique_ptr<const RexScalar>& condition) {
950  CHECK(condition);
951  condition_ = std::move(condition);
952  }
953 
954  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
955  std::shared_ptr<const RelAlgNode> input) override;
956 
957  std::string toString() const override {
958  std::string result =
959  "(RelJoin<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
960  result += condition_ ? condition_->toString() : "null";
961  result += " " + std::to_string(static_cast<int>(join_type_));
962  return result + ")";
963  }
964 
965  size_t size() const override { return inputs_[0]->size() + inputs_[1]->size(); }
966 
967  std::shared_ptr<RelAlgNode> deepCopy() const override;
968 
969  private:
970  mutable std::unique_ptr<const RexScalar> condition_;
972 };
973 
974 class RelFilter : public RelAlgNode {
975  public:
976  RelFilter(std::unique_ptr<const RexScalar>& filter,
977  std::shared_ptr<const RelAlgNode> input)
978  : filter_(std::move(filter)) {
979  CHECK(filter_);
980  inputs_.push_back(input);
981  }
982 
983  const RexScalar* getCondition() const { return filter_.get(); }
984 
985  const RexScalar* getAndReleaseCondition() { return filter_.release(); }
986 
987  void setCondition(std::unique_ptr<const RexScalar>& condition) {
988  CHECK(condition);
989  filter_ = std::move(condition);
990  }
991 
992  size_t size() const override { return inputs_[0]->size(); }
993 
994  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
995  std::shared_ptr<const RelAlgNode> input) override;
996 
997  std::string toString() const override {
998  std::string result =
999  "(RelFilter<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1000  result += filter_ ? filter_->toString() : "null";
1001  return result + ")";
1002  }
1003 
1004  std::shared_ptr<RelAlgNode> deepCopy() const override;
1005 
1006  private:
1007  std::unique_ptr<const RexScalar> filter_;
1008 };
1009 
1010 // Synthetic node to assist execution of left-deep join relational algebra.
1012  public:
1013  RelLeftDeepInnerJoin(const std::shared_ptr<RelFilter>& filter,
1014  std::vector<std::shared_ptr<const RelAlgNode>> inputs,
1015  std::vector<std::shared_ptr<const RelJoin>>& original_joins);
1016 
1017  const RexScalar* getInnerCondition() const;
1018 
1019  const RexScalar* getOuterCondition(const size_t nesting_level) const;
1020 
1021  std::string toString() const override;
1022 
1023  size_t size() const override;
1024 
1025  std::shared_ptr<RelAlgNode> deepCopy() const override;
1026 
1027  bool coversOriginalNode(const RelAlgNode* node) const;
1028 
1029  private:
1030  std::unique_ptr<const RexScalar> condition_;
1031  std::vector<std::unique_ptr<const RexScalar>> outer_conditions_per_level_;
1032  const std::shared_ptr<RelFilter> original_filter_;
1033  const std::vector<std::shared_ptr<const RelJoin>> original_joins_;
1034 };
1035 
1036 // The 'RelCompound' node combines filter and on the fly aggregate computation.
1037 // It's the result of combining a sequence of 'RelFilter' (optional), 'RelProject',
1038 // 'RelAggregate' (optional) and a simple 'RelProject' (optional) into a single node
1039 // which can be efficiently executed with no intermediate buffers.
1041  public:
1042  // 'target_exprs_' are either scalar expressions owned by 'scalar_sources_'
1043  // or aggregate expressions owned by 'agg_exprs_', with the arguments
1044  // owned by 'scalar_sources_'.
1045  RelCompound(std::unique_ptr<const RexScalar>& filter_expr,
1046  const std::vector<const Rex*>& target_exprs,
1047  const size_t groupby_count,
1048  const std::vector<const RexAgg*>& agg_exprs,
1049  const std::vector<std::string>& fields,
1050  std::vector<std::unique_ptr<const RexScalar>>& scalar_sources,
1051  const bool is_agg,
1052  bool update_disguised_as_select = false,
1053  bool delete_disguised_as_select = false,
1054  bool varlen_update_required = false,
1055  TableDescriptor const* manipulation_target_table = nullptr,
1056  ColumnNameList target_columns = ColumnNameList())
1057  : ModifyManipulationTarget(update_disguised_as_select,
1058  delete_disguised_as_select,
1059  varlen_update_required,
1060  manipulation_target_table,
1061  target_columns)
1062  , filter_expr_(std::move(filter_expr))
1063  , target_exprs_(target_exprs)
1064  , groupby_count_(groupby_count)
1065  , fields_(fields)
1066  , is_agg_(is_agg)
1067  , scalar_sources_(std::move(scalar_sources)) {
1068  CHECK_EQ(fields.size(), target_exprs.size());
1069  for (auto agg_expr : agg_exprs) {
1070  agg_exprs_.emplace_back(agg_expr);
1071  }
1072  }
1073 
1074  void replaceInput(std::shared_ptr<const RelAlgNode> old_input,
1075  std::shared_ptr<const RelAlgNode> input) override;
1076 
1077  size_t size() const override { return target_exprs_.size(); }
1078 
1079  const RexScalar* getFilterExpr() const { return filter_expr_.get(); }
1080 
1081  void setFilterExpr(std::unique_ptr<const RexScalar>& new_expr) {
1082  filter_expr_ = std::move(new_expr);
1083  }
1084 
1085  const Rex* getTargetExpr(const size_t i) const { return target_exprs_[i]; }
1086 
1087  const std::vector<std::string>& getFields() const { return fields_; }
1088 
1089  const std::string getFieldName(const size_t i) const { return fields_[i]; }
1090 
1091  const size_t getScalarSourcesSize() const { return scalar_sources_.size(); }
1092 
1093  const RexScalar* getScalarSource(const size_t i) const {
1094  return scalar_sources_[i].get();
1095  }
1096 
1097  void setScalarSources(std::vector<std::unique_ptr<const RexScalar>>& new_sources) {
1098  CHECK_EQ(new_sources.size(), scalar_sources_.size());
1099  scalar_sources_ = std::move(new_sources);
1100  }
1101 
1102  const size_t getGroupByCount() const { return groupby_count_; }
1103 
1104  bool isAggregate() const { return is_agg_; }
1105 
1106  std::string toString() const override {
1107  std::string result =
1108  "(RelCompound<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1109  result += (filter_expr_ ? filter_expr_->toString() : "null") + " ";
1110  for (const auto target_expr : target_exprs_) {
1111  result += target_expr->toString() + " ";
1112  }
1113  result += "groups: [";
1114  for (size_t group_index = 0; group_index < groupby_count_; ++group_index) {
1115  result += " " + std::to_string(group_index);
1116  }
1117  result += " ] sources: [";
1118  for (const auto& scalar_source : scalar_sources_) {
1119  result += " " + scalar_source->toString();
1120  }
1121  return result + " ])";
1122  }
1123 
1124  std::shared_ptr<RelAlgNode> deepCopy() const override;
1125 
1126  private:
1127  std::unique_ptr<const RexScalar> filter_expr_;
1128  const std::vector<const Rex*> target_exprs_;
1129  const size_t groupby_count_;
1130  std::vector<std::unique_ptr<const RexAgg>> agg_exprs_;
1131  const std::vector<std::string> fields_;
1132  const bool is_agg_;
1133  std::vector<std::unique_ptr<const RexScalar>>
1134  scalar_sources_; // building blocks for group_indices_ and agg_exprs_; not actually
1135  // projected, just owned
1136 };
1137 
1138 class RelSort : public RelAlgNode {
1139  public:
1140  RelSort(const std::vector<SortField>& collation,
1141  const size_t limit,
1142  const size_t offset,
1143  std::shared_ptr<const RelAlgNode> input)
1144  : collation_(collation), limit_(limit), offset_(offset) {
1145  inputs_.push_back(input);
1146  }
1147 
1148  bool operator==(const RelSort& that) const {
1149  return limit_ == that.limit_ && offset_ == that.offset_ && hasEquivCollationOf(that);
1150  }
1151 
1152  size_t collationCount() const { return collation_.size(); }
1153 
1154  SortField getCollation(const size_t i) const {
1155  CHECK_LT(i, collation_.size());
1156  return collation_[i];
1157  }
1158 
1159  void setCollation(std::vector<SortField>&& collation) {
1160  collation_ = std::move(collation);
1161  }
1162 
1163  size_t getLimit() const { return limit_; }
1164 
1165  size_t getOffset() const { return offset_; }
1166 
1167  std::string toString() const override {
1168  std::string result =
1169  "(RelSort<" + std::to_string(reinterpret_cast<uint64_t>(this)) + ">(";
1170  result += "limit: " + std::to_string(limit_) + " ";
1171  result += "offset: " + std::to_string(offset_) + " ";
1172  result += "collation: [ ";
1173  for (const auto& sort_field : collation_) {
1174  result += sort_field.toString() + " ";
1175  }
1176  result += "]";
1177  return result + ")";
1178  }
1179 
1180  size_t size() const override { return inputs_[0]->size(); }
1181 
1182  std::shared_ptr<RelAlgNode> deepCopy() const override;
1183 
1184  private:
1185  std::vector<SortField> collation_;
1186  const size_t limit_;
1187  const size_t offset_;
1188 
1189  bool hasEquivCollationOf(const RelSort& that) const;
1190 };
1191 
1192 class RelModify : public RelAlgNode {
1193  public:
1194  enum class ModifyOperation { Insert, Delete, Update };
1195  using RelAlgNodeInputPtr = std::shared_ptr<const RelAlgNode>;
1196  using TargetColumnList = std::vector<std::string>;
1197 
1198  static std::string yieldModifyOperationString(ModifyOperation const op) {
1199  switch (op) {
1200  case ModifyOperation::Delete:
1201  return "DELETE";
1202  case ModifyOperation::Insert:
1203  return "INSERT";
1204  case ModifyOperation::Update:
1205  return "UPDATE";
1206  default:
1207  break;
1208  }
1209  throw std::runtime_error("Unexpected ModifyOperation enum encountered.");
1210  }
1211 
1212  static ModifyOperation yieldModifyOperationEnum(std::string const& op_string) {
1213  if (op_string == "INSERT") {
1214  return ModifyOperation::Insert;
1215  } else if (op_string == "DELETE") {
1216  return ModifyOperation::Delete;
1217  } else if (op_string == "UPDATE") {
1218  return ModifyOperation::Update;
1219  }
1220 
1221  throw std::runtime_error(
1222  std::string("Unsupported logical modify operation encountered " + op_string));
1223  }
1224 
1226  TableDescriptor const* const td,
1227  bool flattened,
1228  std::string const& op_string,
1229  TargetColumnList const& target_column_list,
1230  RelAlgNodeInputPtr input)
1231  : catalog_(cat)
1232  , table_descriptor_(td)
1233  , flattened_(flattened)
1234  , operation_(yieldModifyOperationEnum(op_string))
1235  , target_column_list_(target_column_list) {
1236  inputs_.push_back(input);
1237  }
1238 
1240  TableDescriptor const* const td,
1241  bool flattened,
1242  ModifyOperation op,
1243  TargetColumnList const& target_column_list,
1244  RelAlgNodeInputPtr input)
1245  : catalog_(cat)
1246  , table_descriptor_(td)
1247  , flattened_(flattened)
1248  , operation_(op)
1249  , target_column_list_(target_column_list) {
1250  inputs_.push_back(input);
1251  }
1252 
1253  TableDescriptor const* const getTableDescriptor() const { return table_descriptor_; }
1254  bool const isFlattened() const { return flattened_; }
1255  ModifyOperation getOperation() const { return operation_; }
1256  TargetColumnList const& getUpdateColumnNames() { return target_column_list_; }
1257  int getUpdateColumnCount() const { return target_column_list_.size(); }
1258 
1259  size_t size() const override { return 0; }
1260  std::shared_ptr<RelAlgNode> deepCopy() const override {
1261  return std::make_shared<RelModify>(catalog_,
1262  table_descriptor_,
1263  flattened_,
1264  operation_,
1265  target_column_list_,
1266  inputs_[0]);
1267  }
1268 
1269  std::string toString() const override {
1270  std::ostringstream result_stream;
1271  result_stream << std::boolalpha
1272  << "(RelModify<" + std::to_string(reinterpret_cast<uint64_t>(this)) +
1273  "> "
1274  << table_descriptor_->tableName << " flattened= " << flattened_
1275  << " operation= " << yieldModifyOperationString(operation_) << ")";
1276 
1277  return result_stream.str();
1278  }
1279 
1281  RelProject const* previous_project_node =
1282  dynamic_cast<RelProject const*>(inputs_[0].get());
1283  CHECK(previous_project_node != nullptr);
1284 
1285  previous_project_node->setUpdateViaSelectFlag();
1286  previous_project_node->injectOffsetInFragmentExpr();
1287  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1288  previous_project_node->setTargetColumns(target_column_list_);
1289 
1290  int target_update_column_expr_start =
1291  (int)(previous_project_node->getFields().size() - target_column_list_.size() - 1);
1292  int target_update_column_expr_end =
1293  (int)(previous_project_node->getFields().size() - 2);
1294  CHECK(target_update_column_expr_start >= 0);
1295  CHECK(target_update_column_expr_end >= 0);
1296 
1297  bool varlen_update_required = false;
1298 
1299  auto varlen_scan_visitor = [this,
1300  &varlen_update_required,
1301  target_update_column_expr_start,
1302  target_update_column_expr_end](int index) {
1303  if (index >= target_update_column_expr_start &&
1304  index <= target_update_column_expr_end) {
1305  auto target_index = index - target_update_column_expr_start;
1306 
1307  auto* column_desc = catalog_.getMetadataForColumn(
1308  table_descriptor_->tableId, target_column_list_[target_index]);
1309  CHECK(column_desc);
1310 
1311  if (table_descriptor_->nShards) {
1312  const auto shard_cd =
1313  catalog_.getShardColumnMetadataForTable(table_descriptor_);
1314  CHECK(shard_cd);
1315  if ((column_desc->columnName == shard_cd->columnName)) {
1316  throw std::runtime_error("UPDATE of a shard key is currently unsupported.");
1317  }
1318  }
1319 
1320  // Check for valid types
1321  if (is_feature_enabled<VarlenUpdates>()) {
1322  if (column_desc->columnType.is_varlen()) {
1323  varlen_update_required = true;
1324  }
1325 
1326  if (column_desc->columnType.is_geometry()) {
1327  throw std::runtime_error("UPDATE of a geo column is unsupported.");
1328  }
1329  } else {
1330  if (column_desc->columnType.is_varlen()) {
1331  throw std::runtime_error(
1332  "UPDATE of a none-encoded string, geo, or array column is unsupported.");
1333  }
1334  }
1335  }
1336  };
1337 
1338  previous_project_node->visitScalarExprs(varlen_scan_visitor);
1339  previous_project_node->setVarlenUpdateRequired(varlen_update_required);
1340  }
1341 
1343  RelProject const* previous_project_node =
1344  dynamic_cast<RelProject const*>(inputs_[0].get());
1345  CHECK(previous_project_node != nullptr);
1346  previous_project_node->setDeleteViaSelectFlag();
1347  previous_project_node->injectOffsetInFragmentExpr();
1348  previous_project_node->setModifiedTableDescriptor(table_descriptor_);
1349  }
1350 
1351  private:
1357 };
1358 
1360  public:
1361  RelLogicalValues(const std::vector<TargetMetaInfo>& tuple_type)
1362  : tuple_type_(tuple_type) {}
1363 
1364  const std::vector<TargetMetaInfo> getTupleType() const { return tuple_type_; }
1365 
1366  std::string toString() const override {
1367  // TODO
1368  return "(RelLogicalValues)";
1369  }
1370 
1371  size_t size() const override { return tuple_type_.size(); }
1372 
1373  std::shared_ptr<RelAlgNode> deepCopy() const override {
1374  return std::make_shared<RelLogicalValues>(tuple_type_);
1375  }
1376 
1377  private:
1378  const std::vector<TargetMetaInfo> tuple_type_;
1379 };
1380 
1381 class QueryNotSupported : public std::runtime_error {
1382  public:
1383  QueryNotSupported(const std::string& reason) : std::runtime_error(reason) {}
1384 };
1385 
1386 class RelAlgExecutor;
1387 
1388 std::shared_ptr<const RelAlgNode> deserialize_ra_dag(
1389  const std::string& query_ra,
1390  const Catalog_Namespace::Catalog& cat,
1391  RelAlgExecutor* ra_executor,
1392  const RenderQueryOptions* render_opts = nullptr);
1393 
1394 std::string tree_string(const RelAlgNode*, const size_t indent = 0);
1395 
1396 using RANodeOutput = std::vector<RexInput>;
1397 
1398 RANodeOutput get_node_output(const RelAlgNode* ra_node);
1399 
1400 #endif // QUERYENGINE_RELALGABSTRACTINTERPRETER_H
std::string toString() const override
std::vector< std::shared_ptr< const RelAlgNode > > inputs_
std::string toString() const override
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
size_t size() const
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::unique_ptr< const RexScalar > ConstRexScalarPtr
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 std::vector< std::string > & getFields() const
const size_t getGroupByCount() const
JoinType
Definition: sqldefs.h:98
std::string toString() const override
void setSourceNode(const RelAlgNode *node) const
const RelAlgNode * getRelAlg() const
void setIndex(const unsigned in_index) const
const TableDescriptor * getTableDescriptor() const
RexLiteral(const std::string &val, const SQLTypes type, const SQLTypes target_type, const unsigned scale, const unsigned precision, const unsigned type_scale, const unsigned type_precision)
const std::shared_ptr< const RelAlgNode > ra_
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:81
size_t collationCount() const
SqlWindowFunctionKind getKind() const
size_t size() const override
const size_t index_
SQLTypes
Definition: sqltypes.h:40
std::shared_ptr< RelAlgNode > deepCopy() const override
size_t size() const override
unsigned getId() const
const unsigned type_scale_
std::string toString() const override
std::string toString() const override
std::shared_ptr< const RelAlgNode > deserialize_ra_dag(const std::string &query_ra, const Catalog_Namespace::Catalog &cat, RelAlgExecutor *ra_executor, const RenderQueryOptions *render_opts=nullptr)
RexOperator(const SQLOps op, std::vector< std::unique_ptr< const RexScalar >> &operands, const SQLTypeInfo &type)
static thread_local unsigned crt_id_
void setCondition(std::unique_ptr< const RexScalar > &condition)
std::unique_ptr< const RexScalar > ConstRexScalarPtr
const RexWindowBound & getLowerBound() const
const JoinType join_type_
SortDirection getSortDir() const
void applyDeleteModificationsToInputNode()
std::vector< std::string > TargetColumnList
size_t size() const override
void setTargetColumns(ColumnNameList const &target_columns) const
unsigned getPrecision() const
const SqlWindowFunctionKind kind_
std::unique_ptr< RexLiteral > deepCopy() const
std::string toString() const override
size_t size() const override
SQLOps
Definition: sqldefs.h:29
const RexScalar * getProjectAt(const size_t idx) const
const std::vector< std::string > fields_
const ConstRexScalarPtrVector & getOrderKeys() 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::shared_ptr< std::shared_ptr< const ExecutionResult > > result_
std::unique_ptr< const RexScalar > else_expr_
void addManagedInput(std::shared_ptr< const RelAlgNode > input)
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)
constexpr auto is_datetime(T sql_type)
Definition: sqltypes.h:191
std::vector< std::string > fields_
std::vector< std::unique_ptr< const RexAgg > > getAggExprsAndRelease()
RexInput(const RelAlgNode *node, const unsigned in_index)
void setModifiedTableDescriptor(TableDescriptor const *td) const
const void * context_data_
void setFilterExpr(std::unique_ptr< const RexScalar > &new_expr)
std::shared_ptr< RelAlgNode > deepCopy() const override
bool validateTargetColumns(VALIDATION_FUNCTOR validator) const
virtual ~Rex()
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
TableDescriptor const * getModifiedTableDescriptor() const
const TableDescriptor * td_
std::vector< std::unique_ptr< const RexScalar > > scalar_sources_
const std::vector< std::string > & getFields() const
std::string to_string(char const *&&v)
const SQLAgg agg_
const RexScalar * getCondition() 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
std::vector< RexInput > RANodeOutput
const RexWindowBound & getUpperBound() const
TargetColumnList const & getUpdateColumnNames()
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
void setOutputMetainfo(const std::vector< TargetMetaInfo > &targets_metainfo) const
std::shared_ptr< const RelAlgNode > RelAlgNodeInputPtr
const RexScalar * getThen(const size_t idx) const
ConstRexScalarPtrVector getPartitionKeysAndRelease() const
const RelAlgNode * getSourceNode() const
bool hasContextData() const
const bool distinct_
const NullSortedPosition nulls_pos_
const size_t offset_
#define CHECK_NE(x, y)
Definition: Logger.h:196
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)
const SQLTypeInfo type_
const TableDescriptor * table_descriptor_
const std::vector< std::shared_ptr< const RelJoin > > original_joins_
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()
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_
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)
unsigned getTypeScale() const
const RexScalar * getOperand(const size_t idx) const
std::shared_ptr< RelAlgNode > deepCopy() const override
const RelAlgNode * node_
SQLTypes getType() const
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
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
const SQLTypes type_
std::string tree_string(const RelAlgNode *, const size_t indent=0)
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
void setContextData(const void *context_data) const
const void * getContextData() const
size_t size() const override
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 std::vector< SortField > collation_
#define CHECK_LT(x, y)
Definition: Logger.h:197
Definition: sqltypes.h:54
NullSortedPosition getNullsPosition() const
void setCollation(std::vector< SortField > &&collation)
const std::vector< TargetMetaInfo > & getOutputMetainfo() const
RelLogicalValues(const std::vector< TargetMetaInfo > &tuple_type)
const RexScalar * getCondition() const
const size_t getGroupByCount() const
std::string toString() const override
const std::string getFieldName(const size_t i) const
const std::vector< const Rex * > target_exprs_
size_t getLimit() const
std::vector< std::unique_ptr< const RexAgg > > agg_exprs_
const RexScalar * getScalarSource(const size_t i) const
void injectOffsetInFragmentExpr() const
const RexScalar * getAndReleaseCondition() const
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
std::vector< ConstRexScalarPtr > ConstRexScalarPtrVector
ConstRexScalarPtrVector order_keys_
bool operator==(const SortField &that) const
std::vector< RexLiteral > RexLiteralArray
RelModify(Catalog_Namespace::Catalog const &cat, TableDescriptor const *const td, bool flattened, ModifyOperation op, TargetColumnList const &target_column_list, RelAlgNodeInputPtr input)
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)
std::vector< std::pair< std::unique_ptr< const RexScalar >, std::unique_ptr< const RexScalar > > > expr_pair_list_
SqlWindowFunctionKind
Definition: sqldefs.h:73
RexFunctionOperator(const std::string &name, ConstRexScalarPtrVector &operands, const SQLTypeInfo &ti)
const SQLTypes target_type_
std::vector< RexLiteralArray > TupleContentsArray
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 * getFilterExpr() const
ModifyOperation operation_
#define CHECK(condition)
Definition: Logger.h:187
RelProject(std::vector< std::unique_ptr< const RexScalar >> &scalar_exprs, const std::vector< std::string > &fields, std::shared_ptr< const RelAlgNode > input)
bool const isFlattened() const
std::string toString() const override
ConstRexScalarPtrVector partition_keys_
std::unique_ptr< RexRef > deepCopy() const
const RelAlgNode * getInput(const size_t idx) const
const SQLTypeInfo & getType() const
const std::vector< std::string > & getFields() const
const SQLTypeInfo type_
const std::vector< size_t > operands_
std::string toString() const override
void setExpressions(std::vector< std::unique_ptr< const RexScalar >> &exprs) const
const std::shared_ptr< RelFilter > original_filter_
unsigned getScale() 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::shared_ptr< const ExecutionResult > getExecutionResult() const
specifies the content in-memory of a row in the table metadata table
const std::string & getName() const
RANodeOutput get_node_output(const RelAlgNode *ra_node)
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
std::string toString() const
std::string toString() const override
size_t operator()(const RexInput &rex_in) const
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
const unsigned scale_
TargetColumnList target_column_list_
void setAggExprs(std::vector< std::unique_ptr< const RexAgg >> &agg_exprs)
std::vector< std::string > fields_
void visitScalarExprs(EXPR_VISITOR_FUNCTOR visitor_functor) const
ConstRexScalarPtrVector getOrderKeysAndRelease() const
unsigned getTypePrecision() const
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)
void setFields(std::vector< std::string > &new_fields)
std::vector< std::string > ColumnNameList
RexRef(const size_t index)
const SQLTypeInfo & getType() const
size_t getField() const
bool isDistinct() const
std::string toString() const override
const RexScalar * getElse() const