/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * 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.core.context.factory.StatementAgentInstanceFactoryUpdate; import com.espertech.esper.core.context.factory.StatementAgentInstanceFactoryUpdateResult; 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.service.*; import com.espertech.esper.core.service.resource.StatementResourceHolder; import com.espertech.esper.epl.core.StreamTypeService; import com.espertech.esper.epl.core.StreamTypeServiceImpl; import com.espertech.esper.epl.expression.core.*; import com.espertech.esper.epl.expression.subquery.ExprSubselectNode; import com.espertech.esper.epl.spec.*; import com.espertech.esper.util.StopCallback; import com.espertech.esper.view.ViewProcessingException; import com.espertech.esper.view.Viewable; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Starts and provides the stop method for EPL statements. */ public class EPStatementStartMethodUpdate extends EPStatementStartMethodBase { public EPStatementStartMethodUpdate(StatementSpecCompiled statementSpec) { super(statementSpec); } public EPStatementStartResult startInternal(final EPServicesContext services, final StatementContext statementContext, boolean isNewStatement, boolean isRecoveringStatement, boolean isRecoveringResilient) throws ExprValidationException, ViewProcessingException { // define stop and destroy final List<StopCallback> stopCallbacks = new LinkedList<StopCallback>(); EPStatementDestroyCallbackList destroyCallbacks = new EPStatementDestroyCallbackList(); // determine context final String contextName = statementSpec.getOptionalContextName(); if (contextName != null) { throw new ExprValidationException("Update IStream is not supported in conjunction with a context"); } // First we create streams for subselects, if there are any SubSelectActivationCollection subSelectStreamDesc = EPStatementStartMethodHelperSubselect.createSubSelectActivation(services, statementSpec, statementContext, destroyCallbacks); final StreamSpecCompiled streamSpec = statementSpec.getStreamSpecs()[0]; final UpdateDesc updateSpec = statementSpec.getUpdateSpec(); String triggereventTypeName; if (streamSpec instanceof FilterStreamSpecCompiled) { FilterStreamSpecCompiled filterStreamSpec = (FilterStreamSpecCompiled) streamSpec; triggereventTypeName = filterStreamSpec.getFilterSpec().getFilterForEventTypeName(); } else if (streamSpec instanceof NamedWindowConsumerStreamSpec) { NamedWindowConsumerStreamSpec namedSpec = (NamedWindowConsumerStreamSpec) streamSpec; triggereventTypeName = namedSpec.getWindowName(); } else if (streamSpec instanceof TableQueryStreamSpec) { throw new ExprValidationException("Tables cannot be used in an update-istream statement"); } else { throw new ExprValidationException("Unknown stream specification streamEventType: " + streamSpec); } // determine a stream name String streamName = triggereventTypeName; if (updateSpec.getOptionalStreamName() != null) { streamName = updateSpec.getOptionalStreamName(); } final EventType streamEventType = services.getEventAdapterService().getExistsTypeByName(triggereventTypeName); StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[]{streamEventType}, new String[]{streamName}, new boolean[]{true}, services.getEngineURI(), false); // determine subscriber result types ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); statementContext.getStatementResultService().setSelectClause(new Class[]{streamEventType.getUnderlyingType()}, new String[]{"*"}, false, null, evaluatorContextStmt); // Materialize sub-select views SubSelectStrategyCollection subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, isQueryPlanLogging(services), subSelectStreamDesc, new String[]{streamName}, new EventType[]{streamEventType}, new String[]{triggereventTypeName}, statementSpec.getDeclaredExpressions(), null); ExprValidationContext validationContext = new ExprValidationContext(typeService, statementContext.getEngineImportService(), statementContext.getStatementExtensionServicesContext(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), statementContext.getTableService(), evaluatorContextStmt, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor(), false, false, false, false, null, false); for (OnTriggerSetAssignment assignment : updateSpec.getAssignments()) { ExprNode validated = ExprNodeUtility.getValidatedAssignment(assignment, validationContext); assignment.setExpression(validated); EPStatementStartMethodHelperValidate.validateNoAggregations(validated, "Aggregation functions may not be used within an update-clause"); } if (updateSpec.getOptionalWhereClause() != null) { ExprNode validated = ExprNodeUtility.getValidatedSubtree(ExprNodeOrigin.WHERE, updateSpec.getOptionalWhereClause(), validationContext); updateSpec.setOptionalWhereClause(validated); EPStatementStartMethodHelperValidate.validateNoAggregations(validated, "Aggregation functions may not be used within an update-clause"); } // preprocessing view InternalRoutePreprocessView onExprView = new InternalRoutePreprocessView(streamEventType, statementContext.getStatementResultService()); // validation InternalEventRouterDesc routerDesc = services.getInternalEventRouter().getValidatePreprocessing(onExprView.getEventType(), updateSpec, statementContext.getAnnotations()); // create context factory StatementAgentInstanceFactoryUpdate contextFactory = new StatementAgentInstanceFactoryUpdate(statementContext, services, streamEventType, updateSpec, onExprView, routerDesc, subSelectStrategyCollection); statementContext.setStatementAgentInstanceFactory(contextFactory); // perform start of hook-up to start Viewable finalViewable; EPStatementStopMethod stopStatementMethod; Map<ExprSubselectNode, SubSelectStrategyHolder> subselectStrategyInstances; // With context - delegate instantiation to context final EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks); if (statementSpec.getOptionalContextName() != null) { // 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(null, null, null, null, null, null, null)); } ContextMergeView mergeView = new ContextMergeView(onExprView.getEventType()); finalViewable = mergeView; ContextManagedStatementOnTriggerDesc statement = new ContextManagedStatementOnTriggerDesc(statementSpec, statementContext, mergeView, contextFactory); services.getContextManagementService().addStatement(statementSpec.getOptionalContextName(), statement, isRecoveringResilient); stopStatementMethod = new EPStatementStopMethod() { public void stop() { services.getContextManagementService().stoppedStatement(contextName, statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getExpression(), statementContext.getExceptionHandlingService()); stopMethod.stop(); } }; destroyCallbacks.addCallback(new EPStatementDestroyCallbackContext(services.getContextManagementService(), statementSpec.getOptionalContextName(), statementContext.getStatementName(), statementContext.getStatementId())); } else { // Without context - start here AgentInstanceContext agentInstanceContext = getDefaultAgentInstanceContext(statementContext); final StatementAgentInstanceFactoryUpdateResult resultOfStart = (StatementAgentInstanceFactoryUpdateResult) contextFactory.newContext(agentInstanceContext, isRecoveringResilient); finalViewable = resultOfStart.getFinalView(); final StopCallback stopCallback = services.getEpStatementFactory().makeStopMethod(resultOfStart); stopStatementMethod = new EPStatementStopMethod() { public void stop() { stopCallback.stop(); stopMethod.stop(); } }; subselectStrategyInstances = resultOfStart.getSubselectStrategies(); if (statementContext.getStatementExtensionServicesContext() != null && statementContext.getStatementExtensionServicesContext().getStmtResources() != null) { StatementResourceHolder holder = statementContext.getStatementExtensionServicesContext().extractStatementResourceHolder(resultOfStart); statementContext.getStatementExtensionServicesContext().getStmtResources().setUnpartitioned(holder); statementContext.getStatementExtensionServicesContext().postProcessStart(resultOfStart, isRecoveringResilient); } } // assign subquery nodes EPStatementStartMethodHelperAssignExpr.assignSubqueryStrategies(subSelectStrategyCollection, subselectStrategyInstances); return new EPStatementStartResult(finalViewable, stopStatementMethod, destroyCallbacks); } }