Пример #1
0
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c)
            {
                this.depth++;
                int num = 0;

                Debug.Assert(c.Whens.Count > 1);
                SqlWhen elseNode = c.Whens[c.Whens.Count - 1];
                int     count    = c.Whens.Count - 1;

                this.NewLine();
                while (num < count)
                {
                    SqlWhen when = c.Whens[num];
                    this.sb.Append("IIF(");
                    Visit(c.Expression);
                    sb.Append(" = ");
                    this.Visit(when.Match);
                    this.sb.Append(" , ");
                    this.Visit(when.Value);
                    this.sb.Append(" , ");
                    num++;
                }
                Debug.Assert(elseNode != null);
                this.Visit(elseNode.Value);

                for (int i = 0; i < count; i++)
                {
                    sb.Append(")");
                }
                this.NewLine();
                this.depth--;
                return(c);
            }
 internal bool AreCaseWhenValuesConstant(SqlSimpleCase sc) {
     foreach (SqlWhen when in sc.Whens) {
         if (when.Value.NodeType != SqlNodeType.Value) {
             return false;
         }
     }
     return true;
 }
Пример #3
0
 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;
 }
Пример #4
0
 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);
 }
Пример #5
0
 internal bool AreCaseWhenValuesConstant(SqlSimpleCase sc)
 {
     foreach (SqlWhen when in sc.Whens)
     {
         if (when.Value.NodeType != SqlNodeType.Value)
         {
             return(false);
         }
     }
     return(true);
 }
        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)
        {
            bool saveCanJoin = this.canJoin;

            this.canJoin = false;
            try
            {
                return(base.VisitSimpleCase(c));
            }
            finally
            {
                this.canJoin = saveCanJoin;
            }
        }
 /// <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));
 }
Пример #9
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);
        }
Пример #10
0
        private static SqlExpression UnwrapTrivialCaseExpression(SqlSimpleCase sc)
        {
            if (sc.Whens.Count != 1)
            {
                return(sc);
            }
            if (!AreEqual(sc.Expression, sc.Whens[0].Match))
            {
                return(sc);
            }
            SqlExpression expression = sc.Whens[0].Value;

            if (expression.NodeType == SqlNodeType.SimpleCase)
            {
                return(UnwrapTrivialCaseExpression((SqlSimpleCase)expression));
            }
            return(expression);
        }
Пример #11
0
        /// <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)));
        }
Пример #12
0
        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);
        }
Пример #13
0
 internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
     bool saveCanJoin = this.canJoin;
     this.canJoin = false;
     try {
         return base.VisitSimpleCase(c);
     }
     finally {
         this.canJoin = saveCanJoin;
     }
 }
Пример #14
0
        internal static bool AreEqual(SqlNode node1, SqlNode node2)
        {
            if (node1 == node2)
            {
                return(true);
            }
            if (node1 == null || node2 == null)
            {
                return(false);
            }

            if (node1.NodeType == SqlNodeType.SimpleCase)
            {
                node1 = UnwrapTrivialCaseExpression((SqlSimpleCase)node1);
            }

            if (node2.NodeType == SqlNodeType.SimpleCase)
            {
                node2 = UnwrapTrivialCaseExpression((SqlSimpleCase)node2);
            }

            if (node1.NodeType != node2.NodeType)
            {
                // allow expression sets to compare against single expressions
                if (node1.NodeType == SqlNodeType.ExprSet)
                {
                    SqlExprSet eset = (SqlExprSet)node1;
                    for (int i = 0, n = eset.Expressions.Count; i < n; i++)
                    {
                        if (AreEqual(eset.Expressions[i], node2))
                        {
                            return(true);
                        }
                    }
                }
                else if (node2.NodeType == SqlNodeType.ExprSet)
                {
                    SqlExprSet eset = (SqlExprSet)node2;
                    for (int i = 0, n = eset.Expressions.Count; i < n; i++)
                    {
                        if (AreEqual(node1, eset.Expressions[i]))
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
            if (node1.Equals(node2))
            {
                return(true);
            }

            switch (node1.NodeType)
            {
            case SqlNodeType.Not:
            case SqlNodeType.Not2V:
            case SqlNodeType.Negate:
            case SqlNodeType.BitNot:
            case SqlNodeType.IsNull:
            case SqlNodeType.IsNotNull:
            case SqlNodeType.Count:
            case SqlNodeType.Max:
            case SqlNodeType.Min:
            case SqlNodeType.Sum:
            case SqlNodeType.Avg:
            case SqlNodeType.Stddev:
            case SqlNodeType.ValueOf:
            case SqlNodeType.OuterJoinedValue:
            case SqlNodeType.ClrLength:
                return(AreEqual(((SqlUnary)node1).Operand, ((SqlUnary)node2).Operand));

            case SqlNodeType.Add:
            case SqlNodeType.Sub:
            case SqlNodeType.Mul:
            case SqlNodeType.Div:
            case SqlNodeType.Mod:
            case SqlNodeType.BitAnd:
            case SqlNodeType.BitOr:
            case SqlNodeType.BitXor:
            case SqlNodeType.And:
            case SqlNodeType.Or:
            case SqlNodeType.GE:
            case SqlNodeType.GT:
            case SqlNodeType.LE:
            case SqlNodeType.LT:
            case SqlNodeType.EQ:
            case SqlNodeType.NE:
            case SqlNodeType.EQ2V:
            case SqlNodeType.NE2V:
            case SqlNodeType.Concat:
                SqlBinary firstNode  = (SqlBinary)node1;
                SqlBinary secondNode = (SqlBinary)node2;
                return(AreEqual(firstNode.Left, secondNode.Left) &&
                       AreEqual(firstNode.Right, secondNode.Right));

            case SqlNodeType.Convert:
            case SqlNodeType.Treat:
            {
                SqlUnary sun1 = (SqlUnary)node1;
                SqlUnary sun2 = (SqlUnary)node2;
                return(sun1.ClrType == sun2.ClrType && sun1.SqlType == sun2.SqlType && AreEqual(sun1.Operand, sun2.Operand));
            }

            case SqlNodeType.Between:
            {
                SqlBetween b1 = (SqlBetween)node1;
                SqlBetween b2 = (SqlBetween)node1;
                return(AreEqual(b1.Expression, b2.Expression) &&
                       AreEqual(b1.Start, b2.Start) &&
                       AreEqual(b1.End, b2.End));
            }

            case SqlNodeType.Parameter:
                return(node1 == node2);

            case SqlNodeType.Alias:
                return(AreEqual(((SqlAlias)node1).Node, ((SqlAlias)node2).Node));

            case SqlNodeType.AliasRef:
                return(AreEqual(((SqlAliasRef)node1).Alias, ((SqlAliasRef)node2).Alias));

            case SqlNodeType.Column:
                SqlColumn col1 = (SqlColumn)node1;
                SqlColumn col2 = (SqlColumn)node2;
                return(col1 == col2 || (col1.Expression != null && col2.Expression != null && AreEqual(col1.Expression, col2.Expression)));

            case SqlNodeType.Table:
                return(((SqlTable)node1).MetaTable == ((SqlTable)node2).MetaTable);

            case SqlNodeType.Member:
                return((((SqlMember)node1).Member == ((SqlMember)node2).Member) &&
                       AreEqual(((SqlMember)node1).Expression, ((SqlMember)node2).Expression));

            case SqlNodeType.ColumnRef:
                SqlColumnRef cref1 = (SqlColumnRef)node1;
                SqlColumnRef cref2 = (SqlColumnRef)node2;
                return(GetBaseColumn(cref1) == GetBaseColumn(cref2));

            case SqlNodeType.Value:
                return(Object.Equals(((SqlValue)node1).Value, ((SqlValue)node2).Value));

            case SqlNodeType.TypeCase:
            {
                SqlTypeCase c1 = (SqlTypeCase)node1;
                SqlTypeCase c2 = (SqlTypeCase)node2;
                if (!AreEqual(c1.Discriminator, c2.Discriminator))
                {
                    return(false);
                }
                if (c1.Whens.Count != c2.Whens.Count)
                {
                    return(false);
                }
                for (int i = 0, c = c1.Whens.Count; i < c; ++i)
                {
                    if (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match))
                    {
                        return(false);
                    }
                    if (!AreEqual(c1.Whens[i].TypeBinding, c2.Whens[i].TypeBinding))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            case SqlNodeType.SearchedCase:
            {
                SqlSearchedCase c1 = (SqlSearchedCase)node1;
                SqlSearchedCase c2 = (SqlSearchedCase)node2;
                if (c1.Whens.Count != c2.Whens.Count)
                {
                    return(false);
                }
                for (int i = 0, n = c1.Whens.Count; i < n; i++)
                {
                    if (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) ||
                        !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value))
                    {
                        return(false);
                    }
                }
                return(AreEqual(c1.Else, c2.Else));
            }

            case SqlNodeType.ClientCase:
            {
                SqlClientCase c1 = (SqlClientCase)node1;
                SqlClientCase c2 = (SqlClientCase)node2;
                if (c1.Whens.Count != c2.Whens.Count)
                {
                    return(false);
                }
                for (int i = 0, n = c1.Whens.Count; i < n; i++)
                {
                    if (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) ||
                        !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            case SqlNodeType.DiscriminatedType:
            {
                SqlDiscriminatedType dt1 = (SqlDiscriminatedType)node1;
                SqlDiscriminatedType dt2 = (SqlDiscriminatedType)node2;
                return(AreEqual(dt1.Discriminator, dt2.Discriminator));
            }

            case SqlNodeType.SimpleCase:
            {
                SqlSimpleCase c1 = (SqlSimpleCase)node1;
                SqlSimpleCase c2 = (SqlSimpleCase)node2;
                if (c1.Whens.Count != c2.Whens.Count)
                {
                    return(false);
                }
                for (int i = 0, n = c1.Whens.Count; i < n; i++)
                {
                    if (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) ||
                        !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            case SqlNodeType.Like:
            {
                SqlLike like1 = (SqlLike)node1;
                SqlLike like2 = (SqlLike)node2;
                return(AreEqual(like1.Expression, like2.Expression) &&
                       AreEqual(like1.Pattern, like2.Pattern) &&
                       AreEqual(like1.Escape, like2.Escape));
            }

            case SqlNodeType.Variable:
            {
                SqlVariable v1 = (SqlVariable)node1;
                SqlVariable v2 = (SqlVariable)node2;
                return(v1.Name == v2.Name);
            }

            case SqlNodeType.FunctionCall:
            {
                SqlFunctionCall f1 = (SqlFunctionCall)node1;
                SqlFunctionCall f2 = (SqlFunctionCall)node2;
                if (f1.Name != f2.Name)
                {
                    return(false);
                }
                if (f1.Arguments.Count != f2.Arguments.Count)
                {
                    return(false);
                }
                for (int i = 0, n = f1.Arguments.Count; i < n; i++)
                {
                    if (!AreEqual(f1.Arguments[i], f2.Arguments[i]))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            case SqlNodeType.Link:
            {
                SqlLink l1 = (SqlLink)node1;
                SqlLink l2 = (SqlLink)node2;
                if (!MetaPosition.AreSameMember(l1.Member.Member, l2.Member.Member))
                {
                    return(false);
                }
                if (!AreEqual(l1.Expansion, l2.Expansion))
                {
                    return(false);
                }
                if (l1.KeyExpressions.Count != l2.KeyExpressions.Count)
                {
                    return(false);
                }
                for (int i = 0, c = l1.KeyExpressions.Count; i < c; ++i)
                {
                    if (!AreEqual(l1.KeyExpressions[i], l2.KeyExpressions[i]))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            case SqlNodeType.ExprSet:
                SqlExprSet es1 = (SqlExprSet)node1;
                SqlExprSet es2 = (SqlExprSet)node2;
                if (es1.Expressions.Count != es2.Expressions.Count)
                {
                    return(false);
                }
                for (int i = 0, n = es1.Expressions.Count; i < n; i++)
                {
                    if (!AreEqual(es1.Expressions[i], es2.Expressions[i]))
                    {
                        return(false);
                    }
                }
                return(true);

            case SqlNodeType.OptionalValue:
                SqlOptionalValue ov1 = (SqlOptionalValue)node1;
                SqlOptionalValue ov2 = (SqlOptionalValue)node2;
                return(AreEqual(ov1.Value, ov2.Value));

            case SqlNodeType.Row:
            case SqlNodeType.UserQuery:
            case SqlNodeType.StoredProcedureCall:
            case SqlNodeType.UserRow:
            case SqlNodeType.UserColumn:
            case SqlNodeType.Multiset:
            case SqlNodeType.ScalarSubSelect:
            case SqlNodeType.Element:
            case SqlNodeType.Exists:
            case SqlNodeType.Join:
            case SqlNodeType.Select:
            case SqlNodeType.New:
            case SqlNodeType.ClientQuery:
            case SqlNodeType.ClientArray:
            case SqlNodeType.Insert:
            case SqlNodeType.Update:
            case SqlNodeType.Delete:
            case SqlNodeType.MemberAssign:
            case SqlNodeType.Assign:
            case SqlNodeType.Block:
            case SqlNodeType.Union:
            case SqlNodeType.DoNotVisit:
            case SqlNodeType.MethodCall:
            case SqlNodeType.Nop:
            default:
                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;
            }
Пример #16
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);
        }
Пример #17
0
 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);
 }
Пример #18
0
 internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
     this.depth++;
     this.NewLine();
     sb.Append("(CASE");
     this.depth++;
     if (c.Expression != null) {
         sb.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();
             sb.Append("ELSE ");
             this.Visit(when.Value);
         } else {
             this.NewLine();
             sb.Append("WHEN ");
             this.Visit(when.Match);
             sb.Append(" THEN ");
             this.Visit(when.Value);
         }
     }
     this.depth--;
     this.NewLine();
     sb.Append(" END)");
     this.depth--;
     return c;
 }
        internal static bool?CanBeNull(SqlExpression expr)
        {
            switch (expr.NodeType)
            {
            case SqlNodeType.ExprSet:
                SqlExprSet exprSet = (SqlExprSet)expr;
                return(CanBeNull(exprSet.Expressions));

            case SqlNodeType.SimpleCase:
                SqlSimpleCase sc = (SqlSimpleCase)expr;
                return(CanBeNull(sc.Whens.Select(w => w.Value)));

            case SqlNodeType.Column:
                SqlColumn col = (SqlColumn)expr;
                if (col.MetaMember != null)
                {
                    return(col.MetaMember.CanBeNull);
                }
                else if (col.Expression != null)
                {
                    return(CanBeNull(col.Expression));
                }
                return(null);     // Don't know.

            case SqlNodeType.ColumnRef:
                SqlColumnRef cref = (SqlColumnRef)expr;
                return(CanBeNull(cref.Column));

            case SqlNodeType.Value:
                return(((SqlValue)expr).Value == null);

            case SqlNodeType.New:
            case SqlNodeType.Multiset:
            case SqlNodeType.Grouping:
            case SqlNodeType.DiscriminatedType:
            case SqlNodeType.IsNotNull:     // IsNull\IsNotNull always return true or false and can never return NULL.
            case SqlNodeType.IsNull:
            case SqlNodeType.Exists:
                return(false);

            case SqlNodeType.Add:
            case SqlNodeType.Sub:
            case SqlNodeType.Mul:
            case SqlNodeType.Div:
            case SqlNodeType.Mod:
            case SqlNodeType.BitAnd:
            case SqlNodeType.BitOr:
            case SqlNodeType.BitXor:
            case SqlNodeType.Concat: {
                SqlBinary bop   = (SqlBinary)expr;
                bool?     left  = CanBeNull(bop.Left);
                bool?     right = CanBeNull(bop.Right);
                return((left != false) || (right != false));
            }

            case SqlNodeType.Negate:
            case SqlNodeType.BitNot: {
                SqlUnary uop = (SqlUnary)expr;
                return(CanBeNull(uop.Operand));
            }

            case SqlNodeType.Lift: {
                SqlLift lift = (SqlLift)expr;
                return(CanBeNull(lift.Expression));
            }

            case SqlNodeType.OuterJoinedValue:
                return(true);

            default:
                return(null);    // Don't know.
            }
        }
Пример #20
0
 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;
 }
Пример #21
0
 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;
 }
Пример #22
0
        internal static bool AreEqual(SqlNode node1, SqlNode node2)
        {
            if (node1 == node2)
            {
                return(true);
            }
            if ((node1 != null) && (node2 != null))
            {
                if (node1.NodeType == SqlNodeType.SimpleCase)
                {
                    node1 = UnwrapTrivialCaseExpression((SqlSimpleCase)node1);
                }
                if (node2.NodeType == SqlNodeType.SimpleCase)
                {
                    node2 = UnwrapTrivialCaseExpression((SqlSimpleCase)node2);
                }
                if (node1.NodeType != node2.NodeType)
                {
                    if (node1.NodeType == SqlNodeType.ExprSet)
                    {
                        SqlExprSet set   = (SqlExprSet)node1;
                        int        num   = 0;
                        int        count = set.Expressions.Count;
                        while (num < count)
                        {
                            if (AreEqual(set.Expressions[num], node2))
                            {
                                return(true);
                            }
                            num++;
                        }
                    }
                    else if (node2.NodeType == SqlNodeType.ExprSet)
                    {
                        SqlExprSet set2 = (SqlExprSet)node2;
                        int        num3 = 0;
                        int        num4 = set2.Expressions.Count;
                        while (num3 < num4)
                        {
                            if (AreEqual(node1, set2.Expressions[num3]))
                            {
                                return(true);
                            }
                            num3++;
                        }
                    }
                    return(false);
                }
                if (node1.Equals(node2))
                {
                    return(true);
                }
                switch (node1.NodeType)
                {
                case SqlNodeType.Add:
                case SqlNodeType.And:
                case SqlNodeType.BitAnd:
                case SqlNodeType.BitOr:
                case SqlNodeType.BitXor:
                case SqlNodeType.Concat:
                case SqlNodeType.Div:
                case SqlNodeType.EQ:
                case SqlNodeType.EQ2V:
                case SqlNodeType.LE:
                case SqlNodeType.LT:
                case SqlNodeType.GE:
                case SqlNodeType.GT:
                case SqlNodeType.Mod:
                case SqlNodeType.Mul:
                case SqlNodeType.NE:
                case SqlNodeType.NE2V:
                case SqlNodeType.Or:
                case SqlNodeType.Sub:
                {
                    SqlBinary binary  = (SqlBinary)node1;
                    SqlBinary binary2 = (SqlBinary)node2;
                    if (!AreEqual(binary.Left, binary2.Left))
                    {
                        return(false);
                    }
                    return(AreEqual(binary.Right, binary2.Right));
                }

                case SqlNodeType.Alias:
                    return(AreEqual(((SqlAlias)node1).Node, ((SqlAlias)node2).Node));

                case SqlNodeType.AliasRef:
                    return(AreEqual(((SqlAliasRef)node1).Alias, ((SqlAliasRef)node2).Alias));

                case SqlNodeType.Avg:
                case SqlNodeType.BitNot:
                case SqlNodeType.ClrLength:
                case SqlNodeType.Count:
                case SqlNodeType.Covar:
                case SqlNodeType.IsNotNull:
                case SqlNodeType.IsNull:
                case SqlNodeType.Max:
                case SqlNodeType.Min:
                case SqlNodeType.Negate:
                case SqlNodeType.Not:
                case SqlNodeType.Not2V:
                case SqlNodeType.OuterJoinedValue:
                case SqlNodeType.Stddev:
                case SqlNodeType.Sum:
                case SqlNodeType.ValueOf:
                    return(AreEqual(((SqlUnary)node1).Operand, ((SqlUnary)node2).Operand));

                case SqlNodeType.Between:
                {
                    SqlBetween between  = (SqlBetween)node1;
                    SqlBetween between2 = (SqlBetween)node1;
                    if (!AreEqual(between.Expression, between2.Expression) ||
                        !AreEqual(between.Start, between2.Start))
                    {
                        return(false);
                    }
                    return(AreEqual(between.End, between2.End));
                }

                case SqlNodeType.Cast:
                case SqlNodeType.Convert:
                case SqlNodeType.Treat:
                {
                    SqlUnary unary  = (SqlUnary)node1;
                    SqlUnary unary2 = (SqlUnary)node2;
                    if ((unary.ClrType != unary2.ClrType) || !(unary.SqlType == unary2.SqlType))
                    {
                        return(false);
                    }
                    return(AreEqual(unary.Operand, unary2.Operand));
                }

                case SqlNodeType.ClientCase:
                {
                    SqlClientCase case5 = (SqlClientCase)node1;
                    SqlClientCase case6 = (SqlClientCase)node2;
                    if (case5.Whens.Count == case6.Whens.Count)
                    {
                        int num9  = 0;
                        int num10 = case5.Whens.Count;
                        while (num9 < num10)
                        {
                            if (!AreEqual(case5.Whens[num9].Match, case6.Whens[num9].Match) ||
                                !AreEqual(case5.Whens[num9].Value, case6.Whens[num9].Value))
                            {
                                return(false);
                            }
                            num9++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.Column:
                {
                    SqlColumn column  = (SqlColumn)node1;
                    SqlColumn column2 = (SqlColumn)node2;
                    return((column == column2) ||
                           (((column.Expression != null) && (column2.Expression != null)) &&
                            AreEqual(column.Expression, column2.Expression)));
                }

                case SqlNodeType.ColumnRef:
                {
                    SqlColumnRef cref = (SqlColumnRef)node1;
                    SqlColumnRef ref3 = (SqlColumnRef)node2;
                    return(GetBaseColumn(cref) == GetBaseColumn(ref3));
                }

                case SqlNodeType.DiscriminatedType:
                {
                    SqlDiscriminatedType type  = (SqlDiscriminatedType)node1;
                    SqlDiscriminatedType type2 = (SqlDiscriminatedType)node2;
                    return(AreEqual(type.Discriminator, type2.Discriminator));
                }

                case SqlNodeType.ExprSet:
                {
                    SqlExprSet set3 = (SqlExprSet)node1;
                    SqlExprSet set4 = (SqlExprSet)node2;
                    if (set3.Expressions.Count == set4.Expressions.Count)
                    {
                        int num17 = 0;
                        int num18 = set3.Expressions.Count;
                        while (num17 < num18)
                        {
                            if (!AreEqual(set3.Expressions[num17], set4.Expressions[num17]))
                            {
                                return(false);
                            }
                            num17++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.FunctionCall:
                {
                    SqlFunctionCall call  = (SqlFunctionCall)node1;
                    SqlFunctionCall call2 = (SqlFunctionCall)node2;
                    if (!(call.Name != call2.Name))
                    {
                        if (call.Arguments.Count != call2.Arguments.Count)
                        {
                            return(false);
                        }
                        int num13 = 0;
                        int num14 = call.Arguments.Count;
                        while (num13 < num14)
                        {
                            if (!AreEqual(call.Arguments[num13], call2.Arguments[num13]))
                            {
                                return(false);
                            }
                            num13++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.Link:
                {
                    SqlLink link  = (SqlLink)node1;
                    SqlLink link2 = (SqlLink)node2;
                    if (MetaPosition.AreSameMember(link.Member.Member, link2.Member.Member))
                    {
                        if (!AreEqual(link.Expansion, link2.Expansion))
                        {
                            return(false);
                        }
                        if (link.KeyExpressions.Count != link2.KeyExpressions.Count)
                        {
                            return(false);
                        }
                        int num15 = 0;
                        int num16 = link.KeyExpressions.Count;
                        while (num15 < num16)
                        {
                            if (!AreEqual(link.KeyExpressions[num15], link2.KeyExpressions[num15]))
                            {
                                return(false);
                            }
                            num15++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.Like:
                {
                    SqlLike like  = (SqlLike)node1;
                    SqlLike like2 = (SqlLike)node2;
                    if (!AreEqual(like.Expression, like2.Expression) || !AreEqual(like.Pattern, like2.Pattern))
                    {
                        return(false);
                    }
                    return(AreEqual(like.Escape, like2.Escape));
                }

                case SqlNodeType.Member:
                    if (((SqlMember)node1).Member != ((SqlMember)node2).Member)
                    {
                        return(false);
                    }
                    return(AreEqual(((SqlMember)node1).Expression, ((SqlMember)node2).Expression));

                case SqlNodeType.OptionalValue:
                {
                    SqlOptionalValue value2 = (SqlOptionalValue)node1;
                    SqlOptionalValue value3 = (SqlOptionalValue)node2;
                    return(AreEqual(value2.Value, value3.Value));
                }

                case SqlNodeType.Parameter:
                    return(node1 == node2);

                case SqlNodeType.SearchedCase:
                {
                    SqlSearchedCase case3 = (SqlSearchedCase)node1;
                    SqlSearchedCase case4 = (SqlSearchedCase)node2;
                    if (case3.Whens.Count == case4.Whens.Count)
                    {
                        int num7 = 0;
                        int num8 = case3.Whens.Count;
                        while (num7 < num8)
                        {
                            if (!AreEqual(case3.Whens[num7].Match, case4.Whens[num7].Match) ||
                                !AreEqual(case3.Whens[num7].Value, case4.Whens[num7].Value))
                            {
                                return(false);
                            }
                            num7++;
                        }
                        return(AreEqual(case3.Else, case4.Else));
                    }
                    return(false);
                }

                case SqlNodeType.SimpleCase:
                {
                    SqlSimpleCase case7 = (SqlSimpleCase)node1;
                    SqlSimpleCase case8 = (SqlSimpleCase)node2;
                    if (case7.Whens.Count == case8.Whens.Count)
                    {
                        int num11 = 0;
                        int num12 = case7.Whens.Count;
                        while (num11 < num12)
                        {
                            if (!AreEqual(case7.Whens[num11].Match, case8.Whens[num11].Match) ||
                                !AreEqual(case7.Whens[num11].Value, case8.Whens[num11].Value))
                            {
                                return(false);
                            }
                            num11++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.Table:
                    return(((SqlTable)node1).MetaTable == ((SqlTable)node2).MetaTable);

                case SqlNodeType.TypeCase:
                {
                    SqlTypeCase @case = (SqlTypeCase)node1;
                    SqlTypeCase case2 = (SqlTypeCase)node2;
                    if (AreEqual(@case.Discriminator, case2.Discriminator))
                    {
                        if (@case.Whens.Count != case2.Whens.Count)
                        {
                            return(false);
                        }
                        int num5 = 0;
                        int num6 = @case.Whens.Count;
                        while (num5 < num6)
                        {
                            if (!AreEqual(@case.Whens[num5].Match, case2.Whens[num5].Match))
                            {
                                return(false);
                            }
                            if (!AreEqual(@case.Whens[num5].TypeBinding, case2.Whens[num5].TypeBinding))
                            {
                                return(false);
                            }
                            num5++;
                        }
                        return(true);
                    }
                    return(false);
                }

                case SqlNodeType.Variable:
                {
                    SqlVariable variable  = (SqlVariable)node1;
                    SqlVariable variable2 = (SqlVariable)node2;
                    return(variable.Name == variable2.Name);
                }

                case SqlNodeType.Value:
                    return(object.Equals(((SqlValue)node1).Value, ((SqlValue)node2).Value));
                }
            }
            return(false);
        }
Пример #23
0
            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;
            }
Пример #24
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;
 }