コード例 #1
0
        internal static void AssertEdmType(TypeUsage typeUsage)
        {
            EdmType edmType = typeUsage.EdmType;

            if (TypeSemantics.IsCollectionType(typeUsage))
            {
                return;
            }
            if (TypeSemantics.IsStructuralType(typeUsage) && !Helper.IsComplexType(typeUsage.EdmType) && !Helper.IsEntityType(typeUsage.EdmType))
            {
                foreach (EdmMember structuralMember in TypeHelpers.GetDeclaredStructuralMembers(typeUsage))
                {
                    ;
                }
            }
            else
            {
                if (!TypeSemantics.IsPrimitiveType(typeUsage))
                {
                    return;
                }
                PrimitiveType primitiveType = edmType as PrimitiveType;
                if (primitiveType != null && primitiveType.DataSpace != DataSpace.CSpace)
                {
                    throw new NotSupportedException(string.Format((IFormatProvider)CultureInfo.InvariantCulture, "PrimitiveType must be CSpace '{0}'", (object)typeUsage));
                }
            }
        }
コード例 #2
0
        private DbExpression GenerateScalarResultMappingView(DbExpression storeFunctionInvoke)
        {
            DbExpression queryExpression = storeFunctionInvoke;

            CollectionType functionImportReturnType;

            if (!MetadataHelper.TryGetFunctionImportReturnCollectionType(this.FunctionImport, 0, out functionImportReturnType))
            {
                Debug.Fail("Failed to get the result type of the function import.");
            }

            Debug.Assert(TypeSemantics.IsCollectionType(queryExpression.ResultType), "Store function must be TVF (collection expected).");
            var collectionType = (CollectionType)queryExpression.ResultType.EdmType;

            Debug.Assert(TypeSemantics.IsRowType(collectionType.TypeUsage), "Store function must be TVF (collection of rows expected).");
            var rowType = (RowType)collectionType.TypeUsage.EdmType;
            var column  = rowType.Properties[0];

            Func <DbExpression, DbExpression> scalarView = (DbExpression row) =>
            {
                var propertyAccess = row.Property(column);
                if (TypeSemantics.IsEqual(functionImportReturnType.TypeUsage, column.TypeUsage))
                {
                    return(propertyAccess);
                }
                else
                {
                    return(propertyAccess.CastTo(functionImportReturnType.TypeUsage));
                }
            };

            queryExpression = queryExpression.Select(row => scalarView(row));
            return(queryExpression);
        }
コード例 #3
0
        /// <summary>
        ///     Resolve property <paramref name="name" /> off the <paramref name="valueExpr" />.
        /// </summary>
        internal ValueExpression ResolvePropertyAccess(DbExpression valueExpr, string name, ErrorContext errCtx)
        {
            DbExpression propertyExpr;

            if (TryResolveAsPropertyAccess(valueExpr, name, out propertyExpr))
            {
                return(new ValueExpression(propertyExpr));
            }

            if (TryResolveAsRefPropertyAccess(valueExpr, name, errCtx, out propertyExpr))
            {
                return(new ValueExpression(propertyExpr));
            }

            if (TypeSemantics.IsCollectionType(valueExpr.ResultType))
            {
                var message = Strings.NotAMemberOfCollection(name, valueExpr.ResultType.EdmType.FullName);
                throw EntitySqlException.Create(errCtx, message, null);
            }
            else
            {
                var message = Strings.NotAMemberOfType(name, valueExpr.ResultType.EdmType.FullName);
                throw EntitySqlException.Create(errCtx, message, null);
            }
        }
コード例 #4
0
        internal static void AssertEdmType(TypeUsage typeUsage)
        {
            var type = typeUsage.EdmType;

            if (TypeSemantics.IsCollectionType(typeUsage))
            {
                AssertEdmType(GetElementTypeUsage(typeUsage));
            }
            else if (TypeSemantics.IsStructuralType(typeUsage) &&
                     !Helper.IsComplexType(typeUsage.EdmType) &&
                     !Helper.IsEntityType(typeUsage.EdmType))
            {
                foreach (EdmMember m in GetDeclaredStructuralMembers(typeUsage))
                {
                    AssertEdmType(m.TypeUsage);
                }
            }
            else if (TypeSemantics.IsPrimitiveType(typeUsage))
            {
                var pType = type as PrimitiveType;
                if (null != pType)
                {
                    if (pType.DataSpace
                        != DataSpace.CSpace)
                    {
                        throw new NotSupportedException(
                                  String.Format(CultureInfo.InvariantCulture, "PrimitiveType must be CSpace '{0}'", typeUsage));
                    }
                }
            }
        }
コード例 #5
0
 internal static void RequireCollectionArgument <TExpressionType>(DbExpression argument)
 {
     if (!TypeSemantics.IsCollectionType(argument.ResultType))
     {
         throw new ArgumentException(Strings.Cqt_Unary_CollectionRequired((object)typeof(TExpressionType).Name), nameof(argument));
     }
 }
コード例 #6
0
            internal static DbExpression FindNavigationExpression(DbExpression expression, AliasGenerator aliasGenerator, out NavigationInfo navInfo)
            {
                Debug.Assert(TypeSemantics.IsCollectionType(expression.ResultType), "Non-collection input to projection?");

                navInfo = null;

                TypeUsage elementType = ((CollectionType)expression.ResultType.EdmType).TypeUsage;

                if (!TypeSemantics.IsEntityType(elementType) && !TypeSemantics.IsReferenceType(elementType))
                {
                    return(expression);
                }

                RelationshipNavigationVisitor visitor = new RelationshipNavigationVisitor(aliasGenerator);
                DbExpression rewrittenExpression      = visitor.Find(expression);

                if (!object.ReferenceEquals(expression, rewrittenExpression))
                {
                    Debug.Assert(visitor._original != null && visitor._rewritten != null, "Expression was rewritten but no navigation was found?");
                    navInfo = new NavigationInfo(visitor._original, visitor._rewritten);
                    return(rewrittenExpression);
                }
                else
                {
                    return(expression);
                }
            }
コード例 #7
0
 internal static bool IsCollectionAggregateFunction(FunctionOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     if (n.Children.Count == 1 && TypeSemantics.IsCollectionType(n.Child0.Op.Type))
     {
         return(TypeSemantics.IsAggregateFunction(op.Function));
     }
     return(false);
 }
コード例 #8
0
        private Node VisitCollectionFunction(FunctionOp op, Node n)
        {
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsCollectionType(op.Type), "non-TVF function?");
            Node node1 = this.BuildUnnest(n);
            Node node2 = this.m_command.CreateNode((Op)this.m_command.CreatePhysicalProjectOp((node1.Op as UnnestOp).Table.Columns[0]), node1);

            return(this.m_command.CreateNode((Op)this.m_command.CreateCollectOp(n.Op.Type), node2));
        }
コード例 #9
0
        public override Node Visit(FunctionOp op, Node n)
        {
            this.VisitScalarOpDefault((ScalarOp)op, n);
            Node node = !TypeSemantics.IsCollectionType(op.Type) ? (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n) ? n : this.VisitCollectionAggregateFunction(op, n)) : this.VisitCollectionFunction(op, n);

            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(node != null, "failure to construct a functionOp?");
            return(node);
        }
コード例 #10
0
ファイル: ValueExpressions.cs プロジェクト: dox0/DotNet471RS3
        internal DbNewInstanceExpression(TypeUsage type, DbExpressionList args)
            : base(DbExpressionKind.NewInstance, type)
        {
            Debug.Assert(args != null, "DbNewInstanceExpression arguments cannot be null");
            Debug.Assert(args.Count > 0 || TypeSemantics.IsCollectionType(type), "DbNewInstanceExpression requires at least one argument when not creating an empty collection");

            this._elements = args;
        }
コード例 #11
0
        private static bool TryRankFunctionParameters <TFunctionParameterMetadata>(
            IList <TypeUsage> argumentList,
            IList <TypeUsage> flatArgumentList,
            IList <TFunctionParameterMetadata> overloadParamList,
            Func <TFunctionParameterMetadata, TypeUsage> getParameterTypeUsage,
            Func <TFunctionParameterMetadata, ParameterMode> getParameterMode,
            Func <TypeUsage, TypeUsage, IEnumerable <TypeUsage> > flattenParameterType,
            Func <TypeUsage, TypeUsage, bool> isPromotableTo,
            Func <TypeUsage, TypeUsage, bool> isStructurallyEqual,
            bool isGroupAggregateFunction,
            out int totalRank,
            out int[] parameterRanks)
        {
            totalRank      = 0;
            parameterRanks = (int[])null;
            if (argumentList.Count != overloadParamList.Count)
            {
                return(false);
            }
            List <TypeUsage> typeUsageList = new List <TypeUsage>(flatArgumentList.Count);

            for (int index = 0; index < overloadParamList.Count; ++index)
            {
                TypeUsage typeUsage = argumentList[index];
                TypeUsage type      = getParameterTypeUsage(overloadParamList[index]);
                switch (getParameterMode(overloadParamList[index]))
                {
                case ParameterMode.In:
                case ParameterMode.InOut:
                    if (isGroupAggregateFunction)
                    {
                        if (!TypeSemantics.IsCollectionType(type))
                        {
                            throw new EntitySqlException(Strings.InvalidArgumentTypeForAggregateFunction);
                        }
                        type = TypeHelpers.GetElementTypeUsage(type);
                    }
                    if (!isPromotableTo(typeUsage, type))
                    {
                        return(false);
                    }
                    typeUsageList.AddRange(flattenParameterType(type, typeUsage));
                    continue;

                default:
                    return(false);
                }
            }
            parameterRanks = new int[typeUsageList.Count];
            for (int index = 0; index < parameterRanks.Length; ++index)
            {
                int promotionRank = FunctionOverloadResolver.GetPromotionRank(flatArgumentList[index], typeUsageList[index], isPromotableTo, isStructurallyEqual);
                totalRank            += promotionRank;
                parameterRanks[index] = promotionRank;
            }
            return(true);
        }
コード例 #12
0
        private Node BuildUnnest(Node collectionNode)
        {
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(collectionNode.Op.IsScalarOp, "non-scalar usage of Un-nest?");
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsCollectionType(collectionNode.Op.Type), "non-collection usage for Un-nest?");
            Var  computedVar;
            Node varDefNode = this.m_command.CreateVarDefNode(collectionNode, out computedVar);

            return(this.m_command.CreateNode((Op)this.m_command.CreateUnnestOp(computedVar), varDefNode));
        }
コード例 #13
0
        internal DbSortExpression(TypeUsage resultType, DbExpressionBinding input, System.Collections.ObjectModel.ReadOnlyCollection <DbSortClause> sortOrder)
            : base(DbExpressionKind.Sort, resultType)
        {
            Debug.Assert(input != null, "DbSortExpression input cannot be null");
            Debug.Assert(sortOrder != null, "DbSortExpression sort order cannot be null");
            Debug.Assert(TypeSemantics.IsCollectionType(resultType), "DbSkipExpression requires a collection result type");

            this._input = input;
            this._keys  = sortOrder;
        }
コード例 #14
0
        internal DbSortExpression(TypeUsage resultType, DbExpressionBinding input, ReadOnlyCollection <DbSortClause> sortOrder)
            : base(DbExpressionKind.Sort, resultType)
        {
            DebugCheck.NotNull(input);
            DebugCheck.NotNull(sortOrder);
            Debug.Assert(TypeSemantics.IsCollectionType(resultType), "DbSkipExpression requires a collection result type");

            _input = input;
            _keys  = sortOrder;
        }
コード例 #15
0
        /// <summary>
        /// Build up an unnest above a scalar op node
        ///    X => unnest(X)
        /// </summary>
        /// <param name="collectionNode">the scalarop collection node</param>
        /// <returns>the unnest node</returns>
        private Node BuildUnnest(Node collectionNode)
        {
            PlanCompiler.Assert(collectionNode.Op.IsScalarOp, "non-scalar usage of Unnest?");
            PlanCompiler.Assert(TypeSemantics.IsCollectionType(collectionNode.Op.Type), "non-collection usage for Unnest?");

            Var      newVar;
            Node     varDefNode = m_command.CreateVarDefNode(collectionNode, out newVar);
            UnnestOp unnestOp   = m_command.CreateUnnestOp(newVar);
            Node     unnestNode = m_command.CreateNode(unnestOp, varDefNode);

            return(unnestNode);
        }
コード例 #16
0
 /// <summary>
 /// Returns row type if supplied function is a tvf returning Collection(RowType), otherwise null.
 /// </summary>
 internal static RowType GetTvfReturnType(EdmFunction tvf)
 {
     if (tvf.ReturnParameter != null && TypeSemantics.IsCollectionType(tvf.ReturnParameter.TypeUsage))
     {
         var expectedElementTypeUsage = ((CollectionType)tvf.ReturnParameter.TypeUsage.EdmType).TypeUsage;
         if (TypeSemantics.IsRowType(expectedElementTypeUsage))
         {
             return((RowType)expectedElementTypeUsage.EdmType);
         }
     }
     return(null);
 }
コード例 #17
0
 internal static TypeUsage ValidateNewEmptyCollection(
     TypeUsage collectionType,
     out DbExpressionList validElements)
 {
     ArgumentValidation.CheckType(collectionType, nameof(collectionType));
     if (!TypeSemantics.IsCollectionType(collectionType))
     {
         throw new ArgumentException(Strings.Cqt_NewInstance_CollectionTypeRequired, nameof(collectionType));
     }
     validElements = new DbExpressionList((IList <DbExpression>) new DbExpression[0]);
     return(collectionType);
 }
コード例 #18
0
 internal static TypeUsage GetElementTypeUsage(TypeUsage type)
 {
     if (TypeSemantics.IsCollectionType(type))
     {
         return(((CollectionType)type.EdmType).TypeUsage);
     }
     if (TypeSemantics.IsReferenceType(type))
     {
         return(TypeUsage.Create((EdmType)((RefType)type.EdmType).ElementType));
     }
     return((TypeUsage)null);
 }
コード例 #19
0
        /// <summary>
        /// Converts the reference to a TVF as following: Collect(PhysicalProject(Unnest(Func)))
        /// </summary>
        /// <param name="op">current function op</param>
        /// <param name="n">current function subtree</param>
        /// <returns>the new expression that corresponds to the TVF</returns>
        private Node VisitCollectionFunction(FunctionOp op, Node n)
        {
            PlanCompiler.Assert(TypeSemantics.IsCollectionType(op.Type), "non-TVF function?");

            Node              unnestNode  = BuildUnnest(n);
            UnnestOp          unnestOp    = unnestNode.Op as UnnestOp;
            PhysicalProjectOp projectOp   = m_command.CreatePhysicalProjectOp(unnestOp.Table.Columns[0]);
            Node              projectNode = m_command.CreateNode(projectOp, unnestNode);
            CollectOp         collectOp   = m_command.CreateCollectOp(n.Op.Type);
            Node              collectNode = m_command.CreateNode(collectOp, projectNode);

            return(collectNode);
        }
コード例 #20
0
        internal static TypeUsage RequireCollectionArguments <TExpressionType>(
            DbExpression left,
            DbExpression right)
        {
            if (!TypeSemantics.IsCollectionType(left.ResultType) || !TypeSemantics.IsCollectionType(right.ResultType))
            {
                throw new ArgumentException(Strings.Cqt_Binary_CollectionsRequired((object)typeof(TExpressionType).Name));
            }
            TypeUsage commonTypeUsage = TypeHelpers.GetCommonTypeUsage(left.ResultType, right.ResultType);

            if (commonTypeUsage == null)
            {
                throw new ArgumentException(Strings.Cqt_Binary_CollectionsRequired((object)typeof(TExpressionType).Name));
            }
            return(commonTypeUsage);
        }
コード例 #21
0
 /// <summary>
 ///     Recursively add any Row types to the list of types needing a sentinel.
 /// </summary>
 /// <param name="typesNeedingNullableSentinel"> </param>
 /// <param name="typeUsage"> </param>
 private static void AddTypeNeedingNullSentinel(HashSet <string> typesNeedingNullSentinel, TypeUsage typeUsage)
 {
     if (TypeSemantics.IsCollectionType(typeUsage))
     {
         AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage));
     }
     else
     {
         if (TypeSemantics.IsRowType(typeUsage) ||
             TypeSemantics.IsComplexType(typeUsage))
         {
             MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage);
         }
         foreach (EdmMember m in TypeHelpers.GetAllStructuralMembers(typeUsage))
         {
             AddTypeNeedingNullSentinel(typesNeedingNullSentinel, m.TypeUsage);
         }
     }
 }
コード例 #22
0
 private static void AddTypeNeedingNullSentinel(
     HashSet <string> typesNeedingNullSentinel,
     TypeUsage typeUsage)
 {
     if (TypeSemantics.IsCollectionType(typeUsage))
     {
         StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage));
     }
     else
     {
         if (TypeSemantics.IsRowType(typeUsage) || TypeSemantics.IsComplexType(typeUsage))
         {
             StructuredTypeNullabilityAnalyzer.MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage);
         }
         foreach (EdmMember structuralMember in (IEnumerable)TypeHelpers.GetAllStructuralMembers(typeUsage))
         {
             StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, structuralMember.TypeUsage);
         }
     }
 }
コード例 #23
0
        /// <summary>
        /// Pre-processing for a function. Does the default scalar op processing.
        /// If the function returns a collection (TVF), the method converts this expression into
        ///    Collect(PhysicalProject(Unnest(Func))).
        /// If the function is a collection aggregate, converts it into the corresponding group aggregate.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public override Node Visit(FunctionOp op, Node n)
        {
            VisitScalarOpDefault(op, n);
            Node newNode = null;

            // Is this a TVF?
            if (TypeSemantics.IsCollectionType(op.Type))
            {
                newNode = VisitCollectionFunction(op, n);
            }
            // Is this a collection-aggregate function?
            else if (PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                newNode = VisitCollectionAggregateFunction(op, n);
            }
            else
            {
                newNode = n;
            }

            PlanCompiler.Assert(newNode != null, "failure to construct a functionOp?");
            return(newNode);
        }
        private DbExpression GenerateScalarResultMappingView(DbExpression storeFunctionInvoke)
        {
            var queryExpression = storeFunctionInvoke;

            CollectionType functionImportReturnType;

            if (!MetadataHelper.TryGetFunctionImportReturnCollectionType(FunctionImport, 0, out functionImportReturnType))
            {
                Debug.Fail("Failed to get the result type of the function import.");
            }

            Debug.Assert(TypeSemantics.IsCollectionType(queryExpression.ResultType), "Store function must be TVF (collection expected).");
            var collectionType = (CollectionType)queryExpression.ResultType.EdmType;

            Debug.Assert(TypeSemantics.IsRowType(collectionType.TypeUsage), "Store function must be TVF (collection of rows expected).");
            var rowType = (RowType)collectionType.TypeUsage.EdmType;
            var column  = rowType.Properties[0];

            Func <DbExpression, DbExpression> scalarView = row =>
            {
                var propertyAccess = row.Property(column);
                if (TypeSemantics.IsEqual(
                        functionImportReturnType.TypeUsage, column.TypeUsage))
                {
                    return(propertyAccess);
                }
                else
                {
                    return(propertyAccess.CastTo(functionImportReturnType.TypeUsage));
                }
            };

// ReSharper disable ConvertClosureToMethodGroup
            // using Method Group breaks matching the expression in DbExpressionBuilder.ResolveToExpression
            return(queryExpression.Select(row => scalarView(row)));
// ReSharper restore ConvertClosureToMethodGroup
        }
コード例 #25
0
        internal ValueExpression ResolvePropertyAccess(
            DbExpression valueExpr,
            string name,
            ErrorContext errCtx)
        {
            DbExpression propertyExpr;

            if (this.TryResolveAsPropertyAccess(valueExpr, name, out propertyExpr))
            {
                return(new ValueExpression(propertyExpr));
            }
            if (this.TryResolveAsRefPropertyAccess(valueExpr, name, errCtx, out propertyExpr))
            {
                return(new ValueExpression(propertyExpr));
            }
            if (TypeSemantics.IsCollectionType(valueExpr.ResultType))
            {
                string errorMessage = Strings.NotAMemberOfCollection((object)name, (object)valueExpr.ResultType.EdmType.FullName);
                throw EntitySqlException.Create(errCtx, errorMessage, (Exception)null);
            }
            string errorMessage1 = Strings.NotAMemberOfType((object)name, (object)valueExpr.ResultType.EdmType.FullName);

            throw EntitySqlException.Create(errCtx, errorMessage1, (Exception)null);
        }
コード例 #26
0
 protected static void AssertCollectionType(TypeUsage type)
 {
     Assert(TypeSemantics.IsCollectionType(type), "Type Mismatch: Expected Collection type: Found {0}", TypeHelpers.GetFullName(type));
 }
コード例 #27
0
ファイル: BasicValidator.cs プロジェクト: dotnet/ef6tools
 protected static void AssertCollectionType(TypeUsage type)
 {
     Assert(
         TypeSemantics.IsCollectionType(type), "Type Mismatch: Expected Collection type: Found {0}", type.ToString());
 }
コード例 #28
0
 internal DbDistinctExpression(TypeUsage resultType, DbExpression argument)
     : base(DbExpressionKind.Distinct, resultType, argument)
 {
     Debug.Assert(TypeSemantics.IsCollectionType(argument.ResultType), "DbDistinctExpression argument must have a collection result type");
 }
コード例 #29
0
 /// <summary>
 ///     Is this function a collection aggregate function. It is, if
 ///     - it has exactly one child
 ///     - that child is a collection type
 ///     - and the function has been marked with the aggregate attribute
 /// </summary>
 /// <param name="op"> the function op </param>
 /// <param name="n"> the current subtree </param>
 /// <returns> true, if this was a collection aggregate function </returns>
 internal static bool IsCollectionAggregateFunction(FunctionOp op, Node n)
 {
     return((n.Children.Count == 1) &&
            TypeSemantics.IsCollectionType(n.Child0.Op.Type) &&
            TypeSemantics.IsAggregateFunction(op.Function));
 }
コード例 #30
0
        // <summary>
        // Check promotability, returns true if argument list is promotable to the overload and overload was successfully ranked, otherwise false.
        // Ranks the overload parameter types against the argument list.
        // </summary>
        // <param name="argumentList"> list of argument types </param>
        // <param name="flatArgumentList"> flattened list of argument types </param>
        // <param name="overloadParamList"> list of overload parameter types </param>
        // <param name="getParameterTypeUsage"> TypeUsage getter for the overload parameters </param>
        // <param name="getParameterMode"> ParameterMode getter for the overload parameters </param>
        // <param name="totalRank"> returns total promotion rank of the overload, 0 if no arguments </param>
        // <param name="parameterRanks"> returns individual promotion ranks of the overload parameters, empty array if no arguments </param>
        private static bool TryRankFunctionParameters <TFunctionParameterMetadata>(
            IList <TypeUsage> argumentList,
            IList <TypeUsage> flatArgumentList,
            IList <TFunctionParameterMetadata> overloadParamList,
            Func <TFunctionParameterMetadata, TypeUsage> getParameterTypeUsage,
            Func <TFunctionParameterMetadata, ParameterMode> getParameterMode,
            Func <TypeUsage, TypeUsage, IEnumerable <TypeUsage> > flattenParameterType,
            Func <TypeUsage, TypeUsage, bool> isPromotableTo,
            Func <TypeUsage, TypeUsage, bool> isStructurallyEqual,
            bool isGroupAggregateFunction,
            out int totalRank,
            out int[] parameterRanks)
        {
            totalRank      = 0;
            parameterRanks = null;

            if (argumentList.Count
                != overloadParamList.Count)
            {
                return(false);
            }

            //
            // Check promotability and flatten the parameter types
            //
            var flatOverloadParamList = new List <TypeUsage>(flatArgumentList.Count);

            for (var i = 0; i < overloadParamList.Count; ++i)
            {
                var argumentType  = argumentList[i];
                var parameterType = getParameterTypeUsage(overloadParamList[i]);

                //
                // Parameter mode must match.
                //
                var parameterMode = getParameterMode(overloadParamList[i]);
                if (parameterMode != ParameterMode.In &&
                    parameterMode != ParameterMode.InOut)
                {
                    return(false);
                }

                //
                // If function being ranked is a group aggregate, consider the element type.
                //
                if (isGroupAggregateFunction)
                {
                    if (!TypeSemantics.IsCollectionType(parameterType))
                    {
                        //
                        // Even though it is the job of metadata to ensure that the provider manifest is consistent.
                        // Ensure that if a function is marked as aggregate, then the argument type must be of collection{GivenType}.
                        //
                        var message = Strings.InvalidArgumentTypeForAggregateFunction;
                        throw new EntitySqlException(message);
                    }
                    parameterType = TypeHelpers.GetElementTypeUsage(parameterType);
                }

                //
                // If argument is not promotable - reject the overload.
                //
                if (!isPromotableTo(argumentType, parameterType))
                {
                    return(false);
                }

                //
                // Flatten the parameter type.
                //
                flatOverloadParamList.AddRange(flattenParameterType(parameterType, argumentType));
            }

            Debug.Assert(flatArgumentList.Count == flatOverloadParamList.Count, "flatArgumentList.Count == flatOverloadParamList.Count");

            //
            // Rank argument promotions
            //
            parameterRanks = new int[flatOverloadParamList.Count];
            for (var i = 0; i < parameterRanks.Length; ++i)
            {
                var rank = GetPromotionRank(flatArgumentList[i], flatOverloadParamList[i], isPromotableTo, isStructurallyEqual);
                totalRank        += rank;
                parameterRanks[i] = rank;
            }

            return(true);
        }