/*
* *************************************************************************************
* 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.service;
import com.espertech.esper.epl.expression.ExprNode;
import com.espertech.esper.epl.expression.ExprNodeSubselectDeclaredDotVisitor;
import com.espertech.esper.epl.expression.ExprValidationException;
import com.espertech.esper.epl.spec.*;
import com.espertech.esper.pattern.*;
import java.util.ArrayList;
import java.util.List;
public class StatementLifecycleSvcUtil {
public static void walkStatement(StatementSpecRaw spec, ExprNodeSubselectDeclaredDotVisitor visitor) throws ExprValidationException {
// Look for expressions with sub-selects in select expression list and filter expression
// Recursively compile the statement within the statement.
for (SelectClauseElementRaw raw : spec.getSelectClauseSpec().getSelectExprList())
{
if (raw instanceof SelectClauseExprRawSpec)
{
SelectClauseExprRawSpec rawExpr = (SelectClauseExprRawSpec) raw;
rawExpr.getSelectExpression().accept(visitor);
}
else
{
continue;
}
}
if (spec.getFilterRootNode() != null)
{
spec.getFilterRootNode().accept(visitor);
}
if (spec.getUpdateDesc() != null)
{
if (spec.getUpdateDesc().getOptionalWhereClause() != null)
{
spec.getUpdateDesc().getOptionalWhereClause().accept(visitor);
}
for (OnTriggerSetAssignment assignment : spec.getUpdateDesc().getAssignments())
{
assignment.getExpression().accept(visitor);
}
}
if (spec.getOnTriggerDesc() != null) {
visitSubselectOnTrigger(spec.getOnTriggerDesc(), visitor);
}
// Determine pattern-filter subqueries
for (StreamSpecRaw streamSpecRaw : spec.getStreamSpecs()) {
if (streamSpecRaw instanceof PatternStreamSpecRaw) {
PatternStreamSpecRaw patternStreamSpecRaw = (PatternStreamSpecRaw) streamSpecRaw;
EvalNodeAnalysisResult analysisResult = EvalNodeUtil.recursiveAnalyzeChildNodes(patternStreamSpecRaw.getEvalFactoryNode());
for (EvalFactoryNode evalNode : analysisResult.getActiveNodes()) {
if (evalNode instanceof EvalFilterFactoryNode) {
EvalFilterFactoryNode filterNode = (EvalFilterFactoryNode) evalNode;
for (ExprNode filterExpr : filterNode.getRawFilterSpec().getFilterExpressions()) {
filterExpr.accept(visitor);
}
}
else if (evalNode instanceof EvalObserverFactoryNode) {
int beforeCount = visitor.getSubselects().size();
EvalObserverFactoryNode observerNode = (EvalObserverFactoryNode) evalNode;
for (ExprNode param : observerNode.getPatternObserverSpec().getObjectParameters()) {
param.accept(visitor);
}
if (visitor.getSubselects().size() != beforeCount) {
throw new ExprValidationException("Subselects are not allowed within pattern observer parameters, please consider using a variable instead");
}
}
}
}
}
// walk streams
walkStreamSpecs(spec, visitor);
}
public static void walkStreamSpecs(StatementSpecRaw spec, ExprNodeSubselectDeclaredDotVisitor visitor) {
// Determine filter streams
for (StreamSpecRaw rawSpec : spec.getStreamSpecs())
{
if (rawSpec instanceof FilterStreamSpecRaw) {
FilterStreamSpecRaw raw = (FilterStreamSpecRaw) rawSpec;
for (ExprNode filterExpr : raw.getRawFilterSpec().getFilterExpressions()) {
filterExpr.accept(visitor);
}
}
if (rawSpec instanceof PatternStreamSpecRaw) {
PatternStreamSpecRaw patternStreamSpecRaw = (PatternStreamSpecRaw) rawSpec;
EvalNodeAnalysisResult analysisResult = EvalNodeUtil.recursiveAnalyzeChildNodes(patternStreamSpecRaw.getEvalFactoryNode());
for (EvalFactoryNode evalNode : analysisResult.getActiveNodes()) {
if (evalNode instanceof EvalFilterFactoryNode) {
EvalFilterFactoryNode filterNode = (EvalFilterFactoryNode) evalNode;
for (ExprNode filterExpr : filterNode.getRawFilterSpec().getFilterExpressions()) {
filterExpr.accept(visitor);
}
}
}
}
}
}
private static void visitSubselectOnTrigger(OnTriggerDesc onTriggerDesc, ExprNodeSubselectDeclaredDotVisitor visitor) {
if (onTriggerDesc instanceof OnTriggerWindowUpdateDesc) {
OnTriggerWindowUpdateDesc updates = (OnTriggerWindowUpdateDesc) onTriggerDesc;
for (OnTriggerSetAssignment assignment : updates.getAssignments())
{
assignment.getExpression().accept(visitor);
}
}
else if (onTriggerDesc instanceof OnTriggerSetDesc) {
OnTriggerSetDesc sets = (OnTriggerSetDesc) onTriggerDesc;
for (OnTriggerSetAssignment assignment : sets.getAssignments())
{
assignment.getExpression().accept(visitor);
}
}
else if (onTriggerDesc instanceof OnTriggerSplitStreamDesc) {
OnTriggerSplitStreamDesc splits = (OnTriggerSplitStreamDesc) onTriggerDesc;
for (OnTriggerSplitStream split : splits.getSplitStreams())
{
if (split.getWhereClause() != null) {
split.getWhereClause().accept(visitor);
}
if (split.getSelectClause().getSelectExprList() != null) {
for (SelectClauseElementRaw element : split.getSelectClause().getSelectExprList()) {
if (element instanceof SelectClauseExprRawSpec) {
SelectClauseExprRawSpec selectExpr = (SelectClauseExprRawSpec) element;
selectExpr.getSelectExpression().accept(visitor);
}
}
}
}
}
else if (onTriggerDesc instanceof OnTriggerMergeDesc) {
OnTriggerMergeDesc merge = (OnTriggerMergeDesc) onTriggerDesc;
for (OnTriggerMergeMatched matched : merge.getItems()) {
if (matched.getOptionalMatchCond() != null) {
matched.getOptionalMatchCond().accept(visitor);
}
for (OnTriggerMergeAction action : matched.getActions())
{
if (action.getOptionalWhereClause() != null) {
action.getOptionalWhereClause().accept(visitor);
}
if (action instanceof OnTriggerMergeActionUpdate) {
OnTriggerMergeActionUpdate update = (OnTriggerMergeActionUpdate) action;
for (OnTriggerSetAssignment assignment : update.getAssignments())
{
assignment.getExpression().accept(visitor);
}
}
if (action instanceof OnTriggerMergeActionInsert) {
OnTriggerMergeActionInsert insert = (OnTriggerMergeActionInsert) action;
for (SelectClauseElementRaw element : insert.getSelectClause()) {
if (element instanceof SelectClauseExprRawSpec) {
SelectClauseExprRawSpec selectExpr = (SelectClauseExprRawSpec) element;
selectExpr.getSelectExpression().accept(visitor);
}
}
}
}
}
}
}
public static SelectClauseSpecCompiled compileSelectClause(SelectClauseSpecRaw spec) {
List<SelectClauseElementCompiled> selectElements = new ArrayList<SelectClauseElementCompiled>();
SelectClauseSpecCompiled selectClauseCompiled = new SelectClauseSpecCompiled(selectElements, spec.isDistinct());
for (SelectClauseElementRaw raw : spec.getSelectExprList())
{
if (raw instanceof SelectClauseExprRawSpec)
{
SelectClauseExprRawSpec rawExpr = (SelectClauseExprRawSpec) raw;
selectElements.add(new SelectClauseExprCompiledSpec(rawExpr.getSelectExpression(), rawExpr.getOptionalAsName(), rawExpr.getOptionalAsName()));
}
else if (raw instanceof SelectClauseStreamRawSpec)
{
SelectClauseStreamRawSpec rawExpr = (SelectClauseStreamRawSpec) raw;
selectElements.add(new SelectClauseStreamCompiledSpec(rawExpr.getStreamName(), rawExpr.getOptionalAsName()));
}
else if (raw instanceof SelectClauseElementWildcard)
{
SelectClauseElementWildcard wildcard = (SelectClauseElementWildcard) raw;
selectElements.add(wildcard);
}
else
{
throw new IllegalStateException("Unexpected select clause element class : " + raw.getClass().getName());
}
}
return selectClauseCompiled;
}
}