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); }
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)); }
public override IList <int[]> Evaluate(GroupByRollupEvalContext context) { int index = context.GetIndex(_expression); return(Collections.SingletonList( new int[] { index })); }
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); }
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); }
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)); }
public abstract IList <int[]> Evaluate(GroupByRollupEvalContext context);