public NpgsqlStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactory, NpgsqlTypeMappingSource npgsqlTypeMappingSource) { _sqlExpressionFactory = sqlExpressionFactory; _whitespace = _sqlExpressionFactory.Constant( @" \t\n\r", // TODO: Complete this npgsqlTypeMappingSource.EStringTypeMapping); _textTypeMapping = _sqlExpressionFactory.FindMapping(typeof(string)); }
protected override Expression VisitUnary(UnaryExpression unaryExpression) { var operand = Visit(unaryExpression.Operand); if (TranslationFailed(unaryExpression.Operand, operand)) { return(null); } var sqlOperand = (SqlExpression)operand; switch (unaryExpression.NodeType) { case ExpressionType.Not: return(_sqlExpressionFactory.Not(sqlOperand)); case ExpressionType.Negate: return(_sqlExpressionFactory.Negate(sqlOperand)); case ExpressionType.Convert: // Object convert needs to be converted to explicit cast when mismatching types if (operand.Type.IsInterface && unaryExpression.Type.GetInterfaces().Any(e => e == operand.Type) || unaryExpression.Type.UnwrapNullableType() == operand.Type || unaryExpression.Type.UnwrapNullableType() == typeof(Enum)) { return(sqlOperand); } // Introduce explicit cast only if the target type is mapped else we need to client eval if (unaryExpression.Type == typeof(object) || _sqlExpressionFactory.FindMapping(unaryExpression.Type) != null) { sqlOperand = _sqlExpressionFactory.ApplyDefaultTypeMapping(sqlOperand); return(_sqlExpressionFactory.Convert(sqlOperand, unaryExpression.Type)); } break; } return(null); }
public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { if (method == IPAddressParse) { return(_sqlExpressionFactory.Convert(arguments[0], typeof(IPAddress), _sqlExpressionFactory.FindMapping(typeof(IPAddress)))); } if (method == PhysicalAddressParse) { return(_sqlExpressionFactory.Convert(arguments[0], typeof(PhysicalAddress), _sqlExpressionFactory.FindMapping(typeof(PhysicalAddress)))); } if (method.DeclaringType != typeof(NpgsqlNetworkExtensions)) { return(null); } return(method.Name switch { nameof(NpgsqlNetworkExtensions.LessThan) => _sqlExpressionFactory.LessThan(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.LessThanOrEqual) => _sqlExpressionFactory.LessThanOrEqual(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.GreaterThanOrEqual) => _sqlExpressionFactory.GreaterThanOrEqual(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.GreaterThan) => _sqlExpressionFactory.GreaterThan(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.ContainedBy) => BoolReturningOnTwoNetworkTypes("<<"), nameof(NpgsqlNetworkExtensions.ContainedByOrEqual) => BoolReturningOnTwoNetworkTypes("<<="), nameof(NpgsqlNetworkExtensions.Contains) => BoolReturningOnTwoNetworkTypes(">>"), nameof(NpgsqlNetworkExtensions.ContainsOrEqual) => BoolReturningOnTwoNetworkTypes(">>="), nameof(NpgsqlNetworkExtensions.ContainsOrContainedBy) => BoolReturningOnTwoNetworkTypes("&&"), // TODO: Hack, see #1118 nameof(NpgsqlNetworkExtensions.BitwiseNot) => new SqlUnaryExpression(ExpressionType.Negate, arguments[1], arguments[1].Type, arguments[1].TypeMapping), nameof(NpgsqlNetworkExtensions.BitwiseAnd) => _sqlExpressionFactory.And(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.BitwiseOr) => _sqlExpressionFactory.Or(arguments[1], arguments[2]), // Add/Subtract accept inet + int, so we can't use the default type mapping inference logic which assumes // same-typed operands nameof(NpgsqlNetworkExtensions.Add) => new SqlBinaryExpression( ExpressionType.Add, _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[1]), _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[2]), arguments[1].Type, arguments[1].TypeMapping), nameof(NpgsqlNetworkExtensions.Subtract) when arguments[2].Type == typeof(int)
public NpgsqlRangeTranslator(ISqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; _boolMapping = sqlExpressionFactory.FindMapping(typeof(bool)); }
public virtual SqlExpression Translate(SqlExpression instance, MemberInfo member, Type returnType) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); var declaringType = member.DeclaringType; if (declaringType == typeof(DateTime) || declaringType == typeof(DateTimeOffset)) { var memberName = member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(datePart), instance }, returnType)); } switch (memberName) { case nameof(DateTime.Date): return(_sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment("date"), instance }, returnType, declaringType == typeof(DateTime) ? instance.TypeMapping : _sqlExpressionFactory.FindMapping(typeof(DateTime)))); case nameof(DateTime.TimeOfDay): return(_sqlExpressionFactory.Convert(instance, returnType)); case nameof(DateTime.Now): return(_sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETDATE" : "SYSDATETIMEOFFSET", Array.Empty <SqlExpression>(), returnType)); case nameof(DateTime.UtcNow): var serverTranslation = _sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETUTCDATE" : "SYSUTCDATETIME", Array.Empty <SqlExpression>(), returnType); return(declaringType == typeof(DateTime) ? (SqlExpression)serverTranslation : _sqlExpressionFactory.Convert(serverTranslation, returnType)); case nameof(DateTime.Today): return(_sqlExpressionFactory.Function( "CONVERT", new SqlExpression[] { _sqlExpressionFactory.Fragment("date"), _sqlExpressionFactory.Function( "GETDATE", Array.Empty <SqlExpression>(), typeof(DateTime)) }, returnType)); } } return(null); }