Package com.espertech.esper.core.start

Source Code of com.espertech.esper.core.start.EPStatementStartMethodOnTrigger

/**************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
* http://esper.codehaus.org                                                          *
* http://www.espertech.com                                                           *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license       *
* a copy of which has been included with this distribution in the license.txt file.  *
**************************************************************************************/
package com.espertech.esper.core.start;

import com.espertech.esper.client.EventType;
import com.espertech.esper.client.VariableValueException;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.core.context.activator.ViewableActivator;
import com.espertech.esper.core.context.activator.ViewableActivatorFilterProxy;
import com.espertech.esper.core.context.activator.ViewableActivatorNamedWindow;
import com.espertech.esper.core.context.activator.ViewableActivatorPattern;
import com.espertech.esper.core.context.factory.StatementAgentInstanceFactoryOnTrigger;
import com.espertech.esper.core.context.factory.StatementAgentInstanceFactoryOnTriggerResult;
import com.espertech.esper.core.context.factory.StatementAgentInstanceFactoryOnTriggerSplitDesc;
import com.espertech.esper.core.context.mgr.ContextManagedStatementOnTriggerDesc;
import com.espertech.esper.core.context.stmt.AIRegistryExpr;
import com.espertech.esper.core.context.stmt.AIRegistrySubselect;
import com.espertech.esper.core.context.subselect.SubSelectActivationCollection;
import com.espertech.esper.core.context.subselect.SubSelectStrategyCollection;
import com.espertech.esper.core.context.subselect.SubSelectStrategyHolder;
import com.espertech.esper.core.context.util.AgentInstanceContext;
import com.espertech.esper.core.context.util.ContextMergeView;
import com.espertech.esper.core.context.util.ContextPropertyRegistry;
import com.espertech.esper.core.service.*;
import com.espertech.esper.epl.agg.AggregationService;
import com.espertech.esper.epl.core.ResultSetProcessorFactoryDesc;
import com.espertech.esper.epl.core.ResultSetProcessorFactoryFactory;
import com.espertech.esper.epl.core.StreamTypeService;
import com.espertech.esper.epl.core.StreamTypeServiceImpl;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.epl.metric.StatementMetricHandle;
import com.espertech.esper.epl.named.NamedWindowOnExprFactory;
import com.espertech.esper.epl.named.NamedWindowOnExprFactoryFactory;
import com.espertech.esper.epl.named.NamedWindowProcessor;
import com.espertech.esper.epl.spec.*;
import com.espertech.esper.epl.variable.OnSetVariableViewFactory;
import com.espertech.esper.epl.view.OutputProcessViewFactory;
import com.espertech.esper.epl.view.OutputProcessViewFactoryFactory;
import com.espertech.esper.event.EventTypeMetadata;
import com.espertech.esper.event.map.MapEventType;
import com.espertech.esper.pattern.EvalRootFactoryNode;
import com.espertech.esper.pattern.PatternContext;
import com.espertech.esper.util.StopCallback;
import com.espertech.esper.util.UuidGenerator;
import com.espertech.esper.view.ViewProcessingException;
import com.espertech.esper.view.Viewable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
* Starts and provides the stop method for EPL statements.
*/
public class EPStatementStartMethodOnTrigger extends EPStatementStartMethodBase
{
    private static final Log log = LogFactory.getLog(EPStatementStartMethodOnTrigger.class);

    public EPStatementStartMethodOnTrigger(StatementSpecCompiled statementSpec, EPServicesContext services, StatementContext statementContext) {
        super(statementSpec, services, statementContext);
    }

    public EPStatementStartResult startInternal(boolean isNewStatement, boolean isRecoveringStatement, boolean isRecoveringResilient) throws ExprValidationException, ViewProcessingException {
        // define stop
        final List<StopCallback> stopCallbacks = new LinkedList<StopCallback>();
        final EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);

        // determine context
        final String contextName = statementSpec.getOptionalContextName();
        final ContextPropertyRegistry contextPropertyRegistry = (contextName != null) ? services.getContextManagementService().getContextDescriptor(contextName).getContextPropertyRegistry() : null;

        // create subselect information
        SubSelectActivationCollection subSelectStreamDesc = EPStatementStartMethodHelperSubselect.createSubSelectActivation(services, statementSpec, statementContext);

        // obtain activator
        final StreamSpecCompiled streamSpec = statementSpec.getStreamSpecs().get(0);
        ViewableActivator activator;
        String triggereventTypeName = null;
        EventType activatorResultEventType;
        if (streamSpec instanceof FilterStreamSpecCompiled)
        {
            FilterStreamSpecCompiled filterStreamSpec = (FilterStreamSpecCompiled) streamSpec;
            triggereventTypeName = filterStreamSpec.getFilterSpec().getFilterForEventTypeName();
            activator = new ViewableActivatorFilterProxy(services, filterStreamSpec.getFilterSpec(), statementContext.getAnnotations(), false);
            activatorResultEventType = filterStreamSpec.getFilterSpec().getResultEventType();
        }
        else if (streamSpec instanceof PatternStreamSpecCompiled)
        {
            PatternStreamSpecCompiled patternStreamSpec = (PatternStreamSpecCompiled) streamSpec;
            boolean usedByChildViews = !streamSpec.getViewSpecs().isEmpty() || (statementSpec.getInsertIntoDesc() != null);
            String patternTypeName = statementContext.getStatementId() + "_patternon";
            final EventType eventType = services.getEventAdapterService().createSemiAnonymousMapType(patternTypeName, patternStreamSpec.getTaggedEventTypes(), patternStreamSpec.getArrayEventTypes(), usedByChildViews);

            EvalRootFactoryNode rootNode = services.getPatternNodeFactory().makeRootNode();
            rootNode.addChildNode(patternStreamSpec.getEvalFactoryNode());
            PatternContext patternContext = statementContext.getPatternContextFactory().createContext(statementContext, 0, rootNode, !patternStreamSpec.getArrayEventTypes().isEmpty());
            activator = new ViewableActivatorPattern(patternContext, rootNode, eventType, EPStatementStartMethodHelperUtil.isConsumingFilters(patternStreamSpec.getEvalFactoryNode()));
            activatorResultEventType = eventType;
        }
        else if (streamSpec instanceof NamedWindowConsumerStreamSpec)
        {
            NamedWindowConsumerStreamSpec namedSpec = (NamedWindowConsumerStreamSpec) streamSpec;
            NamedWindowProcessor processor = services.getNamedWindowService().getProcessor(namedSpec.getWindowName());
            if (processor == null) {
                throw new ExprValidationException("A named window by name '" + namedSpec.getWindowName() + "' does not exist");
            }
            triggereventTypeName = namedSpec.getWindowName();
            activator = new ViewableActivatorNamedWindow(processor, namedSpec.getFilterExpressions(), namedSpec.getOptPropertyEvaluator());
            activatorResultEventType = processor.getNamedWindowType();
            if (namedSpec.getOptPropertyEvaluator() != null) {
                activatorResultEventType = namedSpec.getOptPropertyEvaluator().getFragmentEventType();
            }
        }
        else
        {
            throw new ExprValidationException("Unknown stream specification type: " + streamSpec);
        }

        // validation
        SubSelectStrategyCollection subSelectStrategyCollection;
        ResultSetProcessorFactoryDesc resultSetProcessorPrototype = null;
        ExprNode validatedJoin = null;
        StatementAgentInstanceFactoryOnTriggerSplitDesc splitDesc = null;
        ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype = null;
        EventType outputEventType = null;
        OnSetVariableViewFactory onSetVariableViewFactory = null;
        NamedWindowOnExprFactory onExprFactory = null;

        // validation: For on-delete and on-select and on-update triggers
        if (statementSpec.getOnTriggerDesc() instanceof OnTriggerWindowDesc)
        {
            // Determine event types
            OnTriggerWindowDesc onTriggerDesc = (OnTriggerWindowDesc) statementSpec.getOnTriggerDesc();
            NamedWindowProcessor processor = services.getNamedWindowService().getProcessor(onTriggerDesc.getWindowName());
            if (processor == null) {
                throw new ExprValidationException("A named window by name '" + onTriggerDesc.getWindowName() + "' does not exist");
            }

            // validate context
            processor.validateOnExpressionContext(contextName);

            EventType namedWindowType = processor.getNamedWindowType();
            outputEventType = namedWindowType;
            statementContext.getDynamicReferenceEventTypes().add(onTriggerDesc.getWindowName());

            String namedWindowName = onTriggerDesc.getOptionalAsName();
            if (namedWindowName == null)
            {
                namedWindowName = "stream_0";
            }
            String streamName = streamSpec.getOptionalStreamName();
            if (streamName == null)
            {
                streamName = "stream_1";
            }
            String namedWindowTypeName = onTriggerDesc.getWindowName();

            // Materialize sub-select views
            // 0 - named window stream
            // 1 - arriving stream
            subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, new String[]{namedWindowName, streamSpec.getOptionalStreamName()}, new EventType[]{processor.getNamedWindowType(), activatorResultEventType}, new String[]{namedWindowTypeName, triggereventTypeName}, stopCallbacks, statementSpec.getAnnotations(), statementSpec.getDeclaredExpressions(), contextPropertyRegistry);

            StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] {namedWindowType, activatorResultEventType}, new String[] {namedWindowName, streamName}, new boolean[] {false, true}, services.getEngineURI(), false);
            if (onTriggerDesc instanceof OnTriggerWindowUpdateDesc) {
                OnTriggerWindowUpdateDesc updateDesc = (OnTriggerWindowUpdateDesc) onTriggerDesc;
                ExprValidationContext validationContext = new ExprValidationContext(typeService, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), getDefaultAgentInstanceContext(), statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                for (OnTriggerSetAssignment assignment : updateDesc.getAssignments())
                {
                    ExprNode validated = ExprNodeUtility.getValidatedSubtree(assignment.getExpression(), validationContext);
                    assignment.setExpression(validated);
                    EPStatementStartMethodHelperValidate.validateNoAggregations(validated, "Aggregation functions may not be used within an on-update-clause");
                }
            }
            if (onTriggerDesc instanceof OnTriggerMergeDesc) {
                OnTriggerMergeDesc mergeDesc = (OnTriggerMergeDesc) onTriggerDesc;
                validateMergeDesc(mergeDesc, statementContext, processor.getNamedWindowType(), namedWindowName,  activatorResultEventType, streamName);
            }

            // validate join expression
            validatedJoin = validateJoinNamedWindow(statementSpec.getFilterRootNode(),
                    namedWindowType, namedWindowName, namedWindowTypeName,
                    activatorResultEventType, streamName, triggereventTypeName);

            // validate filter, output rate limiting
            EPStatementStartMethodHelperValidate.validateNodes(statementSpec, statementContext, typeService, null);

            // Construct a processor for results; for use in on-select to process selection results
            // Use a wildcard select if the select-clause is empty, such as for on-delete.
            // For on-select the select clause is not empty.
            if (statementSpec.getSelectClauseSpec().getSelectExprList().size() == 0) {
                statementSpec.getSelectClauseSpec().add(new SelectClauseElementWildcard());
            }
            AgentInstanceContext agentInstanceContext = getDefaultAgentInstanceContext();
            resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.getProcessorPrototype(
                    statementSpec, agentInstanceContext, typeService, null, new boolean[0], true, contextPropertyRegistry);


            InternalEventRouter routerService = null;
            boolean addToFront = false;
            if (statementSpec.getInsertIntoDesc() != null || onTriggerDesc instanceof OnTriggerMergeDesc) {
                routerService = services.getInternalEventRouter();
            }
            if (statementSpec.getInsertIntoDesc() != null) {
                addToFront = statementContext.getNamedWindowService().isNamedWindow(statementSpec.getInsertIntoDesc().getEventTypeName());
            }
            boolean isDistinct = statementSpec.getSelectClauseSpec().isDistinct();
            EventType selectResultEventType = resultSetProcessorPrototype.getResultSetProcessorFactory().getResultEventType();
            StatementMetricHandle createNamedWindowMetricsHandle = processor.getCreateNamedWindowMetricsHandle();

            onExprFactory = NamedWindowOnExprFactoryFactory.make(namedWindowType, onTriggerDesc.getWindowName(), namedWindowName,
                    onTriggerDesc,
                    activatorResultEventType, streamSpec.getOptionalStreamName(), addToFront, routerService,
                    selectResultEventType,
                    statementContext, createNamedWindowMetricsHandle, isDistinct);
        }
        // variable assignments
        else if (statementSpec.getOnTriggerDesc() instanceof OnTriggerSetDesc)
        {
            OnTriggerSetDesc desc = (OnTriggerSetDesc) statementSpec.getOnTriggerDesc();
            StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] {activatorResultEventType}, new String[] {streamSpec.getOptionalStreamName()}, new boolean[] {true}, services.getEngineURI(), false);
            ExprValidationContext validationContext = new ExprValidationContext(typeService, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), getDefaultAgentInstanceContext(), statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());

            // Materialize sub-select views
            subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, new String[]{streamSpec.getOptionalStreamName()}, new EventType[]{activatorResultEventType}, new String[]{triggereventTypeName}, stopCallbacks, statementSpec.getAnnotations(), statementSpec.getDeclaredExpressions(), contextPropertyRegistry);

            for (OnTriggerSetAssignment assignment : desc.getAssignments()) {
                ExprNode validated = ExprNodeUtility.getValidatedSubtree(assignment.getExpression(), validationContext);
                assignment.setExpression(validated);
            }

            try {
                ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
                onSetVariableViewFactory = new OnSetVariableViewFactory(statementContext.getStatementId(), desc, statementContext.getEventAdapterService(), statementContext.getVariableService(), statementContext.getStatementResultService(), exprEvaluatorContext);
            }
            catch (VariableValueException ex) {
                throw new ExprValidationException("Error in variable assignment: " + ex.getMessage(), ex);
            }

            outputEventType = onSetVariableViewFactory.getEventType();
        }
        // split-stream use case
        else
        {
            OnTriggerSplitStreamDesc desc = (OnTriggerSplitStreamDesc) statementSpec.getOnTriggerDesc();
            String streamName = streamSpec.getOptionalStreamName();
            if (streamName == null)
            {
                streamName = "stream_0";
            }
            StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] {activatorResultEventType}, new String[] {streamName}, new boolean[] {true}, services.getEngineURI(), false);
            if (statementSpec.getInsertIntoDesc() == null)
            {
                throw new ExprValidationException("Required insert-into clause is not provided, the clause is required for split-stream syntax");
            }
            if ((!statementSpec.getGroupByExpressions().isEmpty()) || (statementSpec.getHavingExprRootNode() != null) || (!statementSpec.getOrderByList().isEmpty()))
            {
                throw new ExprValidationException("A group-by clause, having-clause or order-by clause is not allowed for the split stream syntax");
            }

            // Materialize sub-select views
            subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, new String[]{streamSpec.getOptionalStreamName()}, new EventType[]{activatorResultEventType}, new String[]{triggereventTypeName}, stopCallbacks, statementSpec.getAnnotations(), statementSpec.getDeclaredExpressions(), contextPropertyRegistry);

            EPStatementStartMethodHelperValidate.validateNodes(statementSpec, statementContext, typeService, null);

            AgentInstanceContext agentInstanceContext = getDefaultAgentInstanceContext();
            ResultSetProcessorFactoryDesc[] processorFactories = new ResultSetProcessorFactoryDesc[desc.getSplitStreams().size() + 1];
            ExprNode[] whereClauses = new ExprNode[desc.getSplitStreams().size() + 1];
            processorFactories[0] = ResultSetProcessorFactoryFactory.getProcessorPrototype(
                    statementSpec, agentInstanceContext, typeService, null, new boolean[0], false, contextPropertyRegistry);
            whereClauses[0] = statementSpec.getFilterRootNode();
            boolean[] isNamedWindowInsert = new boolean[desc.getSplitStreams().size() + 1];
            isNamedWindowInsert[0] = false;

            int index = 1;
            for (OnTriggerSplitStream splits : desc.getSplitStreams())
            {
                StatementSpecCompiled splitSpec = new StatementSpecCompiled();
                splitSpec.setInsertIntoDesc(splits.getInsertInto());
                splitSpec.setSelectClauseSpec(StatementLifecycleSvcImpl.compileSelectAllowSubselect(splits.getSelectClause()));
                splitSpec.setFilterExprRootNode(splits.getWhereClause());
                EPStatementStartMethodHelperValidate.validateNodes(splitSpec, statementContext, typeService, null);

                processorFactories[index] = ResultSetProcessorFactoryFactory.getProcessorPrototype(
                        splitSpec, agentInstanceContext, typeService, null, new boolean[0], false, contextPropertyRegistry);
                whereClauses[index] = splitSpec.getFilterRootNode();
                isNamedWindowInsert[index] = statementContext.getNamedWindowService().isNamedWindow(splits.getInsertInto().getEventTypeName());

                index++;
            }

            splitDesc = new StatementAgentInstanceFactoryOnTriggerSplitDesc(processorFactories, whereClauses, isNamedWindowInsert);
        }

        // For on-delete/set/update/merge, create an output processor that passes on as a wildcard the underlying event
        if ((statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_DELETE) ||
            (statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_SET) ||
            (statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_UPDATE) ||
            (statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_MERGE))
        {
            StatementSpecCompiled defaultSelectAllSpec = new StatementSpecCompiled();
            defaultSelectAllSpec.getSelectClauseSpec().add(new SelectClauseElementWildcard());

            StreamTypeService streamTypeService = new StreamTypeServiceImpl(new EventType[] {outputEventType}, new String[] {"trigger_stream"}, new boolean[] {true}, services.getEngineURI(), false);
            outputResultSetProcessorPrototype = ResultSetProcessorFactoryFactory.getProcessorPrototype(defaultSelectAllSpec, getDefaultAgentInstanceContext(), streamTypeService, null, new boolean[0], true, contextPropertyRegistry);
        }

        EventType resultEventType = resultSetProcessorPrototype == null ? null : resultSetProcessorPrototype.getResultSetProcessorFactory().getResultEventType();
        OutputProcessViewFactory outputViewFactory = OutputProcessViewFactoryFactory.make(statementSpec, services.getInternalEventRouter(), statementContext, resultEventType);

        // create context factory
        StatementAgentInstanceFactoryOnTrigger contextFactory = new StatementAgentInstanceFactoryOnTrigger(statementContext, statementSpec, services, activator, subSelectStrategyCollection, resultSetProcessorPrototype, validatedJoin, activatorResultEventType, splitDesc, outputResultSetProcessorPrototype, onSetVariableViewFactory, onExprFactory, outputViewFactory, isRecoveringStatement);

        // perform start of hook-up to start
        Viewable finalViewable;
        EPStatementStopMethod stopStatementMethod;
        EPStatementDestroyMethod destroyStatementMethod;
        Map<ExprSubselectNode, SubSelectStrategyHolder> subselectStrategyInstances;
        AggregationService aggregationService;

        // With context - delegate instantiation to context
        if (statementSpec.getOptionalContextName() != null) {

            // use statement-wide agent-instance-specific aggregation service
            aggregationService = statementContext.getStatementAgentInstanceRegistry().getAgentInstanceAggregationService();

            // use statement-wide agent-instance-specific subselects
            AIRegistryExpr aiRegistryExpr = statementContext.getStatementAgentInstanceRegistry().getAgentInstanceExprService();
            subselectStrategyInstances = new HashMap<ExprSubselectNode, SubSelectStrategyHolder>();
            for (ExprSubselectNode node : subSelectStrategyCollection.getSubqueries().keySet()) {
                AIRegistrySubselect specificService = aiRegistryExpr.allocateSubselect(node);
                node.setStrategy(specificService);
                subselectStrategyInstances.put(node, new SubSelectStrategyHolder(specificService, null, null, null));
            }

            ContextMergeView mergeView = new ContextMergeView(resultSetProcessorPrototype.getResultSetProcessorFactory().getResultEventType());
            finalViewable = mergeView;

            ContextManagedStatementOnTriggerDesc statement = new ContextManagedStatementOnTriggerDesc(statementSpec, statementContext, mergeView, contextFactory);
            services.getContextManagementService().addStatement(contextName, statement);
            stopStatementMethod = new EPStatementStopMethod(){
                public void stop()
                {
                    services.getContextManagementService().stoppedStatement(contextName, statementContext.getStatementName(), statementContext.getStatementId());
                    stopMethod.stop();
                }
            };

            destroyStatementMethod = new EPStatementDestroyMethod(){
                public void destroy() {
                    services.getContextManagementService().destroyedStatement(contextName, statementContext.getStatementName(), statementContext.getStatementId());
                }
            };
        }
        // Without context - start here
        else {
            AgentInstanceContext agentInstanceContext = getDefaultAgentInstanceContext();
            final StatementAgentInstanceFactoryOnTriggerResult resultOfStart = contextFactory.newContext(agentInstanceContext);
            finalViewable = resultOfStart.getFinalView();
            stopStatementMethod = new EPStatementStopMethod() {
                public void stop() {
                    resultOfStart.getStopCallback().stop();
                    stopMethod.stop();
                }
            };
            destroyStatementMethod = null;
            aggregationService = resultOfStart.getOptionalAggegationService();
            subselectStrategyInstances = resultOfStart.getSubselectStrategies();
        }

        // initialize aggregation expression nodes
        if (resultSetProcessorPrototype != null && resultSetProcessorPrototype.getAggregationServiceFactoryDesc() != null) {
            EPStatementStartMethodHelperAssignExpr.assignAggregations(aggregationService, resultSetProcessorPrototype.getAggregationServiceFactoryDesc().getExpressions());
        }

        // assign subquery nodes
        EPStatementStartMethodHelperAssignExpr.assignSubqueryStrategies(subSelectStrategyCollection, subselectStrategyInstances);       

        return new EPStatementStartResult(finalViewable, stopStatementMethod, destroyStatementMethod);
    }

    private void validateMergeDesc(OnTriggerMergeDesc mergeDesc, StatementContext statementContext, EventType namedWindowType, String namedWindowName, EventType triggerStreamType, String triggerStreamName)
        throws ExprValidationException
    {
        String exprNodeErrorMessage = "Aggregation functions may not be used within an merge-clause";
        ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext);

        for (OnTriggerMergeMatched matchedItem : mergeDesc.getItems()) {

            EventType dummyTypeNoProperties = new MapEventType(EventTypeMetadata.createAnonymous("merge_named_window_insert"), "merge_named_window_insert", 0, null, Collections.<String, Object>emptyMap(), null, null, null);
            StreamTypeService twoStreamTypeSvc = new StreamTypeServiceImpl(new EventType[] {namedWindowType, triggerStreamType},
                    new String[] {namedWindowName, triggerStreamName}, new boolean[] {true, true}, statementContext.getEngineURI(), false);
            StreamTypeService insertOnlyTypeSvc = new StreamTypeServiceImpl(new EventType[] {dummyTypeNoProperties, triggerStreamType},
                    new String[] {UuidGenerator.generate(), triggerStreamName}, new boolean[] {true, true}, statementContext.getEngineURI(), false);


            if (matchedItem.getOptionalMatchCond() != null) {
                StreamTypeService matchValidStreams = matchedItem.isMatchedUnmatched() ? twoStreamTypeSvc : insertOnlyTypeSvc;
                matchedItem.setOptionalMatchCond(EPStatementStartMethodHelperValidate.validateExprNoAgg(matchedItem.getOptionalMatchCond(), matchValidStreams, statementContext, evaluatorContextStmt, exprNodeErrorMessage));
                if (!matchedItem.isMatchedUnmatched()) {
                    EPStatementStartMethodHelperValidate.validateSubqueryExcludeOuterStream(matchedItem.getOptionalMatchCond());
                }
            }

            for (OnTriggerMergeAction item : matchedItem.getActions()) {
                if (item instanceof OnTriggerMergeActionDelete) {
                    OnTriggerMergeActionDelete delete = (OnTriggerMergeActionDelete) item;
                    if (delete.getOptionalWhereClause() != null) {
                        delete.setOptionalWhereClause(EPStatementStartMethodHelperValidate.validateExprNoAgg(delete.getOptionalWhereClause(), twoStreamTypeSvc, statementContext, evaluatorContextStmt, exprNodeErrorMessage));
                    }
                }
                else if (item instanceof OnTriggerMergeActionUpdate) {
                    OnTriggerMergeActionUpdate update = (OnTriggerMergeActionUpdate) item;
                    if (update.getOptionalWhereClause() != null) {
                        update.setOptionalWhereClause(EPStatementStartMethodHelperValidate.validateExprNoAgg(update.getOptionalWhereClause(), twoStreamTypeSvc, statementContext, evaluatorContextStmt, exprNodeErrorMessage));
                    }
                    for (OnTriggerSetAssignment assignment : update.getAssignments())
                    {
                        assignment.setExpression(EPStatementStartMethodHelperValidate.validateExprNoAgg(assignment.getExpression(), twoStreamTypeSvc, statementContext, evaluatorContextStmt, exprNodeErrorMessage));
                    }
                }
                else if (item instanceof OnTriggerMergeActionInsert) {
                    OnTriggerMergeActionInsert insert = (OnTriggerMergeActionInsert) item;

                    StreamTypeService insertTypeSvc;
                    if (insert.getOptionalStreamName() == null || insert.getOptionalStreamName().equals(namedWindowName)) {
                        insertTypeSvc = insertOnlyTypeSvc;
                    }
                    else {
                        insertTypeSvc = twoStreamTypeSvc;
                    }

                    List<SelectClauseElementCompiled> compiledSelect = new ArrayList<SelectClauseElementCompiled>();
                    if (insert.getOptionalWhereClause() != null) {
                        insert.setOptionalWhereClause(EPStatementStartMethodHelperValidate.validateExprNoAgg(insert.getOptionalWhereClause(), insertTypeSvc, statementContext, evaluatorContextStmt, exprNodeErrorMessage));
                    }
                    int colIndex = 0;
                    for (SelectClauseElementRaw raw : insert.getSelectClause())
                    {
                        if (raw instanceof SelectClauseStreamRawSpec)
                        {
                            SelectClauseStreamRawSpec rawStreamSpec = (SelectClauseStreamRawSpec) raw;
                            Integer foundStreamNum = null;
                            for (int s = 0; s < insertTypeSvc.getStreamNames().length; s++) {
                                if (rawStreamSpec.getStreamName().equals(insertTypeSvc.getStreamNames()[s])) {
                                    foundStreamNum = s;
                                    break;
                                }
                            }
                            if (foundStreamNum == null) {
                                throw new ExprValidationException("Stream by name '" + rawStreamSpec.getStreamName() + "' was not found");
                            }
                            SelectClauseStreamCompiledSpec streamSelectSpec = new SelectClauseStreamCompiledSpec(rawStreamSpec.getStreamName(), rawStreamSpec.getOptionalAsName());
                            streamSelectSpec.setStreamNumber(foundStreamNum);
                            compiledSelect.add(streamSelectSpec);
                        }
                        else if (raw instanceof SelectClauseExprRawSpec)
                        {
                            SelectClauseExprRawSpec exprSpec = (SelectClauseExprRawSpec) raw;
                            ExprValidationContext validationContext = new ExprValidationContext(insertTypeSvc, statementContext.getMethodResolutionService(), null, statementContext.getTimeProvider(), statementContext.getVariableService(), evaluatorContextStmt, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
                            ExprNode exprCompiled = ExprNodeUtility.getValidatedSubtree(exprSpec.getSelectExpression(), validationContext);
                            String resultName = exprSpec.getOptionalAsName();
                            if (resultName == null)
                            {
                                if (insert.getColumns().size() > colIndex) {
                                    resultName = insert.getColumns().get(colIndex);
                                }
                                else {
                                    resultName = exprCompiled.toExpressionString();
                                }
                            }
                            compiledSelect.add(new SelectClauseExprCompiledSpec(exprCompiled, resultName, exprSpec.getOptionalAsName()));
                            EPStatementStartMethodHelperValidate.validateNoAggregations(exprCompiled, "Expression in a merge-selection may not utilize aggregation functions");
                        }
                        else if (raw instanceof SelectClauseElementWildcard)
                        {
                            compiledSelect.add(new SelectClauseElementWildcard());
                        }
                        else
                        {
                            throw new IllegalStateException("Unknown select clause item:" + raw);
                        }
                        colIndex++;
                    }
                    insert.setSelectClauseCompiled(compiledSelect);
                }
                else {
                    throw new IllegalArgumentException("Unrecognized merge item '" + item.getClass().getName() + "'");
                }
            }
        }
    }

    // For delete actions from named windows
    protected ExprNode validateJoinNamedWindow(ExprNode deleteJoinExpr,
                                         EventType namedWindowType,
                                         String namedWindowStreamName,
                                         String namedWindowName,
                                         EventType filteredType,
                                         String filterStreamName,
                                         String filteredTypeName) throws ExprValidationException
    {
        if (deleteJoinExpr == null)
        {
            return null;
        }

        LinkedHashMap<String, Pair<EventType, String>> namesAndTypes = new LinkedHashMap<String, Pair<EventType, String>>();
        namesAndTypes.put(namedWindowStreamName, new Pair<EventType, String>(namedWindowType, namedWindowName));
        namesAndTypes.put(filterStreamName, new Pair<EventType, String>(filteredType, filteredTypeName));
        StreamTypeService typeService = new StreamTypeServiceImpl(namesAndTypes, services.getEngineURI(), false, false);

        ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext);
        ExprValidationContext validationContext = new ExprValidationContext(typeService, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), evaluatorContextStmt, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
        return ExprNodeUtility.getValidatedSubtree(deleteJoinExpr, validationContext);
    }
}
TOP

Related Classes of com.espertech.esper.core.start.EPStatementStartMethodOnTrigger

TOP
Copyright © 2018 www.massapi.com. 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.