/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void AddParameter(string invariantName, string name, RelationalTypeMapping typeMapping, bool nullable) { Check.NotEmpty(invariantName, nameof(invariantName)); Check.NotEmpty(name, nameof(name)); Check.NotNull(typeMapping, nameof(typeMapping)); _parameters.Add( new TypeMappedRelationalParameter( invariantName, name, typeMapping, nullable)); }
public void CreateParameter_creates_parameter_with_original_values() { var parameterMock = new Mock<DbParameter>(); var commandMock = new Mock<DbCommand>(); commandMock .Protected() .Setup<DbParameter>("CreateDbParameter") .Returns(parameterMock.Object); var columnModificationMock = new Mock<ColumnModification>(); columnModificationMock.Setup(m => m.Property).Returns(new Mock<IProperty>().Object); columnModificationMock.Setup(m => m.OriginalParameterName).Returns("op"); var parameter = new RelationalTypeMapping("s", DbType.String).CreateParameter(commandMock.Object, columnModificationMock.Object, useOriginalValue: true); Assert.Same(parameterMock.Object, parameter); columnModificationMock.Verify(m => m.Value, Times.Never); columnModificationMock.Verify(m => m.OriginalValue, Times.Once); }
public NpgsqlJsonPocoTranslator(NpgsqlSqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; _stringTypeMapping = sqlExpressionFactory.FindMapping(typeof(string)); }
private static Expression CreateGetValueExpression( int index, bool nullable, RelationalTypeMapping typeMapping, Type clrType) { var getMethod = typeMapping.GetDataReaderMethod(); var indexExpression = Expression.Constant(index); Expression valueExpression = Expression.Call( getMethod.DeclaringType != typeof(DbDataReader) ? Expression.Convert(DataReaderParameter, getMethod.DeclaringType) : (Expression)DataReaderParameter, getMethod, indexExpression); valueExpression = typeMapping.CustomizeDataReaderExpression(valueExpression); var converter = typeMapping.Converter; if (converter != null) { if (valueExpression.Type != converter.ProviderClrType) { valueExpression = Expression.Convert(valueExpression, converter.ProviderClrType); } valueExpression = ReplacingExpressionVisitor.Replace( converter.ConvertFromProviderExpression.Parameters.Single(), valueExpression, converter.ConvertFromProviderExpression.Body); } if (valueExpression.Type != clrType) { valueExpression = Expression.Convert(valueExpression, clrType); } //var exceptionParameter // = Expression.Parameter(typeof(Exception), name: "e"); //var property = materializationInfo.Property; //if (detailedErrorsEnabled) //{ // var catchBlock // = Expression // .Catch( // exceptionParameter, // Expression.Call( // _throwReadValueExceptionMethod // .MakeGenericMethod(valueExpression.Type), // exceptionParameter, // Expression.Call( // dataReaderExpression, // _getFieldValueMethod.MakeGenericMethod(typeof(object)), // indexExpression), // Expression.Constant(property, typeof(IPropertyBase)))); // valueExpression = Expression.TryCatch(valueExpression, catchBlock); //} //if (box && valueExpression.Type.GetTypeInfo().IsValueType) //{ // valueExpression = Expression.Convert(valueExpression, typeof(object)); //} if (nullable) { valueExpression = Expression.Condition( Expression.Call(DataReaderParameter, _isDbNullMethod, indexExpression), Expression.Default(valueExpression.Type), valueExpression); } return(valueExpression); }
public override Expression Visit(Expression expression) { if (expression is InExpression inExpression && inExpression.Values != null) { var inValues = new List <object>(); var hasNullValue = false; RelationalTypeMapping typeMapping = null; switch (inExpression.Values) { case SqlConstantExpression sqlConstant: { typeMapping = sqlConstant.TypeMapping; var values = (IEnumerable)sqlConstant.Value; foreach (var value in values) { if (value == null) { hasNullValue = true; continue; } inValues.Add(value); } break; } case SqlParameterExpression sqlParameter: { typeMapping = sqlParameter.TypeMapping; var values = (IEnumerable)_parametersValues[sqlParameter.Name]; foreach (var value in values) { if (value == null) { hasNullValue = true; continue; } inValues.Add(value); } break; } } var updatedInExpression = inValues.Count > 0 ? _sqlExpressionFactory.In( (SqlExpression)Visit(inExpression.Item), _sqlExpressionFactory.Constant(inValues, typeMapping), inExpression.IsNegated) : null; var nullCheckExpression = hasNullValue ? inExpression.IsNegated ? _sqlExpressionFactory.IsNotNull(inExpression.Item) : _sqlExpressionFactory.IsNull(inExpression.Item) : null; if (updatedInExpression != null && nullCheckExpression != null) { return(inExpression.IsNegated ? _sqlExpressionFactory.AndAlso(updatedInExpression, nullCheckExpression) : _sqlExpressionFactory.OrElse(updatedInExpression, nullCheckExpression)); } if (updatedInExpression == null && nullCheckExpression == null) { return(_sqlExpressionFactory.Equal( _sqlExpressionFactory.Constant(true), _sqlExpressionFactory.Constant(inExpression.IsNegated))); } return((SqlExpression)updatedInExpression ?? nullCheckExpression); } return(base.Visit(expression)); }
public override SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) => sqlExpression == null || sqlExpression.TypeMapping != null ? sqlExpression : sqlExpression switch {
internal SqlParameterExpression(ParameterExpression parameterExpression, RelationalTypeMapping typeMapping) : base(parameterExpression.Type, typeMapping) { _parameterExpression = parameterExpression; }
public virtual MySqlJsonTraversalExpression Clone(bool returnsText, Type type, RelationalTypeMapping typeMapping) => new MySqlJsonTraversalExpression(Expression, Path, returnsText, type, typeMapping);
public override SqlFunctionExpression ApplyTypeMapping(RelationalTypeMapping typeMapping) { return(new FbSpacedFunctionExpression(Name, Arguments, IsNullable, ArgumentsPropagateNullability, Type, typeMapping ?? TypeMapping)); }
private NpgsqlArrayArrayTypeMapping(string storeType, RelationalTypeMapping elementMapping, Type arrayType) : this(CreateParameters(storeType, elementMapping, arrayType), elementMapping) { }
protected abstract RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters, RelationalTypeMapping elementMapping);
/// <inheritdoc /> bool IConventionDbFunctionParameterBuilder.CanSetTypeMapping(RelationalTypeMapping typeMapping, bool fromDataAnnotation) => Overrides(fromDataAnnotation, _parameter.GetTypeMappingConfigurationSource()) || _parameter.TypeMapping == typeMapping;
/// <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 override void AddDbParameter(DbCommand command, object?value) => command.Parameters .Add( RelationalTypeMapping .CreateParameter(command, Name, value, IsNullable));
private Expression CreateGetValueExpression( ParameterExpression dbDataReader, int index, bool nullable, RelationalTypeMapping typeMapping, Type clrType) { var getMethod = typeMapping.GetDataReaderMethod(); Expression indexExpression = Expression.Constant(index); if (_indexMapParameter != null) { indexExpression = Expression.ArrayIndex(_indexMapParameter, indexExpression); } Expression valueExpression = Expression.Call( getMethod.DeclaringType != typeof(DbDataReader) ? Expression.Convert(dbDataReader, getMethod.DeclaringType) : (Expression)dbDataReader, getMethod, indexExpression); if (ProjectionColumns != null) { var columnType = valueExpression.Type; if (!columnType.IsValueType || !BufferedDataReader.IsSupportedValueType(columnType)) { columnType = typeof(object); valueExpression = Expression.Convert(valueExpression, typeof(object)); } if (ProjectionColumns[index] == null) { ProjectionColumns[index] = ReaderColumn.Create( columnType, nullable, _indexMapParameter != null ? ((ColumnExpression)_selectExpression.Projection[index].Expression).Name : null, Expression.Lambda( valueExpression, dbDataReader, _indexMapParameter ?? Expression.Parameter(typeof(int[]))).Compile()); } if (getMethod.DeclaringType != typeof(DbDataReader)) { valueExpression = Expression.Call( dbDataReader, RelationalTypeMapping.GetDataReaderMethod(columnType), indexExpression); } } valueExpression = typeMapping.CustomizeDataReaderExpression(valueExpression); var converter = typeMapping.Converter; if (converter != null) { if (valueExpression.Type != converter.ProviderClrType) { valueExpression = Expression.Convert(valueExpression, converter.ProviderClrType); } valueExpression = ReplacingExpressionVisitor.Replace( converter.ConvertFromProviderExpression.Parameters.Single(), valueExpression, converter.ConvertFromProviderExpression.Body); } if (valueExpression.Type != clrType) { valueExpression = Expression.Convert(valueExpression, clrType); } //var exceptionParameter // = Expression.Parameter(typeof(Exception), name: "e"); //var property = materializationInfo.Property; //if (detailedErrorsEnabled) //{ // var catchBlock // = Expression // .Catch( // exceptionParameter, // Expression.Call( // _throwReadValueExceptionMethod // .MakeGenericMethod(valueExpression.Type), // exceptionParameter, // Expression.Call( // dataReaderExpression, // _getFieldValueMethod.MakeGenericMethod(typeof(object)), // indexExpression), // Expression.Constant(property, typeof(IPropertyBase)))); // valueExpression = Expression.TryCatch(valueExpression, catchBlock); //} //if (box && valueExpression.Type.GetTypeInfo().IsValueType) //{ // valueExpression = Expression.Convert(valueExpression, typeof(object)); //} if (nullable) { valueExpression = Expression.Condition( Expression.Call(dbDataReader, _isDbNullMethod, indexExpression), Expression.Default(valueExpression.Type), valueExpression); } return(valueExpression); }
private SqlExpression SimplifyBinaryExpression( ExpressionType operatorType, SqlExpression left, SqlExpression right, RelationalTypeMapping typeMapping) { switch (operatorType) { case ExpressionType.AndAlso: case ExpressionType.OrElse: var leftUnary = left as SqlUnaryExpression; var rightUnary = right as SqlUnaryExpression; if (leftUnary != null && rightUnary != null && (leftUnary.OperatorType == ExpressionType.Equal || leftUnary.OperatorType == ExpressionType.NotEqual) && (rightUnary.OperatorType == ExpressionType.Equal || rightUnary.OperatorType == ExpressionType.NotEqual) && leftUnary.Operand.Equals(rightUnary.Operand)) { // a is null || a is null -> a is null // a is not null || a is not null -> a is not null // a is null && a is null -> a is null // a is not null && a is not null -> a is not null // a is null || a is not null -> true // a is null && a is not null -> false return(leftUnary.OperatorType == rightUnary.OperatorType ? (SqlExpression)leftUnary : _sqlExpressionFactory.Constant(operatorType == ExpressionType.OrElse, typeMapping)); } return(SimplifyLogicalSqlBinaryExpression( operatorType, left, right, typeMapping)); case ExpressionType.Equal: case ExpressionType.NotEqual: var leftConstant = left as SqlConstantExpression; var rightConstant = right as SqlConstantExpression; var leftNullConstant = leftConstant != null && leftConstant.Value == null; var rightNullConstant = rightConstant != null && rightConstant.Value == null; if (leftNullConstant || rightNullConstant) { return(SimplifyNullComparisonExpression( operatorType, left, right, leftNullConstant, rightNullConstant, typeMapping)); } var leftBoolValue = left.Type == typeof(bool) ? (bool?)leftConstant?.Value : null; var rightBoolValue = right.Type == typeof(bool) ? (bool?)rightConstant?.Value : null; if (leftBoolValue != null || rightBoolValue != null) { return(SimplifyBoolConstantComparisonExpression( operatorType, left, right, leftBoolValue, rightBoolValue, typeMapping)); } // only works when a is not nullable // a == a -> true // a != a -> false if ((left is LikeExpression || left is ColumnExpression columnExpression && !columnExpression.IsNullable) && left.Equals(right)) { return(_sqlExpressionFactory.Constant(operatorType == ExpressionType.Equal, typeMapping)); } break; } return(_sqlExpressionFactory.MakeBinary(operatorType, left, right, typeMapping) !); }
private SqlExpression SimplifyNullNotNullExpression( ExpressionType operatorType, SqlExpression operand, Type type, RelationalTypeMapping typeMapping) { switch (operatorType) { case ExpressionType.Equal: case ExpressionType.NotEqual: switch (operand) { case SqlConstantExpression constantOperand: return(SqlExpressionFactory.Constant( operatorType == ExpressionType.Equal ? constantOperand.Value == null : constantOperand.Value != null, typeMapping)); case ColumnExpression columnOperand when !columnOperand.IsNullable: return(SqlExpressionFactory.Constant(operatorType == ExpressionType.NotEqual, typeMapping)); case SqlUnaryExpression sqlUnaryOperand: if (sqlUnaryOperand.OperatorType == ExpressionType.Convert || sqlUnaryOperand.OperatorType == ExpressionType.Not || sqlUnaryOperand.OperatorType == ExpressionType.Negate) { // op(a) is null -> a is null // op(a) is not null -> a is not null return(SimplifyNullNotNullExpression(operatorType, sqlUnaryOperand.Operand, type, typeMapping)); } if (sqlUnaryOperand.OperatorType == ExpressionType.Equal || sqlUnaryOperand.OperatorType == ExpressionType.NotEqual) { // (a is null) is null -> false // (a is not null) is null -> false // (a is null) is not null -> true // (a is not null) is not null -> true return(SqlExpressionFactory.Constant(operatorType == ExpressionType.NotEqual, typeMapping)); } break; case SqlBinaryExpression sqlBinaryOperand: // in general: // binaryOp(a, b) == null -> a == null || b == null // binaryOp(a, b) != null -> a != null && b != null // for AndAlso, OrElse we can't do this optimization // we could do something like this, but it seems too complicated: // (a && b) == null -> a == null && b != 0 || a != 0 && b == null if (sqlBinaryOperand.OperatorType != ExpressionType.AndAlso && sqlBinaryOperand.OperatorType != ExpressionType.OrElse) { var newLeft = SimplifyNullNotNullExpression(operatorType, sqlBinaryOperand.Left, typeof(bool), typeMapping); var newRight = SimplifyNullNotNullExpression(operatorType, sqlBinaryOperand.Right, typeof(bool), typeMapping); return(SimplifyLogicalSqlBinaryExpression( operatorType == ExpressionType.Equal ? ExpressionType.OrElse : ExpressionType.AndAlso, newLeft, newRight, typeMapping)); } break; case SqlFunctionExpression sqlFunctionExpression when sqlFunctionExpression.IsBuiltIn && string.Equals("COALESCE", sqlFunctionExpression.Name, StringComparison.OrdinalIgnoreCase): // for coalesce: // (a ?? b) == null -> a == null && b == null // (a ?? b) != null -> a != null || b != null var leftArgument = SimplifyNullNotNullExpression( operatorType, sqlFunctionExpression.Arguments[0], typeof(bool), typeMapping); var rightArgument = SimplifyNullNotNullExpression( operatorType, sqlFunctionExpression.Arguments[1], typeof(bool), typeMapping); return(SimplifyLogicalSqlBinaryExpression( operatorType == ExpressionType.Equal ? ExpressionType.AndAlso : ExpressionType.OrElse, leftArgument, rightArgument, typeMapping)); } break; } return(SqlExpressionFactory.MakeUnary(operatorType, operand, type, typeMapping)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> protected override void GenerateLiteralValue(StringBuilder builder, string value, RelationalTypeMapping typeMapping = null) { builder.Append(typeMapping.IsUnicode ? "N'" : "'"); EscapeLiteral(builder, value); builder.Append("'"); }
public SingleDimComparerWithComparer(RelationalTypeMapping elementMapping) : base( (a, b) => Compare(a, b, (ValueComparer <TElem>)elementMapping.Comparer), o => o.GetHashCode(), // TODO: Need to get hash code of elements... source => Snapshot(source, (ValueComparer <TElem>)elementMapping.Comparer)) { }
private static RelationalTypeMapping FilterByClrType(RelationalTypeMapping mapping, RelationalTypeMappingInfo mappingInfo) => mapping != null && (mappingInfo.ClrType == null || mappingInfo.ClrType == mapping.ClrType) ? mapping : null;
/// <summary> /// Creates the default array mapping (i.e. for the single-dimensional CLR array type) /// </summary> public NpgsqlArrayTypeMapping(string storeType, RelationalTypeMapping elementMapping) : this(storeType, elementMapping, elementMapping.ClrType.MakeArrayType()) { }
public virtual MySqlJsonTraversalExpression Append([NotNull] SqlExpression pathComponent, Type returnType, RelationalTypeMapping typeMapping) { var newPath = new SqlExpression[Path.Count + 1]; for (var i = 0; i < Path.Count; i++) { newPath[i] = Path[i]; } newPath[newPath.Length - 1] = pathComponent; return(new MySqlJsonTraversalExpression(Expression, newPath, ReturnsText, returnType, typeMapping)); }
/// <summary> /// Creates the default array mapping (i.e. for the single-dimensional CLR array type) /// </summary> public NpgsqlArrayTypeMapping(RelationalTypeMapping elementMapping, Type arrayType) : this(elementMapping.StoreType + "[]", elementMapping, arrayType) { }
public SqlExpression ApplyTypeMapping(RelationalTypeMapping typeMapping) => new SqlParameterExpression(_parameterExpression, typeMapping);
NpgsqlArrayTypeMapping(string storeType, RelationalTypeMapping elementMapping, Type arrayType) : this(new RelationalTypeMappingParameters( new CoreTypeMappingParameters(arrayType, null, CreateComparer(elementMapping, arrayType)), storeType ), elementMapping) { }
public MySqlSqlExpressionFactory(SqlExpressionFactoryDependencies dependencies) : base(dependencies) { _typeMappingSource = dependencies.TypeMappingSource; _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool)); }
protected NpgsqlArrayTypeMapping(RelationalTypeMappingParameters parameters, RelationalTypeMapping elementMapping) : base(parameters) => ElementMapping = elementMapping;
public FbExtractExpression(string part, SqlExpression valueExpression, RelationalTypeMapping typeMapping) : base("EXTRACT", Array.Empty <SqlExpression>(), true, Array.Empty <bool>(), typeof(int), typeMapping) { Part = part; ValueExpression = valueExpression; }
public static SqlFunctionExpression CreateNiladic( SqlExpression instance, string name, Type type, RelationalTypeMapping typeMapping) => new SqlFunctionExpression(instance, schema: null, name, niladic: true, arguments: null, builtIn: true, type, typeMapping);
public LikeExpression(SqlExpression match, SqlExpression pattern, SqlExpression escapeChar, RelationalTypeMapping typeMapping) : base(typeof(bool), typeMapping) { Match = match; Pattern = pattern; EscapeChar = escapeChar; }
public static SqlFunctionExpression Create( string name, IEnumerable <SqlExpression> arguments, Type type, RelationalTypeMapping typeMapping) => new SqlFunctionExpression(instance: null, schema: null, name, niladic: false, arguments, builtIn: true, type, typeMapping);
private SqlExpression SimplifyUnaryExpression( ExpressionType operatorType, SqlExpression operand, Type type, RelationalTypeMapping typeMapping) { switch (operatorType) { case ExpressionType.Not when type == typeof(bool) || type == typeof(bool?): { switch (operand) { // !(true) -> false // !(false) -> true case SqlConstantExpression constantOperand when constantOperand.Value is bool value: { return(SqlExpressionFactory.Constant(!value, typeMapping)); } case InExpression inOperand: return(inOperand.Negate()); case SqlUnaryExpression unaryOperand: switch (unaryOperand.OperatorType) { // !(!a) -> a case ExpressionType.Not: return(unaryOperand.Operand); //!(a IS NULL) -> a IS NOT NULL case ExpressionType.Equal: return(SqlExpressionFactory.IsNotNull(unaryOperand.Operand)); //!(a IS NOT NULL) -> a IS NULL case ExpressionType.NotEqual: return(SqlExpressionFactory.IsNull(unaryOperand.Operand)); } break; case SqlBinaryExpression binaryOperand: { // De Morgan's if (binaryOperand.OperatorType == ExpressionType.AndAlso || binaryOperand.OperatorType == ExpressionType.OrElse) { var newLeft = SimplifyUnaryExpression(ExpressionType.Not, binaryOperand.Left, type, typeMapping); var newRight = SimplifyUnaryExpression(ExpressionType.Not, binaryOperand.Right, type, typeMapping); return(SimplifyLogicalSqlBinaryExpression( binaryOperand.OperatorType == ExpressionType.AndAlso ? ExpressionType.OrElse : ExpressionType.AndAlso, newLeft, newRight, binaryOperand.TypeMapping)); } // those optimizations are only valid in 2-value logic // they are safe to do here because if we apply null semantics // because null semantics removes possibility of nulls in the tree when the comparison is wrapped around NOT if (!_useRelationalNulls && TryNegate(binaryOperand.OperatorType, out var negated)) { return(SimplifyBinaryExpression( negated, binaryOperand.Left, binaryOperand.Right, binaryOperand.TypeMapping)); } } break; } break; } case ExpressionType.Equal: case ExpressionType.NotEqual: return(SimplifyNullNotNullExpression( operatorType, operand, type, typeMapping)); } return(SqlExpressionFactory.MakeUnary(operatorType, operand, type, typeMapping)); }
public RowNumberExpression( IReadOnlyList <SqlExpression> partitions, IReadOnlyList <OrderingExpression> orderings, RelationalTypeMapping typeMapping) : base(typeof(long), typeMapping) { Check.NotEmpty(orderings, nameof(orderings)); Partitions = partitions; Orderings = orderings; }
public FbSpacedFunctionExpression(string name, IEnumerable <SqlExpression> arguments, bool nullable, IEnumerable <bool> argumentsPropagateNullability, Type type, RelationalTypeMapping typeMapping) : base(name, arguments, nullable, argumentsPropagateNullability, type, typeMapping) { }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> protected override string GenerateLiteralValue(string value, RelationalTypeMapping typeMapping = null) => typeMapping == null || typeMapping.IsUnicode ? $"N'{EscapeLiteral(Check.NotNull(value, nameof(value)))}'" : $"'{EscapeLiteral(Check.NotNull(value, nameof(value)))}'";