private static TResult AnalyzeSemanticsCommon <TResult>( System.Data.Entity.Core.Common.EntitySql.AST.Node astExpr, Perspective perspective, ParserOptions parserOptions, IEnumerable <DbParameterReferenceExpression> parameters, IEnumerable <DbVariableReferenceExpression> variables, Func <SemanticAnalyzer, System.Data.Entity.Core.Common.EntitySql.AST.Node, TResult> analysisFunction) where TResult : class { TResult result = default(TResult); try { SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(SemanticResolver.Create(perspective, parserOptions, parameters, variables)); return(analysisFunction(semanticAnalyzer, astExpr)); } catch (MetadataException ex) { throw new EntitySqlException(Strings.GeneralExceptionAsQueryInnerException((object)"Metadata"), (Exception)ex); } catch (MappingException ex) { throw new EntitySqlException(Strings.GeneralExceptionAsQueryInnerException((object)"Mapping"), (Exception)ex); } }
private static bool UntypedNullAwareIsStructurallyEqual(TypeUsage fromType, TypeUsage toType) { if (fromType == null) { return(SemanticResolver.UntypedNullAwareIsPromotableTo(fromType, toType)); } return(TypeSemantics.IsStructurallyEqual(fromType, toType)); }
internal static SemanticResolver Create( Perspective perspective, ParserOptions parserOptions, IEnumerable <DbParameterReferenceExpression> parameters, IEnumerable <DbVariableReferenceExpression> variables) { return(new SemanticResolver(parserOptions, SemanticResolver.ProcessParameters(parameters, parserOptions), SemanticResolver.ProcessVariables(variables, parserOptions), new TypeResolver(perspective, parserOptions))); }
internal void UpdateScopeIndex(int referencedScopeIndex, SemanticResolver sr) { ScopeRegion definingScopeRegion = sr.GetDefiningScopeRegion(referencedScopeIndex); if (this._innermostReferencedScopeRegion != null && this._innermostReferencedScopeRegion.ScopeRegionIndex >= definingScopeRegion.ScopeRegionIndex) { return; } this._innermostReferencedScopeRegion = definingScopeRegion; }
/// <summary> /// Updates referenced scope index of the aggregate. /// Function call is not allowed after <see cref="ValidateAndComputeEvaluatingScopeRegion" /> has been called. /// </summary> internal void UpdateScopeIndex(int referencedScopeIndex, SemanticResolver sr) { Debug.Assert( _evaluatingScopeRegion == null, "Can not update referenced scope index after _evaluatingScopeRegion have been computed."); var referencedScopeRegion = sr.GetDefiningScopeRegion(referencedScopeIndex); if (_innermostReferencedScopeRegion == null || _innermostReferencedScopeRegion.ScopeRegionIndex < referencedScopeRegion.ScopeRegionIndex) { _innermostReferencedScopeRegion = referencedScopeRegion; } }
private static TResult AnalyzeSemanticsCommon <TResult>( Node astExpr, Perspective perspective, ParserOptions parserOptions, IEnumerable <DbParameterReferenceExpression> parameters, IEnumerable <DbVariableReferenceExpression> variables, Func <SemanticAnalyzer, Node, TResult> analysisFunction) where TResult : class { DebugCheck.NotNull(astExpr); DebugCheck.NotNull(perspective); TResult result = null; try { // // Invoke semantic analysis // var analyzer = (new SemanticAnalyzer(SemanticResolver.Create(perspective, parserOptions, parameters, variables))); result = analysisFunction(analyzer, astExpr); } // // Wrap MetadataException as EntityException inner exception // catch (MetadataException metadataException) { var message = Strings.GeneralExceptionAsQueryInnerException("Metadata"); throw new EntitySqlException(message, metadataException); } // // Wrap MappingException as EntityException inner exception // catch (MappingException mappingException) { var message = Strings.GeneralExceptionAsQueryInnerException("Mapping"); throw new EntitySqlException(message, mappingException); } return(result); }
internal void ValidateAndComputeEvaluatingScopeRegion(SemanticResolver sr) { this._evaluatingScopeRegion = this._innermostReferencedScopeRegion ?? this.DefiningScopeRegion; if (!this._evaluatingScopeRegion.IsAggregating) { int scopeRegionIndex = this._evaluatingScopeRegion.ScopeRegionIndex; this._evaluatingScopeRegion = (ScopeRegion)null; foreach (ScopeRegion scopeRegion in sr.ScopeRegions.Skip <ScopeRegion>(scopeRegionIndex)) { if (scopeRegion.IsAggregating) { this._evaluatingScopeRegion = scopeRegion; break; } } if (this._evaluatingScopeRegion == null) { throw new EntitySqlException(Strings.GroupVarNotFoundInScope); } } this.ValidateContainedAggregates(this._evaluatingScopeRegion.ScopeRegionIndex, this.DefiningScopeRegion.ScopeRegionIndex); }
/// <summary> /// Validates the aggregate info and computes <see cref="EvaluatingScopeRegion" /> property. /// Seals the aggregate info object (no more AddContainedAggregate(...), RemoveContainedAggregate(...) and UpdateScopeIndex(...) calls allowed). /// </summary> internal void ValidateAndComputeEvaluatingScopeRegion(SemanticResolver sr) { Debug.Assert(_evaluatingScopeRegion == null, "_evaluatingScopeRegion has already been initialized"); // // If _innermostReferencedScopeRegion is null, it means the aggregate is not correlated (a constant value), // so resolve it to the DefiningScopeRegion. // _evaluatingScopeRegion = _innermostReferencedScopeRegion ?? DefiningScopeRegion; if (!_evaluatingScopeRegion.IsAggregating) { // // In some cases the found scope region does not aggregate (has no grouping). So adding the aggregate to that scope won't work. // In this situation we need to backtrack from the found region to the first inner region that performs aggregation. // Example: // select yy.cx, yy.cy, yy.cz // from {1, 2} as x cross apply (select zz.cx, zz.cy, zz.cz // from {3, 4} as y cross apply (select Count(x) as cx, Count(y) as cy, Count(z) as cz // from {5, 6} as z) as zz // ) as yy // Note that Count aggregates cx and cy refer to scope regions that do aggregate. All three aggregates needs to be added to the only // aggregating region - the innermost. // var scopeRegionIndex = _evaluatingScopeRegion.ScopeRegionIndex; _evaluatingScopeRegion = null; foreach (var innerSR in sr.ScopeRegions.Skip(scopeRegionIndex)) { if (innerSR.IsAggregating) { _evaluatingScopeRegion = innerSR; break; } } if (_evaluatingScopeRegion == null) { var message = Strings.GroupVarNotFoundInScope; throw new EntitySqlException(message); } } // // Validate all the contained aggregates for violation of the containment rule: // None of the nested (contained) aggregates must be evaluating on a scope region that is // a. equal or inner to the evaluating scope of the current aggregate and // b. equal or outer to the defining scope of the current aggregate. // // Example of a disallowed query: // // select // (select max(x + max(y)) // from {1} as y) // from {0} as x // // Example of an allowed query where the ESR of the nested aggregate is outer to the ESR of the outer aggregate: // // select // (select max(y + max(x)) // from {1} as y) // from {0} as x // // Example of an allowed query where the ESR of the nested aggregate is inner to the DSR of the outer aggregate: // // select max(x + anyelement(select value max(y) from {1} as y)) // from {0} as x // Debug.Assert(_evaluatingScopeRegion.IsAggregating, "_evaluatingScopeRegion.IsAggregating must be true"); Debug.Assert( _evaluatingScopeRegion.ScopeRegionIndex <= DefiningScopeRegion.ScopeRegionIndex, "_evaluatingScopeRegion must outer to the DefiningScopeRegion"); ValidateContainedAggregates(_evaluatingScopeRegion.ScopeRegionIndex, DefiningScopeRegion.ScopeRegionIndex); }
internal abstract DbLambda GetLambda(SemanticResolver sr);