예제 #1
0
 /// <summary>
 /// Factory method.
 /// </summary>
 /// <param name="type"> A type of the clause to build. </param>
 /// <param name="graph"> A graph to conduct computation on. </param>
 /// <param name="helper"> A helper that contains information about execution. </param>
 /// <param name="map"> A map of variables. </param>
 /// <param name="parseTree"> A parsed tree to create the clause from. </param>
 /// <param name="exprInfo"> A query expression information. </param>
 public static QueryObject Factory(Type type, Graph graph, QueryExecutionHelper helper, VariableMap map, Node parseTree, QueryExpressionInfo exprInfo)
 {
     if (type == typeof(SelectObject))
     {
         return(new SelectObject(graph, map, helper, (SelectNode)parseTree, exprInfo));
     }
     else if (type == typeof(MatchObject))
     {
         return(new MatchObject(graph, map, helper, (MatchNode)parseTree, exprInfo));
     }
     else if (type == typeof(MatchObjectStreamed))
     {
         return(new MatchObjectStreamed(graph, map, helper, (MatchNode)parseTree, exprInfo));
     }
     else if (type == typeof(OrderByObject))
     {
         return(new OrderByObject(graph, map, helper, (OrderByNode)parseTree, exprInfo));
     }
     else if (type == typeof(GroupByObject) && graph == null && map == null && parseTree == null)
     {
         return(new GroupByObject(helper, exprInfo));
     }
     else if (type == typeof(GroupByObject))
     {
         return(new GroupByObject(graph, map, helper, (GroupByNode)parseTree, exprInfo));
     }
     else
     {
         throw new ArgumentException($"Query object factory, cannot create type {type}.");
     }
 }
예제 #2
0
        /// <summary>
        /// Builds a streamed version of a query from an input.
        /// Cannot contain order by and group by simultaneously.
        /// Called by static create method.
        /// </summary>
        /// <param name="tokens"> An input query.</param>
        /// <param name="graph"> A graph to compute the query on.</param>
        /// <param name="threadCount"> Maximum number of threads available to use.</param>
        /// <param name="printer"> A printer to use. </param>
        /// <param name="formater"> A formater to use by printer. </param>
        /// <param name="verticesPerThread"> A number of vertices distributed to threads during parallel computation of the query.</param>
        /// <param name="fileName">  A file to store results into if set, otherwise null. </param>
        /// <param name="isStreamed"> A flag to distinguish a normal construtor from streamed constructor.</param>
        /// <param name="allowPrint"> Whether to allow printing. Mainly for benchmarking purposes.</param>
        /// <param name="fixedArraySize"> The size of the arrays used for storing results of the matcher.</param>
        /// <param name="grouperAlias"> A grouper to use when specifying group by.</param>
        /// <param name="sorterAlias"> A sorter to use when specifying order by.</param>
        private Query(List <Token> tokens, Graph graph, bool allowPrint, int threadCount, PrinterType printer, FormaterType formater, int verticesPerThread, string fileName, GrouperAlias grouperAlias, SorterAlias sorterAlias, int fixedArraySize, bool isStreamed)
        {
            this.graph       = graph;
            this.variableMap = new VariableMap();
            this.qEhelper    = new QueryExecutionHelper(threadCount, printer, formater, verticesPerThread, fixedArraySize, fileName, "DFSParallelStreamed", "DFSSingleThreadStreamed", "SIMPLE", grouperAlias, sorterAlias);

            // Parse input query.
            var parsedClauses = Parser.Parse(tokens);

            if (parsedClauses.ContainsKey(Parser.Clause.OrderBy) && parsedClauses.ContainsKey(Parser.Clause.GroupBy))
            {
                throw new ArgumentException($"{this.GetType()}, the streamed version of the query cannot contain group by and order by at the same time.");
            }

            // MATCH is always leaf.
            MatchObjectStreamed match = (MatchObjectStreamed)QueryObject.Factory
                                            (typeof(MatchObjectStreamed), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Match], null);

            // GROUP BY and obtain the aggregates and hashes -> the all necessary info is in the expressionInfo class.
            if (parsedClauses.ContainsKey(Parser.Clause.GroupBy))
            {
                this.exprInfo = new QueryExpressionInfo(true);
                GroupByResultProcessor.ParseGroupBy(graph, variableMap, qEhelper, (GroupByNode)parsedClauses[Parser.Clause.GroupBy], exprInfo);
            }
            else
            {
                this.exprInfo = new QueryExpressionInfo(false);
            }

            // SELECT is the last one to process the resuls.
            this.query = QueryObject.Factory
                             (typeof(SelectObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Select], exprInfo);
            ((SelectObject)this.query).allowPrint = allowPrint;

            SetSingleGroupFlags();

            // ORDER BY
            if (parsedClauses.ContainsKey(Parser.Clause.OrderBy))
            {
                var comps       = OrderByResultProcessor.ParseOrderBy(graph, variableMap, qEhelper, (OrderByNode)parsedClauses[Parser.Clause.OrderBy], exprInfo, variableMap.GetCount());
                var orderByProc = OrderByResultProcessor.Factory(this.exprInfo, comps, qEhelper, variableMap.GetCount(), this.exprInfo.CollectUsedVariables());
                match.PassResultProcessor(orderByProc);
            }
            else
            {
                // Check if the query is aggregation and not a simple query.
                if ((this.exprInfo.Aggregates.Count == 0 && this.qEhelper.IsSetSingleGroupGroupBy) || (!this.qEhelper.IsSetSingleGroupGroupBy && !parsedClauses.ContainsKey(Parser.Clause.GroupBy)))
                {
                    throw new ArgumentException($"{this.GetType()}, no grouping or sorting was specified. The Streamed version allows to compute only aggregations. If you want to use only patter matching, please change to mode Normal.");
                }
                var groupByProc = GroupByResultProcessor.Factory(exprInfo, qEhelper, variableMap.GetCount(), this.exprInfo.CollectUsedVariables(), isStreamed);

                match.PassResultProcessor(groupByProc);
            }
            query.AddToEnd(match);
        }
예제 #3
0
        /// <summary>
        /// Builds a query from an input.
        /// Cannot contain order by and group by simultaneously.
        /// Called by static Create method.
        /// </summary>
        /// <param name="tokens"> An input query. </param>
        /// <param name="graph"> A graph to compute the query on. </param>
        /// <param name="threadCount"> Maximum number of threads available to use. </param>
        /// <param name="printer"> A printer to use. </param>
        /// <param name="formater"> A formater to use by printer. </param>
        /// <param name="verticesPerThread"> A number of vertices distributed to threads during parallel computation of the query.</param>
        /// <param name="fileName"> A file to store results into if set, otherwise null. </param>
        /// <param name="allowPrint"> Whether to allow printing. Mainly for benchmarking purposes.</param>
        /// <param name="fixedArraySize"> The size of the arrays used for storing results of the matcher.</param>
        /// <param name="grouperAlias"> A grouper to use when specifying group by.</param>
        /// <param name="sorterAlias"> A sorter to use when specifying order by.</param>
        private Query(List <Token> tokens, Graph graph, bool allowPrint, int threadCount, PrinterType printer, FormaterType formater, int verticesPerThread, string fileName, GrouperAlias grouperAlias, SorterAlias sorterAlias, int fixedArraySize)
        {
            this.graph       = graph;
            this.variableMap = new VariableMap();
            this.qEhelper    = new QueryExecutionHelper(threadCount, printer, formater, verticesPerThread, fixedArraySize, fileName, "DFSParallel", "DFSSingleThread", "SIMPLE", grouperAlias, sorterAlias);

            // Parse input query.
            var parsedClauses = Parser.Parse(tokens);

            // Create execution chain.
            if (parsedClauses.ContainsKey(Parser.Clause.GroupBy) && parsedClauses.ContainsKey(Parser.Clause.OrderBy))
            {
                throw new ArgumentException($"{this.GetType()}, the query cannot contain both order by and group by");
            }
            QueryObject groupBy = null;
            QueryObject orderBy = null;

            // MATCH is always leaf.
            QueryObject match = QueryObject.Factory
                                    (typeof(MatchObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Match], null);

            // Second must be group by because it defines what can be in other clauses.
            // GROUP BY
            if (parsedClauses.ContainsKey(Parser.Clause.GroupBy))
            {
                this.exprInfo = new QueryExpressionInfo(true);
                groupBy       = QueryObject.Factory(typeof(GroupByObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.GroupBy], exprInfo);
            }
            else
            {
                this.exprInfo = new QueryExpressionInfo(false);
            }

            // SELECT is the last one to process the resuls.
            this.query = QueryObject.Factory
                             (typeof(SelectObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.Select], exprInfo);
            ((SelectObject)this.query).allowPrint = allowPrint;

            // Check if the results are in a single group.
            this.SetSingleGroupFlags();

            // ORDER BY
            if (parsedClauses.ContainsKey(Parser.Clause.OrderBy))
            {
                orderBy = QueryObject.Factory(typeof(OrderByObject), graph, qEhelper, variableMap, parsedClauses[Parser.Clause.OrderBy], exprInfo);
                query.AddToEnd(orderBy);
            }

            // If the single group by is set, add GroupBy object to the execution chain.
            if (this.qEhelper.IsSetSingleGroupGroupBy && !this.qEhelper.IsSetGroupBy)
            {
                groupBy = QueryObject.Factory(typeof(GroupByObject), null, qEhelper, null, null, exprInfo);
            }

            if (groupBy != null)
            {
                query.AddToEnd(groupBy);
            }
            query.AddToEnd(match);
            query.PassStoringVariables(this.exprInfo.CollectUsedVariables());
        }