// <summary> // Is the given var guaranteed to be non-nullable with regards to the node // that is currently being processed. // True, if it is listed as such on any on the node infos on any of the // current relop ancestors. // </summary> internal bool IsNonNullable(Var variable) { if (variable.VarType == VarType.Parameter && !TypeSemantics.IsNullable(variable.Type)) { return(true); } foreach (var relOpAncestor in m_relOpAncestors) { // Rules applied to the children of the relOpAncestor may have caused it change. // Thus, if the node is used, it has to have its node info recomputed Command.RecomputeNodeInfo(relOpAncestor); var nodeInfo = Command.GetExtendedNodeInfo(relOpAncestor); if (nodeInfo.NonNullableVisibleDefinitions.IsSet(variable)) { return(true); } else if (nodeInfo.LocalDefinitions.IsSet(variable)) { //The var is defined on this ancestor but is not non-nullable, // therefore there is no need to further check other ancestors return(false); } } return(false); }
// <summary> // Determine whether the given CLR type is legal for an ObjectParameter or constant // DbExpression. // </summary> private bool TryGetTypeUsageForTerminal(Expression expression, out TypeUsage typeUsage) { DebugCheck.NotNull(expression); var type = expression.Type; if (_rootContext.Perspective.TryGetTypeByName( TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, // bIgnoreCase out typeUsage) && (TypeSemantics.IsScalarType(typeUsage))) { if (expression.NodeType == ExpressionType.Convert) { type = ((UnaryExpression)expression).Operand.Type; } if (type.IsValueType && Nullable.GetUnderlyingType(type) == null && TypeSemantics.IsNullable(typeUsage)) { typeUsage = typeUsage.ShallowCopy( new FacetValues { Nullable = false }); } return(true); } typeUsage = null; return(false); }
// <summary> // Determine whether the given CLR type is legal for an ObjectParameter or constant // DbExpression. // </summary> private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage) { DebugCheck.NotNull(type); if (_rootContext.Perspective.TryGetTypeByName( TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, // bIgnoreCase out typeUsage) && (TypeSemantics.IsScalarType(typeUsage))) { if (type.IsValueType && Nullable.GetUnderlyingType(type) == null && TypeSemantics.IsNullable(typeUsage)) { typeUsage = typeUsage.ShallowCopy( new FacetValues { Nullable = false }); } return(true); } typeUsage = null; return(false); }
internal static void PopulateParameterFromTypeUsage(DbParameter parameter, TypeUsage type, bool isOutParam) { EntityUtil.CheckArgumentNull(parameter, "parameter"); EntityUtil.CheckArgumentNull(type, "type"); // parameter.IsNullable - from the NullableConstraintAttribute value parameter.IsNullable = TypeSemantics.IsNullable(type); // parameter.ParameterName - set by the caller; // parameter.SourceColumn - not applicable until we have a data adapter; // parameter.SourceColumnNullMapping - not applicable until we have a data adapter; // parameter.SourceVersion - not applicable until we have a data adapter; // parameter.Value - left unset; // parameter.DbType - determined by the TypeMapping; // parameter.Precision - from the TypeMapping; // parameter.Scale - from the TypeMapping; // parameter.Size - from the TypeMapping; // type.EdmType may not be a primitive type here - e.g. the user specified // a complex or entity type when creating an ObjectParameter instance. To keep // the same behavior we had in previous versions we let it through here. We will // throw an exception later when actually invoking the stored procedure where we // don't allow parameters that are non-primitive. if (Helper.IsPrimitiveType(type.EdmType)) { DbType dbType; if (TryGetDbTypeFromPrimitiveType((PrimitiveType)type.EdmType, out dbType)) { switch (dbType) { case DbType.Binary: PopulateBinaryParameter(parameter, type, dbType, isOutParam); break; case DbType.DateTime: case DbType.Time: case DbType.DateTimeOffset: PopulateDateTimeParameter(parameter, type, dbType); break; case DbType.Decimal: PopulateDecimalParameter(parameter, type, dbType); break; case DbType.String: PopulateStringParameter(parameter, type, isOutParam); break; default: parameter.DbType = dbType; break; } } } }
internal DbExpression(DbExpressionKind kind, TypeUsage type, bool forceNullable = true) { DbExpression.CheckExpressionKind(kind); this._kind = kind; if (forceNullable && !TypeSemantics.IsNullable(type)) { type = type.ShallowCopy(new FacetValues() { Nullable = (FacetValueContainer <bool?>) new bool?(true) }); } this._type = type; }
internal MemberInformation( int ordinal, int?entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember) { this.Ordinal = ordinal; this.EntityKeyOrdinal = entityKeyOrdinal; this.Flags = flags; this.Member = member; this.IsServerGenerated = isServerGenerated; this.CheckIsNotNull = !TypeSemantics.IsNullable(member) && (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType); }
internal DbExpression(DbExpressionKind kind, TypeUsage type) { CheckExpressionKind(kind); _kind = kind; Debug.Assert(type != null, string.Format(CultureInfo.InvariantCulture, "{0}.Type is null in DbExpression constructor", this.GetType().Name)); if (!TypeSemantics.IsNullable(type)) { type = type.ShallowCopy(new FacetValues { Nullable = true }); } Debug.Assert(type.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); this._type = type; }
internal DbExpression(DbExpressionKind kind, TypeUsage type, bool forceNullable = true) { CheckExpressionKind(kind); _kind = kind; DebugCheck.NotNull(type); if (forceNullable && !TypeSemantics.IsNullable(type)) { type = type.ShallowCopy( new FacetValues { Nullable = true }); } Debug.Assert(type.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); _type = type; }
internal MemberInformation(int ordinal, int?entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember) { Debug.Assert(entityKeyOrdinal.HasValue == (member.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType && (flags & PropagatorFlags.Key) == PropagatorFlags.Key), "key ordinal should only be provided if this is an entity key property"); this.Ordinal = ordinal; this.EntityKeyOrdinal = entityKeyOrdinal; this.Flags = flags; this.Member = member; this.IsServerGenerated = isServerGenerated; // in two cases, we must check that a member value is not null: // - where the type participates in an isnull condition, nullability constraints must be honored // - for complex types, mapping relies on nullability constraint // - in other cases, nullability does not impact round trippability so we don't check this.CheckIsNotNull = !TypeSemantics.IsNullable(member) && (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType); }
internal bool IsNonNullable(Var variable) { if (variable.VarType == VarType.Parameter && !TypeSemantics.IsNullable(variable.Type)) { return(true); } foreach (System.Data.Entity.Core.Query.InternalTrees.Node relOpAncestor in this.m_relOpAncestors) { this.Command.RecomputeNodeInfo(relOpAncestor); ExtendedNodeInfo extendedNodeInfo = this.Command.GetExtendedNodeInfo(relOpAncestor); if (extendedNodeInfo.NonNullableVisibleDefinitions.IsSet(variable)) { return(true); } if (extendedNodeInfo.LocalDefinitions.IsSet(variable)) { return(false); } } return(false); }
internal static void PopulateParameterFromTypeUsage( DbParameter parameter, TypeUsage type, bool isOutParam) { parameter.IsNullable = TypeSemantics.IsNullable(type); DbType dbType; if (!Helper.IsPrimitiveType(type.EdmType) || !DbCommandDefinition.TryGetDbTypeFromPrimitiveType((PrimitiveType)type.EdmType, out dbType)) { return; } switch (dbType) { case DbType.Binary: DbCommandDefinition.PopulateBinaryParameter(parameter, type, dbType, isOutParam); break; case DbType.DateTime: case DbType.Time: case DbType.DateTimeOffset: DbCommandDefinition.PopulateDateTimeParameter(parameter, type, dbType); break; case DbType.Decimal: DbCommandDefinition.PopulateDecimalParameter(parameter, type, dbType); break; case DbType.String: DbCommandDefinition.PopulateStringParameter(parameter, type, isOutParam); break; default: parameter.DbType = dbType; break; } }
/// <summary> /// Creates a SqlParameter given a name, type, and direction /// </summary> internal static SqlParameter CreateSqlParameter(string name, TypeUsage type, ParameterMode mode, object value, bool preventTruncation, SqlVersion version) { int? size; byte? precision; byte? scale; string udtTypeName; value = EnsureSqlParameterValue(value); SqlParameter result = new SqlParameter(name, value); // .Direction ParameterDirection direction = MetadataHelper.ParameterModeToParameterDirection(mode); if (result.Direction != direction) { result.Direction = direction; } // .Size, .Precision, .Scale and .SqlDbType // output parameters are handled differently (we need to ensure there is space for return // values where the user has not given a specific Size/MaxLength) bool isOutParam = mode != ParameterMode.In; SqlDbType sqlDbType = GetSqlDbType(type, isOutParam, version, out size, out precision, out scale, out udtTypeName); if (result.SqlDbType != sqlDbType) { result.SqlDbType = sqlDbType; } if (sqlDbType == SqlDbType.Udt) { result.UdtTypeName = udtTypeName; } // Note that we overwrite 'facet' parameters where either the value is different or // there is an output parameter. This is because output parameters in SqlClient have their // facets clobbered if they are implicitly set (e.g. if the Size was implicitly set // by setting the value) if (size.HasValue) { // size.HasValue is always true for Output parameters if ((isOutParam || result.Size != size.Value)) { if (preventTruncation && size.Value != -1) { // To prevent truncation, set the Size of the parameter to the larger of either // the declared length or the actual length for the parameter. This allows SQL // Server to complain if a value is too long while preventing cache misses for // values within the range. result.Size = Math.Max(result.Size, size.Value); } else { result.Size = size.Value; } } } else { PrimitiveTypeKind typeKind = MetadataHelper.GetPrimitiveTypeKind(type); if (typeKind == PrimitiveTypeKind.String) { result.Size = GetDefaultStringMaxLength(version, sqlDbType); } else if (typeKind == PrimitiveTypeKind.Binary) { result.Size = GetDefaultBinaryMaxLength(version); } } if (precision.HasValue && (isOutParam || result.Precision != precision.Value)) { result.Precision = precision.Value; } if (scale.HasValue && (isOutParam || result.Scale != scale.Value)) { result.Scale = scale.Value; } // .IsNullable bool isNullable = TypeSemantics.IsNullable(type); if (isOutParam || isNullable != result.IsNullable) { result.IsNullable = isNullable; } return(result); }
// <summary> // Constructs a SqlCeParameter // </summary> internal static DbParameter CreateSqlCeParameter( string name, TypeUsage type, object value, bool ignoreMaxLengthFacet, bool isLocalProvider) { var rdpSqlCeParameter = Type.GetType(RemoteProvider.SqlCeParameter); // No other parameter type is supported. // DebugCheck.NotNull(type); int? size; byte?precision; byte?scale; var result = isLocalProvider ? new SqlCeParameter() : (DbParameter)RemoteProviderHelper.CreateRemoteProviderType(RemoteProvider.SqlCeParameter); result.ParameterName = name; result.Value = value; // .Direction // parameter.Direction - take the default. we don't support output parameters. result.Direction = ParameterDirection.Input; // .Size, .Precision, .Scale and .SqlDbType var sqlDbType = GetSqlDbType(type, out size, out precision, out scale); // Skip guessing the parameter type (only for strings & blobs) if parameter size is not available // Instead, let QP take proper guess at execution time with available details. // if ((null != size) || (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) && !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Binary))) { if (isLocalProvider) { var sqlCeParameter = (SqlCeParameter)result; if (sqlCeParameter.SqlDbType != sqlDbType) { sqlCeParameter.SqlDbType = sqlDbType; } } else { // Remote Provider is loaded by reflection. As SqlDbType is not part of the base interface // We need to access this using reflection only. var rdpType = RemoteProviderHelper.GetRemoteProviderType(RemoteProvider.SqlCeParameter); var rdpInfo = rdpType.GetProperty("SqlDbType"); rdpInfo.SetValue(result, sqlDbType, null); } } // Note that we overwrite 'facet' parameters where either the value is different or // there is an output parameter. This is because output parameters in SqlClient have their // facets clobbered if they are implicitly set (e.g. if the Precision was implicitly set // by setting the value) if (!ignoreMaxLengthFacet && size.HasValue && (result.Size != size.Value)) { result.Size = size.Value; } if (precision.HasValue && (((IDbDataParameter)result).Precision != precision.Value)) { ((IDbDataParameter)result).Precision = precision.Value; } if (scale.HasValue && (((IDbDataParameter)result).Scale != scale.Value)) { ((IDbDataParameter)result).Scale = scale.Value; } // .IsNullable var isNullable = TypeSemantics.IsNullable(type); if (isNullable != result.IsNullable) { result.IsNullable = isNullable; } return(result); }
private bool TryGetTypeUsageForTerminal(Expression expression, out TypeUsage typeUsage) { Type type = expression.Type; if (this._rootContext.Perspective.TryGetTypeByName(TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, out typeUsage) && TypeSemantics.IsScalarType(typeUsage)) { if (expression.NodeType == ExpressionType.Convert) { type = ((UnaryExpression)expression).Operand.Type; } if (type.IsValueType && Nullable.GetUnderlyingType(type) == (Type)null && TypeSemantics.IsNullable(typeUsage)) { typeUsage = typeUsage.ShallowCopy(new FacetValues() { Nullable = (FacetValueContainer <bool?>) new bool?(false) }); } return(true); } typeUsage = (TypeUsage)null; return(false); }