示例#1
0
        /// <summary>
        ///     Factory method for creating a type usage for underlying type of enum type usage.
        /// </summary>
        /// <param name="enumTypeUsage"> Enum type usage used to create an underlying type usage of. </param>
        /// <returns> Type usage for the underlying enum type. </returns>
        internal static TypeUsage CreateEnumUnderlyingTypeUsage(TypeUsage enumTypeUsage)
        {
            DebugCheck.NotNull(enumTypeUsage);
            Debug.Assert(TypeSemantics.IsEnumerationType(enumTypeUsage), "enumTypeUsage is not an enumerated type");

            return(TypeUsage.Create(Helper.GetUnderlyingEdmTypeForEnumType(enumTypeUsage.EdmType), enumTypeUsage.Facets));
        }
示例#2
0
        internal DbConstantExpression(TypeUsage resultType, object value)
            : base(DbExpressionKind.Constant, resultType)
        {
            Debug.Assert(value != null, "DbConstantExpression value cannot be null");
            Debug.Assert(TypeSemantics.IsScalarType(resultType), "DbConstantExpression must have a primitive or enum value");
            Debug.Assert(!value.GetType().IsEnum || TypeSemantics.IsEnumerationType(resultType), "value is an enum while the result type is not of enum type.");
            Debug.Assert(Helper.AsPrimitive(resultType.EdmType).ClrEquivalentType == (value.GetType().IsEnum ? value.GetType().GetEnumUnderlyingType() : value.GetType()),
                         "the type of the value has to match the result type (for enum types only underlying types are compared).");

            // binary values should be cloned before use
            PrimitiveType primitiveType;

            this._shouldCloneValue = TypeHelpers.TryGetEdmType <PrimitiveType>(resultType, out primitiveType) &&
                                     primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary;

            if (this._shouldCloneValue)
            {
                // DevDiv#480416: DbConstantExpression with a binary value is not fully immutable
                //
                this._value = ((byte[])value).Clone();
            }
            else
            {
                this._value = value;
            }
        }
示例#3
0
        internal DbConstantExpression(TypeUsage resultType, object value)
            : base(DbExpressionKind.Constant, resultType)
        {
            DebugCheck.NotNull(value);
            Debug.Assert(TypeSemantics.IsScalarType(resultType), "DbConstantExpression must have a primitive or enum value");
            Debug.Assert(
                !value.GetType().IsEnum() || TypeSemantics.IsEnumerationType(resultType),
                "value is an enum while the result type is not of enum type.");
            Debug.Assert(
                Helper.AsPrimitive(resultType.EdmType).ClrEquivalentType
                == (value.GetType().IsEnum() ? value.GetType().GetEnumUnderlyingType() : value.GetType()),
                "the type of the value has to match the result type (for enum types only underlying types are compared).");

            // binary values should be cloned before use
            PrimitiveType primitiveType;

            _shouldCloneValue = TypeHelpers.TryGetEdmType(resultType, out primitiveType) &&
                                primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary;

            if (_shouldCloneValue)
            {
                // DevDiv#480416: DbConstantExpression with a binary value is not fully immutable
                // CONSIDER: Adding an immutable Binary type or using System.Data.Linq.Binary
                _value = ((byte[])value).Clone();
            }
            else
            {
                _value = value;
            }
        }
 internal static TypeUsage GetPrimitiveTypeUsageForScalar(TypeUsage scalarType)
 {
     if (!TypeSemantics.IsEnumerationType(scalarType))
     {
         return(scalarType);
     }
     return(TypeHelpers.CreateEnumUnderlyingTypeUsage(scalarType));
 }
示例#5
0
        internal MetadataMember ResolveMetadataMemberAccess(MetadataMember qualifier, string name, ErrorContext errCtx)
        {
            var fullName = GetFullName(qualifier.Name, name);

            if (qualifier.MetadataMemberClass
                == MetadataMemberClass.Namespace)
            {
                //
                // Try resolving as a type.
                //
                MetadataType type;
                if (TryGetTypeFromMetadata(fullName, out type))
                {
                    return(type);
                }

                //
                // Try resolving as a function.
                //
                MetadataFunctionGroup function;
                if (TryGetFunctionFromMetadata(qualifier.Name, name, out function))
                {
                    return(function);
                }

                //
                // Otherwise, resolve as a namespace.
                //
                return(new MetadataNamespace(fullName));
            }
            else if (qualifier.MetadataMemberClass
                     == MetadataMemberClass.Type)
            {
                var type = (MetadataType)qualifier;
                if (TypeSemantics.IsEnumerationType(type.TypeUsage))
                {
                    EnumMember member;
                    if (_perspective.TryGetEnumMember(
                            (EnumType)type.TypeUsage.EdmType, name, _parserOptions.NameComparisonCaseInsensitive /*ignoreCase*/, out member))
                    {
                        Debug.Assert(member != null, "member != null");
                        Debug.Assert(
                            _parserOptions.NameComparer.Equals(name, member.Name), "_parserOptions.NameComparer.Equals(name, member.Name)");
                        return(new MetadataEnumMember(fullName, type.TypeUsage, member));
                    }
                    else
                    {
                        var message = Strings.NotAMemberOfType(name, qualifier.Name);
                        throw EntitySqlException.Create(errCtx, message, null);
                    }
                }
            }

            var message1 = Strings.InvalidMetadataMemberClassResolution(
                qualifier.Name, qualifier.MetadataMemberClassName, MetadataNamespace.NamespaceClassName);

            throw EntitySqlException.Create(errCtx, message1, null);
        }
示例#6
0
        /// <summary>
        ///     Gets primitive type usage for <paramref name="scalarType" />.
        /// </summary>
        /// <param name="scalarType"> Primitive or enum type usage. </param>
        /// <returns>
        ///     Primitive type usage for <paramref name="scalarType" /> .
        /// </returns>
        /// <remarks>
        ///     For enum types a new type usage based on the underlying type will be created. For primitive types
        ///     the value passed to the function will be returned.
        /// </remarks>
        internal static TypeUsage GetPrimitiveTypeUsageForScalar(TypeUsage scalarType)
        {
            DebugCheck.NotNull(scalarType);
            Debug.Assert(TypeSemantics.IsScalarType(scalarType), "Primitive or enum type expected.");

            return(TypeSemantics.IsEnumerationType(scalarType)
                       ? CreateEnumUnderlyingTypeUsage(scalarType)
                       : scalarType);
        }
        private static string GetTypeUsageToken(TypeUsage type)
        {
            string result = null;

            // Dev10#537010: EntityCommand false positive cache hits caused by insufficient parameter type information in cache key
            // Ensure String types are correctly differentiated.
            if (ReferenceEquals(type, DbTypeMap.AnsiString))
            {
                result = "AnsiString";
            }
            else if (ReferenceEquals(type, DbTypeMap.AnsiStringFixedLength))
            {
                result = "AnsiStringFixedLength";
            }
            else if (ReferenceEquals(type, DbTypeMap.String))
            {
                result = "String";
            }
            else if (ReferenceEquals(type, DbTypeMap.StringFixedLength))
            {
                result = "StringFixedLength";
            }
            else if (ReferenceEquals(type, DbTypeMap.Xml))
            {
                // Xml is currently mapped to (unicode, variable-length) string, so the TypeUsage
                // given to the provider is actually a String TypeUsage.
                Debug.Assert(
                    TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String),
                    "Update GetTypeUsageToken to return 'Xml' for Xml parameters");
                result = "String";
            }
            else if (TypeSemantics.IsEnumerationType(type))
            {
                result = type.EdmType.FullName;
            }
            else
            {
                // String/Xml TypeUsages are the only DbType-derived TypeUsages that carry meaningful facets.
                // Otherwise, the primitive type name is a sufficient token (note that full name is not required
                // since model types always have the 'Edm' namespace).
                Debug.Assert(TypeSemantics.IsPrimitiveType(type), "EntityParameter TypeUsage not a primitive type?");
                Debug.Assert(
                    !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String),
                    "String TypeUsage not derived from DbType.AnsiString, AnsiString, String, StringFixedLength or Xml?");
                result = type.EdmType.Name;
            }

            return(result);
        }
示例#8
0
        internal System.Data.Entity.Core.Query.InternalTrees.Node GetInternalTree(
            Command targetIqtCommand,
            IList <System.Data.Entity.Core.Query.InternalTrees.Node> targetIqtArguments)
        {
            if (this.m_internalTreeNode == null)
            {
                DiscriminatorMap discriminatorMap;
                Command          command = ITreeGenerator.Generate(this.GenerateFunctionView(out discriminatorMap), discriminatorMap);
                System.Data.Entity.Core.Query.InternalTrees.Node root = command.Root;
                System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(root.Op.OpType == OpType.PhysicalProject, "Expected a physical projectOp at the root of the tree - found " + (object)root.Op.OpType);
                PhysicalProjectOp op = (PhysicalProjectOp)root.Op;
                System.Data.Entity.Core.Query.InternalTrees.Node child0 = root.Child0;
                command.DisableVarVecEnumCaching();
                System.Data.Entity.Core.Query.InternalTrees.Node relOpNode = child0;
                Var computedVar = op.Outputs[0];
                if (!Command.EqualTypes(op.ColumnMap.Type, this.FunctionImport.ReturnParameter.TypeUsage))
                {
                    TypeUsage typeUsage = ((CollectionType)this.FunctionImport.ReturnParameter.TypeUsage.EdmType).TypeUsage;
                    System.Data.Entity.Core.Query.InternalTrees.Node node1          = command.CreateNode((Op)command.CreateVarRefOp(computedVar));
                    System.Data.Entity.Core.Query.InternalTrees.Node node2          = command.CreateNode((Op)command.CreateSoftCastOp(typeUsage), node1);
                    System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(node2, out computedVar);
                    ProjectOp projectOp = command.CreateProjectOp(computedVar);
                    relOpNode = command.CreateNode((Op)projectOp, relOpNode, varDefListNode);
                }
                this.m_internalTreeNode = command.BuildCollect(relOpNode, computedVar);
            }
            Dictionary <string, System.Data.Entity.Core.Query.InternalTrees.Node> viewArguments = new Dictionary <string, System.Data.Entity.Core.Query.InternalTrees.Node>(this.m_commandParameters.Length);

            for (int index = 0; index < this.m_commandParameters.Length; ++index)
            {
                DbParameterReferenceExpression commandParameter       = this.m_commandParameters[index];
                System.Data.Entity.Core.Query.InternalTrees.Node node = targetIqtArguments[index];
                if (TypeSemantics.IsEnumerationType(node.Op.Type))
                {
                    node = targetIqtCommand.CreateNode((Op)targetIqtCommand.CreateSoftCastOp(TypeHelpers.CreateEnumUnderlyingTypeUsage(node.Op.Type)), node);
                }
                viewArguments.Add(commandParameter.ParameterName, node);
            }
            return(FunctionImportMappingComposable.FunctionViewOpCopier.Copy(targetIqtCommand, this.m_internalTreeNode, viewArguments));
        }
示例#9
0
        internal MetadataMember ResolveMetadataMemberAccess(
            MetadataMember qualifier,
            string name,
            ErrorContext errCtx)
        {
            string fullName = TypeResolver.GetFullName(qualifier.Name, name);

            if (qualifier.MetadataMemberClass == MetadataMemberClass.Namespace)
            {
                MetadataType type;
                if (this.TryGetTypeFromMetadata(fullName, out type))
                {
                    return((MetadataMember)type);
                }
                MetadataFunctionGroup functionGroup;
                if (this.TryGetFunctionFromMetadata(qualifier.Name, name, out functionGroup))
                {
                    return((MetadataMember)functionGroup);
                }
                return((MetadataMember) new MetadataNamespace(fullName));
            }
            if (qualifier.MetadataMemberClass == MetadataMemberClass.Type)
            {
                MetadataType metadataType = (MetadataType)qualifier;
                if (TypeSemantics.IsEnumerationType(metadataType.TypeUsage))
                {
                    EnumMember outMember;
                    if (this._perspective.TryGetEnumMember((EnumType)metadataType.TypeUsage.EdmType, name, this._parserOptions.NameComparisonCaseInsensitive, out outMember))
                    {
                        return((MetadataMember) new MetadataEnumMember(fullName, metadataType.TypeUsage, outMember));
                    }
                    string errorMessage = Strings.NotAMemberOfType((object)name, (object)qualifier.Name);
                    throw EntitySqlException.Create(errCtx, errorMessage, (Exception)null);
                }
            }
            string errorMessage1 = Strings.InvalidMetadataMemberClassResolution((object)qualifier.Name, (object)qualifier.MetadataMemberClassName, (object)MetadataNamespace.NamespaceClassName);

            throw EntitySqlException.Create(errCtx, errorMessage1, (Exception)null);
        }
        internal Node GetInternalTree(Command targetIqtCommand, IList <Node> targetIqtArguments)
        {
            if (m_internalTreeNode == null)
            {
                DiscriminatorMap discriminatorMap;
                var tree = GenerateFunctionView(out discriminatorMap);
                Debug.Assert(tree != null, "tree != null");

                // Convert this into an ITree first
                var itree       = ITreeGenerator.Generate(tree, discriminatorMap);
                var rootProject = itree.Root; // PhysicalProject(RelInput)
                PlanCompiler.Assert(
                    rootProject.Op.OpType == OpType.PhysicalProject,
                    "Expected a physical projectOp at the root of the tree - found " + rootProject.Op.OpType);
                var rootProjectOp = (PhysicalProjectOp)rootProject.Op;
                Debug.Assert(rootProjectOp.Outputs.Count == 1, "rootProjectOp.Outputs.Count == 1");
                var rootInput = rootProject.Child0; // the RelInput in PhysicalProject(RelInput)

                // #554756: VarVec enumerators are not cached on the shared Command instance.
                itree.DisableVarVecEnumCaching();

                // Function import returns a collection, so convert it to a scalar by wrapping into CollectOp.
                var relNode = rootInput;
                var relVar  = rootProjectOp.Outputs[0];
                // ProjectOp does not implement Type property, so get the type from the column map.
                var functionViewType = rootProjectOp.ColumnMap.Type;
                if (!Command.EqualTypes(functionViewType, FunctionImport.ReturnParameter.TypeUsage))
                {
                    Debug.Assert(
                        TypeSemantics.IsPromotableTo(functionViewType, FunctionImport.ReturnParameter.TypeUsage),
                        "Mapping expression result type must be promotable to the c-space function return type.");

                    // Build "relNode = Project(relNode, SoftCast(relVar))"
                    var expectedCollectionType = (CollectionType)FunctionImport.ReturnParameter.TypeUsage.EdmType;
                    var expectedElementType    = expectedCollectionType.TypeUsage;

                    var varRefNode     = itree.CreateNode(itree.CreateVarRefOp(relVar));
                    var castNode       = itree.CreateNode(itree.CreateSoftCastOp(expectedElementType), varRefNode);
                    var varDefListNode = itree.CreateVarDefListNode(castNode, out relVar);

                    var projectOp = itree.CreateProjectOp(relVar);
                    relNode = itree.CreateNode(projectOp, relNode, varDefListNode);
                }

                // Build "Collect(PhysicalProject(relNode))
                m_internalTreeNode = itree.BuildCollect(relNode, relVar);
            }
            Debug.Assert(m_internalTreeNode != null, "m_internalTreeNode != null");

            // Prepare argument replacement dictionary
            Debug.Assert(m_commandParameters.Length == targetIqtArguments.Count, "m_commandParameters.Length == targetIqtArguments.Count");
            var viewArguments = new Dictionary <string, Node>(m_commandParameters.Length);

            for (var i = 0; i < m_commandParameters.Length; ++i)
            {
                var commandParam = m_commandParameters[i];
                var argumentNode = targetIqtArguments[i];

                // If function import parameter is of enum type, the argument value for it will be of enum type. We however have
                // converted enum types to underlying types for m_commandParameters. So we now need to softcast the argument
                // expression to the underlying type as well.
                if (TypeSemantics.IsEnumerationType(argumentNode.Op.Type))
                {
                    argumentNode = targetIqtCommand.CreateNode(
                        targetIqtCommand.CreateSoftCastOp(TypeHelpers.CreateEnumUnderlyingTypeUsage(argumentNode.Op.Type)),
                        argumentNode);
                }

                Debug.Assert(
                    TypeSemantics.IsPromotableTo(argumentNode.Op.Type, commandParam.ResultType),
                    "Argument type must be promotable to parameter type.");

                viewArguments.Add(commandParam.ParameterName, argumentNode);
            }

            return(FunctionViewOpCopier.Copy(targetIqtCommand, m_internalTreeNode, viewArguments));
        }
示例#11
0
 internal static bool IsEnumerationType(TypeUsage type)
 {
     return(TypeSemantics.IsEnumerationType(type));
 }
 private static string GetTypeUsageToken(TypeUsage type)
 {
     return(!object.ReferenceEquals((object)type, (object)DbTypeMap.AnsiString) ? (!object.ReferenceEquals((object)type, (object)DbTypeMap.AnsiStringFixedLength) ? (!object.ReferenceEquals((object)type, (object)DbTypeMap.String) ? (!object.ReferenceEquals((object)type, (object)DbTypeMap.StringFixedLength) ? (!object.ReferenceEquals((object)type, (object)DbTypeMap.Xml) ? (!TypeSemantics.IsEnumerationType(type) ? type.EdmType.Name : type.EdmType.FullName) : "String") : "StringFixedLength") : "String") : "AnsiStringFixedLength") : "AnsiString");
 }