Exemple #1
0
        private SqlExpression TranslateEqualsOp(SqlNodeType op, SqlExpression left, SqlExpression right, bool allowExpand)
        {
            switch (op)
            {
            case SqlNodeType.EQ:
            case SqlNodeType.NE:
                return(sql.Binary(op, left, right));

            case SqlNodeType.EQ2V: {
                if (SqlExpressionNullability.CanBeNull(left) != false && SqlExpressionNullability.CanBeNull(right) != false)
                {
                    var nodeType3 = allowExpand ? SqlNodeType.EQ2V : SqlNodeType.EQ;
                    return(sql.Binary(SqlNodeType.Or, sql.Binary(SqlNodeType.And, sql.Unary(SqlNodeType.IsNull, (SqlExpression)SqlDuplicator.Copy(left)), sql.Unary(SqlNodeType.IsNull, (SqlExpression)SqlDuplicator.Copy(right))), sql.Binary(SqlNodeType.And, sql.Binary(SqlNodeType.And, sql.Unary(SqlNodeType.IsNotNull, (SqlExpression)SqlDuplicator.Copy(left)), sql.Unary(SqlNodeType.IsNotNull, (SqlExpression)SqlDuplicator.Copy(right))), sql.Binary(nodeType3, left, right))));
                }
                var nodeType4 = allowExpand ? SqlNodeType.EQ2V : SqlNodeType.EQ;
                return(sql.Binary(nodeType4, left, right));
            }

            case SqlNodeType.NE2V: {
                if (SqlExpressionNullability.CanBeNull(left) != false && SqlExpressionNullability.CanBeNull(right) != false)
                {
                    var nodeType = allowExpand ? SqlNodeType.EQ2V : SqlNodeType.EQ;
                    return(sql.Unary(SqlNodeType.Not, sql.Binary(SqlNodeType.Or, sql.Binary(SqlNodeType.And, sql.Unary(SqlNodeType.IsNull, (SqlExpression)SqlDuplicator.Copy(left)), sql.Unary(SqlNodeType.IsNull, (SqlExpression)SqlDuplicator.Copy(right))), sql.Binary(SqlNodeType.And, sql.Binary(SqlNodeType.And, sql.Unary(SqlNodeType.IsNotNull, (SqlExpression)SqlDuplicator.Copy(left)), sql.Unary(SqlNodeType.IsNotNull, (SqlExpression)SqlDuplicator.Copy(right))), sql.Binary(nodeType, left, right)))));
                }
                var nodeType2 = allowExpand ? SqlNodeType.NE2V : SqlNodeType.NE;
                return(sql.Binary(nodeType2, left, right));
            }

            default:
                throw Error.UnexpectedNode(op);
            }
        }
            /// <summary>
            /// For CASE statements which represent boolean values:
            ///
            ///  CASE XXX
            ///    WHEN AAA THEN true        ===>        (XXX==AAA) || (XXX==BBB)
            ///    WHEN BBB THEN true
            ///    ELSE false
            ///    etc.
            ///  END
            ///
            /// Also,
            ///
            ///  CASE XXX
            ///    WHEN AAA THEN false        ===>        (XXX!=AAA) && (XXX!=BBB)
            ///    WHEN BBB THEN false
            ///    ELSE true
            ///    etc.
            ///  END
            ///
            /// The reduce to a conjunction or disjunction of equality or inequality.
            /// The possibility of NULL in XXX is taken into account.
            /// </summary>
            private SqlExpression TryToWriteAsSimpleBooleanExpression(Type caseType, SqlExpression discriminator, List <SqlWhen> newWhens, bool allValuesLiteral)
            {
                SqlExpression rewrite = null;

                if (caseType == typeof(bool) && allValuesLiteral)
                {
                    bool?holdsNull = SqlExpressionNullability.CanBeNull(discriminator);
                    // The discriminator can't hold a NULL.
                    // In this case, we don't need the special fallback that CASE-ELSE gives.
                    // We can just construct a boolean operation.
                    bool?whenValue = null;
                    for (int i = 0; i < newWhens.Count; ++i)
                    {
                        SqlValue lit   = (SqlValue)newWhens[i].Value; // Must be SqlValue because of allValuesLiteral.
                        bool     value = (bool)lit.Value;             // Must be bool because of caseType==typeof(bool).
                        if (newWhens[i].Match != null)                // Skip the ELSE
                        {
                            if (value)
                            {
                                rewrite = sql.OrAccumulate(rewrite, sql.Binary(SqlNodeType.EQ, discriminator, newWhens[i].Match));
                            }
                            else
                            {
                                rewrite = sql.AndAccumulate(rewrite, sql.Binary(SqlNodeType.NE, discriminator, newWhens[i].Match));
                            }
                        }
                        else
                        {
                            whenValue = value;
                        }
                    }
                    // If it could possibly hold null values.
                    if (holdsNull != false && whenValue != null)
                    {
                        if (whenValue == true)
                        {
                            rewrite = sql.OrAccumulate(rewrite, sql.Unary(SqlNodeType.IsNull, discriminator, discriminator.SourceExpression));
                        }
                        else
                        {
                            rewrite = sql.AndAccumulate(rewrite, sql.Unary(SqlNodeType.IsNotNull, discriminator, discriminator.SourceExpression));
                        }
                    }
                }
                return(rewrite);
            }
Exemple #3
0
            internal override SqlExpression ConvertPredicateToValue(SqlExpression predicateExpression)
            {
                // Transform the 'Predicate' expression into a 'Bit' by forming the
                // following operation:
                //   CASE
                //    WHEN predicateExpression THEN 1
                //    ELSE NOT(predicateExpression) THEN 0
                //    ELSE NULL
                //   END

                // Possible simplification to the generated SQL would be to detect when 'predicateExpression'
                // is SqlUnary(NOT) and use its operand with the literal 1 and 0 below swapped.
                SqlExpression valueTrue  = sql.ValueFromObject(true, false, predicateExpression.SourceExpression);
                SqlExpression valueFalse = sql.ValueFromObject(false, false, predicateExpression.SourceExpression);

                if (SqlExpressionNullability.CanBeNull(predicateExpression) != false)
                {
                    SqlExpression valueNull = sql.Value(valueTrue.ClrType, valueTrue.SqlType, null, false, predicateExpression.SourceExpression);
                    return(new SqlSearchedCase(
                               predicateExpression.ClrType,
                               new SqlWhen[] {
                        new SqlWhen(predicateExpression, valueTrue),
                        new SqlWhen(new SqlUnary(SqlNodeType.Not, predicateExpression.ClrType, predicateExpression.SqlType, predicateExpression, predicateExpression.SourceExpression), valueFalse)
                    },
                               valueNull,
                               predicateExpression.SourceExpression
                               ));
                }
                else
                {
                    return(new SqlSearchedCase(
                               predicateExpression.ClrType,
                               new SqlWhen[] { new SqlWhen(predicateExpression, valueTrue) },
                               valueFalse,
                               predicateExpression.SourceExpression
                               ));
                }
            }