Ejemplo n.º 1
0
        private void EvaluateSingles(List <SqlBinaryExpression> list, List <ExpressionPlan> plans)
        {
            // The list of simple expression plans (lhs = single)
            var simplePlanList = new List <SingleColumnPlan>();
            // The list of complex function expression plans (lhs = expression)
            var complexPlanList = new List <SingleColumnPlan>();

            foreach (var expression in list)
            {
                // The single var
                ObjectName        singleVar;
                SqlExpressionType op = expression.ExpressionType;
                SqlExpression     left = expression.Left, right = expression.Right;

                if (expression.Right is SqlQuantifiedExpression)
                {
                    singleVar = expression.Left.AsReferenceName();

                    if (singleVar != null)
                    {
                        plans.Add(new SimpleSelectPlan(this, singleVar, op, expression.Right));
                    }
                    else
                    {
                        singleVar = expression.Left.DiscoverReferences().First();
                        plans.Add(new ComplexSinglePlan(this, singleVar, expression));
                    }
                }
                else
                {
                    singleVar = expression.Left.DiscoverReferences().FirstOrDefault();
                    if (singleVar == null)
                    {
                        // Reverse the expressions and the operator
                        var tempExp = left;
                        left      = right;
                        right     = tempExp;
                        op        = op.Reverse();
                        singleVar = left.DiscoverReferences().First();
                    }

                    var tableSource = FindPlan(singleVar);

                    // Simple LHS?
                    var v = left.AsReferenceName();
                    if (v != null)
                    {
                        AddSingleColumnPlan(simplePlanList, tableSource, v, singleVar, new [] { left, right }, op);
                    }
                    else
                    {
                        // No, complex lhs
                        AddSingleColumnPlan(complexPlanList, tableSource, null, singleVar, new [] { left, right }, op);
                    }
                }
            }

            plans.AddRange(simplePlanList.Select(plan => new SimpleSinglePlan(this, plan.UniqueName, plan.Expression)).Cast <ExpressionPlan>());
            plans.AddRange(complexPlanList.Select(plan => new ComplexSinglePlan(this, plan.UniqueName, plan.Expression)).Cast <ExpressionPlan>());
        }
Ejemplo n.º 2
0
        private static IQueryPlanNode PlanForOrderBy(IQueryPlanNode plan, IList <SortColumn> orderBy, QueryExpressionFrom queryFrom, IList <SelectColumn> selectedColumns)
        {
            // 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 <SqlExpression>();

                for (int i = 0; i < sz; ++i)
                {
                    var           column = orderBy[i];
                    SqlExpression exp    = column.Expression;
                    ascendingList[i] = column.Ascending;
                    var v = exp.AsReferenceName();

                    if (v != null)
                    {
                        var newV = queryFrom.ResolveReference(v);
                        if (newV == null)
                        {
                            throw new InvalidOperationException(String.Format("Could not resolve ORDER BY column '{0}' in expression", v));
                        }

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

                        // Resolve the expression,
                        exp = exp.Prepare(queryFrom.ExpressionPreparer);

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

                        // The new ordering functions are called 'FUNCTIONTABLE.#ORDER-n'
                        // where n is the number of the ordering expression.
                        orderList[i] = new ObjectName(FunctionTableName, "#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 SqlExpression[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 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;
                        var mappedNames   = topSubsetNode.AliasColumnNames;

                        // 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);
        }