/// <summary> /// Parses a group by expression. /// Group by expression consists only of expressions separated by comma. /// GroupBy -> GROUP BY GroupByTerm (, GroupByTerm)* /// GroupByTerm -> Expression /// </summary> /// <returns> A tree representation of a group by or null if the tokens are missing group token on its first position. </returns> static public GroupByNode ParseGroupBy(ref int position, List <Token> tokens) { GroupByNode groupByNode = new GroupByNode(); // We expect after reading match expr that the position is set on the Group token. // GROUP if (!CheckToken(position, Token.TokenType.Group, tokens)) { return(null); } else { position++; // BY if (!CheckToken(position, Token.TokenType.By, tokens)) { ThrowError("Group by parser", "Expected BY token.", position, tokens); } else { position++; } Node node = ParseGroupByTerm(ref position, tokens); if (node == null) { ThrowError("Group by parser", "Failed to parse group by expresion. Expected group by term.", position, tokens); } groupByNode.AddNext(node); return(groupByNode); } }
/// <summary> /// A root node of the parse tree. /// Jumps to thxe node under the root. /// There must be always at least one result. /// </summary> public void Visit(GroupByNode node) { node.next.Accept(this); if (this.holders.Count == 0) { throw new ArgumentException($"{this.GetType()}, the final results is empty or null."); } }
public void Visit(GroupByNode node) { throw new NotImplementedException(); }
/// <summary> /// Parses Group by parse tree, the information is stored in the expression info class. /// The reason this method is separated from constructor is because it cannot guess whether the /// clause is a normal group by or a single group group by, thus the group by must always be parsed /// as the first clause after the Match clause. /// </summary> public static void ParseGroupBy(Graph graph, VariableMap variableMap, IGroupByExecutionHelper executionHelper, GroupByNode groupByNode, QueryExpressionInfo exprInfo) { if (executionHelper == null || groupByNode == null || variableMap == null || graph == null || exprInfo == null) { throw new ArgumentNullException($"Group by results processor, passing null arguments to the constructor."); } var groupbyVisitor = new GroupByVisitor(graph.labels, variableMap, exprInfo); groupbyVisitor.Visit(groupByNode); executionHelper.IsSetGroupBy = true; }
/// <summary> /// Creates a group by object for multigroup group by (defined group by clause). /// </summary> /// <param name="graph"> A property graph. </param> /// <param name="variableMap"> A variable map. </param> /// <param name="executionHelper"> A group by execution helper. </param> /// <param name="groupByNode"> A parsed tree of group by expression. </param> /// <param name="exprInfo"> A query expression information. </param> public GroupByObject(Graph graph, VariableMap variableMap, IGroupByExecutionHelper executionHelper, GroupByNode groupByNode, QueryExpressionInfo exprInfo) { if (executionHelper == null || groupByNode == null || variableMap == null || graph == null || exprInfo == null) { throw new ArgumentNullException($"{this.GetType()}, passing null arguments to the constructor."); } this.helper = executionHelper; var groupbyVisitor = new GroupByVisitor(graph.labels, variableMap, exprInfo); groupbyVisitor.Visit(groupByNode); this.hashes = groupbyVisitor.GetResult().ToArray(); this.aggregates = exprInfo.Aggregates; this.helper.IsSetGroupBy = true; }