/// <summary> /// Ctor. /// </summary> /// <param name="aggregationNode">expression</param> /// <param name="factory">method factory</param> public AggregationServiceAggExpressionDesc( ExprAggregateNode aggregationNode, AggregationForgeFactory factory) { AggregationNode = aggregationNode; Factory = factory; }
/// <summary> /// Add an equivalent aggregation function node /// </summary> /// <param name="aggNodeToAdd">node to add</param> public void AddEquivalent(ExprAggregateNode aggNodeToAdd) { if (EquivalentNodes == null) { EquivalentNodes = new List<ExprAggregateNode>(); } EquivalentNodes.Add(aggNodeToAdd); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (!(node is ExprAvedevNode)) { return false; } return true; }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (node is ExprMinMaxAggrNode other) { return other.MinMaxTypeEnum == MinMaxTypeEnum && other.IsEver == IsEver; } return false; }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (!(node is ExprMedianNode)) { return(false); } return(true); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (!(node is ExprFirstLastEverNode)) { return false; } var other = (ExprFirstLastEverNode) node; return other.IsFirst == IsFirst; }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (node is ExprPlugInAggNode other) { return(other.AggregationFunctionName == AggregationFunctionName); } return(false); }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { var other = node as ExprMinMaxAggrNode; if (other == null) { return(false); } return(other._minMaxTypeEnum == this._minMaxTypeEnum && other._isEver == this._isEver); }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (node is ExprMinMaxAggrNode other) { return(other._minMaxTypeEnum == _minMaxTypeEnum && other._isEver == _isEver); } return(false); }
public TableColumnDescAgg( int positionInDeclaration, string columnName, ExprAggregateNode aggregation, EventType optionalAssociatedType) : base(positionInDeclaration, columnName) { Aggregation = aggregation; OptionalAssociatedType = optionalAssociatedType; }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { var other = node as ExprPlugInAggNode; if (other == null) { return(false); } return(((ExprAggregateNodeBase)other).AggregationFunctionName.Equals(AggregationFunctionName)); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (!(node is ExprAggMultiFunctionSortedMinMaxByNode)) { return(false); } ExprAggMultiFunctionSortedMinMaxByNode other = (ExprAggMultiFunctionSortedMinMaxByNode)node; return(_max == other._max && _containedType == other._containedType && _sortedwin == other._sortedwin && _ever == other._ever); }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { var other = node as ExprPlugInAggFunctionFactoryNode; if (other == null) { return(false); } return(other.AggregationFunctionName == AggregationFunctionName); }
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)); } }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (node is ExprAggMultiFunctionLinearAccessNode other) { return(_stateType == other._stateType && _containedType == other._containedType && _scalarCollectionComponentType == other._scalarCollectionComponentType); } return(false); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { if (!(node is ExprAggMultiFunctionSortedMinMaxByNode)) { return false; } var other = (ExprAggMultiFunctionSortedMinMaxByNode) node; return IsMax == other.IsMax && containedType == other.containedType && sortedwin == other.sortedwin && ever == other.ever; }
public static void ValidateAggregationType( AggregationMethodFactory requiredFactory, AggregationMethodFactory providedFactory) { if (!TypeHelper.IsSubclassOrImplementsInterface(providedFactory.GetType(), requiredFactory.GetType())) throw new ExprValidationException( "Not a '" + requiredFactory.AggregationExpression.AggregationFunctionName + "' aggregation"); ExprAggregateNode aggNodeRequired = requiredFactory.AggregationExpression; ExprAggregateNode aggNodeProvided = providedFactory.AggregationExpression; if (aggNodeRequired.IsDistinct != aggNodeProvided.IsDistinct) throw new ExprValidationException( "The aggregation declares " + (aggNodeRequired.IsDistinct ? "a" : "no") + " distinct and provided is " + (aggNodeProvided.IsDistinct ? "a" : "no") + " distinct"); }
private static string FindColumnNameForAggregation( IDictionary<ExprNode, string> selectClauseNamedNodes, IList<ExprDeclaredNode> declaredExpressions, ExprAggregateNode aggregationNode) { if (selectClauseNamedNodes.ContainsKey(aggregationNode)) { return selectClauseNamedNodes.Get(aggregationNode); } foreach (var node in declaredExpressions) { if (node.Body == aggregationNode) { return node.Prototype.Name; } } return null; }
public void QExprTableSubpropAccessor(ExprNode exprNode, string tableName, string subpropName, ExprAggregateNode aggregationExpression) { }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { throw new UnsupportedOperationException("not implemented"); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { return node is ExprLeavingAggNode; }
/// <summary> /// Return true if a expression aggregate node semantically equals the current node, or false if not. /// <para /> /// For use by the equalsNode implementation which compares the distinct flag. /// </summary> /// <param name="node">to compare to</param> /// <returns>true if semantically equal, or false if not equals</returns> protected abstract bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node);
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { return false; }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { return node is ExprMedianNode; }
public static AggregationServiceFactoryDesc GetService( IList<ExprAggregateNode> selectAggregateExprNodes, IDictionary<ExprNode, string> selectClauseNamedNodes, IList<ExprDeclaredNode> declaredExpressions, ExprNode[] groupByNodes, IList<ExprAggregateNode> havingAggregateExprNodes, IList<ExprAggregateNode> orderByAggregateExprNodes, IList<ExprAggregateNodeGroupKey> groupKeyExpressions, bool hasGroupByClause, Attribute[] annotations, VariableService variableService, bool isJoin, bool isDisallowNoReclaim, ExprNode whereClause, ExprNode havingClause, AggregationServiceFactoryService factoryService, EventType[] typesPerStream, AggregationGroupByRollupDesc groupByRollupDesc, string optionalContextName, IntoTableSpec intoTableSpec, TableService tableService, bool isUnidirectional, bool isFireAndForget, bool isOnSelect, EngineImportService engineImportService) { // No aggregates used, we do not need this service if ((selectAggregateExprNodes.IsEmpty()) && (havingAggregateExprNodes.IsEmpty())) { if (intoTableSpec != null) { throw new ExprValidationException("Into-table requires at least one aggregation function"); } return new AggregationServiceFactoryDesc( factoryService.GetNullAggregationService(), Collections.GetEmptyList<AggregationServiceAggExpressionDesc>(), Collections.GetEmptyList<ExprAggregateNodeGroupKey>()); } // Validate the absence of "prev" function in where-clause: // Since the "previous" function does not post remove stream results, disallow when used with aggregations. if ((whereClause != null) || (havingClause != null)) { var visitor = new ExprNodePreviousVisitorWParent(); if (whereClause != null) { whereClause.Accept(visitor); } if (havingClause != null) { havingClause.Accept(visitor); } if ((visitor.Previous != null) && (!visitor.Previous.IsEmpty())) { string funcname = visitor.Previous[0].Second.PreviousType.ToString().ToLowerInvariant(); throw new ExprValidationException( "The '" + funcname + "' function may not occur in the where-clause or having-clause of a statement with aggregations as 'previous' does not provide remove stream data; Use the 'first','last','window' or 'count' aggregation functions instead"); } } // Compile a map of aggregation nodes and equivalent-to aggregation nodes. // Equivalent-to functions are for example "select Sum(a*b), 5*Sum(a*b)". // Reducing the total number of aggregation functions. var aggregations = new List<AggregationServiceAggExpressionDesc>(); foreach (ExprAggregateNode selectAggNode in selectAggregateExprNodes) { AddEquivalent(selectAggNode, aggregations); } foreach (ExprAggregateNode havingAggNode in havingAggregateExprNodes) { AddEquivalent(havingAggNode, aggregations); } foreach (ExprAggregateNode orderByAggNode in orderByAggregateExprNodes) { AddEquivalent(orderByAggNode, aggregations); } // Construct a list of evaluation node for the aggregation functions (regular agg). // For example "Sum(2 * 3)" would make the sum an evaluation node. var methodAggEvaluatorsList = new List<ExprEvaluator>(); foreach (AggregationServiceAggExpressionDesc aggregation in aggregations) { ExprAggregateNode aggregateNode = aggregation.AggregationNode; if (!aggregateNode.Factory.IsAccessAggregation) { ExprEvaluator evaluator = aggregateNode.Factory.GetMethodAggregationEvaluator(typesPerStream.Length > 1, typesPerStream); methodAggEvaluatorsList.Add(evaluator); } } // determine local group-by, report when hook provided AggregationGroupByLocalGroupDesc localGroupDesc = AnalyzeLocalGroupBy( aggregations, groupByNodes, groupByRollupDesc, intoTableSpec); // determine binding AggregationServiceFactory serviceFactory; if (intoTableSpec != null) { // obtain metadata TableMetadata metadata = tableService.GetTableMetadata(intoTableSpec.Name); if (metadata == null) { throw new ExprValidationException( "Invalid into-table clause: Failed to find table by name '" + intoTableSpec.Name + "'"); } EPLValidationUtil.ValidateContextName( true, intoTableSpec.Name, metadata.ContextName, optionalContextName, false); // validate group keys Type[] groupByTypes = ExprNodeUtility.GetExprResultTypes(groupByNodes); ExprTableNodeUtil.ValidateExpressions( intoTableSpec.Name, groupByTypes, "group-by", groupByNodes, metadata.KeyTypes, "group-by"); // determine how this binds to existing aggregations, assign column numbers BindingMatchResult bindingMatchResult = MatchBindingsAssignColumnNumbers( intoTableSpec, metadata, aggregations, selectClauseNamedNodes, methodAggEvaluatorsList, declaredExpressions); // return factory if (!hasGroupByClause) { serviceFactory = factoryService.GetNoGroupWBinding( bindingMatchResult.Accessors, isJoin, bindingMatchResult.MethodPairs, intoTableSpec.Name, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents); } else { serviceFactory = factoryService.GetGroupWBinding( metadata, bindingMatchResult.MethodPairs, bindingMatchResult.Accessors, isJoin, intoTableSpec, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents, groupByRollupDesc); } return new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions); } // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation. int columnNumber = 0; foreach (AggregationServiceAggExpressionDesc entry in aggregations) { if (!entry.Factory.IsAccessAggregation) { entry.ColumnNum = columnNumber++; } } foreach (AggregationServiceAggExpressionDesc entry in aggregations) { if (entry.Factory.IsAccessAggregation) { entry.ColumnNum = columnNumber++; } } // determine method aggregation factories and Evaluators(non-access) ExprEvaluator[] methodAggEvaluators = methodAggEvaluatorsList.ToArray(); var methodAggFactories = new AggregationMethodFactory[methodAggEvaluators.Length]; int count = 0; foreach (AggregationServiceAggExpressionDesc aggregation in aggregations) { ExprAggregateNode aggregateNode = aggregation.AggregationNode; if (!aggregateNode.Factory.IsAccessAggregation) { methodAggFactories[count] = aggregateNode.Factory; count++; } } // handle access aggregations AggregationMultiFunctionAnalysisResult multiFunctionAggPlan = AggregationMultiFunctionAnalysisHelper.AnalyzeAccessAggregations(aggregations); AggregationAccessorSlotPair[] accessorPairs = multiFunctionAggPlan.AccessorPairs; AggregationStateFactory[] accessAggregations = multiFunctionAggPlan.StateFactories; // analyze local group by AggregationLocalGroupByPlan localGroupByPlan = null; if (localGroupDesc != null) { localGroupByPlan = AggregationGroupByLocalGroupByAnalyzer.Analyze( methodAggEvaluators, methodAggFactories, accessAggregations, localGroupDesc, groupByNodes, accessorPairs); try { var hook = (AggregationLocalLevelHook) TypeHelper.GetAnnotationHook( annotations, HookType.INTERNAL_AGGLOCALLEVEL, typeof (AggregationLocalLevelHook), engineImportService); if (hook != null) { hook.Planned(localGroupDesc, localGroupByPlan); } } catch (ExprValidationException) { throw new EPException("Failed to obtain hook for " + HookType.INTERNAL_AGGLOCALLEVEL); } } // Handle without a group-by clause: we group all into the same pot if (!hasGroupByClause) { if (localGroupByPlan != null) { serviceFactory = factoryService.GetNoGroupLocalGroupBy( isJoin, localGroupByPlan, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetNoGroupNoAccess( methodAggEvaluators, methodAggFactories, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0)) { serviceFactory = factoryService.GetNoGroupAccessOnly( accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetNoGroupAccessMixed( methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } else { bool hasNoReclaim = HintEnum.DISABLE_RECLAIM_GROUP.GetHint(annotations) != null; HintAttribute reclaimGroupAged = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations); HintAttribute reclaimGroupFrequency = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations); if (localGroupByPlan != null) { serviceFactory = factoryService.GetGroupLocalGroupBy( isJoin, localGroupByPlan, isUnidirectional, isFireAndForget, isOnSelect); } else { if (!isDisallowNoReclaim && hasNoReclaim) { if (groupByRollupDesc != null) { throw GetRollupReclaimEx(); } if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetGroupedNoReclaimNoAccess( groupByNodes, methodAggEvaluators, methodAggFactories, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0)) { serviceFactory = factoryService.GetGroupNoReclaimAccessOnly( groupByNodes, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetGroupNoReclaimMixed( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } else if (!isDisallowNoReclaim && reclaimGroupAged != null) { if (groupByRollupDesc != null) { throw GetRollupReclaimEx(); } serviceFactory = factoryService.GetGroupReclaimAged( groupByNodes, methodAggEvaluators, methodAggFactories, reclaimGroupAged, reclaimGroupFrequency, variableService, accessorPairs, accessAggregations, isJoin, optionalContextName, isUnidirectional, isFireAndForget, isOnSelect); } else if (groupByRollupDesc != null) { serviceFactory = factoryService.GetGroupReclaimMixableRollup( groupByNodes, groupByRollupDesc, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupByRollupDesc, isUnidirectional, isFireAndForget, isOnSelect); } else { if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetGroupReclaimNoAccess( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetGroupReclaimMixable( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } } } return new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions); }
public override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { return(false); }
protected override bool EqualsNodeAggregateMethodOnly(ExprAggregateNode node) { return(node is ExprRateAggNode); }
/// <summary> /// Produces an aggregation service for use with match-recognice. /// </summary> /// <param name="numStreams">number of streams</param> /// <param name="measureExprNodesPerStream">measure nodes</param> /// <param name="typesPerStream">type information</param> /// <exception cref="ExprValidationException">for validation errors</exception> /// <returns>service</returns> public static AggregationServiceMatchRecognizeFactoryDesc GetServiceMatchRecognize( int numStreams, IDictionary<int, IList<ExprAggregateNode>> measureExprNodesPerStream, EventType[] typesPerStream) { var equivalencyListPerStream = new OrderedDictionary<int, List<AggregationServiceAggExpressionDesc>>(); foreach (var entry in measureExprNodesPerStream) { var equivalencyList = new List<AggregationServiceAggExpressionDesc>(); equivalencyListPerStream.Put(entry.Key, equivalencyList); foreach (ExprAggregateNode selectAggNode in entry.Value) { AddEquivalent(selectAggNode, equivalencyList); } } var aggregatorsPerStream = new LinkedHashMap<int, AggregationMethodFactory[]>(); var evaluatorsPerStream = new Dictionary<int, ExprEvaluator[]>(); foreach (var equivalencyPerStream in equivalencyListPerStream) { int index = 0; int stream = equivalencyPerStream.Key; var aggregators = new AggregationMethodFactory[equivalencyPerStream.Value.Count]; aggregatorsPerStream.Put(stream, aggregators); var evaluators = new ExprEvaluator[equivalencyPerStream.Value.Count]; evaluatorsPerStream.Put(stream, evaluators); foreach (AggregationServiceAggExpressionDesc aggregation in equivalencyPerStream.Value) { ExprAggregateNode aggregateNode = aggregation.AggregationNode; if (aggregateNode.ChildNodes.Count > 1) { evaluators[index] = ExprMethodAggUtil.GetMultiNodeEvaluator( aggregateNode.ChildNodes, typesPerStream.Length > 1, typesPerStream); } else if (aggregateNode.ChildNodes.Count > 0) { // Use the evaluation node under the aggregation node to obtain the aggregation value evaluators[index] = aggregateNode.ChildNodes[0].ExprEvaluator; } else { // For aggregation that doesn't evaluate any particular sub-expression, return null on evaluation evaluators[index] = new ProxyExprEvaluator { ProcEvaluate = eventParams => null, ProcReturnType = () => null }; } aggregators[index] = aggregateNode.Factory; index++; } } // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation. int columnNumber = 0; var allExpressions = new List<AggregationServiceAggExpressionDesc>(); foreach (var equivalencyPerStream in equivalencyListPerStream) { foreach (AggregationServiceAggExpressionDesc entry in equivalencyPerStream.Value) { entry.ColumnNum = columnNumber++; } allExpressions.AddAll(equivalencyPerStream.Value); } var factory = new AggregationServiceMatchRecognizeFactoryImpl( numStreams, aggregatorsPerStream, evaluatorsPerStream); return new AggregationServiceMatchRecognizeFactoryDesc(factory, allExpressions); }