예제 #1
0
 public EPPreparedExecuteIUDSingleStreamDelete(StatementSpecCompiled statementSpec, EPServicesContext services, StatementContext statementContext)
     : base(statementSpec, services, statementContext)
 {
 }
예제 #2
0
 /// <summary>
 /// Supplies a compiled statement spec.
 /// </summary>
 /// <param name="statementSpecCompiled">compiled validated filters</param>
 /// <param name="subselectNumber">subselect assigned number</param>
 public void SetStatementSpecCompiled(StatementSpecCompiled statementSpecCompiled, int subselectNumber)
 {
     _statementSpecCompiled = statementSpecCompiled;
     _subselectNumber       = subselectNumber;
 }
예제 #3
0
 public ContextManagedStatementSelectDesc(StatementSpecCompiled statementSpec, StatementContext statementContext, ContextMergeView mergeView, StatementAgentInstanceFactory factory, IList <AggregationServiceAggExpressionDesc> aggregationExpressions, SubSelectStrategyCollection subSelectPrototypeCollection)
     : base(statementSpec, statementContext, mergeView, factory)
 {
     AggregationExpressions       = aggregationExpressions;
     SubSelectPrototypeCollection = subSelectPrototypeCollection;
 }
 public StatementAgentInstanceFactoryOnTriggerSplit(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection, StatementAgentInstanceFactoryOnTriggerSplitDesc splitDesc, EventType activatorResultEventType, string[] insertIntoTableNames)
     : base(statementContext, statementSpec, services, activator, subSelectStrategyCollection)
 {
     _splitDesc = splitDesc;
     _activatorResultEventType = activatorResultEventType;
     _insertIntoTableNames     = insertIntoTableNames;
 }
예제 #5
0
        public static OnTriggerPlan HandleSplitStream(
            string aiFactoryProviderClassName,
            CodegenNamespaceScope namespaceScope,
            string classPostfix,
            OnTriggerSplitStreamDesc desc,
            StreamSpecCompiled streamSpec,
            OnTriggerActivatorDesc activatorResult,
            IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            var raw = @base.StatementSpec.Raw;
            if (raw.InsertIntoDesc == null) {
                throw new ExprValidationException(
                    "Required insert-into clause is not provided, the clause is required for split-stream syntax");
            }

            if (raw.GroupByExpressions != null && raw.GroupByExpressions.Count > 0 ||
                raw.HavingClause != null ||
                raw.OrderByList.Count > 0) {
                throw new ExprValidationException(
                    "A group-by clause, having-clause or order-by clause is not allowed for the split stream syntax");
            }

            var streamName = streamSpec.OptionalStreamName;
            if (streamName == null) {
                streamName = "stream_0";
            }

            StreamTypeService typeServiceTrigger = new StreamTypeServiceImpl(
                new[] {activatorResult.ActivatorResultEventType},
                new[] {streamName},
                new[] {true},
                false,
                false);

            // materialize sub-select views
            var subselectForges = SubSelectHelperForgePlanner.PlanSubSelect(
                @base,
                subselectActivation,
                new[] {streamSpec.OptionalStreamName},
                new[] {activatorResult.ActivatorResultEventType},
                new[] {activatorResult.TriggerEventTypeName},
                services);

            // compile top-level split
            var items = new OnSplitItemForge[desc.SplitStreams.Count + 1];
            items[0] = OnSplitValidate(
                typeServiceTrigger,
                @base.StatementSpec,
                @base.ContextPropertyRegistry,
                null,
                @base.StatementRawInfo,
                services);

            // compile each additional split
            var index = 1;
            foreach (var splits in desc.SplitStreams) {
                var splitSpec = new StatementSpecCompiled();

                splitSpec.Raw.InsertIntoDesc = splits.InsertInto;
                splitSpec.SelectClauseCompiled = CompileSelectAllowSubselect(splits.SelectClause);
                splitSpec.Raw.WhereClause = splits.WhereClause;

                PropertyEvaluatorForge optionalPropertyEvaluator = null;
                StreamTypeService typeServiceProperty;
                if (splits.FromClause != null) {
                    optionalPropertyEvaluator = PropertyEvaluatorForgeFactory.MakeEvaluator(
                        splits.FromClause.PropertyEvalSpec,
                        activatorResult.ActivatorResultEventType,
                        streamName,
                        @base.StatementRawInfo,
                        services);
                    typeServiceProperty = new StreamTypeServiceImpl(
                        new[] {optionalPropertyEvaluator.FragmentEventType},
                        new[] {splits.FromClause.OptionalStreamName},
                        new[] {true},
                        false,
                        false);
                }
                else {
                    typeServiceProperty = typeServiceTrigger;
                }

                items[index] = OnSplitValidate(
                    typeServiceProperty,
                    splitSpec,
                    @base.ContextPropertyRegistry,
                    optionalPropertyEvaluator,
                    @base.StatementRawInfo,
                    services);
                index++;
            }

            // handle result set processor classes
            IList<StmtClassForgable> forgables = new List<StmtClassForgable>();
            for (var i = 0; i < items.Length; i++) {
                var classNameRSP = CodeGenerationIDGenerator.GenerateClassNameSimple(
                    typeof(ResultSetProcessorFactoryProvider),
                    classPostfix + "_" + i);
                forgables.Add(
                    new StmtClassForgableRSPFactoryProvider(
                        classNameRSP,
                        items[i].ResultSetProcessorDesc,
                        namespaceScope,
                        @base.StatementRawInfo));
                items[i].ResultSetProcessorClassName = classNameRSP;
            }

            // plan table access
            var tableAccessForges = ExprTableEvalHelperPlan.PlanTableAccess(@base.StatementSpec.TableAccessNodes);

            // build forge
            var splitStreamForge = new StatementAgentInstanceFactoryOnTriggerSplitStreamForge(
                activatorResult.Activator,
                activatorResult.ActivatorResultEventType,
                subselectForges,
                tableAccessForges,
                items,
                desc.IsFirst);
            var triggerForge = new StmtClassForgableAIFactoryProviderOnTrigger(
                aiFactoryProviderClassName,
                namespaceScope,
                splitStreamForge);

            return new OnTriggerPlan(triggerForge, forgables, new SelectSubscriberDescriptor());
        }
        public static FilterValueSetParam[][] GetAddendumFilters(
            object keyValue,
            FilterSpecCompiled filtersSpec,
            ContextDetailPartitioned segmentedSpec,
            StatementSpecCompiled optionalStatementSpecCompiled)
        {
            // determine whether create-named-window
            var isCreateWindow = optionalStatementSpecCompiled != null &&
                                 optionalStatementSpecCompiled.CreateWindowDesc != null;
            ContextDetailPartitionItem foundPartition = null;

            if (!isCreateWindow)
            {
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    var typeOrSubtype = EventTypeUtility.IsTypeOrSubTypeOf(
                        filtersSpec.FilterForEventType, partitionItem.FilterSpecCompiled.FilterForEventType);
                    if (typeOrSubtype)
                    {
                        foundPartition = partitionItem;
                    }
                }
            }
            else
            {
                var declaredAsName = optionalStatementSpecCompiled.CreateWindowDesc.AsEventTypeName;
                if (declaredAsName == null)
                {
                    return(null);
                }
                foreach (var partitionItem in segmentedSpec.Items)
                {
                    if (partitionItem.FilterSpecCompiled.FilterForEventType.Name.Equals(declaredAsName))
                    {
                        foundPartition = partitionItem;
                        break;
                    }
                }
            }

            if (foundPartition == null)
            {
                return(null);
            }

            var addendumFilters = new List <FilterValueSetParam>(foundPartition.PropertyNames.Count);

            if (foundPartition.PropertyNames.Count == 1)
            {
                var propertyName = foundPartition.PropertyNames[0];
                var getter       = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(propertyName);
                var resultType   = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(propertyName);
                var lookupable   = new FilterSpecLookupable(propertyName, getter, resultType, false);
                var filter       = GetFilterMayEqualOrNull(lookupable, keyValue);
                addendumFilters.Add(filter);
            }
            else
            {
                var keys = ((MultiKeyUntyped)keyValue).Keys;
                for (var i = 0; i < foundPartition.PropertyNames.Count; i++)
                {
                    var partitionPropertyName = foundPartition.PropertyNames[i];
                    var getter     = foundPartition.FilterSpecCompiled.FilterForEventType.GetGetter(partitionPropertyName);
                    var resultType = foundPartition.FilterSpecCompiled.FilterForEventType.GetPropertyType(partitionPropertyName);
                    var lookupable = new FilterSpecLookupable(partitionPropertyName, getter, resultType, false);
                    var filter     = GetFilterMayEqualOrNull(lookupable, keys[i]);
                    addendumFilters.Add(filter);
                }
            }

            var addendum = new FilterValueSetParam[1][];

            addendum[0] = addendumFilters.ToArray();

            var partitionFilters = foundPartition.ParametersCompiled;

            if (partitionFilters != null)
            {
                addendum = ContextControllerAddendumUtil.AddAddendum(partitionFilters, addendum[0]);
            }

            return(addendum);
        }
 public EPStatementStartMethodCreateSchema(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
예제 #8
0
 public EPStatementStartMethodCreateIndex(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
 public EPStatementStartMethodCreateWindow(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
 public StatementAgentInstanceFactoryOnTriggerBase(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection)
 {
     this.StatementContext             = statementContext;
     this.StatementSpec                = statementSpec;
     this.Services                     = services;
     this._activator                   = activator;
     this._subSelectStrategyCollection = subSelectStrategyCollection;
 }
 public void ValidateStatement(
     string contextName,
     StatementSpecCompiled spec,
     StatementCompileTimeServices compileTimeServices)
 {
 }
예제 #12
0
        protected internal static StreamJoinAnalysisResultCompileTime VerifyJoinViews(
            StatementSpecCompiled statementSpec,
            NamedWindowCompileTimeResolver namedWindowCompileTimeResolver)
        {
            var streamSpecs = statementSpec.StreamSpecs;
            var analysisResult = new StreamJoinAnalysisResultCompileTime(streamSpecs.Length);
            if (streamSpecs.Length < 2) {
                return analysisResult;
            }

            // Determine if any stream has a unidirectional keyword

            // inspect unidirectional indicator and named window flags
            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++) {
                var streamSpec = statementSpec.StreamSpecs[i];
                if (streamSpec.Options.IsUnidirectional) {
                    analysisResult.SetUnidirectionalInd(i);
                }

                if (streamSpec.ViewSpecs.Length > 0) {
                    analysisResult.SetHasChildViews(i);
                }

                if (streamSpec is NamedWindowConsumerStreamSpec) {
                    var nwSpec = (NamedWindowConsumerStreamSpec) streamSpec;
                    if (nwSpec.OptPropertyEvaluator != null && !streamSpec.Options.IsUnidirectional) {
                        throw new ExprValidationException(
                            "Failed to validate named window use in join, Contained-event is only allowed for named windows when marked as unidirectional");
                    }

                    var nwinfo = nwSpec.NamedWindow;
                    analysisResult.SetNamedWindowsPerStream(i, nwinfo);
                    analysisResult.UniqueKeys[i] = EventTableIndexMetadataUtil.GetUniqueness(
                        nwinfo.IndexMetadata,
                        nwinfo.Uniqueness);
                }
            }

            // non-outer-join: verify unidirectional can be on a single stream only
            if (statementSpec.StreamSpecs.Length > 1 && analysisResult.IsUnidirectional) {
                VerifyJoinUnidirectional(analysisResult, statementSpec);
            }

            // count streams that provide data, excluding streams that poll data (DB and method)
            var countProviderNonpolling = 0;
            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++) {
                var streamSpec = statementSpec.StreamSpecs[i];
                if (streamSpec is MethodStreamSpec ||
                    streamSpec is DBStatementStreamSpec ||
                    streamSpec is TableQueryStreamSpec) {
                    continue;
                }

                countProviderNonpolling++;
            }

            // if there is only one stream providing data, the analysis is done
            if (countProviderNonpolling == 1) {
                return analysisResult;
            }
            // there are multiple driving streams, verify the presence of a view for insert/remove stream

            // validation of join views works differently for unidirectional as there can be self-joins that don't require a view
            // see if this is a self-join in which all streams are filters and filter specification is the same.
            FilterSpecCompiled unidirectionalFilterSpec = null;
            FilterSpecCompiled lastFilterSpec = null;
            var pureSelfJoin = true;
            foreach (var streamSpec in statementSpec.StreamSpecs) {
                if (!(streamSpec is FilterStreamSpecCompiled)) {
                    pureSelfJoin = false;
                    continue;
                }

                var filterSpec = ((FilterStreamSpecCompiled) streamSpec).FilterSpecCompiled;
                if (lastFilterSpec != null && !lastFilterSpec.EqualsTypeAndFilter(filterSpec)) {
                    pureSelfJoin = false;
                }

                if (streamSpec.ViewSpecs.Length > 0) {
                    pureSelfJoin = false;
                }

                lastFilterSpec = filterSpec;

                if (streamSpec.Options.IsUnidirectional) {
                    unidirectionalFilterSpec = filterSpec;
                }
            }

            // self-join without views and not unidirectional
            if (pureSelfJoin && unidirectionalFilterSpec == null) {
                analysisResult.IsPureSelfJoin = true;
                return analysisResult;
            }

            // weed out filter and pattern streams that don't have a view in a join
            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++) {
                var streamSpec = statementSpec.StreamSpecs[i];
                if (streamSpec.ViewSpecs.Length > 0) {
                    continue;
                }

                var name = streamSpec.OptionalStreamName;
                if (name == null && streamSpec is FilterStreamSpecCompiled) {
                    name = ((FilterStreamSpecCompiled) streamSpec).FilterSpecCompiled.FilterForEventTypeName;
                }

                if (name == null && streamSpec is PatternStreamSpecCompiled) {
                    name = "pattern event stream";
                }

                if (streamSpec.Options.IsUnidirectional) {
                    continue;
                }

                // allow a self-join without a child view, in that the filter spec is the same as the unidirection's stream filter
                if (unidirectionalFilterSpec != null &&
                    streamSpec is FilterStreamSpecCompiled &&
                    ((FilterStreamSpecCompiled) streamSpec).FilterSpecCompiled.EqualsTypeAndFilter(
                        unidirectionalFilterSpec)) {
                    analysisResult.SetUnidirectionalNonDriving(i);
                    continue;
                }

                if (streamSpec is FilterStreamSpecCompiled ||
                    streamSpec is PatternStreamSpecCompiled) {
                    throw new ExprValidationException(
                        "Joins require that at least one view is specified for each stream, no view was specified for " +
                        name);
                }
            }

            return analysisResult;
        }
        public static OutputProcessViewFactoryForgeDesc Make(
            EventType[] typesPerStream,
            EventType resultEventType,
            ResultSetProcessorType resultSetProcessorType,
            StatementSpecCompiled statementSpec,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            InsertIntoDesc insertIntoDesc = statementSpec.Raw.InsertIntoDesc;
            SelectClauseStreamSelectorEnum selectStreamSelector = statementSpec.Raw.SelectStreamSelectorEnum;
            OutputLimitSpec outputLimitSpec = statementSpec.Raw.OutputLimitSpec;
            int streamCount = statementSpec.StreamSpecs.Length;
            bool isDistinct = statementSpec.Raw.SelectClauseSpec.IsDistinct;
            bool isGrouped = statementSpec.GroupByExpressions != null &&
                             statementSpec.GroupByExpressions.GroupByNodes.Length > 0;
            List<StmtClassForgeableFactory> additionalForgeables = new List<StmtClassForgeableFactory>();

            // determine routing
            bool isRouted = false;
            bool routeToFront = false;
            if (insertIntoDesc != null) {
                isRouted = true;
                routeToFront = services.NamedWindowCompileTimeResolver.Resolve(insertIntoDesc.EventTypeName) != null;
            }

            OutputStrategyPostProcessForge outputStrategyPostProcessForge = null;
            if ((insertIntoDesc != null) || (selectStreamSelector == SelectClauseStreamSelectorEnum.RSTREAM_ONLY)) {
                SelectClauseStreamSelectorEnum? insertIntoStreamSelector = null;
                TableMetaData table = null;

                if (insertIntoDesc != null) {
                    insertIntoStreamSelector = insertIntoDesc.StreamSelector;
                    table = services.TableCompileTimeResolver.Resolve(statementSpec.Raw.InsertIntoDesc.EventTypeName);
                    if (table != null) {
                        EPLValidationUtil.ValidateContextName(
                            true,
                            table.TableName,
                            table.OptionalContextName,
                            statementSpec.Raw.OptionalContextName,
                            true);
                    }
                }

                bool audit = AuditEnum.INSERT.GetAudit(statementSpec.Annotations) != null;
                outputStrategyPostProcessForge = new OutputStrategyPostProcessForge(
                    isRouted,
                    insertIntoStreamSelector,
                    selectStreamSelector,
                    routeToFront,
                    table,
                    audit);
            }

            MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKeyDistinct(
                isDistinct,
                resultEventType,
                statementRawInfo,
                SerdeCompileTimeResolverNonHA.INSTANCE);
            MultiKeyClassRef distinctMultiKey = multiKeyPlan.ClassRef;
            additionalForgeables.AddRange(multiKeyPlan.MultiKeyForgeables);

            OutputProcessViewFactoryForge outputProcessViewFactoryForge;
            if (outputLimitSpec == null) {
                if (!isDistinct) {
                    if (outputStrategyPostProcessForge == null || !outputStrategyPostProcessForge.HasTable) {
                        // without table we have a shortcut implementation
                        outputProcessViewFactoryForge =
                            new OutputProcessViewDirectSimpleForge(outputStrategyPostProcessForge);
                    }
                    else {
                        outputProcessViewFactoryForge =
                            new OutputProcessViewDirectForge(outputStrategyPostProcessForge);
                    }
                }
                else {
                    outputProcessViewFactoryForge = new OutputProcessViewDirectDistinctOrAfterFactoryForge(
                        outputStrategyPostProcessForge,
                        isDistinct,
                        distinctMultiKey,
                        null,
                        null,
                        resultEventType);
                }
            }
            else if (outputLimitSpec.RateType == OutputLimitRateType.AFTER) {
                outputProcessViewFactoryForge = new OutputProcessViewDirectDistinctOrAfterFactoryForge(
                    outputStrategyPostProcessForge,
                    isDistinct,
                    distinctMultiKey,
                    outputLimitSpec.AfterTimePeriodExpr,
                    outputLimitSpec.AfterNumberOfEvents,
                    resultEventType);
            }
            else {
                try {
                    bool isWithHavingClause = statementSpec.Raw.HavingClause != null;
                    bool isStartConditionOnCreation = HasOnlyTables(statementSpec.StreamSpecs);
                    OutputConditionFactoryForge outputConditionFactoryForge =
                        OutputConditionFactoryFactory.CreateCondition(
                            outputLimitSpec,
                            isGrouped,
                            isWithHavingClause,
                            isStartConditionOnCreation,
                            statementRawInfo,
                            services);
                    bool hasOrderBy = statementSpec.Raw.OrderByList != null && statementSpec.Raw.OrderByList.Count > 0;
                    bool hasAfter = outputLimitSpec.AfterNumberOfEvents != null ||
                                    outputLimitSpec.AfterTimePeriodExpr != null;

                    // hint checking with order-by
                    bool hasOptHint = ResultSetProcessorOutputConditionTypeExtensions
                        .GetOutputLimitOpt(statementSpec.Annotations, services.Configuration, hasOrderBy);
                    ResultSetProcessorOutputConditionType conditionType =
                        ResultSetProcessorOutputConditionTypeExtensions
                            .GetConditionType(
                                outputLimitSpec.DisplayLimit,
                                resultSetProcessorType.IsAggregated(),
                                hasOrderBy,
                                hasOptHint,
                                resultSetProcessorType.IsGrouped());

                    // plan serdes
                    foreach (EventType eventType in typesPerStream) {
                        IList<StmtClassForgeableFactory> serdeForgeables = SerdeEventTypeUtility.Plan(
                            eventType,
                            statementRawInfo,
                            services.SerdeEventTypeRegistry,
                            services.SerdeResolver);
                        additionalForgeables.AddRange(serdeForgeables);
                    }
                    
                    bool terminable = outputLimitSpec.RateType == OutputLimitRateType.TERM ||
                                      outputLimitSpec.IsAndAfterTerminate;
                    outputProcessViewFactoryForge = new OutputProcessViewConditionForge(
                        outputStrategyPostProcessForge,
                        isDistinct,
                        distinctMultiKey,
                        outputLimitSpec.AfterTimePeriodExpr,
                        outputLimitSpec.AfterNumberOfEvents,
                        outputConditionFactoryForge,
                        streamCount,
                        conditionType,
                        terminable,
                        hasAfter,
                        resultSetProcessorType.IsUnaggregatedUngrouped(),
                        selectStreamSelector,
                        typesPerStream,
                        resultEventType);
                }
                catch (Exception ex) {
                    throw new ExprValidationException("Failed to validate the output rate limiting clause: " + ex.Message, ex);
                }
            }
            
            return new OutputProcessViewFactoryForgeDesc(outputProcessViewFactoryForge, additionalForgeables);
        }
예제 #14
0
 public EPPreparedExecuteIUDInsertInto(StatementSpecCompiled statementSpec, EPServicesContext services, StatementContext statementContext)
     : base(AssociatedFromClause(statementSpec), services, statementContext)
 {
 }
        private static StreamJoinAnalysisResult VerifyJoinViews(StatementSpecCompiled statementSpec, NamedWindowMgmtService namedWindowMgmtService, AgentInstanceContext defaultAgentInstanceContext)
        {
            var streamSpecs    = statementSpec.StreamSpecs;
            var analysisResult = new StreamJoinAnalysisResult(streamSpecs.Length);

            if (streamSpecs.Length < 2)
            {
                return(analysisResult);
            }

            // Determine if any stream has a unidirectional keyword

            // inspect unidirectional indicator and named window flags
            var unidirectionalStreamNumber = -1;

            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];
                if (streamSpec.Options.IsUnidirectional)
                {
                    analysisResult.SetUnidirectionalInd(i);
                    if (unidirectionalStreamNumber != -1)
                    {
                        throw new ExprValidationException("The unidirectional keyword can only apply to one stream in a join");
                    }
                    unidirectionalStreamNumber = i;
                }
                if (streamSpec.ViewSpecs.Length > 0)
                {
                    analysisResult.SetHasChildViews(i);
                }
                if (streamSpec is NamedWindowConsumerStreamSpec)
                {
                    var nwSpec = (NamedWindowConsumerStreamSpec)streamSpec;
                    if (nwSpec.OptPropertyEvaluator != null && !streamSpec.Options.IsUnidirectional)
                    {
                        throw new ExprValidationException("Failed to validate named window use in join, contained-event is only allowed for named windows when marked as unidirectional");
                    }
                    analysisResult.SetNamedWindow(i);
                    var        processor     = namedWindowMgmtService.GetProcessor(nwSpec.WindowName);
                    string[][] uniqueIndexes = processor.UniqueIndexes;
                    analysisResult.UniqueKeys[i] = uniqueIndexes;
                    if (processor.IsVirtualDataWindow)
                    {
                        analysisResult.ViewExternal[i] = agentInstanceContext => processor.GetProcessorInstance(agentInstanceContext).RootViewInstance.VirtualDataWindow;
                    }
                }
            }
            if ((unidirectionalStreamNumber != -1) && (analysisResult.HasChildViews[unidirectionalStreamNumber]))
            {
                throw new ExprValidationException("The unidirectional keyword requires that no views are declared onto the stream");
            }
            analysisResult.UnidirectionalStreamNumber = unidirectionalStreamNumber;

            // count streams that provide data, excluding streams that poll data (DB and method)
            var countProviderNonpolling = 0;

            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];
                if ((streamSpec is MethodStreamSpec) ||
                    (streamSpec is DBStatementStreamSpec) ||
                    (streamSpec is TableQueryStreamSpec))
                {
                    continue;
                }
                countProviderNonpolling++;
            }

            // if there is only one stream providing data, the analysis is done
            if (countProviderNonpolling == 1)
            {
                return(analysisResult);
            }
            // there are multiple driving streams, verify the presence of a view for insert/remove stream

            // validation of join views works differently for unidirectional as there can be self-joins that don't require a view
            // see if this is a self-join in which all streams are filters and filter specification is the same.
            FilterSpecCompiled unidirectionalFilterSpec = null;
            FilterSpecCompiled lastFilterSpec           = null;
            var pureSelfJoin = true;

            foreach (var streamSpec in statementSpec.StreamSpecs)
            {
                if (!(streamSpec is FilterStreamSpecCompiled))
                {
                    pureSelfJoin = false;
                    continue;
                }

                var filterSpec = ((FilterStreamSpecCompiled)streamSpec).FilterSpec;
                if ((lastFilterSpec != null) && (!lastFilterSpec.EqualsTypeAndFilter(filterSpec)))
                {
                    pureSelfJoin = false;
                }
                if (streamSpec.ViewSpecs.Length > 0)
                {
                    pureSelfJoin = false;
                }
                lastFilterSpec = filterSpec;

                if (streamSpec.Options.IsUnidirectional)
                {
                    unidirectionalFilterSpec = filterSpec;
                }
            }

            // self-join without views and not unidirectional
            if ((pureSelfJoin) && (unidirectionalFilterSpec == null))
            {
                analysisResult.IsPureSelfJoin = true;
                return(analysisResult);
            }

            // weed out filter and pattern streams that don't have a view in a join
            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];
                if (streamSpec.ViewSpecs.Length > 0)
                {
                    continue;
                }

                var name = streamSpec.OptionalStreamName;
                if ((name == null) && (streamSpec is FilterStreamSpecCompiled))
                {
                    name = ((FilterStreamSpecCompiled)streamSpec).FilterSpec.FilterForEventTypeName;
                }
                if ((name == null) && (streamSpec is PatternStreamSpecCompiled))
                {
                    name = "pattern event stream";
                }

                if (streamSpec.Options.IsUnidirectional)
                {
                    continue;
                }
                // allow a self-join without a child view, in that the filter spec is the same as the unidirection's stream filter
                if ((unidirectionalFilterSpec != null) &&
                    (streamSpec is FilterStreamSpecCompiled) &&
                    (((FilterStreamSpecCompiled)streamSpec).FilterSpec.EqualsTypeAndFilter(unidirectionalFilterSpec)))
                {
                    analysisResult.SetUnidirectionalNonDriving(i);
                    continue;
                }
                if ((streamSpec is FilterStreamSpecCompiled) ||
                    (streamSpec is PatternStreamSpecCompiled))
                {
                    throw new ExprValidationException("Joins require that at least one view is specified for each stream, no view was specified for " + name);
                }
            }

            return(analysisResult);
        }
예제 #16
0
        public static OutputProcessViewFactory Make(StatementSpecCompiled statementSpec, InternalEventRouter internalEventRouter, StatementContext statementContext, EventType resultEventType, OutputProcessViewCallback optionalOutputProcessViewCallback, TableService tableService, ResultSetProcessorType resultSetProcessorType)
        {
            // determine direct-callback
            if (optionalOutputProcessViewCallback != null)
            {
                return(new OutputProcessViewFactoryCallback(optionalOutputProcessViewCallback));
            }

            // determine routing
            var isRouted     = false;
            var routeToFront = false;

            if (statementSpec.InsertIntoDesc != null)
            {
                isRouted     = true;
                routeToFront = statementContext.NamedWindowService.IsNamedWindow(statementSpec.InsertIntoDesc.EventTypeName);
            }

            OutputStrategyPostProcessFactory outputStrategyPostProcessFactory = null;

            if ((statementSpec.InsertIntoDesc != null) || (statementSpec.SelectStreamSelectorEnum == SelectClauseStreamSelectorEnum.RSTREAM_ONLY))
            {
                SelectClauseStreamSelectorEnum?insertIntoStreamSelector = null;
                string tableName = null;

                if (statementSpec.InsertIntoDesc != null)
                {
                    insertIntoStreamSelector = statementSpec.InsertIntoDesc.StreamSelector;
                    var tableMetadata = tableService.GetTableMetadata(statementSpec.InsertIntoDesc.EventTypeName);
                    if (tableMetadata != null)
                    {
                        tableName = tableMetadata.TableName;
                        EPLValidationUtil.ValidateContextName(true, tableName, tableMetadata.ContextName, statementSpec.OptionalContextName, true);
                    }
                }

                outputStrategyPostProcessFactory = new OutputStrategyPostProcessFactory(isRouted, insertIntoStreamSelector, statementSpec.SelectStreamSelectorEnum, internalEventRouter, statementContext.EpStatementHandle, routeToFront, tableService, tableName);
            }

            // Do we need to enforce an output policy?
            var streamCount     = statementSpec.StreamSpecs.Length;
            var outputLimitSpec = statementSpec.OutputLimitSpec;
            var isDistinct      = statementSpec.SelectClauseSpec.IsDistinct;
            var isGrouped       = statementSpec.GroupByExpressions != null && statementSpec.GroupByExpressions.GroupByNodes.Length > 0;

            if (outputLimitSpec != null)
            {
                var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    =
                    new ExprValidationContext(
                        new StreamTypeServiceImpl(statementContext.EngineURI, false),
                        statementContext.MethodResolutionService, null,
                        statementContext.TimeProvider,
                        statementContext.VariableService,
                        statementContext.TableService,
                        evaluatorContextStmt,
                        statementContext.EventAdapterService,
                        statementContext.StatementName,
                        statementContext.StatementId,
                        statementContext.Annotations,
                        statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, false, false, null, false);
                if (outputLimitSpec.AfterTimePeriodExpr != null)
                {
                    var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.AfterTimePeriodExpr, validationContext);
                    outputLimitSpec.AfterTimePeriodExpr = timePeriodExpr;
                }
                if (outputLimitSpec.TimePeriodExpr != null)
                {
                    var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.TimePeriodExpr, validationContext);
                    outputLimitSpec.TimePeriodExpr = timePeriodExpr;
                    if (timePeriodExpr.IsConstantResult && timePeriodExpr.EvaluateAsSeconds(null, true, new ExprEvaluatorContextStatement(statementContext, false)) <= 0)
                    {
                        throw new ExprValidationException("Invalid time period expression returns a zero or negative time interval");
                    }
                }
            }

            OutputProcessViewFactory outputProcessViewFactory;

            if (outputLimitSpec == null)
            {
                if (!isDistinct)
                {
                    outputProcessViewFactory = new OutputProcessViewDirectFactory(statementContext, outputStrategyPostProcessFactory);
                }
                else
                {
                    outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, null, null, resultEventType);
                }
            }
            else if (outputLimitSpec.RateType == OutputLimitRateType.AFTER)
            {
                outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType);
            }
            else
            {
                try {
                    var isWithHavingClause         = statementSpec.HavingExprRootNode != null;
                    var isStartConditionOnCreation = HasOnlyTables(statementSpec.StreamSpecs);
                    var outputConditionFactory     = OutputConditionFactoryFactory.CreateCondition(outputLimitSpec, statementContext, isGrouped, isWithHavingClause, isStartConditionOnCreation);
                    var hasOrderBy = statementSpec.OrderByList != null && statementSpec.OrderByList.Length > 0;

                    OutputProcessViewConditionFactory.ConditionType conditionType;

                    var hasAfter = outputLimitSpec.AfterNumberOfEvents != null || outputLimitSpec.AfterTimePeriodExpr != null;
                    var isUnaggregatedUngrouped = resultSetProcessorType == ResultSetProcessorType.HANDTHROUGH || resultSetProcessorType == ResultSetProcessorType.UNAGGREGATED_UNGROUPED;

                    // hint checking with order-by
                    var hasOptHint = HintEnum.ENABLE_OUTPUTLIMIT_OPT.GetHint(statementSpec.Annotations) != null;
                    if (hasOptHint && hasOrderBy)
                    {
                        throw new ExprValidationException("The " + HintEnum.ENABLE_OUTPUTLIMIT_OPT + " hint is not supported with order-by");
                    }

                    if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.SNAPSHOT)
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.SNAPSHOT;
                    }
                    // For FIRST without groups we are using a special logic that integrates the first-flag, in order to still conveniently use all sorts of output conditions.
                    // FIRST with group-by is handled by setting the output condition to null (OutputConditionNull) and letting the ResultSetProcessor handle first-per-group.
                    // Without having-clause there is no required order of processing, thus also use regular policy.
                    else if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.FIRST && statementSpec.GroupByExpressions == null)
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_FIRST;
                    }
                    else if (isUnaggregatedUngrouped && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST)
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED;
                    }
                    else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.ALL && !hasOrderBy)
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED;
                    }
                    else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST && !hasOrderBy)
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED;
                    }
                    else
                    {
                        conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_NONFIRST;
                    }

                    var selectClauseStreamSelectorEnum = statementSpec.SelectStreamSelectorEnum;
                    var terminable = outputLimitSpec.RateType == OutputLimitRateType.TERM || outputLimitSpec.IsAndAfterTerminate;
                    outputProcessViewFactory = new OutputProcessViewConditionFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType, outputConditionFactory, streamCount, conditionType, outputLimitSpec.DisplayLimit, terminable, hasAfter, isUnaggregatedUngrouped, selectClauseStreamSelectorEnum);
                }
                catch (Exception ex) {
                    throw new ExprValidationException("Error in the output rate limiting clause: " + ex.Message, ex);
                }
            }

            return(outputProcessViewFactory);
        }
        public static EPStatementStartMethodSelectDesc Prepare(
            StatementSpecCompiled statementSpec,
            EPServicesContext services,
            StatementContext statementContext,
            bool recoveringResilient,
            AgentInstanceContext defaultAgentInstanceContext,
            bool queryPlanLogging,
            ViewableActivatorFactory optionalViewableActivatorFactory,
            OutputProcessViewCallback optionalOutputProcessViewCallback,
            SelectExprProcessorDeliveryCallback selectExprProcessorDeliveryCallback)
        {
            // define stop and destroy
            var stopCallbacks    = new List <StopCallback>();
            var destroyCallbacks = new EPStatementDestroyCallbackList();

            // determine context
            var contextName             = statementSpec.OptionalContextName;
            var contextPropertyRegistry = (contextName != null) ? services.ContextManagementService.GetContextDescriptor(contextName).ContextPropertyRegistry : null;

            // Determine stream names for each stream - some streams may not have a name given
            var streamNames = EPStatementStartMethodHelperUtil.DetermineStreamNames(statementSpec.StreamSpecs);
            var numStreams  = streamNames.Length;

            if (numStreams == 0)
            {
                throw new ExprValidationException("The from-clause is required but has not been specified");
            }
            var isJoin     = statementSpec.StreamSpecs.Length > 1;
            var hasContext = statementSpec.OptionalContextName != null;

            // First we create streams for subselects, if there are any
            var subSelectStreamDesc = EPStatementStartMethodHelperSubselect.CreateSubSelectActivation(services, statementSpec, statementContext, destroyCallbacks);

            // Create streams and views
            var eventStreamParentViewableActivators = new ViewableActivator[numStreams];
            var unmaterializedViewChain             = new ViewFactoryChain[numStreams];
            var eventTypeNames           = new string[numStreams];
            var isNamedWindow            = new bool[numStreams];
            var historicalEventViewables = new HistoricalEventViewable[numStreams];

            // verify for joins that required views are present
            var joinAnalysisResult   = VerifyJoinViews(statementSpec, statementContext.NamedWindowMgmtService, defaultAgentInstanceContext);
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);

            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];

                var isCanIterateUnbound = streamSpec.ViewSpecs.Length == 0 &&
                                          (services.ConfigSnapshot.EngineDefaults.ViewResourcesConfig.IsIterableUnbound ||
                                           AnnotationUtil.FindAttribute(statementSpec.Annotations, typeof(IterableUnboundAttribute)) != null);

                // Create view factories and parent view based on a filter specification
                if (streamSpec is FilterStreamSpecCompiled)
                {
                    var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec;
                    eventTypeNames[i] = filterStreamSpec.FilterSpec.FilterForEventTypeName;

                    // Since only for non-joins we get the existing stream's lock and try to reuse it's views
                    var filterSubselectSameStream = EPStatementStartMethodHelperUtil.DetermineSubquerySameStream(statementSpec, filterStreamSpec);

                    // create activator
                    ViewableActivator activatorDeactivator;
                    if (optionalViewableActivatorFactory != null)
                    {
                        activatorDeactivator = optionalViewableActivatorFactory.CreateActivatorSimple(filterStreamSpec);
                        if (activatorDeactivator == null)
                        {
                            throw new IllegalStateException("Viewable activate is null for " + filterStreamSpec.FilterSpec.FilterForEventType.Name);
                        }
                    }
                    else
                    {
                        if (!hasContext)
                        {
                            activatorDeactivator = services.ViewableActivatorFactory.CreateStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, i, isCanIterateUnbound);
                        }
                        else
                        {
                            InstrumentationAgent instrumentationAgentFilter = null;
                            if (InstrumentationHelper.ENABLED)
                            {
                                var eventTypeName = filterStreamSpec.FilterSpec.FilterForEventType.Name;
                                var streamNumber  = i;
                                instrumentationAgentFilter = new ProxyInstrumentationAgent()
                                {
                                    ProcIndicateQ = () => {
                                        InstrumentationHelper.Get().QFilterActivationStream(eventTypeName, streamNumber);
                                    },
                                    ProcIndicateA = () => {
                                        InstrumentationHelper.Get().AFilterActivationStream();
                                    },
                                };
                            }

                            activatorDeactivator = services.ViewableActivatorFactory.CreateFilterProxy(services, filterStreamSpec.FilterSpec, statementSpec.Annotations, false, instrumentationAgentFilter, isCanIterateUnbound, i);
                        }
                    }
                    eventStreamParentViewableActivators[i] = activatorDeactivator;

                    var resultEventType = filterStreamSpec.FilterSpec.ResultEventType;
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, resultEventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1);
                }
                // Create view factories and parent view based on a pattern expression
                else if (streamSpec is PatternStreamSpecCompiled)
                {
                    var patternStreamSpec = (PatternStreamSpecCompiled)streamSpec;
                    var usedByChildViews  = streamSpec.ViewSpecs.Length > 0 || (statementSpec.InsertIntoDesc != null);
                    var patternTypeName   = statementContext.StatementId + "_pattern_" + i;
                    var eventType         = services.EventAdapterService.CreateSemiAnonymousMapType(patternTypeName, patternStreamSpec.TaggedEventTypes, patternStreamSpec.ArrayEventTypes, usedByChildViews);
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, eventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1);

                    var rootFactoryNode = services.PatternNodeFactory.MakeRootNode(patternStreamSpec.EvalFactoryNode);
                    var patternContext  = statementContext.PatternContextFactory.CreateContext(statementContext, i, rootFactoryNode, patternStreamSpec.MatchedEventMapMeta, true);

                    // create activator
                    var patternActivator = services.ViewableActivatorFactory.CreatePattern(patternContext, rootFactoryNode, eventType, EPStatementStartMethodHelperUtil.IsConsumingFilters(patternStreamSpec.EvalFactoryNode), patternStreamSpec.IsSuppressSameEventMatches, patternStreamSpec.IsDiscardPartialsOnMatch, isCanIterateUnbound);
                    eventStreamParentViewableActivators[i] = patternActivator;
                }
                // Create view factories and parent view based on a database SQL statement
                else if (streamSpec is DBStatementStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Historical data");
                    var sqlStreamSpec                  = (DBStatementStreamSpec)streamSpec;
                    var typeConversionHook             = (SQLColumnTypeConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLCOL, typeof(SQLColumnTypeConversion), statementContext.MethodResolutionService);
                    var outputRowConversionHook        = (SQLOutputRowConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLROW, typeof(SQLOutputRowConversion), statementContext.MethodResolutionService);
                    var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle;
                    var historicalEventViewable        = DatabasePollingViewableFactory.CreateDBStatementView(
                        statementContext.StatementId, i, sqlStreamSpec,
                        services.DatabaseRefService,
                        services.EventAdapterService,
                        epStatementAgentInstanceHandle,
                        statementContext.Annotations,
                        typeConversionHook,
                        outputRowConversionHook,
                        statementContext.ConfigSnapshot.EngineDefaults.LoggingConfig.IsEnableADO,
                        services.DataCacheFactory,
                        statementContext);
                    historicalEventViewables[i]            = historicalEventViewable;
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable);
                    stopCallbacks.Add(historicalEventViewable);
                }
                else if (streamSpec is MethodStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Method data");
                    var methodStreamSpec = (MethodStreamSpec)streamSpec;
                    var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle;
                    var historicalEventViewable        = MethodPollingViewableFactory.CreatePollMethodView(
                        i, methodStreamSpec, services.EventAdapterService, epStatementAgentInstanceHandle,
                        statementContext.MethodResolutionService, services.EngineImportService,
                        statementContext.SchedulingService, statementContext.ScheduleBucket, evaluatorContextStmt,
                        statementContext.VariableService, statementContext.ContextName, services.DataCacheFactory,
                        statementContext);
                    historicalEventViewables[i]            = historicalEventViewable;
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable);
                    stopCallbacks.Add(historicalEventViewable);
                }
                else if (streamSpec is TableQueryStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Table data");
                    var tableStreamSpec = (TableQueryStreamSpec)streamSpec;
                    if (isJoin && 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             metadata         = services.TableService.GetTableMetadata(tableStreamSpec.TableName);
                    ExprEvaluator[] tableFilterEvals = null;
                    if (tableStreamSpec.FilterExpressions.Count > 0)
                    {
                        tableFilterEvals = ExprNodeUtility.GetEvaluators(tableStreamSpec.FilterExpressions);
                    }
                    EPLValidationUtil.ValidateContextName(true, metadata.TableName, metadata.ContextName, statementSpec.OptionalContextName, false);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateTable(metadata, tableFilterEvals);
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(metadata.InternalEventType);
                    eventTypeNames[i] = tableStreamSpec.TableName;
                    joinAnalysisResult.SetTablesForStream(i, metadata);
                    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");
                    }
                    if (isJoin)
                    {
                        destroyCallbacks.AddCallback(new EPStatementDestroyCallbackTableIdxRef(services.TableService, metadata, statementContext.StatementName));
                    }
                    services.StatementVariableRefService.AddReferences(statementContext.StatementName, metadata.TableName);
                }
                else if (streamSpec is NamedWindowConsumerStreamSpec)
                {
                    var namedSpec       = (NamedWindowConsumerStreamSpec)streamSpec;
                    var processor       = services.NamedWindowMgmtService.GetProcessor(namedSpec.WindowName);
                    var namedWindowType = processor.TailView.EventType;
                    if (namedSpec.OptPropertyEvaluator != null)
                    {
                        namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType;
                    }

                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateNamedWindow(processor, namedSpec, statementContext);
                    services.NamedWindowConsumerMgmtService.AddConsumer(statementContext, namedSpec);
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, namedWindowType, namedSpec.ViewSpecs, namedSpec.Options, statementContext, false, -1);
                    joinAnalysisResult.SetNamedWindow(i);
                    eventTypeNames[i] = namedSpec.WindowName;
                    isNamedWindow[i]  = true;

                    // Consumers to named windows cannot declare a data window view onto the named window to avoid duplicate remove streams
                    EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(unmaterializedViewChain[i].FactoryChain);
                }
                else
                {
                    throw new ExprValidationException("Unknown stream specification type: " + streamSpec);
                }
            }

            // handle match-recognize pattern
            if (statementSpec.MatchRecognizeSpec != null)
            {
                if (isJoin)
                {
                    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 = (unmaterializedViewChain[0].FactoryChain.IsEmpty()) && (!(statementSpec.StreamSpecs[0] is NamedWindowConsumerStreamSpec));
                var factoryX  = services.RegexHandlerFactory.MakeViewFactory(unmaterializedViewChain[0], statementSpec.MatchRecognizeSpec, defaultAgentInstanceContext, isUnbound, statementSpec.Annotations, services.ConfigSnapshot.EngineDefaults.MatchRecognizeConfig);
                unmaterializedViewChain[0].FactoryChain.Add(factoryX);

                EPStatementStartMethodHelperAssignExpr.AssignAggregations(factoryX.AggregationService, factoryX.AggregationExpressions);
            }

            // Obtain event types from view factory chains
            var streamEventTypes = new EventType[statementSpec.StreamSpecs.Length];

            for (var i = 0; i < unmaterializedViewChain.Length; i++)
            {
                streamEventTypes[i] = unmaterializedViewChain[i].EventType;
            }

            // Add uniqueness information useful for joins
            joinAnalysisResult.AddUniquenessInfo(unmaterializedViewChain, statementSpec.Annotations);

            // Validate sub-select views
            var subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.PlanSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, streamNames, streamEventTypes, eventTypeNames, statementSpec.DeclaredExpressions, contextPropertyRegistry);

            // Construct type information per stream
            StreamTypeService typeService      = new StreamTypeServiceImpl(streamEventTypes, streamNames, EPStatementStartMethodHelperUtil.GetHasIStreamOnly(isNamedWindow, unmaterializedViewChain), services.EngineURI, false);
            var viewResourceDelegateUnverified = new ViewResourceDelegateUnverified();

            // 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;
                }
                historicalEventViewable.Validate(
                    services.EngineImportService,
                    typeService,
                    statementContext.MethodResolutionService,
                    statementContext.TimeProvider,
                    statementContext.VariableService, statementContext.TableService,
                    statementContext.ScriptingService, evaluatorContextStmt,
                    services.ConfigSnapshot, services.SchedulingService, services.EngineURI,
                    statementSpec.SqlParameters,
                    statementContext.EventAdapterService, statementContext);
                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");
                }
            }

            // unidirectional is not supported with into-table
            if (joinAnalysisResult.IsUnidirectional && statementSpec.IntoTableSpec != null)
            {
                throw new ExprValidationException("Into-table does not allow unidirectional joins");
            }

            // Construct a processor for results posted by views and joins, which takes care of aggregation if required.
            // May return null if we don't need to post-process results posted by views or joins.
            var resultSetProcessorPrototypeDesc = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                statementSpec, statementContext, typeService, viewResourceDelegateUnverified, joinAnalysisResult.UnidirectionalInd, true, contextPropertyRegistry, selectExprProcessorDeliveryCallback, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, false, false);

            // Validate where-clause filter tree, outer join clause and output limit expression
            EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, viewResourceDelegateUnverified);

            // Handle 'prior' function nodes in terms of view requirements
            var viewResourceDelegateVerified = EPStatementStartMethodHelperViewResources.VerifyPreviousAndPriorRequirements(unmaterializedViewChain, viewResourceDelegateUnverified);

            // handle join
            JoinSetComposerPrototype joinSetComposerPrototype = null;

            if (numStreams > 1)
            {
                var selectsRemoveStream =
                    statementSpec.SelectStreamSelectorEnum.IsSelectsRStream() ||
                    statementSpec.OutputLimitSpec != null;
                var hasAggregations = !resultSetProcessorPrototypeDesc.AggregationServiceFactoryDesc.Expressions.IsEmpty();
                joinSetComposerPrototype = JoinSetComposerPrototypeFactory.MakeComposerPrototype(
                    statementContext.StatementName, statementContext.StatementId,
                    statementSpec.OuterJoinDescList, statementSpec.FilterRootNode, typeService.EventTypes, streamNames,
                    joinAnalysisResult, queryPlanLogging, statementContext, historicalViewableDesc, defaultAgentInstanceContext,
                    selectsRemoveStream, hasAggregations, services.TableService, false, services.EventTableIndexService.AllowInitIndex(recoveringResilient));
            }

            // obtain factory for output limiting
            var outputViewFactory = OutputProcessViewFactoryFactory.Make(statementSpec, services.InternalEventRouter, statementContext, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultEventType, optionalOutputProcessViewCallback, services.TableService, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultSetProcessorType, services.ResultSetProcessorHelperFactory, services.StatementVariableRefService);

            // Factory for statement-context instances
            var factory = new StatementAgentInstanceFactorySelect(
                numStreams, eventStreamParentViewableActivators,
                statementContext, statementSpec, services,
                typeService, unmaterializedViewChain, resultSetProcessorPrototypeDesc, joinAnalysisResult, recoveringResilient,
                joinSetComposerPrototype, subSelectStrategyCollection, viewResourceDelegateVerified, outputViewFactory);

            EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);

            return(new EPStatementStartMethodSelectDesc(factory, subSelectStrategyCollection, viewResourceDelegateUnverified, resultSetProcessorPrototypeDesc, stopMethod, destroyCallbacks));
        }
 public EPStatementStartMethodCreateExpression(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
 public EPStatementStartMethodCreateVariable(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
예제 #20
0
 protected EPStatementStartMethodBase(StatementSpecCompiled statementSpec)
 {
     _statementSpec = statementSpec;
 }
예제 #21
0
 public ContextManagedStatementCreateVariableDesc(StatementSpecCompiled statementSpec, StatementContext statementContext, ContextMergeView mergeView, StatementAgentInstanceFactory factory)
     : base(statementSpec, statementContext, mergeView, factory)
 {
 }
 public EPStatementStartMethodSelect(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
예제 #23
0
 public EPStatementStartMethodCreateContext(StatementSpecCompiled statementSpec)
     : base(statementSpec)
 {
 }
예제 #24
0
 public ViewableActivator CreateStreamReuseView(EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool isJoin, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound)
 {
     return(new ViewableActivatorStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, streamNum, isCanIterateUnbound));
 }
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="statementSpec">is a container for the definition of all statement constructs thatmay have been used in the statement, i.e. if defines the select clauses, insert into, outer joins etc.
        /// </param>
        /// <param name="services">is the service instances for dependency injection</param>
        /// <param name="statementContext">is statement-level information and statement services</param>
        /// <throws>com.espertech.esper.epl.expression.core.ExprValidationException if the preparation failed</throws>
        public EPPreparedExecuteIUDSingleStream(
            StatementSpecCompiled statementSpec,
            EPServicesContext services,
            StatementContext statementContext)
        {
            var queryPlanLogging = services.ConfigSnapshot.EngineDefaults.LoggingConfig.IsEnableQueryPlan;

            if (queryPlanLogging)
            {
                QueryPlanLog.Info("Query plans for Fire-and-forget query '" + statementContext.Expression + "'");
            }

            HasTableAccess = statementSpec.IntoTableSpec != null ||
                             (statementSpec.TableNodes != null && statementSpec.TableNodes.Length > 0);
            if (statementSpec.InsertIntoDesc != null && services.TableService.GetTableMetadata(statementSpec.InsertIntoDesc.EventTypeName) != null)
            {
                HasTableAccess = true;
            }
            if (statementSpec.FireAndForgetSpec is FireAndForgetSpecUpdate ||
                statementSpec.FireAndForgetSpec is FireAndForgetSpecDelete)
            {
                HasTableAccess |= statementSpec.StreamSpecs[0] is TableQueryStreamSpec;
            }

            StatementSpec    = statementSpec;
            Services         = services;
            StatementContext = statementContext;

            // validate general FAF criteria
            EPPreparedExecuteMethodHelper.ValidateFAFQuery(statementSpec);

            // obtain processor
            var streamSpec = statementSpec.StreamSpecs[0];

            Processor = FireAndForgetProcessorFactory.ValidateResolveProcessor(streamSpec, services);

            // obtain name and type
            var processorName = Processor.NamedWindowOrTableName;
            var eventType     = Processor.EventTypeResultSetProcessor;

            // determine alias
            var aliasName = processorName;

            if (streamSpec.OptionalStreamName != null)
            {
                aliasName = streamSpec.OptionalStreamName;
            }

            // compile filter to optimize access to named window
            var typeService = new StreamTypeServiceImpl(new EventType[] { eventType }, new string[] { aliasName }, new bool[] { true }, services.EngineURI, true);
            FilterSpecCompiled filter;

            if (statementSpec.FilterRootNode != null)
            {
                var tagged = new LinkedHashMap <string, Pair <EventType, string> >();
                FilterSpecCompiled filterCompiled;
                try {
                    filterCompiled = FilterSpecCompiler.MakeFilterSpec(eventType, aliasName,
                                                                       Collections.SingletonList(statementSpec.FilterRootNode), null,
                                                                       tagged, tagged, typeService,
                                                                       null, statementContext,
                                                                       Collections.SingletonList(0));
                }
                catch (Exception ex) {
                    Log.Warn("Unexpected exception analyzing filter paths: " + ex.Message, ex);
                    filterCompiled = null;
                }
                filter = filterCompiled;
            }
            else
            {
                filter = null;
            }

            // validate expressions
            EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, null);

            // get executor
            Executor = GetExecutor(filter, aliasName);
        }
예제 #26
0
        internal static IndexHintPair GetIndexHintPair(StatementContext statementContext, StatementSpecCompiled statementSpec)
        {
            IndexHint       indexHint       = IndexHint.GetIndexHint(statementContext.Annotations);
            ExcludePlanHint excludePlanHint = null;

            if (statementSpec.OnTriggerDesc is OnTriggerWindowDesc)
            {
                OnTriggerWindowDesc onTriggerWindowDesc = (OnTriggerWindowDesc)statementSpec.OnTriggerDesc;
                string[]            streamNames         = { onTriggerWindowDesc.OptionalAsName, statementSpec.StreamSpecs[0].OptionalStreamName };
                excludePlanHint = ExcludePlanHint.GetHint(streamNames, statementContext);
            }
            return(new IndexHintPair(indexHint, excludePlanHint));
        }
예제 #27
0
 public StatementAgentInstanceFactoryCreateWindow(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, ViewFactoryChain unmaterializedViewChain, ResultSetProcessorFactoryDesc resultSetProcessorPrototype, OutputProcessViewFactory outputProcessViewFactory, bool recoveringStatement)
     : base(statementContext.Annotations)
 {
     _statementContext            = statementContext;
     _statementSpec               = statementSpec;
     _services                    = services;
     _activator                   = activator;
     _unmaterializedViewChain     = unmaterializedViewChain;
     _resultSetProcessorPrototype = resultSetProcessorPrototype;
     _outputProcessViewFactory    = outputProcessViewFactory;
     _isRecoveringStatement       = recoveringStatement;
 }
예제 #28
0
        public StatementAgentInstanceFactoryOnTriggerNamedWindow(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection, ResultSetProcessorFactoryDesc resultSetProcessorPrototype, ExprNode validatedJoin, ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype, NamedWindowOnExprFactory onExprFactory, OutputProcessViewFactory outputProcessViewFactory, EventType activatorResultEventType, NamedWindowProcessor processor)
            : base(statementContext, statementSpec, services, activator, subSelectStrategyCollection)
        {
            _resultSetProcessorPrototype       = resultSetProcessorPrototype;
            _outputResultSetProcessorPrototype = outputResultSetProcessorPrototype;
            _onExprFactory            = onExprFactory;
            _outputProcessViewFactory = outputProcessViewFactory;
            _processor = processor;

            IndexHintPair   pair            = GetIndexHintPair(statementContext, statementSpec);
            IndexHint       indexHint       = pair.IndexHint;
            ExcludePlanHint excludePlanHint = pair.ExcludePlanHint;

            _queryPlan = SubordinateQueryPlanner.PlanOnExpression(
                validatedJoin, activatorResultEventType, indexHint, processor.IsEnableSubqueryIndexShare, -1, excludePlanHint,
                processor.IsVirtualDataWindow, processor.EventTableIndexMetadataRepo, processor.NamedWindowType,
                processor.OptionalUniqueKeyProps, false, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations);
            if (_queryPlan.IndexDescs != null)
            {
                SubordinateQueryPlannerUtil.AddIndexMetaAndRef(_queryPlan.IndexDescs, processor.EventTableIndexMetadataRepo, statementContext.StatementName);
                statementContext.StatementStopService.StatementStopped += () =>
                {
                    for (int i = 0; i < _queryPlan.IndexDescs.Length; i++)
                    {
                        bool last = processor.EventTableIndexMetadataRepo.RemoveIndexReference(_queryPlan.IndexDescs[i].IndexMultiKey, statementContext.StatementName);
                        if (last)
                        {
                            processor.EventTableIndexMetadataRepo.RemoveIndex(_queryPlan.IndexDescs[i].IndexMultiKey);
                            processor.RemoveAllInstanceIndexes(_queryPlan.IndexDescs[i].IndexMultiKey);
                        }
                    }
                };
            }
            SubordinateQueryPlannerUtil.QueryPlanLogOnExpr(processor.RootView.IsQueryPlanLogging, NamedWindowRootView.QueryPlanLog,
                                                           _queryPlan, statementContext.Annotations);
        }
예제 #29
0
파일: Select.cs 프로젝트: qinfengzhu/nesper
        public DataFlowOpInitializeResult Initialize(DataFlowOpInitializateContext context)
        {
            if (context.InputPorts.IsEmpty())
            {
                throw new ArgumentException("Select operator requires at least one input stream");
            }
            if (context.OutputPorts.Count != 1)
            {
                throw new ArgumentException("Select operator requires one output stream but produces " + context.OutputPorts.Count + " streams");
            }

            DataFlowOpOutputPort portZero = context.OutputPorts[0];

            if (portZero.OptionalDeclaredType != null && !portZero.OptionalDeclaredType.IsUnderlying)
            {
                _submitEventBean = true;
            }

            // determine adapter factories for each type
            int numStreams = context.InputPorts.Count;

            _adapterFactories = new EventBeanAdapterFactory[numStreams];
            for (int i = 0; i < numStreams; i++)
            {
                EventType eventType = context.InputPorts.Get(i).TypeDesc.EventType;
                _adapterFactories[i] = context.StatementContext.EventAdapterService.GetAdapterFactoryForType(eventType);
            }

            // Compile and prepare execution
            //
            StatementContext     statementContext     = context.StatementContext;
            EPServicesContext    servicesContext      = context.ServicesContext;
            AgentInstanceContext agentInstanceContext = context.AgentInstanceContext;

            // validate
            if (select.InsertIntoDesc != null)
            {
                throw new ExprValidationException("Insert-into clause is not supported");
            }
            if (select.SelectStreamSelectorEnum != SelectClauseStreamSelectorEnum.ISTREAM_ONLY)
            {
                throw new ExprValidationException("Selecting remove-stream is not supported");
            }
            ExprNodeSubselectDeclaredDotVisitor visitor            = StatementSpecRawAnalyzer.WalkSubselectAndDeclaredDotExpr(select);
            GroupByClauseExpressions            groupByExpressions = GroupByExpressionHelper.GetGroupByRollupExpressions(
                servicesContext.Container,
                select.GroupByExpressions,
                select.SelectClauseSpec,
                select.HavingExprRootNode,
                select.OrderByList,
                visitor);

            if (!visitor.Subselects.IsEmpty())
            {
                throw new ExprValidationException("Subselects are not supported");
            }

            IDictionary <int, FilterStreamSpecRaw> streams = new Dictionary <int, FilterStreamSpecRaw>();

            for (int streamNum = 0; streamNum < select.StreamSpecs.Count; streamNum++)
            {
                var rawStreamSpec = select.StreamSpecs[streamNum];
                if (!(rawStreamSpec is FilterStreamSpecRaw))
                {
                    throw new ExprValidationException("From-clause must contain only streams and cannot contain patterns or other constructs");
                }
                streams.Put(streamNum, (FilterStreamSpecRaw)rawStreamSpec);
            }

            // compile offered streams
            IList <StreamSpecCompiled> streamSpecCompileds = new List <StreamSpecCompiled>();

            for (int streamNum = 0; streamNum < select.StreamSpecs.Count; streamNum++)
            {
                var filter    = streams.Get(streamNum);
                var inputPort = FindInputPort(filter.RawFilterSpec.EventTypeName, context.InputPorts);
                if (inputPort == null)
                {
                    throw new ExprValidationException(
                              string.Format("Failed to find stream '{0}' among input ports, input ports are {1}", filter.RawFilterSpec.EventTypeName, GetInputPortNames(context.InputPorts).Render(", ", "[]")));
                }
                var eventType                = inputPort.Value.Value.TypeDesc.EventType;
                var streamAlias              = filter.OptionalStreamName;
                var filterSpecCompiled       = new FilterSpecCompiled(eventType, streamAlias, new IList <FilterSpecParam>[] { Collections.GetEmptyList <FilterSpecParam>() }, null);
                var filterStreamSpecCompiled = new FilterStreamSpecCompiled(filterSpecCompiled, select.StreamSpecs[0].ViewSpecs, streamAlias, StreamSpecOptions.DEFAULT);
                streamSpecCompileds.Add(filterStreamSpecCompiled);
            }

            // create compiled statement spec
            SelectClauseSpecCompiled selectClauseCompiled = StatementLifecycleSvcUtil.CompileSelectClause(select.SelectClauseSpec);

            // determine if snapshot output is needed
            OutputLimitSpec outputLimitSpec = select.OutputLimitSpec;

            _isOutputLimited = outputLimitSpec != null;
            if (iterate)
            {
                if (outputLimitSpec != null)
                {
                    throw new ExprValidationException("Output rate limiting is not supported with 'iterate'");
                }
                outputLimitSpec = new OutputLimitSpec(OutputLimitLimitType.SNAPSHOT, OutputLimitRateType.TERM);
            }

            var mergedAnnotations = AnnotationUtil.MergeAnnotations(statementContext.Annotations, context.OperatorAnnotations);
            var orderByArray      = OrderByItem.ToArray(select.OrderByList);
            var outerJoinArray    = OuterJoinDesc.ToArray(select.OuterJoinDescList);
            var streamSpecArray   = streamSpecCompileds.ToArray();
            var compiled          = new StatementSpecCompiled(null, null, null, null, null, null, null, SelectClauseStreamSelectorEnum.ISTREAM_ONLY,
                                                              selectClauseCompiled, streamSpecArray, outerJoinArray, select.FilterExprRootNode, select.HavingExprRootNode, outputLimitSpec,
                                                              orderByArray, ExprSubselectNode.EMPTY_SUBSELECT_ARRAY, ExprNodeUtility.EMPTY_DECLARED_ARR, ExprNodeUtility.EMPTY_SCRIPTS, select.ReferencedVariables,
                                                              select.RowLimitSpec, CollectionUtil.EMPTY_STRING_ARRAY, mergedAnnotations, null, null, null, null, null, null, null, null, null, groupByExpressions, null, null);

            // create viewable per port
            var viewables = new EPLSelectViewable[context.InputPorts.Count];

            _viewablesPerPort = viewables;
            foreach (var entry in context.InputPorts)
            {
                EPLSelectViewable viewable = new EPLSelectViewable(entry.Value.TypeDesc.EventType);
                viewables[entry.Key] = viewable;
            }

            var activatorFactory = new ProxyViewableActivatorFactory
            {
                ProcCreateActivatorSimple = filterStreamSpec =>
                {
                    EPLSelectViewable found = null;
                    foreach (EPLSelectViewable sviewable in viewables)
                    {
                        if (sviewable.EventType == filterStreamSpec.FilterSpec.FilterForEventType)
                        {
                            found = sviewable;
                        }
                    }
                    if (found == null)
                    {
                        throw new IllegalStateException("Failed to find viewable for filter");
                    }
                    EPLSelectViewable viewable = found;
                    return(new ProxyViewableActivator(
                               (agentInstanceContext2, isSubselect, isRecoveringResilient) =>
                               new ViewableActivationResult(
                                   viewable,
                                   new ProxyStopCallback(() => { }),
                                   null,
                                   null,
                                   null,
                                   false,
                                   false,
                                   null)));
                }
            };

            // for per-row deliver, register select expression result callback
            OutputProcessViewCallback optionalOutputProcessViewCallback = null;

            if (!iterate && !_isOutputLimited)
            {
                _deliveryCallback = new EPLSelectDeliveryCallback();
                optionalOutputProcessViewCallback = this;
            }

            // prepare
            EPStatementStartMethodSelectDesc selectDesc = EPStatementStartMethodSelectUtil.Prepare(compiled, servicesContext, statementContext, false, agentInstanceContext, false, activatorFactory, optionalOutputProcessViewCallback, _deliveryCallback);

            // start
            _selectResult = (StatementAgentInstanceFactorySelectResult)selectDesc.StatementAgentInstanceFactorySelect.NewContext(agentInstanceContext, false);

            // for output-rate-limited, register a dispatch view
            if (_isOutputLimited)
            {
                _selectResult.FinalView.AddView(new EPLSelectUpdateDispatchView(this));
            }

            // assign strategies to expression nodes
            EPStatementStartMethodHelperAssignExpr.AssignExpressionStrategies(
                selectDesc,
                _selectResult.OptionalAggegationService,
                _selectResult.SubselectStrategies,
                _selectResult.PriorNodeStrategies,
                _selectResult.PreviousNodeStrategies,
                null,
                null,
                _selectResult.TableAccessEvalStrategies);

            EventType outputEventType = selectDesc.ResultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultEventType;

            _agentInstanceContext = agentInstanceContext;
            return(new DataFlowOpInitializeResult(new GraphTypeDesc[] { new GraphTypeDesc(false, true, outputEventType) }));
        }
예제 #30
0
        public static OnTriggerSetPlan HandleSetVariable(
            string className,
            CodegenNamespaceScope namespaceScope,
            string classPostfix,
            OnTriggerActivatorDesc activatorResult,
            string optionalStreamName,
            IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation,
            OnTriggerSetDesc desc,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            StreamTypeService typeService = new StreamTypeServiceImpl(
                new[] {activatorResult.ActivatorResultEventType},
                new[] {optionalStreamName},
                new[] {true},
                false,
                false);
            var validationContext = new ExprValidationContextBuilder(typeService, @base.StatementRawInfo, services)
                .WithAllowBindingConsumption(true)
                .Build();

            // handle subselects
            var subselectForges = SubSelectHelperForgePlanner.PlanSubSelect(
                @base,
                subselectActivation,
                new[] {optionalStreamName},
                new[] {activatorResult.ActivatorResultEventType},
                new[] {activatorResult.TriggerEventTypeName},
                services);

            // validate assignments
            foreach (var assignment in desc.Assignments) {
                var validated = ExprNodeUtilityValidate.GetValidatedAssignment(assignment, validationContext);
                assignment.Expression = validated;
            }

            // create read-write logic
            var variableReadWritePackageForge = new VariableReadWritePackageForge(desc.Assignments, services);

            // plan table access
            var tableAccessForges = ExprTableEvalHelperPlan.PlanTableAccess(@base.StatementSpec.TableAccessNodes);

            // create output event type
            var eventTypeName = services.EventTypeNameGeneratorStatement.AnonymousTypeName;
            var eventTypeMetadata = new EventTypeMetadata(
                eventTypeName,
                @base.ModuleName,
                EventTypeTypeClass.STATEMENTOUT,
                EventTypeApplicationType.MAP,
                NameAccessModifier.TRANSIENT,
                EventTypeBusModifier.NONBUS,
                false,
                EventTypeIdPair.Unassigned());
            var eventType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                eventTypeMetadata,
                variableReadWritePackageForge.VariableTypes,
                null,
                null,
                null,
                null,
                services.BeanEventTypeFactoryPrivate,
                services.EventTypeCompileTimeResolver);
            services.EventTypeCompileTimeRegistry.NewType(eventType);

            // Handle output format
            var defaultSelectAllSpec = new StatementSpecCompiled();
            defaultSelectAllSpec.SelectClauseCompiled.WithSelectExprList(new SelectClauseElementWildcard());
            defaultSelectAllSpec.Raw.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH;
            StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                new EventType[] {eventType},
                new[] {"trigger_stream"},
                new[] {true},
                false,
                false);
            var resultSetProcessor = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                new ResultSetSpec(defaultSelectAllSpec),
                streamTypeService,
                null,
                new bool[1],
                false,
                @base.ContextPropertyRegistry,
                false,
                false,
                @base.StatementRawInfo,
                services);
            var classNameRSP = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(ResultSetProcessorFactoryProvider),
                classPostfix);

            var forge = new StatementAgentInstanceFactoryOnTriggerSetForge(
                activatorResult.Activator,
                eventType,
                subselectForges,
                tableAccessForges,
                variableReadWritePackageForge,
                classNameRSP);
            IList<StmtClassForgable> forgables = new List<StmtClassForgable>();
            forgables.Add(
                new StmtClassForgableRSPFactoryProvider(
                    classNameRSP,
                    resultSetProcessor,
                    namespaceScope,
                    @base.StatementRawInfo));

            var onTrigger = new StmtClassForgableAIFactoryProviderOnTrigger(className, namespaceScope, forge);
            return new OnTriggerSetPlan(onTrigger, forgables, resultSetProcessor.SelectSubscriberDescriptor);
        }