/// <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;
            }
        }
Beispiel #2
0
        private static TResult AnalyzeSemanticsCommon <TResult>(AST.Node astExpr,
                                                                Perspective perspective,
                                                                ParserOptions parserOptions,
                                                                IEnumerable <DbParameterReferenceExpression> parameters,
                                                                IEnumerable <DbVariableReferenceExpression> variables,
                                                                Func <SemanticAnalyzer, AST.Node, TResult> analysisFunction)
            where TResult : class
        {
            TResult result = null;

            try
            {
                //
                // Validate arguments
                //
                EntityUtil.CheckArgumentNull(astExpr, "astExpr");
                EntityUtil.CheckArgumentNull(perspective, "perspective");

                //
                // Invoke semantic analysis
                //
                SemanticAnalyzer analyzer = (new SemanticAnalyzer(SemanticResolver.Create(perspective, parserOptions, parameters, variables)));
                result = analysisFunction(analyzer, astExpr);
            }
            //
            // Wrap MetadataException as EntityException inner exception
            //
            catch (System.Data.MetadataException metadataException)
            {
                throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.GeneralExceptionAsQueryInnerException("Metadata"), metadataException);
            }
            //
            // Wrap MappingException as EntityException inner exception
            //
            catch (System.Data.MappingException mappingException)
            {
                throw EntityUtil.EntitySqlError(System.Data.Entity.Strings.GeneralExceptionAsQueryInnerException("Mapping"), mappingException);
            }

            return(result);
        }
Beispiel #3
0
        internal static FbxSemanticsUnsafe <TVertex> ParseUnsafe(Stream stream, bool leaveStreamOpen = true, CancellationToken cancellationToken = default)
        {
            ValueTypeRentMemory <RawString> textures = default;
            FbxObject?fbx = null;

            try {
                var vertexCreator = SkinnedVertexCreator <TVertex> .Build();

                fbx = FbxParser.Parse(stream);
                using var resolver = new SemanticResolver(fbx);
                var objectsNode = resolver.ObjectsNode;
                var(meshes, skeletons) = ParseMeshAndSkeleton(resolver, vertexCreator, cancellationToken);
                try {
                    using (meshes) {
                        textures = ParseTexture(objectsNode, cancellationToken);
                        //ParseMaterial(objectsNode);
                        var(vertices, indices) = meshes.CreateCombined();
                        return(new FbxSemanticsUnsafe <TVertex>(ref fbx, ref indices, ref vertices, ref textures, ref skeletons));
                    }
                }
                catch {
                    skeletons.Dispose();
                    throw;
                }
            }
            catch {
                fbx?.Dispose();
                textures.Dispose();
                throw;
            }
            finally {
                if (leaveStreamOpen == false)
                {
                    stream?.Dispose();
                }
            }
        }
        /// <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);