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