private SqlExpression ApplyTypeMappingOnSqlUnary( SqlUnaryExpression sqlUnaryExpression, CoreTypeMapping typeMapping) { SqlExpression operand; Type resultType; CoreTypeMapping resultTypeMapping; switch (sqlUnaryExpression.OperatorType) { case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.Not when sqlUnaryExpression.IsLogicalNot(): { resultTypeMapping = _boolTypeMapping; resultType = typeof(bool); operand = ApplyDefaultTypeMapping(sqlUnaryExpression.Operand); break; } case ExpressionType.Convert: resultTypeMapping = typeMapping; // Since we are applying convert, resultTypeMapping decides the clrType resultType = resultTypeMapping?.ClrType ?? sqlUnaryExpression.Type; operand = ApplyDefaultTypeMapping(sqlUnaryExpression.Operand); break; case ExpressionType.Not: case ExpressionType.Negate: resultTypeMapping = typeMapping; // While Not is logical, negate is numeric hence we use clrType from TypeMapping resultType = resultTypeMapping?.ClrType ?? sqlUnaryExpression.Type; operand = ApplyTypeMapping(sqlUnaryExpression.Operand, typeMapping); break; default: throw new InvalidOperationException( CosmosStrings.UnsupportedOperatorForSqlExpression( sqlUnaryExpression.OperatorType, typeof(SqlUnaryExpression).ShortDisplayName())); ; } return(new SqlUnaryExpression(sqlUnaryExpression.OperatorType, operand, resultType, resultTypeMapping)); }
private SqlExpression ApplyTypeMappingOnSqlBinary( SqlBinaryExpression sqlBinaryExpression, CoreTypeMapping typeMapping) { var left = sqlBinaryExpression.Left; var right = sqlBinaryExpression.Right; Type resultType; CoreTypeMapping resultTypeMapping; CoreTypeMapping inferredTypeMapping; switch (sqlBinaryExpression.OperatorType) { case ExpressionType.Equal: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.NotEqual: { inferredTypeMapping = ExpressionExtensions.InferTypeMapping(left, right) // We avoid object here since the result does not get typeMapping from outside. ?? (left.Type != typeof(object) ? _typeMappingSource.FindMapping(left.Type) : _typeMappingSource.FindMapping(right.Type)); resultType = typeof(bool); resultTypeMapping = _boolTypeMapping; } break; case ExpressionType.AndAlso: case ExpressionType.OrElse: { inferredTypeMapping = _boolTypeMapping; resultType = typeof(bool); resultTypeMapping = _boolTypeMapping; } break; case ExpressionType.Add: case ExpressionType.Subtract: case ExpressionType.Multiply: case ExpressionType.Divide: case ExpressionType.Modulo: case ExpressionType.LeftShift: case ExpressionType.RightShift: case ExpressionType.And: case ExpressionType.Or: { inferredTypeMapping = typeMapping ?? ExpressionExtensions.InferTypeMapping(left, right); resultType = inferredTypeMapping?.ClrType ?? left.Type; resultTypeMapping = inferredTypeMapping; } break; default: throw new InvalidOperationException( CosmosStrings.UnsupportedOperatorForSqlExpression( sqlBinaryExpression.OperatorType, typeof(SqlBinaryExpression).ShortDisplayName())); } return(new SqlBinaryExpression( sqlBinaryExpression.OperatorType, ApplyTypeMapping(left, inferredTypeMapping), ApplyTypeMapping(right, inferredTypeMapping), resultType, resultTypeMapping)); }
private static ExpressionType VerifyOperator(ExpressionType operatorType) => _allowedOperators.Contains(operatorType) ? operatorType : throw new InvalidOperationException( CosmosStrings.UnsupportedOperatorForSqlExpression( operatorType, typeof(SqlBinaryExpression).ShortDisplayName()));