Exemple #1
0
        private static void AddEquivalent(
            ExprAggregateNode aggNodeToAdd,
            IList<AggregationServiceAggExpressionDesc> equivalencyList,
            bool intoTableNonRollup)
        {
            // Check any same aggregation nodes among all aggregation clauses
            var foundEquivalent = false;
            foreach (var existing in equivalencyList) {
                var aggNode = existing.AggregationNode;

                // we have equivalence when:
                // (a) equals on node returns true
                // (b) positional parameters are the same
                // (c) non-positional (group-by over, if present, are the same ignoring duplicates)
                if (!aggNode.EqualsNode(aggNodeToAdd, false)) {
                    continue;
                }

                if (!ExprNodeUtilityCompare.DeepEquals(
                    aggNode.PositionalParams,
                    aggNodeToAdd.PositionalParams,
                    false)) {
                    continue;
                }

                if (!ExprNodeUtilityCompare.DeepEqualsNullChecked(
                    aggNode.OptionalFilter,
                    aggNodeToAdd.OptionalFilter,
                    false)) {
                    continue;
                }

                if (aggNode.OptionalLocalGroupBy != null || aggNodeToAdd.OptionalLocalGroupBy != null) {
                    if (aggNode.OptionalLocalGroupBy == null && aggNodeToAdd.OptionalLocalGroupBy != null ||
                        aggNode.OptionalLocalGroupBy != null && aggNodeToAdd.OptionalLocalGroupBy == null) {
                        continue;
                    }

                    if (!ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                        aggNode.OptionalLocalGroupBy.PartitionExpressions,
                        aggNodeToAdd.OptionalLocalGroupBy.PartitionExpressions)) {
                        continue;
                    }
                }

                existing.AddEquivalent(aggNodeToAdd);
                foundEquivalent = true;
                break;
            }

            if (!foundEquivalent || intoTableNonRollup) {
                equivalencyList.Add(new AggregationServiceAggExpressionDesc(aggNodeToAdd, aggNodeToAdd.Factory));
            }
        }
Exemple #2
0
        private static IList<AggregationServiceAggExpressionDesc> FindPartition(
            IList<AggregationGroupByLocalGroupLevel> partitions,
            ExprNode[] partitionExpressions)
        {
            foreach (var level in partitions) {
                if (ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(level.PartitionExpr, partitionExpressions)) {
                    return level.Expressions;
                }
            }

            return null;
        }
Exemple #3
0
        private static AggregationGroupByLocalGroupDesc AnalyzeLocalGroupBy(
            IList<AggregationServiceAggExpressionDesc> aggregations,
            ExprNode[] groupByNodes,
            AggregationGroupByRollupDescForge groupByRollupDesc,
            IntoTableSpec intoTableSpec)
        {
            var hasOver = false;
            foreach (var desc in aggregations) {
                if (desc.AggregationNode.OptionalLocalGroupBy != null) {
                    hasOver = true;
                    break;
                }
            }

            if (!hasOver) {
                return null;
            }

            if (groupByRollupDesc != null) {
                throw new ExprValidationException("Roll-up and group-by parameters cannot be combined");
            }

            if (intoTableSpec != null) {
                throw new ExprValidationException("Into-table and group-by parameters cannot be combined");
            }

            IList<AggregationGroupByLocalGroupLevel> partitions = new List<AggregationGroupByLocalGroupLevel>();
            foreach (var desc in aggregations) {
                var localGroupBy = desc.AggregationNode.OptionalLocalGroupBy;

                var partitionExpressions = localGroupBy == null ? groupByNodes : localGroupBy.PartitionExpressions;
                var found = FindPartition(partitions, partitionExpressions);
                if (found == null) {
                    found = new List<AggregationServiceAggExpressionDesc>();
                    var level = new AggregationGroupByLocalGroupLevel(partitionExpressions, found);
                    partitions.Add(level);
                }

                found.Add(desc);
            }

            // check single group-by partition and it matches the group-by clause
            if (partitions.Count == 1 &&
                ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(partitions[0].PartitionExpr, groupByNodes)) {
                return null;
            }

            return new AggregationGroupByLocalGroupDesc(aggregations.Count, partitions.ToArray());
        }
        private static AggregationMFIdentifier FindExisting(
            Deque<AggregationMFIdentifier> accessProviderSlots,
            AggregationMultiFunctionStateKey providerKey,
            ExprAggregateLocalGroupByDesc optionalOver,
            ExprNode[] groupByNodes)
        {
            foreach (var ident in accessProviderSlots) {
                if (!providerKey.Equals(ident.AggregationStateKey)) {
                    continue;
                }

                // if there is no local-group by, but there is group-by-clause, and the ident-over matches, use that
                if (optionalOver == null &&
                    groupByNodes.Length > 0 &&
                    ident.OptionalLocalGroupBy != null &&
                    ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                        groupByNodes,
                        ident.OptionalLocalGroupBy.PartitionExpressions)) {
                    return ident;
                }

                if (optionalOver == null && ident.OptionalLocalGroupBy == null) {
                    return ident;
                }

                if (optionalOver != null &&
                    ident.OptionalLocalGroupBy != null &&
                    ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                        optionalOver.PartitionExpressions,
                        ident.OptionalLocalGroupBy.PartitionExpressions)) {
                    return ident;
                }
            }

            return null;
        }
Exemple #5
0
        public static AggregationLocalGroupByPlanForge Analyze(
            ExprForge[][] methodForges,
            AggregationForgeFactory[] methodFactories,
            AggregationStateFactoryForge[] accessAggregations,
            AggregationGroupByLocalGroupDesc localGroupDesc,
            ExprNode[] groupByExpressions,
            AggregationAccessorSlotPairForge[] accessors,
            ImportService importService,
            bool fireAndForget,
            string statementName)
        {
            if (groupByExpressions == null) {
                groupByExpressions = ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY;
            }

            var columns = new AggregationLocalGroupByColumnForge[localGroupDesc.NumColumns];
            IList<AggregationLocalGroupByLevelForge> levelsList = new List<AggregationLocalGroupByLevelForge>();
            AggregationLocalGroupByLevelForge optionalTopLevel = null;

            // determine optional top level (level number is -1)
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    optionalTopLevel = GetLevel(
                        -1,
                        levelDesc,
                        methodForges,
                        methodFactories,
                        accessAggregations,
                        columns,
                        groupByExpressions.Length == 0,
                        accessors,
                        importService,
                        fireAndForget,
                        statementName);
                }
            }

            // determine default (same as group-by) level, if any, assign level number 0
            var levelNumber = 0;
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    continue;
                }

                var isDefaultLevel = groupByExpressions != null &&
                                     ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                                         groupByExpressions,
                                         levelDesc.PartitionExpr);
                if (isDefaultLevel) {
                    var level = GetLevel(
                        0,
                        levelDesc,
                        methodForges,
                        methodFactories,
                        accessAggregations,
                        columns,
                        isDefaultLevel,
                        accessors,
                        importService,
                        fireAndForget,
                        statementName);
                    levelsList.Add(level);
                    levelNumber++;
                    break;
                }
            }

            // determine all other levels, assign level numbers
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    continue;
                }

                var isDefaultLevel = groupByExpressions != null &&
                                     ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                                         groupByExpressions,
                                         levelDesc.PartitionExpr);
                if (isDefaultLevel) {
                    continue;
                }

                var level = GetLevel(
                    levelNumber,
                    levelDesc,
                    methodForges,
                    methodFactories,
                    accessAggregations,
                    columns,
                    isDefaultLevel,
                    accessors,
                    importService,
                    fireAndForget,
                    statementName);
                levelsList.Add(level);
                levelNumber++;
            }

            // totals
            var numMethods = 0;
            var numAccesses = 0;
            if (optionalTopLevel != null) {
                numMethods += optionalTopLevel.MethodFactories.Length;
                numAccesses += optionalTopLevel.AccessStateForges.Length;
            }

            foreach (var level in levelsList) {
                numMethods += level.MethodFactories.Length;
                numAccesses += level.AccessStateForges.Length;
            }

            AggregationLocalGroupByLevelForge[] levels = levelsList.ToArray();
            return new AggregationLocalGroupByPlanForge(numMethods, numAccesses, columns, optionalTopLevel, levels);
        }
        public static AggregationLocalGroupByPlanDesc Analyze(
            ExprForge[][] methodForges,
            AggregationForgeFactory[] methodFactories,
            AggregationStateFactoryForge[] accessAggregations,
            AggregationGroupByLocalGroupDesc localGroupDesc,
            ExprNode[] groupByExpressions,
            MultiKeyClassRef groupByMultiKey,
            AggregationAccessorSlotPairForge[] accessors,
            StatementRawInfo raw,
            SerdeCompileTimeResolver serdeResolver)
        {
            if (groupByExpressions == null) {
                groupByExpressions = ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY;
            }

            var columns = new AggregationLocalGroupByColumnForge[localGroupDesc.NumColumns];
            var levelsList = new List<AggregationLocalGroupByLevelForge>();
            AggregationLocalGroupByLevelForge optionalTopLevel = null;
            var additionalForgeables = new List<StmtClassForgeableFactory>();

            // determine optional top level (level number is -1)
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    AggregationGroupByLocalGroupLevelDesc top = GetLevel(
                        -1,
                        levelDesc,
                        methodForges,
                        methodFactories,
                        accessAggregations,
                        columns,
                        groupByExpressions.Length == 0,
                        accessors,
                        groupByExpressions,
                        groupByMultiKey,
                        raw,
                        serdeResolver);
                    optionalTopLevel = top.Forge;
                    additionalForgeables.AddRange(top.AdditionalForgeables);
                }
            }

            // determine default (same as group-by) level, if any, assign level number 0
            var levelNumber = 0;
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    continue;
                }

                var isDefaultLevel = groupByExpressions != null &&
                                     ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                                         groupByExpressions,
                                         levelDesc.PartitionExpr);

                if (isDefaultLevel) {
                    AggregationGroupByLocalGroupLevelDesc level = GetLevel(
                        0,
                        levelDesc,
                        methodForges,
                        methodFactories,
                        accessAggregations,
                        columns,
                        isDefaultLevel,
                        accessors,
                        groupByExpressions,
                        groupByMultiKey,
                        raw,
                        serdeResolver);
                    additionalForgeables.AddRange(level.AdditionalForgeables);
                    levelsList.Add(level.Forge);
                    levelNumber++;
                    break;
                }
            }

            // determine all other levels, assign level numbers
            for (var i = 0; i < localGroupDesc.Levels.Length; i++) {
                var levelDesc = localGroupDesc.Levels[i];
                if (levelDesc.PartitionExpr.Length == 0) {
                    continue;
                }

                var isDefaultLevel = groupByExpressions != null &&
                                     ExprNodeUtilityCompare.DeepEqualsIgnoreDupAndOrder(
                                         groupByExpressions,
                                         levelDesc.PartitionExpr);
                if (isDefaultLevel) {
                    continue;
                }

                AggregationGroupByLocalGroupLevelDesc level = GetLevel(
                    levelNumber,
                    levelDesc,
                    methodForges,
                    methodFactories,
                    accessAggregations,
                    columns,
                    isDefaultLevel,
                    accessors,
                    groupByExpressions,
                    groupByMultiKey,
                    raw,
                    serdeResolver);
                levelsList.Add(level.Forge);
                additionalForgeables.AddRange(level.AdditionalForgeables);
                levelNumber++;
            }

            // totals
            var numMethods = 0;
            var numAccesses = 0;
            if (optionalTopLevel != null) {
                numMethods += optionalTopLevel.MethodFactories.Length;
                numAccesses += optionalTopLevel.AccessStateForges.Length;
            }

            foreach (var level in levelsList) {
                numMethods += level.MethodFactories.Length;
                numAccesses += level.AccessStateForges.Length;
            }

            AggregationLocalGroupByLevelForge[] levels = levelsList.ToArray();
            AggregationLocalGroupByPlanForge forge = new AggregationLocalGroupByPlanForge(numMethods, numAccesses, columns, optionalTopLevel, levels);
            return new AggregationLocalGroupByPlanDesc(forge, additionalForgeables);
        }