public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); // Issue #15586: Query: TypeCompatibility chart for inference. return(_methodInfo.Equals(method) ? _sqlExpressionFactory.Function( "abs", new SqlExpression[] { _sqlExpressionFactory.Divide( _sqlExpressionFactory.Function( "random", Array.Empty <SqlExpression>(), nullable: false, argumentsPropagateNullability: Array.Empty <bool>(), method.ReturnType), _sqlExpressionFactory.Constant(9223372036854780000.0)) }, nullable: false, argumentsPropagateNullability: Array.Empty <bool>(), method.ReturnType) : null); }
public SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (typeof(Point).IsAssignableFrom(member.DeclaringType)) { Check.DebugAssert(instance !.TypeMapping != null, "Instance must have typeMapping assigned."); var storeType = instance.TypeMapping.StoreType; var isGeography = string.Equals(storeType, "geography", StringComparison.OrdinalIgnoreCase); if (MemberToPropertyName.TryGetValue(member, out var propertyName) || (isGeography ? GeographyMemberToPropertyName.TryGetValue(member, out propertyName) : GeometryMemberToPropertyName.TryGetValue(member, out propertyName)) && propertyName != null) { return(_sqlExpressionFactory.NiladicFunction( instance, propertyName, nullable: true, instancePropagatesNullability: true, returnType)); } } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (_memberToFunctionName.TryGetValue(member, out var functionName) && instance != null) { return(returnType == typeof(bool) ? _sqlExpressionFactory.Case( new[] { new CaseWhenClause( _sqlExpressionFactory.IsNotNull(instance), _sqlExpressionFactory.Function( functionName, new[] { instance }, nullable: false, argumentsPropagateNullability: new[] { false }, returnType)) }, null) : _sqlExpressionFactory.Function( functionName, new[] { instance }, nullable: true, argumentsPropagateNullability: new[] { true }, returnType)); } return(null); }
public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (member.DeclaringType == typeof(DateTime)) { var memberName = member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { return(_sqlExpressionFactory.Convert( SqliteExpression.Strftime( _sqlExpressionFactory, typeof(string), datePart, instance !), returnType)); } if (memberName == nameof(DateTime.Ticks)) { return(_sqlExpressionFactory.Convert( _sqlExpressionFactory.Multiply( _sqlExpressionFactory.Subtract( _sqlExpressionFactory.Function( "julianday", new[] { instance ! },
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (Equals(method, _isNullOrEmptyMethodInfo)) { var argument = arguments[0]; return(_sqlExpressionFactory.OrElse( _sqlExpressionFactory.IsNull(argument), _sqlExpressionFactory.Equal( argument, _sqlExpressionFactory.Constant(string.Empty)))); } if (Equals(method, _concatMethodInfo)) { return(_sqlExpressionFactory.Add( arguments[0], arguments[1])); } return(null); }
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (instance?.Type.IsGenericList() == true && !IsMappedToNonArray(instance)) { // Translate list[i]. Note that array[i] is translated by NpgsqlSqlTranslatingExpressionVisitor.VisitBinary (ArrayIndex) if (method.Name == "get_Item" && arguments.Count == 1) { return // Try translating indexing inside json column (_jsonPocoTranslator.TranslateMemberAccess(instance, arguments[0], method.ReturnType) ?? // Other types should be subscriptable - but PostgreSQL arrays are 1-based, so adjust the index. _sqlExpressionFactory.ArrayIndex(instance, GenerateOneBasedIndexExpression(arguments[0]))); } return(TranslateCommon(instance, arguments)); } if (instance is null && arguments.Count > 0 && arguments[0].Type.IsArrayOrGenericList() && !IsMappedToNonArray(arguments[0])) { // Extension method over an array or list if (method.IsClosedFormOf(SequenceEqual) && arguments[1].Type.IsArray) { return(_sqlExpressionFactory.Equal(arguments[0], arguments[1])); } return(TranslateCommon(arguments[0], arguments.Slice(1))); } // Not an array/list return(null);
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (method.IsGenericMethod && method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) && arguments[0].Type == typeof(byte[])) { var source = arguments[0]; var sourceTypeMapping = source.TypeMapping; var value = arguments[1] is SqlConstantExpression constantValue ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value }, sourceTypeMapping) : _sqlExpressionFactory.Convert(arguments[1], typeof(byte[]), sourceTypeMapping); return(_sqlExpressionFactory.GreaterThan( _sqlExpressionFactory.Function( "CHARINDEX", new[] { value, source }, nullable: true, argumentsPropagateNullability: new[] { true, true }, typeof(int)), _sqlExpressionFactory.Constant(0))); } return(null); }
public virtual SqlExpression?ApplyTypeMapping(SqlExpression?sqlExpression, CoreTypeMapping?typeMapping) { if (sqlExpression == null || sqlExpression.TypeMapping != null) { return(sqlExpression); } #pragma warning disable IDE0066 // Convert switch statement to expression switch (sqlExpression) #pragma warning restore IDE0066 // Convert switch statement to expression { case SqlConditionalExpression sqlConditionalExpression: return(ApplyTypeMappingOnSqlConditional(sqlConditionalExpression, typeMapping)); case SqlBinaryExpression sqlBinaryExpression: return(ApplyTypeMappingOnSqlBinary(sqlBinaryExpression, typeMapping)); case SqlUnaryExpression sqlUnaryExpression: return(ApplyTypeMappingOnSqlUnary(sqlUnaryExpression, typeMapping)); case SqlConstantExpression sqlConstantExpression: return(sqlConstantExpression.ApplyTypeMapping(typeMapping)); case SqlParameterExpression sqlParameterExpression: return(sqlParameterExpression.ApplyTypeMapping(typeMapping)); case SqlFunctionExpression sqlFunctionExpression: return(sqlFunctionExpression.ApplyTypeMapping(typeMapping)); default: return(sqlExpression); } }
public PostgresFunctionExpression( string name, IEnumerable <SqlExpression> arguments, IEnumerable <string?>?argumentNames, IEnumerable <string?>?argumentSeparators, bool nullable, IEnumerable <bool> argumentsPropagateNullability, bool aggregateDistinct, SqlExpression?aggregatePredicate, IReadOnlyList <OrderingExpression> aggregateOrderings, Type type, RelationalTypeMapping?typeMapping) : base(name, arguments, nullable, argumentsPropagateNullability, type, typeMapping) { Check.NotEmpty(name, nameof(name)); Check.NotNull(type, nameof(type)); ArgumentNames = (argumentNames ?? Array.Empty <string>()).ToList(); ArgumentSeparators = (argumentSeparators ?? Array.Empty <string>()).ToList(); if (ArgumentNames.SkipWhile(a => a is null).Contains(null)) { throw new ArgumentException($"{nameof(argumentNames)} must contain nulls followed by non-nulls", nameof(argumentNames)); } IsAggregateDistinct = aggregateDistinct; AggregatePredicate = aggregatePredicate; AggregateOrderings = aggregateOrderings; }
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (method.Equals(_regexIsMatchMethodInfo)) { var input = arguments[0]; var pattern = arguments[1]; var stringTypeMapping = ExpressionExtensions.InferTypeMapping(input, pattern); return(_sqlExpressionFactory.Function( "regexp", new[] { _sqlExpressionFactory.ApplyTypeMapping(pattern, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(input, stringTypeMapping) }, nullable: true, argumentsPropagateNullability: new[] { true, true }, typeof(bool))); } return(null); }
/// <inheritdoc /> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (method == TsQueryParse || method == TsVectorParse) { return(_sqlExpressionFactory.Convert(arguments[0], method.ReturnType)); } if (method.DeclaringType == typeof(NpgsqlFullTextSearchDbFunctionsExtensions)) { return(method.Name switch { // Methods accepting a configuration (regconfig) nameof(NpgsqlFullTextSearchDbFunctionsExtensions.ToTsVector) when arguments.Count == 3 => ConfigAccepting("to_tsvector"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.PlainToTsQuery) when arguments.Count == 3 => ConfigAccepting("plainto_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.PhraseToTsQuery) when arguments.Count == 3 => ConfigAccepting("phraseto_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.ToTsQuery) when arguments.Count == 3 => ConfigAccepting("to_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.WebSearchToTsQuery) when arguments.Count == 3 => ConfigAccepting("websearch_to_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.Unaccent) when arguments.Count == 3 => DictionaryAccepting("unaccent"), // Methods not accepting a configuration nameof(NpgsqlFullTextSearchDbFunctionsExtensions.ArrayToTsVector) => NonConfigAccepting("array_to_tsvector"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.ToTsVector) => NonConfigAccepting("to_tsvector"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.PlainToTsQuery) => NonConfigAccepting("plainto_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.PhraseToTsQuery) => NonConfigAccepting("phraseto_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.ToTsQuery) => NonConfigAccepting("to_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.WebSearchToTsQuery) => NonConfigAccepting("websearch_to_tsquery"), nameof(NpgsqlFullTextSearchDbFunctionsExtensions.Unaccent) => NonConfigAccepting("unaccent"), _ => null });
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (Equals(member, _isClosed) && instance != null) { return(_sqlExpressionFactory.Case( new[] { new CaseWhenClause( _sqlExpressionFactory.IsNotNull(instance), _sqlExpressionFactory.Function( "IsClosed", new[] { instance }, nullable: false, argumentsPropagateNullability: new[] { false }, returnType)) }, null)); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (_memberToFunctionName.TryGetValue(member, out var functionName)) { Check.DebugAssert(instance !.TypeMapping != null, "Instance must have typeMapping assigned."); var storeType = instance.TypeMapping.StoreType; var isGeography = storeType == "geography"; if (isGeography && functionName == "STIsRing") { return(null); } var resultTypeMapping = typeof(Geometry).IsAssignableFrom(returnType) ? _typeMappingSource.FindMapping(returnType, storeType) : _typeMappingSource.FindMapping(returnType); return(_sqlExpressionFactory.Function( instance, functionName, Enumerable.Empty <SqlExpression>(), nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: Enumerable.Empty <bool>(), returnType, resultTypeMapping)); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (Equals(method, _getPointN) && instance != null) { return(_sqlExpressionFactory.Function( instance, "STPointN", new[] { _sqlExpressionFactory.Add( arguments[0], _sqlExpressionFactory.Constant(1)) }, nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: new[] { true }, method.ReturnType, _typeMappingSource.FindMapping(method.ReturnType, instance.TypeMapping !.StoreType))); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (member.Name == nameof(string.Length) && instance?.Type == typeof(string)) { return(_sqlExpressionFactory.Convert( _sqlExpressionFactory.Function( "LEN", new[] { instance }, nullable: true, argumentsPropagateNullability: new[] { true }, typeof(long)), returnType)); } return(null); }
public virtual SqlExpression?ApplyTypeMapping(SqlExpression?sqlExpression, CoreTypeMapping?typeMapping) { if (sqlExpression == null || sqlExpression.TypeMapping != null) { return(sqlExpression); } switch (sqlExpression) { case SqlConditionalExpression sqlConditionalExpression: return(ApplyTypeMappingOnSqlConditional(sqlConditionalExpression, typeMapping)); case SqlBinaryExpression sqlBinaryExpression: return(ApplyTypeMappingOnSqlBinary(sqlBinaryExpression, typeMapping)); case SqlUnaryExpression sqlUnaryExpression: return(ApplyTypeMappingOnSqlUnary(sqlUnaryExpression, typeMapping)); case SqlConstantExpression sqlConstantExpression: return(sqlConstantExpression.ApplyTypeMapping(typeMapping)); case SqlParameterExpression sqlParameterExpression: return(sqlParameterExpression.ApplyTypeMapping(typeMapping)); default: return(sqlExpression); } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (Equals(method, _item) && instance != null) { return(_sqlExpressionFactory.Function( instance, "STGeometryN", new[] { _sqlExpressionFactory.Add( arguments[0], _sqlExpressionFactory.Constant(1)) }, nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: new[] { false }, method.ReturnType, _typeMappingSource.FindMapping(typeof(Geometry), instance.TypeMapping !.StoreType))); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (member.DeclaringType?.IsNullableValueType() == true && instance != null) { switch (member.Name) { case nameof(Nullable <int> .Value): return(instance); case nameof(Nullable <int> .HasValue): return(_sqlExpressionFactory.IsNotNull(instance)); } } return(null); }
private SqlFunctionExpression( [CanBeNull] SqlExpression?instance, [CanBeNull] string?schema, [NotNull] string name, bool niladic, [CanBeNull] IEnumerable <SqlExpression>?arguments, bool nullable, bool?instancePropagatesNullability, [CanBeNull] IEnumerable <bool>?argumentsPropagateNullability, bool builtIn, [NotNull] Type type, [CanBeNull] RelationalTypeMapping?typeMapping) : base(type, typeMapping) { Check.NotEmpty(name, nameof(name)); Check.NotNull(type, nameof(type)); Instance = instance; Name = name; Schema = schema; IsNiladic = niladic; IsBuiltIn = builtIn; Arguments = arguments?.ToList(); IsNullable = nullable; InstancePropagatesNullability = instancePropagatesNullability; ArgumentsPropagateNullability = argumentsPropagateNullability?.ToList(); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (method.Equals(MethodInfo)) { var matchExpression = arguments[1]; var pattern = arguments[2]; var stringTypeMapping = ExpressionExtensions.InferTypeMapping(matchExpression, pattern); return(_sqlExpressionFactory.Function( "glob", new[] { _sqlExpressionFactory.ApplyTypeMapping(pattern, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(matchExpression, stringTypeMapping) }, nullable: true, argumentsPropagateNullability: new[] { true, true }, typeof(bool))); } return(null); }
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (_methodInfoDateDiffMapping.TryGetValue(method, out var datePart)) { var startDate = arguments[1]; var endDate = arguments[2]; var typeMapping = ExpressionExtensions.InferTypeMapping(startDate, endDate); startDate = _sqlExpressionFactory.ApplyTypeMapping(startDate, typeMapping); endDate = _sqlExpressionFactory.ApplyTypeMapping(endDate, typeMapping); return(_sqlExpressionFactory.Function( "DATEDIFF", new[] { _sqlExpressionFactory.Fragment(datePart), startDate, endDate }, nullable: true, argumentsPropagateNullability: new[] { false, true, true }, typeof(int))); } return(null); }
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (method.DeclaringType != typeof(NpgsqlJsonDbFunctionsExtensions)) { return(null); } var args = arguments // Skip useless DbFunctions instance .Skip(1) // JSON extensions accept object parameters for JSON, since they must be able to handle POCOs, strings or DOM types. // This means they come wrapped in a convert node, which we need to remove. // Convert nodes may also come from wrapping JsonTraversalExpressions generated through POCO traversal. .Select(RemoveConvert) // If a function is invoked over a JSON traversal expression, that expression may come with // returnText: true (i.e. operator ->> and not ->). Since the functions below require a json object and // not text, we transform it. .Select(a => a is PostgresJsonTraversalExpression traversal ? WithReturnsText(traversal, false) : a) .ToArray(); if (!args.Any(a => a.TypeMapping is NpgsqlJsonTypeMapping || a is PostgresJsonTraversalExpression)) { throw new InvalidOperationException("The EF JSON methods require a JSON parameter and none was found."); } if (method.Name == nameof(NpgsqlJsonDbFunctionsExtensions.JsonTypeof)) { return(_sqlExpressionFactory.Function( ((NpgsqlJsonTypeMapping)args[0].TypeMapping !).IsJsonb ? "jsonb_typeof" : "json_typeof", new[] { args[0] }, nullable: true, argumentsPropagateNullability: TrueArrays[1], typeof(string))); } // The following are jsonb-only, not support on json if (args.Any(a => a.TypeMapping is NpgsqlJsonTypeMapping jsonMapping && !jsonMapping.IsJsonb)) { throw new InvalidOperationException("JSON methods on EF.Functions only support the jsonb type, not json."); } return(method.Name switch { nameof(NpgsqlJsonDbFunctionsExtensions.JsonContains) => _sqlExpressionFactory.Contains(Jsonb(args[0]), Jsonb(args[1])), nameof(NpgsqlJsonDbFunctionsExtensions.JsonContained) => _sqlExpressionFactory.ContainedBy(Jsonb(args[0]), Jsonb(args[1])), nameof(NpgsqlJsonDbFunctionsExtensions.JsonExists) => _sqlExpressionFactory.MakePostgresBinary(PostgresExpressionType.JsonExists, Jsonb(args[0]), args[1]), nameof(NpgsqlJsonDbFunctionsExtensions.JsonExistAny) => _sqlExpressionFactory.MakePostgresBinary(PostgresExpressionType.JsonExistsAny, Jsonb(args[0]), args[1]), nameof(NpgsqlJsonDbFunctionsExtensions.JsonExistAll) => _sqlExpressionFactory.MakePostgresBinary(PostgresExpressionType.JsonExistsAll, Jsonb(args[0]), args[1]), _ => null });
private SqlExpression TranslateIndexOf( SqlExpression instance, MethodInfo method, SqlExpression searchExpression, SqlExpression?startIndex) { var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, searchExpression) !; searchExpression = _sqlExpressionFactory.ApplyTypeMapping(searchExpression, stringTypeMapping); instance = _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping); var charIndexArguments = new List <SqlExpression> { searchExpression, instance }; if (startIndex is not null) { charIndexArguments.Add(_sqlExpressionFactory.Add(startIndex, _sqlExpressionFactory.Constant(1))); } var argumentsPropagateNullability = Enumerable.Repeat(true, charIndexArguments.Count); SqlExpression charIndexExpression; var storeType = stringTypeMapping.StoreType; if (string.Equals(storeType, "nvarchar(max)", StringComparison.OrdinalIgnoreCase) || string.Equals(storeType, "varchar(max)", StringComparison.OrdinalIgnoreCase)) { charIndexExpression = _sqlExpressionFactory.Function( "CHARINDEX", charIndexArguments, nullable: true, argumentsPropagateNullability, typeof(long)); charIndexExpression = _sqlExpressionFactory.Convert(charIndexExpression, typeof(int)); } else { charIndexExpression = _sqlExpressionFactory.Function( "CHARINDEX", charIndexArguments, nullable: true, argumentsPropagateNullability, method.ReturnType); } charIndexExpression = _sqlExpressionFactory.Subtract(charIndexExpression, _sqlExpressionFactory.Constant(1)); return(_sqlExpressionFactory.Case( new[] { new CaseWhenClause( _sqlExpressionFactory.Equal( searchExpression, _sqlExpressionFactory.Constant(string.Empty, stringTypeMapping)), _sqlExpressionFactory.Constant(0)) }, charIndexExpression)); }
/// <summary> /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will /// return this expression. /// </summary> /// <param name="match">The <see cref="Match" /> property of the result.</param> /// <param name="pattern">The <see cref="Pattern" /> property of the result.</param> /// <param name="escapeChar">The <see cref="EscapeChar" /> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public virtual LikeExpression Update( SqlExpression match, SqlExpression pattern, SqlExpression?escapeChar) => match != Match || pattern != Pattern || escapeChar != EscapeChar ? new LikeExpression(match, pattern, escapeChar, TypeMapping) : this;
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (method.IsGenericMethod && method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) && ValidateValues(arguments[0])) { return(_sqlExpressionFactory.In(RemoveObjectConvert(arguments[1]), arguments[0], negated: false)); } if (arguments.Count == 1 && method.IsContainsMethod() && instance != null && ValidateValues(instance)) { return(_sqlExpressionFactory.In(RemoveObjectConvert(arguments[0]), instance, negated: false)); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) => method.IsGenericMethod && Equals(method.GetGenericMethodDefinition(), _methodInfo) && arguments[2] is SqlConstantExpression constantExpression &&
public CaseExpression( [NotNull] IReadOnlyList <CaseWhenClause> whenClauses, [CanBeNull] SqlExpression?elseResult = null) : base(Check.NotEmpty(whenClauses, nameof(whenClauses))[0].Result.Type, whenClauses[0].Result.TypeMapping) { _whenClauses.AddRange(whenClauses); ElseResult = elseResult; }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) => Equals(member, _count) ? _sqlExpressionFactory.Function( "NumGeometries", new[] { instance ! },
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); SqlExpression?modifier = null; if (_addMilliseconds.Equals(method)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert( _sqlExpressionFactory.Divide( arguments[0], _sqlExpressionFactory.Constant(1000.0)), typeof(string)), _sqlExpressionFactory.Constant(" seconds")); } else if (_addTicks.Equals(method)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert( _sqlExpressionFactory.Divide( arguments[0], _sqlExpressionFactory.Constant((double)TimeSpan.TicksPerDay)), typeof(string)), _sqlExpressionFactory.Constant(" seconds")); } else if (_methodInfoToUnitSuffix.TryGetValue(method, out var unitSuffix)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert(arguments[0], typeof(string)), _sqlExpressionFactory.Constant(unitSuffix)); } if (modifier != null) { return(_sqlExpressionFactory.Function( "rtrim", new SqlExpression[] { _sqlExpressionFactory.Function( "rtrim", new SqlExpression[] { SqliteExpression.Strftime( _sqlExpressionFactory, method.ReturnType, "%Y-%m-%d %H:%M:%f", instance !, new[] { modifier }), _sqlExpressionFactory.Constant("0") },
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) => MemberToFunctionName.TryGetValue(member, out var functionName) ? _sqlExpressionFactory.Function( functionName, new[] { instance ! },