Exemplo n.º 1
0
        /// <summary>
        /// Evaluates a list of expressions that are pattern searches (eg. LIKE, 
        /// NOT LIKE and REGEXP).
        /// </summary>
        /// <param name="patternExprs"></param>
        /// <param name="evaluateOrder"></param>
        /// <remarks>
        /// The LHS or RHS may be complex expressions with variables, but we are 
        /// guarenteed that there are no sub-expressions in the expression.
        /// </remarks>
        private void EvaluatePatterns(IEnumerable<Expression> patternExprs, IList<ExpressionPlan> evaluateOrder)
        {
            // Split the patterns into simple and complex plans.  A complex plan
            // may require that a join occurs.
            foreach (Expression expr in patternExprs) {
                var binary = (BinaryExpression) expr;
                Expression[] exps = {binary.Left, binary.Right};

                // If the LHS is a single variable and the RHS is a constant then
                // the conditions are right for a simple pattern search.
                ObjectName lhsVar = exps[0].AsVariable();
                if (expr.IsConstant()) {
                    ExpressionPlan exprPlan = new ConstantExpressionPlan(this, expr);
                    exprPlan.OptimizableValue = 0f;
                    evaluateOrder.Add(exprPlan);
                } else if (lhsVar != null && exps[1].IsConstant()) {
                    ExpressionPlan exprPlan = new SimplePatternExpressionPlan(this, lhsVar, expr);
                    exprPlan.OptimizableValue = 0.25f;
                    evaluateOrder.Add(exprPlan);
                } else {
                    // Otherwise we must assume a complex pattern search which may
                    // require a join.  For example, 'a + b LIKE 'a%'' or
                    // 'a LIKE b'.  At the very least, this will be an exhaustive
                    // search and at the worst it will be a join + exhaustive search.
                    // So we should evaluate these at the end of the evaluation order.
                    ExpressionPlan exprPlan = new ExhaustiveSelectExpressionPlan(this, expr);
                    exprPlan.OptimizableValue = 0.82f;
                    evaluateOrder.Add(exprPlan);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Evaluates a list of expressions containing sub-queries.
        /// </summary>
        /// <param name="expressions"></param>
        /// <param name="evaluateOrder"></param>
        /// <remarks>
        /// Non-correlated sub-queries can often be optimized in to fast 
        /// searches.  Correlated queries, or expressions containing multiple 
        /// sub-queries are write through the <see cref="ExhaustiveSelectExpressionPlan"/>.
        /// </remarks>
        private void EvaluateSubQueries(IEnumerable<Expression> expressions, IList<ExpressionPlan> evaluateOrder)
        {
            // For each sub-command expression
            foreach (Expression andexp in expressions) {
                var binary = (BinaryExpression) andexp;

                bool isExhaustive;

                // Is this an easy sub-command?
                Operator op = binary.Operator;
                if (!op.IsSubQuery()) {
                    // Must be an exhaustive sub-command
                    isExhaustive = true;
                } else {
                    // Split the expression.
                    Expression[] exps ={binary.Left, binary.Right};
                    // Check that the left is a simple enough variable reference
                    ObjectName leftVar = exps[0].AsVariable();
                    if (leftVar == null)
                        isExhaustive = true;
                    else {
                        // Check that the right is a sub-command plan.
                        IQueryPlanNode rightPlan = exps[1].AsQueryPlanNode();
                        if (rightPlan == null)
                            isExhaustive = true;
                        else {
                            // Finally, check if the plan is correlated or not
                            IList<CorrelatedVariable> cv = rightPlan.DiscoverCorrelatedVariables(1, new List<CorrelatedVariable>());
                            isExhaustive = cv.Count != 0;
                        }
                    }
                }

                // If this is an exhaustive operation,
                if (isExhaustive) {
                    // This expression could involve multiple variables, so we may need
                    // to join.
                    IList<ObjectName> allVars = andexp.AllVariables().ToList();

                    // Also find all correlated variables.
                    int level = 0;
                    IList<CorrelatedVariable> allCorrelated = andexp.DiscoverCorrelatedVariables(ref level, new List<CorrelatedVariable>());
                    int sz = allCorrelated.Count;

                    // If there are no variables (and no correlated variables) then this
                    // must be a constant select, For example, 3 in ( select ... )
                    if (allVars.Count == 0 && sz == 0) {
                        ExpressionPlan exprPlan = new ConstantExpressionPlan(this, andexp);
                        exprPlan.OptimizableValue = 0f;
                        evaluateOrder.Add(exprPlan);
                    } else {
                        foreach (CorrelatedVariable cv in allCorrelated)
                            allVars.Add(cv.Variable);

                        // An exhaustive expression plan which might require a join or a
                        // slow correlated search.  This should be evaluated after the
                        // multiple variables are processed.
                        ExpressionPlan expPlan = new ExhaustiveSubQueryExpressionPlan(this, allVars, andexp);
                        expPlan.OptimizableValue = 0.85f;
                        evaluateOrder.Add(expPlan);
                    }

                } else {
                    // This is a simple sub-command expression plan with a single LHS
                    // variable and a single RHS sub-command.
                    ExpressionPlan expPlan = new SimpleSubQueryExpressionPlan(this, andexp);
                    expPlan.OptimizableValue = 0.3f;
                    evaluateOrder.Add(expPlan);

                }

            } // For each 'and' expression
        }
Exemplo n.º 3
0
 // ----
 // An expression plan for a constant expression.  These are very
 // optimizable indeed.
 /// <summary>
 /// Evaluates a list of constant conditional exressions of 
 /// the form <c>3 + 2 = 0</c>, <c>true = true</c>, etc.
 /// </summary>
 /// <param name="constantVars"></param>
 /// <param name="evaluateOrder"></param>
 private void EvaluateConstants(IEnumerable<Expression> constantVars, IList<ExpressionPlan> evaluateOrder)
 {
     // For each constant variable
     foreach (Expression expr in constantVars) {
         // Add the exression plan
         ExpressionPlan expPlan = new ConstantExpressionPlan(this, expr);
         expPlan.OptimizableValue = 0f;
         evaluateOrder.Add(expPlan);
     }
 }