/* *************************************************************************************** * 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.context.factory; import com.espertech.esper.client.EventType; import com.espertech.esper.collection.Pair; import com.espertech.esper.core.context.activator.ViewableActivator; import com.espertech.esper.core.context.subselect.SubSelectStrategyCollection; import com.espertech.esper.core.context.util.AgentInstanceContext; import com.espertech.esper.core.service.EPServicesContext; import com.espertech.esper.core.service.StatementContext; import com.espertech.esper.core.start.EPStatementStartMethodHelperUtil; import com.espertech.esper.epl.agg.service.AggregationService; import com.espertech.esper.epl.core.ResultSetProcessor; import com.espertech.esper.epl.core.ResultSetProcessorFactoryDesc; import com.espertech.esper.epl.expression.core.ExprNode; import com.espertech.esper.epl.expression.core.ExprValidationException; import com.espertech.esper.epl.join.hint.ExcludePlanHint; import com.espertech.esper.epl.join.hint.IndexHint; import com.espertech.esper.epl.join.table.EventTable; import com.espertech.esper.epl.lookup.SubordWMatchExprLookupStrategy; import com.espertech.esper.epl.lookup.SubordinateQueryPlanner; import com.espertech.esper.epl.lookup.SubordinateQueryPlannerUtil; import com.espertech.esper.epl.lookup.SubordinateWMatchExprQueryPlanResult; import com.espertech.esper.epl.named.*; import com.espertech.esper.epl.spec.OnTriggerType; import com.espertech.esper.epl.spec.OnTriggerWindowDesc; import com.espertech.esper.epl.spec.StatementSpecCompiled; import com.espertech.esper.epl.view.OutputProcessViewFactory; import com.espertech.esper.util.StopCallback; import com.espertech.esper.view.View; import java.util.List; public class StatementAgentInstanceFactoryOnTriggerNamedWindow extends StatementAgentInstanceFactoryOnTriggerBase { private final ResultSetProcessorFactoryDesc resultSetProcessorPrototype; private final ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype; private final NamedWindowOnExprFactory onExprFactory; private final OutputProcessViewFactory outputProcessViewFactory; private final NamedWindowProcessor processor; private final SubordinateWMatchExprQueryPlanResult queryPlan; public StatementAgentInstanceFactoryOnTriggerNamedWindow(final StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection, ResultSetProcessorFactoryDesc resultSetProcessorPrototype, ExprNode validatedJoin, ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype, NamedWindowOnExprFactory onExprFactory, OutputProcessViewFactory outputProcessViewFactory, EventType activatorResultEventType, final NamedWindowProcessor processor, List<StopCallback> stopCallbacks) throws ExprValidationException { super(statementContext, statementSpec, services, activator, subSelectStrategyCollection); this.resultSetProcessorPrototype = resultSetProcessorPrototype; this.outputResultSetProcessorPrototype = outputResultSetProcessorPrototype; this.onExprFactory = onExprFactory; this.outputProcessViewFactory = outputProcessViewFactory; this.processor = processor; IndexHintPair pair = getIndexHintPair(statementContext, statementSpec); IndexHint indexHint = pair.getIndexHint(); ExcludePlanHint excludePlanHint = pair.getExcludePlanHint(); queryPlan = SubordinateQueryPlanner.planOnExpression( validatedJoin, activatorResultEventType, indexHint, processor.isEnableSubqueryIndexShare(), -1, excludePlanHint, processor.isVirtualDataWindow(), processor.getEventTableIndexMetadataRepo(), processor.getNamedWindowType(), processor.getOptionalUniqueKeyProps(), false, statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations()); if (queryPlan.getIndexDescs() != null) { SubordinateQueryPlannerUtil.addIndexMetaAndRef(queryPlan.getIndexDescs(), processor.getEventTableIndexMetadataRepo(), statementContext.getStatementName()); stopCallbacks.add(new StopCallback() { public void stop() { for (int i = 0; i < queryPlan.getIndexDescs().length; i++) { boolean last = processor.getEventTableIndexMetadataRepo().removeIndexReference(queryPlan.getIndexDescs()[i].getIndexMultiKey(), statementContext.getStatementName()); if (last) { processor.getEventTableIndexMetadataRepo().removeIndex(queryPlan.getIndexDescs()[i].getIndexMultiKey()); processor.removeAllInstanceIndexes(queryPlan.getIndexDescs()[i].getIndexMultiKey()); } } } }); } SubordinateQueryPlannerUtil.queryPlanLogOnExpr(processor.getRootView().isQueryPlanLogging(), NamedWindowRootView.getQueryPlanLog(), queryPlan, statementContext.getAnnotations(), statementContext.getEngineImportService()); } public OnExprViewResult determineOnExprView(AgentInstanceContext agentInstanceContext, List<StopCallback> stopCallbacks, boolean isRecoveringReslient) { // get result set processor and aggregation services Pair<ResultSetProcessor, AggregationService> pair = EPStatementStartMethodHelperUtil.startResultSetAndAggregation(resultSetProcessorPrototype, agentInstanceContext, false, null); // get named window processor instance NamedWindowProcessorInstance processorInstance = processor.getProcessorInstance(agentInstanceContext); // obtain on-expr view EventTable[] indexes = null; if (queryPlan.getIndexDescs() != null) { indexes = SubordinateQueryPlannerUtil.realizeTables(queryPlan.getIndexDescs(), processor.getNamedWindowType(), processorInstance.getRootViewInstance().getIndexRepository(), processorInstance.getRootViewInstance().getDataWindowContents(), processorInstance.getTailViewInstance().getAgentInstanceContext(), isRecoveringReslient); } SubordWMatchExprLookupStrategy strategy = queryPlan.getFactory().realize(indexes, agentInstanceContext, processorInstance.getRootViewInstance().getDataWindowContents(), processorInstance.getRootViewInstance().getVirtualDataWindow()); NamedWindowOnExprBaseView onExprBaseView = onExprFactory.make(strategy, processorInstance.getRootViewInstance(), agentInstanceContext, pair.getFirst()); return new OnExprViewResult(onExprBaseView, pair.getSecond()); } public void assignExpressions(StatementAgentInstanceFactoryResult result) { } public void unassignExpressions() { } public View determineFinalOutputView(AgentInstanceContext agentInstanceContext, View onExprView) { if ((statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_DELETE) || (statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_UPDATE) || (statementSpec.getOnTriggerDesc().getOnTriggerType() == OnTriggerType.ON_MERGE)) { ResultSetProcessor outputResultSetProcessor = outputResultSetProcessorPrototype.getResultSetProcessorFactory().instantiate(null, null, agentInstanceContext); View outputView = outputProcessViewFactory.makeView(outputResultSetProcessor, agentInstanceContext); onExprView.addView(outputView); return outputView; } return onExprView; } protected static IndexHintPair getIndexHintPair(StatementContext statementContext, StatementSpecCompiled statementSpec) throws ExprValidationException { IndexHint indexHint = IndexHint.getIndexHint(statementContext.getAnnotations()); ExcludePlanHint excludePlanHint = null; if (statementSpec.getOnTriggerDesc() instanceof OnTriggerWindowDesc) { OnTriggerWindowDesc onTriggerWindowDesc = (OnTriggerWindowDesc) statementSpec.getOnTriggerDesc(); String[] streamNames = {onTriggerWindowDesc.getOptionalAsName(), statementSpec.getStreamSpecs()[0].getOptionalStreamName()}; excludePlanHint = ExcludePlanHint.getHint(streamNames, statementContext); } return new IndexHintPair(indexHint, excludePlanHint); } public static class IndexHintPair { private final IndexHint indexHint; private final ExcludePlanHint excludePlanHint; public IndexHintPair(IndexHint indexHint, ExcludePlanHint excludePlanHint) { this.indexHint = indexHint; this.excludePlanHint = excludePlanHint; } public IndexHint getIndexHint() { return indexHint; } public ExcludePlanHint getExcludePlanHint() { return excludePlanHint; } } }