internal static EntitySqlException Create( System.Data.Entity.Core.Common.EntitySql.ErrorContext errCtx, string errorMessage, Exception innerException) { return(EntitySqlException.Create(errCtx.CommandText, errorMessage, errCtx.InputPosition, errCtx.ErrorContextInfo, errCtx.UseContextInfoAsResourceIdentifier, innerException)); }
internal GroupPartitionInfo( GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion) : base(GroupAggregateKind.Partition, groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion) { Debug.Assert(groupPartitionExpr != null, "groupPartitionExpr != null"); }
internal GroupPartitionInfo( GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion) : base(GroupAggregateKind.Partition, groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion) { DebugCheck.NotNull(groupPartitionExpr); }
/// <summary> /// Reports incompatible type error /// </summary> /// <param name="errCtx"> </param> /// <param name="leftType"> </param> /// <param name="rightType"> </param> internal static void ReportIncompatibleCommonType(ErrorContext errCtx, TypeUsage leftType, TypeUsage rightType) { // // 'navigate' through the type structure in order to find where the incompability is // ReportIncompatibleCommonType(errCtx, leftType, rightType, leftType, rightType); // // if we hit this point, throw the generic incompatible type error message // throw EntitySqlException.Create(errCtx, Strings.ArgumentTypesAreIncompatible(leftType.Identity, rightType.Identity), null); }
protected GroupAggregateInfo( GroupAggregateKind aggregateKind, GroupAggregateExpr astNode, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion) { Debug.Assert(aggregateKind != GroupAggregateKind.None, "aggregateKind != GroupAggregateKind.None"); DebugCheck.NotNull(errCtx); DebugCheck.NotNull(definingScopeRegion); AggregateKind = aggregateKind; AstNode = astNode; ErrCtx = errCtx; DefiningScopeRegion = definingScopeRegion; SetContainingAggregate(containingAggregate); }
/// <summary> /// Resolve namespace, type or function <paramref name="name" /> in the <paramref name="metadataMember" /> /// </summary> internal MetadataMember ResolveMetadataMemberAccess(MetadataMember metadataMember, string name, ErrorContext errCtx) { return(TypeResolver.ResolveMetadataMemberAccess(metadataMember, name, errCtx)); }
internal MetadataMember ResolveUnqualifiedName( string name, bool partOfQualifiedName, ErrorContext errCtx) { bool flag1 = partOfQualifiedName && this._resolveLeftMostUnqualifiedNameAsNamespaceOnly; bool flag2 = !partOfQualifiedName; InlineFunctionGroup inlineFunctionGroup; if (!flag1 && flag2 && this.TryGetInlineFunction(name, out inlineFunctionGroup)) { return((MetadataMember)inlineFunctionGroup); } MetadataNamespace metadataNamespace; if (this._aliasedNamespaces.TryGetValue(name, out metadataNamespace)) { return((MetadataMember)metadataNamespace); } if (!flag1) { MetadataType type1 = (MetadataType)null; MetadataFunctionGroup functionGroup1 = (MetadataFunctionGroup)null; if (!this.TryGetTypeFromMetadata(name, out type1) && flag2) { string[] strArray = name.Split('.'); if (strArray.Length > 1 && ((IEnumerable <string>)strArray).All <string>((Func <string, bool>)(p => p.Length > 0))) { string functionName = strArray[strArray.Length - 1]; this.TryGetFunctionFromMetadata(name.Substring(0, name.Length - functionName.Length - 1), functionName, out functionGroup1); } } MetadataNamespace ns2 = (MetadataNamespace)null; foreach (MetadataNamespace ns1 in this._namespaces) { MetadataType type2; if (this.TryGetTypeFromMetadata(TypeResolver.GetFullName(ns1.Name, name), out type2)) { if (type1 != null || functionGroup1 != null) { throw TypeResolver.AmbiguousMetadataMemberName(errCtx, name, ns1, ns2); } type1 = type2; ns2 = ns1; } MetadataFunctionGroup functionGroup2; if (flag2 && this.TryGetFunctionFromMetadata(ns1.Name, name, out functionGroup2)) { if (type1 != null || functionGroup1 != null) { throw TypeResolver.AmbiguousMetadataMemberName(errCtx, name, ns1, ns2); } functionGroup1 = functionGroup2; ns2 = ns1; } } if (type1 != null) { return((MetadataMember)type1); } if (functionGroup1 != null) { return((MetadataMember)functionGroup1); } } return((MetadataMember) new MetadataNamespace(name)); }
/// <summary> /// Resolve entity set or function import <paramref name="name" /> in the <paramref name="entityContainer" /> /// </summary> internal ExpressionResolution ResolveEntityContainerMemberAccess(EntityContainer entityContainer, string name, ErrorContext errCtx) { ExpressionResolution resolution; if (TryResolveEntityContainerMemberAccess(entityContainer, name, out resolution)) { return(resolution); } else { var message = Strings.MemberDoesNotBelongToEntityContainer(name, entityContainer.Name); throw EntitySqlException.Create(errCtx, message, null); } }
internal MetadataMember ResolveUnqualifiedName(string name, bool partOfQualifiedName, ErrorContext errCtx) { DebugCheck.NotEmpty(name); // // In the case of Name1.Name2...NameN and if backward compatibility mode is on, then resolve Name1 as namespace only, ignore any other possible resolutions. // var resolveAsNamespaceOnly = partOfQualifiedName && _resolveLeftMostUnqualifiedNameAsNamespaceOnly; // // In the case of Name1.Name2...NameN, ignore functions while resolving Name1: functions don't have members. // var includeFunctions = !partOfQualifiedName; // // Try resolving as an inline function. // InlineFunctionGroup inlineFunctionGroup; if (!resolveAsNamespaceOnly && includeFunctions && TryGetInlineFunction(name, out inlineFunctionGroup)) { return(inlineFunctionGroup); } // // Try resolving as a namespace alias. // MetadataNamespace aliasedNamespaceImport; if (_aliasedNamespaces.TryGetValue(name, out aliasedNamespaceImport)) { return(aliasedNamespaceImport); } if (!resolveAsNamespaceOnly) { // // Try resolving as a type or functionGroup in the global namespace or as an imported member. // Throw if ambiguous. // MetadataType type = null; MetadataFunctionGroup functionGroup = null; if (!TryGetTypeFromMetadata(name, out type)) { if (includeFunctions) { // // If name looks like a multipart identifier, try resolving it in the global namespace. // Escaped multipart identifiers usually appear in views: select [NS1.NS2.Product](...) from ... // var multipart = name.Split('.'); if (multipart.Length > 1 && multipart.All(p => p.Length > 0)) { var functionName = multipart[multipart.Length - 1]; var namespaceName = name.Substring(0, name.Length - functionName.Length - 1); TryGetFunctionFromMetadata(namespaceName, functionName, out functionGroup); } } } // // Try resolving as an imported member. // MetadataNamespace importedMemberNamespace = null; foreach (var namespaceImport in _namespaces) { var fullName = GetFullName(namespaceImport.Name, name); MetadataType importedType; if (TryGetTypeFromMetadata(fullName, out importedType)) { if (type == null && functionGroup == null) { type = importedType; importedMemberNamespace = namespaceImport; } else { throw AmbiguousMetadataMemberName(errCtx, name, namespaceImport, importedMemberNamespace); } } MetadataFunctionGroup importedFunctionGroup; if (includeFunctions && TryGetFunctionFromMetadata(namespaceImport.Name, name, out importedFunctionGroup)) { if (type == null && functionGroup == null) { functionGroup = importedFunctionGroup; importedMemberNamespace = namespaceImport; } else { throw AmbiguousMetadataMemberName(errCtx, name, namespaceImport, importedMemberNamespace); } } } if (type != null) { return(type); } if (functionGroup != null) { return(functionGroup); } } // // Otherwise, resolve as a namespace. // return(new MetadataNamespace(name)); }
internal FunctionAggregateInfo( MethodExpr methodExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion) : base(GroupAggregateKind.Function, methodExpr, errCtx, containingAggregate, definingScopeRegion) { DebugCheck.NotNull(methodExpr); }
/// <summary> /// Enters processing of a group partition aggregate. /// </summary> internal IDisposable EnterGroupKeyDefinition( GroupAggregateKind aggregateKind, ErrorContext errCtx, out GroupKeyAggregateInfo aggregateInfo) { aggregateInfo = new GroupKeyAggregateInfo(aggregateKind, errCtx, _currentGroupAggregateInfo, CurrentScopeRegion); return(EnterGroupAggregate(aggregateInfo)); }
internal FunctionAggregateInfo( MethodExpr methodExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion) : base(GroupAggregateKind.Function, methodExpr, errCtx, containingAggregate, definingScopeRegion) { Debug.Assert(methodExpr != null, "methodExpr != null"); }
internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { var message = Strings.InvalidGroupIdentifierReference(refName); throw EntitySqlException.Create(errCtx, message, null); }
internal static void ReportAliasAlreadyUsedError(string aliasName, ErrorContext errCtx, string contextMessage) { throw EntitySqlException.Create( errCtx, String.Format(CultureInfo.InvariantCulture, "{0} {1}", Strings.AliasNameAlreadyUsed(aliasName), contextMessage), null); }
internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return(_varRef); }
/// <summary> /// navigates through the type structure to find where the incompatibility happens /// </summary> /// <param name="errCtx"> </param> /// <param name="rootLeftType"> </param> /// <param name="rootRightType"> </param> /// <param name="leftType"> </param> /// <param name="rightType"> </param> private static void ReportIncompatibleCommonType( ErrorContext errCtx, TypeUsage rootLeftType, TypeUsage rootRightType, TypeUsage leftType, TypeUsage rightType) { TypeUsage commonType = null; var isRootType = (rootLeftType == leftType); var errorMessage = String.Empty; if (leftType.EdmType.BuiltInTypeKind != rightType.EdmType.BuiltInTypeKind) { throw EntitySqlException.Create( errCtx, Strings.TypeKindMismatch( GetReadableTypeKind(leftType), GetReadableTypeName(leftType), GetReadableTypeKind(rightType), GetReadableTypeName(rightType)), null); } switch (leftType.EdmType.BuiltInTypeKind) { case BuiltInTypeKind.RowType: var leftRow = (RowType)leftType.EdmType; var rightRow = (RowType)rightType.EdmType; if (leftRow.Members.Count != rightRow.Members.Count) { if (isRootType) { errorMessage = Strings.InvalidRootRowType( GetReadableTypeName(leftRow), GetReadableTypeName(rightRow)); } else { errorMessage = Strings.InvalidRowType( GetReadableTypeName(leftRow), GetReadableTypeName(rootLeftType), GetReadableTypeName(rightRow), GetReadableTypeName(rootRightType)); } throw EntitySqlException.Create(errCtx, errorMessage, null); } for (var i = 0; i < leftRow.Members.Count; i++) { ReportIncompatibleCommonType( errCtx, rootLeftType, rootRightType, leftRow.Members[i].TypeUsage, rightRow.Members[i].TypeUsage); } break; case BuiltInTypeKind.CollectionType: case BuiltInTypeKind.RefType: ReportIncompatibleCommonType( errCtx, rootLeftType, rootRightType, TypeHelpers.GetElementTypeUsage(leftType), TypeHelpers.GetElementTypeUsage(rightType)); break; case BuiltInTypeKind.EntityType: if (!TypeSemantics.TryGetCommonType(leftType, rightType, out commonType)) { if (isRootType) { errorMessage = Strings.InvalidEntityRootTypeArgument( GetReadableTypeName(leftType), GetReadableTypeName(rightType)); } else { errorMessage = Strings.InvalidEntityTypeArgument( GetReadableTypeName(leftType), GetReadableTypeName(rootLeftType), GetReadableTypeName(rightType), GetReadableTypeName(rootRightType)); } throw EntitySqlException.Create(errCtx, errorMessage, null); } break; case BuiltInTypeKind.ComplexType: var leftComplex = (ComplexType)leftType.EdmType; var rightComplex = (ComplexType)rightType.EdmType; if (leftComplex.Members.Count != rightComplex.Members.Count) { if (isRootType) { errorMessage = Strings.InvalidRootComplexType( GetReadableTypeName(leftComplex), GetReadableTypeName(rightComplex)); } else { errorMessage = Strings.InvalidComplexType( GetReadableTypeName(leftComplex), GetReadableTypeName(rootLeftType), GetReadableTypeName(rightComplex), GetReadableTypeName(rootRightType)); } throw EntitySqlException.Create(errCtx, errorMessage, null); } for (var i = 0; i < leftComplex.Members.Count; i++) { ReportIncompatibleCommonType( errCtx, rootLeftType, rootRightType, leftComplex.Members[i].TypeUsage, rightComplex.Members[i].TypeUsage); } break; default: if (!TypeSemantics.TryGetCommonType(leftType, rightType, out commonType)) { if (isRootType) { errorMessage = Strings.InvalidPlaceholderRootTypeArgument( GetReadableTypeKind(leftType), GetReadableTypeName(leftType), GetReadableTypeKind(rightType), GetReadableTypeName(rightType)); } else { errorMessage = Strings.InvalidPlaceholderTypeArgument( GetReadableTypeKind(leftType), GetReadableTypeName(leftType), GetReadableTypeName(rootLeftType), GetReadableTypeKind(rightType), GetReadableTypeName(rightType), GetReadableTypeName(rootRightType)); } throw EntitySqlException.Create(errCtx, errorMessage, null); } break; } }
/// <summary> /// Adds an aliased namespace import. /// </summary> internal void AddAliasedNamespaceImport(string alias, MetadataNamespace @namespace, ErrorContext errCtx) { if (_aliasedNamespaces.ContainsKey(alias)) { var message = Strings.NamespaceAliasAlreadyUsed(alias); throw EntitySqlException.Create(errCtx, message, null); } _aliasedNamespaces.Add(alias, @namespace); }
private static Exception AmbiguousMetadataMemberName(ErrorContext errCtx, string name, MetadataNamespace ns1, MetadataNamespace ns2) { var message = Strings.AmbiguousMetadataMemberName(name, ns1.Name, ns2 != null ? ns2.Name : null); throw EntitySqlException.Create(errCtx, message, null); }
/// <summary> /// Enters processing of a function group aggregate. /// </summary> internal IDisposable EnterFunctionAggregate(MethodExpr methodExpr, ErrorContext errCtx, out FunctionAggregateInfo aggregateInfo) { aggregateInfo = new FunctionAggregateInfo(methodExpr, errCtx, _currentGroupAggregateInfo, CurrentScopeRegion); return(EnterGroupAggregate(aggregateInfo)); }
/// <summary> /// Enters processing of a group partition aggregate. /// </summary> internal IDisposable EnterGroupPartition( GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, out GroupPartitionInfo aggregateInfo) { aggregateInfo = new GroupPartitionInfo(groupPartitionExpr, errCtx, _currentGroupAggregateInfo, CurrentScopeRegion); return(EnterGroupAggregate(aggregateInfo)); }
// <summary> // Initializes a new instance EntityException with an ErrorContext instance and a given error message. // </summary> internal static EntitySqlException Create(ErrorContext errCtx, string errorMessage, Exception innerException) { return Create( errCtx.CommandText, errorMessage, errCtx.InputPosition, errCtx.ErrorContextInfo, errCtx.UseContextInfoAsResourceIdentifier, innerException); }
private static void ReportIncompatibleCommonType( ErrorContext errCtx, TypeUsage rootLeftType, TypeUsage rootRightType, TypeUsage leftType, TypeUsage rightType) { TypeUsage commonType = (TypeUsage)null; bool flag = rootLeftType == leftType; string empty = string.Empty; if (leftType.EdmType.BuiltInTypeKind != rightType.EdmType.BuiltInTypeKind) { throw EntitySqlException.Create(errCtx, Strings.TypeKindMismatch((object)CqlErrorHelper.GetReadableTypeKind(leftType), (object)CqlErrorHelper.GetReadableTypeName(leftType), (object)CqlErrorHelper.GetReadableTypeKind(rightType), (object)CqlErrorHelper.GetReadableTypeName(rightType)), (Exception)null); } switch (leftType.EdmType.BuiltInTypeKind) { case BuiltInTypeKind.CollectionType: case BuiltInTypeKind.RefType: CqlErrorHelper.ReportIncompatibleCommonType(errCtx, rootLeftType, rootRightType, TypeHelpers.GetElementTypeUsage(leftType), TypeHelpers.GetElementTypeUsage(rightType)); break; case BuiltInTypeKind.ComplexType: ComplexType edmType1 = (ComplexType)leftType.EdmType; ComplexType edmType2 = (ComplexType)rightType.EdmType; if (edmType1.Members.Count != edmType2.Members.Count) { string errorMessage = !flag?Strings.InvalidComplexType((object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType1), (object)CqlErrorHelper.GetReadableTypeName(rootLeftType), (object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType2), (object)CqlErrorHelper.GetReadableTypeName(rootRightType)) : Strings.InvalidRootComplexType((object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType1), (object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType2)); throw EntitySqlException.Create(errCtx, errorMessage, (Exception)null); } for (int index = 0; index < edmType1.Members.Count; ++index) { CqlErrorHelper.ReportIncompatibleCommonType(errCtx, rootLeftType, rootRightType, edmType1.Members[index].TypeUsage, edmType2.Members[index].TypeUsage); } break; case BuiltInTypeKind.EntityType: if (TypeSemantics.TryGetCommonType(leftType, rightType, out commonType)) { break; } string errorMessage1 = !flag?Strings.InvalidEntityTypeArgument((object)CqlErrorHelper.GetReadableTypeName(leftType), (object)CqlErrorHelper.GetReadableTypeName(rootLeftType), (object)CqlErrorHelper.GetReadableTypeName(rightType), (object)CqlErrorHelper.GetReadableTypeName(rootRightType)) : Strings.InvalidEntityRootTypeArgument((object)CqlErrorHelper.GetReadableTypeName(leftType), (object)CqlErrorHelper.GetReadableTypeName(rightType)); throw EntitySqlException.Create(errCtx, errorMessage1, (Exception)null); case BuiltInTypeKind.RowType: RowType edmType3 = (RowType)leftType.EdmType; RowType edmType4 = (RowType)rightType.EdmType; if (edmType3.Members.Count != edmType4.Members.Count) { string errorMessage2 = !flag?Strings.InvalidRowType((object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType3), (object)CqlErrorHelper.GetReadableTypeName(rootLeftType), (object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType4), (object)CqlErrorHelper.GetReadableTypeName(rootRightType)) : Strings.InvalidRootRowType((object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType3), (object)CqlErrorHelper.GetReadableTypeName((EdmType)edmType4)); throw EntitySqlException.Create(errCtx, errorMessage2, (Exception)null); } for (int index = 0; index < edmType3.Members.Count; ++index) { CqlErrorHelper.ReportIncompatibleCommonType(errCtx, rootLeftType, rootRightType, edmType3.Members[index].TypeUsage, edmType4.Members[index].TypeUsage); } break; default: if (TypeSemantics.TryGetCommonType(leftType, rightType, out commonType)) { break; } string errorMessage3 = !flag?Strings.InvalidPlaceholderTypeArgument((object)CqlErrorHelper.GetReadableTypeKind(leftType), (object)CqlErrorHelper.GetReadableTypeName(leftType), (object)CqlErrorHelper.GetReadableTypeName(rootLeftType), (object)CqlErrorHelper.GetReadableTypeKind(rightType), (object)CqlErrorHelper.GetReadableTypeName(rightType), (object)CqlErrorHelper.GetReadableTypeName(rootRightType)) : Strings.InvalidPlaceholderRootTypeArgument((object)CqlErrorHelper.GetReadableTypeKind(leftType), (object)CqlErrorHelper.GetReadableTypeName(leftType), (object)CqlErrorHelper.GetReadableTypeKind(rightType), (object)CqlErrorHelper.GetReadableTypeName(rightType)); throw EntitySqlException.Create(errCtx, errorMessage3, (Exception)null); } }
// <summary> // Returns CQT expression corresponding to the scope entry. // </summary> internal abstract DbExpression GetExpression(string refName, ErrorContext errCtx);
internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return(this._varBasedExpression); }
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); }
/// <summary> /// Returns the appropriate expression from a given scope entry. /// May return null for scope entries like <see cref="InvalidGroupInputRefScopeEntry" />. /// </summary> private DbExpression GetExpressionFromScopeEntry(ScopeEntry scopeEntry, int scopeIndex, string varName, ErrorContext errCtx) { // // If // 1) we are in the context of a group aggregate or group key, // 2) and the scopeEntry can have multiple interpretations depending on the aggregation context, // 3) and the defining scope region of the scopeEntry is outer or equal to the defining scope region of the group aggregate, // 4) and the defining scope region of the scopeEntry is not performing conversion of a group key definition, // Then the expression that corresponds to the scopeEntry is either the GroupVarBasedExpression or the GroupAggBasedExpression. // Otherwise the default expression that corresponds to the scopeEntry is provided by scopeEntry.GetExpression(...) call. // // Explanation for #2 from the list above: // A scope entry may have multiple aggregation-context interpretations: // - An expression in the context of a group key definition, obtained by scopeEntry.GetExpression(...); // Example: select k1 from {0} as a group by a%2 as k1 // ^^^ // - An expression in the context of a function aggregate, provided by iGroupExpressionExtendedInfo.GroupVarBasedExpression; // Example: select max( a ) from {0} as a group by a%2 as k1 // ^^^ // - An expression in the context of a group partition, provided by iGroupExpressionExtendedInfo.GroupAggBasedExpression; // Example: select GroupPartition( a ) from {0} as a group by a%2 as k1 // ^^^ // Note that expressions obtained from aggregation-context-dependent scope entries outside of the three contexts mentioned above // will default to the value returned by the scopeEntry.GetExpression(...) call. This value is the same as in the group key definition context. // These expressions have correct result types which enables partial expression validation. // However the contents of the expressions are invalid outside of the group key definitions, hence they can not appear in the final expression tree. // SemanticAnalyzer.ProcessGroupByClause(...) method guarantees that such expressions are only temporarily used during GROUP BY clause processing and // dropped afterwards. // Example: select a, k1 from {0} as a group by a%2 as k1 // ^^^^^ - these expressions are processed twice: once during GROUP BY and then SELECT clause processing, // the expressions obtained during GROUP BY clause processing are dropped and only // the ones obtained during SELECT clause processing are accepted. // // Explanation for #3 from the list above: // - An outer scope entry referenced inside of an aggregate may lift the aggregate to the outer scope region for evaluation, // hence such a scope entry must be interpreted in the aggregation context. See explanation for #4 below for more info. // Example: // // select // (select max(x) from {1} as y) // from {0} as x // // - If a scope entry is defined inside of a group aggregate, then the scope entry is not affected by the aggregate, // hence such a scope entry is not interpreted in the aggregation context. // Example: // // select max( // anyelement( select b from {1} as b ) // ) // from {0} as a group by a %2 as a1 // // In this query the aggregate argument contains a nested query expression. // The nested query references b. Because b is defined inside of the aggregate it is not interpreted in the aggregation context and // the expression for b should not be GroupVar/GroupAgg based, even though the reference to b appears inside of an aggregate. // // Explanation for #4 from the list above: // An aggregate evaluating on a particular scope region defines the interpretation of scope entries defined on that scope region. // In the case when an inner aggregate references a scope entry belonging to the evaluating region of an outer aggregate, the interpretation // of the scope entry is controlled by the outer aggregate, otherwise it is controlled by the inner aggregate. // Example: // // select a1 // from {0} as a group by // anyelement(select value max(a + b) from {1} as b) // as a1 // // In this query the aggregate inside of a1 group key definition, the max(a + b), references scope entry a. // Because a is referenced inside of the group key definition (which serves as an outer aggregate) and the key definition belongs to // the same scope region as a, a is interpreted in the context of the group key definition, not the function aggregate and // the expression for a is obtained by scopeEntry.GetExpression(...) call, not iGroupExpressionExtendedInfo.GroupVarBasedExpression. // var expr = scopeEntry.GetExpression(varName, errCtx); Debug.Assert(expr != null, "scopeEntry.GetExpression(...) returned null"); if (_currentGroupAggregateInfo != null) { // // Make sure defining scope regions agree as described above. // Outer scope region has smaller index value than the inner. // var definingScopeRegionOfScopeEntry = GetDefiningScopeRegion(scopeIndex); if (definingScopeRegionOfScopeEntry.ScopeRegionIndex <= _currentGroupAggregateInfo.DefiningScopeRegion.ScopeRegionIndex) { // // Let the group aggregate know the scope of the scope entry it references. // This affects the scope region that will evaluate the group aggregate. // _currentGroupAggregateInfo.UpdateScopeIndex(scopeIndex, this); var iGroupExpressionExtendedInfo = scopeEntry as IGroupExpressionExtendedInfo; if (iGroupExpressionExtendedInfo != null) { // // Find the aggregate that controls interpretation of the current scope entry. // This would be a containing aggregate with the defining scope region matching definingScopeRegionOfScopeEntry. // If there is no such aggregate, then the current containing aggregate controls interpretation. // GroupAggregateInfo expressionInterpretationContext; for (expressionInterpretationContext = _currentGroupAggregateInfo; expressionInterpretationContext != null && expressionInterpretationContext.DefiningScopeRegion.ScopeRegionIndex >= definingScopeRegionOfScopeEntry.ScopeRegionIndex; expressionInterpretationContext = expressionInterpretationContext.ContainingAggregate) { if (expressionInterpretationContext.DefiningScopeRegion.ScopeRegionIndex == definingScopeRegionOfScopeEntry.ScopeRegionIndex) { break; } } if (expressionInterpretationContext == null || expressionInterpretationContext.DefiningScopeRegion.ScopeRegionIndex < definingScopeRegionOfScopeEntry.ScopeRegionIndex) { expressionInterpretationContext = _currentGroupAggregateInfo; } switch (expressionInterpretationContext.AggregateKind) { case GroupAggregateKind.Function: if (iGroupExpressionExtendedInfo.GroupVarBasedExpression != null) { expr = iGroupExpressionExtendedInfo.GroupVarBasedExpression; } break; case GroupAggregateKind.Partition: if (iGroupExpressionExtendedInfo.GroupAggBasedExpression != null) { expr = iGroupExpressionExtendedInfo.GroupAggBasedExpression; } break; case GroupAggregateKind.GroupKey: // // User the current expression obtained from scopeEntry.GetExpression(...) // break; default: Debug.Fail("Unexpected group aggregate kind."); break; } } } } return(expr); }
internal ExpressionResolution ResolveSimpleName(string name, bool leftHandSideOfMemberAccess, ErrorContext errCtx) { DebugCheck.NotEmpty(name); // // Try resolving as a scope entry. // ScopeEntry scopeEntry; int scopeIndex; if (TryScopeLookup(name, out scopeEntry, out scopeIndex)) { // // Check for invalid join left expression correlation. // if (scopeEntry.EntryKind == ScopeEntryKind.SourceVar && ((SourceScopeEntry)scopeEntry).IsJoinClauseLeftExpr) { var message = Strings.InvalidJoinLeftCorrelation; throw EntitySqlException.Create(errCtx, message, null); } // // Set correlation flag. // SetScopeRegionCorrelationFlag(scopeIndex); return(new ValueExpression(GetExpressionFromScopeEntry(scopeEntry, scopeIndex, name, errCtx))); } // // Try resolving as a member of the default entity container. // var defaultEntityContainer = TypeResolver.Perspective.GetDefaultContainer(); ExpressionResolution defaultEntityContainerResolution; if (defaultEntityContainer != null && TryResolveEntityContainerMemberAccess(defaultEntityContainer, name, out defaultEntityContainerResolution)) { return(defaultEntityContainerResolution); } if (!_ignoreEntityContainerNameResolution) { // // Try resolving as an entity container. // EntityContainer entityContainer; if (TypeResolver.Perspective.TryGetEntityContainer( name, _parserOptions.NameComparisonCaseInsensitive /*ignoreCase*/, out entityContainer)) { return(new EntityContainerExpression(entityContainer)); } } // // Otherwise, resolve as an unqualified name. // return(TypeResolver.ResolveUnqualifiedName(name, leftHandSideOfMemberAccess /* partOfQualifiedName */, errCtx)); }
internal MetadataMember ResolveMetadataMemberName(string[] name, ErrorContext errCtx) { return(TypeResolver.ResolveMetadataMemberName(name, errCtx)); }
/// <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); } }
/// <summary> /// If <paramref name="valueExpr" /> returns a reference, then deref and try resolving <paramref name="name" /> as a property of the dereferenced value. /// </summary> private bool TryResolveAsRefPropertyAccess(DbExpression valueExpr, string name, ErrorContext errCtx, out DbExpression propertyExpr) { DebugCheck.NotNull(valueExpr); propertyExpr = null; if (TypeSemantics.IsReferenceType(valueExpr.ResultType)) { DbExpression derefExpr = valueExpr.Deref(); var derefExprType = derefExpr.ResultType; if (TryResolveAsPropertyAccess(derefExpr, name, out propertyExpr)) { return(true); } else { var message = Strings.InvalidDeRefProperty(name, derefExprType.EdmType.FullName, valueExpr.ResultType.EdmType.FullName); throw EntitySqlException.Create(errCtx, message, null); } } return(false); }
internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return _varRef; }
internal MetadataMember ResolveMetadataMemberName( string[] name, ErrorContext errCtx) { return(name.Length != 1 ? this.ResolveFullyQualifiedName(name, name.Length, errCtx) : this.ResolveUnqualifiedName(name[0], false, errCtx)); }