10#include <mutable/mutable-config.hpp>
36 friend struct Decorrelation;
40 std::vector<std::reference_wrapper<Join>>
joins_;
44 bool decorrelated_ =
true;
48 if (alias_.has_value()
and strlen(*alias_) == 0)
49 throw invalid_argument(
"if the data source has an alias, it must not be empty");
56 std::size_t
id()
const {
return id_; }
69 const auto &
joins()
const {
return joins_; }
76 auto it = std::find_if(joins_.begin(), joins_.end(), [&join](
auto j) { return &j.get() == &join; });
77 if (it == joins_.end())
91 friend struct GetPrimaryKey;
133 bool is_correlated()
const override;
139 using sources_t = std::vector<std::reference_wrapper<DataSource>>;
156 if (this->condition_ != other.
condition_)
return false;
157 if (this->sources().size() != other.
sources().size())
return false;
158 for (
auto &this_src : sources_) {
159 auto it = std::find_if(other.
sources().begin(), other.
sources().end(), [this_src](
auto other_src) {
160 return &this_src.get() == &other_src.get();
162 if (it == other.
sources().end())
return false;
174 friend struct Decorrelation;
175 friend struct GetPrimaryKey;
179 using order_type = std::pair<std::reference_wrapper<const ast::Expr>,
bool>;
184 std::vector<std::unique_ptr<Join>>
joins_;
187 std::vector<std::reference_wrapper<const ast::FnApplicationExpr>>
aggregates_;
190 struct { uint64_t limit = 0, offset = 0; } limit_;
221 static std::unique_ptr<QueryGraph> Build(
const ast::Stmt &stmt);
230 source->id_ = sources_.size();
231 sources_.emplace_back(source.release());
234 std::unique_ptr<BaseTable> base(
new BaseTable(sources_.size(), std::move(alias), table));
235 auto &ref = sources_.emplace_back(std::move(base));
236 return as<BaseTable>(*ref);
239 std::unique_ptr<Query> Q(
new Query(sources_.size(), std::move(alias), std::move(query_graph)));
240 auto &ref = sources_.emplace_back(std::move(Q));
241 return as<Query>(*ref);
245 auto it = std::next(sources_.begin(),
id);
246 auto ds = std::move(*it);
247 M_insist(ds->id() ==
id,
"IDs of sources must be sequential");
250 while (it != sources_.end()) {
257 const auto &
sources()
const {
return sources_; }
258 const auto &
joins()
const {
return joins_; }
259 const auto &
group_by()
const {
return group_by_; }
261 const std::vector<projection_type> &
projections()
const {
return projections_; }
262 const auto &
order_by()
const {
return order_by_; }
263 auto limit()
const {
return limit_; }
267 auto &ds = sources_[
id];
268 M_insist(ds->id() ==
id,
"given id and data source id must match");
273 bool grouping()
const {
return not group_by_.empty() or not aggregates_.empty(); }
275 bool is_correlated()
const;
278 if (not adjacency_matrix_) [[unlikely]]
279 compute_adjacency_matrix();
280 return *adjacency_matrix_;
284 if (not adjacency_matrix_) [[unlikely]]
285 compute_adjacency_matrix();
286 return *adjacency_matrix_;
290 void dot(std::ostream &out)
const;
293 void sql(std::ostream &out)
const;
297 M_insist(not t_ or *t_ == *t,
"QueryGraph is already linked to another transaction");
300 for (
auto &ds : sources_)
301 if (
auto bt = cast<const Query>(ds.get()))
302 bt->query_graph_->transaction(t_);
309 M_insist(std::find_if(sources_.begin(), sources_.end(), [&](std::unique_ptr<DataSource> &source){
310 return *source == ds;
311 }) != sources_.end());
313 auto filter = cnf::to_CNF(*filter_expr);
315 custom_filter_exprs_.push_back(std::move(filter_expr));
319 void dump(std::ostream &out)
const;
323 void compute_adjacency_matrix()
const;
324 void dot_recursive(std::ostream &out)
const;
327 auto it = std::find_if(joins_.begin(), joins_.end(), [&join](
auto &j) { return j.get() == &join; });
328 if (it == joins_.end())
and(sizeof(T)==4) U64x1 reinterpret_to_U64(m
void swap(PlanTableBase< Actual > &first, PlanTableBase< Actual > &second)
ThreadSafeStringPool::proxy_optional_type ThreadSafePooledOptionalString
An adjacency matrix for a given query graph.
A BaseTable is a DataSource that is materialized and stored persistently by the database system.
bool is_correlated() const override
BaseTable is never correlated.
ThreadSafePooledOptionalString name() const override
Returns the name of this DataSource.
const Table & table() const
Returns a reference to the Table providing the tuples.
BaseTable(std::size_t id, ThreadSafePooledOptionalString alias, const Table &table)
list of designators expanded from GetPrimaryKey::compute() or GetAttributes::compute()
const Table & table_
the table providing the tuples
A DataSource in a QueryGraph.
std::size_t id_
unique identifier of this data source within its query graph
const cnf::CNF & filter() const
Returns the filter of this DataSource.
virtual ThreadSafePooledOptionalString name() const =0
Returns the name of this DataSource.
const ThreadSafePooledOptionalString & alias() const
Returns the alias of this DataSource.
const auto & joins() const
Returns a reference to the Joins using this DataSource.
DataSource(std::size_t id, ThreadSafePooledOptionalString alias)
std::vector< std::reference_wrapper< Join > > joins_
joins with this data source
virtual bool is_correlated() const =0
Returns true iff the data source is correlated.
ThreadSafePooledOptionalString alias_
alias of this data source, may not have a value if this data source has no alias
void update_filter(cnf::CNF filter)
Adds filter to the current filter of this DataSource by logical conjunction.
cnf::CNF filter_
filter condition on this data source
void remove_join(Join &join)
bool operator==(const DataSource &other) const
void add_join(Join &join)
Adds join to the set of Joins of this DataSource.
std::size_t id() const
Returns the id of this DataSource.
bool operator!=(const DataSource &other) const
A Join in a QueryGraph combines DataSources by a join condition.
std::vector< std::reference_wrapper< DataSource > > sources_t
const cnf::CNF & condition() const
Returns the join condition.
bool operator==(const Join &other) const
sources_t sources_
the sources to join
cnf::CNF condition_
join condition
void update_condition(cnf::CNF update)
Adds condition to the current condition of this Join by logical conjunction.
bool operator!=(const Join &other) const
Join(cnf::CNF condition, sources_t sources)
const sources_t & sources() const
Returns a reference to the joined DataSources.
The query graph represents all data sources and joins in a graph structure.
std::size_t num_joins() const
Returns the number of Joins in this graph.
std::vector< order_type > order_by_
the order
friend void swap(QueryGraph &first, QueryGraph &second)
struct m::QueryGraph::@0 limit_
limit: limit and offset
QueryGraph & operator=(QueryGraph &&other)
std::vector< std::unique_ptr< Join > > joins_
collection of all joins in this query graph
const auto & group_by() const
void add_source(std::unique_ptr< DataSource > source)
const std::vector< projection_type > & projections() const
const DataSource & operator[](uint64_t id) const
Returns a data souce given its id.
QueryGraph(QueryGraph &&other)
bool grouping() const
Returns true iff the graph contains a grouping.
Scheduler::Transaction * transaction() const
Returns the transaction ID.
std::vector< std::unique_ptr< ast::Expr > > custom_filter_exprs_
Stores the expressions of custom filters that have been added to the DataSources after semantic anal...
const auto & joins() const
std::pair< std::reference_wrapper< const ast::Expr >, ThreadSafePooledOptionalString > projection_type
std::pair< std::reference_wrapper< const ast::Expr >, bool > order_type
true means ascending, false means descending
QueryGraph(const QueryGraph &)=delete
const AdjacencyMatrix & adjacency_matrix() const
std::size_t num_sources() const
Returns the number of DataSources in this graph.
void add_custom_filter(std::unique_ptr< ast::Expr > filter_expr, DataSource &ds)
Creates a cnf::CNF from filter_expr and adds it to the current filter of the given DataSource ds by l...
const auto & aggregates() const
void remove_join(Join &join)
const auto & order_by() const
std::vector< std::reference_wrapper< const ast::FnApplicationExpr > > aggregates_
the aggregates to compute
const auto & sources() const
std::unique_ptr< DataSource > remove_source(std::size_t id)
std::vector< projection_type > projections_
the data to compute
BaseTable & add_source(ThreadSafePooledOptionalString alias, const Table &table)
std::pair< std::reference_wrapper< const ast::Expr >, ThreadSafePooledOptionalString > group_type
void transaction(Scheduler::Transaction *t)
Set the transaction ID.
Scheduler::Transaction * t_
the transaction this query graph belongs to
std::unique_ptr< AdjacencyMatrix > adjacency_matrix_
std::vector< group_type > group_by_
the grouping keys
std::vector< std::unique_ptr< DataSource > > sources_
collection of all data sources in this query graph
Query & add_source(ThreadSafePooledOptionalString alias, std::unique_ptr< QueryGraph > query_graph)
AdjacencyMatrix & adjacency_matrix()
A Query in a QueryGraph is a DataSource that represents a nested query.
Query(std::size_t id, ThreadSafePooledOptionalString alias, std::unique_ptr< QueryGraph > query_graph)
std::unique_ptr< QueryGraph > query_graph_
query graph of the sub-query
ThreadSafePooledOptionalString name() const override
Returns the name of this DataSource.
QueryGraph & query_graph() const
Returns a reference to the internal QueryGraph.
Implements a small and efficient set over integers in the range of 0 to 63 (including).
A table is a sorted set of attributes.
virtual const ThreadSafePooledString & name() const =0
Returns the name of the Table.
A CNF represents a conjunction of cnf::Clauses.
Signals that an argument to a function of method was invalid.