예제 #1
0
 private SqlColumn FindColumnWithExpression(IEnumerable <SqlColumn> columns, SqlExpression expr)
 {
     foreach (SqlColumn c in columns)
     {
         if (c == expr)
         {
             return(c);
         }
         if (SqlComparer.AreEqual(c.Expression, expr))
         {
             return(c);
         }
     }
     return(null);
 }
예제 #2
0
            internal override SqlSelect VisitSelect(SqlSelect select)
            {
                select.From  = this.VisitSource(select.From);
                select.Where = this.VisitExpression(select.Where);
                for (int i = 0, n = select.GroupBy.Count; i < n; i++)
                {
                    select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]);
                }
                // remove duplicate group expressions
                for (int i = select.GroupBy.Count - 1; i >= 0; i--)
                {
                    for (int j = i - 1; j >= 0; j--)
                    {
                        if (SqlComparer.AreEqual(select.GroupBy[i], select.GroupBy[j]))
                        {
                            select.GroupBy.RemoveAt(i);
                            break;
                        }
                    }
                }
                select.Having = this.VisitExpression(select.Having);
                for (int i = 0, n = select.OrderBy.Count; i < n; i++)
                {
                    select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression);
                }
                // remove duplicate order expressions
                if (select.OrderBy.Count > 0)
                {
                    this.equalizer.BuildEqivalenceMap(select.From);

                    for (int i = select.OrderBy.Count - 1; i >= 0; i--)
                    {
                        for (int j = i - 1; j >= 0; j--)
                        {
                            if (this.equalizer.AreEquivalent(select.OrderBy[i].Expression, select.OrderBy[j].Expression))
                            {
                                select.OrderBy.RemoveAt(i);
                                break;
                            }
                        }
                    }
                }
                select.Top       = this.VisitExpression(select.Top);
                select.Row       = (SqlRow)this.Visit(select.Row);
                select.Selection = this.VisitExpression(select.Selection);
                return(select);
            }
예제 #3
0
        private static SqlExpression UnwrapTrivialCaseExpression(SqlSimpleCase sc)
        {
            if (sc.Whens.Count != 1)
            {
                return(sc);
            }
            if (!SqlComparer.AreEqual(sc.Expression, sc.Whens[0].Match))
            {
                return(sc);
            }
            SqlExpression result = sc.Whens[0].Value;

            if (result.NodeType == SqlNodeType.SimpleCase)
            {
                return(UnwrapTrivialCaseExpression((SqlSimpleCase)result));
            }
            return(result);
        }
예제 #4
0
            internal bool AreEquivalent(SqlExpression e1, SqlExpression e2)
            {
                if (SqlComparer.AreEqual(e1, e2))
                {
                    return(true);
                }

                SqlColumnRef cr1 = e1 as SqlColumnRef;
                SqlColumnRef cr2 = e2 as SqlColumnRef;

                if (cr1 != null && cr2 != null)
                {
                    SqlColumn c1 = cr1.GetRootColumn();
                    SqlColumn c2 = cr2.GetRootColumn();
                    SqlColumn r;
                    return(this.map.TryGetValue(c1, out r) && r == c2);
                }

                return(false);
            }
예제 #5
0
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c)
            {
                c.Expression = this.VisitExpression(c.Expression);
                int compareWhen = 0;

                // Find the ELSE if it exists.
                for (int i = 0, n = c.Whens.Count; i < n; i++)
                {
                    if (c.Whens[i].Match == null)
                    {
                        compareWhen = i;
                        break;
                    }
                }

                c.Whens[compareWhen].Match = VisitExpression(c.Whens[compareWhen].Match);
                c.Whens[compareWhen].Value = VisitExpression(c.Whens[compareWhen].Value);

                // Compare each other when value to the compare when
                List <SqlWhen> newWhens         = new List <SqlWhen>();
                bool           allValuesLiteral = true;

                for (int i = 0, n = c.Whens.Count; i < n; i++)
                {
                    if (compareWhen != i)
                    {
                        SqlWhen when = c.Whens[i];
                        when.Match = this.VisitExpression(when.Match);
                        when.Value = this.VisitExpression(when.Value);
                        if (!SqlComparer.AreEqual(c.Whens[compareWhen].Value, when.Value))
                        {
                            newWhens.Add(when);
                        }
                        allValuesLiteral = allValuesLiteral && when.Value.NodeType == SqlNodeType.Value;
                    }
                }
                newWhens.Add(c.Whens[compareWhen]);

                // Did everything reduce to a single CASE?
                SqlExpression rewrite = TryToConsolidateAllValueExpressions(newWhens.Count, c.Whens[compareWhen].Value);

                if (rewrite != null)
                {
                    return(rewrite);
                }

                // Can it be a conjuction (or disjunction) of clauses?
                rewrite = TryToWriteAsSimpleBooleanExpression(c.ClrType, c.Expression, newWhens, allValuesLiteral);
                if (rewrite != null)
                {
                    return(rewrite);
                }

                // Can any WHEN clauses be reduced to fall into the ELSE clause?
                rewrite = TryToWriteAsReducedCase(c.ClrType, c.Expression, newWhens, c.Whens[compareWhen].Match, c.Whens.Count);
                if (rewrite != null)
                {
                    return(rewrite);
                }

                return(c);
            }