Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / TypeResolver.cs / 1 / TypeResolver.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backup [....] //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql { using System; using System.Globalization; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Data.Common; using System.Data.Metadata.Edm; using System.Data.Entity; ////// Represents Type Resolver Helper in the context of a typespace /// internal sealed class TypeResolver { private TypeUsage _cachedStringType; private TypeUsage _cachedBooleanType; private TypeUsage _cachedInt64Type; private Perspective _perspective; private Dictionary_aliasedNamespaces; private HashSet _namespaces; /// /// Initializes TypeResolver instance /// /// /// internal TypeResolver( Perspective perspective, StringComparer stringComparer ) { EntityUtil.CheckArgumentNull(perspective, "perspective"); _perspective = perspective; _aliasedNamespaces = new Dictionary(stringComparer); _namespaces = new HashSet (stringComparer); } /// /// returns perspective instance /// internal Perspective Perspective { get { return _perspective; } } ////// Add aliased namespace declaration /// /// /// internal bool TryAddAliasedNamespace( string alias, string namespaceName ) { if (_aliasedNamespaces.ContainsKey(alias)) { return false; } _aliasedNamespaces.Add(alias, namespaceName); return true; } ////// Add namespaces declaration /// /// internal bool TryAddNamespace( string namespaceName ) { if (_namespaces.Contains(namespaceName)) { return false; } _namespaces.Add(namespaceName); return true; } ////// returns true if key type is valid for collation /// /// ///internal static bool IsKeyValidForCollation( TypeUsage type ) { return (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) /* && isSearchable */ ); } /// /// returns if a given type is allowed to have method calls /// /// ///internal static bool IsValidTypeForMethodCall( TypeUsage type ) { return (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType); } /// /// returns true if type is string type /// /// ///internal static bool IsStringType( TypeUsage type ) { return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String); } /// /// Checks if a type is boolean /// /// ///internal static bool IsBooleanType( TypeUsage type ) { return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean); } /// /// Checks if two types are sub/super type inclusive /// /// /// ///internal static bool IsSubOrSuperType( TypeUsage type1, TypeUsage type2 ) { return TypeSemantics.IsEquivalent(type1, type2) || type1.IsSubtypeOf(type2) || type2.IsSubtypeOf(type1); } /// /// returns target space Edm.String type /// internal TypeUsage StringType { get { if (null == _cachedStringType) { _cachedStringType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String); } return _cachedStringType; } } ////// returns target space Edm.Booelan type /// internal TypeUsage BooleanType { get { if (null == _cachedBooleanType) { _cachedBooleanType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean); } return _cachedBooleanType; } } ////// returns target space Edm.Int64 type /// internal TypeUsage Int64Type { get { if (null == _cachedInt64Type) { _cachedInt64Type = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64); } return _cachedInt64Type; } } ////// resolves a name as type /// /// /// /// ///TypeUsage internal TypeUsage ResolveNameAsType( string[] names, int countNames, out int matchCount ) { TypeUsage TypeUsage = null; matchCount = 0; // // lookup type in aliased namespaces if aliased // if (names.Length > 1 && (countNames > (names.Length - 1))) { string namespaceName = null; if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetTypeFromMetadata(namespaceName + "." + ConcatStringsWithSeparator(names, '.', 1, countNames - 1), out TypeUsage)) { matchCount = 1; return TypeUsage; } } } string typeName = ConcatStringsWithSeparator(names, '.', 0, countNames); // // Try Full type name // if (TryGetTypeFromMetadata(typeName, out TypeUsage)) { matchCount = 1; return TypeUsage; } // // lookup type in namespaces // TypeUsage matchType; foreach (string ns in _namespaces) { if (TryGetTypeFromMetadata(ns + "." + typeName, out matchType)) { matchCount++; TypeUsage = matchType; } } return TypeUsage; } ////// Resolves a Name as Function /// /// /// /// /// ///internal IList ResolveNameAsFunction( string[] names, bool ignoreCase, out int matchCount, out List foundNamespaces) { IList functionList = null; foundNamespaces = new List (); string namespaceName = null; string functionName = names[names.Length - 1]; matchCount = 0; // // lookup type in aliased namespaces if aliased // if (names.Length > 1) { if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList)) { matchCount = 1; foundNamespaces.Add(namespaceName); return functionList; } } // // Try function full name // namespaceName = ConcatStringsWithSeparator(names, '.', 0, names.Length - 1); if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList)) { matchCount = 1; foundNamespaces.Add(namespaceName); } return functionList; } // // lookup type in namespaces // IList tmpFunctionList; foreach (string ns in _namespaces) { if (TryGetFunctionFromMetadata(functionName, ns, ignoreCase, out tmpFunctionList)) { matchCount++; functionList = tmpFunctionList; foundNamespaces.Add(ns); } } return functionList; } /// /// find name base type /// /// /// /// ///internal TypeUsage ResolveBaseType( string[] names, out int suffixIndex, out int matchCount ) { TypeUsage TypeUsage = null; suffixIndex = 0; matchCount = 0; Debug.Assert(names.Length > 0, "names.Length > 0"); // // lookup in aliased namespaces // if (!TryGetBaseTypeInAliasedNamespaces(names, out TypeUsage, out suffixIndex)) { // // Try Resolve id base type // int idMatchCount = 0; int idSuffix = 0; TypeUsage idTypeUsage; if (TryGetIdentifierBaseType(names, out idTypeUsage, out idSuffix)) { idMatchCount++; } // // lookup in known namespaces // if (TryGetBaseTypeInNamespaces(names, out TypeUsage, out suffixIndex, out matchCount)) { matchCount += idMatchCount; } if (null == TypeUsage) { TypeUsage = idTypeUsage; suffixIndex = idSuffix; matchCount = idMatchCount; } } return TypeUsage; } /// /// given an identifier try to get its base type /// /// /// /// ///internal bool TryGetIdentifierBaseType( string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; System.Text.StringBuilder sb = new System.Text.StringBuilder(); for(int i=0; i < names.Length; i++) { sb.Append(names[i]); if (TryGetTypeFromMetadata(sb.ToString(), out TypeUsage)) { suffixIndex = i; return true; } sb.Append('.'); } return false; } /// /// try resolve base type in aliased namespaces /// /// /// /// ///internal bool TryGetBaseTypeInAliasedNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; if (names.Length > 1) { string namespaceName = null; if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetBaseTypeFromMetadata(namespaceName, TrimNamesPrefix(names, 1), out TypeUsage, out suffixIndex)) { suffixIndex++; return true; } } } return false; } /// /// try resolve Base type in declared non-aliased namespaces /// /// /// /// /// ///internal bool TryGetBaseTypeInNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex, out int matchCount ) { TypeUsage = null; suffixIndex = 0; matchCount = 0; TypeUsage matchType = null; foreach (string nsPrefix in _namespaces) { if (TryGetTypeFromMetadata(nsPrefix + "." + names[0], out TypeUsage)) { matchType = TypeUsage; suffixIndex = 1; matchCount++; } } TypeUsage = matchType; return (matchCount > 0); } /// /// try get base type from metadata /// /// /// /// /// ///internal bool TryGetBaseTypeFromMetadata( string namespaceName, string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; if (TryGetTypeFromMetadata(namespaceName + "." + names[0], out TypeUsage)) { suffixIndex = 1; } return (null != TypeUsage); } /// /// Lookup metadata for a function given its fqn /// /// /// /// /// ///internal bool TryGetFunctionFromMetadata(string name, string namespaceName, bool ignoreCase, out IList functionMetadata) { System.Collections.ObjectModel.ReadOnlyCollection functions = _perspective.GetFunctions(name, namespaceName, ignoreCase); functionMetadata = functions; if (functionMetadata.Count > 0) { return true; } return false; } /// /// Get global function metadata /// /// /// /// /// ///Funciton metadata internal static EdmFunction ResolveFunctionOverloads( IListfunctionsMetadata, IList argTypes, bool isGroupAggregateFunction, out bool isAmbiguous ) { EdmFunction closestFunctionMatch = null; uint maxRank = 0; isAmbiguous = false; Debug.Assert(functionsMetadata.Count > 0, "functionsMetadata.Count must be greater than zero"); for (int i = 0 ; i < functionsMetadata.Count ; i++) { uint rank = RankFunctionParameters(argTypes, functionsMetadata[i].Parameters, isGroupAggregateFunction); if (0 == rank) { continue; } if (rank == maxRank) { isAmbiguous = true; } if (rank > maxRank) { isAmbiguous = false; maxRank = rank; closestFunctionMatch = functionsMetadata[i]; } } return closestFunctionMatch; } /// /// Ranks a list of candidate parameter types against the function formal signature especification /// /// list of candidate parameter types /// function formal signature parameter metadata /// ////// assumes no overload will have more than 10^12 equivalent parameters static internal uint RankFunctionParameters( IListcandidateParams, IList signatureParams, bool isGroupAggregateFunction ) { if (candidateParams.Count != signatureParams.Count) { return 0; } if (0 == candidateParams.Count && 0 == signatureParams.Count) { return 0X40000000; } int equivalenceCount = 0; int promotionCount = 0; for (int i = 0 ; i < candidateParams.Count ; i++) { TypeUsage candidateParamType = candidateParams[i]; TypeUsage formalParamType = signatureParams[i].TypeUsage; // // if function being ranked is a group aggregate, consider the element type // if (isGroupAggregateFunction) { if (!TypeSemantics.IsCollectionType(formalParamType)) { // // 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} // throw EntityUtil.EntitySqlError(Strings.InvalidArgumentTypeForAggregateFunction); } formalParamType = TypeHelpers.GetElementTypeUsage(formalParamType); } if (signatureParams[i].Mode != ParameterMode.In && signatureParams[i].Mode != ParameterMode.InOut) { return 0; } if (TypeSemantics.IsEquivalent(candidateParamType, formalParamType) || (TypeSemantics.IsNullType(candidateParamType) && !TypeSemantics.IsCollectionType(formalParamType))) { equivalenceCount++; } else if (TypeSemantics.IsPromotableTo(candidateParamType, formalParamType)) { promotionCount += GetPromotionRank(candidateParamType, formalParamType); } else { return 0; } } if (equivalenceCount >= 0x8000 || promotionCount >= 0x8000) { throw EntityUtil.EntitySqlError(Strings.TooManyFunctionArguments); } return (uint)((equivalenceCount << 15) | promotionCount); } /// /// Assume that candidateType *IS PROMOTABLE* to formalType /// /// /// ///static private int GetPromotionRank( TypeUsage candidateType, TypeUsage formalType ) { int promotionRank = 1; Debug.Assert(TypeSemantics.IsPromotableTo(candidateType, formalType)); if (TypeSemantics.IsCollectionType(candidateType) && TypeSemantics.IsCollectionType(formalType)) { return GetPromotionRank(TypeHelpers.GetElementTypeUsage(candidateType), TypeHelpers.GetElementTypeUsage(formalType)); } PrimitiveType primitiveCandidateType = candidateType.EdmType as PrimitiveType; PrimitiveType primitiveFormalType = formalType.EdmType as PrimitiveType; if (null != primitiveCandidateType && null != primitiveFormalType) { IList promotionTypes = EdmProviderManifest.Instance.GetPromotionTypes(primitiveCandidateType); if (primitiveCandidateType == primitiveFormalType) { // we don't put the same type in the manifest, so we need to check // if it is the same type. promotionRank = promotionTypes.Count + 1; // +1 because we want to be 1 above the rank of any other possibility } else { Debug.Assert(promotionTypes.Count > 0); Debug.Assert(Helper.IsPromotableTo(promotionTypes, primitiveFormalType) != -1); promotionRank = promotionTypes.Count - Helper.IsPromotableTo(promotionTypes, primitiveFormalType); } } Debug.Assert(promotionRank >= 0, "promotionRank >=0"); return promotionRank; } /// /// Try get fqtn from current metadata typespace /// /// /// ///internal bool TryGetTypeFromMetadata( string typeFullName, out TypeUsage typeUsage ) { return _perspective.TryGetTypeByName(typeFullName, true /* ignore case */, out typeUsage); } /// /// Returns the proper TypeUsage for a given literal expression /// /// ///internal TypeUsage GetLiteralTypeUsage( Literal literal ) { PrimitiveType primitiveType = null; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(literal.Type, out primitiveType)) { throw EntityUtil.EntitySqlError(literal.ErrCtx, System.Data.Entity.Strings.LiteralTypeNotFoundInMetadata(literal.OriginalValue)); } TypeUsage literalTypeUsage = TypeHelpers.GetLiteralTypeUsage(primitiveType.PrimitiveTypeKind, literal.IsUnicodeString); return literalTypeUsage; } /// /// Trims prefix from fqn in array form /// /// /// ///internal static string[] TrimNamesPrefix( string[] names, int startIndex ) { string[] s = new string[names.Length - 1]; for (int i = startIndex ; i < names.Length ; s[i - 1] = names[i], i++) ; return s; } /// /// returns full string /// /// ///static internal string GetFullName( string[] names ) { return ConcatStringsWithSeparator(names, '.', 0 /*startIndex*/, names.Length); } static private string ConcatStringsWithSeparator( string[] names, char separator, int startIndex, int endIndex ) { Debug.Assert(names.Length > 0, "names.Length > 0"); Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex"); Debug.Assert(startIndex >= 0, "startIndex >= 0"); Debug.Assert(startIndex < names.Length, "startIndex < names.Length"); if (startIndex == endIndex) { return names[startIndex]; } StringBuilder sb = new StringBuilder(); sb.Append(names[startIndex]); for (int i = startIndex + 1 ; i < endIndex ; i++) { sb.Append(separator).Append(names[i]); } return sb.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backup [....] //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql { using System; using System.Globalization; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Data.Common; using System.Data.Metadata.Edm; using System.Data.Entity; ////// Represents Type Resolver Helper in the context of a typespace /// internal sealed class TypeResolver { private TypeUsage _cachedStringType; private TypeUsage _cachedBooleanType; private TypeUsage _cachedInt64Type; private Perspective _perspective; private Dictionary_aliasedNamespaces; private HashSet _namespaces; /// /// Initializes TypeResolver instance /// /// /// internal TypeResolver( Perspective perspective, StringComparer stringComparer ) { EntityUtil.CheckArgumentNull(perspective, "perspective"); _perspective = perspective; _aliasedNamespaces = new Dictionary(stringComparer); _namespaces = new HashSet (stringComparer); } /// /// returns perspective instance /// internal Perspective Perspective { get { return _perspective; } } ////// Add aliased namespace declaration /// /// /// internal bool TryAddAliasedNamespace( string alias, string namespaceName ) { if (_aliasedNamespaces.ContainsKey(alias)) { return false; } _aliasedNamespaces.Add(alias, namespaceName); return true; } ////// Add namespaces declaration /// /// internal bool TryAddNamespace( string namespaceName ) { if (_namespaces.Contains(namespaceName)) { return false; } _namespaces.Add(namespaceName); return true; } ////// returns true if key type is valid for collation /// /// ///internal static bool IsKeyValidForCollation( TypeUsage type ) { return (TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) /* && isSearchable */ ); } /// /// returns if a given type is allowed to have method calls /// /// ///internal static bool IsValidTypeForMethodCall( TypeUsage type ) { return (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType); } /// /// returns true if type is string type /// /// ///internal static bool IsStringType( TypeUsage type ) { return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String); } /// /// Checks if a type is boolean /// /// ///internal static bool IsBooleanType( TypeUsage type ) { return TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean); } /// /// Checks if two types are sub/super type inclusive /// /// /// ///internal static bool IsSubOrSuperType( TypeUsage type1, TypeUsage type2 ) { return TypeSemantics.IsEquivalent(type1, type2) || type1.IsSubtypeOf(type2) || type2.IsSubtypeOf(type1); } /// /// returns target space Edm.String type /// internal TypeUsage StringType { get { if (null == _cachedStringType) { _cachedStringType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String); } return _cachedStringType; } } ////// returns target space Edm.Booelan type /// internal TypeUsage BooleanType { get { if (null == _cachedBooleanType) { _cachedBooleanType = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean); } return _cachedBooleanType; } } ////// returns target space Edm.Int64 type /// internal TypeUsage Int64Type { get { if (null == _cachedInt64Type) { _cachedInt64Type = _perspective.MetadataWorkspace.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64); } return _cachedInt64Type; } } ////// resolves a name as type /// /// /// /// ///TypeUsage internal TypeUsage ResolveNameAsType( string[] names, int countNames, out int matchCount ) { TypeUsage TypeUsage = null; matchCount = 0; // // lookup type in aliased namespaces if aliased // if (names.Length > 1 && (countNames > (names.Length - 1))) { string namespaceName = null; if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetTypeFromMetadata(namespaceName + "." + ConcatStringsWithSeparator(names, '.', 1, countNames - 1), out TypeUsage)) { matchCount = 1; return TypeUsage; } } } string typeName = ConcatStringsWithSeparator(names, '.', 0, countNames); // // Try Full type name // if (TryGetTypeFromMetadata(typeName, out TypeUsage)) { matchCount = 1; return TypeUsage; } // // lookup type in namespaces // TypeUsage matchType; foreach (string ns in _namespaces) { if (TryGetTypeFromMetadata(ns + "." + typeName, out matchType)) { matchCount++; TypeUsage = matchType; } } return TypeUsage; } ////// Resolves a Name as Function /// /// /// /// /// ///internal IList ResolveNameAsFunction( string[] names, bool ignoreCase, out int matchCount, out List foundNamespaces) { IList functionList = null; foundNamespaces = new List (); string namespaceName = null; string functionName = names[names.Length - 1]; matchCount = 0; // // lookup type in aliased namespaces if aliased // if (names.Length > 1) { if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList)) { matchCount = 1; foundNamespaces.Add(namespaceName); return functionList; } } // // Try function full name // namespaceName = ConcatStringsWithSeparator(names, '.', 0, names.Length - 1); if (TryGetFunctionFromMetadata(functionName, namespaceName, ignoreCase, out functionList)) { matchCount = 1; foundNamespaces.Add(namespaceName); } return functionList; } // // lookup type in namespaces // IList tmpFunctionList; foreach (string ns in _namespaces) { if (TryGetFunctionFromMetadata(functionName, ns, ignoreCase, out tmpFunctionList)) { matchCount++; functionList = tmpFunctionList; foundNamespaces.Add(ns); } } return functionList; } /// /// find name base type /// /// /// /// ///internal TypeUsage ResolveBaseType( string[] names, out int suffixIndex, out int matchCount ) { TypeUsage TypeUsage = null; suffixIndex = 0; matchCount = 0; Debug.Assert(names.Length > 0, "names.Length > 0"); // // lookup in aliased namespaces // if (!TryGetBaseTypeInAliasedNamespaces(names, out TypeUsage, out suffixIndex)) { // // Try Resolve id base type // int idMatchCount = 0; int idSuffix = 0; TypeUsage idTypeUsage; if (TryGetIdentifierBaseType(names, out idTypeUsage, out idSuffix)) { idMatchCount++; } // // lookup in known namespaces // if (TryGetBaseTypeInNamespaces(names, out TypeUsage, out suffixIndex, out matchCount)) { matchCount += idMatchCount; } if (null == TypeUsage) { TypeUsage = idTypeUsage; suffixIndex = idSuffix; matchCount = idMatchCount; } } return TypeUsage; } /// /// given an identifier try to get its base type /// /// /// /// ///internal bool TryGetIdentifierBaseType( string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; System.Text.StringBuilder sb = new System.Text.StringBuilder(); for(int i=0; i < names.Length; i++) { sb.Append(names[i]); if (TryGetTypeFromMetadata(sb.ToString(), out TypeUsage)) { suffixIndex = i; return true; } sb.Append('.'); } return false; } /// /// try resolve base type in aliased namespaces /// /// /// /// ///internal bool TryGetBaseTypeInAliasedNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; if (names.Length > 1) { string namespaceName = null; if (_aliasedNamespaces.TryGetValue(names[0], out namespaceName)) { if (TryGetBaseTypeFromMetadata(namespaceName, TrimNamesPrefix(names, 1), out TypeUsage, out suffixIndex)) { suffixIndex++; return true; } } } return false; } /// /// try resolve Base type in declared non-aliased namespaces /// /// /// /// /// ///internal bool TryGetBaseTypeInNamespaces( string[] names, out TypeUsage TypeUsage, out int suffixIndex, out int matchCount ) { TypeUsage = null; suffixIndex = 0; matchCount = 0; TypeUsage matchType = null; foreach (string nsPrefix in _namespaces) { if (TryGetTypeFromMetadata(nsPrefix + "." + names[0], out TypeUsage)) { matchType = TypeUsage; suffixIndex = 1; matchCount++; } } TypeUsage = matchType; return (matchCount > 0); } /// /// try get base type from metadata /// /// /// /// /// ///internal bool TryGetBaseTypeFromMetadata( string namespaceName, string[] names, out TypeUsage TypeUsage, out int suffixIndex ) { TypeUsage = null; suffixIndex = 0; if (TryGetTypeFromMetadata(namespaceName + "." + names[0], out TypeUsage)) { suffixIndex = 1; } return (null != TypeUsage); } /// /// Lookup metadata for a function given its fqn /// /// /// /// /// ///internal bool TryGetFunctionFromMetadata(string name, string namespaceName, bool ignoreCase, out IList functionMetadata) { System.Collections.ObjectModel.ReadOnlyCollection functions = _perspective.GetFunctions(name, namespaceName, ignoreCase); functionMetadata = functions; if (functionMetadata.Count > 0) { return true; } return false; } /// /// Get global function metadata /// /// /// /// /// ///Funciton metadata internal static EdmFunction ResolveFunctionOverloads( IListfunctionsMetadata, IList argTypes, bool isGroupAggregateFunction, out bool isAmbiguous ) { EdmFunction closestFunctionMatch = null; uint maxRank = 0; isAmbiguous = false; Debug.Assert(functionsMetadata.Count > 0, "functionsMetadata.Count must be greater than zero"); for (int i = 0 ; i < functionsMetadata.Count ; i++) { uint rank = RankFunctionParameters(argTypes, functionsMetadata[i].Parameters, isGroupAggregateFunction); if (0 == rank) { continue; } if (rank == maxRank) { isAmbiguous = true; } if (rank > maxRank) { isAmbiguous = false; maxRank = rank; closestFunctionMatch = functionsMetadata[i]; } } return closestFunctionMatch; } /// /// Ranks a list of candidate parameter types against the function formal signature especification /// /// list of candidate parameter types /// function formal signature parameter metadata /// ////// assumes no overload will have more than 10^12 equivalent parameters static internal uint RankFunctionParameters( IListcandidateParams, IList signatureParams, bool isGroupAggregateFunction ) { if (candidateParams.Count != signatureParams.Count) { return 0; } if (0 == candidateParams.Count && 0 == signatureParams.Count) { return 0X40000000; } int equivalenceCount = 0; int promotionCount = 0; for (int i = 0 ; i < candidateParams.Count ; i++) { TypeUsage candidateParamType = candidateParams[i]; TypeUsage formalParamType = signatureParams[i].TypeUsage; // // if function being ranked is a group aggregate, consider the element type // if (isGroupAggregateFunction) { if (!TypeSemantics.IsCollectionType(formalParamType)) { // // 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} // throw EntityUtil.EntitySqlError(Strings.InvalidArgumentTypeForAggregateFunction); } formalParamType = TypeHelpers.GetElementTypeUsage(formalParamType); } if (signatureParams[i].Mode != ParameterMode.In && signatureParams[i].Mode != ParameterMode.InOut) { return 0; } if (TypeSemantics.IsEquivalent(candidateParamType, formalParamType) || (TypeSemantics.IsNullType(candidateParamType) && !TypeSemantics.IsCollectionType(formalParamType))) { equivalenceCount++; } else if (TypeSemantics.IsPromotableTo(candidateParamType, formalParamType)) { promotionCount += GetPromotionRank(candidateParamType, formalParamType); } else { return 0; } } if (equivalenceCount >= 0x8000 || promotionCount >= 0x8000) { throw EntityUtil.EntitySqlError(Strings.TooManyFunctionArguments); } return (uint)((equivalenceCount << 15) | promotionCount); } /// /// Assume that candidateType *IS PROMOTABLE* to formalType /// /// /// ///static private int GetPromotionRank( TypeUsage candidateType, TypeUsage formalType ) { int promotionRank = 1; Debug.Assert(TypeSemantics.IsPromotableTo(candidateType, formalType)); if (TypeSemantics.IsCollectionType(candidateType) && TypeSemantics.IsCollectionType(formalType)) { return GetPromotionRank(TypeHelpers.GetElementTypeUsage(candidateType), TypeHelpers.GetElementTypeUsage(formalType)); } PrimitiveType primitiveCandidateType = candidateType.EdmType as PrimitiveType; PrimitiveType primitiveFormalType = formalType.EdmType as PrimitiveType; if (null != primitiveCandidateType && null != primitiveFormalType) { IList promotionTypes = EdmProviderManifest.Instance.GetPromotionTypes(primitiveCandidateType); if (primitiveCandidateType == primitiveFormalType) { // we don't put the same type in the manifest, so we need to check // if it is the same type. promotionRank = promotionTypes.Count + 1; // +1 because we want to be 1 above the rank of any other possibility } else { Debug.Assert(promotionTypes.Count > 0); Debug.Assert(Helper.IsPromotableTo(promotionTypes, primitiveFormalType) != -1); promotionRank = promotionTypes.Count - Helper.IsPromotableTo(promotionTypes, primitiveFormalType); } } Debug.Assert(promotionRank >= 0, "promotionRank >=0"); return promotionRank; } /// /// Try get fqtn from current metadata typespace /// /// /// ///internal bool TryGetTypeFromMetadata( string typeFullName, out TypeUsage typeUsage ) { return _perspective.TryGetTypeByName(typeFullName, true /* ignore case */, out typeUsage); } /// /// Returns the proper TypeUsage for a given literal expression /// /// ///internal TypeUsage GetLiteralTypeUsage( Literal literal ) { PrimitiveType primitiveType = null; if (!ClrProviderManifest.Instance.TryGetPrimitiveType(literal.Type, out primitiveType)) { throw EntityUtil.EntitySqlError(literal.ErrCtx, System.Data.Entity.Strings.LiteralTypeNotFoundInMetadata(literal.OriginalValue)); } TypeUsage literalTypeUsage = TypeHelpers.GetLiteralTypeUsage(primitiveType.PrimitiveTypeKind, literal.IsUnicodeString); return literalTypeUsage; } /// /// Trims prefix from fqn in array form /// /// /// ///internal static string[] TrimNamesPrefix( string[] names, int startIndex ) { string[] s = new string[names.Length - 1]; for (int i = startIndex ; i < names.Length ; s[i - 1] = names[i], i++) ; return s; } /// /// returns full string /// /// ///static internal string GetFullName( string[] names ) { return ConcatStringsWithSeparator(names, '.', 0 /*startIndex*/, names.Length); } static private string ConcatStringsWithSeparator( string[] names, char separator, int startIndex, int endIndex ) { Debug.Assert(names.Length > 0, "names.Length > 0"); Debug.Assert(startIndex <= endIndex, "startIndex <= endIndex"); Debug.Assert(startIndex >= 0, "startIndex >= 0"); Debug.Assert(startIndex < names.Length, "startIndex < names.Length"); if (startIndex == endIndex) { return names[startIndex]; } StringBuilder sb = new StringBuilder(); sb.Append(names[startIndex]); for (int i = startIndex + 1 ; i < endIndex ; i++) { sb.Append(separator).Append(names[i]); } return sb.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataContractSerializerElement.cs
- XPathException.cs
- MDIWindowDialog.cs
- RandomNumberGenerator.cs
- InnerItemCollectionView.cs
- CheckableControlBaseAdapter.cs
- SystemWebCachingSectionGroup.cs
- ToolStripItem.cs
- CodeNamespaceCollection.cs
- Package.cs
- TryExpression.cs
- CachedFontFace.cs
- BindingsCollection.cs
- OdbcStatementHandle.cs
- BrowserInteropHelper.cs
- DataServiceRequestOfT.cs
- WinEventQueueItem.cs
- TextSerializer.cs
- TextSpan.cs
- bidPrivateBase.cs
- RegexInterpreter.cs
- Registry.cs
- SocketInformation.cs
- Italic.cs
- WindowInteractionStateTracker.cs
- AutomationEvent.cs
- ProcessModelInfo.cs
- AuthenticationModuleElement.cs
- ImageList.cs
- XPathAncestorIterator.cs
- CapabilitiesState.cs
- SafeFileHandle.cs
- ImmComposition.cs
- UndirectedGraph.cs
- OrderByBuilder.cs
- ActivityTypeCodeDomSerializer.cs
- _TimerThread.cs
- DataGridViewCheckBoxColumn.cs
- LambdaCompiler.Address.cs
- Mutex.cs
- HttpRuntimeSection.cs
- XmlText.cs
- IdleTimeoutMonitor.cs
- TextElementEnumerator.cs
- StrokeNodeOperations2.cs
- Keyboard.cs
- MethodRental.cs
- _BufferOffsetSize.cs
- MimeMultiPart.cs
- ByteFacetDescriptionElement.cs
- OutputCacheSection.cs
- HostedHttpContext.cs
- RowTypeElement.cs
- Html32TextWriter.cs
- SuppressIldasmAttribute.cs
- FormViewInsertEventArgs.cs
- XmlNodeReader.cs
- XmlObjectSerializerReadContextComplexJson.cs
- ProfilePropertySettings.cs
- XmlUrlResolver.cs
- XmlSchemaValidator.cs
- DataGrid.cs
- ToolStripPanelCell.cs
- XmlSchemaComplexContent.cs
- PeerApplicationLaunchInfo.cs
- FieldValue.cs
- contentDescriptor.cs
- GridViewDeletedEventArgs.cs
- HtmlTernaryTree.cs
- AsymmetricSignatureFormatter.cs
- QuotedStringWriteStateInfo.cs
- NodeLabelEditEvent.cs
- XmlSerializerOperationFormatter.cs
- CellIdBoolean.cs
- AppSecurityManager.cs
- CodeGen.cs
- DrawingContext.cs
- ListBox.cs
- ImageBrush.cs
- MessageQueue.cs
- SmtpClient.cs
- StringFormat.cs
- DataSourceCache.cs
- MsmqIntegrationProcessProtocolHandler.cs
- ValidatedControlConverter.cs
- WebBrowserBase.cs
- ColorEditor.cs
- XmlNotation.cs
- SerializableAttribute.cs
- ToolboxComponentsCreatedEventArgs.cs
- Grid.cs
- AnnotationAuthorChangedEventArgs.cs
- securestring.cs
- ComponentRenameEvent.cs
- SecureStringHasher.cs
- ListSortDescription.cs
- UserNameSecurityTokenAuthenticator.cs
- ComIntegrationManifestGenerator.cs
- OdbcConnection.cs
- ChannelServices.cs