Deveel.Data.Sql.Query.QueryTablePlanner.PlanExpressionList C# (CSharp) Method

PlanExpressionList() private method

private PlanExpressionList ( IEnumerable expressions ) : void
expressions IEnumerable
return void
        private void PlanExpressionList(IEnumerable<SqlExpression> expressions)
        {
            var subLogicExpressions = new List<SqlBinaryExpression>();
            // The list of expressions that have a sub-select in them.
            var subQueryExpressions = new List<SqlBinaryExpression>();
            // The list of all constant expressions ( true = true )
            var constants = new List<SqlExpression>();
            // The list of pattern matching expressions (eg. 't LIKE 'a%')
            var patternExpressions = new List<SqlBinaryExpression>();
            // The list of all expressions that are a single variable on one
            // side, a conditional operator, and a constant on the other side.
            var singleVars = new List<SqlBinaryExpression>();
            // The list of multi variable expressions (possible joins)
            var multiVars = new List<SqlBinaryExpression>();

            foreach (var expression in expressions) {
                SqlBinaryExpression exp;

                if (!(expression is SqlBinaryExpression)) {
                    // If this is not a binary expression we imply
                    // [expression] = 'true'
                    exp = SqlExpression.Equal(expression, SqlExpression.Constant(true));
                } else {
                    exp = (SqlBinaryExpression) expression;
                }

                if (exp.ExpressionType.IsLogical()) {
                    subLogicExpressions.Add(exp);
                } else if (exp.HasSubQuery()) {
                    subQueryExpressions.Add(exp);
                } else if (exp.ExpressionType.IsPattern()) {
                    patternExpressions.Add(exp);
                } else {
                    // The list of variables in the expression.
                    var columnNames = exp.DiscoverReferences().ToList();
                    if (columnNames.Count == 0) {
                        // These are ( 54 + 9 = 9 ), ( "z" > "a" ), ( 9.01 - 2 ), etc
                        constants.Add(exp);
                    } else if (columnNames.Count == 1) {
                        // These are ( id = 90 ), ( 'a' < number ), etc
                        singleVars.Add(exp);
                    } else if (columnNames.Count > 1) {
                        // These are ( id = part_id ),
                        // ( cost_of + value_of < sold_at ), ( id = part_id - 10 )
                        multiVars.Add(exp);
                    } else {
                        throw new InvalidOperationException("Invalid number of column names");
                    }
                }
            }

            // The order in which expression are evaluated,
            // (ExpressionPlan)
            var evaluateOrder = new List<ExpressionPlan>();

            // Evaluate the constants.  These should always be evaluated first
            // because they always evaluate to either true or false or null.
            EvaluateConstants(constants, evaluateOrder);

            // Evaluate the singles.  If formed well these can be evaluated
            // using fast indices.  eg. (a > 9 - 3) is more optimal than
            // (a + 3 > 9).
            EvaluateSingles(singleVars, evaluateOrder);

            // Evaluate the pattern operators.  Note that some patterns can be
            // optimized better than others, but currently we keep this near the
            // middle of our evaluation sequence.
            EvaluatePatterns(patternExpressions, evaluateOrder);

            // Evaluate the sub-queries.  These are queries of the form,
            // (a IN ( SELECT ... )), (a = ( SELECT ... ) = ( SELECT ... )), etc.
            EvaluateSubQueries(subQueryExpressions, evaluateOrder);

            // Evaluate multiple variable expressions.  It's possible these are
            // joins.
            EvaluateMultiples(multiVars, evaluateOrder);

            // Lastly evaluate the sub-logic expressions.  These expressions are
            // OR type expressions.
            EvaluateSubLogic(subLogicExpressions, evaluateOrder);

            evaluateOrder.Sort();

            // And add each expression to the plan
            foreach (ExpressionPlan plan in evaluateOrder) {
                plan.AddToPlanTree();
            }
        }