mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
Operator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <mutable/mutable-config.hpp>
5#include <mutable/IR/CNF.hpp>
10#include <functional>
11#include <iostream>
12#include <unordered_map>
13#include <utility>
14#include <variant>
15#include <vector>
16
17
18namespace m {
19
20// forward declarations
21struct OperatorVisitor;
23struct Tuple;
24
27struct M_EXPORT OperatorInformation
28{
31
34};
35
37struct M_EXPORT OperatorData
38{
39 virtual ~OperatorData() = 0;
40};
41
44struct M_EXPORT Operator
45{
46 friend void swap(Operator &first, Operator &second) {
47 using std::swap;
48 swap(first.schema_, second.schema_);
49 swap(first.info_, second.info_);
50 swap(first.data_, second.data_);
51 swap(first.id_, second.id_);
52 }
53
54 private:
56 std::unique_ptr<OperatorInformation> info_;
57 mutable OperatorData *data_ = nullptr;
58 protected:
59 mutable std::size_t id_ = -1UL;
60
61 public:
62 Operator() = default;
63 Operator(Operator &&other) : Operator() { swap(*this, other); }
64 virtual ~Operator() { delete data_; }
65
67 Schema & schema() { return schema_; }
69 const Schema & schema() const { return schema_; }
70
71 bool has_info() const { return bool(info_); }
72 OperatorInformation & info() { M_insist(bool(info_)); return *info_; }
73 const OperatorInformation & info() const { return const_cast<Operator*>(this)->info(); }
74 std::unique_ptr<OperatorInformation> info(std::unique_ptr<OperatorInformation> new_info) {
75 using std::swap;
76 swap(new_info, info_);
77 return new_info;
78 }
79
81 virtual void assign_post_order_ids(std::size_t start_id = 0UL) const { id_ = start_id; }
83 virtual void reset_ids() const { id_ = -1UL; }
85 std::size_t id() const {
86 M_insist(id_ != -1UL, "id must be first set by calling `assign_post_order_ids()`");
87 return id_;
88 }
89 private:
91 void id(std::size_t id) const { id_ = id; }
92
93 public:
96 OperatorData * data(OperatorData *data) const { std::swap(data, data_); return data; }
98 OperatorData * data() const { return data_; }
99
100 virtual void accept(OperatorVisitor &v) = 0;
101 virtual void accept(ConstOperatorVisitor &v) const = 0;
102
103 friend M_EXPORT std::ostream & operator<<(std::ostream &out, const Operator &op);
104
107 void minimize_schema();
108
110 void dot(std::ostream &out) const;
111
112 void dump(std::ostream &out) const;
113 void dump() const;
114};
115
116struct Consumer;
117
119struct M_EXPORT Producer : virtual Operator
120{
121 private:
123
124 public:
126 Consumer * parent() const { return parent_; }
128 Consumer * parent(Consumer *c) { std::swap(parent_, c); return c; }
129};
130
132struct M_EXPORT Consumer : virtual Operator
133{
134 private:
135 std::vector<Producer*> children_;
136
137 public:
138 Consumer() = default;
139 Consumer(Consumer&&) = default;
140 virtual ~Consumer() {
141 for (auto c : children_)
142 delete c;
143 }
144
146 virtual void add_child(Producer *child) {
147 if (not child)
148 throw invalid_argument("no child given");
149 children_.push_back(child);
150 child->parent(this);
151 schema() += child->schema();
152 }
154 virtual Producer * set_child(Producer *child, std::size_t i) {
155 if (not child)
156 throw invalid_argument("no child given");
157 if (i >= children_.size())
158 throw out_of_range("index i out of bounds");
159 auto old = children_[i];
160 children_[i] = child;
161 child->parent(this);
162
163 /* Recompute operator schema. */
164 auto &S = schema();
165 S = Schema();
166 for (auto c : children_)
167 S += c->schema();
168
169 return old;
170 }
171
173 const std::vector<Producer*> & children() const { return children_; }
174
176 Producer * child(std::size_t i) const {
177 if (i >= children_.size())
178 throw out_of_range("index i out of bounds");
179 return children_[i];
180 }
181
182 protected:
183 std::vector<Producer*> & children() { return children_; }
184
185 public:
186 void assign_post_order_ids(std::size_t start_id = 0UL) const override {
187 auto next_start_id = start_id;
188 for (auto c : children_) {
189 c->assign_post_order_ids(next_start_id);
190 next_start_id = c->id() + 1;
191 }
192 id_ = next_start_id;
193 }
194 void reset_ids() const override {
195 id_ = -1UL;
196 for (auto c : children_)
197 c->reset_ids();
198 }
199};
200
201struct M_EXPORT CallbackOperator : Consumer
202{
203 using callback_type = std::function<void(const Schema &, const Tuple&)>;
204
205 private:
207
208 public:
209 CallbackOperator(callback_type callback) : callback_(std::move(callback)) { }
210
213 CallbackOperator clone_node() const { return CallbackOperator(callback_); }
214
215 const auto & callback() const { return callback_; }
216
217 void accept(OperatorVisitor &v) override;
218 void accept(ConstOperatorVisitor &v) const override;
219};
220
222struct M_EXPORT PrintOperator : Consumer
223{
224 std::ostream &out;
225
226 PrintOperator(std::ostream &out) : out(out) { }
227
230 PrintOperator clone_node() const { return PrintOperator(out); }
231
232 void accept(OperatorVisitor &v) override;
233 void accept(ConstOperatorVisitor &v) const override;
234};
235
237struct M_EXPORT NoOpOperator : Consumer
238{
239 std::ostream &out;
240
241 NoOpOperator(std::ostream &out) : out(out) { }
242
245 NoOpOperator clone_node() const { return NoOpOperator(out); }
246
247 void accept(OperatorVisitor &v) override;
248 void accept(ConstOperatorVisitor &v) const override;
249};
250
251struct M_EXPORT ScanOperator : Producer
252{
253 private:
254 const Store &store_;
256
257 public:
259 : store_(store)
260 , alias_(std::move(alias))
261 {
262 auto &S = schema();
263 for (auto &e : store.table().schema())
264 S.add({alias_, e.id.name}, e.type, e.constraints);
265 }
266
269 ScanOperator clone_node() const { return ScanOperator(store_, alias_); }
270
271 const Store & store() const { return store_; }
272 const ThreadSafePooledString & alias() const { return alias_; }
273
274 void accept(OperatorVisitor &v) override;
275 void accept(ConstOperatorVisitor &v) const override;
276};
277
279{
280 protected:
282
283 public:
284 FilterOperator(cnf::CNF filter) : filter_(std::move(filter)) { }
285
288 FilterOperator clone_node() const { return FilterOperator(filter_); }
289
290 const cnf::CNF & filter() const { return filter_; }
292 auto old_filter = std::move(filter_);
293 filter_ = std::move(f);
294 return old_filter;
295 }
296
297 void accept(OperatorVisitor &v) override;
298 void accept(ConstOperatorVisitor &v) const override;
299};
300
302{
304 : FilterOperator(std::move(filter))
305 {
306 M_insist(this->filter().size() == 1, "a disjunctive filter must have exactly one clause");
307 M_insist(this->filter()[0].size() >= 2, "a disjunctive filter must have at least two predicates ");
308 }
309
313
314 void accept(OperatorVisitor &v) override;
315 void accept(ConstOperatorVisitor &v) const override;
316};
317
319{
320 static constexpr Schema::entry_type::constraints_t REMOVED_CONSTRAINTS =
321 Schema::entry_type::UNIQUE | Schema::entry_type::REFERENCES_UNIQUE; // FIXME: still unique for 1:1 joins and depends on what was referenced
322
323 private:
325
326 public:
327 JoinOperator(cnf::CNF predicate) : predicate_(std::move(predicate)) { }
328
329 /*----- Override child setters to correctly adapt the constraints of the computed schema! ------------------------*/
330 virtual void add_child(Producer *child) override {
331 const auto old_num_entries = schema().num_entries();
332 Consumer::add_child(child); // delegate to inherited method
333
334 /* Remove uniqueness constraints (in added schema part) due to denormalization. */
335 for (auto i = old_num_entries; i != schema().num_entries(); ++i)
336 schema()[i].constraints &= ~REMOVED_CONSTRAINTS;
337 }
338 virtual Producer * set_child(Producer *child, std::size_t i) override {
339 auto old = Consumer::set_child(child, i); // delegate to inherited method
340
341 /* Remove uniqueness constraints (in entire schema because of recomputation) due to denormalization. */
342 for (auto &e : schema())
343 e.constraints &= ~REMOVED_CONSTRAINTS;
344
345 return old;
346 }
347
350 JoinOperator clone_node() const { return JoinOperator(predicate_); }
351
352 const cnf::CNF & predicate() const { return predicate_; }
353
354 void accept(OperatorVisitor &v) override;
355 void accept(ConstOperatorVisitor &v) const override;
356};
357
359{
361
362 private:
363 std::vector<projection_type> projections_;
364
365 public:
366 ProjectionOperator(std::vector<projection_type> projections);
367
370 ProjectionOperator clone_node() const { return ProjectionOperator(projections_); }
371
372 /*----- Override child setters to *NOT* modify the computed schema! ----------------------------------------------*/
373 virtual void add_child(Producer *child) override {
374 if (not child)
375 throw invalid_argument("no child given");
376 children().push_back(child);
377 child->parent(this);
378
379 /* Add constraints from child to computed schema. */
380 auto &S = schema();
381 for (std::size_t i = 0; i < projections_.size(); ++i) {
382 if (auto D = cast<const ast::Designator>(projections_[i].first)) {
383 Schema::Identifier id(D->table_name.text, D->attr_name.text.assert_not_none());
384 S[i].constraints |= child->schema()[id].second.constraints;
385 }
386 }
387 }
388 virtual Producer * set_child(Producer *child, std::size_t i) override {
389 if (not child)
390 throw invalid_argument("no child given");
391 if (i >= children().size())
392 throw out_of_range("index i out of bounds");
393 auto old = children()[i];
394 children()[i] = child;
395 child->parent(this);
396
397 /* Add constraints from child to computed schema. */
398 auto &S = schema();
399 for (std::size_t i = 0; i < projections_.size(); ++i) {
400 if (auto D = cast<const ast::Designator>(projections_[i].first)) {
401 Schema::Identifier id(D->table_name.text, D->attr_name.text.assert_not_none());
402 S[i].constraints |= child->schema()[id].second.constraints;
403 }
404 }
405
406 return old;
407 }
408
409 const std::vector<projection_type> & projections() const { return projections_; }
410 std::vector<projection_type> & projections() { return projections_; }
411
412 void accept(OperatorVisitor &v) override;
413 void accept(ConstOperatorVisitor &v) const override;
414};
415
417{
418 /* This class is used to unwind the stack when the limit of produced tuples is reached. */
419 struct stack_unwind : std::exception { };
420
421 private:
422 std::size_t limit_;
423 std::size_t offset_;
424
425 public:
426 LimitOperator(std::size_t limit, std::size_t offset)
427 : limit_(limit)
428 , offset_(offset)
429 { }
430
433 LimitOperator clone_node() const { return LimitOperator(limit_, offset_); }
434
435 std::size_t limit() const { return limit_; }
436 std::size_t offset() const { return offset_; }
437
438 void accept(OperatorVisitor &v) override;
439 void accept(ConstOperatorVisitor &v) const override;
440};
441
443{
445
446 private:
447 std::vector<group_type> group_by_;
448 std::vector<std::reference_wrapper<const ast::FnApplicationExpr>> aggregates_;
449
450 public:
451 GroupingOperator(std::vector<group_type> group_by,
452 std::vector<std::reference_wrapper<const ast::FnApplicationExpr>> aggregates);
453
456 GroupingOperator clone_node() const { return GroupingOperator(group_by_, aggregates_); }
457
458 /*----- Override child setters to *NOT* modify the computed schema! ----------------------------------------------*/
459 virtual void add_child(Producer *child) override {
460 if (not child)
461 throw invalid_argument("no child given");
462 children().push_back(child);
463 child->parent(this);
464
465 /* Add constraints from child to computed schema. */
466 auto &S = schema();
467 for (std::size_t i = 0; i < group_by_.size(); ++i) {
468 if (auto D = cast<const ast::Designator>(group_by_[i].first)) {
469 Schema::Identifier id(D->table_name.text, D->attr_name.text.assert_not_none());
470 S[i].constraints |= child->schema()[id].second.constraints;
471 }
472 }
473 }
474 virtual Producer * set_child(Producer *child, std::size_t i) override {
475 if (not child)
476 throw invalid_argument("no child given");
477 if (i >= children().size())
478 throw out_of_range("index i out of bounds");
479 auto old = children()[i];
480 children()[i] = child;
481 child->parent(this);
482
483 /* Add constraints from child to computed schema. */
484 auto &S = schema();
485 for (std::size_t i = 0; i < group_by_.size(); ++i) {
486 if (auto D = cast<const ast::Designator>(group_by_[i].first)) {
487 Schema::Identifier id(D->table_name.text, D->attr_name.text.assert_not_none());
488 S[i].constraints |= child->schema()[id].second.constraints;
489 }
490 }
491
492 return old;
493 }
494
495 const auto & group_by() const { return group_by_; }
496 const auto & aggregates() const { return aggregates_; }
497 auto & aggregates() { return aggregates_; }
498
499 void accept(OperatorVisitor &v) override;
500 void accept(ConstOperatorVisitor &v) const override;
501};
502
504{
505 private:
506 std::vector<std::reference_wrapper<const ast::FnApplicationExpr>> aggregates_;
507
508 public:
509 AggregationOperator(std::vector<std::reference_wrapper<const ast::FnApplicationExpr>> aggregates);
510
513 AggregationOperator clone_node() const { return AggregationOperator(aggregates_); }
514
515 /*----- Override child setters to *NOT* modify the computed schema! ----------------------------------------------*/
516 virtual void add_child(Producer *child) override {
517 if (not child)
518 throw invalid_argument("no child given");
519 children().push_back(child);
520 child->parent(this);
521 }
522 virtual Producer * set_child(Producer *child, std::size_t i) override {
523 if (not child)
524 throw invalid_argument("no child given");
525 if (i >= children().size())
526 throw out_of_range("index i out of bounds");
527 auto old = children()[i];
528 children()[i] = child;
529 child->parent(this);
530 return old;
531 }
532
533 const auto & aggregates() const { return aggregates_; }
534 auto & aggregates() { return aggregates_; }
535
536 void accept(OperatorVisitor &v) override;
537 void accept(ConstOperatorVisitor &v) const override;
538};
539
541{
543
544 private:
545 std::vector<order_type> order_by_;
546
547 public:
548 SortingOperator(std::vector<order_type> order_by) : order_by_(std::move(order_by)) { }
549
552 SortingOperator clone_node() const { return SortingOperator(order_by_); }
553
554 const auto & order_by() const { return order_by_; }
555
556 void accept(OperatorVisitor &v) override;
557 void accept(ConstOperatorVisitor &v) const override;
558};
559
560#define M_OPERATOR_LIST(X) \
561 X(ScanOperator) \
562 X(CallbackOperator) \
563 X(PrintOperator) \
564 X(NoOpOperator) \
565 X(FilterOperator) \
566 X(DisjunctiveFilterOperator) \
567 X(JoinOperator) \
568 X(ProjectionOperator) \
569 X(LimitOperator) \
570 X(GroupingOperator) \
571 X(AggregationOperator) \
572 X(SortingOperator)
573
574M_DECLARE_VISITOR(OperatorVisitor, Operator, M_OPERATOR_LIST)
576
577namespace {
578
579template<bool C>
580struct ThePreOrderOperatorVisitor : std::conditional_t<C, ConstOperatorVisitor, OperatorVisitor>
581{
582 using super = std::conditional_t<C, ConstOperatorVisitor, OperatorVisitor>;
583 template<typename T> using Const = typename super::template Const<T>;
584 void operator()(Const<Operator> &op) override {
585 try { op.accept(*this); } catch (visit_skip_subtree) { return; }
586 if (auto c = cast<Const<Consumer>>(&op)) {
587 for (auto child : c->children())
588 (*this)(*child);
589 }
590 }
591};
592
593template<bool C>
594struct ThePostOrderOperatorVisitor : std::conditional_t<C, ConstOperatorVisitor, OperatorVisitor>
595{
596 using super = std::conditional_t<C, ConstOperatorVisitor, OperatorVisitor>;
597 template<typename T> using Const = typename super::template Const<T>;
598 void operator()(Const<Operator> &op) override {
599 if (auto c = cast<Const<Consumer>>(&op)) {
600 for (auto child : c->children())
601 (*this)(*child);
602 }
603 op.accept(*this);
604 }
605};
606
607}
608using PreOrderOperatorVisitor = ThePreOrderOperatorVisitor<false>;
609using ConstPreOrderOperatorVisitor = ThePreOrderOperatorVisitor<true>;
610using PostOrderOperatorVisitor = ThePostOrderOperatorVisitor<false>;
611using ConstPostOrderOperatorVisitor = ThePostOrderOperatorVisitor<true>;
612
617
618
619enum class OperatorKind
620{
621#define X(Kind) Kind,
623#undef X
624};
625
626}
#define id(X)
#define M_OPERATOR_LIST(X)
Definition: Operator.hpp:560
#define M_DECLARE_VISITOR(VISITOR_NAME, BASE_CLASS, CLASS_LIST)
Defines a visitor VISITOR_NAME to visit the class hierarchy rooted in BASE_CLASS and with subclasses ...
Definition: Visitor.hpp:181
#define M_MAKE_STL_VISITABLE(VISITOR, BASE_CLASS, CLASS_LIST)
Defines a function visit() to make the class hierarchy STL-style visitable with VISITOR.
Definition: Visitor.hpp:166
#define M_insist(...)
Definition: macro.hpp:129
‍mutable namespace
Definition: Backend.hpp:10
ThePreOrderOperatorVisitor< true > ConstPreOrderOperatorVisitor
Definition: Operator.hpp:609
ThePreOrderOperatorVisitor< false > PreOrderOperatorVisitor
Definition: Operator.hpp:608
void swap(PlanTableBase< Actual > &first, PlanTableBase< Actual > &second)
Definition: PlanTable.hpp:394
ThreadSafeStringPool::proxy_type ThreadSafePooledString
Definition: Pool.hpp:464
ThePostOrderOperatorVisitor< false > PostOrderOperatorVisitor
Definition: Operator.hpp:610
OperatorKind
Definition: Operator.hpp:620
STL namespace.
void accept(OperatorVisitor &v) override
const auto & aggregates() const
Definition: Operator.hpp:533
virtual void add_child(Producer *child) override
Adds a child to this Consumer and updates this Consumers schema accordingly.
Definition: Operator.hpp:516
virtual Producer * set_child(Producer *child, std::size_t i) override
Sets the i-th child of this Consumer.
Definition: Operator.hpp:522
std::vector< std::reference_wrapper< const ast::FnApplicationExpr > > aggregates_
the aggregates to compute
Definition: Operator.hpp:506
void accept(ConstOperatorVisitor &v) const override
AggregationOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:513
CallbackOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:213
std::function< void(const Schema &, const Tuple &)> callback_type
Definition: Operator.hpp:203
void accept(OperatorVisitor &v) override
callback_type callback_
Definition: Operator.hpp:206
void accept(ConstOperatorVisitor &v) const override
CallbackOperator(callback_type callback)
Definition: Operator.hpp:209
const auto & callback() const
Definition: Operator.hpp:215
A Consumer is an Operator that can be evaluated on a sequence of tuples.
Definition: Operator.hpp:133
void reset_ids() const override
Resets the IDs of the operator tree rooted in this.
Definition: Operator.hpp:194
virtual Producer * set_child(Producer *child, std::size_t i)
Sets the i-th child of this Consumer.
Definition: Operator.hpp:154
Producer * child(std::size_t i) const
Returns the i-th child of this Consumer.
Definition: Operator.hpp:176
Consumer()=default
std::vector< Producer * > & children()
Definition: Operator.hpp:183
virtual void add_child(Producer *child)
Adds a child to this Consumer and updates this Consumers schema accordingly.
Definition: Operator.hpp:146
Consumer(Consumer &&)=default
virtual ~Consumer()
Definition: Operator.hpp:140
const std::vector< Producer * > & children() const
Returns a reference to the children of this Consumer.
Definition: Operator.hpp:173
std::vector< Producer * > children_
the children of this Consumer
Definition: Operator.hpp:135
void assign_post_order_ids(std::size_t start_id=0UL) const override
Assigns IDs to the operator tree rooted in this in post-order starting with ID start_id.
Definition: Operator.hpp:186
DisjunctiveFilterOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:312
void accept(OperatorVisitor &v) override
void accept(ConstOperatorVisitor &v) const override
DisjunctiveFilterOperator(cnf::CNF filter)
Definition: Operator.hpp:303
cnf::CNF filter_
Definition: Operator.hpp:281
const cnf::CNF & filter() const
Definition: Operator.hpp:290
const cnf::CNF filter(cnf::CNF f)
Definition: Operator.hpp:291
FilterOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:288
void accept(ConstOperatorVisitor &v) const override
void accept(OperatorVisitor &v) override
FilterOperator(cnf::CNF filter)
Definition: Operator.hpp:284
std::vector< group_type > group_by_
the compound grouping key
Definition: Operator.hpp:447
std::vector< std::reference_wrapper< const ast::FnApplicationExpr > > aggregates_
the aggregates to compute
Definition: Operator.hpp:448
virtual void add_child(Producer *child) override
Adds a child to this Consumer and updates this Consumers schema accordingly.
Definition: Operator.hpp:459
void accept(ConstOperatorVisitor &v) const override
QueryGraph::group_type group_type
Definition: Operator.hpp:444
GroupingOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:456
const auto & aggregates() const
Definition: Operator.hpp:496
const auto & group_by() const
Definition: Operator.hpp:495
virtual Producer * set_child(Producer *child, std::size_t i) override
Sets the i-th child of this Consumer.
Definition: Operator.hpp:474
void accept(OperatorVisitor &v) override
const cnf::CNF & predicate() const
Definition: Operator.hpp:352
JoinOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:350
virtual void add_child(Producer *child) override
Adds a child to this Consumer and updates this Consumers schema accordingly.
Definition: Operator.hpp:330
virtual Producer * set_child(Producer *child, std::size_t i) override
Sets the i-th child of this Consumer.
Definition: Operator.hpp:338
JoinOperator(cnf::CNF predicate)
Definition: Operator.hpp:327
cnf::CNF predicate_
Definition: Operator.hpp:324
void accept(OperatorVisitor &v) override
void accept(ConstOperatorVisitor &v) const override
LimitOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:433
LimitOperator(std::size_t limit, std::size_t offset)
Definition: Operator.hpp:426
std::size_t limit_
Definition: Operator.hpp:422
void accept(OperatorVisitor &v) override
std::size_t limit() const
Definition: Operator.hpp:435
void accept(ConstOperatorVisitor &v) const override
std::size_t offset_
Definition: Operator.hpp:423
std::size_t offset() const
Definition: Operator.hpp:436
std::conditional_t< C, ConstOperatorVisitor, OperatorVisitor > super
Definition: Operator.hpp:596
typename super::template Const< T > Const
Definition: Operator.hpp:597
void operator()(Const< Operator > &op) override
Definition: Operator.hpp:598
std::conditional_t< C, ConstOperatorVisitor, OperatorVisitor > super
Definition: Operator.hpp:582
void operator()(Const< Operator > &op) override
Definition: Operator.hpp:584
typename super::template Const< T > Const
Definition: Operator.hpp:583
Drops the produced results and outputs only the number of result tuples produced.
Definition: Operator.hpp:238
void accept(ConstOperatorVisitor &v) const override
NoOpOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:245
NoOpOperator(std::ostream &out)
Definition: Operator.hpp:241
void accept(OperatorVisitor &v) override
std::ostream & out
Definition: Operator.hpp:239
This interface allows for attaching arbitrary data to Operator instances.
Definition: Operator.hpp:38
This class provides additional information about an Operator, e.g.
Definition: Operator.hpp:28
QueryGraph::Subproblem subproblem
‍the subproblem processed by this Operator's subplan
Definition: Operator.hpp:30
double estimated_cardinality
‍the estimated cardinality of the result set of this Operator
Definition: Operator.hpp:33
An Operator represents an operation in a query plan.
Definition: Operator.hpp:45
virtual void reset_ids() const
Resets the IDs of the operator tree rooted in this.
Definition: Operator.hpp:83
OperatorData * data() const
Returns the OperatorData attached to this Operator.
Definition: Operator.hpp:98
Operator(Operator &&other)
Definition: Operator.hpp:63
const OperatorInformation & info() const
Definition: Operator.hpp:73
Schema & schema()
Returns the Schema of this Operator.
Definition: Operator.hpp:67
virtual void assign_post_order_ids(std::size_t start_id=0UL) const
Assigns IDs to the operator tree rooted in this in post-order starting with ID start_id.
Definition: Operator.hpp:81
const Schema & schema() const
Returns the Schema of this Operator.
Definition: Operator.hpp:69
Operator()=default
OperatorData * data(OperatorData *data) const
Attached OperatorData data to this Operator.
Definition: Operator.hpp:96
virtual void accept(OperatorVisitor &v)=0
std::size_t id_
the ID of this Operator; used as index in the DP table of PhysicalOperator
Definition: Operator.hpp:59
OperatorInformation & info()
Definition: Operator.hpp:72
virtual ~Operator()
Definition: Operator.hpp:64
Schema schema_
the schema of this Operator
Definition: Operator.hpp:55
bool has_info() const
Definition: Operator.hpp:71
friend M_EXPORT std::ostream & operator<<(std::ostream &out, const Operator &op)
virtual void accept(ConstOperatorVisitor &v) const =0
void id(std::size_t id) const
Sets the ID of this.
Definition: Operator.hpp:91
friend void swap(Operator &first, Operator &second)
Definition: Operator.hpp:46
std::unique_ptr< OperatorInformation > info_
additional information about this Operator
Definition: Operator.hpp:56
std::size_t id() const
Returns the ID of this.
Definition: Operator.hpp:85
OperatorData * data_
the data object associated to this Operator; may be nullptr
Definition: Operator.hpp:57
std::unique_ptr< OperatorInformation > info(std::unique_ptr< OperatorInformation > new_info)
Definition: Operator.hpp:74
Prints the produced Tuples to a std::ostream instance.
Definition: Operator.hpp:223
std::ostream & out
Definition: Operator.hpp:224
void accept(OperatorVisitor &v) override
PrintOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:230
PrintOperator(std::ostream &out)
Definition: Operator.hpp:226
void accept(ConstOperatorVisitor &v) const override
A Producer is an Operator that can be evaluated to a sequence of tuples.
Definition: Operator.hpp:120
Consumer * parent() const
Returns the parent of this Producer.
Definition: Operator.hpp:126
Consumer * parent_
the parent of this Producer
Definition: Operator.hpp:122
Consumer * parent(Consumer *c)
Sets the parent of this Producer.
Definition: Operator.hpp:128
std::vector< projection_type > projections_
Definition: Operator.hpp:363
std::vector< projection_type > & projections()
Definition: Operator.hpp:410
QueryGraph::projection_type projection_type
Definition: Operator.hpp:360
virtual Producer * set_child(Producer *child, std::size_t i) override
Sets the i-th child of this Consumer.
Definition: Operator.hpp:388
ProjectionOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:370
virtual void add_child(Producer *child) override
Adds a child to this Consumer and updates this Consumers schema accordingly.
Definition: Operator.hpp:373
void accept(OperatorVisitor &v) override
void accept(ConstOperatorVisitor &v) const override
const std::vector< projection_type > & projections() const
Definition: Operator.hpp:409
std::pair< std::reference_wrapper< const ast::Expr >, ThreadSafePooledOptionalString > projection_type
Definition: QueryGraph.hpp:178
std::pair< std::reference_wrapper< const ast::Expr >, bool > order_type
true means ascending, false means descending
Definition: QueryGraph.hpp:179
std::pair< std::reference_wrapper< const ast::Expr >, ThreadSafePooledOptionalString > group_type
Definition: QueryGraph.hpp:180
void accept(OperatorVisitor &v) override
ScanOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:269
const ThreadSafePooledString & alias() const
Definition: Operator.hpp:272
const Store & store() const
Definition: Operator.hpp:271
const Store & store_
Definition: Operator.hpp:254
void accept(ConstOperatorVisitor &v) const override
ScanOperator(const Store &store, ThreadSafePooledString alias)
Definition: Operator.hpp:258
ThreadSafePooledString alias_
Definition: Operator.hpp:255
An Identifier is composed of a name and an optional prefix.
Definition: Schema.hpp:42
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
Definition: Schema.hpp:39
Implements a small and efficient set over integers in the range of 0 to 63 (including).
Definition: ADT.hpp:26
std::vector< order_type > order_by_
the order to sort by
Definition: Operator.hpp:545
const auto & order_by() const
Definition: Operator.hpp:554
QueryGraph::order_type order_type
Definition: Operator.hpp:542
SortingOperator clone_node() const
Creates and returns a copy of this single operator node, i.e.
Definition: Operator.hpp:552
void accept(ConstOperatorVisitor &v) const override
SortingOperator(std::vector< order_type > order_by)
Definition: Operator.hpp:548
void accept(OperatorVisitor &v) override
Defines a generic store interface.
Definition: Store.hpp:22
const Table & table() const
Definition: Store.hpp:36
virtual Schema schema(const ThreadSafePooledOptionalString &alias={}) const =0
Returns a Schema for this Table given the alias alias.
A CNF represents a conjunction of cnf::Clauses.
Definition: CNF.hpp:134
Signals that an argument to a function of method was invalid.
Definition: exception.hpp:37
Signals that an index-based or key-based access was out of range.
Definition: exception.hpp:43
Exception class which can be thrown to skip recursion of the subtree in pre-order visitors.
Definition: Visitor.hpp:18