From feee6ed80ed7ca349dd1a834a6d84cf22810040a Mon Sep 17 00:00:00 2001 From: florijan Date: Thu, 6 Apr 2017 09:31:02 +0200 Subject: [PATCH] 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 --- src/query/frontend/ast/ast.hpp | 18 +++++++++ src/query/frontend/ast/ast_visitor.hpp | 6 ++- src/query/frontend/logical/operator.cpp | 15 ++++++++ src/query/frontend/logical/operator.hpp | 51 +++++++++++++++++++++---- 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp index b3a972022..cac2021d9 100644 --- a/src/query/frontend/ast/ast.hpp +++ b/src/query/frontend/ast/ast.hpp @@ -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; diff --git a/src/query/frontend/ast/ast_visitor.hpp b/src/query/frontend/ast/ast_visitor.hpp index 871f32c84..4ddc17583 100644 --- a/src/query/frontend/ast/ast_visitor.hpp +++ b/src/query/frontend/ast/ast_visitor.hpp @@ -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>; } diff --git a/src/query/frontend/logical/operator.cpp b/src/query/frontend/logical/operator.cpp index 036d9a9e6..e6ccfbc42 100644 --- a/src/query/frontend/logical/operator.cpp +++ b/src/query/frontend/logical/operator.cpp @@ -905,5 +905,20 @@ bool Accumulate::AccumulateCursor::Pull(Frame &frame, return true; } +Aggregate::Aggregate(const std::shared_ptr &input, + const std::vector &aggregations, + std::vector 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 Aggregate::MakeCursor(GraphDbAccessor &db) { + return std::unique_ptr(); +} + } // namespace plan } // namespace query diff --git a/src/query/frontend/logical/operator.hpp b/src/query/frontend/logical/operator.hpp index dad258df5..c61be1735 100644 --- a/src/query/frontend/logical/operator.hpp +++ b/src/query/frontend/logical/operator.hpp @@ -56,13 +56,16 @@ template 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, - ExpandUniquenessFilter, Accumulate, AdvanceCommand>; +using LogicalOperatorVisitor = + ::utils::Visitor, + ExpandUniquenessFilter, 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 input, const std::vector &symbols, - bool advance_command=false); + Accumulate(std::shared_ptr input, + const std::vector &symbols, bool advance_command = false); void Accept(LogicalOperatorVisitor &visitor) override; std::unique_ptr 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; + + Aggregate(const std::shared_ptr &input, + const std::vector &aggregations, + std::vector group_by); + void Accept(LogicalOperatorVisitor &visitor) override; + std::unique_ptr MakeCursor(GraphDbAccessor &db) override; + + private: + std::shared_ptr input_; + std::vector aggregations_; + std::vector group_by_; +}; + } // namespace plan } // namespace query