/**
   * @param node
   * @param path path is IdentificationVariableData returned by leavePathExprIdentificationVar
   * @param field is name of field as String returned by leaveFieldCMPField
   * @return CMPVariableData for given path and field if the method is called while in
   *     selecctClause. A StringBuffer containing sqlText representing this cmp field if the method
   *     is called while in where Clause
   */
  @Override
  public Object leavePathExprCMPField(EJBQLAST node, Object path, Object field) {
    IdentificationVariableData pathData = (IdentificationVariableData) path;
    String fieldName = (String) field;

    if (inSelectClause) {
      return selectPlan.getCMPVariableData(pathData, fieldName);
    } else {
      return selectPlan.getStateFieldSQLText(pathData, fieldName);
    }
  }
 @Override
 public Object leaveDistinct(EJBQLAST node) {
   // If this method is called, distinct is specified on  the query.
   // Return a non null object.
   selectPlan.setDistinct();
   return null;
 }
 /**
  * Get Data for identification variable.
  *
  * @param idVarNode A node that corresponds to
  * @return
  */
 private IdentificationVariableData getIdentificationVarData(EJBQLAST idVarNode) {
   JavaType entityJavaType = (JavaType) idVarNode.getTypeInfo();
   assert entityJavaType != null
       : "This method is to be called only for" // NOI18N
           + "node that corresponds to identification variable."; // NOI18N
   String navigationId = idVarNode.getNavigationId();
   return selectPlan.getIdentificationVariableData(entityJavaType, navigationId);
 }
 @Override
 public ArrayList<ResultElement> leaveSelectClause(
     EJBQLAST node, Object distinct, Object selectExpr) {
   // TODO: selectExpr should be a list. For now mock up a list to pass to selectPlan
   // Begin  Mock
   ArrayList<ResultElement> resultElements = new ArrayList<ResultElement>();
   resultElements.add((ResultElement) selectExpr);
   // End Mock
   selectPlan.setResultElements(resultElements);
   inSelectClause = false;
   return resultElements;
 }
  /**
   * This method is called when two entities are compared. We have following combinations plus
   * corresponding case where lhs and rhs are switched possible here 1. entity = ?1 2. cmr = ?1 3.
   * cmr = entity (e.g. d.company = c )
   *
   * @param node
   * @param lhs
   * @param rhs
   * @return StringBuffer representing the sql corresponding to sql comparision
   */
  @Override
  public StringBuffer leaveRelationalExprEntityEqual(EJBQLAST node, Object lhs, Object rhs) {
    StringBuffer retVal;
    boolean lhsIsParam = lhs instanceof SelectPlan.ParameterData;
    boolean rhsIsParam = rhs instanceof SelectPlan.ParameterData;
    if (lhsIsParam || rhsIsParam) {
      // Look for entity = ?1 expression.
      // Need to generate entity.pk1 = ? and entity.pk2 = ? ....
      if (lhsIsParam && rhsIsParam) {
        // Comparision of type entityParam1 = entityParam2.
        // TODO: Check with Dave, the query compiler should catch this
        // and throw an error. Then this can turn into an assert
        throw new UnsupportedOperationException(
            "Expression of type " + "entityParam1 = entityParam2 not supported");
      }
      // At this point it is guaranteed that only one of them is a param
      IdentificationVariableData idVarData;
      SelectPlan.ParameterData paramData;
      if (lhsIsParam) {
        paramData = (SelectPlan.ParameterData) lhs;
        idVarData = (IdentificationVariableData) rhs;
      } else {
        assert rhsIsParam;
        paramData = (SelectPlan.ParameterData) rhs;
        idVarData = (IdentificationVariableData) lhs;
      }
      retVal = selectPlan.generateEntityToParamComparison(idVarData, paramData);

    } else {
      // Both the arguments are of type entity. The expression is of
      // type e.singleValuedCmrPathExpr = rangeVar
      // Need to generate
      // e.fk1 = rangeVar.pk1 and e.fk2 = rangeVar.pk2
      retVal =
          selectPlan.generateEntityToEntityComparision(
              (IdentificationVariableData) lhs, (IdentificationVariableData) rhs);
    }
    return retVal;
  }
  /**
   * Process user parameters. User parameters of type PersistenceCapable are treated specially.
   *
   * @param node The node represting pararmeter in query tree
   * @return If the parameter corresponds to a PersistenceCapable type, the text of the node as it
   *     is. Please note that by convention, all methods processing where clause rerturn a
   *     StringBuffer. This methos deviates from the convention for parameter of PersistenceCapable
   *     type. However, for this type of parameter, the return value of this method will always go
   *     into method leaveRelationalExpresionEntityEqual() which will always return a Stringbuffer.
   *     Else a StringBuffer representing parameter marker.
   */
  @Override
  public Object leaveParameter(EJBQLAST node) {
    // TODO: As per discussion on conf call on 05/05, it should be possible to
    // extract enough information while in this method to get hold of RunTimeMappingField
    // (That is atleast String entityType and String fieldName).
    // This information is required for embedded objects and object cocomparison
    // for objects with composite pk to construct correct sql text and parameters
    Object retVal;
    JavaType javaType = (JavaType) node.getTypeInfo();
    if (javaType.isPersistenceCapable()) {
      // If this corresponds to an entity mapped to composite pk, this
      // parameter will translate into multiple parameter markers in the
      // generated sql. Let leaveRelationalExpresionEntityEqual handle this
      // case
      retVal = selectPlan.getParameterData(javaType, node.getText());

    } else {
      // The parameter will have exactly one parameter marker in the
      // generated sql text. Add the parameter to plan.
      retVal = selectPlan.addUserParameter(node.getText());
    }
    return retVal;
  }
 @Override
 public void leaveSelectStmt(
     EJBQLAST node,
     Object from,
     Object select,
     Object where,
     Object groupBy,
     Object having,
     Object orderBy) {
   executor =
       selectPlan.getExecutor(
           (StringBuffer) where, (StringBuffer) orderBy,
           (StringBuffer) groupBy, (StringBuffer) having);
 }
 @Override
 public StringBuffer leaveBetweenExpr(
     EJBQLAST node, Object expr, Object lower, Object upper, boolean sense) {
   return selectPlan.getBetweenExpr(
       (StringBuffer) expr, (StringBuffer) lower, (StringBuffer) upper, sense);
 }
 @Override
 public StringBuffer leaveNullComparisonExpr(EJBQLAST node, Object expr, boolean sense) {
   return selectPlan.getNullExpr((StringBuffer) expr, sense);
 }
 @Override
 public StringBuffer leaveSingleCharStringLiteral(EJBQLAST node) {
   return selectPlan.getSingleCharExpr(node.getText());
 }
 @Override
 public StringBuffer leaveLikeExpr(
     EJBQLAST node, Object expr, Object pattern, Object escape, boolean sense) {
   return selectPlan.getLikeExpr(
       (StringBuffer) expr, (StringBuffer) pattern, (StringBuffer) escape, sense);
 }
 @Override
 public StringBuffer leaveUnaryExprNot(EJBQLAST node, Object expr) {
   return selectPlan.getUnaryNotExpr((StringBuffer) expr);
 }
 @Override
 public StringBuffer leaveConditionalExprOr(EJBQLAST node, Object lhs, Object rhs) {
   return selectPlan.getOrExpr((StringBuffer) lhs, (StringBuffer) rhs);
 }
 @Override
 public StringBuffer leaveBinaryArithmeticExprDiv(EJBQLAST node, Object lhs, Object rhs) {
   return selectPlan.getDivExpr((StringBuffer) lhs, (StringBuffer) rhs);
 }
 @Override
 public StringBuffer leaveSqrt(EJBQLAST node, Object expr) {
   return selectPlan.getSqrtExpr((StringBuffer) expr);
 }
 /**
  * This method is called for occurance of cmr expression in where clause. For query Select
  * Obect(d) from Department d where d.company.name = ?1 this method is called for expression
  * "d.company"
  *
  * @param node The node in query tree that corresponds to the experssion.
  * @param path Data about path expression. In the above example this is data about expression d
  *     This is return value of method leavePathExprIdentificationVar Please note that for
  *     expression of type e.department.company.name = ?1 value of path for cmr company will be as
  *     returned by leavePathExprCMRField for expression * e.deparmtnet
  * @param field the cmr field. This is as returned by leaveFieldCMRField
  * @return
  */
 public Object leavePathExprCMRField(EJBQLAST node, Object path, Object field) {
   IdentificationVariableData pathData = (IdentificationVariableData) path;
   String fieldName = (String) field;
   return selectPlan.getCMRVariableData(pathData, fieldName);
 }
 @Override
 public StringBuffer leaveTrim(EJBQLAST node, Object trimSpec, Object trimChar, Object str) {
   return selectPlan.getTrimExpr((String) trimSpec, (String) trimChar, (StringBuffer) str);
 }
 @Override
 public StringBuffer leaveUpper(EJBQLAST node, Object expr) {
   return selectPlan.getUpperExpr((StringBuffer) expr);
 }
 @Override
 public StringBuffer leaveLength(EJBQLAST node, Object expr) {
   return selectPlan.getLengthExpr((StringBuffer) expr);
 }
 @Override
 public StringBuffer leaveSubstring(EJBQLAST node, Object str, Object start, Object length) {
   return selectPlan.getSubstringExpr(
       (StringBuffer) str, (StringBuffer) start, (StringBuffer) length);
 }
 /** string functions * */
 @Override
 public StringBuffer leaveConcat(EJBQLAST node, Object lhs, Object rhs) {
   return selectPlan.getConcatExpr((StringBuffer) lhs, (StringBuffer) rhs);
 }
 @Override
 public StringBuffer leaveLocate(EJBQLAST node, Object pattern, Object str, Object start) {
   return selectPlan.getLocateExpr(
       (StringBuffer) pattern, (StringBuffer) str, (StringBuffer) start);
 }
 @Override
 public StringBuffer leaveRelationalExprGT(EJBQLAST node, Object lhs, Object rhs) {
   return selectPlan.getGTExpr((StringBuffer) lhs, (StringBuffer) rhs);
 }
 /**
  * For query Select .. from Department d...., This method is called for expression Department d.
  *
  * @param node The node in query tree that corresponds to the experssion.
  * @param schemaName Name of the schema. In above example this is Department. This is return value
  *     of method leaveAbstractSchemaName.
  * @param identVariable Data about identifactionVariable. In above example, this is data about d.
  * @return The data about this variable is added to selectPlan by this method. This method always
  *     return null.
  */
 @Override
 public Object leaveRangeVarDecl(EJBQLAST node, Object schemaName, Object identVariable) {
   selectPlan.addRangeVariable((IdentificationVariableData) identVariable);
   return null;
 }
 @Override
 public StringBuffer leaveLiteralString(EJBQLAST node) {
   return selectPlan.getStringExpr(node.getText());
 }