public static void WalkStreamSpecs(
            StatementSpecRaw spec,
            ExprNodeSubselectDeclaredDotVisitor visitor)
        {
            // determine pattern-filter subqueries
            foreach (StreamSpecRaw streamSpecRaw in spec.StreamSpecs) {
                if (streamSpecRaw is PatternStreamSpecRaw) {
                    PatternStreamSpecRaw patternStreamSpecRaw = (PatternStreamSpecRaw) streamSpecRaw;
                    EvalNodeAnalysisResult analysisResult =
                        EvalNodeUtil.RecursiveAnalyzeChildNodes(patternStreamSpecRaw.EvalForgeNode);
                    foreach (EvalForgeNode evalNode in analysisResult.ActiveNodes) {
                        if (evalNode is EvalFilterForgeNode) {
                            EvalFilterForgeNode filterNode = (EvalFilterForgeNode) evalNode;
                            foreach (ExprNode filterExpr in filterNode.RawFilterSpec.FilterExpressions) {
                                filterExpr.Accept(visitor);
                            }
                        }
                        else if (evalNode is EvalObserverForgeNode) {
                            int beforeCount = visitor.Subselects.Count;
                            EvalObserverForgeNode observerNode = (EvalObserverForgeNode) evalNode;
                            foreach (ExprNode param in observerNode.PatternObserverSpec.ObjectParameters) {
                                param.Accept(visitor);
                            }

                            if (visitor.Subselects.Count != beforeCount) {
                                throw new ExprValidationException(
                                    "Subselects are not allowed within pattern observer parameters, please consider using a variable instead");
                            }
                        }
                    }
                }
            }

            // determine filter streams
            foreach (StreamSpecRaw rawSpec in spec.StreamSpecs) {
                if (rawSpec is FilterStreamSpecRaw) {
                    FilterStreamSpecRaw raw = (FilterStreamSpecRaw) rawSpec;
                    foreach (ExprNode filterExpr in raw.RawFilterSpec.FilterExpressions) {
                        filterExpr.Accept(visitor);
                    }
                }
            }
        }
Пример #2
0
        private ContextDetailMatchPair ValidateRewriteContextCondition(
            bool isStartCondition,
            int nestingLevel,
            ContextSpecCondition endpoint,
            ISet<string> eventTypesReferenced,
            MatchEventSpec priorMatches,
            ISet<string> priorAllTags,
            CreateContextValidationEnv validationEnv)
        {
            if (endpoint is ContextSpecConditionCrontab) {
                var crontab = (ContextSpecConditionCrontab) endpoint;
                var forgesPerCrontab = new ExprForge[crontab.Crontabs.Count][];
                for (int i = 0; i < crontab.Crontabs.Count; i++) {
                    var item = crontab.Crontabs[i];
                    var forges = ScheduleExpressionUtil.CrontabScheduleValidate(
                        ExprNodeOrigin.CONTEXTCONDITION,
                        item,
                        false,
                        validationEnv.StatementRawInfo,
                        validationEnv.Services);
                    forgesPerCrontab[i] = forges;
                }
                crontab.ForgesPerCrontab = forgesPerCrontab;
                validationEnv.ScheduleHandleCallbackProviders.Add(crontab);
                return new ContextDetailMatchPair(
                    crontab,
                    new MatchEventSpec(),
                    new LinkedHashSet<string>(),
                    EmptyList<StmtClassForgeableFactory>.Instance);
            }

            if (endpoint is ContextSpecConditionTimePeriod) {
                var timePeriod = (ContextSpecConditionTimePeriod) endpoint;
                var validationContext = new ExprValidationContextBuilder(
                    new StreamTypeServiceImpl(false),
                    validationEnv.StatementRawInfo,
                    validationEnv.Services).Build();
                ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.CONTEXTCONDITION,
                    timePeriod.TimePeriod,
                    validationContext);
                if (timePeriod.TimePeriod.IsConstantResult) {
                    if (timePeriod.TimePeriod.EvaluateAsSeconds(null, true, null) < 0) {
                        throw new ExprValidationException(
                            "Invalid negative time period expression '" +
                            ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(timePeriod.TimePeriod) +
                            "'");
                    }
                }

                validationEnv.ScheduleHandleCallbackProviders.Add(timePeriod);
                return new ContextDetailMatchPair(
                    timePeriod,
                    new MatchEventSpec(),
                    new LinkedHashSet<string>(),
                    EmptyList<StmtClassForgeableFactory>.Instance);
            }

            if (endpoint is ContextSpecConditionPattern) {
                var pattern = (ContextSpecConditionPattern) endpoint;
                var matches = ValidatePatternContextConditionPattern(
                    isStartCondition,
                    nestingLevel,
                    pattern,
                    eventTypesReferenced,
                    priorMatches,
                    priorAllTags,
                    validationEnv);

                var validatedDesc = ValidatePatternContextConditionPattern(
                    isStartCondition,
                    nestingLevel,
                    pattern,
                    eventTypesReferenced,
                    priorMatches,
                    priorAllTags,
                    validationEnv);
                return new ContextDetailMatchPair(
                    pattern,
                    validatedDesc.MatchEventSpec,
                    validatedDesc.AllTags,
                    validatedDesc.AdditionalForgeables);
            }

            if (endpoint is ContextSpecConditionFilter) {
                var filter = (ContextSpecConditionFilter) endpoint;
                ValidateNotTable(filter.FilterSpecRaw.EventTypeName, validationEnv.Services);

                // compile as filter if there are no prior match to consider
                if (priorMatches == null ||
                    priorMatches.ArrayEventTypes.IsEmpty() && priorMatches.TaggedEventTypes.IsEmpty()) {
                    var rawExpr = new FilterStreamSpecRaw(
                        filter.FilterSpecRaw,
                        ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                        null,
                        StreamSpecOptions.DEFAULT);
                    var compiledDesc = StreamSpecCompiler.Compile(
                        rawExpr,
                        eventTypesReferenced,
                        false,
                        false,
                        true,
                        false,
                        filter.OptionalFilterAsName,
                        0,
                        validationEnv.StatementRawInfo,
                        validationEnv.Services);
                    var compiled = (FilterStreamSpecCompiled) compiledDesc.StreamSpecCompiled;

                    filter.FilterSpecCompiled = compiled.FilterSpecCompiled;
                    var matchEventSpec = new MatchEventSpec();
                    var filterForType = compiled.FilterSpecCompiled.FilterForEventType;
                    var allTags = new LinkedHashSet<string>();
                    if (filter.OptionalFilterAsName != null) {
                        matchEventSpec.TaggedEventTypes.Put(
                            filter.OptionalFilterAsName,
                            new Pair<EventType, string>(filterForType, rawExpr.RawFilterSpec.EventTypeName));
                        allTags.Add(filter.OptionalFilterAsName);
                    }

                    validationEnv.FilterSpecCompileds.Add(compiled.FilterSpecCompiled);
                    var serdeForgeables = SerdeEventTypeUtility.Plan(
                        filter.FilterSpecCompiled.FilterForEventType,
                        validationEnv.StatementRawInfo,
                        validationEnv.Services.SerdeEventTypeRegistry,
                        validationEnv.Services.SerdeResolver);
                    var allForgeables = compiledDesc.AdditionalForgeables
                        .Concat(serdeForgeables)
                        .ToList();
                    return new ContextDetailMatchPair(filter, matchEventSpec, allTags, allForgeables);
                }

                // compile as pattern if there are prior matches to consider, since this is a type of followed-by relationship
                EvalForgeNode forgeNode = new EvalFilterForgeNode(validationEnv.Services.IsAttachPatternText, filter.FilterSpecRaw, filter.OptionalFilterAsName, 0);
                var pattern = new ContextSpecConditionPattern(forgeNode, true, false);
                var validated = ValidatePatternContextConditionPattern(
                    isStartCondition,
                    nestingLevel,
                    pattern,
                    eventTypesReferenced,
                    priorMatches,
                    priorAllTags,
                    validationEnv);
                return new ContextDetailMatchPair(pattern, validated.MatchEventSpec, validated.AllTags, validated.AdditionalForgeables);
            }

            if (endpoint is ContextSpecConditionImmediate || endpoint is ContextSpecConditionNever) {
                return new ContextDetailMatchPair(
                    endpoint,
                    new MatchEventSpec(),
                    new LinkedHashSet<String>(),
                    EmptyList<StmtClassForgeableFactory>.Instance);
            }

            throw new IllegalStateException("Unrecognized endpoint type " + endpoint);
        }