/**
   * 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);
    }
  }
  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;
    RelationalOpEnum relop = relNode.getRelationalOpEnum();

    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];
      relop = relop.reversed();
    }
    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, relop);
  }