internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { c.Expression = this.VisitExpression(c.Expression); for (int i = 0, n = c.Whens.Count; i < n; i++) { // Don't walk down the match side. This can't be a column. c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value); } return c; }
internal bool AreCaseWhenValuesConstant(SqlSimpleCase sc) { foreach(SqlWhen when in sc.Whens) { if(when.Value.NodeType != SqlNodeType.Value) { return false; } } return true; }
/// <summary> /// Helper for VisitBinaryOperator. Builds the new case with distributed valueds. /// </summary> private SqlExpression DistributeOperatorIntoCase(SqlNodeType nt, SqlSimpleCase sc, SqlExpression expr) { if(nt != SqlNodeType.EQ && nt != SqlNodeType.NE && nt != SqlNodeType.EQ2V && nt != SqlNodeType.NE2V) throw Error.ArgumentOutOfRange("nt"); object val = Eval(expr); List<SqlExpression> values = new List<SqlExpression>(); List<SqlExpression> matches = new List<SqlExpression>(); foreach(SqlWhen when in sc.Whens) { matches.Add(when.Match); object whenVal = Eval(when.Value); bool eq = when.Value.SqlType.AreValuesEqual(whenVal, val); values.Add(_sql.ValueFromObject((nt == SqlNodeType.EQ || nt == SqlNodeType.EQ2V) == eq, false, sc.SourceExpression)); } return this.VisitExpression(_sql.Case(typeof(bool), sc.Expression, matches, values, sc.SourceExpression)); }
internal virtual SqlExpression VisitSimpleCase(SqlSimpleCase c) { c.Expression = this.VisitExpression(c.Expression); for (int i = 0, n = c.Whens.Count; i < n; i++) { SqlWhen when = c.Whens[i]; when.Match = this.VisitExpression(when.Match); when.Value = this.VisitExpression(when.Value); } return c; }
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { _depth++; this.NewLine(); _commandStringBuilder.Append("(CASE"); _depth++; if(c.Expression != null) { _commandStringBuilder.Append(" "); this.Visit(c.Expression); } for(int i = 0, n = c.Whens.Count; i < n; i++) { SqlWhen when = c.Whens[i]; if(i == n - 1 && when.Match == null) { this.NewLine(); _commandStringBuilder.Append("ELSE "); this.Visit(when.Value); } else { this.NewLine(); _commandStringBuilder.Append("WHEN "); this.Visit(when.Match); _commandStringBuilder.Append(" THEN "); this.Visit(when.Value); } } _depth--; this.NewLine(); _commandStringBuilder.Append(" END)"); _depth--; return c; }
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { SqlExpression expr = this.VisitExpression(c.Expression); SqlWhen[] whens = new SqlWhen[c.Whens.Count]; for(int i = 0, n = whens.Length; i < n; i++) { SqlWhen when = c.Whens[i]; whens[i] = new SqlWhen(this.VisitExpression(when.Match), this.VisitExpression(when.Value)); } return new SqlSimpleCase(c.ClrType, expr, whens, c.SourceExpression); }
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; }
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { base.VisitSimpleCase(c); // determine the best common type for all the when values ProviderType type = c.Whens[0].Value.SqlType; for(int i = 1; i < c.Whens.Count; i++) { ProviderType whenType = c.Whens[i].Value.SqlType; type = typeProvider.GetBestType(type, whenType); } // coerce each one foreach(SqlWhen when in c.Whens.Where(w => w.Value.SqlType != type && !w.Value.SqlType.IsRuntimeOnlyType)) { when.Value = sql.UnaryConvert(when.Value.ClrType, type, when.Value, when.Value.SourceExpression); } return c; }
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 override SqlExpression VisitSimpleCase(SqlSimpleCase c) { bool saveCanJoin = this.canJoin; this.canJoin = false; try { return base.VisitSimpleCase(c); } finally { this.canJoin = saveCanJoin; } }