private OnTriggerActivatorDesc ActivatorNamedWindow( NamedWindowConsumerStreamSpec namedSpec, StatementCompileTimeServices services) { var namedWindow = namedSpec.NamedWindow; var triggerEventTypeName = namedSpec.NamedWindow.EventType.Name; var typesFilterValidation = new StreamTypeServiceImpl( namedWindow.EventType, namedSpec.OptionalStreamName, false); var filterSingle = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(namedSpec.FilterExpressions); var filterQueryGraph = EPLValidationUtil.ValidateFilterGetQueryGraphSafe( filterSingle, typesFilterValidation, @base.StatementRawInfo, services); var activator = new ViewableActivatorNamedWindowForge( namedSpec, namedWindow, filterSingle, filterQueryGraph, false, namedSpec.OptPropertyEvaluator); var activatorResultEventType = namedWindow.EventType; if (namedSpec.OptPropertyEvaluator != null) { activatorResultEventType = namedSpec.OptPropertyEvaluator.FragmentEventType; } return new OnTriggerActivatorDesc(activator, triggerEventTypeName, activatorResultEventType); }
public void ValidatePositionals(ExprValidationContext validationContext) { ExprAggregateNodeParamDesc paramDesc = ExprAggregateNodeUtil.GetValidatePositionalParams(ChildNodes, true); if (validationContext.StatementRawInfo.StatementType == StatementType.CREATE_TABLE && (paramDesc.OptLocalGroupBy != null || paramDesc.OptionalFilter != null)) { throw new ExprValidationException( "The 'group_by' and 'filter' parameter is not allowed in create-table statements"); } optionalAggregateLocalGroupByDesc = paramDesc.OptLocalGroupBy; optionalFilter = paramDesc.OptionalFilter; if (optionalAggregateLocalGroupByDesc != null) { ExprNodeUtilityValidate.ValidateNoSpecialsGroupByExpressions( optionalAggregateLocalGroupByDesc.PartitionExpressions); } if (optionalFilter != null) { ExprNodeUtilityValidate.ValidateNoSpecialsGroupByExpressions(new[] {optionalFilter}); } if (optionalFilter != null && IsFilterExpressionAsLastParameter) { if (paramDesc.PositionalParams.Length > 1) { throw new ExprValidationException("Only a single filter expression can be provided"); } positionalParams = ExprNodeUtilityMake.AddExpression(paramDesc.PositionalParams, optionalFilter); } else { positionalParams = paramDesc.PositionalParams; } }
private static void LogFilterPlans( IList<ExprNode> validatedNodes, FilterSpecPlanForge plan, EventType eventType, string optionalStreamName, StatementRawInfo statementRawInfo) { var buf = new StringBuilder(); buf .Append("Filter plan for statement '") .Append(statementRawInfo.StatementName) .Append("' filtering event type '") .Append(eventType.Name + "'"); if (optionalStreamName != null) { buf.Append(" alias '" + optionalStreamName + "'"); } if (validatedNodes.IsEmpty()) { buf.Append(" empty"); } else { var andNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(validatedNodes); var expression = ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(andNode); buf .Append(" expression '") .Append(expression) .Append("' for ") .Append(plan.Paths.Length) .Append(" paths"); } buf.Append(Environment.NewLine); plan.AppendPlan(buf); Log.Info(buf.ToString()); }
public static IList<ExprNode> ValidateAllowSubquery( ExprNodeOrigin exprNodeOrigin, IList<ExprNode> exprNodes, StreamTypeService streamTypeService, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { IList<ExprNode> validatedNodes = new List<ExprNode>(); ExprValidationContext validationContext = new ExprValidationContextBuilder(streamTypeService, statementRawInfo, services) .WithAllowBindingConsumption(true) .WithIsFilterExpression(true) .Build(); foreach (var node in exprNodes) { // Determine subselects var visitor = new ExprNodeSubselectDeclaredDotVisitor(); node.Accept(visitor); // Compile subselects if (!visitor.Subselects.IsEmpty()) { // The outer event type is the filtered-type itself foreach (var subselect in visitor.Subselects) { try { SubSelectHelperFilters.HandleSubselectSelectClauses( subselect, streamTypeService.EventTypes[0], streamTypeService.StreamNames[0], streamTypeService.StreamNames[0], taggedEventTypes, arrayEventTypes, statementRawInfo, services); } catch (ExprValidationException ex) { throw new ExprValidationException( "Failed to validate " + ExprNodeUtilityMake.GetSubqueryInfoText(subselect) + ": " + ex.Message, ex); } } } var validated = ExprNodeUtilityValidate.GetValidatedSubtree(exprNodeOrigin, node, validationContext); validatedNodes.Add(validated); if (validated.Forge.EvaluationType != typeof(bool?) && validated.Forge.EvaluationType != typeof(bool)) { throw new ExprValidationException( "Filter expression not returning a boolean value: '" + ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(validated) + "'"); } } return validatedNodes; }
public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext) { string message = "The nth aggregation function requires two parameters, an expression returning aggregation values and a numeric index constant"; if (this.positionalParams.Length != 2) { throw new ExprValidationException(message); } ExprNode first = this.positionalParams[0]; ExprNode second = this.positionalParams[1]; if (!second.Forge.ForgeConstantType.IsCompileTimeConstant) { throw new ExprValidationException(message); } var num = second.Forge.ExprEvaluator.Evaluate(null, true, null); int size = num.AsInt32(); if (optionalFilter != null) { this.positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } var childType = first.Forge.EvaluationType; var serde = validationContext.SerdeResolver.SerdeForAggregationDistinct(childType, validationContext.StatementRawInfo); var distinctValueSerde = isDistinct ? serde : null; return new AggregationForgeFactoryNth(this, childType, serde, distinctValueSerde, size); }
public ICollection<object> EvaluateGetROCollectionScalar( EventBean[] eventsPerStream, bool isNewData, ExprEvaluatorContext context) { throw ExprNodeUtilityMake.MakeUnsupportedCompileTime(); }
public object Evaluate( EventBean[] eventsPerStream, bool isNewData, ExprEvaluatorContext context) { throw ExprNodeUtilityMake.MakeUnsupportedCompileTime(); }
private static FilterSpecPlanPathTripletForge HandleOrAlternateExpression( ExprOrNode orNode, bool performConditionPlanning, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes, ISet <string> allTagNamesOrdered, string statementName, StreamTypeService streamTypeService, StatementRawInfo raw, StatementCompileTimeServices services) { IList <ExprNode> valueExpressions = new List <ExprNode>(orNode.ChildNodes.Length); foreach (ExprNode child in orNode.ChildNodes) { FilterSpecExprNodeVisitorValueLimitedExpr visitor = new FilterSpecExprNodeVisitorValueLimitedExpr(); child.Accept(visitor); if (visitor.IsLimited) { valueExpressions.Add(child); } } // The or-node must have a single constituent and one or more value expressions if (orNode.ChildNodes.Length != valueExpressions.Count + 1) { return(null); } IList <ExprNode> constituents = new List <ExprNode>(orNode.ChildNodes); constituents.RemoveAll(valueExpressions); if (constituents.Count != 1) { throw new IllegalStateException("Found multiple constituents"); } ExprNode constituent = constituents[0]; FilterSpecPlanPathTripletForge triplet = MakeFilterParam( constituent, performConditionPlanning, taggedEventTypes, arrayEventTypes, allTagNamesOrdered, statementName, streamTypeService, raw, services); if (triplet == null) { return(null); } ExprNode controlConfirm = ExprNodeUtilityMake.ConnectExpressionsByLogicalOrWhenNeeded(valueExpressions); return(new FilterSpecPlanPathTripletForge(triplet.Param, controlConfirm)); }
public object Evaluate( EventBean[] eventsPerStream, bool isNewData, ICollection<EventBean> matchingEvents, ExprEvaluatorContext exprEvaluatorContext) { throw ExprNodeUtilityMake.MakeUnsupportedCompileTime(); }
public void Init( ViewFactoryContext viewFactoryContext, EPStatementInitServices services) { Comparer = ExprNodeUtilityMake.GetComparatorHashableMultiKeys( SortCriteriaTypes, IsUseCollatorSort, IsDescendingValues); // hashable-key comparator since we may remove sort keys }
private static ExprAndNode MakeValidateAndNode( IList<ExprNode> remainingExprNodes, FilterSpecCompilerArgs args) { var andNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalAnd(remainingExprNodes); var validationContext = new ExprValidationContextBuilder(args.streamTypeService, args.statementRawInfo, args.compileTimeServices) .WithAllowBindingConsumption(true) .WithContextDescriptor(args.contextDescriptor) .Build(); andNode.Validate(validationContext); return andNode; }
internal static ExprNode DecomposePopulateConsolidate( FilterSpecParaForgeMap filterParamExprMap, bool performConditionPlanning, IList<ExprNode> validatedNodes, FilterSpecCompilerArgs args) { var constituents = DecomposeCheckAggregation(validatedNodes); // Remove constituents that are value-expressions ExprNode topLevelControl = null; if (performConditionPlanning) { IList<ExprNode> valueOnlyConstituents = null; foreach (var node in constituents) { var visitor = new FilterSpecExprNodeVisitorValueLimitedExpr(); node.Accept(visitor); if (visitor.IsLimited) { if (valueOnlyConstituents == null) { valueOnlyConstituents = new List<ExprNode>(); } valueOnlyConstituents.Add(node); } } if (valueOnlyConstituents != null) { constituents.RemoveAll(valueOnlyConstituents); topLevelControl = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(valueOnlyConstituents); } } // Make filter parameter for each expression node, if it can be optimized foreach (var constituent in constituents) { var triplet = FilterSpecCompilerIndexPlannerConstituent.MakeFilterParam( constituent, performConditionPlanning, args.taggedEventTypes, args.arrayEventTypes, args.allTagNamesOrdered, args.statementRawInfo.StatementName, args.streamTypeService, args.statementRawInfo, args.compileTimeServices); filterParamExprMap.Put(constituent, triplet); // accepts null values as the expression may not be optimized } // Consolidate entries as possible, i.e. (a != 5 and a != 6) is (a not in (5,6)) // Removes duplicates for same property and same filter operator for filter service index optimizations FilterSpecCompilerConsolidateUtil.Consolidate(filterParamExprMap, args.statementRawInfo.StatementName); return topLevelControl; }
public override ExprNode Validate(ExprValidationContext validationContext) { if (ChildNodes.Length != 2) { throw new ExprValidationException("Prior node must have 2 parameters"); } if (!ChildNodes[0].Forge.ForgeConstantType.IsCompileTimeConstant) { throw new ExprValidationException( "Prior function requires a constant-value integer-typed index expression as the first parameter"); } // Child identifier nodes receive optional event ExprNodeUtilityMake.SetChildIdentNodesOptionalEvent(this); var constantNode = ChildNodes[0]; var constantNodeType = constantNode.Forge.EvaluationType; if (constantNodeType != typeof(int?) && constantNodeType != typeof(int)) { throw new ExprValidationException("Prior function requires an integer index parameter"); } var value = constantNode.Forge.ExprEvaluator.Evaluate(null, false, null); ConstantIndexNumber = value.AsInt32(); InnerForge = ChildNodes[1].Forge; // Determine stream number if (ChildNodes[1] is ExprIdentNode) { var identNode = (ExprIdentNode) ChildNodes[1]; StreamNumber = identNode.StreamId; EvaluationType = InnerForge.EvaluationType.GetBoxedType(); } else if (ChildNodes[1] is ExprStreamUnderlyingNode) { var streamNode = (ExprStreamUnderlyingNode) ChildNodes[1]; StreamNumber = streamNode.StreamId; EvaluationType = InnerForge.EvaluationType.GetBoxedType(); } else { throw new ExprValidationException("Previous function requires an event property as parameter"); } // add request if (validationContext.ViewResourceDelegate == null) { throw new ExprValidationException("Prior function cannot be used in this context"); } validationContext.ViewResourceDelegate.AddPriorNodeRequest(this); priorStrategyFieldName = validationContext.MemberNames.PriorStrategy(StreamNumber); return null; }
private static ExprNode GetFilterExpressionInclOnClause( ExprNode whereClause, OuterJoinDesc[] outerJoinDescList, StatementRawInfo rawInfo, StatementCompileTimeServices services) { if (whereClause == null) { // no need to add as query planning is fully based on on-clause return null; } if (outerJoinDescList.Length == 0) { // not an outer-join syntax return whereClause; } if (!OuterJoinDesc.ConsistsOfAllInnerJoins(outerJoinDescList)) { // all-inner joins return whereClause; } var hasOnClauses = OuterJoinDesc.HasOnClauses(outerJoinDescList); if (!hasOnClauses) { return whereClause; } IList<ExprNode> expressions = new List<ExprNode>(); expressions.Add(whereClause); foreach (var outerJoinDesc in outerJoinDescList) { if (outerJoinDesc.OptLeftNode != null) { expressions.Add(outerJoinDesc.MakeExprNode(rawInfo, services)); } } var andNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalAnd(expressions); try { andNode.Validate(null); } catch (ExprValidationException ex) { throw new EPRuntimeException("Unexpected exception validating expression: " + ex.Message, ex); } return andNode; }
public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext) { string message = "The nth aggregation function requires two parameters, an expression returning aggregation values and a numeric index constant"; if (this.positionalParams.Length != 2) { throw new ExprValidationException(message); } ExprNode first = this.positionalParams[0]; ExprNode second = this.positionalParams[1]; if (!second.Forge.ForgeConstantType.IsCompileTimeConstant) { throw new ExprValidationException(message); } var num = second.Forge.ExprEvaluator.Evaluate(null, true, null); int size = num.AsInt32(); if (optionalFilter != null) { this.positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } return new AggregationFactoryMethodNth(this, first.Forge.EvaluationType, size); }
private static CombPermutationTriplets ComputePermutation( FilterSpecParaForgeMap filterParamExprMap, object[] permutation, OrChildNode[][] orChildNodes, bool hasControl, FilterSpecCompilerArgs args) { var mapAll = new FilterSpecParaForgeMap(); mapAll.Add(filterParamExprMap); // combine IList <ExprNode> nvPerOr = new List <ExprNode>(permutation.Length); IList <ExprNode> negatingPath = new List <ExprNode>(permutation.Length); for (var orNodeNum = 0; orNodeNum < permutation.Length; orNodeNum++) { int orChildNodeNum = permutation[orNodeNum].AsInt32(); var current = orChildNodes[orNodeNum][orChildNodeNum]; if (current is OrChildNodeNV) { var nv = (OrChildNodeNV)current; mapAll.Add(nv.Map); if (current is OrChildNodeNVNegated) { negatingPath.Add(((OrChildNodeNVNegated)current).Control); } } else { var v = (OrChildNodeV)current; negatingPath.Add(v.Node); } var orChildNodesForCurrent = orChildNodes[orNodeNum]; foreach (var other in orChildNodesForCurrent) { if (current == other) { continue; } if (other is OrChildNodeV) { var v = (OrChildNodeV)other; var not = new ExprNotNode(); not.AddChildNode(v.Node); nvPerOr.Add(not); } } } // consolidate across FilterSpecCompilerConsolidateUtil.Consolidate(mapAll, args.statementRawInfo.StatementName); IList <FilterSpecPlanPathTripletForge> triplets = new List <FilterSpecPlanPathTripletForge>(mapAll.Triplets); var countUnassigned = mapAll.CountUnassignedExpressions(); if (countUnassigned != 0) { var triplet = MakeRemainingNode(mapAll.UnassignedExpressions, args); triplets.Add(triplet); } // without conditions we are done var tripletsArray = triplets.ToArray(); if (!hasControl) { return(new CombPermutationTriplets(tripletsArray, null)); } var negatingNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(negatingPath); var excluded = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(nvPerOr); var merged = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(negatingNode, excluded); return(new CombPermutationTriplets(tripletsArray, merged)); }
public void Apply(QueryGraphForge filterQueryGraph) { if (targetStreamNum == parameterStreamNum) { return; } var targetStartExpr = ExprNodeUtilityMake.MakeExprIdentNode( typesPerStream, targetStreamNum, targetStartProp); var targetEndExpr = ExprNodeUtilityMake.MakeExprIdentNode(typesPerStream, targetStreamNum, targetEndProp); var parameterStartExpr = ExprNodeUtilityMake.MakeExprIdentNode( typesPerStream, parameterStreamNum, parameterStartProp); var parameterEndExpr = ExprNodeUtilityMake.MakeExprIdentNode( typesPerStream, parameterStreamNum, parameterEndProp); if (targetStartExpr.Forge.EvaluationType != parameterStartExpr.Forge.EvaluationType) { return; } if (currentMethod == DateTimeMethodEnum.BEFORE) { // a.end < b.start filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetEndExpr, parameterStreamNum, parameterStartExpr, RelationalOpEnum.LT); } else if (currentMethod == DateTimeMethodEnum.AFTER) { // a.start > b.end filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetStartExpr, parameterStreamNum, parameterEndExpr, RelationalOpEnum.GT); } else if (currentMethod == DateTimeMethodEnum.COINCIDES) { // a.startTimestamp = b.startTimestamp and a.endTimestamp = b.endTimestamp filterQueryGraph.AddStrictEquals( targetStreamNum, targetStartProp, targetStartExpr, parameterStreamNum, parameterStartProp, parameterStartExpr); var noDuration = parameterEndProp.Equals(parameterStartProp) && targetEndProp.Equals(targetStartProp); if (!noDuration) { var leftEndExpr = ExprNodeUtilityMake.MakeExprIdentNode( typesPerStream, targetStreamNum, targetEndProp); var rightEndExpr = ExprNodeUtilityMake.MakeExprIdentNode( typesPerStream, parameterStreamNum, parameterEndProp); filterQueryGraph.AddStrictEquals( targetStreamNum, targetEndProp, leftEndExpr, parameterStreamNum, parameterEndProp, rightEndExpr); } } else if (currentMethod == DateTimeMethodEnum.DURING || currentMethod == DateTimeMethodEnum.INCLUDES) { // DURING: b.startTimestamp < a.startTimestamp <= a.endTimestamp < b.endTimestamp // INCLUDES: a.startTimestamp < b.startTimestamp <= b.endTimestamp < a.endTimestamp var relop = currentMethod == DateTimeMethodEnum.DURING ? RelationalOpEnum.LT : RelationalOpEnum.GT; filterQueryGraph.AddRelationalOpStrict( parameterStreamNum, parameterStartExpr, targetStreamNum, targetStartExpr, relop); filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetEndExpr, parameterStreamNum, parameterEndExpr, relop); } else if (currentMethod == DateTimeMethodEnum.FINISHES || currentMethod == DateTimeMethodEnum.FINISHEDBY) { // FINISHES: b.startTimestamp < a.startTimestamp and a.endTimestamp = b.endTimestamp // FINISHEDBY: a.startTimestamp < b.startTimestamp and a.endTimestamp = b.endTimestamp var relop = currentMethod == DateTimeMethodEnum.FINISHES ? RelationalOpEnum.LT : RelationalOpEnum.GT; filterQueryGraph.AddRelationalOpStrict( parameterStreamNum, parameterStartExpr, targetStreamNum, targetStartExpr, relop); filterQueryGraph.AddStrictEquals( targetStreamNum, targetEndProp, targetEndExpr, parameterStreamNum, parameterEndProp, parameterEndExpr); } else if (currentMethod == DateTimeMethodEnum.MEETS) { // a.endTimestamp = b.startTimestamp filterQueryGraph.AddStrictEquals( targetStreamNum, targetEndProp, targetEndExpr, parameterStreamNum, parameterStartProp, parameterStartExpr); } else if (currentMethod == DateTimeMethodEnum.METBY) { // a.startTimestamp = b.endTimestamp filterQueryGraph.AddStrictEquals( targetStreamNum, targetStartProp, targetStartExpr, parameterStreamNum, parameterEndProp, parameterEndExpr); } else if (currentMethod == DateTimeMethodEnum.OVERLAPS || currentMethod == DateTimeMethodEnum.OVERLAPPEDBY) { // OVERLAPS: a.startTimestamp < b.startTimestamp < a.endTimestamp < b.endTimestamp // OVERLAPPEDBY: b.startTimestamp < a.startTimestamp < b.endTimestamp < a.endTimestamp var relop = currentMethod == DateTimeMethodEnum.OVERLAPS ? RelationalOpEnum.LT : RelationalOpEnum.GT; filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetStartExpr, parameterStreamNum, parameterStartExpr, relop); filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetEndExpr, parameterStreamNum, parameterEndExpr, relop); if (currentMethod == DateTimeMethodEnum.OVERLAPS) { filterQueryGraph.AddRelationalOpStrict( parameterStreamNum, parameterStartExpr, targetStreamNum, targetEndExpr, RelationalOpEnum.LT); } else { filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetStartExpr, parameterStreamNum, parameterEndExpr, RelationalOpEnum.LT); } } else if (currentMethod == DateTimeMethodEnum.STARTS || currentMethod == DateTimeMethodEnum.STARTEDBY) { // STARTS: a.startTimestamp = b.startTimestamp and a.endTimestamp < b.endTimestamp // STARTEDBY: a.startTimestamp = b.startTimestamp and b.endTimestamp < a.endTimestamp filterQueryGraph.AddStrictEquals( targetStreamNum, targetStartProp, targetStartExpr, parameterStreamNum, parameterStartProp, parameterStartExpr); var relop = currentMethod == DateTimeMethodEnum.STARTS ? RelationalOpEnum.LT : RelationalOpEnum.GT; filterQueryGraph.AddRelationalOpStrict( targetStreamNum, targetEndExpr, parameterStreamNum, parameterEndExpr, relop); } }
public static SubSelectActivationDesc CreateSubSelectActivation( IList <FilterSpecCompiled> filterSpecCompileds, IList <NamedWindowConsumerStreamSpec> namedWindowConsumers, StatementBaseInfo statement, StatementCompileTimeServices services) { IDictionary <ExprSubselectNode, SubSelectActivationPlan> result = new LinkedHashMap <ExprSubselectNode, SubSelectActivationPlan>(); IList <StmtClassForgeableFactory> additionalForgeables = new List <StmtClassForgeableFactory>(); // Process all subselect expression nodes foreach (ExprSubselectNode subselect in statement.StatementSpec.SubselectNodes) { StatementSpecCompiled statementSpec = subselect.StatementSpecCompiled; StreamSpecCompiled streamSpec = statementSpec.StreamSpecs[0]; int subqueryNumber = subselect.SubselectNumber; if (subqueryNumber == -1) { throw new IllegalStateException("Unexpected subquery"); } ViewFactoryForgeArgs args = new ViewFactoryForgeArgs(-1, true, subqueryNumber, streamSpec.Options, null, statement.StatementRawInfo, services); if (streamSpec is FilterStreamSpecCompiled) { if (services.IsFireAndForget) { throw new ExprValidationException("Fire-and-forget queries only allow subqueries against named windows and tables"); } FilterStreamSpecCompiled filterStreamSpec = (FilterStreamSpecCompiled)statementSpec.StreamSpecs[0]; // Register filter, create view factories ViewableActivatorForge activatorDeactivator = new ViewableActivatorFilterForge( filterStreamSpec.FilterSpecCompiled, false, null, true, subqueryNumber); ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges( streamSpec.ViewSpecs, args, filterStreamSpec.FilterSpecCompiled.ResultEventType); IList <ViewFactoryForge> forges = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); EventType eventType = forges.IsEmpty() ? filterStreamSpec.FilterSpecCompiled.ResultEventType : forges[forges.Count - 1].EventType; subselect.RawEventType = eventType; filterSpecCompileds.Add(filterStreamSpec.FilterSpecCompiled); // Add lookup to list, for later starts result.Put( subselect, new SubSelectActivationPlan(filterStreamSpec.FilterSpecCompiled.ResultEventType, forges, activatorDeactivator, streamSpec)); } else if (streamSpec is TableQueryStreamSpec) { TableQueryStreamSpec table = (TableQueryStreamSpec)streamSpec; ExprNode filter = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(table.FilterExpressions); ViewableActivatorForge viewableActivator = new ViewableActivatorTableForge(table.Table, filter); result.Put( subselect, new SubSelectActivationPlan(table.Table.InternalEventType, EmptyList <ViewFactoryForge> .Instance, viewableActivator, streamSpec)); subselect.RawEventType = table.Table.InternalEventType; } else { NamedWindowConsumerStreamSpec namedSpec = (NamedWindowConsumerStreamSpec)statementSpec.StreamSpecs[0]; namedWindowConsumers.Add(namedSpec); NamedWindowMetaData nwinfo = namedSpec.NamedWindow; EventType namedWindowType = nwinfo.EventType; if (namedSpec.OptPropertyEvaluator != null) { namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType; } // if named-window index sharing is disabled (the default) or filter expressions are provided then consume the insert-remove stream bool disableIndexShare = HintEnum.DISABLE_WINDOW_SUBQUERY_INDEXSHARE.GetHint(statement.StatementRawInfo.Annotations) != null; bool processorDisableIndexShare = !namedSpec.NamedWindow.IsEnableIndexShare; if (disableIndexShare && namedSpec.NamedWindow.IsVirtualDataWindow) { disableIndexShare = false; } if ((!namedSpec.FilterExpressions.IsEmpty() || processorDisableIndexShare || disableIndexShare) && (!services.IsFireAndForget)) { ExprNode filterEvaluator = null; if (!namedSpec.FilterExpressions.IsEmpty()) { filterEvaluator = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(namedSpec.FilterExpressions); } ViewableActivatorForge activatorNamedWindow = new ViewableActivatorNamedWindowForge( namedSpec, nwinfo, filterEvaluator, null, true, namedSpec.OptPropertyEvaluator); ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, namedWindowType); IList <ViewFactoryForge> forges = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); subselect.RawEventType = forges.IsEmpty() ? namedWindowType : forges[forges.Count - 1].EventType; result.Put(subselect, new SubSelectActivationPlan(namedWindowType, forges, activatorNamedWindow, streamSpec)); } else { // else if there are no named window stream filter expressions and index sharing is enabled ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, namedWindowType); IList <ViewFactoryForge> forges = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); subselect.RawEventType = namedWindowType; ViewableActivatorForge activatorNamedWindow = new ViewableActivatorSubselectNoneForge(namedWindowType); result.Put(subselect, new SubSelectActivationPlan(namedWindowType, forges, activatorNamedWindow, streamSpec)); } } } return(new SubSelectActivationDesc(result, additionalForgeables)); }
public double GetFilterValue( MatchedEventMap matchedEvents, ExprEvaluatorContext exprEvaluatorContext) { throw ExprNodeUtilityMake.MakeUnsupportedCompileTime(); }
public void Apply(QueryGraphForge queryGraph) { var targetExpr = ExprNodeUtilityMake.MakeExprIdentNode(typesPerStream, targetStreamNum, targetPropertyName); RangeFilterAnalyzer.Apply(targetExpr, start, end, includeLow, includeHigh, false, queryGraph); }
public FAFQueryMethodSelectDesc( StatementSpecCompiled statementSpec, Compilable compilable, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { Annotations = statementSpec.Annotations; ContextName = statementSpec.Raw.OptionalContextName; var queryPlanLogging = services.Configuration.Common.Logging.IsEnableQueryPlan; if (queryPlanLogging) { QUERY_PLAN_LOG.Info("Query plans for Fire-and-forget query '" + compilable.ToEPL() + "'"); } HasTableAccess = statementSpec.TableAccessNodes != null && statementSpec.TableAccessNodes.Count > 0; foreach (var streamSpec in statementSpec.StreamSpecs) { HasTableAccess |= streamSpec is TableQueryStreamSpec; } HasTableAccess |= StatementLifecycleSvcUtil.IsSubqueryWithTable( statementSpec.SubselectNodes, services.TableCompileTimeResolver); IsDistinct = statementSpec.SelectClauseCompiled.IsDistinct; FAFQueryMethodHelper.ValidateFAFQuery(statementSpec); var numStreams = statementSpec.StreamSpecs.Length; var typesPerStream = new EventType[numStreams]; var namesPerStream = new string[numStreams]; var eventTypeNames = new string[numStreams]; Processors = new FireAndForgetProcessorForge[numStreams]; ConsumerFilters = new ExprNode[numStreams]; // check context partition use if (statementSpec.Raw.OptionalContextName != null) { if (numStreams > 1) { throw new ExprValidationException( "Joins in runtime queries for context partitions are not supported"); } } // resolve types and processors for (var i = 0; i < numStreams; i++) { var streamSpec = statementSpec.StreamSpecs[i]; Processors[i] = FireAndForgetProcessorForgeFactory.ValidateResolveProcessor(streamSpec); if (numStreams > 1 && Processors[i].ContextName != null) { throw new ExprValidationException( "Joins against named windows that are under context are not supported"); } var streamName = Processors[i].NamedWindowOrTableName; if (streamSpec.OptionalStreamName != null) { streamName = streamSpec.OptionalStreamName; } namesPerStream[i] = streamName; typesPerStream[i] = Processors[i].EventTypeRspInputEvents; eventTypeNames[i] = typesPerStream[i].Name; IList<ExprNode> consumerFilterExprs; if (streamSpec is NamedWindowConsumerStreamSpec) { var namedSpec = (NamedWindowConsumerStreamSpec) streamSpec; consumerFilterExprs = namedSpec.FilterExpressions; } else { var tableSpec = (TableQueryStreamSpec) streamSpec; consumerFilterExprs = tableSpec.FilterExpressions; } ConsumerFilters[i] = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(consumerFilterExprs); } // compile filter to optimize access to named window var optionalStreamsIfAny = OuterJoinAnalyzer.OptionalStreamsIfAny(statementSpec.Raw.OuterJoinDescList); var types = new StreamTypeServiceImpl( typesPerStream, namesPerStream, new bool[numStreams], false, optionalStreamsIfAny); var excludePlanHint = ExcludePlanHint.GetHint(types.StreamNames, statementRawInfo, services); QueryGraph = new QueryGraphForge(numStreams, excludePlanHint, false); if (statementSpec.Raw.WhereClause != null) { for (var i = 0; i < numStreams; i++) { try { var validationContext = new ExprValidationContextBuilder(types, statementRawInfo, services) .WithAllowBindingConsumption(true) .WithIsFilterExpression(true) .Build(); var validated = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.FILTER, statementSpec.Raw.WhereClause, validationContext); FilterExprAnalyzer.Analyze(validated, QueryGraph, false); } catch (Exception ex) { Log.Warn("Unexpected exception analyzing filter paths: " + ex.Message, ex); } } } // handle subselects // first we create streams for subselects, if there are any var @base = new StatementBaseInfo(compilable, statementSpec, null, statementRawInfo, null); var subqueryNamedWindowConsumers = new List<NamedWindowConsumerStreamSpec>(); SubSelectActivationDesc subSelectActivationDesc = SubSelectHelperActivations.CreateSubSelectActivation( EmptyList<FilterSpecCompiled>.Instance, subqueryNamedWindowConsumers, @base, services); IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation = subSelectActivationDesc.Subselects; AdditionalForgeables.AddAll(subSelectActivationDesc.AdditionalForgeables); SubSelectHelperForgePlan subSelectForgePlan = SubSelectHelperForgePlanner.PlanSubSelect( @base, subselectActivation, namesPerStream, typesPerStream, eventTypeNames, services); SubselectForges = subSelectForgePlan.Subselects; AdditionalForgeables.AddAll(subSelectForgePlan.AdditionalForgeables); // obtain result set processor var isIStreamOnly = new bool[namesPerStream.Length]; isIStreamOnly.Fill(true); StreamTypeService typeService = new StreamTypeServiceImpl( typesPerStream, namesPerStream, isIStreamOnly, true, optionalStreamsIfAny); WhereClause = EPStatementStartMethodHelperValidate.ValidateNodes( statementSpec.Raw, typeService, null, statementRawInfo, services); var resultSetSpec = new ResultSetSpec(statementSpec); ResultSetProcessor = ResultSetProcessorFactoryFactory.GetProcessorPrototype( resultSetSpec, typeService, null, new bool[0], true, null, true, false, statementRawInfo, services); AdditionalForgeables.AddAll(ResultSetProcessor.AdditionalForgeables); // plan table access TableAccessForges = ExprTableEvalHelperPlan.PlanTableAccess(statementSpec.Raw.TableExpressions); // plan joins or simple queries if (numStreams > 1) { var streamJoinAnalysisResult = new StreamJoinAnalysisResultCompileTime(numStreams); CompatExtensions.Fill(streamJoinAnalysisResult.NamedWindowsPerStream, (NamedWindowMetaData) null); for (var i = 0; i < numStreams; i++) { var uniqueIndexes = Processors[i].UniqueIndexes; streamJoinAnalysisResult.UniqueKeys[i] = uniqueIndexes; } var hasAggregations = ResultSetProcessor.ResultSetProcessorType.IsAggregated(); var desc = JoinSetComposerPrototypeForgeFactory.MakeComposerPrototype( statementSpec, streamJoinAnalysisResult, types, new HistoricalViewableDesc(numStreams), true, hasAggregations, statementRawInfo, services); AdditionalForgeables.AddAll(desc.AdditionalForgeables); Joins = desc.Forge; } else { Joins = null; } var multiKeyPlan = MultiKeyPlanner.PlanMultiKeyDistinct( IsDistinct, ResultSetProcessor.ResultEventType, statementRawInfo, SerdeCompileTimeResolverNonHA.INSTANCE); AdditionalForgeables.AddAll(multiKeyPlan.MultiKeyForgeables); DistinctMultiKey = multiKeyPlan.ClassRef; }
public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext) { Type[] parameterTypes = new Type[positionalParams.Length]; object[] constant = new object[positionalParams.Length]; bool[] isConstant = new bool[positionalParams.Length]; ExprNode[] expressions = new ExprNode[positionalParams.Length]; int count = 0; bool hasDataWindows = true; foreach (ExprNode child in positionalParams) { if (child.Forge.ForgeConstantType == ExprForgeConstantType.COMPILETIMECONST) { isConstant[count] = true; constant[count] = child.Forge.ExprEvaluator.Evaluate(null, true, null); } parameterTypes[count] = child.Forge.EvaluationType; expressions[count] = child; if (!ExprNodeUtilityAggregation.HasRemoveStreamForAggregations( child, validationContext.StreamTypeService, validationContext.IsResettingAggregations)) { hasDataWindows = false; } if (child is ExprWildcard) { ExprAggMultiFunctionUtil.CheckWildcardNotJoinOrSubquery( validationContext.StreamTypeService, functionName); parameterTypes[count] = validationContext.StreamTypeService.EventTypes[0].UnderlyingType; isConstant[count] = false; constant[count] = null; } count++; } LinkedHashMap<string, IList<ExprNode>> namedParameters = null; if (optionalFilter != null) { namedParameters = new LinkedHashMap<string, IList<ExprNode>>(); namedParameters.Put("filter", Collections.SingletonList(optionalFilter)); positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } AggregationFunctionValidationContext context = new AggregationFunctionValidationContext( parameterTypes, isConstant, constant, base.IsDistinct, hasDataWindows, expressions, namedParameters); try { // the aggregation function factory is transient, obtain if not provided if (aggregationFunctionForge == null) { aggregationFunctionForge = validationContext.ImportService.ResolveAggregationFunction(functionName); } aggregationFunctionForge.Validate(context); } catch (Exception ex) { throw new ExprValidationException( "Plug-in aggregation function '" + functionName + "' failed validation: " + ex.Message, ex); } AggregationFunctionMode mode = aggregationFunctionForge.AggregationFunctionMode; if (mode == null) { throw new ExprValidationException("Aggregation function forge returned a null value for mode"); } if (mode is AggregationFunctionModeManaged) { if (positionalParams.Length > 2) { throw new ExprValidationException( "Aggregation function forge single-value mode requires zero, one or two parameters"); } } else if (mode is AggregationFunctionModeMultiParam || mode is AggregationFunctionModeCodeGenerated) { } else { throw new ExprValidationException("Aggregation function forge returned an unrecognized mode " + mode); } return new AggregationMethodFactoryPluginMethod(this, aggregationFunctionForge, mode); }
private void InitInnerEvaluatorTypable() { throw ExprNodeUtilityMake.MakeUnsupportedCompileTime(); }
public override AggregationForgeFactory ValidateAggregationChild(ExprValidationContext validationContext) { if (this.positionalParams.Length == 0) { throw new ExprValidationException( "The rate aggregation function minimally requires a numeric constant or expression as a parameter."); } // handle "ever" ExprNode first = this.positionalParams[0]; if (first.Forge.ForgeConstantType.IsCompileTimeConstant) { string messageX = "The rate aggregation function requires a numeric constant or time period as the first parameter in the constant-value notation"; long intervalTime; if (first is ExprTimePeriod) { double secInterval = ((ExprTimePeriod) first).EvaluateAsSeconds(null, true, null); intervalTime = validationContext.ImportService.TimeAbacus.DeltaForSecondsDouble(secInterval); } else if (ExprNodeUtilityQuery.IsConstant(first)) { if (!first.Forge.EvaluationType.IsNumeric()) { throw new ExprValidationException(messageX); } var num = first.Forge.ExprEvaluator.Evaluate(null, true, null); intervalTime = validationContext.ImportService.TimeAbacus.DeltaForSecondsNumber(num); } else { throw new ExprValidationException(messageX); } if (optionalFilter == null) { this.positionalParams = ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY; } else { this.positionalParams = new ExprNode[] {optionalFilter}; } return new AggregationForgeFactoryRate(this, true, intervalTime, validationContext.ImportService.TimeAbacus); } string message = "The rate aggregation function requires a property or expression returning a non-constant long-type value as the first parameter in the timestamp-property notation"; Type boxedParamOne = first.Forge.EvaluationType.GetBoxedType(); if (boxedParamOne != typeof(long?)) { throw new ExprValidationException(message); } if (first.Forge.ForgeConstantType.IsConstant) { throw new ExprValidationException(message); } if (first is ExprTimestampNode) { throw new ExprValidationException( "The rate aggregation function does not allow the current runtime timestamp as a parameter"); } if (this.positionalParams.Length > 1) { if (!this.positionalParams[1].Forge.EvaluationType.IsNumeric()) { throw new ExprValidationException( "The rate aggregation function accepts an expression returning a numeric value to accumulate as an optional second parameter"); } } bool hasDataWindows = ExprNodeUtilityAggregation.HasRemoveStreamForAggregations( first, validationContext.StreamTypeService, validationContext.IsResettingAggregations); if (!hasDataWindows) { throw new ExprValidationException( "The rate aggregation function in the timestamp-property notation requires data windows"); } if (optionalFilter != null) { positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } return new AggregationForgeFactoryRate(this, false, -1, validationContext.ImportService.TimeAbacus); }
private AggregationLinearFactoryDesc HandleNonIntoTable( ExprNode[] childNodes, AggregationAccessorLinearType?stateType, ExprValidationContext validationContext) { var streamTypeService = validationContext.StreamTypeService; int streamNum; Type resultType; ExprForge forge; ExprNode evaluatorIndex = null; bool istreamOnly; EventType containedType; Type scalarCollectionComponentType = null; // validate wildcard use var isWildcard = childNodes.Length == 0 || childNodes.Length > 0 && childNodes[0] is ExprWildcard; if (isWildcard) { ExprAggMultiFunctionUtil.ValidateWildcardStreamNumbers(validationContext.StreamTypeService, stateType?.GetNameInvariant()); streamNum = 0; containedType = streamTypeService.EventTypes[0]; resultType = containedType.UnderlyingType; var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType); forge = ExprNodeUtilityMake.MakeUnderlyingForge(0, resultType, tableMetadataX); istreamOnly = GetIstreamOnly(streamTypeService, 0); if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } } else if (childNodes.Length > 0 && childNodes[0] is ExprStreamUnderlyingNode) { // validate "stream.*" streamNum = ExprAggMultiFunctionUtil.ValidateStreamWildcardGetStreamNum(childNodes[0]); istreamOnly = GetIstreamOnly(streamTypeService, streamNum); if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } var type = streamTypeService.EventTypes[streamNum]; containedType = type; resultType = type.UnderlyingType; var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(type); forge = ExprNodeUtilityMake.MakeUnderlyingForge(streamNum, resultType, tableMetadataX); } else { // validate when neither wildcard nor "stream.*" var child = childNodes[0]; var streams = ExprNodeUtilityQuery.GetIdentStreamNumbers(child); if (streams.IsEmpty() || (streams.Count > 1)) { throw new ExprValidationException( GetErrorPrefix(stateType) + " requires that any child expressions evaluate properties of the same stream; Use 'firstever' or 'lastever' or 'nth' instead"); } streamNum = streams.First(); istreamOnly = GetIstreamOnly(streamTypeService, streamNum); if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } resultType = childNodes[0].Forge.EvaluationType; forge = childNodes[0].Forge; if (streamNum >= streamTypeService.EventTypes.Length) { containedType = streamTypeService.EventTypes[0]; } else { containedType = streamTypeService.EventTypes[streamNum]; } scalarCollectionComponentType = resultType; } if (childNodes.Length > 1) { if (stateType == AggregationAccessorLinearType.WINDOW) { throw new ExprValidationException(GetErrorPrefix(stateType) + " does not accept an index expression; Use 'first' or 'last' instead"); } evaluatorIndex = childNodes[1]; var indexResultType = evaluatorIndex.Forge.EvaluationType; if (indexResultType != typeof(int?) && indexResultType != typeof(int)) { throw new ExprValidationException(GetErrorPrefix(stateType) + " requires an index expression that returns an integer value"); } } // determine accessor AggregationAccessorForge accessor; if (evaluatorIndex != null) { var isFirst = stateType == AggregationAccessorLinearType.FIRST; var constant = -1; ExprForge forgeIndex; if (evaluatorIndex.Forge.ForgeConstantType.IsCompileTimeConstant) { constant = evaluatorIndex.Forge.ExprEvaluator.Evaluate(null, true, null).AsInt32(); forgeIndex = null; } else { forgeIndex = evaluatorIndex.Forge; } accessor = new AggregationAccessorFirstLastIndexWEvalForge(streamNum, forge, forgeIndex, constant, isFirst); } else { if (stateType == AggregationAccessorLinearType.FIRST) { accessor = new AggregationAccessorFirstWEvalForge(streamNum, forge); } else if (stateType == AggregationAccessorLinearType.LAST) { accessor = new AggregationAccessorLastWEvalForge(streamNum, forge); } else if (stateType == AggregationAccessorLinearType.WINDOW) { accessor = new AggregationAccessorWindowWEvalForge(streamNum, forge, resultType); } else { throw new IllegalStateException("Access type is undefined or not known as code '" + stateType + "'"); } } var accessorResultType = resultType; if (stateType == AggregationAccessorLinearType.WINDOW) { accessorResultType = TypeHelper.GetArrayType(resultType); } var isFafWindow = streamTypeService.IsOnDemandStreams && stateType == AggregationAccessorLinearType.WINDOW; var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType); if (tableMetadata == null && !isFafWindow && (istreamOnly || streamTypeService.IsOnDemandStreams)) { if (optionalFilter != null) { positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } var serde = validationContext.SerdeResolver.SerdeForAggregation(accessorResultType, validationContext.StatementRawInfo); AggregationForgeFactory factoryX = new AggregationForgeFactoryFirstLastUnbound(this, accessorResultType, optionalFilter != null, serde); return(new AggregationLinearFactoryDesc(factoryX, containedType, scalarCollectionComponentType, streamNum)); } var stateKey = new AggregationStateKeyWStream( streamNum, containedType, AggregationStateTypeWStream.DATAWINDOWACCESS_LINEAR, ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY, optionalFilter); var optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge; AggregationStateFactoryForge stateFactory = new AggregationStateLinearForge(this, streamNum, optionalFilterForge); var factory = new AggregationForgeFactoryAccessLinear( this, accessor, accessorResultType, stateKey, stateFactory, AggregationAgentDefault.INSTANCE, containedType); var enumerationType = scalarCollectionComponentType == null ? containedType : null; var serdeForgables = SerdeEventTypeUtility.Plan( containedType, validationContext.StatementRawInfo, validationContext.SerdeEventTypeRegistry, validationContext.SerdeResolver); validationContext.AdditionalForgeables.AddAll(serdeForgables); return(new AggregationLinearFactoryDesc(factory, enumerationType, scalarCollectionComponentType, streamNum)); }
public static StmtForgeMethodSelectResult Make( IContainer container, bool dataflowOperator, string @namespace, string classPostfix, StatementBaseInfo @base, StatementCompileTimeServices services) { var filterSpecCompileds = new List<FilterSpecCompiled>(); var scheduleHandleCallbackProviders = new List<ScheduleHandleCallbackProvider>(); var namedWindowConsumers = new List<NamedWindowConsumerStreamSpec>(); var statementSpec = @base.StatementSpec; var additionalForgeables = new List<StmtClassForgeableFactory>(); var streamNames = StatementForgeMethodSelectUtil.DetermineStreamNames(statementSpec.StreamSpecs); var numStreams = streamNames.Length; if (numStreams == 0) { throw new ExprValidationException("The from-clause is required but has not been specified"); } // first we create streams for subselects, if there are any SubSelectActivationDesc subSelectActivationDesc = SubSelectHelperActivations.CreateSubSelectActivation( filterSpecCompileds, namedWindowConsumers, @base, services); IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation = subSelectActivationDesc.Subselects; additionalForgeables.AddAll(subSelectActivationDesc.AdditionalForgeables); // verify for joins that required views are present StreamJoinAnalysisResultCompileTime joinAnalysisResult = StatementForgeMethodSelectUtil.VerifyJoinViews(statementSpec); var streamEventTypes = new EventType[statementSpec.StreamSpecs.Length]; var eventTypeNames = new string[numStreams]; var isNamedWindow = new bool[numStreams]; var viewableActivatorForges = new ViewableActivatorForge[numStreams]; var viewForges = new IList<ViewFactoryForge>[numStreams]; var historicalEventViewables = new HistoricalEventViewableForge[numStreams]; for (var stream = 0; stream < numStreams; stream++) { var streamSpec = statementSpec.StreamSpecs[stream]; var isCanIterateUnbound = streamSpec.ViewSpecs.Length == 0 && (services.Configuration.Compiler.ViewResources.IsIterableUnbound || AnnotationUtil.HasAnnotation(statementSpec.Annotations, typeof(IterableUnboundAttribute))); var args = new ViewFactoryForgeArgs( stream, false, -1, streamSpec.Options, null, @base.StatementRawInfo, services); if (dataflowOperator) { var dfResult = HandleDataflowActivation(args, streamSpec); streamEventTypes[stream] = dfResult.StreamEventType; eventTypeNames[stream] = dfResult.EventTypeName; viewableActivatorForges[stream] = dfResult.ViewableActivatorForge; viewForges[stream] = dfResult.ViewForges; additionalForgeables.AddAll(dfResult.AdditionalForgeables); } else if (streamSpec is FilterStreamSpecCompiled) { var filterStreamSpec = (FilterStreamSpecCompiled) statementSpec.StreamSpecs[stream]; var filterSpecCompiled = filterStreamSpec.FilterSpecCompiled; streamEventTypes[stream] = filterSpecCompiled.ResultEventType; eventTypeNames[stream] = filterStreamSpec.FilterSpecCompiled.FilterForEventTypeName; viewableActivatorForges[stream] = new ViewableActivatorFilterForge( filterSpecCompiled, isCanIterateUnbound, stream, false, -1); ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, streamEventTypes[stream]); viewForges[stream] = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); filterSpecCompileds.Add(filterSpecCompiled); } else if (streamSpec is PatternStreamSpecCompiled) { var patternStreamSpec = (PatternStreamSpecCompiled) streamSpec; var forges = patternStreamSpec.Root.CollectFactories(); foreach (var forgeNode in forges) { forgeNode.CollectSelfFilterAndSchedule(filterSpecCompileds, scheduleHandleCallbackProviders); } var patternType = ViewableActivatorPatternForge.MakeRegisterPatternType( @base, stream, patternStreamSpec, services); var patternContext = new PatternContext(0, patternStreamSpec.MatchedEventMapMeta, false, -1, false); viewableActivatorForges[stream] = new ViewableActivatorPatternForge( patternType, patternStreamSpec, patternContext, isCanIterateUnbound); streamEventTypes[stream] = patternType; ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, patternType); viewForges[stream] = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); } else if (streamSpec is NamedWindowConsumerStreamSpec) { var namedSpec = (NamedWindowConsumerStreamSpec) streamSpec; var namedWindow = services.NamedWindowCompileTimeResolver.Resolve(namedSpec.NamedWindow.EventType.Name); var namedWindowType = namedWindow.EventType; if (namedSpec.OptPropertyEvaluator != null) { namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType; } var typesFilterValidation = new StreamTypeServiceImpl( namedWindowType, namedSpec.OptionalStreamName, false); var filterSingle = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(namedSpec.FilterExpressions); var filterQueryGraph = EPLValidationUtil.ValidateFilterGetQueryGraphSafe( filterSingle, typesFilterValidation, @base.StatementRawInfo, services); namedWindowConsumers.Add(namedSpec); viewableActivatorForges[stream] = new ViewableActivatorNamedWindowForge( namedSpec, namedWindow, filterSingle, filterQueryGraph, true, namedSpec.OptPropertyEvaluator); streamEventTypes[stream] = namedWindowType; viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>(); joinAnalysisResult.SetNamedWindowsPerStream(stream, namedWindow); eventTypeNames[stream] = namedSpec.NamedWindow.EventType.Name; isNamedWindow[stream] = true; // Consumers to named windows cannot declare a data window view onto the named window to avoid duplicate remove streams ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, namedWindowType); viewForges[stream] = viewForgeDesc.Forges; additionalForgeables.AddAll(viewForgeDesc.MultikeyForges); EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(viewForges[stream]); } else if (streamSpec is TableQueryStreamSpec) { ValidateNoViews(streamSpec, "Table data"); var tableStreamSpec = (TableQueryStreamSpec) streamSpec; if (numStreams > 1 && tableStreamSpec.FilterExpressions.Count > 0) { throw new ExprValidationException( "Joins with tables do not allow table filter expressions, please add table filters to the where-clause instead"); } var table = tableStreamSpec.Table; EPLValidationUtil.ValidateContextName( true, table.TableName, table.OptionalContextName, statementSpec.Raw.OptionalContextName, false); var filter = ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(tableStreamSpec.FilterExpressions); viewableActivatorForges[stream] = new ViewableActivatorTableForge(table, filter); viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>(); eventTypeNames[stream] = tableStreamSpec.Table.TableName; streamEventTypes[stream] = tableStreamSpec.Table.InternalEventType; joinAnalysisResult.SetTablesForStream(stream, table); if (tableStreamSpec.Options.IsUnidirectional) { throw new ExprValidationException("Tables cannot be marked as unidirectional"); } if (tableStreamSpec.Options.IsRetainIntersection || tableStreamSpec.Options.IsRetainUnion) { throw new ExprValidationException("Tables cannot be marked with retain"); } } else if (streamSpec is DBStatementStreamSpec) { ValidateNoViews(streamSpec, "Historical data"); var sqlStreamSpec = (DBStatementStreamSpec) streamSpec; var typeConversionHook = (SQLColumnTypeConversion) ImportUtil.GetAnnotationHook( statementSpec.Annotations, HookType.SQLCOL, typeof(SQLColumnTypeConversion), services.ImportServiceCompileTime); var outputRowConversionHook = (SQLOutputRowConversion) ImportUtil.GetAnnotationHook( statementSpec.Annotations, HookType.SQLROW, typeof(SQLOutputRowConversion), services.ImportServiceCompileTime); var viewable = HistoricalEventViewableDatabaseForgeFactory.CreateDBStatementView( stream, sqlStreamSpec, typeConversionHook, outputRowConversionHook, @base, services, statementSpec.Annotations); streamEventTypes[stream] = viewable.EventType; viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>(); viewableActivatorForges[stream] = new ViewableActivatorHistoricalForge(viewable); historicalEventViewables[stream] = viewable; } else if (streamSpec is MethodStreamSpec) { ValidateNoViews(streamSpec, "Method data"); var methodStreamSpec = (MethodStreamSpec) streamSpec; var viewable = HistoricalEventViewableMethodForgeFactory.CreateMethodStatementView( stream, methodStreamSpec, @base, services); historicalEventViewables[stream] = viewable; streamEventTypes[stream] = viewable.EventType; viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>(); viewableActivatorForges[stream] = new ViewableActivatorHistoricalForge(viewable); historicalEventViewables[stream] = viewable; } else { throw new IllegalStateException("Unrecognized stream " + streamSpec); } // plan serde for iterate-unbound if (isCanIterateUnbound) { var serdeForgeables = SerdeEventTypeUtility.Plan( streamEventTypes[stream], @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver); additionalForgeables.AddAll(serdeForgeables); } } // handle match-recognize pattern if (statementSpec.Raw.MatchRecognizeSpec != null) { if (numStreams > 1) { throw new ExprValidationException("Joins are not allowed when using match-recognize"); } if (joinAnalysisResult.TablesPerStream[0] != null) { throw new ExprValidationException("Tables cannot be used with match-recognize"); } var isUnbound = viewForges[0].IsEmpty() && !(statementSpec.StreamSpecs[0] is NamedWindowConsumerStreamSpec); var eventType = viewForges[0].IsEmpty() ? streamEventTypes[0] : viewForges[0][(viewForges[0].Count - 1)].EventType; var plan = RowRecogNFAViewPlanUtil.ValidateAndPlan(services.Container, eventType, isUnbound, @base, services); var forge = new RowRecogNFAViewFactoryForge(plan.Forge); additionalForgeables.AddAll(plan.AdditionalForgeables); scheduleHandleCallbackProviders.Add(forge); viewForges[0].Add(forge); var serdeForgeables = SerdeEventTypeUtility.Plan( eventType, @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver); additionalForgeables.AddAll(serdeForgeables); } // Obtain event types from view factory chains for (var i = 0; i < viewForges.Length; i++) { streamEventTypes[i] = viewForges[i].IsEmpty() ? streamEventTypes[i] : viewForges[i][(viewForges[i].Count - 1)].EventType; } // add unique-information to join analysis joinAnalysisResult.AddUniquenessInfo(viewForges, statementSpec.Annotations); // plan sub-selects SubSelectHelperForgePlan subselectForgePlan = SubSelectHelperForgePlanner.PlanSubSelect( @base, subselectActivation, streamNames, streamEventTypes, eventTypeNames, services); var subselectForges = subselectForgePlan.Subselects; additionalForgeables.AddAll(subselectForgePlan.AdditionalForgeables); DetermineViewSchedules(subselectForges, scheduleHandleCallbackProviders); // determine view schedules var viewResourceDelegateExpr = new ViewResourceDelegateExpr(); ViewFactoryForgeUtil.DetermineViewSchedules(viewForges, scheduleHandleCallbackProviders); var hasIStreamOnly = StatementForgeMethodSelectUtil.GetHasIStreamOnly(isNamedWindow, viewForges); var optionalStreamsIfAny = OuterJoinAnalyzer.OptionalStreamsIfAny(statementSpec.Raw.OuterJoinDescList); StreamTypeService typeService = new StreamTypeServiceImpl( streamEventTypes, streamNames, hasIStreamOnly, false, optionalStreamsIfAny); // Validate views that require validation, specifically streams that don't have // sub-views such as DB SQL joins var historicalViewableDesc = new HistoricalViewableDesc(numStreams); for (var stream = 0; stream < historicalEventViewables.Length; stream++) { var historicalEventViewable = historicalEventViewables[stream]; if (historicalEventViewable == null) { continue; } scheduleHandleCallbackProviders.Add(historicalEventViewable); IList<StmtClassForgeableFactory> forgeables = historicalEventViewable.Validate(typeService, @base, services); additionalForgeables.AddAll(forgeables); historicalViewableDesc.SetHistorical(stream, historicalEventViewable.RequiredStreams); if (historicalEventViewable.RequiredStreams.Contains(stream)) { throw new ExprValidationException( "Parameters for historical stream " + stream + " indicate that the stream is subordinate to itself as stream parameters originate in the same stream"); } } // Validate where-clause filter tree, outer join clause and output limit expression var whereClauseValidated = EPStatementStartMethodHelperValidate.ValidateNodes( statementSpec.Raw, typeService, viewResourceDelegateExpr, @base.StatementRawInfo, services); var whereClauseForge = whereClauseValidated?.Forge; // Obtain result set processor var resultSetProcessorDesc = ResultSetProcessorFactoryFactory.GetProcessorPrototype( new ResultSetSpec(statementSpec), typeService, viewResourceDelegateExpr, joinAnalysisResult.UnidirectionalInd, true, @base.ContextPropertyRegistry, false, false, @base.StatementRawInfo, services); additionalForgeables.AddAll(resultSetProcessorDesc.AdditionalForgeables); // Handle 'prior' function nodes in terms of view requirements var viewResourceDelegateDesc = ViewResourceVerifyHelper.VerifyPreviousAndPriorRequirements(viewForges, viewResourceDelegateExpr); var hasPrior = ViewResourceDelegateDesc.HasPrior(viewResourceDelegateDesc); if (hasPrior) { for (var stream = 0; stream < numStreams; stream++) { if (!viewResourceDelegateDesc[stream].PriorRequests.IsEmpty()) { viewForges[stream].Add(new PriorEventViewForge(viewForges[stream].IsEmpty(), streamEventTypes[stream])); var serdeForgeables = SerdeEventTypeUtility.Plan( streamEventTypes[stream], @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver); additionalForgeables.AddAll(serdeForgeables); } } } var outputProcessDesc = OutputProcessViewForgeFactory.Make( typeService.EventTypes, resultSetProcessorDesc.ResultEventType, resultSetProcessorDesc.ResultSetProcessorType, statementSpec, @base.StatementRawInfo, services); var outputProcessViewFactoryForge = outputProcessDesc.Forge; additionalForgeables.AddAll(outputProcessDesc.AdditionalForgeables); outputProcessViewFactoryForge.CollectSchedules(scheduleHandleCallbackProviders); JoinSetComposerPrototypeForge joinForge = null; if (numStreams > 1) { var hasAggregations = !resultSetProcessorDesc.AggregationServiceForgeDesc.Expressions.IsEmpty(); var desc = JoinSetComposerPrototypeForgeFactory.MakeComposerPrototype( statementSpec, joinAnalysisResult, typeService, historicalViewableDesc, false, hasAggregations, @base.StatementRawInfo, services); joinForge = desc.Forge; additionalForgeables.AddAll(desc.AdditionalForgeables); HandleIndexDependencies(joinForge.OptionalQueryPlan, services); } // plan table access var tableAccessForges = ExprTableEvalHelperPlan.PlanTableAccess(@base.StatementSpec.TableAccessNodes); ValidateTableAccessUse(statementSpec.Raw.IntoTableSpec, statementSpec.Raw.TableExpressions); if (joinAnalysisResult.IsUnidirectional && statementSpec.Raw.IntoTableSpec != null) { throw new ExprValidationException("Into-table does not allow unidirectional joins"); } var orderByWithoutOutputLimit = statementSpec.Raw.OrderByList != null && !statementSpec.Raw.OrderByList.IsEmpty() && statementSpec.Raw.OutputLimitSpec == null; var statementAIFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple( typeof(StatementAIFactoryProvider), classPostfix); var resultSetProcessorProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple( typeof(ResultSetProcessorFactoryProvider), classPostfix); var outputProcessViewProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple( typeof(OutputProcessViewFactoryProvider), classPostfix); var statementProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix); var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementFields), classPostfix); //var statementFieldsClassName = namespaceScope.FieldsClassNameOptional; var forgeX = new StatementAgentInstanceFactorySelectForge( typeService.StreamNames, viewableActivatorForges, resultSetProcessorProviderClassName, viewForges, viewResourceDelegateDesc, whereClauseForge, joinForge, outputProcessViewProviderClassName, subselectForges, tableAccessForges, orderByWithoutOutputLimit, joinAnalysisResult.IsUnidirectional); var namespaceScope = new CodegenNamespaceScope( @namespace, statementFieldsClassName, services.IsInstrumented); var forgeablesX = additionalForgeables .Select(additional => additional.Make(namespaceScope, classPostfix)) .ToList(); forgeablesX.Add( new StmtClassForgeableRSPFactoryProvider( resultSetProcessorProviderClassName, resultSetProcessorDesc, namespaceScope, @base.StatementRawInfo)); forgeablesX.Add( new StmtClassForgeableOPVFactoryProvider( outputProcessViewProviderClassName, outputProcessViewFactoryForge, namespaceScope, numStreams, @base.StatementRawInfo)); forgeablesX.Add( new StmtClassForgeableAIFactoryProviderSelect(statementAIFactoryProviderClassName, namespaceScope, forgeX)); forgeablesX.Add( new StmtClassForgeableStmtFields(statementFieldsClassName, namespaceScope, numStreams)); if (!dataflowOperator) { var informationals = StatementInformationalsUtil.GetInformationals( @base, filterSpecCompileds, scheduleHandleCallbackProviders, namedWindowConsumers, true, resultSetProcessorDesc.SelectSubscriberDescriptor, namespaceScope, services); forgeablesX.Add( new StmtClassForgeableStmtProvider(statementAIFactoryProviderClassName, statementProviderClassName, informationals, namespaceScope)); } var forgeableResult = new StmtForgeMethodResult( forgeablesX, filterSpecCompileds, scheduleHandleCallbackProviders, namedWindowConsumers, FilterSpecCompiled.MakeExprNodeList(filterSpecCompileds, EmptyList<FilterSpecParamExprNodeForge>.Instance)); return new StmtForgeMethodSelectResult(forgeableResult, resultSetProcessorDesc.ResultEventType, numStreams); }
internal static FilterSpecPlanForge PlanRemainingNodesWithConditions( FilterSpecParaForgeMap overallExpressions, FilterSpecCompilerArgs args, int filterServiceMaxFilterWidth, ExprNode topLevelNegator) { var unassigned = overallExpressions.UnassignedExpressions; var orNodes = new List <ExprOrNode>(unassigned.Count); foreach (var node in unassigned) { if (node is ExprOrNode) { orNodes.Add((ExprOrNode)node); } } var expressionsWithoutOr = new FilterSpecParaForgeMap(); expressionsWithoutOr.Add(overallExpressions); // first dimension: or-node index // second dimension: or child node index var countOr = 0; var sizeFactorized = 1; var sizePerOr = new int[orNodes.Count]; var orChildNodes = new OrChildNode[orNodes.Count][]; var hasControl = false; foreach (var orNode in orNodes) { expressionsWithoutOr.RemoveNode(orNode); // get value-nodes and non-value nodes var nonValueNodes = GetNonValueChildNodes(orNode); var valueNodes = new List <ExprNode>(Arrays.AsList(orNode.ChildNodes)); valueNodes.RemoveAll(nonValueNodes); ExprNode singleValueNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalOrWhenNeeded(valueNodes); // get all child nodes; last one is confirm if present IList <ExprNode> allChildNodes = new List <ExprNode>(nonValueNodes); if (singleValueNode != null) { allChildNodes.Add(singleValueNode); } var len = allChildNodes.Count; orChildNodes[countOr] = new OrChildNode[len]; for (var i = 0; i < len; i++) { var child = allChildNodes[i]; if (child == singleValueNode) { hasControl = true; orChildNodes[countOr][i] = new OrChildNodeV(singleValueNode); } else { var map = new FilterSpecParaForgeMap(); var nodes = Collections.SingletonList(child); var confirm = DecomposePopulateConsolidate(map, true, nodes, args); if (confirm == null) { orChildNodes[countOr][i] = new OrChildNodeNV(child, map); } else { hasControl = true; orChildNodes[countOr][i] = new OrChildNodeNVNegated(child, map, confirm); } } } sizePerOr[countOr] = len; sizeFactorized = sizeFactorized * len; countOr++; } // compute permutations var permutations = new CombPermutationTriplets[sizeFactorized]; var combinationEnumeration = CombinationEnumeration.FromZeroBasedRanges(sizePerOr); var count = 0; foreach (var permutation in combinationEnumeration) { permutations[count] = ComputePermutation(expressionsWithoutOr, permutation, orChildNodes, hasControl, args); count++; } // Remove any permutations that only have a control-confirm var result = new List <FilterSpecPlanPathForge>(sizeFactorized); var pathControlConfirm = new List <ExprNode>(); foreach (var permutation in permutations) { if (permutation.Triplets.Length > 0) { result.Add(new FilterSpecPlanPathForge(permutation.Triplets, permutation.NegateCondition)); } else { pathControlConfirm.Add(permutation.NegateCondition); } } if (result.Count > filterServiceMaxFilterWidth) { return(null); } var pathArray = result.ToArray(); ExprNode topLevelConfirmer = ExprNodeUtilityMake.ConnectExpressionsByLogicalOrWhenNeeded(pathControlConfirm); // determine when the path-negate condition is the same as the root confirm-expression if (topLevelConfirmer != null) { var not = new ExprNotNode(); not.AddChildNode(topLevelConfirmer); foreach (var path in pathArray) { if (ExprNodeUtilityCompare.DeepEquals(not, path.PathNegate, true)) { path.PathNegate = null; } } } var convertor = new MatchedEventConvertorForge( args.taggedEventTypes, args.arrayEventTypes, args.allTagNamesOrdered, null, true); return(new FilterSpecPlanForge(pathArray, topLevelConfirmer, topLevelNegator, convertor)); }