Пример #1
0
        private static IQueryPlanNode PlanGroup(IQueryPlanNode node,
                                                QuerySelectColumnSet columnSet,
                                                ObjectName groupmaxColumn,
                                                int gsz,
                                                ObjectName[] groupByList,
                                                IList <Expression> groupByFunctions,
                                                int fsz,
                                                string[] defFunNames,
                                                Expression[] defFunList)
        {
            // If there is more than 1 aggregate function or there is a group by
            // clause, then we must add a grouping plan.
            if (columnSet.AggregateCount > 0 || gsz > 0)
            {
                // If there is no GROUP BY clause then assume the entire result is the
                // group.
                if (gsz == 0)
                {
                    node = new GroupNode(node, groupmaxColumn, defFunList, defFunNames);
                }
                else
                {
                    // Do we have any group by functions that need to be planned first?
                    int gfsz = groupByFunctions.Count;
                    if (gfsz > 0)
                    {
                        var groupFunList = new Expression[gfsz];
                        var groupFunName = new String[gfsz];
                        for (int i = 0; i < gfsz; ++i)
                        {
                            groupFunList[i] = groupByFunctions[i];
                            groupFunName[i] = "#GROUPBY-" + i;
                        }
                        node = new CreateFunctionsNode(node, groupFunList, groupFunName);
                    }

                    // Otherwise we provide the 'group_by_list' argument
                    node = new GroupNode(node, groupByList, groupmaxColumn, defFunList, defFunNames);
                }
            }
            else
            {
                // Otherwise no grouping is occuring.  We simply need create a function
                // node with any functions defined in the SELECT.
                // Plan a FunctionsNode with the functions defined in the SELECT.
                if (fsz > 0)
                {
                    node = new CreateFunctionsNode(node, defFunList, defFunNames);
                }
            }

            return(node);
        }
Пример #2
0
        /// <summary>
        /// Plans an ORDER BY set.
        /// </summary>
        /// <param name="plan"></param>
        /// <param name="orderBy"></param>
        /// <param name="fromSet"></param>
        /// <param name="selectedColumns"></param>
        /// <remarks>
        /// This is given its own function because we may want to plan
        /// this at the end of a number of composite functions.
        /// </remarks>
        /// <returns></returns>
        private static IQueryPlanNode PlanForOrderBy(IQueryPlanNode plan, IList <ByColumn> orderBy, TableExpressionFromSet fromSet, IList <SelectColumn> selectedColumns)
        {
            var functionTable = new ObjectName("FUNCTIONTABLE");

            // Sort on the ORDER BY clause
            if (orderBy.Count > 0)
            {
                int sz            = orderBy.Count;
                var orderList     = new ObjectName[sz];
                var ascendingList = new bool[sz];

                var functionOrders = new List <Expression>();

                for (int i = 0; i < sz; ++i)
                {
                    ByColumn   column = orderBy[i];
                    Expression exp    = column.Expression;
                    ascendingList[i] = column.Ascending;
                    ObjectName v = exp.AsVariable();
                    if (v != null)
                    {
                        ObjectName newV = fromSet.ResolveReference(v);
                        if (newV == null)
                        {
                            throw new ApplicationException("Can not resolve ORDER BY variable: " + v);
                        }

                        newV         = SubstituteAliasedVariable(newV, selectedColumns);
                        orderList[i] = newV;
                    }
                    else
                    {
                        // Otherwise we must be ordering by an expression such as
                        // '0 - a'.

                        // Resolve the expression,
                        exp = exp.Prepare(fromSet.ExpressionQualifier);

                        // Make sure we substitute any aliased columns in the order by
                        // columns.
                        exp = SubstituteAliasedVariables(exp, selectedColumns);

                        // The new ordering functions are called 'FUNCTIONTABLE.#ORDER-n'
                        // where n is the number of the ordering expression.
                        orderList[i] = new ObjectName(functionTable, "#ORDER-" + functionOrders.Count);
                        functionOrders.Add(exp);
                    }
                }

                // If there are functional orderings,
                // For this we must define a new FunctionTable with the expressions,
                // then order by those columns, and then use another SubsetNode
                // command node.
                int fsz = functionOrders.Count;
                if (fsz > 0)
                {
                    var funs   = new Expression[fsz];
                    var fnames = new String[fsz];
                    for (int n = 0; n < fsz; ++n)
                    {
                        funs[n]   = functionOrders[n];
                        fnames[n] = "#ORDER-" + n;
                    }

                    if (plan is SubsetNode)
                    {
                        // If the top plan is a QueryPlan.SubsetNode then we use the
                        //   information from it to create a new SubsetNode that
                        //   doesn't include the functional orders we have attached here.
                        var          topSubsetNode = (SubsetNode)plan;
                        ObjectName[] mappedNames   = topSubsetNode.NewColumnNames;

                        // Defines the sort functions
                        plan = new CreateFunctionsNode(plan, funs, fnames);
                        // Then plan the sort
                        plan = new SortNode(plan, orderList, ascendingList);
                        // Then plan the subset
                        plan = new SubsetNode(plan, mappedNames, mappedNames);
                    }
                    else
                    {
                        // Defines the sort functions
                        plan = new CreateFunctionsNode(plan, funs, fnames);
                        // Plan the sort
                        plan = new SortNode(plan, orderList, ascendingList);
                    }
                }
                else
                {
                    // No functional orders so we only need to sort by the columns
                    // defined.
                    plan = new SortNode(plan, orderList, ascendingList);
                }
            }

            return(plan);
        }
Пример #3
0
        private static IQueryPlanNode PlanGroup(IQueryPlanNode node,
			QuerySelectColumnSet columnSet,
			ObjectName groupmaxColumn,
			int gsz,
			ObjectName[] groupByList,
			IList<Expression> groupByFunctions,
			int fsz,
			string[] defFunNames,
			Expression[] defFunList)
        {
            // If there is more than 1 aggregate function or there is a group by
            // clause, then we must add a grouping plan.
            if (columnSet.AggregateCount > 0 || gsz > 0) {
                // If there is no GROUP BY clause then assume the entire result is the
                // group.
                if (gsz == 0) {
                    node = new GroupNode(node, groupmaxColumn, defFunList, defFunNames);
                } else {
                    // Do we have any group by functions that need to be planned first?
                    int gfsz = groupByFunctions.Count;
                    if (gfsz > 0) {
                        var groupFunList = new Expression[gfsz];
                        var groupFunName = new String[gfsz];
                        for (int i = 0; i < gfsz; ++i) {
                            groupFunList[i] = groupByFunctions[i];
                            groupFunName[i] = "#GROUPBY-" + i;
                        }
                        node = new CreateFunctionsNode(node, groupFunList, groupFunName);
                    }

                    // Otherwise we provide the 'group_by_list' argument
                    node = new GroupNode(node, groupByList, groupmaxColumn, defFunList, defFunNames);
                }
            } else {
                // Otherwise no grouping is occuring.  We simply need create a function
                // node with any functions defined in the SELECT.
                // Plan a FunctionsNode with the functions defined in the SELECT.
                if (fsz > 0)
                    node = new CreateFunctionsNode(node, defFunList, defFunNames);
            }

            return node;
        }
Пример #4
0
        /// <summary>
        /// Plans an ORDER BY set.
        /// </summary>
        /// <param name="plan"></param>
        /// <param name="orderBy"></param>
        /// <param name="fromSet"></param>
        /// <param name="selectedColumns"></param>
        /// <remarks>
        /// This is given its own function because we may want to plan 
        /// this at the end of a number of composite functions.
        /// </remarks>
        /// <returns></returns>
        private static IQueryPlanNode PlanForOrderBy(IQueryPlanNode plan, IList<ByColumn> orderBy, TableExpressionFromSet fromSet, IList<SelectColumn> selectedColumns)
        {
            var functionTable = new ObjectName("FUNCTIONTABLE");

            // Sort on the ORDER BY clause
            if (orderBy.Count > 0) {
                int sz = orderBy.Count;
                var orderList = new ObjectName[sz];
                var ascendingList = new bool[sz];

                var functionOrders = new List<Expression>();

                for (int i = 0; i < sz; ++i) {
                    ByColumn column = orderBy[i];
                    Expression exp = column.Expression;
                    ascendingList[i] = column.Ascending;
                    ObjectName v = exp.AsVariable();
                    if (v != null) {
                        ObjectName newV = fromSet.ResolveReference(v);
                        if (newV == null)
                            throw new ApplicationException("Can not resolve ORDER BY variable: " + v);

                        newV = SubstituteAliasedVariable(newV, selectedColumns);
                        orderList[i] = newV;
                    } else {
                        // Otherwise we must be ordering by an expression such as
                        // '0 - a'.

                        // Resolve the expression,
                        exp = exp.Prepare(fromSet.ExpressionQualifier);

                        // Make sure we substitute any aliased columns in the order by
                        // columns.
                        exp = SubstituteAliasedVariables(exp, selectedColumns);

                        // The new ordering functions are called 'FUNCTIONTABLE.#ORDER-n'
                        // where n is the number of the ordering expression.
                        orderList[i] = new ObjectName(functionTable, "#ORDER-" + functionOrders.Count);
                        functionOrders.Add(exp);
                    }
                }

                // If there are functional orderings,
                // For this we must define a new FunctionTable with the expressions,
                // then order by those columns, and then use another SubsetNode
                // command node.
                int fsz = functionOrders.Count;
                if (fsz > 0) {
                    var funs = new Expression[fsz];
                    var fnames = new String[fsz];
                    for (int n = 0; n < fsz; ++n) {
                        funs[n] = functionOrders[n];
                        fnames[n] = "#ORDER-" + n;
                    }

                    if (plan is SubsetNode) {
                        // If the top plan is a QueryPlan.SubsetNode then we use the
                        //   information from it to create a new SubsetNode that
                        //   doesn't include the functional orders we have attached here.
                        var topSubsetNode = (SubsetNode)plan;
                        ObjectName[] mappedNames = topSubsetNode.NewColumnNames;

                        // Defines the sort functions
                        plan = new CreateFunctionsNode(plan, funs, fnames);
                        // Then plan the sort
                        plan = new SortNode(plan, orderList, ascendingList);
                        // Then plan the subset
                        plan = new SubsetNode(plan, mappedNames, mappedNames);
                    } else {
                        // Defines the sort functions
                        plan = new CreateFunctionsNode(plan, funs, fnames);
                        // Plan the sort
                        plan = new SortNode(plan, orderList, ascendingList);
                    }

                } else {
                    // No functional orders so we only need to sort by the columns
                    // defined.
                    plan = new SortNode(plan, orderList, ascendingList);
                }
            }

            return plan;
        }