Package com.espertech.esper.core.service

Examples of com.espertech.esper.core.service.StatementContext


    public ViewableActivationResult activate(AgentInstanceContext agentInstanceContext, boolean isSubselect, boolean isRecoveringResilient) {
        PatternAgentInstanceContext patternAgentInstanceContext = agentInstanceContext.getStatementContext().getPatternContextFactory().createPatternAgentContext(patternContext, agentInstanceContext, hasConsumingFilter);
        EvalRootNode rootNode = EvalNodeUtil.makeRootNodeFromFactory(rootFactoryNode, patternAgentInstanceContext);

        final EventStream sourceEventStream = new ZeroDepthStream(eventType);
        final StatementContext statementContext = patternContext.getStatementContext();
        final PatternMatchCallback callback = new PatternMatchCallback() {
            public void matchFound(Map<String, Object> matchEvent)
            {
                EventBean compositeEvent = statementContext.getEventAdapterService().adapterForTypedMap(matchEvent, eventType);
                sourceEventStream.insert(compositeEvent);
            }
        };

        EvalRootState rootState = rootNode.start(callback, patternContext, isRecoveringResilient);
View Full Code Here


    {
        EventType parentViewType = viewChain.getEventType();
        this.matchRecognizeSpec = matchRecognizeSpec;
        this.isUnbound = isUnbound;
        this.isIterateOnly = HintEnum.ITERATE_ONLY.getHint(annotations) != null;
        StatementContext statementContext = agentInstanceContext.getStatementContext();

        // Determine single-row and multiple-row variables
        variablesSingle = new LinkedHashSet<String>();
        Set<String> variablesMultiple = new LinkedHashSet<String>();
        EventRowRegexHelper.recursiveInspectVariables(matchRecognizeSpec.getPattern(), false, variablesSingle, variablesMultiple);

        // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression).
        int streamNum = 0;
        variableStreams = new LinkedHashMap<String, Pair<Integer, Boolean>>();
        for (String variableSingle : variablesSingle)
        {
            variableStreams.put(variableSingle, new Pair<Integer, Boolean>(streamNum, false));
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            variableStreams.put(variableMultiple, new Pair<Integer, Boolean>(streamNum, true));
            streamNum++;
        }

        // mapping of stream to variable
        streamVariables = new TreeMap<Integer, String>();
        for (Map.Entry<String, Pair<Integer, Boolean>> entry : variableStreams.entrySet())
        {
            streamVariables.put(entry.getValue().getFirst(), entry.getKey());
        }

        // determine visibility rules
        Map<String, Set<String>> visibility = EventRowRegexHelper.determineVisibility(matchRecognizeSpec.getPattern());

        // assemble all single-row variables for expression validation
        String[] allStreamNames = new String[variableStreams.size()];
        EventType[] allTypes = new EventType[variableStreams.size()];

        streamNum = 0;
        for (String variableSingle : variablesSingle)
        {
            allStreamNames[streamNum] = variableSingle;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            allStreamNames[streamNum] = variableMultiple;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }

        // determine type service for use with DEFINE
        // validate each DEFINE clause expression
        Set<String> definedVariables = new HashSet<String>();
        List<ExprAggregateNode> aggregateNodes = new ArrayList<ExprAggregateNode>();
        ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
        this.isExprRequiresMultimatchState = new boolean[variableStreams.size()];

        for (int defineIndex = 0; defineIndex < matchRecognizeSpec.getDefines().size(); defineIndex++)
        {
            MatchRecognizeDefineItem defineItem = matchRecognizeSpec.getDefines().get(defineIndex);
            if (definedVariables.contains(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' has already been defined");
            }
            definedVariables.add(defineItem.getIdentifier());

            // stream-type visibilities handled here
            StreamTypeService typeServiceDefines = EventRowRegexNFAViewFactoryHelper.buildDefineStreamTypeServiceDefine(statementContext, variableStreams, defineItem, visibility, parentViewType);

            ExprNode exprNodeResult = handlePreviousFunctions(defineItem.getExpression());
            ExprValidationContext validationContext = new ExprValidationContext(typeServiceDefines, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), true);

            ExprNode validated;
            try {
                // validate
                validated = ExprNodeUtility.getValidatedSubtree(exprNodeResult, validationContext);

                // check aggregates
                defineItem.setExpression(validated);
                ExprAggregateNodeUtil.getAggregatesBottomUp(validated, aggregateNodes);
                if (!aggregateNodes.isEmpty()) {
                    throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause");
                }
            }
            catch (ExprValidationException ex) {
                throw new ExprValidationException("Failed to validate condition expression for variable '" + defineItem.getIdentifier() + "': " + ex.getMessage(), ex);
            }

            // determine access to event properties from multi-matches
            ExprNodeIdentifierCollectVisitor visitor = new ExprNodeIdentifierCollectVisitor();
            validated.accept(visitor);
            Set<Integer> streamsRequired = visitor.getStreamsRequired();
            for (int streamRequired : streamsRequired) {
                if (streamRequired >= variableStreams.size()) {
                    int streamNumIdent = variableStreams.get(defineItem.getIdentifier()).getFirst();
                    isExprRequiresMultimatchState[streamNumIdent] = true;
                    break;
                }
            }
        }
        isDefineAsksMultimatches = CollectionUtil.isAnySet(isExprRequiresMultimatchState);
        defineMultimatchEventBean = isDefineAsksMultimatches ? EventRowRegexNFAViewFactoryHelper.getDefineMultimatchBean(statementContext, variableStreams, parentViewType) : null;

        // assign "prev" node indexes
        // Since an expression such as "prior(2, price), prior(8, price)" translates into {2, 8} the relative index is {0, 1}.
        // Map the expression-supplied index to a relative index
        int countPrev = 0;
        for (Map.Entry<Integer, List<ExprPreviousMatchRecognizeNode>> entry : callbacksPerIndex.entrySet()) {
            for (ExprPreviousMatchRecognizeNode callback : entry.getValue()) {
                callback.setAssignedIndex(countPrev);
            }
            countPrev++;
        }

        // determine type service for use with MEASURE
        Map<String, Object> measureTypeDef = new LinkedHashMap<String, Object>();
        for (String variableSingle : variablesSingle)
        {
            measureTypeDef.put(variableSingle, parentViewType);
        }
        for (String variableMultiple : variablesMultiple)
        {
            measureTypeDef.put(variableMultiple, new EventType[] {parentViewType});
        }
        String outputEventTypeName = statementContext.getStatementId() + "_rowrecog";
        compositeEventType = statementContext.getEventAdapterService().createAnonymousMapType(outputEventTypeName, measureTypeDef);
        StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(compositeEventType, "MATCH_RECOGNIZE", true, statementContext.getEngineURI());

        // find MEASURE clause aggregations
        boolean measureReferencesMultivar = false;
        List<ExprAggregateNode> measureAggregateExprNodes = new ArrayList<ExprAggregateNode>();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(measureItem.getExpr(), measureAggregateExprNodes);
        }
        if (!measureAggregateExprNodes.isEmpty())
        {
            boolean[] isIStreamOnly = new boolean[allStreamNames.length];
            Arrays.fill(isIStreamOnly, true);
            StreamTypeServiceImpl typeServiceAggregateMeasure = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.getEngineURI(), false);
            Map<Integer, List<ExprAggregateNode>> measureExprAggNodesPerStream = new HashMap<Integer, List<ExprAggregateNode>>();

            for (ExprAggregateNode aggregateNode : measureAggregateExprNodes)
            {
                int count = 0;
                ExprNodeIdentifierVisitor visitor = new ExprNodeIdentifierVisitor(true);

                ExprValidationContext validationContext = new ExprValidationContext(typeServiceAggregateMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), false);
                for (ExprNode child : aggregateNode.getChildNodes())
                {
                    ExprNode validated = ExprNodeUtility.getValidatedSubtree(child, validationContext);
                    validated.accept(visitor);
                    aggregateNode.setChildNode(count++, new ExprNodeValidated(validated));
                }
                validationContext = new ExprValidationContext(typeServiceMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), false);
                aggregateNode.validate(validationContext);

                // verify properties used within the aggregation
                Set<Integer> aggregatedStreams = new HashSet<Integer>();
                for (Pair<Integer, String> pair : visitor.getExprProperties())
                {
                    aggregatedStreams.add(pair.getFirst());
                }

                Integer multipleVarStream = null;
                for (int streamNumAggregated : aggregatedStreams)
                {
                    String variable = streamVariables.get(streamNumAggregated);
                    if (variablesMultiple.contains(variable))
                    {
                        measureReferencesMultivar = true;
                        if (multipleVarStream == null)
                        {
                            multipleVarStream = streamNumAggregated;
                            continue;
                        }
                        throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events");
                    }
                }

                if (multipleVarStream == null)
                {
                    throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events");
                }

                List<ExprAggregateNode> aggNodesForStream = measureExprAggNodesPerStream.get(multipleVarStream);
                if (aggNodesForStream == null)
                {
                    aggNodesForStream = new ArrayList<ExprAggregateNode>();
                    measureExprAggNodesPerStream.put(multipleVarStream, aggNodesForStream);
                }
                aggNodesForStream.add(aggregateNode);
            }

            AggregationServiceMatchRecognizeFactoryDesc factoryDesc = AggregationServiceFactoryFactory.getServiceMatchRecognize(streamVariables.size(), measureExprAggNodesPerStream, exprEvaluatorContext);
            aggregationService = factoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext);
            aggregationExpressions = factoryDesc.getExpressions();
        }
        else
        {
            aggregationService = null;
            aggregationExpressions = Collections.emptyList();
        }

        // validate each MEASURE clause expression
        Map<String, Object> rowTypeDef = new LinkedHashMap<String, Object>();
        ExprNodeIdentifierCollectVisitor streamRefVisitorNonAgg = new ExprNodeIdentifierCollectVisitor();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            if (measureItem.getName() == null)
            {
                throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name");
            }
            ExprNode validated = validateMeasureClause(measureItem.getExpr(), typeServiceMeasure, variablesMultiple, variablesSingle, statementContext);
            measureItem.setExpr(validated);
            rowTypeDef.put(measureItem.getName(), validated.getExprEvaluator().getType());
            validated.accept(streamRefVisitorNonAgg);
        }

        // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only)
        for (ExprIdentNode identNode : streamRefVisitorNonAgg.getExprProperties()) {
            String rootPropName = identNode.getResolvedPropertyNameRoot();
            if (variablesMultiple.contains(rootPropName) || (rootPropName == null)) {
                measureReferencesMultivar = true;
                break;
            }
        }
        Set<Integer> streamsRequired = streamRefVisitorNonAgg.getStreamsRequired();
        for (int streamRequired : streamsRequired) {
            String streamVariable = streamVariables.get(streamRequired);
            if (streamVariable != null) {
                Pair<Integer, Boolean> def = variableStreams.get(streamVariable);
                if (def != null && def.getSecond()) {
                    measureReferencesMultivar = true;
                    break;
                }
            }
        }
        isCollectMultimatches = measureReferencesMultivar || isDefineAsksMultimatches;

        // create rowevent type
        String rowEventTypeName = statementContext.getStatementId() + "_rowrecogrow";
        rowEventType = statementContext.getEventAdapterService().createAnonymousMapType(rowEventTypeName, rowTypeDef);

        // validate partition-by expressions, if any
        if (!matchRecognizeSpec.getPartitionByExpressions().isEmpty())
        {
            StreamTypeService typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.getEngineURI());
            List<ExprNode> validated = new ArrayList<ExprNode>();
            ExprValidationContext validationContext = new ExprValidationContext(typeServicePartition, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), false);
            for (ExprNode partitionExpr : matchRecognizeSpec.getPartitionByExpressions())
            {
                validated.add(ExprNodeUtility.getValidatedSubtree(partitionExpr, validationContext));
            }
            matchRecognizeSpec.setPartitionByExpressions(validated);
        }

        // validate interval if present
        if (matchRecognizeSpec.getInterval() != null) {
            ExprValidationContext validationContext = new ExprValidationContext(new StreamTypeServiceImpl(statementContext.getEngineURI(), false), statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), false);
            matchRecognizeSpec.getInterval().validate(validationContext);
        }
    }
View Full Code Here

            adapterFactories[i] = context.getStatementContext().getEventAdapterService().getAdapterFactoryForType(eventType);
        }

        // Compile and prepare execution
        //
        final StatementContext statementContext = context.getStatementContext();
        EPServicesContext servicesContext = context.getServicesContext();
        AgentInstanceContext agentInstanceContext = context.getAgentInstanceContext();

        // validate
        if (select.getInsertIntoDesc() != null) {
            throw new ExprValidationException("Insert-into clause is not supported");
        }
        if (select.getSelectStreamSelectorEnum() != SelectClauseStreamSelectorEnum.ISTREAM_ONLY) {
            throw new ExprValidationException("Selecting remove-stream is not supported");
        }
        ExprNodeSubselectDeclaredDotVisitor visitor = StatementSpecRawAnalyzer.walkSubselectAndDeclaredDotExpr(select);
        if (!visitor.getSubselects().isEmpty()) {
            throw new ExprValidationException("Subselects are not supported");
        }

        Map<Integer, FilterStreamSpecRaw> streams = new HashMap<Integer, FilterStreamSpecRaw>();
        for (int streamNum = 0; streamNum < select.getStreamSpecs().size(); streamNum++) {
            StreamSpecRaw rawStreamSpec = select.getStreamSpecs().get(streamNum);
            if (!(rawStreamSpec instanceof 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
        List<StreamSpecCompiled> streamSpecCompileds = new ArrayList<StreamSpecCompiled>();
        for (int streamNum = 0; streamNum < select.getStreamSpecs().size(); streamNum++) {
            FilterStreamSpecRaw filter = streams.get(streamNum);
            Map.Entry<Integer, DataFlowOpInputPort> inputPort = findInputPort(filter.getRawFilterSpec().getEventTypeName(), context.getInputPorts());
            if (inputPort == null) {
                throw new ExprValidationException("Failed to find stream '" + filter.getRawFilterSpec().getEventTypeName() + "' among input ports, input ports are " + Arrays.toString(getInputPortNames(context.getInputPorts())));
            }
            EventType eventType = inputPort.getValue().getTypeDesc().getEventType();
            String streamAlias = filter.getOptionalStreamName();
            FilterSpecCompiled filterSpecCompiled = new FilterSpecCompiled(eventType, streamAlias, Collections.<FilterSpecParam>emptyList(), null);
            FilterStreamSpecCompiled filterStreamSpecCompiled = new FilterStreamSpecCompiled(filterSpecCompiled, select.getStreamSpecs().get(0).getViewSpecs(), streamAlias, new StreamSpecOptions());
            streamSpecCompileds.add(filterStreamSpecCompiled);
        }

        // create compiled statement spec
        SelectClauseSpecCompiled selectClauseCompiled = StatementLifecycleSvcUtil.compileSelectClause(select.getSelectClauseSpec());

        // determine if snapshot output is needed
        OutputLimitSpec outputLimitSpec = select.getOutputLimitSpec();
        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);
        }

        Annotation[] mergedAnnotations = AnnotationUtil.mergeAnnotations(statementContext.getAnnotations(), context.getOperatorAnnotations());
        ExprNode[] groupByExpressions = ExprNodeUtility.toArray(select.getGroupByExpressions());
        OrderByItem[] orderByArray = OrderByItem.toArray(select.getOrderByList());
        OuterJoinDesc[] outerJoinArray = OuterJoinDesc.toArray(select.getOuterJoinDescList());
        StreamSpecCompiled[] streamSpecArray = streamSpecCompileds.toArray(new StreamSpecCompiled[streamSpecCompileds.size()]);
        StatementSpecCompiled compiled = new StatementSpecCompiled(null, null, null, null, null, null, SelectClauseStreamSelectorEnum.ISTREAM_ONLY,
View Full Code Here

    {
        EventType parentViewType = viewChain.getEventType();
        this.matchRecognizeSpec = matchRecognizeSpec;
        this.isUnbound = isUnbound;
        this.isIterateOnly = HintEnum.ITERATE_ONLY.getHint(annotations) != null;
        StatementContext statementContext = agentInstanceContext.getStatementContext();

        // Determine single-row and multiple-row variables
        variablesSingle = new LinkedHashSet<String>();
        Set<String> variablesMultiple = new LinkedHashSet<String>();
        EventRowRegexHelper.recursiveInspectVariables(matchRecognizeSpec.getPattern(), false, variablesSingle, variablesMultiple);

        // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression).
        int streamNum = 0;
        variableStreams = new LinkedHashMap<String, Pair<Integer, Boolean>>();
        for (String variableSingle : variablesSingle)
        {
            variableStreams.put(variableSingle, new Pair<Integer, Boolean>(streamNum, false));
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            variableStreams.put(variableMultiple, new Pair<Integer, Boolean>(streamNum, true));
            streamNum++;
        }

        // mapping of stream to variable
        streamVariables = new TreeMap<Integer, String>();
        for (Map.Entry<String, Pair<Integer, Boolean>> entry : variableStreams.entrySet())
        {
            streamVariables.put(entry.getValue().getFirst(), entry.getKey());
        }

        // assemble all single-row variables for expression validation
        String[] singleVarStreamNames = new String[variableStreams.size()];
        String[] allStreamNames = new String[variableStreams.size()];
        EventType[] singleVarTypes = new EventType[variableStreams.size()];
        EventType[] allTypes = new EventType[variableStreams.size()];

        streamNum = 0;
        for (String variableSingle : variablesSingle)
        {
            singleVarStreamNames[streamNum] = variableSingle;
            singleVarTypes[streamNum] = parentViewType;
            allStreamNames[streamNum] = variableSingle;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            allStreamNames[streamNum] = variableMultiple;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }

        // determine type service for use with DEFINE
        // validate each DEFINE clause expression
        Set<String> definedVariables = new HashSet<String>();
        List<ExprAggregateNode> aggregateNodes = new ArrayList<ExprAggregateNode>();
        ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
        for (MatchRecognizeDefineItem defineItem : matchRecognizeSpec.getDefines())
        {
            if (definedVariables.contains(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' has already been defined");
            }
            definedVariables.add(defineItem.getIdentifier());

            String[] streamNamesDefine = new String[singleVarStreamNames.length];
            System.arraycopy(singleVarStreamNames, 0, streamNamesDefine, 0, singleVarStreamNames.length);
            EventType[] typesDefine = new EventType[singleVarTypes.length];
            System.arraycopy(singleVarTypes, 0, typesDefine, 0, singleVarTypes.length);
            boolean[] isIStreamOnly = new boolean[singleVarTypes.length];
            Arrays.fill(isIStreamOnly, true);

            // the own stream is available for querying
            if (!variableStreams.containsKey(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' does not occur in pattern");
            }
            int streamNumDefine = variableStreams.get(defineItem.getIdentifier()).getFirst();
            streamNamesDefine[streamNumDefine] = defineItem.getIdentifier();
            typesDefine[streamNumDefine] = parentViewType;

            StreamTypeService typeServiceDefines = new StreamTypeServiceImpl(typesDefine, streamNamesDefine, isIStreamOnly, statementContext.getEngineURI(), false);
            ExprNode exprNodeResult = handlePreviousFunctions(defineItem.getExpression());
            ExprValidationContext validationContext = new ExprValidationContext(typeServiceDefines, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            ExprNode validated = ExprNodeUtility.getValidatedSubtree(exprNodeResult, validationContext);
            defineItem.setExpression(validated);

            ExprAggregateNodeUtil.getAggregatesBottomUp(validated, aggregateNodes);
            if (!aggregateNodes.isEmpty())
            {
                throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause");
            }
        }

        // determine type service for use with MEASURE
        Map<String, Object> measureTypeDef = new LinkedHashMap<String, Object>();
        for (String variableSingle : variablesSingle)
        {
            measureTypeDef.put(variableSingle, parentViewType);
        }
        for (String variableMultiple : variablesMultiple)
        {
            measureTypeDef.put(variableMultiple, new EventType[] {parentViewType});
        }
        String outputEventTypeName = statementContext.getStatementId() + "_rowrecog";
        compositeEventType = statementContext.getEventAdapterService().createAnonymousMapType(outputEventTypeName, measureTypeDef);
        StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(compositeEventType, "MATCH_RECOGNIZE", true, statementContext.getEngineURI());

        // find MEASURE clause aggregations
        boolean measureReferencesMultivar = false;
        List<ExprAggregateNode> measureAggregateExprNodes = new ArrayList<ExprAggregateNode>();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(measureItem.getExpr(), measureAggregateExprNodes);
        }
        if (!measureAggregateExprNodes.isEmpty())
        {
            boolean[] isIStreamOnly = new boolean[allStreamNames.length];
            Arrays.fill(isIStreamOnly, true);
            StreamTypeServiceImpl typeServiceAggregateMeasure = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.getEngineURI(), false);
            Map<Integer, List<ExprAggregateNode>> measureExprAggNodesPerStream = new HashMap<Integer, List<ExprAggregateNode>>();

            for (ExprAggregateNode aggregateNode : measureAggregateExprNodes)
            {
                int count = 0;
                ExprNodeIdentifierVisitor visitor = new ExprNodeIdentifierVisitor(true);

                ExprValidationContext validationContext = new ExprValidationContext(typeServiceAggregateMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                for (ExprNode child : aggregateNode.getChildNodes())
                {
                    ExprNode validated = ExprNodeUtility.getValidatedSubtree(child, validationContext);
                    validated.accept(visitor);
                    aggregateNode.getChildNodes().set(count++, new ExprNodeValidated(validated));
                }
                validationContext = new ExprValidationContext(typeServiceMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                aggregateNode.validate(validationContext);

                // verify properties used within the aggregation
                Set<Integer> aggregatedStreams = new HashSet<Integer>();
                for (Pair<Integer, String> pair : visitor.getExprProperties())
                {
                    aggregatedStreams.add(pair.getFirst());
                }

                Integer multipleVarStream = null;
                for (int streamNumAggregated : aggregatedStreams)
                {
                    String variable = streamVariables.get(streamNumAggregated);
                    if (variablesMultiple.contains(variable))
                    {
                        measureReferencesMultivar = true;
                        if (multipleVarStream == null)
                        {
                            multipleVarStream = streamNumAggregated;
                            continue;
                        }
                        throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events");
                    }
                }

                if (multipleVarStream == null)
                {
                    throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events");
                }

                List<ExprAggregateNode> aggNodesForStream = measureExprAggNodesPerStream.get(multipleVarStream);
                if (aggNodesForStream == null)
                {
                    aggNodesForStream = new ArrayList<ExprAggregateNode>();
                    measureExprAggNodesPerStream.put(multipleVarStream, aggNodesForStream);
                }
                aggNodesForStream.add(aggregateNode);
            }

            AggregationServiceMatchRecognizeFactoryDesc factoryDesc = AggregationServiceFactoryFactory.getServiceMatchRecognize(streamVariables.size(), measureExprAggNodesPerStream, statementContext.getMethodResolutionService(), exprEvaluatorContext);
            aggregationService = factoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext);
            aggregationExpressions = factoryDesc.getExpressions();
        }
        else
        {
            aggregationService = null;
            aggregationExpressions = Collections.emptyList();
        }

        // validate each MEASURE clause expression
        Map<String, Object> rowTypeDef = new LinkedHashMap<String, Object>();
        ExprNodeIdentifierCollectVisitor streamRefVisitorNonAgg = new ExprNodeIdentifierCollectVisitor();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            if (measureItem.getName() == null)
            {
                throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name");
            }
            ExprNode validated = validateMeasureClause(measureItem.getExpr(), typeServiceMeasure, variablesMultiple, variablesSingle, statementContext);
            measureItem.setExpr(validated);
            rowTypeDef.put(measureItem.getName(), validated.getExprEvaluator().getType());
            validated.accept(streamRefVisitorNonAgg);
        }

        // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only)
        for (ExprIdentNode ref : streamRefVisitorNonAgg.getExprProperties()) {
            String rootPropName = ref.getResolvedPropertyNameRoot();
            if (variablesMultiple.contains(rootPropName) || (rootPropName == null)) {
                measureReferencesMultivar = true;
                break;
            }
        }
        isSelectAsksMultimatches = measureReferencesMultivar;

        // create rowevent type
        String rowEventTypeName = statementContext.getStatementId() + "_rowrecogrow";
        rowEventType = statementContext.getEventAdapterService().createAnonymousMapType(rowEventTypeName, rowTypeDef);

        // validate partition-by expressions, if any
        if (!matchRecognizeSpec.getPartitionByExpressions().isEmpty())
        {
            StreamTypeService typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.getEngineURI());
            List<ExprNode> validated = new ArrayList<ExprNode>();
            ExprValidationContext validationContext = new ExprValidationContext(typeServicePartition, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            for (ExprNode partitionExpr : matchRecognizeSpec.getPartitionByExpressions())
            {
                validated.add(ExprNodeUtility.getValidatedSubtree(partitionExpr, validationContext));
            }
            matchRecognizeSpec.setPartitionByExpressions(validated);
View Full Code Here

        // order-by clause with the full expression
        expandColumnNames(selectClauseSpec.getSelectExprList(), orderByList);

        // Validate selection expressions, if any (could be wildcard i.e. empty list)
        List<SelectClauseExprCompiledSpec> namedSelectionList = new LinkedList<SelectClauseExprCompiledSpec>();
        StatementContext stmtContext = agentInstanceContext.getStatementContext();
        ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(stmtContext);
        ExprValidationContext validationContext = new ExprValidationContext(typeService, stmtContext.getMethodResolutionService(), viewResourceDelegate, stmtContext.getSchedulingService(), stmtContext.getVariableService(),evaluatorContextStmt, stmtContext.getEventAdapterService(), stmtContext.getStatementName(), stmtContext.getStatementId(), stmtContext.getAnnotations(), stmtContext.getContextDescriptor());

        for (int i = 0; i < selectClauseSpec.getSelectExprList().size(); i++)
        {
            // validate element
            SelectClauseElementCompiled element = selectClauseSpec.getSelectExprList().get(i);
            if (element instanceof SelectClauseExprCompiledSpec)
            {
                SelectClauseExprCompiledSpec expr = (SelectClauseExprCompiledSpec) element;
                ExprNode validatedExpression = ExprNodeUtility.getValidatedSubtree(expr.getSelectExpression(), validationContext);

                // determine an element name if none assigned
                String asName = expr.getAssignedName();
                if (asName == null)
                {
                    asName = validatedExpression.toExpressionString();
                }

                expr.setAssignedName(asName);
                expr.setSelectExpression(validatedExpression);
                namedSelectionList.add(expr);
            }
        }
        boolean isUsingWildcard = selectClauseSpec.isUsingWildcard();

        // Validate stream selections, if any (such as stream.*)
        boolean isUsingStreamSelect = false;
        for (SelectClauseElementCompiled compiled : selectClauseSpec.getSelectExprList())
        {
            if (!(compiled instanceof SelectClauseStreamCompiledSpec))
            {
                continue;
            }
            SelectClauseStreamCompiledSpec streamSelectSpec = (SelectClauseStreamCompiledSpec) compiled;
            int streamNum = Integer.MIN_VALUE;
            boolean isFragmentEvent = false;
            boolean isProperty = false;
            Class propertyType = null;
            isUsingStreamSelect = true;
            for (int i = 0; i < typeService.getStreamNames().length; i++)
            {
                String streamName = streamSelectSpec.getStreamName();
                if (typeService.getStreamNames()[i].equals(streamName))
                {
                    streamNum = i;
                    break;
                }

                // see if the stream name is known as a nested event type
                EventType candidateProviderOfFragments = typeService.getEventTypes()[i];
                // for the native event type we don't need to fragment, we simply use the property itself since all wrappers understand Java objects
                if (!(candidateProviderOfFragments instanceof NativeEventType) && (candidateProviderOfFragments.getFragmentType(streamName) != null))
                {
                    streamNum = i;
                    isFragmentEvent = true;
                    break;
                }
            }

            // stream name not found
            if (streamNum == Integer.MIN_VALUE)
            {
                // see if the stream name specified resolves as a property
                PropertyResolutionDescriptor desc = null;
                try
                {
                    desc = typeService.resolveByPropertyName(streamSelectSpec.getStreamName());
                }
                catch (StreamTypesException e)
                {
                    // not handled
                }

                if (desc == null)
                {
                    throw new ExprValidationException("Stream selector '" + streamSelectSpec.getStreamName() + ".*' does not match any stream name in the from clause");
                }
                isProperty = true;
                propertyType = desc.getPropertyType();
                streamNum = desc.getStreamNum();
            }

            streamSelectSpec.setStreamNumber(streamNum);
            streamSelectSpec.setFragmentEvent(isFragmentEvent);
            streamSelectSpec.setProperty(isProperty, propertyType);
        }

        // Validate group-by expressions, if any (could be empty list for no group-by)
        Class[] groupByTypes = new Class[groupByNodes.size()];
        for (int i = 0; i < groupByNodes.size(); i++)
        {
            // Ensure there is no subselects
            ExprNodeSubselectVisitor visitor = new ExprNodeSubselectVisitor();
            groupByNodes.get(i).accept(visitor);
            if (visitor.getSubselects().size() > 0)
            {
                throw new ExprValidationException("Subselects not allowed within group-by");
            }

            ExprNode validatedGroupBy = ExprNodeUtility.getValidatedSubtree(groupByNodes.get(i), validationContext);
            groupByNodes.set(i, validatedGroupBy);
            groupByTypes[i] = validatedGroupBy.getExprEvaluator().getType();
        }
        stmtContext.getMethodResolutionService().setGroupKeyTypes(groupByTypes);

        // Validate having clause, if present
        if (optionalHavingNode != null)
        {
            // Ensure there is no subselects
            ExprNodeSubselectVisitor visitor = new ExprNodeSubselectVisitor();
            optionalHavingNode.accept(visitor);
            if (visitor.getSubselects().size() > 0)
            {
                throw new ExprValidationException("Subselects not allowed within having-clause");
            }

            optionalHavingNode = ExprNodeUtility.getValidatedSubtree(optionalHavingNode, validationContext);
        }

        // Validate order-by expressions, if any (could be empty list for no order-by)
        for (int i = 0; i < orderByList.size(); i++)
        {
          ExprNode orderByNode = orderByList.get(i).getExprNode();

            // Ensure there is no subselects
            ExprNodeSubselectVisitor visitor = new ExprNodeSubselectVisitor();
            orderByNode.accept(visitor);
            if (visitor.getSubselects().size() > 0)
            {
                throw new ExprValidationException("Subselects not allowed within order-by clause");
            }

            Boolean isDescending = orderByList.get(i).isDescending();
          OrderByItem validatedOrderBy = new OrderByItem(ExprNodeUtility.getValidatedSubtree(orderByNode, validationContext), isDescending);
          orderByList.set(i, validatedOrderBy);
        }

        // Get the select expression nodes
        List<ExprNode> selectNodes = new ArrayList<ExprNode>();
        for(SelectClauseExprCompiledSpec element : namedSelectionList)
        {
          selectNodes.add(element.getSelectExpression());
        }

        // Get the order-by expression nodes
        List<ExprNode> orderByNodes = new ArrayList<ExprNode>();
        for(OrderByItem element : orderByList)
        {
          orderByNodes.add(element.getExprNode());
        }

        // Determine aggregate functions used in select, if any
        List<ExprAggregateNode> selectAggregateExprNodes = new LinkedList<ExprAggregateNode>();
        for (SelectClauseExprCompiledSpec element : namedSelectionList)
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(element.getSelectExpression(), selectAggregateExprNodes);
        }
        if (!allowAggregation && !selectAggregateExprNodes.isEmpty())
        {
            throw new ExprValidationException("Aggregation functions are not allowed in this context");
        }

        // Determine if we have a having clause with aggregation
        List<ExprAggregateNode> havingAggregateExprNodes = new LinkedList<ExprAggregateNode>();
        Set<Pair<Integer, String>> propertiesAggregatedHaving = new HashSet<Pair<Integer, String>>();
        if (optionalHavingNode != null)
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(optionalHavingNode, havingAggregateExprNodes);
            propertiesAggregatedHaving = ExprNodeUtility.getAggregatedProperties(havingAggregateExprNodes);
        }
        if (!allowAggregation && !havingAggregateExprNodes.isEmpty())
        {
            throw new ExprValidationException("Aggregation functions are not allowed in this context");
        }

        // Determine if we have a order-by clause with aggregation
        List<ExprAggregateNode> orderByAggregateExprNodes = new LinkedList<ExprAggregateNode>();
        if (orderByNodes != null)
        {
            for (ExprNode orderByNode : orderByNodes)
            {
                ExprAggregateNodeUtil.getAggregatesBottomUp(orderByNode, orderByAggregateExprNodes);
            }
            if (!allowAggregation && !orderByAggregateExprNodes.isEmpty())
            {
                throw new ExprValidationException("Aggregation functions are not allowed in this context");
            }
        }

        // Construct the appropriate aggregation service
        boolean hasGroupBy = !groupByNodes.isEmpty();
        AggregationServiceFactoryDesc aggregationServiceFactory = AggregationServiceFactoryFactory.getService(selectAggregateExprNodes, havingAggregateExprNodes, orderByAggregateExprNodes, hasGroupBy, stmtContext.getMethodResolutionService(), evaluatorContextStmt, statementSpecCompiled.getAnnotations(), stmtContext.getVariableService(), typeService.getEventTypes().length > 1,
                statementSpecCompiled.getFilterRootNode(), statementSpecCompiled.getHavingExprRootNode());

        boolean useCollatorSort = false;
        if (stmtContext.getConfigSnapshot() != null)
        {
            useCollatorSort = stmtContext.getConfigSnapshot().getEngineDefaults().getLanguage().isSortUsingCollator();
        }

        // Construct the processor for sorting output events
        OrderByProcessorFactory orderByProcessorFactory = OrderByProcessorFactoryFactory.getProcessor(namedSelectionList,
                groupByNodes, orderByList, statementSpecCompiled.getRowLimitSpec(), stmtContext.getVariableService(), useCollatorSort);

        // Construct the processor for evaluating the select clause
        SelectExprEventTypeRegistry selectExprEventTypeRegistry = new SelectExprEventTypeRegistry(stmtContext.getDynamicReferenceEventTypes());
        SelectExprProcessor selectExprProcessor = SelectExprProcessorFactory.getProcessor(Collections.<Integer>emptyList(), selectClauseSpec.getSelectExprList(), isUsingWildcard, insertIntoDesc, statementSpecCompiled.getForClauseSpec(), typeService, stmtContext.getEventAdapterService(), stmtContext.getStatementResultService(), stmtContext.getValueAddEventService(), selectExprEventTypeRegistry, stmtContext.getMethodResolutionService(), evaluatorContextStmt,
                stmtContext.getVariableService(), stmtContext.getTimeProvider(), stmtContext.getEngineURI(), stmtContext.getStatementId(), stmtContext.getStatementName(), stmtContext.getAnnotations(), stmtContext.getContextDescriptor());

        // Get a list of event properties being aggregated in the select clause, if any
        Set<Pair<Integer, String>> propertiesGroupBy = getGroupByProperties(groupByNodes);
        // Figure out all non-aggregated event properties in the select clause (props not under a sum/avg/max aggregation node)
        Set<Pair<Integer, String>> nonAggregatedProps = ExprNodeUtility.getNonAggregatedProps(typeService.getEventTypes(), selectNodes, contextPropertyRegistry);
View Full Code Here

    public ViewableActivationResult activate(AgentInstanceContext agentInstanceContext) {
        PatternAgentInstanceContext patternAgentInstanceContext = agentInstanceContext.getStatementContext().getPatternContextFactory().createPatternAgentContext(patternContext, agentInstanceContext, hasConsumingFilter);
        EvalRootNode rootNode = EvalNodeUtil.makeRootNodeFromFactory(rootFactoryNode, patternAgentInstanceContext);

        final EventStream sourceEventStream = new ZeroDepthStream(eventType);
        final StatementContext statementContext = patternContext.getStatementContext();
        final PatternMatchCallback callback = new PatternMatchCallback() {
            public void matchFound(Map<String, Object> matchEvent)
            {
                EventBean compositeEvent = statementContext.getEventAdapterService().adapterForTypedMap(matchEvent, eventType);
                sourceEventStream.insert(compositeEvent);
            }
        };

        PatternStopCallback patternStopCallback = rootNode.start(callback, patternContext);
View Full Code Here

    {
        EventType parentViewType = viewChain.getEventType();
        this.matchRecognizeSpec = matchRecognizeSpec;
        this.isUnbound = isUnbound;
        this.isIterateOnly = HintEnum.ITERATE_ONLY.getHint(annotations) != null;
        StatementContext statementContext = agentInstanceContext.getStatementContext();

        // Determine single-row and multiple-row variables
        variablesSingle = new LinkedHashSet<String>();
        Set<String> variablesMultiple = new LinkedHashSet<String>();
        EventRowRegexHelper.recursiveInspectVariables(matchRecognizeSpec.getPattern(), false, variablesSingle, variablesMultiple);

        // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression).
        int streamNum = 0;
        variableStreams = new LinkedHashMap<String, Pair<Integer, Boolean>>();
        for (String variableSingle : variablesSingle)
        {
            variableStreams.put(variableSingle, new Pair<Integer, Boolean>(streamNum, false));
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            variableStreams.put(variableMultiple, new Pair<Integer, Boolean>(streamNum, true));
            streamNum++;
        }

        // mapping of stream to variable
        streamVariables = new TreeMap<Integer, String>();
        for (Map.Entry<String, Pair<Integer, Boolean>> entry : variableStreams.entrySet())
        {
            streamVariables.put(entry.getValue().getFirst(), entry.getKey());
        }

        // assemble all single-row variables for expression validation
        String[] singleVarStreamNames = new String[variableStreams.size()];
        String[] allStreamNames = new String[variableStreams.size()];
        EventType[] singleVarTypes = new EventType[variableStreams.size()];
        EventType[] allTypes = new EventType[variableStreams.size()];

        streamNum = 0;
        for (String variableSingle : variablesSingle)
        {
            singleVarStreamNames[streamNum] = variableSingle;
            singleVarTypes[streamNum] = parentViewType;
            allStreamNames[streamNum] = variableSingle;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            allStreamNames[streamNum] = variableMultiple;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }

        // determine type service for use with DEFINE
        // validate each DEFINE clause expression
        Set<String> definedVariables = new HashSet<String>();
        List<ExprAggregateNode> aggregateNodes = new ArrayList<ExprAggregateNode>();
        ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
        for (MatchRecognizeDefineItem defineItem : matchRecognizeSpec.getDefines())
        {
            if (definedVariables.contains(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' has already been defined");
            }
            definedVariables.add(defineItem.getIdentifier());

            String[] streamNamesDefine = new String[singleVarStreamNames.length];
            System.arraycopy(singleVarStreamNames, 0, streamNamesDefine, 0, singleVarStreamNames.length);
            EventType[] typesDefine = new EventType[singleVarTypes.length];
            System.arraycopy(singleVarTypes, 0, typesDefine, 0, singleVarTypes.length);
            boolean[] isIStreamOnly = new boolean[singleVarTypes.length];
            Arrays.fill(isIStreamOnly, true);

            // the own stream is available for querying
            if (!variableStreams.containsKey(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' does not occur in pattern");
            }
            int streamNumDefine = variableStreams.get(defineItem.getIdentifier()).getFirst();
            streamNamesDefine[streamNumDefine] = defineItem.getIdentifier();
            typesDefine[streamNumDefine] = parentViewType;

            StreamTypeService typeServiceDefines = new StreamTypeServiceImpl(typesDefine, streamNamesDefine, isIStreamOnly, statementContext.getEngineURI(), false);
            ExprNode exprNodeResult = handlePreviousFunctions(defineItem.getExpression());
            ExprValidationContext validationContext = new ExprValidationContext(typeServiceDefines, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            ExprNode validated = ExprNodeUtility.getValidatedSubtree(exprNodeResult, validationContext);
            defineItem.setExpression(validated);

            ExprAggregateNodeUtil.getAggregatesBottomUp(validated, aggregateNodes);
            if (!aggregateNodes.isEmpty())
            {
                throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause");
            }
        }

        // determine type service for use with MEASURE
        Map<String, Object> measureTypeDef = new LinkedHashMap<String, Object>();
        for (String variableSingle : variablesSingle)
        {
            measureTypeDef.put(variableSingle, parentViewType);
        }
        for (String variableMultiple : variablesMultiple)
        {
            measureTypeDef.put(variableMultiple, new EventType[] {parentViewType});
        }
        String outputEventTypeName = statementContext.getStatementId() + "_rowrecog";
        compositeEventType = statementContext.getEventAdapterService().createAnonymousMapType(outputEventTypeName, measureTypeDef);
        StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(compositeEventType, "MATCH_RECOGNIZE", true, statementContext.getEngineURI());

        // find MEASURE clause aggregations
        boolean measureReferencesMultivar = false;
        List<ExprAggregateNode> measureAggregateExprNodes = new ArrayList<ExprAggregateNode>();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(measureItem.getExpr(), measureAggregateExprNodes);
        }
        if (!measureAggregateExprNodes.isEmpty())
        {
            boolean[] isIStreamOnly = new boolean[allStreamNames.length];
            Arrays.fill(isIStreamOnly, true);
            StreamTypeServiceImpl typeServiceAggregateMeasure = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.getEngineURI(), false);
            Map<Integer, List<ExprAggregateNode>> measureExprAggNodesPerStream = new HashMap<Integer, List<ExprAggregateNode>>();

            for (ExprAggregateNode aggregateNode : measureAggregateExprNodes)
            {
                int count = 0;
                ExprNodeIdentifierVisitor visitor = new ExprNodeIdentifierVisitor(true);

                ExprValidationContext validationContext = new ExprValidationContext(typeServiceAggregateMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                for (ExprNode child : aggregateNode.getChildNodes())
                {
                    ExprNode validated = ExprNodeUtility.getValidatedSubtree(child, validationContext);
                    validated.accept(visitor);
                    aggregateNode.getChildNodes().set(count++, new ExprNodeValidated(validated));
                }
                validationContext = new ExprValidationContext(typeServiceMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                aggregateNode.validate(validationContext);

                // verify properties used within the aggregation
                Set<Integer> aggregatedStreams = new HashSet<Integer>();
                for (Pair<Integer, String> pair : visitor.getExprProperties())
                {
                    aggregatedStreams.add(pair.getFirst());
                }

                Integer multipleVarStream = null;
                for (int streamNumAggregated : aggregatedStreams)
                {
                    String variable = streamVariables.get(streamNumAggregated);
                    if (variablesMultiple.contains(variable))
                    {
                        measureReferencesMultivar = true;
                        if (multipleVarStream == null)
                        {
                            multipleVarStream = streamNumAggregated;
                            continue;
                        }
                        throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events");
                    }
                }

                if (multipleVarStream == null)
                {
                    throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events");
                }

                List<ExprAggregateNode> aggNodesForStream = measureExprAggNodesPerStream.get(multipleVarStream);
                if (aggNodesForStream == null)
                {
                    aggNodesForStream = new ArrayList<ExprAggregateNode>();
                    measureExprAggNodesPerStream.put(multipleVarStream, aggNodesForStream);
                }
                aggNodesForStream.add(aggregateNode);
            }

            AggregationServiceMatchRecognizeFactoryDesc factoryDesc = AggregationServiceFactoryFactory.getServiceMatchRecognize(streamVariables.size(), measureExprAggNodesPerStream, exprEvaluatorContext);
            aggregationService = factoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext);
            aggregationExpressions = factoryDesc.getExpressions();
        }
        else
        {
            aggregationService = null;
            aggregationExpressions = Collections.emptyList();
        }

        // validate each MEASURE clause expression
        Map<String, Object> rowTypeDef = new LinkedHashMap<String, Object>();
        ExprNodeIdentifierCollectVisitor streamRefVisitorNonAgg = new ExprNodeIdentifierCollectVisitor();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            if (measureItem.getName() == null)
            {
                throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name");
            }
            ExprNode validated = validateMeasureClause(measureItem.getExpr(), typeServiceMeasure, variablesMultiple, variablesSingle, statementContext);
            measureItem.setExpr(validated);
            rowTypeDef.put(measureItem.getName(), validated.getExprEvaluator().getType());
            validated.accept(streamRefVisitorNonAgg);
        }

        // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only)
        for (ExprIdentNode identNode : streamRefVisitorNonAgg.getExprProperties()) {
            String rootPropName = identNode.getResolvedPropertyNameRoot();
            if (variablesMultiple.contains(rootPropName) || (rootPropName == null)) {
                measureReferencesMultivar = true;
                break;
            }
        }
        isSelectAsksMultimatches = measureReferencesMultivar;

        // create rowevent type
        String rowEventTypeName = statementContext.getStatementId() + "_rowrecogrow";
        rowEventType = statementContext.getEventAdapterService().createAnonymousMapType(rowEventTypeName, rowTypeDef);

        // validate partition-by expressions, if any
        if (!matchRecognizeSpec.getPartitionByExpressions().isEmpty())
        {
            StreamTypeService typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.getEngineURI());
            List<ExprNode> validated = new ArrayList<ExprNode>();
            ExprValidationContext validationContext = new ExprValidationContext(typeServicePartition, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            for (ExprNode partitionExpr : matchRecognizeSpec.getPartitionByExpressions())
            {
                validated.add(ExprNodeUtility.getValidatedSubtree(partitionExpr, validationContext));
            }
            matchRecognizeSpec.setPartitionByExpressions(validated);
View Full Code Here

            adapterFactories[i] = context.getStatementContext().getEventAdapterService().getAdapterFactoryForType(eventType);
        }

        // Compile and prepare execution
        //
        final StatementContext statementContext = context.getStatementContext();
        EPServicesContext servicesContext = context.getServicesContext();
        AgentInstanceContext agentInstanceContext = context.getAgentInstanceContext();

        // validate
        if (select.getInsertIntoDesc() != null) {
            throw new ExprValidationException("Insert-into clause is not supported");
        }
        if (select.getSelectStreamSelectorEnum() != SelectClauseStreamSelectorEnum.ISTREAM_ONLY) {
            throw new ExprValidationException("Selecting remove-stream is not supported");
        }
        ExprNodeSubselectDeclaredDotVisitor visitor = StatementSpecRawAnalyzer.walkSubselectAndDeclaredDotExpr(select);
        if (!visitor.getSubselects().isEmpty()) {
            throw new ExprValidationException("Subselects are not supported");
        }

        Map<Integer, FilterStreamSpecRaw> streams = new HashMap<Integer, FilterStreamSpecRaw>();
        for (int streamNum = 0; streamNum < select.getStreamSpecs().size(); streamNum++) {
            StreamSpecRaw rawStreamSpec = select.getStreamSpecs().get(streamNum);
            if (!(rawStreamSpec instanceof 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
        List<StreamSpecCompiled> streamSpecCompileds = new ArrayList<StreamSpecCompiled>();
        for (int streamNum = 0; streamNum < select.getStreamSpecs().size(); streamNum++) {
            FilterStreamSpecRaw filter = streams.get(streamNum);
            Map.Entry<Integer, DataFlowOpInputPort> inputPort = findInputPort(filter.getRawFilterSpec().getEventTypeName(), context.getInputPorts());
            if (inputPort == null) {
                throw new ExprValidationException("Failed to find stream '" + filter.getRawFilterSpec().getEventTypeName() + "' among input ports, input ports are " + Arrays.toString(getInputPortNames(context.getInputPorts())));
            }
            EventType eventType = inputPort.getValue().getTypeDesc().getEventType();
            String streamAlias = filter.getOptionalStreamName();
            FilterSpecCompiled filterSpecCompiled = new FilterSpecCompiled(eventType, streamAlias, Collections.<FilterSpecParam>emptyList(), null);
            FilterStreamSpecCompiled filterStreamSpecCompiled = new FilterStreamSpecCompiled(filterSpecCompiled, select.getStreamSpecs().get(0).getViewSpecs(), streamAlias, new StreamSpecOptions());
            streamSpecCompileds.add(filterStreamSpecCompiled);
        }

        // create compiled statement spec
        SelectClauseSpecCompiled selectClauseCompiled = StatementLifecycleSvcUtil.compileSelectClause(select.getSelectClauseSpec());

        // determine if snapshot output is needed
        OutputLimitSpec outputLimitSpec = select.getOutputLimitSpec();
        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);
        }

        Annotation[] mergedAnnotations = AnnotationUtil.mergeAnnotations(statementContext.getAnnotations(), context.getOperatorAnnotations());
        List<ExprNode> groupByExpressions = select.getGroupByExpressions();
        StatementSpecCompiled compiled = new StatementSpecCompiled(null, null, null, null, null, null, SelectClauseStreamSelectorEnum.ISTREAM_ONLY,
                selectClauseCompiled, streamSpecCompileds, select.getOuterJoinDescList(), select.getFilterExprRootNode(), groupByExpressions, select.getHavingExprRootNode(), outputLimitSpec,
                select.getOrderByList(), Collections.<ExprSubselectNode>emptyList(), Collections.<ExprDeclaredNode>emptyList(), select.getReferencedVariables(),
                select.getRowLimitSpec(), new HashSet<String>(), mergedAnnotations, null, null, null, null, null, null, null);
View Full Code Here

        if (patternStopCallback != null) {
            patternStopCallback.stop();
        }

        PatternStreamSpecCompiled patternStreamSpec = endpointPatternSpec.getPatternCompiled();
        StatementContext stmtContext = agentInstanceContext.getStatementContext();

        EvalRootFactoryNode rootFactoryNode = servicesContext.getPatternNodeFactory().makeRootNode();
        PatternContext patternContext = stmtContext.getPatternContextFactory().createContext(stmtContext, 0, rootFactoryNode, new MatchedEventMapMeta(patternStreamSpec.getAllTags(), !patternStreamSpec.getArrayEventTypes().isEmpty()));
        rootFactoryNode.addChildNode(patternStreamSpec.getEvalFactoryNode());

        PatternAgentInstanceContext patternAgentInstanceContext = stmtContext.getPatternContextFactory().createPatternAgentContext(patternContext, agentInstanceContext, false);
        EvalRootNode rootNode = EvalNodeUtil.makeRootNodeFromFactory(rootFactoryNode, patternAgentInstanceContext);

        if (priorMatches == null) {
            priorMatches = new MatchedEventMapImpl(patternContext.getMatchedEventMapMeta());
        }
View Full Code Here

    {
        EventType parentViewType = viewChain.getEventType();
        this.matchRecognizeSpec = matchRecognizeSpec;
        this.isUnbound = isUnbound;
        this.isIterateOnly = HintEnum.ITERATE_ONLY.getHint(annotations) != null;
        StatementContext statementContext = agentInstanceContext.getStatementContext();

        // Determine single-row and multiple-row variables
        variablesSingle = new LinkedHashSet<String>();
        Set<String> variablesMultiple = new LinkedHashSet<String>();
        EventRowRegexHelper.recursiveInspectVariables(matchRecognizeSpec.getPattern(), false, variablesSingle, variablesMultiple);

        // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression).
        int streamNum = 0;
        variableStreams = new LinkedHashMap<String, Pair<Integer, Boolean>>();
        for (String variableSingle : variablesSingle)
        {
            variableStreams.put(variableSingle, new Pair<Integer, Boolean>(streamNum, false));
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            variableStreams.put(variableMultiple, new Pair<Integer, Boolean>(streamNum, true));
            streamNum++;
        }

        // mapping of stream to variable
        streamVariables = new TreeMap<Integer, String>();
        for (Map.Entry<String, Pair<Integer, Boolean>> entry : variableStreams.entrySet())
        {
            streamVariables.put(entry.getValue().getFirst(), entry.getKey());
        }

        // assemble all single-row variables for expression validation
        String[] singleVarStreamNames = new String[variableStreams.size()];
        String[] allStreamNames = new String[variableStreams.size()];
        EventType[] singleVarTypes = new EventType[variableStreams.size()];
        EventType[] allTypes = new EventType[variableStreams.size()];

        streamNum = 0;
        for (String variableSingle : variablesSingle)
        {
            singleVarStreamNames[streamNum] = variableSingle;
            singleVarTypes[streamNum] = parentViewType;
            allStreamNames[streamNum] = variableSingle;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }
        for (String variableMultiple : variablesMultiple)
        {
            allStreamNames[streamNum] = variableMultiple;
            allTypes[streamNum] = parentViewType;
            streamNum++;
        }

        // determine type service for use with DEFINE
        // validate each DEFINE clause expression
        Set<String> definedVariables = new HashSet<String>();
        List<ExprAggregateNode> aggregateNodes = new ArrayList<ExprAggregateNode>();
        ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
        for (MatchRecognizeDefineItem defineItem : matchRecognizeSpec.getDefines())
        {
            if (definedVariables.contains(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' has already been defined");
            }
            definedVariables.add(defineItem.getIdentifier());

            String[] streamNamesDefine = new String[singleVarStreamNames.length];
            System.arraycopy(singleVarStreamNames, 0, streamNamesDefine, 0, singleVarStreamNames.length);
            EventType[] typesDefine = new EventType[singleVarTypes.length];
            System.arraycopy(singleVarTypes, 0, typesDefine, 0, singleVarTypes.length);
            boolean[] isIStreamOnly = new boolean[singleVarTypes.length];
            Arrays.fill(isIStreamOnly, true);

            // the own stream is available for querying
            if (!variableStreams.containsKey(defineItem.getIdentifier()))
            {
                throw new ExprValidationException("Variable '" + defineItem.getIdentifier() + "' does not occur in pattern");
            }
            int streamNumDefine = variableStreams.get(defineItem.getIdentifier()).getFirst();
            streamNamesDefine[streamNumDefine] = defineItem.getIdentifier();
            typesDefine[streamNumDefine] = parentViewType;

            StreamTypeService typeServiceDefines = new StreamTypeServiceImpl(typesDefine, streamNamesDefine, isIStreamOnly, statementContext.getEngineURI(), false);
            ExprNode exprNodeResult = handlePreviousFunctions(defineItem.getExpression());
            ExprValidationContext validationContext = new ExprValidationContext(typeServiceDefines, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            ExprNode validated = ExprNodeUtility.getValidatedSubtree(exprNodeResult, validationContext);
            defineItem.setExpression(validated);

            ExprAggregateNodeUtil.getAggregatesBottomUp(validated, aggregateNodes);
            if (!aggregateNodes.isEmpty())
            {
                throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause");
            }
        }

        // determine type service for use with MEASURE
        Map<String, Object> measureTypeDef = new LinkedHashMap<String, Object>();
        for (String variableSingle : variablesSingle)
        {
            measureTypeDef.put(variableSingle, parentViewType);
        }
        for (String variableMultiple : variablesMultiple)
        {
            measureTypeDef.put(variableMultiple, new EventType[] {parentViewType});
        }
        String outputEventTypeName = statementContext.getStatementId() + "_rowrecog";
        compositeEventType = statementContext.getEventAdapterService().createAnonymousMapType(outputEventTypeName, measureTypeDef);
        StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(compositeEventType, "MATCH_RECOGNIZE", true, statementContext.getEngineURI());

        // find MEASURE clause aggregations
        boolean measureReferencesMultivar = false;
        List<ExprAggregateNode> measureAggregateExprNodes = new ArrayList<ExprAggregateNode>();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            ExprAggregateNodeUtil.getAggregatesBottomUp(measureItem.getExpr(), measureAggregateExprNodes);
        }
        if (!measureAggregateExprNodes.isEmpty())
        {
            boolean[] isIStreamOnly = new boolean[allStreamNames.length];
            Arrays.fill(isIStreamOnly, true);
            StreamTypeServiceImpl typeServiceAggregateMeasure = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.getEngineURI(), false);
            Map<Integer, List<ExprAggregateNode>> measureExprAggNodesPerStream = new HashMap<Integer, List<ExprAggregateNode>>();

            for (ExprAggregateNode aggregateNode : measureAggregateExprNodes)
            {
                int count = 0;
                ExprNodeIdentifierVisitor visitor = new ExprNodeIdentifierVisitor(true);

                ExprValidationContext validationContext = new ExprValidationContext(typeServiceAggregateMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                for (ExprNode child : aggregateNode.getChildNodes())
                {
                    ExprNode validated = ExprNodeUtility.getValidatedSubtree(child, validationContext);
                    validated.accept(visitor);
                    aggregateNode.setChildNode(count++, new ExprNodeValidated(validated));
                }
                validationContext = new ExprValidationContext(typeServiceMeasure, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                aggregateNode.validate(validationContext);

                // verify properties used within the aggregation
                Set<Integer> aggregatedStreams = new HashSet<Integer>();
                for (Pair<Integer, String> pair : visitor.getExprProperties())
                {
                    aggregatedStreams.add(pair.getFirst());
                }

                Integer multipleVarStream = null;
                for (int streamNumAggregated : aggregatedStreams)
                {
                    String variable = streamVariables.get(streamNumAggregated);
                    if (variablesMultiple.contains(variable))
                    {
                        measureReferencesMultivar = true;
                        if (multipleVarStream == null)
                        {
                            multipleVarStream = streamNumAggregated;
                            continue;
                        }
                        throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events");
                    }
                }

                if (multipleVarStream == null)
                {
                    throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events");
                }

                List<ExprAggregateNode> aggNodesForStream = measureExprAggNodesPerStream.get(multipleVarStream);
                if (aggNodesForStream == null)
                {
                    aggNodesForStream = new ArrayList<ExprAggregateNode>();
                    measureExprAggNodesPerStream.put(multipleVarStream, aggNodesForStream);
                }
                aggNodesForStream.add(aggregateNode);
            }

            AggregationServiceMatchRecognizeFactoryDesc factoryDesc = AggregationServiceFactoryFactory.getServiceMatchRecognize(streamVariables.size(), measureExprAggNodesPerStream, exprEvaluatorContext);
            aggregationService = factoryDesc.getAggregationServiceFactory().makeService(agentInstanceContext);
            aggregationExpressions = factoryDesc.getExpressions();
        }
        else
        {
            aggregationService = null;
            aggregationExpressions = Collections.emptyList();
        }

        // validate each MEASURE clause expression
        Map<String, Object> rowTypeDef = new LinkedHashMap<String, Object>();
        ExprNodeIdentifierCollectVisitor streamRefVisitorNonAgg = new ExprNodeIdentifierCollectVisitor();
        for (MatchRecognizeMeasureItem measureItem : matchRecognizeSpec.getMeasures())
        {
            if (measureItem.getName() == null)
            {
                throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name");
            }
            ExprNode validated = validateMeasureClause(measureItem.getExpr(), typeServiceMeasure, variablesMultiple, variablesSingle, statementContext);
            measureItem.setExpr(validated);
            rowTypeDef.put(measureItem.getName(), validated.getExprEvaluator().getType());
            validated.accept(streamRefVisitorNonAgg);
        }

        // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only)
        for (ExprIdentNode identNode : streamRefVisitorNonAgg.getExprProperties()) {
            String rootPropName = identNode.getResolvedPropertyNameRoot();
            if (variablesMultiple.contains(rootPropName) || (rootPropName == null)) {
                measureReferencesMultivar = true;
                break;
            }
        }
        isSelectAsksMultimatches = measureReferencesMultivar;

        // create rowevent type
        String rowEventTypeName = statementContext.getStatementId() + "_rowrecogrow";
        rowEventType = statementContext.getEventAdapterService().createAnonymousMapType(rowEventTypeName, rowTypeDef);

        // validate partition-by expressions, if any
        if (!matchRecognizeSpec.getPartitionByExpressions().isEmpty())
        {
            StreamTypeService typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.getEngineURI());
            List<ExprNode> validated = new ArrayList<ExprNode>();
            ExprValidationContext validationContext = new ExprValidationContext(typeServicePartition, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            for (ExprNode partitionExpr : matchRecognizeSpec.getPartitionByExpressions())
            {
                validated.add(ExprNodeUtility.getValidatedSubtree(partitionExpr, validationContext));
            }
            matchRecognizeSpec.setPartitionByExpressions(validated);
        }

        // validate interval if present
        if (matchRecognizeSpec.getInterval() != null) {
            ExprValidationContext validationContext = new ExprValidationContext(new StreamTypeServiceImpl(statementContext.getEngineURI(), false), statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
            matchRecognizeSpec.getInterval().validate(validationContext);
        }
    }
View Full Code Here

TOP

Related Classes of com.espertech.esper.core.service.StatementContext

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.