Пример #1
0
        private Pair<FilterSpecCompiled, IList<StmtClassForgeableFactory>> CompilePartitionedFilterSpec(
            FilterSpecRaw filterSpecRaw,
            ISet<string> eventTypesReferenced,
            CreateContextValidationEnv validationEnv)
        {
            ValidateNotTable(filterSpecRaw.EventTypeName, validationEnv.Services);
            var raw = new FilterStreamSpecRaw(
                filterSpecRaw,
                ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                null,
                StreamSpecOptions.DEFAULT);
            var compiledDesc = StreamSpecCompiler.Compile(
                raw,
                eventTypesReferenced,
                false,
                false,
                true,
                false,
                null,
                0,
                validationEnv.StatementRawInfo,
                validationEnv.Services);
            if (!(compiledDesc.StreamSpecCompiled is FilterStreamSpecCompiled filters)) {
                throw new ExprValidationException("Partition criteria may not include named windows");
            }

            var spec = filters.FilterSpecCompiled;
            validationEnv.FilterSpecCompileds.Add(spec);
            return new Pair<FilterSpecCompiled, IList<StmtClassForgeableFactory>>(
                spec,
                compiledDesc.AdditionalForgeables);
        }
Пример #2
0
 public EvalFactoryNode MakeFilterNode(
     FilterSpecRaw filterSpecification,
     String eventAsName,
     int?consumptionLevel)
 {
     return(new EvalFilterFactoryNode(filterSpecification, eventAsName, consumptionLevel));
 }
Пример #3
0
        private FilterSpecCompiled CompilePartitonedFilterSpec(
            FilterSpecRaw filterSpecRaw,
            ISet<string> eventTypesReferenced,
            CreateContextValidationEnv validationEnv)
        {
            ValidateNotTable(filterSpecRaw.EventTypeName, validationEnv.Services);
            var raw = new FilterStreamSpecRaw(
                filterSpecRaw,
                ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                null,
                StreamSpecOptions.DEFAULT);
            var compiled = StreamSpecCompiler.Compile(
                raw,
                eventTypesReferenced,
                false,
                false,
                true,
                false,
                null,
                0,
                validationEnv.StatementRawInfo,
                validationEnv.Services);
            if (!(compiled is FilterStreamSpecCompiled)) {
                throw new ExprValidationException("Partition criteria may not include named windows");
            }

            var filters = (FilterStreamSpecCompiled) compiled;
            var spec = filters.FilterSpecCompiled;
            validationEnv.FilterSpecCompileds.Add(spec);
            return spec;
        }
Пример #4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="filterSpecification">specifies the filter properties</param>
 /// <param name="eventAsName">is the name to use for adding matching events to the MatchedEventMaptable used when indicating truth value of true.</param>
 /// <param name="consumptionLevel">The consumption level.</param>
 public EvalFilterFactoryNode(FilterSpecRaw filterSpecification,
                              String eventAsName,
                              int?consumptionLevel)
 {
     _rawFilterSpec    = filterSpecification;
     _eventAsName      = eventAsName;
     _consumptionLevel = consumptionLevel;
 }
Пример #5
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="filterSpecification">specifies the filter properties</param>
 /// <param name="eventAsName">
 /// is the name to use for adding matching events to the MatchedEventMap
 /// table used when indicating truth value of true.
 /// </param>
 /// <param name="consumptionLevel">when using @consume</param>
 public EvalFilterFactoryNode(FilterSpecRaw filterSpecification,
                              string eventAsName,
                              int?consumptionLevel)
 {
     EventAsTagNumber = -1;
     RawFilterSpec    = filterSpecification;
     EventAsName      = eventAsName;
     ConsumptionLevel = consumptionLevel;
 }
Пример #6
0
 /// <summary>
 ///     Constructor.
 /// </summary>
 /// <param name="attachPatternText">whether to attach EPL subexpression text</param>
 /// <param name="filterSpecification">specifies the filter properties</param>
 /// <param name="eventAsName">
 ///     is the name to use for adding matching events to the MatchedEventMaptable used when indicating truth value of true.
 /// </param>
 /// <param name="consumptionLevel">when using @consume</param>
 public EvalFilterForgeNode(
     bool attachPatternText,
     FilterSpecRaw filterSpecification,
     string eventAsName,
     int? consumptionLevel)
     : base(attachPatternText)
 {
     RawFilterSpec = filterSpecification;
     EventAsName = eventAsName;
     ConsumptionLevel = consumptionLevel;
 }
        private static void RewriteNamedWindowSubselect(
            IList<ExprDotNode> chainedExpressionsDot,
            IList<ExprSubselectNode> subselects,
            NamedWindowCompileTimeResolver service)
        {
            foreach (var dotNode in chainedExpressionsDot) {
                if (dotNode.ChainSpec.IsEmpty()) {
                    continue;
                }
                
                var proposedWindow = dotNode.ChainSpec[0].GetRootNameOrEmptyString();
                var namedWindowDetail = service.Resolve(proposedWindow);
                if (namedWindowDetail == null) {
                    continue;
                }

                // build spec for subselect
                var raw = new StatementSpecRaw(SelectClauseStreamSelectorEnum.ISTREAM_ONLY);
                var filter = new FilterSpecRaw(proposedWindow, Collections.GetEmptyList<ExprNode>(), null);
                raw.StreamSpecs.Add(
                    new FilterStreamSpecRaw(
                        filter,
                        ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                        proposedWindow,
                        StreamSpecOptions.DEFAULT));

                
                var modified = new List<Chainable>(dotNode.ChainSpec);
                var firstChain = modified.DeleteAt(0);
                var firstChainParams = firstChain.GetParametersOrEmpty();
                if (!firstChainParams.IsEmpty()) {
                    if (firstChainParams.Count == 1) {
                        raw.WhereClause = firstChainParams[0];
                    } else {
                        ExprAndNode andNode = new ExprAndNodeImpl();
                        foreach (ExprNode node in firstChainParams) {
                            andNode.AddChildNode(node);
                        }
                        raw.WhereClause = andNode;
                    }
                }

                // activate subselect
                ExprSubselectNode subselect = new ExprSubselectRowNode(raw);
                subselects.Add(subselect);
                dotNode.ChildNodes = new ExprNode[] {subselect};
                dotNode.ChainSpec = modified;
            }
        }
Пример #8
0
        private static ContextSpec WalkNested(
            IList<EsperEPL2GrammarParser.ContextContextNestedContext> nestedContexts,
            IDictionary<ITree, ExprNode> astExprNodeMap,
            IDictionary<ITree, EvalForgeNode> astPatternNodeMap,
            PropertyEvalSpec propertyEvalSpec,
            FilterSpecRaw filterSpec)
        {
            IList<CreateContextDesc> contexts = new List<CreateContextDesc>(nestedContexts.Count);
            foreach (var nestedctx in nestedContexts)
            {
                var contextDetail = WalkChoice(nestedctx.createContextChoice(), astExprNodeMap, astPatternNodeMap, propertyEvalSpec);
                var desc = new CreateContextDesc(nestedctx.name.Text, contextDetail);
                contexts.Add(desc);
            }

            return new ContextNested(contexts);
        }
Пример #9
0
        private static ContextDetailCondition GetContextCondition(EsperEPL2GrammarParser.CreateContextRangePointContext ctx, IDictionary <ITree, ExprNode> astExprNodeMap, IDictionary <ITree, EvalFactoryNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, bool immediate)
        {
            if (ctx.crontabLimitParameterSet() != null)
            {
                IList <ExprNode> crontab = ASTExprHelper.ExprCollectSubNodes(ctx.crontabLimitParameterSet(), 0, astExprNodeMap);
                return(new ContextDetailConditionCrontab(crontab, immediate));
            }
            else if (ctx.patternInclusionExpression() != null)
            {
                EvalFactoryNode evalNode  = ASTExprHelper.PatternGetRemoveTopNode(ctx.patternInclusionExpression(), astPatternNodeMap);
                bool            inclusive = false;
                if (ctx.i != null)
                {
                    String ident = ctx.i.Text;
                    if (ident != null && ident.ToLower() != "inclusive")
                    {
                        throw ASTWalkException.From("Expected 'inclusive' keyword after '@', found '" + ident + "' instead");
                    }
                    inclusive = true;
                }
                return(new ContextDetailConditionPattern(evalNode, inclusive, immediate));
            }
            else if (ctx.createContextFilter() != null)
            {
                FilterSpecRaw filterSpecRaw = ASTFilterSpecHelper.WalkFilterSpec(ctx.createContextFilter().eventFilterExpression(), propertyEvalSpec, astExprNodeMap);
                String        asName        = ctx.createContextFilter().i != null?ctx.createContextFilter().i.Text : null;

                if (immediate)
                {
                    throw ASTWalkException.From("Invalid use of 'now' with initiated-by stream, this combination is not supported");
                }
                return(new ContextDetailConditionFilter(filterSpecRaw, asName));
            }
            else if (ctx.AFTER() != null)
            {
                ExprTimePeriod timePeriod = (ExprTimePeriod)ASTExprHelper.ExprCollectSubNodes(ctx.timePeriod(), 0, astExprNodeMap)[0];
                return(new ContextDetailConditionTimePeriod(timePeriod, immediate));
            }
            else
            {
                throw new IllegalStateException("Unrecognized child type");
            }
        }
Пример #10
0
        public static CreateContextDesc WalkCreateContext(
            EsperEPL2GrammarParser.CreateContextExprContext ctx,
            IDictionary<ITree, ExprNode> astExprNodeMap,
            IDictionary<ITree, EvalForgeNode> astPatternNodeMap,
            PropertyEvalSpec propertyEvalSpec,
            FilterSpecRaw filterSpec)
        {
            var contextName = ctx.name.Text;
            ContextSpec contextDetail;

            var choice = ctx.createContextDetail().createContextChoice();
            if (choice != null)
            {
                contextDetail = WalkChoice(choice, astExprNodeMap, astPatternNodeMap, propertyEvalSpec);
            }
            else
            {
                contextDetail = WalkNested(
                    ctx.createContextDetail().contextContextNested(), astExprNodeMap, astPatternNodeMap, propertyEvalSpec, filterSpec);
            }

            return new CreateContextDesc(contextName, contextDetail);
        }
Пример #11
0
        private void ValidateContextDetail(
            EPServicesContext servicesContext,
            StatementContext statementContext,
            ISet <string> eventTypesReferenced,
            ContextDetail contextDetail,
            AgentInstanceContext agentInstanceContext)
        {
            if (contextDetail is ContextDetailPartitioned)
            {
                var segmented = (ContextDetailPartitioned)contextDetail;
                foreach (var partition in segmented.Items)
                {
                    ValidateNotTable(servicesContext, partition.FilterSpecRaw.EventTypeName);
                    var raw      = new FilterStreamSpecRaw(partition.FilterSpecRaw, ViewSpec.EMPTY_VIEWSPEC_ARRAY, null, new StreamSpecOptions());
                    var compiled = raw.Compile(statementContext, eventTypesReferenced, false, Collections.GetEmptyList <int>(), false, true, false, null);
                    if (!(compiled is FilterStreamSpecCompiled))
                    {
                        throw new ExprValidationException("Partition criteria may not include named windows");
                    }
                    var result = (FilterStreamSpecCompiled)compiled;
                    partition.FilterSpecCompiled = result.FilterSpec;
                }
            }
            else if (contextDetail is ContextDetailCategory)
            {
                // compile filter
                var category = (ContextDetailCategory)contextDetail;
                ValidateNotTable(servicesContext, category.FilterSpecRaw.EventTypeName);
                var raw    = new FilterStreamSpecRaw(category.FilterSpecRaw, ViewSpec.EMPTY_VIEWSPEC_ARRAY, null, new StreamSpecOptions());
                var result = (FilterStreamSpecCompiled)raw.Compile(statementContext, eventTypesReferenced, false, Collections.GetEmptyList <int>(), false, true, false, null);
                category.FilterSpecCompiled = result.FilterSpec;
                servicesContext.StatementEventTypeRefService.AddReferences(statementContext.StatementName, CollectionUtil.ToArray(eventTypesReferenced));

                // compile expressions
                foreach (var item in category.Items)
                {
                    ValidateNotTable(servicesContext, category.FilterSpecRaw.EventTypeName);
                    var filterSpecRaw = new FilterSpecRaw(category.FilterSpecRaw.EventTypeName, Collections.SingletonList(item.Expression), null);
                    var rawExpr       = new FilterStreamSpecRaw(filterSpecRaw, ViewSpec.EMPTY_VIEWSPEC_ARRAY, null, new StreamSpecOptions());
                    var compiled      = (FilterStreamSpecCompiled)rawExpr.Compile(statementContext, eventTypesReferenced, false, Collections.GetEmptyList <int>(), false, true, false, null);
                    item.SetCompiledFilter(compiled.FilterSpec, agentInstanceContext);
                }
            }
            else if (contextDetail is ContextDetailHash)
            {
                var hashed = (ContextDetailHash)contextDetail;
                foreach (var hashItem in hashed.Items)
                {
                    var raw = new FilterStreamSpecRaw(hashItem.FilterSpecRaw, ViewSpec.EMPTY_VIEWSPEC_ARRAY, null, new StreamSpecOptions());
                    ValidateNotTable(servicesContext, hashItem.FilterSpecRaw.EventTypeName);
                    var result = (FilterStreamSpecCompiled)raw.Compile(statementContext, eventTypesReferenced, false, Collections.GetEmptyList <int>(), false, true, false, null);
                    hashItem.FilterSpecCompiled = result.FilterSpec;

                    // validate parameters
                    var streamTypes       = new StreamTypeServiceImpl(result.FilterSpec.FilterForEventType, null, true, statementContext.EngineURI);
                    var validationContext = new ExprValidationContext(
                        streamTypes,
                        statementContext.EngineImportService,
                        statementContext.StatementExtensionServicesContext, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService, statementContext.TableService,
                        GetDefaultAgentInstanceContext(statementContext), statementContext.EventAdapterService,
                        statementContext.StatementName, statementContext.StatementId, statementContext.Annotations,
                        statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false,
                        null, false);
                    ExprNodeUtility.Validate(ExprNodeOrigin.CONTEXT, Collections.SingletonList(hashItem.Function), validationContext);
                }
            }
            else if (contextDetail is ContextDetailInitiatedTerminated)
            {
                var def            = (ContextDetailInitiatedTerminated)contextDetail;
                var startCondition = ValidateRewriteContextCondition(servicesContext, statementContext, def.Start, eventTypesReferenced, new MatchEventSpec(), new LinkedHashSet <string>());
                var endCondition   = ValidateRewriteContextCondition(servicesContext, statementContext, def.End, eventTypesReferenced, startCondition.Matches, startCondition.AllTags);
                def.Start = startCondition.Condition;
                def.End   = endCondition.Condition;

                if (def.DistinctExpressions != null)
                {
                    if (!(startCondition.Condition is ContextDetailConditionFilter))
                    {
                        throw new ExprValidationException("Distinct-expressions require a stream as the initiated-by condition");
                    }
                    var distinctExpressions = def.DistinctExpressions;
                    if (distinctExpressions.Length == 0)
                    {
                        throw new ExprValidationException("Distinct-expressions have not been provided");
                    }
                    var filter = (ContextDetailConditionFilter)startCondition.Condition;
                    if (filter.OptionalFilterAsName == null)
                    {
                        throw new ExprValidationException("Distinct-expressions require that a stream name is assigned to the stream using 'as'");
                    }
                    var types             = new StreamTypeServiceImpl(filter.FilterSpecCompiled.FilterForEventType, filter.OptionalFilterAsName, true, servicesContext.EngineURI);
                    var validationContext = new ExprValidationContext(
                        types,
                        statementContext.EngineImportService,
                        statementContext.StatementExtensionServicesContext, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService, statementContext.TableService,
                        GetDefaultAgentInstanceContext(statementContext), statementContext.EventAdapterService,
                        statementContext.StatementName, statementContext.StatementId, statementContext.Annotations,
                        statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false,
                        null, false);
                    for (var i = 0; i < distinctExpressions.Length; i++)
                    {
                        ExprNodeUtility.ValidatePlainExpression(ExprNodeOrigin.CONTEXTDISTINCT, ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(distinctExpressions[i]), distinctExpressions[i]);
                        distinctExpressions[i] = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.CONTEXTDISTINCT, distinctExpressions[i], validationContext);
                    }
                }
            }
            else if (contextDetail is ContextDetailNested)
            {
                var nested = (ContextDetailNested)contextDetail;
                foreach (var nestedContext in nested.Contexts)
                {
                    ValidateContextDetail(servicesContext, statementContext, eventTypesReferenced, nestedContext.ContextDetail, agentInstanceContext);
                }
            }
            else
            {
                throw new IllegalStateException("Unrecognized context detail " + contextDetail);
            }
        }
Пример #12
0
        private IList<StmtClassForgeableFactory> ValidateContextDetail(
            ContextSpec contextSpec,
            int nestingLevel,
            CreateContextValidationEnv validationEnv)
        {
            ISet<string> eventTypesReferenced = new HashSet<string>();
            IList<StmtClassForgeableFactory> additionalForgeables = new List<StmtClassForgeableFactory>();
            
            if (contextSpec is ContextSpecKeyed) {
                var segmented = (ContextSpecKeyed) contextSpec;
                IDictionary<string, EventType> asNames = new Dictionary<string, EventType>();
                var partitionHasNameAssignment = false;
                Type[] getterTypes = null;
                foreach (var partition in segmented.Items) {
                    Pair<FilterSpecCompiled, IList<StmtClassForgeableFactory>> pair = CompilePartitionedFilterSpec(
                        partition.FilterSpecRaw, eventTypesReferenced, validationEnv);
                    FilterSpecCompiled filterSpecCompiled = pair.First;
                    additionalForgeables.AddAll(pair.Second);
                   
                    partition.FilterSpecCompiled = filterSpecCompiled;

                    var getters = new EventPropertyGetterSPI[partition.PropertyNames.Count];
                    var serdes = new DataInputOutputSerdeForge[partition.PropertyNames.Count];
                    var eventType = (EventTypeSPI) filterSpecCompiled.FilterForEventType;
                    getterTypes = new Type[partition.PropertyNames.Count];
                    
                    for (var i = 0; i < partition.PropertyNames.Count; i++) {
                        var propertyName = partition.PropertyNames[i];
                        var getter = eventType.GetGetterSPI(propertyName);
                        if (getter == null) {
                            throw new ExprValidationException(
                                "For context '" + validationEnv.ContextName + "' property name '" + propertyName + "' not found on type " + eventType.Name);
                        }
                        getters[i] = getter;
                        getterTypes[i] = eventType.GetPropertyType(propertyName);
                        serdes[i] = validationEnv.Services.SerdeResolver.SerdeForFilter(
                            getterTypes[i], validationEnv.StatementRawInfo);
                    }

                    partition.Getters = getters;
                    partition.LookupableSerdes = serdes;

                    if (partition.AliasName != null) {
                        partitionHasNameAssignment = true;
                        ValidateAsName(asNames, partition.AliasName, filterSpecCompiled.FilterForEventType);
                    }
                }

                // plan multi-key, make sure we use the same multikey for all items
                MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKey(
                    getterTypes, false, @base.StatementRawInfo, validationEnv.Services.SerdeResolver);
                additionalForgeables.AddAll(multiKeyPlan.MultiKeyForgeables);
                foreach (ContextSpecKeyedItem partition in segmented.Items) {
                    partition.KeyMultiKey = multiKeyPlan.ClassRef;
                }
                segmented.MultiKeyClassRef = multiKeyPlan.ClassRef;
                
                if (segmented.OptionalInit != null) {
                    asNames.Clear();
                    foreach (var initCondition in segmented.OptionalInit) {
                        ContextDetailMatchPair pair = ValidateRewriteContextCondition(
                            true,
                            nestingLevel,
                            initCondition,
                            eventTypesReferenced,
                            new MatchEventSpec(),
                            new EmptySet<string>(),
                            validationEnv);
                        additionalForgeables.AddAll(pair.AdditionalForgeables);

                        var filterForType = initCondition.FilterSpecCompiled.FilterForEventType;
                        var found = false;
                        foreach (var partition in segmented.Items) {
                            if (partition.FilterSpecCompiled.FilterForEventType == filterForType) {
                                found = true;
                                break;
                            }
                        }

                        if (!found) {
                            throw new ExprValidationException(
                                "Segmented context '" +
                                validationEnv.ContextName +
                                "' requires that all of the event types that are listed in the initialized-by also appear in the partition-by, type '" +
                                filterForType.Name +
                                "' is not one of the types listed in partition-by");
                        }

                        if (initCondition.OptionalFilterAsName != null) {
                            if (partitionHasNameAssignment) {
                                throw new ExprValidationException(
                                    "Segmented context '" +
                                    validationEnv.ContextName +
                                    "' requires that either partition-by or initialized-by assign stream names, but not both");
                            }

                            ValidateAsName(asNames, initCondition.OptionalFilterAsName, filterForType);
                        }
                    }
                }

                if (segmented.OptionalTermination != null) {
                    var matchEventSpec = new MatchEventSpec();
                    var allTags = new LinkedHashSet<string>();
                    foreach (var partition in segmented.Items) {
                        if (partition.AliasName != null) {
                            allTags.Add(partition.AliasName);
                            var eventType = partition.FilterSpecCompiled.FilterForEventType;
                            matchEventSpec.TaggedEventTypes[partition.AliasName] = new Pair<EventType,string>(
                                eventType, partition.FilterSpecRaw.EventTypeName);
                            var serdeForgeables = SerdeEventTypeUtility.Plan(
                                eventType,
                                validationEnv.StatementRawInfo,
                                validationEnv.Services.SerdeEventTypeRegistry,
                                validationEnv.Services.SerdeResolver);
                            additionalForgeables.AddAll(serdeForgeables);
                        }
                    }

                    if (segmented.OptionalInit != null) {
                        foreach (var initCondition in segmented.OptionalInit) {
                            if (initCondition.OptionalFilterAsName != null) {
                                allTags.Add(initCondition.OptionalFilterAsName);
                                matchEventSpec.TaggedEventTypes.Put(
                                    initCondition.OptionalFilterAsName,
                                    new Pair<EventType, string>(
                                        initCondition.FilterSpecCompiled.FilterForEventType,
                                        initCondition.FilterSpecRaw.EventTypeName));
                            }
                        }
                    }

                    var endCondition = ValidateRewriteContextCondition(
                        false,
                        nestingLevel,
                        segmented.OptionalTermination,
                        eventTypesReferenced,
                        matchEventSpec,
                        allTags,
                        validationEnv);
                    additionalForgeables.AddAll(endCondition.AdditionalForgeables);

                    segmented.OptionalTermination = endCondition.Condition;
                }
            }
            else if (contextSpec is ContextSpecCategory) {
                // compile filter
                var category = (ContextSpecCategory) contextSpec;
                ValidateNotTable(category.FilterSpecRaw.EventTypeName, validationEnv.Services);
                var raw = new FilterStreamSpecRaw(
                    category.FilterSpecRaw,
                    ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                    null,
                    StreamSpecOptions.DEFAULT);

                var compiledDesc = StreamSpecCompiler.CompileFilter(
                    raw,
                    false,
                    false,
                    true,
                    false,
                    null,
                    validationEnv.StatementRawInfo,
                    validationEnv.Services);
                var result = (FilterStreamSpecCompiled) compiledDesc.StreamSpecCompiled;
                additionalForgeables.AddAll(compiledDesc.AdditionalForgeables);
                
                category.FilterSpecCompiled = result.FilterSpecCompiled;
                validationEnv.FilterSpecCompileds.Add(result.FilterSpecCompiled);

                // compile expressions
                foreach (var item in category.Items) {
                    ValidateNotTable(category.FilterSpecRaw.EventTypeName, validationEnv.Services);
                    var filterSpecRaw = new FilterSpecRaw(
                        category.FilterSpecRaw.EventTypeName,
                        Collections.SingletonList(item.Expression),
                        null);
                    var rawExpr = new FilterStreamSpecRaw(
                        filterSpecRaw,
                        ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                        null,
                        StreamSpecOptions.DEFAULT);
                    var compiledDescItems = StreamSpecCompiler.CompileFilter(
                        rawExpr,
                        false,
                        false,
                        true,
                        false,
                        null,
                        validationEnv.StatementRawInfo,
                        validationEnv.Services);
                    var compiled = (FilterStreamSpecCompiled) compiledDescItems.StreamSpecCompiled;
                    additionalForgeables.AddAll(compiledDescItems.AdditionalForgeables);
                    compiled.FilterSpecCompiled.TraverseFilterBooleanExpr(
                        node => validationEnv.FilterBooleanExpressions.Add(node));
                    item.FilterPlan = compiled.FilterSpecCompiled.Parameters;
                }
            }
            else if (contextSpec is ContextSpecHash) {
                var hashed = (ContextSpecHash) contextSpec;
                foreach (var hashItem in hashed.Items) {
                    var raw = new FilterStreamSpecRaw(
                        hashItem.FilterSpecRaw,
                        ViewSpec.EMPTY_VIEWSPEC_ARRAY,
                        null,
                        StreamSpecOptions.DEFAULT);
                    ValidateNotTable(hashItem.FilterSpecRaw.EventTypeName, validationEnv.Services);

                    var compiledDesc = StreamSpecCompiler.Compile(
                        raw,
                        eventTypesReferenced,
                        false,
                        false,
                        true,
                        false,
                        null,
                        0,
                        validationEnv.StatementRawInfo,
                        validationEnv.Services);
                    additionalForgeables.AddAll(compiledDesc.AdditionalForgeables);
                    var result = (FilterStreamSpecCompiled)  compiledDesc.StreamSpecCompiled;

                    validationEnv.FilterSpecCompileds.Add(result.FilterSpecCompiled);
                    hashItem.FilterSpecCompiled = result.FilterSpecCompiled;

                    // validate parameters
                    var streamTypes = new StreamTypeServiceImpl(
                        result.FilterSpecCompiled.FilterForEventType,
                        null,
                        true);
                    var validationContext =
                        new ExprValidationContextBuilder(
                                streamTypes,
                                validationEnv.StatementRawInfo,
                                validationEnv.Services)
                            .WithIsFilterExpression(true)
                            .Build();
                    ExprNodeUtilityValidate.Validate(
                        ExprNodeOrigin.CONTEXT,
                        Collections.SingletonList(hashItem.Function),
                        validationContext);
                }
            }
            else if (contextSpec is ContextSpecInitiatedTerminated) {
                var def = (ContextSpecInitiatedTerminated) contextSpec;
                var startCondition = ValidateRewriteContextCondition(
                    true,
                    nestingLevel,
                    def.StartCondition,
                    eventTypesReferenced,
                    new MatchEventSpec(),
                    new LinkedHashSet<string>(),
                    validationEnv);
                additionalForgeables.AddAll(startCondition.AdditionalForgeables);

                var endCondition = ValidateRewriteContextCondition(
                    false,
                    nestingLevel,
                    def.EndCondition,
                    eventTypesReferenced,
                    startCondition.Matches,
                    startCondition.AllTags,
                    validationEnv);
                additionalForgeables.AddAll(endCondition.AdditionalForgeables);
                
                def.StartCondition = startCondition.Condition;
                def.EndCondition = endCondition.Condition;

                if (def.DistinctExpressions != null) {
                    if (!(startCondition.Condition is ContextSpecConditionFilter)) {
                        throw new ExprValidationException(
                            "Distinct-expressions require a stream as the initiated-by condition");
                    }

                    var distinctExpressions = def.DistinctExpressions;
                    if (distinctExpressions.Length == 0) {
                        throw new ExprValidationException("Distinct-expressions have not been provided");
                    }

                    var filter = (ContextSpecConditionFilter) startCondition.Condition;
                    if (filter.OptionalFilterAsName == null) {
                        throw new ExprValidationException(
                            "Distinct-expressions require that a stream name is assigned to the stream using 'as'");
                    }

                    var types = new StreamTypeServiceImpl(
                        filter.FilterSpecCompiled.FilterForEventType,
                        filter.OptionalFilterAsName,
                        true);
                    var validationContext =
                        new ExprValidationContextBuilder(types, validationEnv.StatementRawInfo, validationEnv.Services)
                            .WithAllowBindingConsumption(true)
                            .Build();
                    for (var i = 0; i < distinctExpressions.Length; i++) {
                        ExprNodeUtilityValidate.ValidatePlainExpression(
                            ExprNodeOrigin.CONTEXTDISTINCT,
                            distinctExpressions[i]);
                        distinctExpressions[i] = ExprNodeUtilityValidate.GetValidatedSubtree(
                            ExprNodeOrigin.CONTEXTDISTINCT,
                            distinctExpressions[i],
                            validationContext);
                    }

                    var multiKeyPlan = MultiKeyPlanner.PlanMultiKey(
                        distinctExpressions,
                        false,
                        @base.StatementRawInfo,
                        validationEnv.Services.SerdeResolver);
                    def.DistinctMultiKey = multiKeyPlan.ClassRef;
                    additionalForgeables.AddAll(multiKeyPlan.MultiKeyForgeables);
                }
            }
            else if (contextSpec is ContextNested) {
                var nested = (ContextNested) contextSpec;
                var level = 0;
                ISet<string> namesUsed = new HashSet<string>();
                namesUsed.Add(validationEnv.ContextName);
                foreach (var nestedContext in nested.Contexts) {
                    if (namesUsed.Contains(nestedContext.ContextName)) {
                        throw new ExprValidationException(
                            "Context by name '" +
                            nestedContext.ContextName +
                            "' has already been declared within nested context '" +
                            validationEnv.ContextName +
                            "'");
                    }

                    namesUsed.Add(nestedContext.ContextName);

                    var forgeables = ValidateContextDetail(nestedContext.ContextDetail, level, validationEnv);
                    additionalForgeables.AddAll(forgeables);
                    level++;
                }
            }
            else {
                throw new IllegalStateException("Unrecognized context detail " + contextSpec);
            }

            return additionalForgeables;
        }
Пример #13
0
        private static ContextDetail WalkChoice(EsperEPL2GrammarParser.CreateContextChoiceContext ctx, IDictionary <ITree, ExprNode> astExprNodeMap, IDictionary <ITree, EvalFactoryNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, FilterSpecRaw filterSpec)
        {
            // temporal fixed (start+end) and overlapping (initiated/terminated)
            if (ctx.START() != null || ctx.INITIATED() != null)
            {
                ExprNode[] distinctExpressions = null;
                if (ctx.createContextDistinct() != null)
                {
                    if (ctx.createContextDistinct().expressionList() == null)
                    {
                        distinctExpressions = new ExprNode[0];
                    }
                    else
                    {
                        distinctExpressions = ASTExprHelper.ExprCollectSubNodesPerNode(ctx.createContextDistinct().expressionList().expression(), astExprNodeMap);
                    }
                }

                ContextDetailCondition startEndpoint;
                if (ctx.START() != null)
                {
                    bool immediate = CheckNow(ctx.i);
                    if (immediate)
                    {
                        startEndpoint = new ContextDetailConditionImmediate();
                    }
                    else
                    {
                        startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false);
                    }
                }
                else
                {
                    bool immediate = CheckNow(ctx.i);
                    startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, immediate);
                }

                bool overlapping = ctx.INITIATED() != null;
                ContextDetailCondition endEndpoint = GetContextCondition(ctx.r2, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false);
                return(new ContextDetailInitiatedTerminated(startEndpoint, endEndpoint, overlapping, distinctExpressions));
            }

            // partitioned
            if (ctx.PARTITION() != null)
            {
                IList <EsperEPL2GrammarParser.CreateContextPartitionItemContext> partitions = ctx.createContextPartitionItem();
                IList <ContextDetailPartitionItem> rawSpecs = new List <ContextDetailPartitionItem>();
                foreach (EsperEPL2GrammarParser.CreateContextPartitionItemContext partition in partitions)
                {
                    filterSpec       = ASTFilterSpecHelper.WalkFilterSpec(partition.eventFilterExpression(), propertyEvalSpec, astExprNodeMap);
                    propertyEvalSpec = null;

                    IList <String> propertyNames = new List <String>();
                    IList <EsperEPL2GrammarParser.EventPropertyContext> properties = partition.eventProperty();
                    foreach (EsperEPL2GrammarParser.EventPropertyContext property in properties)
                    {
                        String propertyName = ASTUtil.GetPropertyName(property, 0);
                        propertyNames.Add(propertyName);
                    }
                    ASTExprHelper.ExprCollectSubNodes(partition, 0, astExprNodeMap); // remove expressions

                    rawSpecs.Add(new ContextDetailPartitionItem(filterSpec, propertyNames));
                }
                return(new ContextDetailPartitioned(rawSpecs));
            }

            // hash
            else if (ctx.COALESCE() != null)
            {
                IList <EsperEPL2GrammarParser.CreateContextCoalesceItemContext> coalesces = ctx.createContextCoalesceItem();
                IList <ContextDetailHashItem> rawSpecs = new List <ContextDetailHashItem>(coalesces.Count);
                foreach (EsperEPL2GrammarParser.CreateContextCoalesceItemContext coalesce in coalesces)
                {
                    ExprChainedSpec func = ASTLibFunctionHelper.GetLibFunctionChainSpec(coalesce.libFunctionNoClass(), astExprNodeMap);
                    filterSpec       = ASTFilterSpecHelper.WalkFilterSpec(coalesce.eventFilterExpression(), propertyEvalSpec, astExprNodeMap);
                    propertyEvalSpec = null;
                    rawSpecs.Add(new ContextDetailHashItem(func, filterSpec));
                }

                String granularity = ctx.g.Text;
                if (!granularity.ToLower().Equals("granularity"))
                {
                    throw ASTWalkException.From("Expected 'granularity' keyword after list of coalesce items, found '" + granularity + "' instead");
                }
                var    num            = ASTConstantHelper.Parse(ctx.number());
                String preallocateStr = ctx.p != null ? ctx.p.Text : null;
                if (preallocateStr != null && !preallocateStr.ToLower().Equals("preallocate"))
                {
                    throw ASTWalkException.From("Expected 'preallocate' keyword after list of coalesce items, found '" + preallocateStr + "' instead");
                }
                if (!num.GetType().IsNumericNonFP() || num.GetType().GetBoxedType() == typeof(long?))
                {
                    throw ASTWalkException.From("Granularity provided must be an int-type number, received " + num.GetType() + " instead");
                }

                return(new ContextDetailHash(rawSpecs, num.AsInt(), preallocateStr != null));
            }

            // categorized
            if (ctx.createContextGroupItem() != null)
            {
                IList <EsperEPL2GrammarParser.CreateContextGroupItemContext> grps = ctx.createContextGroupItem();
                IList <ContextDetailCategoryItem> items = new List <ContextDetailCategoryItem>();
                foreach (EsperEPL2GrammarParser.CreateContextGroupItemContext grp in grps)
                {
                    ExprNode exprNode = ASTExprHelper.ExprCollectSubNodes(grp, 0, astExprNodeMap)[0];
                    String   name     = grp.i.Text;
                    items.Add(new ContextDetailCategoryItem(exprNode, name));
                }
                filterSpec = ASTFilterSpecHelper.WalkFilterSpec(ctx.eventFilterExpression(), propertyEvalSpec, astExprNodeMap);
                return(new ContextDetailCategory(items, filterSpec));
            }

            throw new IllegalStateException("Unrecognized context detail type");
        }