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));
        }
Пример #2
0
 public OnTriggerWindowPlan(
     OnTriggerWindowDesc onTriggerDesc,
     string contextName,
     OnTriggerActivatorDesc activatorResult,
     StreamSelector? optionalStreamSelector,
     IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation,
     StreamSpecCompiled streamSpec)
 {
     OnTriggerDesc = onTriggerDesc;
     ContextName = contextName;
     ActivatorResult = activatorResult;
     OptionalStreamSelector = optionalStreamSelector;
     SubselectActivation = subselectActivation;
     StreamSpec = streamSpec;
 }
Пример #3
0
 public static TableOnViewFactory Make(TableMetadata tableMetadata,
                                       OnTriggerDesc onTriggerDesc,
                                       EventType filterEventType,
                                       string filterStreamName,
                                       StatementContext statementContext,
                                       StatementMetricHandle metricsHandle,
                                       bool isDistinct,
                                       InternalEventRouter internalEventRouter
                                       )
 {
     if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_DELETE)
     {
         return(new TableOnDeleteViewFactory(statementContext.StatementResultService, tableMetadata));
     }
     else if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_SELECT)
     {
         EventBeanReader eventBeanReader = null;
         if (isDistinct)
         {
             eventBeanReader = tableMetadata.InternalEventType.Reader;
         }
         OnTriggerWindowDesc windowDesc = (OnTriggerWindowDesc)onTriggerDesc;
         return(new TableOnSelectViewFactory(tableMetadata, internalEventRouter, statementContext.EpStatementHandle,
                                             eventBeanReader, isDistinct, statementContext.StatementResultService, statementContext.InternalEventEngineRouteDest, windowDesc.IsDeleteAndSelect));
     }
     else if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_UPDATE)
     {
         OnTriggerWindowUpdateDesc updateDesc     = (OnTriggerWindowUpdateDesc)onTriggerDesc;
         EventBeanUpdateHelper     updateHelper   = EventBeanUpdateHelperFactory.Make(tableMetadata.TableName, (EventTypeSPI)tableMetadata.InternalEventType, updateDesc.Assignments, updateDesc.OptionalAsName, filterEventType, false, statementContext.StatementName, statementContext.EngineURI, statementContext.EventAdapterService);
         TableUpdateStrategy       updateStrategy = statementContext.TableService.GetTableUpdateStrategy(tableMetadata, updateHelper, false);
         var onUpdateViewFactory = new TableOnUpdateViewFactory(statementContext.StatementResultService, tableMetadata, updateHelper, updateStrategy);
         statementContext.TableService.AddTableUpdateStrategyReceiver(tableMetadata, statementContext.StatementName, onUpdateViewFactory, updateHelper, false);
         return(onUpdateViewFactory);
     }
     else if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_MERGE)
     {
         OnTriggerMergeDesc onMergeTriggerDesc = (OnTriggerMergeDesc)onTriggerDesc;
         var onMergeHelper = new TableOnMergeHelper(statementContext, onMergeTriggerDesc, filterEventType, filterStreamName, internalEventRouter, tableMetadata);
         return(new TableOnMergeViewFactory(tableMetadata, onMergeHelper, statementContext.StatementResultService, metricsHandle, statementContext.MetricReportingService));
     }
     else
     {
         throw new IllegalStateException("Unknown trigger type " + onTriggerDesc.OnTriggerType);
     }
 }
Пример #4
0
        public static OnTriggerPlanValidationResult ValidateOnTriggerPlan(
            EventType namedWindowOrTableType,
            OnTriggerWindowDesc onTriggerDesc,
            StreamSpecCompiled streamSpec,
            OnTriggerActivatorDesc activatorResult,
            IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            var zeroStreamAliasName = onTriggerDesc.OptionalAsName;
            if (zeroStreamAliasName == null) {
                zeroStreamAliasName = "stream_0";
            }

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

            var namedWindowTypeName = onTriggerDesc.WindowName;

            // Materialize sub-select views
            // 0 - named window stream
            // 1 - arriving stream
            // 2 - initial value before update
            string[] subselectStreamNames = {zeroStreamAliasName, streamSpec.OptionalStreamName};
            EventType[] subselectEventTypes = {namedWindowOrTableType, activatorResult.ActivatorResultEventType};
            string[] subselectEventTypeNames = {namedWindowTypeName, activatorResult.TriggerEventTypeName};
            var subselectForges = SubSelectHelperForgePlanner.PlanSubSelect(
                @base,
                subselectActivation,
                subselectStreamNames,
                subselectEventTypes,
                subselectEventTypeNames,
                services);

            var typeService = new StreamTypeServiceImpl(
                new[] {namedWindowOrTableType, activatorResult.ActivatorResultEventType},
                new[] {zeroStreamAliasName, streamName},
                new[] {false, true},
                true,
                false);

            // allow "initial" as a prefix to properties
            StreamTypeServiceImpl assignmentTypeService;
            if (zeroStreamAliasName.Equals(INITIAL_VALUE_STREAM_NAME) || streamName.Equals(INITIAL_VALUE_STREAM_NAME)) {
                assignmentTypeService = typeService;
            }
            else {
                assignmentTypeService = new StreamTypeServiceImpl(
                    new[] {namedWindowOrTableType, activatorResult.ActivatorResultEventType, namedWindowOrTableType},
                    new[] {zeroStreamAliasName, streamName, INITIAL_VALUE_STREAM_NAME},
                    new[] {false, true, true},
                    false,
                    false);
                assignmentTypeService.IsStreamZeroUnambigous = true;
            }

            if (onTriggerDesc is OnTriggerWindowUpdateDesc) {
                var updateDesc = (OnTriggerWindowUpdateDesc) onTriggerDesc;
                var validationContext = new ExprValidationContextBuilder(
                        assignmentTypeService,
                        @base.StatementRawInfo,
                        services)
                    .WithAllowBindingConsumption(true)
                    .Build();
                foreach (var assignment in updateDesc.Assignments) {
                    var validated = ExprNodeUtilityValidate.GetValidatedAssignment(assignment, validationContext);
                    assignment.Expression = validated;
                    EPStatementStartMethodHelperValidate.ValidateNoAggregations(
                        validated,
                        "Aggregation functions may not be used within an on-update-clause");
                }
            }

            if (onTriggerDesc is OnTriggerMergeDesc) {
                var mergeDesc = (OnTriggerMergeDesc) onTriggerDesc;
                ValidateMergeDesc(
                    mergeDesc,
                    namedWindowOrTableType,
                    zeroStreamAliasName,
                    activatorResult.ActivatorResultEventType,
                    streamName,
                    @base.StatementRawInfo,
                    services);
            }

            // validate join expression
            var validatedJoin = ValidateJoinNamedWindow(
                ExprNodeOrigin.WHERE,
                @base.StatementSpec.Raw.WhereClause,
                namedWindowOrTableType,
                zeroStreamAliasName,
                namedWindowTypeName,
                activatorResult.ActivatorResultEventType,
                streamName,
                activatorResult.TriggerEventTypeName,
                null,
                @base.StatementRawInfo,
                services);

            // validate filter, output rate limiting
            EPStatementStartMethodHelperValidate.ValidateNodes(
                @base.StatementSpec.Raw,
                typeService,
                null,
                @base.StatementRawInfo,
                services);

            // Construct a processor for results; for use in on-select to process selection results
            // Use a wildcard select if the select-clause is empty, such as for on-delete.
            // For on-select the select clause is not empty.
            if (@base.StatementSpec.SelectClauseCompiled.SelectExprList.Length == 0) {
                @base.StatementSpec.SelectClauseCompiled.WithSelectExprList(new SelectClauseElementWildcard());
            }

            var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                new ResultSetSpec(@base.StatementSpec),
                typeService,
                null,
                new bool[0],
                true,
                @base.ContextPropertyRegistry,
                false,
                true,
                @base.StatementRawInfo,
                services);

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

            return new OnTriggerPlanValidationResult(
                subselectForges,
                tableAccessForges,
                resultSetProcessorPrototype,
                validatedJoin,
                zeroStreamAliasName);
        }
Пример #5
0
        public static bool IsWritesToTables(StatementSpecRaw statementSpec, TableService tableService)
        {
            // determine if writing to a table:

            // insert-into (single)
            if (statementSpec.InsertIntoDesc != null)
            {
                if (IsTable(statementSpec.InsertIntoDesc.EventTypeName, tableService))
                {
                    return(true);
                }
            }

            // into-table
            if (statementSpec.IntoTableSpec != null)
            {
                return(true);
            }

            // triggers
            if (statementSpec.OnTriggerDesc != null)
            {
                OnTriggerDesc onTriggerDesc = statementSpec.OnTriggerDesc;

                // split-stream insert-into
                if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_SPLITSTREAM)
                {
                    OnTriggerSplitStreamDesc split = (OnTriggerSplitStreamDesc)onTriggerDesc;
                    foreach (OnTriggerSplitStream stream in split.SplitStreams)
                    {
                        if (IsTable(stream.InsertInto.EventTypeName, tableService))
                        {
                            return(true);
                        }
                    }
                }

                // on-delete/update/merge/on-selectdelete
                if (onTriggerDesc is OnTriggerWindowDesc)
                {
                    OnTriggerWindowDesc window = (OnTriggerWindowDesc)onTriggerDesc;
                    if (onTriggerDesc.OnTriggerType == OnTriggerType.ON_DELETE ||
                        onTriggerDesc.OnTriggerType == OnTriggerType.ON_UPDATE ||
                        onTriggerDesc.OnTriggerType == OnTriggerType.ON_MERGE ||
                        window.IsDeleteAndSelect)
                    {
                        if (IsTable(window.WindowName, tableService))
                        {
                            return(true);
                        }
                    }
                }

                // on-merge with insert-action
                if (onTriggerDesc is OnTriggerMergeDesc)
                {
                    OnTriggerMergeDesc merge = (OnTriggerMergeDesc)onTriggerDesc;
                    foreach (OnTriggerMergeMatched item in merge.Items)
                    {
                        foreach (OnTriggerMergeAction action in item.Actions)
                        {
                            if (action is OnTriggerMergeActionInsert)
                            {
                                OnTriggerMergeActionInsert insert = (OnTriggerMergeActionInsert)action;
                                if (insert.OptionalStreamName != null && IsTable(insert.OptionalStreamName, tableService))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            } // end of trigger handling

            // fire-and-forget insert/update/delete
            if (statementSpec.FireAndForgetSpec != null)
            {
                FireAndForgetSpec faf = statementSpec.FireAndForgetSpec;
                if (faf is FireAndForgetSpecDelete ||
                    faf is FireAndForgetSpecInsert ||
                    faf is FireAndForgetSpecUpdate)
                {
                    if (statementSpec.StreamSpecs.Count == 1)
                    {
                        return(IsTable(((FilterStreamSpecRaw)statementSpec.StreamSpecs[0]).RawFilterSpec.EventTypeName, tableService));
                    }
                }
            }

            return(false);
        }