Query::Plan::Aggregate API

Reviewers: mislav.bradac, buda, teon.banek

Reviewed By: mislav.bradac, teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D229
This commit is contained in:
florijan 2017-04-06 09:31:02 +02:00
parent f7f44a3e81
commit feee6ed80e
4 changed files with 81 additions and 9 deletions

View File

@ -363,6 +363,24 @@ class PropertyLookup : public Expression {
: Expression(uid), expression_(expression), property_(property) {}
};
class Aggregation : public UnaryOperator {
friend class AstTreeStorage;
public:
enum class Op { COUNT, MIN, MAX, SUM, AVG };
Op op_;
void Accept(TreeVisitorBase &visitor) override {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
protected:
Aggregation(int uid, Expression *expression, Op op)
: UnaryOperator(uid, expression), op_(op) {}
};
class NamedExpression : public Tree {
friend class AstTreeStorage;

View File

@ -9,6 +9,7 @@ class Query;
class NamedExpression;
class Identifier;
class PropertyLookup;
class Aggregation;
class Create;
class Match;
class Return;
@ -48,6 +49,7 @@ using TreeVisitorBase = ::utils::Visitor<
DivisionOperator, ModOperator, NotEqualOperator, EqualOperator,
LessOperator, GreaterOperator, LessEqualOperator, GreaterEqualOperator,
UnaryPlusOperator, UnaryMinusOperator, Identifier, Literal, PropertyLookup,
Create, Match, Return, With, Pattern, NodeAtom, EdgeAtom, Delete, Where,
SetProperty, SetProperties, SetLabels, RemoveProperty, RemoveLabels>;
Aggregation, Create, Match, Return, With, Pattern, NodeAtom, EdgeAtom,
Delete, Where, SetProperty, SetProperties, SetLabels, RemoveProperty,
RemoveLabels>;
}

View File

@ -905,5 +905,20 @@ bool Accumulate::AccumulateCursor::Pull(Frame &frame,
return true;
}
Aggregate::Aggregate(const std::shared_ptr<LogicalOperator> &input,
const std::vector<Aggregate::Element> &aggregations,
std::vector<NamedExpression *> group_by)
: input_(input), aggregations_(aggregations), group_by_(group_by) {}
void Aggregate::Accept(LogicalOperatorVisitor &visitor) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
std::unique_ptr<Cursor> Aggregate::MakeCursor(GraphDbAccessor &db) {
return std::unique_ptr<Cursor>();
}
} // namespace plan
} // namespace query

View File

@ -56,13 +56,16 @@ template <typename TAccessor>
class ExpandUniquenessFilter;
class Accumulate;
class AdvanceCommand;
class Aggregate;
/** @brief Base class for visitors of @c LogicalOperator class hierarchy. */
using LogicalOperatorVisitor = ::utils::Visitor<
CreateNode, CreateExpand, ScanAll, Expand, NodeFilter, EdgeFilter, Filter,
Produce, Delete, SetProperty, SetProperties, SetLabels, RemoveProperty,
RemoveLabels, ExpandUniquenessFilter<VertexAccessor>,
ExpandUniquenessFilter<EdgeAccessor>, Accumulate, AdvanceCommand>;
using LogicalOperatorVisitor =
::utils::Visitor<CreateNode, CreateExpand, ScanAll, Expand, NodeFilter,
EdgeFilter, Filter, Produce, Delete, SetProperty,
SetProperties, SetLabels, RemoveProperty, RemoveLabels,
ExpandUniquenessFilter<VertexAccessor>,
ExpandUniquenessFilter<EdgeAccessor>, Accumulate,
AdvanceCommand, Aggregate>;
/** @brief Base class for logical operators.
*
@ -771,8 +774,8 @@ class ExpandUniquenessFilter : public LogicalOperator {
*/
class Accumulate : public LogicalOperator {
public:
Accumulate(std::shared_ptr<LogicalOperator> input, const std::vector<Symbol> &symbols,
bool advance_command=false);
Accumulate(std::shared_ptr<LogicalOperator> input,
const std::vector<Symbol> &symbols, bool advance_command = false);
void Accept(LogicalOperatorVisitor &visitor) override;
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor &db) override;
@ -785,6 +788,7 @@ class Accumulate : public LogicalOperator {
public:
AccumulateCursor(Accumulate &self, GraphDbAccessor &db);
bool Pull(Frame &frame, SymbolTable &symbol_table) override;
private:
Accumulate &self_;
GraphDbAccessor &db_;
@ -795,5 +799,38 @@ class Accumulate : public LogicalOperator {
};
};
/** @brief Performs an arbitrary number of aggregations of data
* from the given input grouped by the given criteria.
*
* Aggregations are defined by triples that define
* (input data expression, type of aggregation, output symbol).
* Input data is grouped based on the given set of named
* expressions. Grouping is done on unique values.
*
* IMPORTANT:
* Ops taking their input from an aggregation are only
* allowed to use frame values that are either aggregation
* outputs or group-by named-expressions. All other frame
* elements are in an undefined state after aggregation.
*/
class Aggregate : public LogicalOperator {
public:
/** @brief An aggregation element, contains:
* (input data expression, type of aggregation, output symbol).
*/
using Element = std::tuple<Expression *, Aggregation::Op, Symbol>;
Aggregate(const std::shared_ptr<LogicalOperator> &input,
const std::vector<Element> &aggregations,
std::vector<NamedExpression *> group_by);
void Accept(LogicalOperatorVisitor &visitor) override;
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor &db) override;
private:
std::shared_ptr<LogicalOperator> input_;
std::vector<Element> aggregations_;
std::vector<NamedExpression *> group_by_;
};
} // namespace plan
} // namespace query