Пример #1
0
        public override IList <int[]> Evaluate(GroupByRollupEvalContext context)
        {
            int[][] childIndexes = EvaluateChildNodes(context);

            // find duplicate entries among child expressions
            for (int i = 0; i < childIndexes.Length; i++)
            {
                for (int j = i + 1; j < childIndexes.Length; j++)
                {
                    ValidateCompare(childIndexes[i], childIndexes[j]);
                }
            }

            IList <int[]> rollup;

            if (_cube)
            {
                rollup = HandleCube(childIndexes);
            }
            else
            {
                rollup = HandleRollup(childIndexes);
            }
            rollup.Add(new int[0]);
            return(rollup);
        }
Пример #2
0
        public override IList <int[]> Evaluate(GroupByRollupEvalContext context)
        {
            var result = new int[_expressions.Count];

            for (int i = 0; i < _expressions.Count; i++)
            {
                int index = context.GetIndex(_expressions[i]);
                result[i] = index;
            }

            result.SortInPlace();

            // find dups
            for (int i = 0; i < result.Length - 1; i++)
            {
                if (result[i] == result[i + 1])
                {
                    throw new GroupByRollupDuplicateException(
                              new int[]
                    {
                        result[i]
                    });
                }
            }

            return(Collections.SingletonList(result));
        }
Пример #3
0
        public override IList <int[]> Evaluate(GroupByRollupEvalContext context)
        {
            int index = context.GetIndex(_expression);

            return(Collections.SingletonList(
                       new int[]
            {
                index
            }));
        }
Пример #4
0
        private int[][] EvaluateChildNodes(GroupByRollupEvalContext context)
        {
            int size         = ChildNodes.Count;
            var childIndexes = new int[size][];

            for (int i = 0; i < size; i++)
            {
                var childIndex = ChildNodes[i].Evaluate(context);
                if (childIndex.Count != 1)
                {
                    throw new IllegalStateException();
                }
                childIndexes[i] = childIndex[0];
            }
            return(childIndexes);
        }
Пример #5
0
        public override IList <int[]> Evaluate(GroupByRollupEvalContext context)
        {
            IList <int[]> rollup = new List <int[]>();

            foreach (GroupByRollupNodeBase node in this.ChildNodes)
            {
                IList <int[]> result = node.Evaluate(context);

                // find dups
                foreach (var row in result)
                {
                    foreach (var existing in rollup)
                    {
                        if (Collections.AreEqual(row, existing))
                        {
                            throw new GroupByRollupDuplicateException(row);
                        }
                    }
                }

                rollup.AddAll(result);
            }
            return(rollup);
        }
Пример #6
0
        public static GroupByClauseExpressions GetGroupByRollupExpressions(
            IList <GroupByClauseElement> groupByElements,
            SelectClauseSpecRaw selectClauseSpec,
            ExprNode optionalHavingNode,
            IList <OrderByItem> orderByList,
            ExprNodeSubselectDeclaredDotVisitor visitor)
        {
            if (groupByElements == null || groupByElements.Count == 0)
            {
                return(null);
            }

            // walk group-by-elements, determine group-by expressions and rollup nodes
            var groupByExpressionInfo = GroupByToRollupNodes(groupByElements);

            // obtain expression nodes, collect unique nodes and assign index
            var distinctGroupByExpressions = new List <ExprNode>();
            var expressionToIndex          = new Dictionary <ExprNode, int>();

            foreach (ExprNode exprNode in groupByExpressionInfo.Expressions)
            {
                var found = false;
                for (var i = 0; i < distinctGroupByExpressions.Count; i++)
                {
                    ExprNode other = distinctGroupByExpressions[i];
                    // find same expression
                    if (ExprNodeUtility.DeepEquals(exprNode, other))
                    {
                        expressionToIndex.Put(exprNode, i);
                        found = true;
                        break;
                    }
                }

                // not seen before
                if (!found)
                {
                    expressionToIndex.Put(exprNode, distinctGroupByExpressions.Count);
                    distinctGroupByExpressions.Add(exprNode);
                }
            }

            // determine rollup, validate it is either (not both)
            var hasGroupingSet = false;
            var hasRollup      = false;

            foreach (var element in groupByElements)
            {
                if (element is GroupByClauseElementGroupingSet)
                {
                    hasGroupingSet = true;
                }
                if (element is GroupByClauseElementRollupOrCube)
                {
                    hasRollup = true;
                }
            }

            // no-rollup or grouping-sets means simply validate
            var groupByExpressions = distinctGroupByExpressions.ToArray();

            if (!hasRollup && !hasGroupingSet)
            {
                return(new GroupByClauseExpressions(groupByExpressions));
            }

            // evaluate rollup node roots
            IList <GroupByRollupNodeBase> nodes = groupByExpressionInfo.Nodes;
            var perNodeCombinations             = new Object[nodes.Count][];
            var context = new GroupByRollupEvalContext(expressionToIndex);

            try {
                for (var i = 0; i < nodes.Count; i++)
                {
                    var node         = nodes[i];
                    var combinations = node.Evaluate(context);
                    perNodeCombinations[i] = new Object[combinations.Count];
                    for (var j = 0; j < combinations.Count; j++)
                    {
                        perNodeCombinations[i][j] = combinations[j];
                    }
                }
            }
            catch (GroupByRollupDuplicateException ex) {
                if (ex.Indexes.Length == 0)
                {
                    throw new ExprValidationException("Failed to validate the group-by clause, found duplicate specification of the overall grouping '()'");
                }
                else
                {
                    var writer    = new StringWriter();
                    var delimiter = "";
                    for (var i = 0; i < ex.Indexes.Length; i++)
                    {
                        writer.Write(delimiter);
                        writer.Write(groupByExpressions[ex.Indexes[i]].ToExpressionStringMinPrecedenceSafe());
                        delimiter = ", ";
                    }
                    throw new ExprValidationException("Failed to validate the group-by clause, found duplicate specification of expressions (" + writer.ToString() + ")");
                }
            }

            // enumerate combinations building an index list
            var combinationEnumeration            = new CombinationEnumeration(perNodeCombinations);
            ICollection <int>         combination = new SortedSet <int>();
            ICollection <MultiKeyInt> indexList   = new LinkedHashSet <MultiKeyInt>();

            while (combinationEnumeration.MoveNext())
            {
                combination.Clear();
                Object[] combinationOA = combinationEnumeration.Current;
                foreach (var indexes in combinationOA)
                {
                    var indexarr = (int[])indexes;
                    foreach (var anIndex in indexarr)
                    {
                        combination.Add(anIndex);
                    }
                }
                var indexArr = CollectionUtil.IntArray(combination);
                indexList.Add(new MultiKeyInt(indexArr));
            }

            // obtain rollup levels
            var rollupLevels = new int[indexList.Count][];
            var count        = 0;

            foreach (var mk in indexList)
            {
                rollupLevels[count++] = mk.Keys;
            }
            var numberOfLevels = rollupLevels.Length;

            if (numberOfLevels == 1 && rollupLevels[0].Length == 0)
            {
                throw new ExprValidationException("Failed to validate the group-by clause, the overall grouping '()' cannot be the only grouping");
            }

            // obtain select-expression copies for rewrite
            var expressions = selectClauseSpec.SelectExprList;
            var selects     = new ExprNode[numberOfLevels][];

            for (var i = 0; i < numberOfLevels; i++)
            {
                selects[i] = new ExprNode[expressions.Count];
                for (var j = 0; j < expressions.Count; j++)
                {
                    SelectClauseElementRaw selectRaw = expressions[j];
                    if (!(selectRaw is SelectClauseExprRawSpec))
                    {
                        throw new ExprValidationException("Group-by with rollup requires that the select-clause does not use wildcard");
                    }
                    var compiled = (SelectClauseExprRawSpec)selectRaw;
                    selects[i][j] = CopyVisitExpression(compiled.SelectExpression, visitor);
                }
            }

            // obtain having-expression copies for rewrite
            ExprNode[] optHavingNodeCopy = null;
            if (optionalHavingNode != null)
            {
                optHavingNodeCopy = new ExprNode[numberOfLevels];
                for (var i = 0; i < numberOfLevels; i++)
                {
                    optHavingNodeCopy[i] = CopyVisitExpression(optionalHavingNode, visitor);
                }
            }

            // obtain orderby-expression copies for rewrite
            ExprNode[][] optOrderByCopy = null;
            if (orderByList != null && orderByList.Count > 0)
            {
                optOrderByCopy = new ExprNode[numberOfLevels][];
                for (var i = 0; i < numberOfLevels; i++)
                {
                    optOrderByCopy[i] = new ExprNode[orderByList.Count];
                    for (var j = 0; j < orderByList.Count; j++)
                    {
                        OrderByItem element = orderByList[j];
                        optOrderByCopy[i][j] = CopyVisitExpression(element.ExprNode, visitor);
                    }
                }
            }

            return(new GroupByClauseExpressions(groupByExpressions, rollupLevels, selects, optHavingNodeCopy, optOrderByCopy));
        }
Пример #7
0
 public abstract IList <int[]> Evaluate(GroupByRollupEvalContext context);