internal GroupPartitionInfo(
     GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Partition, groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion)
 {
     Debug.Assert(groupPartitionExpr != null, "groupPartitionExpr != null");
 }
Example #2
0
        internal void SetContainingAggregate(GroupAggregateInfo containingAggregate)
        {
            if (_containingAggregate != null)
            {
                //
                // Aggregates in this query
                //
                //      select value max(anyelement(select value max(b + max(a + anyelement(select value c1
                //                                                                          from {2} as c group by c as c1)))
                //                                  from {1} as b group by b as b1))
                //
                //      from {0} as a group by a as a1
                //
                // are processed in the following steps:
                // 1.  the outermost aggregate (max1) begins processing as a collection function;
                // 2.  the middle aggregate (max2) begins processing as a collection function;
                // 3.  the innermost aggregate (max3) is processed as a collection function;
                // 4.  max3 is reprocessed as an aggregate; it does not see any containing aggregates at this point, so it's not wired up;
                //     max3 is validated and sealed;
                //     evaluating scope region for max3 is the outermost scope region, to which it gets assigned;
                //     max3 aggregate info object is attached to the corresponding AST node;
                // 5.  max2 completes processing as a collection function and begins processing as an aggregate;
                // 6.  max3 is reprocessed as an aggregate in the SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) method, and
                //     wired up to max2 as contained/containing;
                // 7.  max2 completes processing as an aggregate;
                //     max2 is validated and sealed;
                //     note that max2 does not see any containing aggregates at this point, so it's wired up only to max3;
                //     evaluating scope region for max2 is the middle scope region to which it gets assigned;
                // 6.  middle scope region completes processing, yields a DbExpression and cleans up all aggregate info objects assigned to it (max2);
                //     max2 is detached from the corresponding AST node;
                //     at this point max3 is still assigned to the outermost scope region and still wired to the dropped max2 as containing/contained;
                // 7.  max1 completes processing as a collection function and begins processing as an aggregate;
                // 8.  max2 is revisited and begins processing as a collection function (note that because the old aggregate info object for max2 was dropped
                //     and detached from the AST node in step 6, SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) does not recognize max2 as an aggregate);
                // 9.  max3 is recognized as an aggregate in the SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) method;
                //     max3 is rewired from the dropped max2 (step 6) to max1 as contained/containing, now max1 and max3 are wired as containing/contained;
                // 10. max2 completes processing as a collection function and begins processing as an aggregate;
                //     max2 sees max1 as a containing aggregate and wires to it;
                // 11. max3 is reprocessed as resolved aggregate inside of TryConvertAsResolvedGroupAggregate(...) method;
                //     max3 is rewired from max1 to max2 as containing/contained aggregate;
                // 12. at this point max1 is wired to max2 and max2 is wired to max3, the tree is correct;
                //
                // ... both max1 and max3 are assigned to the same scope for evaluation, this is detected and an error is reported;
                //

                //
                // Remove this aggregate from the old containing aggregate before rewiring to the new parent.
                //
                _containingAggregate.RemoveContainedAggregate(this);
            }

            //
            // Accept the new parent and wire to it as a contained aggregate.
            //
            _containingAggregate = containingAggregate;
            if (_containingAggregate != null)
            {
                _containingAggregate.AddContainedAggregate(this);
            }
        }
 internal GroupPartitionInfo(
     GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Partition, groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion)
 {
     DebugCheck.NotNull(groupPartitionExpr);
 }
 internal GroupPartitionInfo(
     GroupPartitionExpr groupPartitionExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Partition, groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion)
 {
     DebugCheck.NotNull(groupPartitionExpr);
 }
Example #5
0
        /// <summary>
        ///     Function call is _allowed_ after <see cref="ValidateAndComputeEvaluatingScopeRegion" /> has been called.
        ///     Removing contained aggregates cannot invalidate the current aggregate.
        ///     Consider the following query:
        ///     select value max(a + anyelement(select value max(b + max(a + anyelement(select value c1
        ///     from {2} as c group by c as c1)))
        ///     from {1} as b group by b as b1))
        ///     from {0} as a group by a as a1
        ///     Outer aggregate - max1, middle aggregate - max2, inner aggregate - max3.
        ///     In this query after max1 have been processed as a collection function, max2 and max3 are wired as containing/contained.
        ///     There is a point later when max1 is processed as an aggregate, max2 is processed as a collection function and max3 is processed as
        ///     an aggregate. Note that at this point the "aggregate" version of max2 is dropped and detached from the AST node when the middle scope region
        ///     completes processing; also note that because evaluating scope region of max3 is the outer scope region, max3 aggregate info is still attached to
        ///     the AST node and it is still wired to the dropped aggregate info object of max2. At this point max3 does not see new max2 as a containing aggregate,
        ///     and it rewires to max1, during this rewiring it needs to to remove itself from the old max2 and add itself to max1.
        ///     The old max2 at this point is sealed, so the removal is performed on the sealed object.
        /// </summary>
        private void RemoveContainedAggregate(GroupAggregateInfo containedAggregate)
        {
            Debug.Assert(
                _containedAggregates != null && _containedAggregates.Contains(containedAggregate),
                "_containedAggregates.Contains(containedAggregate)");

            _containedAggregates.Remove(containedAggregate);
        }
Example #6
0
 private void AddContainedAggregate(GroupAggregateInfo containedAggregate)
 {
     if (this._containedAggregates == null)
     {
         this._containedAggregates = new List <GroupAggregateInfo>();
     }
     this._containedAggregates.Add(containedAggregate);
 }
 internal GroupPartitionInfo(
     GroupPartitionExpr groupPartitionExpr,
     ErrorContext errCtx,
     GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Partition, (GroupAggregateExpr)groupPartitionExpr, errCtx, containingAggregate, definingScopeRegion)
 {
 }
 internal FunctionAggregateInfo(
     MethodExpr methodExpr,
     ErrorContext errCtx,
     GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Function, (GroupAggregateExpr)methodExpr, errCtx, containingAggregate, definingScopeRegion)
 {
 }
Example #9
0
 internal GroupKeyAggregateInfo(
     GroupAggregateKind aggregateKind,
     ErrorContext errCtx,
     GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
     : base(aggregateKind, (GroupAggregateExpr)null, errCtx, containingAggregate, definingScopeRegion)
 {
 }
Example #10
0
 private IDisposable EnterGroupAggregate(GroupAggregateInfo aggregateInfo)
 {
     this._currentGroupAggregateInfo = aggregateInfo;
     return((IDisposable) new Disposer((Action)(() =>
     {
         this._currentGroupAggregateInfo = aggregateInfo.ContainingAggregate;
         aggregateInfo.ValidateAndComputeEvaluatingScopeRegion(this);
     })));
 }
Example #11
0
        /// <summary>
        ///     Function call is not allowed after <see cref="ValidateAndComputeEvaluatingScopeRegion" /> has been called.
        ///     Adding new contained aggregate may invalidate the current aggregate.
        /// </summary>
        private void AddContainedAggregate(GroupAggregateInfo containedAggregate)
        {
            Debug.Assert(_evaluatingScopeRegion == null, "Can not add contained aggregate after _evaluatingScopeRegion have been computed.");

            if (_containedAggregates == null)
            {
                _containedAggregates = new List <GroupAggregateInfo>();
            }
            Debug.Assert(_containedAggregates.Contains(containedAggregate) == false, "containedAggregate is already registered");
            _containedAggregates.Add(containedAggregate);
        }
Example #12
0
 protected GroupAggregateInfo(
     GroupAggregateKind aggregateKind,
     GroupAggregateExpr astNode,
     ErrorContext errCtx,
     GroupAggregateInfo containingAggregate,
     ScopeRegion definingScopeRegion)
 {
     this.AggregateKind       = aggregateKind;
     this.AstNode             = astNode;
     this.ErrCtx              = errCtx;
     this.DefiningScopeRegion = definingScopeRegion;
     this.SetContainingAggregate(containingAggregate);
 }
Example #13
0
 internal void SetContainingAggregate(GroupAggregateInfo containingAggregate)
 {
     if (this._containingAggregate != null)
     {
         this._containingAggregate.RemoveContainedAggregate(this);
     }
     this._containingAggregate = containingAggregate;
     if (this._containingAggregate == null)
     {
         return;
     }
     this._containingAggregate.AddContainedAggregate(this);
 }
Example #14
0
        private DbExpression GetExpressionFromScopeEntry(
            ScopeEntry scopeEntry,
            int scopeIndex,
            string varName,
            ErrorContext errCtx)
        {
            DbExpression dbExpression = scopeEntry.GetExpression(varName, errCtx);

            if (this._currentGroupAggregateInfo != null)
            {
                ScopeRegion definingScopeRegion = this.GetDefiningScopeRegion(scopeIndex);
                if (definingScopeRegion.ScopeRegionIndex <= this._currentGroupAggregateInfo.DefiningScopeRegion.ScopeRegionIndex)
                {
                    this._currentGroupAggregateInfo.UpdateScopeIndex(scopeIndex, this);
                    IGroupExpressionExtendedInfo expressionExtendedInfo = scopeEntry as IGroupExpressionExtendedInfo;
                    if (expressionExtendedInfo != null)
                    {
                        GroupAggregateInfo groupAggregateInfo = this._currentGroupAggregateInfo;
                        while (groupAggregateInfo != null && groupAggregateInfo.DefiningScopeRegion.ScopeRegionIndex >= definingScopeRegion.ScopeRegionIndex && groupAggregateInfo.DefiningScopeRegion.ScopeRegionIndex != definingScopeRegion.ScopeRegionIndex)
                        {
                            groupAggregateInfo = groupAggregateInfo.ContainingAggregate;
                        }
                        if (groupAggregateInfo == null || groupAggregateInfo.DefiningScopeRegion.ScopeRegionIndex < definingScopeRegion.ScopeRegionIndex)
                        {
                            groupAggregateInfo = this._currentGroupAggregateInfo;
                        }
                        switch (groupAggregateInfo.AggregateKind)
                        {
                        case GroupAggregateKind.Function:
                            if (expressionExtendedInfo.GroupVarBasedExpression != null)
                            {
                                dbExpression = expressionExtendedInfo.GroupVarBasedExpression;
                                break;
                            }
                            break;

                        case GroupAggregateKind.Partition:
                            if (expressionExtendedInfo.GroupAggBasedExpression != null)
                            {
                                dbExpression = expressionExtendedInfo.GroupAggBasedExpression;
                                break;
                            }
                            break;
                        }
                    }
                }
            }
            return(dbExpression);
        }
Example #15
0
        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);
        }
        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);
        }
        private IDisposable EnterGroupAggregate(GroupAggregateInfo aggregateInfo)
        {
            _currentGroupAggregateInfo = aggregateInfo;
            return(new Disposer(
                       delegate
            {
                //
                // First, pop the element from the stack to keep the stack valid...
                //
                Debug.Assert(_currentGroupAggregateInfo == aggregateInfo, "Aggregare info stack is corrupted.");
                _currentGroupAggregateInfo = aggregateInfo.ContainingAggregate;

                //
                // ...then validate and seal the aggregate info.
                // Note that this operation may throw an EntitySqlException.
                //
                aggregateInfo.ValidateAndComputeEvaluatingScopeRegion(this);
            }));
        }
Example #18
0
 internal FunctionAggregateInfo(
     MethodExpr methodExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Function, methodExpr, errCtx, containingAggregate, definingScopeRegion)
 {
     DebugCheck.NotNull(methodExpr);
 }
Example #19
0
 private void RemoveContainedAggregate(GroupAggregateInfo containedAggregate)
 {
     this._containedAggregates.Remove(containedAggregate);
 }
 internal FunctionAggregateInfo(
     MethodExpr methodExpr, ErrorContext errCtx, GroupAggregateInfo containingAggregate, ScopeRegion definingScopeRegion)
     : base(GroupAggregateKind.Function, methodExpr, errCtx, containingAggregate, definingScopeRegion)
 {
     Debug.Assert(methodExpr != null, "methodExpr != null");
 }
        internal void SetContainingAggregate(GroupAggregateInfo containingAggregate)
        {
            if (_containingAggregate != null)
            {
                //
                // Aggregates in this query
                //
                //      select value max(anyelement(select value max(b + max(a + anyelement(select value c1 
                //                                                                          from {2} as c group by c as c1))) 
                //                                  from {1} as b group by b as b1)) 
                //
                //      from {0} as a group by a as a1
                //
                // are processed in the following steps:
                // 1.  the outermost aggregate (max1) begins processing as a collection function;
                // 2.  the middle aggregate (max2) begins processing as a collection function;
                // 3.  the innermost aggregate (max3) is processed as a collection function;
                // 4.  max3 is reprocessed as an aggregate; it does not see any containing aggregates at this point, so it's not wired up;
                //     max3 is validated and sealed;
                //     evaluating scope region for max3 is the outermost scope region, to which it gets assigned;
                //     max3 aggregate info object is attached to the corresponding AST node;
                // 5.  max2 completes processing as a collection function and begins processing as an aggregate;
                // 6.  max3 is reprocessed as an aggregate in the SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) method, and 
                //     wired up to max2 as contained/containing;
                // 7.  max2 completes processing as an aggregate;
                //     max2 is validated and sealed;
                //     note that max2 does not see any containing aggregates at this point, so it's wired up only to max3;
                //     evaluating scope region for max2 is the middle scope region to which it gets assigned;
                // 6.  middle scope region completes processing, yields a DbExpression and cleans up all aggregate info objects assigned to it (max2);
                //     max2 is detached from the corresponding AST node;
                //     at this point max3 is still assigned to the outermost scope region and still wired to the dropped max2 as containing/contained;
                // 7.  max1 completes processing as a collection function and begins processing as an aggregate;
                // 8.  max2 is revisited and begins processing as a collection function (note that because the old aggregate info object for max2 was dropped 
                //     and detached from the AST node in step 6, SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) does not recognize max2 as an aggregate);
                // 9.  max3 is recognized as an aggregate in the SemanticAnalyzer.TryConvertAsResolvedGroupAggregate(...) method;
                //     max3 is rewired from the dropped max2 (step 6) to max1 as contained/containing, now max1 and max3 are wired as containing/contained;
                // 10. max2 completes processing as a collection function and begins processing as an aggregate;
                //     max2 sees max1 as a containing aggregate and wires to it;
                // 11. max3 is reprocessed as resolved aggregate inside of TryConvertAsResolvedGroupAggregate(...) method;
                //     max3 is rewired from max1 to max2 as containing/contained aggregate;
                // 12. at this point max1 is wired to max2 and max2 is wired to max3, the tree is correct;
                //
                // ... both max1 and max3 are assigned to the same scope for evaluation, this is detected and an error is reported;
                //

                //
                // Remove this aggregate from the old containing aggregate before rewiring to the new parent.
                //
                _containingAggregate.RemoveContainedAggregate(this);
            }

            //
            // Accept the new parent and wire to it as a contained aggregate.
            //
            _containingAggregate = containingAggregate;
            if (_containingAggregate != null)
            {
                _containingAggregate.AddContainedAggregate(this);
            }
        }
        // <summary>
        // Function call is not allowed after <see cref="ValidateAndComputeEvaluatingScopeRegion" /> has been called.
        // Adding new contained aggregate may invalidate the current aggregate.
        // </summary>
        private void AddContainedAggregate(GroupAggregateInfo containedAggregate)
        {
            Debug.Assert(_evaluatingScopeRegion == null, "Can not add contained aggregate after _evaluatingScopeRegion have been computed.");

            if (_containedAggregates == null)
            {
                _containedAggregates = new List<GroupAggregateInfo>();
            }
            Debug.Assert(_containedAggregates.Contains(containedAggregate) == false, "containedAggregate is already registered");
            _containedAggregates.Add(containedAggregate);
        }
        // <summary>
        // Function call is _allowed_ after <see cref="ValidateAndComputeEvaluatingScopeRegion" /> has been called.
        // Removing contained aggregates cannot invalidate the current aggregate.
        // Consider the following query:
        // select value max(a + anyelement(select value max(b + max(a + anyelement(select value c1
        // from {2} as c group by c as c1)))
        // from {1} as b group by b as b1))
        // from {0} as a group by a as a1
        // Outer aggregate - max1, middle aggregate - max2, inner aggregate - max3.
        // In this query after max1 have been processed as a collection function, max2 and max3 are wired as containing/contained.
        // There is a point later when max1 is processed as an aggregate, max2 is processed as a collection function and max3 is processed as
        // an aggregate. Note that at this point the "aggregate" version of max2 is dropped and detached from the AST node when the middle scope region
        // completes processing; also note that because evaluating scope region of max3 is the outer scope region, max3 aggregate info is still attached to
        // the AST node and it is still wired to the dropped aggregate info object of max2. At this point max3 does not see new max2 as a containing aggregate,
        // and it rewires to max1, during this rewiring it needs to to remove itself from the old max2 and add itself to max1.
        // The old max2 at this point is sealed, so the removal is performed on the sealed object.
        // </summary>
        private void RemoveContainedAggregate(GroupAggregateInfo containedAggregate)
        {
            Debug.Assert(
                _containedAggregates != null && _containedAggregates.Contains(containedAggregate),
                "_containedAggregates.Contains(containedAggregate)");

            _containedAggregates.Remove(containedAggregate);
        }