{
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;
services.getStatementEventTypeRefService().addReferences(statementContext.getStatementName(), new String[] {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
// 2 - initial value before update
subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, isQueryPlanLogging(services), subSelectStreamDesc, new String[]{namedWindowName, streamSpec.getOptionalStreamName()}, new EventType[]{processor.getNamedWindowType(), activatorResultEventType}, new String[]{namedWindowTypeName, triggereventTypeName}, stopCallbacks, statementSpec.getAnnotations(), statementSpec.getDeclaredExpressions(), contextPropertyRegistry);
StreamTypeServiceImpl typeService = new StreamTypeServiceImpl(new EventType[] {namedWindowType, activatorResultEventType}, new String[] {namedWindowName, streamName}, new boolean[] {false, true}, services.getEngineURI(), true);
// allow "initial" as a prefix to properties
StreamTypeServiceImpl assignmentTypeService;
if (namedWindowName.equals(INITIAL_VALUE_STREAM_NAME) || streamName.equals(INITIAL_VALUE_STREAM_NAME)) {
assignmentTypeService = typeService;
}
else {
assignmentTypeService = new StreamTypeServiceImpl(new EventType[] {namedWindowType, activatorResultEventType, namedWindowType}, new String[] {namedWindowName, streamName, INITIAL_VALUE_STREAM_NAME}, new boolean[] {false, true, true}, services.getEngineURI(), false);
assignmentTypeService.setStreamZeroUnambigous(true);
}
if (onTriggerDesc instanceof OnTriggerWindowUpdateDesc) {
OnTriggerWindowUpdateDesc updateDesc = (OnTriggerWindowUpdateDesc) onTriggerDesc;
ExprValidationContext validationContext = new ExprValidationContext(assignmentTypeService, statementContext.getMethodResolutionService(), null, statementContext.getSchedulingService(), statementContext.getVariableService(), getDefaultAgentInstanceContext(statementContext), statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
for (OnTriggerSetAssignment assignment : updateDesc.getAssignments())
{
ExprNode validated = ExprNodeUtility.getValidatedAssignment(assignment, 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(services.getEngineURI(), statementContext, 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().length == 0) {
statementSpec.getSelectClauseSpec().setSelectExprList(new SelectClauseElementWildcard());
}
resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.getProcessorPrototype(
statementSpec, statementContext, typeService, null, new boolean[0], true, contextPropertyRegistry, null);
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), statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
// Materialize sub-select views
subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.planSubSelect(services, statementContext, isQueryPlanLogging(services), 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.getValidatedAssignment(assignment, 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().length > 0) || (statementSpec.getHavingExprRootNode() != null) || (statementSpec.getOrderByList().length > 0))
{
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, isQueryPlanLogging(services), subSelectStreamDesc, new String[]{streamSpec.getOptionalStreamName()}, new EventType[]{activatorResultEventType}, new String[]{triggereventTypeName}, stopCallbacks, statementSpec.getAnnotations(), statementSpec.getDeclaredExpressions(), contextPropertyRegistry);
EPStatementStartMethodHelperValidate.validateNodes(statementSpec, statementContext, typeService, null);
ResultSetProcessorFactoryDesc[] processorFactories = new ResultSetProcessorFactoryDesc[desc.getSplitStreams().size() + 1];
ExprNode[] whereClauses = new ExprNode[desc.getSplitStreams().size() + 1];
processorFactories[0] = ResultSetProcessorFactoryFactory.getProcessorPrototype(
statementSpec, statementContext, typeService, null, new boolean[0], false, contextPropertyRegistry, null);
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, statementContext, typeService, null, new boolean[0], false, contextPropertyRegistry, null);
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().setSelectExprList(new SelectClauseElementWildcard());
StreamTypeService streamTypeService = new StreamTypeServiceImpl(new EventType[] {outputEventType}, new String[] {"trigger_stream"}, new boolean[] {true}, services.getEngineURI(), false);
outputResultSetProcessorPrototype = ResultSetProcessorFactoryFactory.getProcessorPrototype(defaultSelectAllSpec, statementContext, streamTypeService, null, new boolean[0], true, contextPropertyRegistry, null);
}
EventType resultEventType = resultSetProcessorPrototype == null ? null : resultSetProcessorPrototype.getResultSetProcessorFactory().getResultEventType();
OutputProcessViewFactory outputViewFactory = OutputProcessViewFactoryFactory.make(statementSpec, services.getInternalEventRouter(), statementContext, resultEventType, null);
// 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
final EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);
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 (Map.Entry<ExprSubselectNode, SubSelectStrategyFactoryDesc> entry : subSelectStrategyCollection.getSubqueries().entrySet()) {
AIRegistrySubselect specificService = aiRegistryExpr.allocateSubselect(entry.getKey());
entry.getKey().setStrategy(specificService);
Map<ExprPriorNode, ExprPriorEvalStrategy> subselectPriorStrategies = new HashMap<ExprPriorNode, ExprPriorEvalStrategy>();
for (ExprPriorNode subselectPrior : entry.getValue().getPriorNodesList()) {