Package com.espertech.esper.epl.join.plan

Source Code of com.espertech.esper.epl.join.plan.FilterExprAnalyzer

/**************************************************************************************
* 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.epl.join.plan;

import com.espertech.esper.epl.datetime.eval.ExprDotNodeFilterAnalyzerDesc;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.epl.join.util.Eligibility;
import com.espertech.esper.epl.join.util.EligibilityDesc;
import com.espertech.esper.epl.join.util.EligibilityUtil;
import com.espertech.esper.epl.join.util.RangeFilterAnalyzer;

/**
* Analyzes a filter expression and builds a query graph model.
* The 'equals', 'and' 'between' and relational operators expressions in the filter expression are extracted
* and placed in the query graph model as navigable relationships (by key and index
* properties as well as ranges) between streams.
*/
public class FilterExprAnalyzer
{
    /**
     * Analyzes filter expression to build query graph model.
     * @param topNode - filter top node
     * @param queryGraph - model containing relationships between streams, to be written to
     */
    public static void analyze(ExprNode topNode, QueryGraph queryGraph, boolean isOuterJoin)
    {
        // Analyze relationships between streams. Relationships are properties in AND and EQUALS nodes of joins.
        if (topNode instanceof ExprEqualsNode)
        {
            ExprEqualsNode equalsNode = (ExprEqualsNode) topNode;
            if (!equalsNode.isNotEquals())
            {
                analyzeEqualsNode(equalsNode, queryGraph, isOuterJoin);
            }
        }
        else if (topNode instanceof ExprAndNode)
        {
            ExprAndNode andNode = (ExprAndNode) topNode;
            analyzeAndNode(andNode, queryGraph, isOuterJoin);
        }
        else if (topNode instanceof ExprBetweenNode) {
            ExprBetweenNode betweenNode = (ExprBetweenNode) topNode;
            analyzeBetweenNode(betweenNode, queryGraph);
        }
        else if (topNode instanceof ExprRelationalOpNode) {
            ExprRelationalOpNode relNode = (ExprRelationalOpNode) topNode;
            analyzeRelationalOpNode(relNode, queryGraph);
        }
        else if (topNode instanceof ExprDotNode && !isOuterJoin)
        {
            ExprDotNode dotNode = (ExprDotNode) topNode;
            analyzeDotNode(dotNode, queryGraph);
        }
    }

    private static void analyzeDotNode(ExprDotNode dotNode, QueryGraph queryGraph) {
        ExprDotNodeFilterAnalyzerDesc interval = dotNode.getExprDotNodeFilterAnalyzerDesc();
        if (interval == null) {
            return;
        }
        interval.apply(queryGraph);
    }

    private static void analyzeRelationalOpNode(ExprRelationalOpNode relNode, QueryGraph queryGraph) {
        if ( ((relNode.getChildNodes()[0] instanceof ExprIdentNode)) &&
             ((relNode.getChildNodes()[1] instanceof ExprIdentNode)))
        {
            ExprIdentNode identNodeLeft = (ExprIdentNode) relNode.getChildNodes()[0];
            ExprIdentNode identNodeRight = (ExprIdentNode) relNode.getChildNodes()[1];

            if (identNodeLeft.getStreamId() != identNodeRight.getStreamId())
            {
                queryGraph.addRelationalOpStrict(identNodeLeft.getStreamId(), identNodeLeft.getResolvedPropertyName(), identNodeLeft,
                        identNodeRight.getStreamId(), identNodeRight.getResolvedPropertyName(), identNodeRight, relNode.getRelationalOpEnum());
            }
            return;
        }

        int indexedStream = -1;
        String indexedProp = null;
        ExprNode exprNodeNoIdent = null;

        if (relNode.getChildNodes()[0] instanceof ExprIdentNode) {
            ExprIdentNode identNode = (ExprIdentNode) relNode.getChildNodes()[0];
            indexedStream = identNode.getStreamId();
            indexedProp = identNode.getResolvedPropertyName();
            exprNodeNoIdent = relNode.getChildNodes()[1];
        }
        else if (relNode.getChildNodes()[1] instanceof ExprIdentNode) {
            ExprIdentNode identNode = (ExprIdentNode) relNode.getChildNodes()[1];
            indexedStream = identNode.getStreamId();
            indexedProp = identNode.getResolvedPropertyName();
            exprNodeNoIdent = relNode.getChildNodes()[0];
        }
        if (indexedStream == -1) {
            return;     // require property of right/left side of equals
        }

        EligibilityDesc eligibility = EligibilityUtil.verifyInputStream(exprNodeNoIdent, indexedStream);
        if (!eligibility.getEligibility().isEligible()) {
            return;
        }

        queryGraph.addRelationalOp(indexedStream, indexedProp, eligibility.getStreamNum(), exprNodeNoIdent, relNode.getRelationalOpEnum());
    }

    private static void analyzeBetweenNode(ExprBetweenNode betweenNode, QueryGraph queryGraph) {
        RangeFilterAnalyzer.apply(betweenNode.getChildNodes()[0], betweenNode.getChildNodes()[1], betweenNode.getChildNodes()[2],
                betweenNode.isLowEndpointIncluded(), betweenNode.isHighEndpointIncluded(), betweenNode.isNotBetween(),
                queryGraph);
    }

    /**
     * Analye EQUALS (=) node.
     * @param equalsNode - node to analyze
     * @param queryGraph - store relationships between stream properties
     */
    protected static void analyzeEqualsNode(ExprEqualsNode equalsNode, QueryGraph queryGraph, boolean isOuterJoin)
    {
        if ( (equalsNode.getChildNodes()[0] instanceof ExprIdentNode) &&
             (equalsNode.getChildNodes()[1] instanceof ExprIdentNode))
        {
            ExprIdentNode identNodeLeft = (ExprIdentNode) equalsNode.getChildNodes()[0];
            ExprIdentNode identNodeRight = (ExprIdentNode) equalsNode.getChildNodes()[1];

            if (identNodeLeft.getStreamId() != identNodeRight.getStreamId())
            {
                queryGraph.addStrictEquals(identNodeLeft.getStreamId(), identNodeLeft.getResolvedPropertyName(), identNodeLeft,
                        identNodeRight.getStreamId(), identNodeRight.getResolvedPropertyName(), identNodeRight);
            }

            return;
        }
        if (isOuterJoin) {      // outerjoins don't use constants or one-way expression-derived information to evaluate join
            return;
        }

        // handle constant-compare or transformation case
        int indexedStream = -1;
        String indexedProp = null;
        ExprNode exprNodeNoIdent = null;

        if (equalsNode.getChildNodes()[0] instanceof ExprIdentNode) {
            ExprIdentNode identNode = (ExprIdentNode) equalsNode.getChildNodes()[0];
            indexedStream = identNode.getStreamId();
            indexedProp = identNode.getResolvedPropertyName();
            exprNodeNoIdent = equalsNode.getChildNodes()[1];
        }
        else if (equalsNode.getChildNodes()[1] instanceof ExprIdentNode) {
            ExprIdentNode identNode = (ExprIdentNode) equalsNode.getChildNodes()[1];
            indexedStream = identNode.getStreamId();
            indexedProp = identNode.getResolvedPropertyName();
            exprNodeNoIdent = equalsNode.getChildNodes()[0];
        }
        if (indexedStream == -1) {
            return;     // require property of right/left side of equals
        }

        EligibilityDesc eligibility = EligibilityUtil.verifyInputStream(exprNodeNoIdent, indexedStream);
        if (!eligibility.getEligibility().isEligible()) {
            return;
        }

        if (eligibility.getEligibility() == Eligibility.REQUIRE_NONE) {
            queryGraph.addUnkeyedExpression(indexedStream, indexedProp, exprNodeNoIdent);
        }
        else {
            queryGraph.addKeyedExpression(indexedStream, indexedProp, eligibility.getStreamNum(), exprNodeNoIdent);
        }
    }

    /**
     * Analyze the AND-node.
     * @param andNode - node to analyze
     * @param queryGraph - to store relationships between stream properties
     */
    protected static void analyzeAndNode(ExprAndNode andNode, QueryGraph queryGraph, boolean isOuterJoin)
    {
        for (ExprNode childNode : andNode.getChildNodes())
        {
            analyze(childNode, queryGraph, isOuterJoin);
        }
    }
}
TOP

Related Classes of com.espertech.esper.epl.join.plan.FilterExprAnalyzer

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.