// <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);
        }
Beispiel #2
0
        // <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;
                    }
                }
            }
        }
Beispiel #5
0
 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;
        }
Beispiel #8
0
        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;
        }
Beispiel #9
0
            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);
            }
Beispiel #10
0
 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);
 }
Beispiel #11
0
        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);
        }