/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * CodeGeneration.g
 *
 * Created on March 13, 2000
 */

header
{
    package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc;
    
    import java.util.*;
    import java.lang.reflect.Field;
    import java.lang.IllegalAccessException;

    import com.sun.jdo.api.persistence.support.JDOFatalUserException;
    import com.sun.jdo.spi.persistence.support.sqlstore.PersistenceCapable;
    import com.sun.jdo.spi.persistence.support.sqlstore.PersistenceManager;
    import com.sun.jdo.spi.persistence.support.sqlstore.RetrieveDesc;
    import com.sun.jdo.spi.persistence.support.sqlstore.StateManager;

    import org.glassfish.persistence.common.I18NHelper;
    import com.sun.jdo.spi.persistence.utility.FieldTypeEnumeration;
    import com.sun.jdo.spi.persistence.utility.logging.Logger;

    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.TypeTable;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.Type;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.ClassType;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.FieldInfo;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.NumericType;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.NumericWrapperClassType;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.NumberType;
    import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.StringType;
}

/**
 * This class defines the code generation pass of the JQL compiler.
 * Input of this pass is the typed and optimized AST as produced by optimizer.
 * The result is a RetrieveDesc.
 *
 * @author  Michael Bouschen
 * @author  Shing Wai Chan
 * @version 0.1
 */
class CodeGeneration extends TreeParser;
                             
options
{
    importVocab = JQL;
    ASTLabelType = "JQLAST"; //NOI18N
}

{
    /** Name of the USE_IN property. */
    public static final String USE_IN_PROPERTY = 
        "com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.USE_IN";

    /** */
    private static final boolean USE_IN = Boolean.getBoolean(USE_IN_PROPERTY);

    /**
     * I18N support
     */
    protected final static ResourceBundle messages = 
      I18NHelper.loadBundle(CodeGeneration.class);

    /**
     * The persistence manager the query object is connected to.
     */
    protected PersistenceManager pm;
    
    /**
     * type table
     */
    protected TypeTable typetab;
    
    /**
     * query parameter table
     */
    protected ParameterTable paramtab;
    
    /**
     *
     */
    protected ErrorMsg errorMsg;
    
    /**
     * prefetchEnabled flag for RetrieveDesc.
     */
    protected boolean prefetchEnabled;
    
    /**
     * The RetrieveDesc for the candidate class. 
     * Code gen for the CLASS_DEF AST will initilaized this variable.
     * Code gen for the filter expression will add the constraints.
     */
    protected RetrieveDesc candidateRD;

    /**
     * rd2TagMap maps RetrieveDesc to tags. A tag is either the variable name or
     * the navigation path that used to create a new RetrieveDesc. This info is 
     * needed to identify whether two different RetrieveDescs denote the same 
     * variable or relationship.
     */
    protected Map rd2TagMap;

    /** 
     * Set of RetrieveDescs. CodeGeneration uses this set to prevent multiple 
     * addConstraint calls for the RetrieveDescs denoting a variable.
     */
    protected Set boundRetrieveDescs;

    /** The logger */
    private static Logger logger = LogHelperQueryCompilerJDO.getLogger();

    /**
     * Defines the SQL wildcard character to be used in wildcard pattern 
     * (string methods startsWith and endsWith).
     */
    protected static final String WILDCARD_PATTERN = "%"; //NOI18N
    
    /**
     *
     */
    public void init(PersistenceManager pm, TypeTable typetab, 
                     ParameterTable paramtab, ErrorMsg errorMsg,
                     boolean prefetchEnabled)
    {
        this.pm = pm;
        this.typetab = typetab;
        this.paramtab = paramtab;
        this.errorMsg = errorMsg;
        this.prefetchEnabled = prefetchEnabled;
        this.rd2TagMap = new HashMap();
        this.boundRetrieveDescs = new HashSet();
    }
    
    /**
     *
     */
    public void reportError(RecognitionException ex) {
        errorMsg.fatal("CodeGeneration error", ex); //NOI18N
    }

    /**
     *
     */
    public void reportError(String s) {
        errorMsg.fatal("CodeGeneration error: " + s); //NOI18N
    }
    
    /**
     * Returns the RetrieveDesc that represents the current query.
     */
    public RetrieveDesc getRetrieveDesc()
    {
        if (candidateRD instanceof DebugRetrieveDesc)
            return ((DebugRetrieveDesc)candidateRD).wrapped;
        return candidateRD;
    }

    /**
     * Helper method for checkRetrieveDesc handling operators & and &&.
     */
    protected void checkAndOpRetrieveDesc(JQLAST op, JQLAST left, 
        JQLAST right, Map usedRD) throws RecognitionException
    {
        if ((right.getType() == CONTAINS) || (right.getType() == NOT_CONTAINS))
        {
            // If right is a CONTAINS clause, start analysing the right expr.
            // This ensures that the lft expression can reuse the RD defined 
            // for the variable from the contains clause
            checkRetrieveDesc(right, usedRD);
            checkRetrieveDesc(left, usedRD);
        }
        else
        {
            checkRetrieveDesc(left, usedRD);
            checkRetrieveDesc(right, usedRD); 
        }
        op.setRetrieveDesc(getCommonRetrieveDesc(left, right)); 
    }
    
    /**
     * Check the attached RetrieveDesc of the specified binary operation and its operands.
     */
    protected RetrieveDesc getCommonRetrieveDesc(JQLAST left, JQLAST right)
    {
        RetrieveDesc rd = null;
        RetrieveDesc leftRD = left.getRetrieveDesc();
        RetrieveDesc rightRD = right.getRetrieveDesc();

        if ((leftRD == null) && (rightRD != null))
        {
            // case 1: no RetrieveDesc for left operand, but right operand returns RetrieveDesc
            // attach the right RetrieveDesc to all nodes of the left subtree
            propagateRetrieveDesc(left, rightRD);
            rd = rightRD;
        }

        else if ((leftRD != null) && (rightRD == null))
        {
            // case 2: no RetrieveDesc for right operand, but left operand returns RetrieveDesc
            // attach the left RetrieveDesc to all nodes of the right subtree
            propagateRetrieveDesc(right, leftRD);
            rd = leftRD;
        }
        else if ((leftRD != null) && (rightRD != null))
        {
            // case 3: both left and right operand have a RetrieveDesc attached
            if (leftRD == rightRD)
            {
                // case 3a: left and right RetrieveDesc are identical
                rd = leftRD;
            }
            else
            {
                // case 3b: left and right RetrieveDesc are NOT identical
                // check navigation:
                rd = getCommonRetrieveDescHelper(leftRD, findNavigationSource(left), 
                                                 rightRD, findNavigationSource(right));

                // use leftRD as default
                if (rd == null) 
                {
                    rd = leftRD;
                }
            }
        }
        return rd;
    }

    /** Helper method for getCommonRetrieveDesc used to check navigation. */
    protected RetrieveDesc getCommonRetrieveDescHelper(
        RetrieveDesc leftRD, JQLAST leftNavSrc, 
        RetrieveDesc rightRD, JQLAST rightNavSrc)
    {
        RetrieveDesc rd = null;
        String leftPath = (String)rd2TagMap.get(leftRD);
        String rightPath = (String)rd2TagMap.get(rightRD);
        RetrieveDesc leftNavSrcRD = 
            (leftNavSrc == null) ? null : leftNavSrc.getRetrieveDesc();
        String leftNavSrcPath = 
            (leftNavSrcRD == null ) ? null: (String)rd2TagMap.get(leftNavSrcRD);
        RetrieveDesc rightNavSrcRD = 
            (rightNavSrc == null) ? null : rightNavSrc.getRetrieveDesc();
        String rightNavSrcPath = 
            (rightNavSrcRD == null) ? null : (String)rd2TagMap.get(rightNavSrcRD);

        if ((leftNavSrcPath != null) && leftNavSrcPath.equals(rightPath))
        {
            // case I: left operand is a navigation and 
            //         the navigation source is equal to the right operand
            rd = rightRD;
        }
        else if ((rightNavSrcPath != null) && rightNavSrcPath.equals(leftPath))
        {
            // case II: right operand is a navigation and 
            //          the navigation source is equal to the left operand
            rd = leftRD;
        }
        else if ((leftNavSrcPath != null) && (rightNavSrcPath != null) &&  
            leftNavSrcPath.equals(rightNavSrcPath))
        {
            // case III: both operands are navigations and have the same source
            rd = leftNavSrcRD;
        }
        else {
            // case IV: check whether the navigation source is a bound variable.
            //          If yes, check the collection source
            JQLAST leftConstraint = findNavigationSourceOfBoundVariable(leftNavSrc);
            JQLAST rightConstraint = findNavigationSourceOfBoundVariable(rightNavSrc);
            if ((leftConstraint != null) && (rightConstraint != null))
            {
                rd = getCommonRetrieveDescHelper(leftRD, leftConstraint, 
                                                 rightRD, rightConstraint);
            }
            else if ((leftConstraint == null) && (rightConstraint != null))
            {
                rd = getCommonRetrieveDescHelper(leftRD, leftNavSrc, 
                                                 rightRD, rightConstraint);
            }
            else if ((leftConstraint != null) && (rightConstraint == null))
            {
                rd = getCommonRetrieveDescHelper(leftRD, leftConstraint, 
                                                 rightRD, rightNavSrc);
            }
        }
        return rd;
    }

    /**
     * Helper method to support getting the common RetrieveDesc for operands 
     * taking three arguments such as like with escape, substring, indexOf.
     */
    protected RetrieveDesc getCommonRetrieveDesc(JQLAST arg1, JQLAST arg2, JQLAST arg3)
    {
        RetrieveDesc rd = null;
        if (arg3 == null) {
            // Just call the regular method for binray ops, 
            // if the third argument is not specified.
            rd = getCommonRetrieveDesc(arg1, arg2);
        }
        else {
            // First check args two and three.
            getCommonRetrieveDesc(arg2, arg3);
            // Now check the first and the second arg.
            rd = getCommonRetrieveDesc(arg1, arg2);
            // Propagate the common RetrieveDesc to the third arg. 
            // This is important, if arg two and three are literals.
            // Then the first call checking arg2 and arg3 did not attach any 
            // RetrieveDesc. The second call checking arg1 and arg2 might have 
            // propagated a rd from arg1 to arg2. So this propagateRetrieveDesc
            // call propagates this rd to arg3, too.
            propagateRetrieveDesc(arg3, rd);
        }
        return rd;
    }

    /** 
     * Helper method to support getting the common RetrieveDesc for object 
     * comparison operators.
     */
    protected RetrieveDesc getObjectComparisonRetrieveDesc(JQLAST left, JQLAST right)
    {
        RetrieveDesc rd = null;
        if ((left.getType() == NAVIGATION) && 
            (right.getType() == VALUE) && (right.getValue() == null))
        {
            // case obj.relship == null
            // take the RetrieveDesc from the navigation source
            rd = ((JQLAST)left.getFirstChild()).getRetrieveDesc();
        }
        else if ((left.getType() == VALUE) && (left.getValue() == null) && 
            (right.getType() == NAVIGATION))
        {
            // case null == obj.relship
            // take the RetrieveDesc from the navigation source
            rd = ((JQLAST)right.getFirstChild()).getRetrieveDesc();
        }
        else
        {
            // use regular getCommonRetrieveDesc
            rd = getCommonRetrieveDesc(left, right);
        }
        return rd;
    }

    /**
     * Returns the source if a navigation or field access.
     */
    protected JQLAST findNavigationSource(JQLAST tree)
    {
        JQLAST child = (JQLAST)tree.getFirstChild();
        switch (tree.getType())
        {
        case NOT_IN:
        case FIELD_ACCESS:
        case NAVIGATION:
            return findNavigationSource(child);
        case THIS:
        case VARIABLE:
            return tree;
        case CONTAINS:
        case NOT_CONTAINS:
            return null;
        default:
            for (JQLAST node = child; node != null; node = (JQLAST)node.getNextSibling())
            {
                JQLAST tmp = findNavigationSource(node);
                if (tmp != null)
                    return tmp;
            }
        }
        return null;
    }

    /** 
     * If the specifid node is a bound variable return the navigation source of 
     * it's collection. 
     */
    protected JQLAST findNavigationSourceOfBoundVariable(JQLAST tree)
    {
        if ((tree.getType() == VARIABLE) && (tree.getFirstChild() != null))
            return findNavigationSource((JQLAST)tree.getFirstChild());
        return null;
    }
    
    /**
     * Attach the specified RetrieveDesc to all JQLAST node of the ast subtree,
     * that do not have a RetrieveDesc attached.
     */
    protected void propagateRetrieveDesc(JQLAST ast, RetrieveDesc rd)
    {
        if (ast.getRetrieveDesc() == null)
        {
            ast.setRetrieveDesc(rd);
        }
        for (JQLAST node = (JQLAST)ast.getFirstChild(); 
             node != null; 
             node = (JQLAST)node.getNextSibling())
        {
            propagateRetrieveDesc(node, rd);
        }
    }

    /**
     * Returns an Object representing 0 according to the specified type.
     */
    protected Object getZeroValue(Type type)
    {
        return (type instanceof NumberType) ? 
               ((NumberType)type).getValue(new Integer(0)) :
               null;
    }

    /**
     * Returns an Object representing -1 according to the specified type.
     */
    protected Object getMinusOneValue(Type type)
    {
        return (type instanceof NumberType) ? 
               ((NumberType)type).getValue(new Integer(-1)) :
               null;
    }
   
    /**
     * Returns -value. 
     * The method assumes that the passed argument is a numeric wrapper class object. 
     * If so it negates the wrapped numeric value and wraps the negated value into a 
     * numeric wrapper class object.
     */
    protected Object negate(Object value, Type type)
    {
        return (type instanceof NumberType) ? 
               ((NumberType)type).negate((Number)value) :
               null;
    }

    /**
     * Returns the boolean operation of the equivalent relational expression 
     * with swapped arguments.
     * expr1 > expr2 <=> expr2 < expr1
     */
    protected int getSwappedOp(int operation)
    {
        int ret = 0;
        switch (operation)
        {
        case RetrieveDesc.OP_EQ:
            ret = RetrieveDesc.OP_EQ;
            break;
        case RetrieveDesc.OP_NE:
            ret = RetrieveDesc.OP_NE;
            break;
        case RetrieveDesc.OP_LT:
            ret = RetrieveDesc.OP_GT;
            break;
        case RetrieveDesc.OP_LE:
            ret = RetrieveDesc.OP_GE;
            break;
        case RetrieveDesc.OP_GT:
            ret = RetrieveDesc.OP_LT;
            break;
        case RetrieveDesc.OP_GE:
            ret = RetrieveDesc.OP_LE;
            break;
        }
        return ret;
    }

    /**
     * Code generation for a comparison of the form field relop value, 
     * where field denotes a non relationship field
     * This method checks for null values and generates OP_NULL / OP_NOTNULL constraints 
     * in the case of field relop null
     */
    protected void generateSimpleFieldValueComparison(RetrieveDesc rd, String name, 
                                                      int operation, Object value)
    {
        if (value != null)
        {
            rd.addConstraint(name, operation, value);
        }   
        else if (operation == RetrieveDesc.OP_EQ)
        {
            rd.addConstraint(name, RetrieveDesc.OP_NULL, null);
        }
        else if (operation == RetrieveDesc.OP_NE)
        {
            rd.addConstraint(name, RetrieveDesc.OP_NOTNULL, null);
        }
        else
        {
            errorMsg.fatal(I18NHelper.getMessage(messages, "jqlc.codegeneration.generatesimplefieldvaluecomparison.invalidvalue")); //NOI18N
        }
    }

    /**
     * Code generation for a comparison of the form 
     *   dbvalue relop constant
     * where dbvalue denotes an object in the database such as 
     * - this
     * - the result of a relationship navigation
     * - variable access
     * and constant is a constant value at query compile time (e.g. a literal)
     */
    protected void generateDbValueConstantComparison(RetrieveDesc rd, ClassType objectType, 
                                                     int operation, Object value, Type valueType)
    {
        int booleanOp = getKeyFieldsComparisonBooleanOp(operation);

        List keyFieldNames = objectType.getKeyFieldNames();
        for (Iterator i = keyFieldNames.iterator(); i.hasNext();)
        {
            String keyFieldName = (String)i.next();
            Object keyFieldValue = null;
            if (value != null)
            {
                keyFieldValue = getFieldValue((ClassType)valueType, value, keyFieldName);
            }
            generateSimpleFieldValueComparison(rd, keyFieldName, operation, keyFieldValue);
            if (i.hasNext())
                rd.addConstraint(null, booleanOp, null);
        }
    }

    /**
     * Code generation for a comparison of the form 
     *   dbvalue relop dbvalue
     * where dbvalue denotes an object in the database such as 
     * - this
     * - the result of a relationship navigation
     * - variable access
     */
    protected void generateDbValueDbValueComparison(RetrieveDesc leftRD, ClassType leftType, int operation, 
                                                    RetrieveDesc rightRD, ClassType rightType)
    {
        int booleanOp = getKeyFieldsComparisonBooleanOp(operation);
        
        // Note, this code assumes that both operands are of class types that have 
        // the same key fields. Thus take the list of key field names of the left side.
        List leftKeyFieldNames = leftType.getKeyFieldNames();
        for (Iterator i = leftKeyFieldNames.iterator(); i.hasNext();)
        {
            String keyFieldName = (String)i.next();
            leftRD.addConstraint(keyFieldName, operation, rightRD, keyFieldName);
            if (i.hasNext())
                leftRD.addConstraint(null, booleanOp, null);
        }
    }

    /**
     * Code generation for a comparison of the form 
     *   parameter relop constantValue
     */
    protected void generateParameterValueComparison(RetrieveDesc rd,
                                                    String paramName, 
                                                    int operation, Object value)
    {
        if (value != null)
        {
            rd.addConstraint(null, RetrieveDesc.OP_VALUE, value);
            rd.addConstraint(null, RetrieveDesc.OP_PARAMETER,
                paramtab.getParameterInfoForParamName(paramName));
            rd.addConstraint(null, operation, null);
        }   
        else if (operation == RetrieveDesc.OP_EQ)
        {
            rd.addConstraint(null, RetrieveDesc.OP_PARAMETER,
                paramtab.getParameterInfoForParamName(paramName));
            rd.addConstraint(null, RetrieveDesc.OP_NULL, null);
        }
        else if (operation == RetrieveDesc.OP_NE)
        {
            rd.addConstraint(null, RetrieveDesc.OP_PARAMETER,
                paramtab.getParameterInfoForParamName(paramName));
            rd.addConstraint(null, RetrieveDesc.OP_NOTNULL, null);
        }
        else
        {
            errorMsg.fatal(I18NHelper.getMessage(messages, "jqlc.codegeneration.generateparametervaluecomparison.invalidvalue")); //NOI18N
        }
    }

    /**
     * Returns the boolean operation used to connect the key field comparison expressions:
     * l == r is mapped to l.pk1 == r.pk1 & ... & l.pkn == r.pkn => return &
     * l != r is mapped to l.pk1 != r.pk1 | ... | l.pkn != r.pkn => return |
     */
    protected int getKeyFieldsComparisonBooleanOp(int operation)
    {
        switch (operation)
        {
        case RetrieveDesc.OP_EQ:
            return RetrieveDesc.OP_AND;
        case RetrieveDesc.OP_NE:
            return RetrieveDesc.OP_OR;
        }
        errorMsg.fatal(I18NHelper.getMessage(messages,
            "jqlc.codegeneration.getkeyfieldscomparisonbooleanop.invalidobj", //NOI18N
            String.valueOf(operation)));
        return 0;
    }

    /**
     * Returns the value of the  field access object.field.
     * Uses jdoGetField for object of a persistence capable class and reflection otherwise.
     */
    protected static Object getFieldValue (ClassType classType, Object object, String fieldName)
    {
        Object value = null;
        FieldInfo fieldInfo = classType.getFieldInfo(fieldName);
        if (classType.isPersistenceCapable())
        {
            PersistenceCapable pc = (PersistenceCapable)object;
            int index = fieldInfo.getFieldNumber();
            StateManager stateManager = pc.jdoGetStateManager();
            
            if (stateManager != null)
            {
                // call stateManager.prepareGetField to allow the stateManager 
                // to mediate the field access
                stateManager.prepareGetField(index);
            }
            value = pc.jdoGetField(index);
        }
        else
        {
            // non persistence capable class => use reflection
            try
            {
                value = fieldInfo.getField().get(object);
            }
            catch (IllegalAccessException e) 
            {
                throw new JDOFatalUserException(
                    I18NHelper.getMessage(messages, "jqlc.codegeneration.fieldaccess.illegal",  //NOI18N
                        fieldName, (object==null ? "null" : object.toString())), e); //NOI18N
            }
        }
        return value;
    }
    
    /**
     * This method checks whether the result RetrieveDesc needs a DISTINCT clause or not. 
     * @param query the query AST
     */
    protected void handleDistinct(JQLAST query, boolean distinct)
    {
        // candidateRD is null in the case of false filter
        if (candidateRD == null)
            return;
        
        if (distinct)
            candidateRD.addResult(RetrieveDesc.OP_DISTINCT, FieldTypeEnumeration.NOT_ENUMERATED);
    }

    /**
     * This method returns true if the specified node is an AST that represensts a value.
     * It returns false for CONTAINS/NOT_CONTAINS nodes and boolean operations that include 
     * only CONTAINS nodes 
     */
    protected boolean pushesValueOnStack(JQLAST node)
    {
        switch(node.getType())
        {
        case CONTAINS:
        case NOT_CONTAINS:
            return false;
        case BAND:
        case BOR:
        case AND:
        case OR:
            JQLAST left = (JQLAST)node.getFirstChild();
            JQLAST right = (JQLAST)left.getNextSibling();
            return pushesValueOnStack(left) || pushesValueOnStack(right);
        default:
            return true;
        }
    }

    /**
     * Create a new RetrieveDesc for the specified classType and
     * store this RetrieveDesc in the cache with the specified path expression attached.
     * The method wraps the RetrieveDesc in a DebugRetrieveDesc, if debug mode is on.
     */
    protected RetrieveDesc createRetrieveDesc(String pathExpr, ClassType classType)
    {
        RetrieveDesc rd = pm.getRetrieveDesc(classType.getJavaClass());
        if (logger.isLoggable(Logger.FINEST)) 
        {
            rd = new DebugRetrieveDesc(rd);
            logger.finest("LOG_JQLCDumpRD", "create " + JQLAST.getRetrieveDescRepr(rd)); //NOI18N
        }        
        rd2TagMap.put(rd, pathExpr);
        rd.setNavigationalId(pathExpr);
        return rd;
    }

    /**
     * Wrapper that traces the RetrieveDesc calls
     */
    protected static class DebugRetrieveDesc implements RetrieveDesc
    {
        RetrieveDesc wrapped = null;

        DebugRetrieveDesc(RetrieveDesc wrapped)
        {
            this.wrapped = wrapped;
        }
        
        public RetrieveDesc unwrap(RetrieveDesc rd)
        {
            if (rd instanceof DebugRetrieveDesc)
                return ((DebugRetrieveDesc)rd).wrapped;
            return rd;
        }

        // methods from RetrieveDesc 
        public void addResult(String name, RetrieveDesc desc, boolean projection)
        {
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) + ".addResult(" +  //NOI18N
                    name + ", " + JQLAST.getRetrieveDescRepr(desc) + ", " + //NOI18N
                    projection + ")"); //NOI18N
            desc = unwrap(desc);
            wrapped.addResult(name, desc, projection);   
        }
        
        public void addResult(int opCode, int resultType)
        {
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) + ".addResult(" +  //NOI18N
                    opCode + ", " + resultType + ")"); //NOI18N
            wrapped.addResult(opCode, resultType);   
        }
        
        public void addConstraint(String name, int operation, Object value)
        {
            String thirdArgRepr = null;
            if (value instanceof RetrieveDesc)
            {
                RetrieveDesc foreignConstraint = (RetrieveDesc)value;
                thirdArgRepr = JQLAST.getRetrieveDescRepr(foreignConstraint);
                value = unwrap(foreignConstraint);
            }
            else
            {
                thirdArgRepr = (value == null) ? "null" : value.toString();
            }
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                JQLAST.getRetrieveDescRepr(this) + ".addConstraint(" +  //NOI18N
                name + ", " + operation + ", " + thirdArgRepr + ")"); //NOI18N
            wrapped.addConstraint(name, operation, value);
        }

        public void addConstraint(String name, RetrieveDesc foreignConstraint)
        {
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) + ".addConstraint(" +  //NOI18N
                    name + ", " + JQLAST.getRetrieveDescRepr(foreignConstraint) + ")"); //NOI18N
            foreignConstraint = unwrap(foreignConstraint);
            wrapped.addConstraint(name, foreignConstraint);
        }

        public void addConstraint(String name, int operator, RetrieveDesc foreignConstraint, String foreignFieldName)
        {
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) + ".addConstraint(" +  //NOI18N
                    name + ", " + operator + ", " + JQLAST.getRetrieveDescRepr(foreignConstraint) + //NOI18N
                    ", " +  foreignFieldName + ")"); //NOI18N
            foreignConstraint = unwrap(foreignConstraint);
            wrapped.addConstraint(name, operator, foreignConstraint, foreignFieldName); 
        }
        
        public void setNavigationalId(Object navigationalId)
        { 
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) + 
                    ".setNavigationalId(" + navigationalId + ")"); //NOI18N
            wrapped.setNavigationalId(navigationalId); 
        }

        public void setPrefetchEnabled(boolean prefetchEnabled)
        {
            if (logger.isLoggable(Logger.FINEST))
                logger.finest("LOG_JQLCDumpRD", //NOI18N
                    JQLAST.getRetrieveDescRepr(this) +
                    ".setPrefetchEnabled(" + prefetchEnabled + ")"); //NOI18N
            wrapped.setPrefetchEnabled(prefetchEnabled);
        }

        // Methods from ActionDesc

        public Class getPersistenceCapableClass()
        { return wrapped.getPersistenceCapableClass(); }
    }
}

// rules

query
    :   q:.
        {
            prepareRetrieveDescs(q);
            if (logger.isLoggable(Logger.FINEST)) 
                logger.finest("LOG_JQLCDumpTree", q.getTreeRepr("RD annotated AST")); //NOI18N
            doCodeGen(q);
        }
    ;

doCodeGen
{ 
    boolean distinct = false;
}
    :   #(  q:QUERY
            candidateClass 
            parameters
            variables
            ordering
            distinct = result
            filter
        )
        {
            handleDistinct(q, distinct);
        }
    ;

// ----------------------------------
// rules: candidate class
// ----------------------------------

candidateClass
{   
    errorMsg.setContext("setCandidates"); //NOI18N
}
    :   c:CLASS_DEF
        // Note, DISTINCT is added by handleDistinct called in the rule query
    ;
// ----------------------------------
// rules: parameter declaration
// ----------------------------------

parameters
{   
    errorMsg.setContext("declareParameters"); //NOI18N
}
    :   ( declareParameter )*
    ;

declareParameter
    :   #( PARAMETER_DEF type IDENT )
    ;

// ----------------------------------
// rules: variable declaration
// ----------------------------------

variables 
{ 
    errorMsg.setContext("declareVariables"); //NOI18N
}
    :   ( declareVariable )*
    ;

declareVariable
    :   #( VARIABLE_DEF type i:IDENT )
    ;

// ----------------------------------
// rules: ordering specification
// ----------------------------------

ordering
{   
    errorMsg.setContext("setOrdering"); //NOI18N
}
    :   ( orderSpec )*
    ;

orderSpec
{
    int op = 0;
}
    :   #(  ORDERING_DEF 
            (   ASCENDING  { op = RetrieveDesc.OP_ORDERBY; }
            |   DESCENDING { op = RetrieveDesc.OP_ORDERBY_DESC; }
            )
            orderingExpr[op]
        )
    ;

orderingExpr [int op]
    :   ( #(  FIELD_ACCESS expression IDENT) )=> #(  f:FIELD_ACCESS expression i:IDENT )
        {
            f.getRetrieveDesc().addConstraint(i.getText(), op, null);
        }
    |   e:.
        {
            errorMsg.unsupported(e.getLine(), e.getColumn(),
                I18NHelper.getMessage(messages, 
                    "jqlc.codegeneration.generic.unsupportedop", // NOI18N
                    e.getText()));
        }
    ;

// ----------------------------------
// rules: result expression
// ----------------------------------

result returns [boolean distinct]
{   
    errorMsg.setContext("setResult"); //NOI18N
    distinct = false;
}
    :   #(  RESULT_DEF 
            distinct = resultExpr[true]
        )
    |   {
            // no result is equivalent to setResult("distinct this") =>
            // distinct is true
            distinct = true;
        }
    ;

resultExpr [boolean outer] returns [boolean distinct]
{
    String name = null;
    // this should be take care at first level of recursion
    distinct = false;
    boolean tmp;
}
    :   #( d:DISTINCT tmp = resultExpr[outer] )
        {
            distinct = true;
        }
    |   #( avg:AVG distinct = resultExpr[true] )
        {
            candidateRD.addResult(RetrieveDesc.OP_AVG,
                avg.getJQLType().getEnumType());
        }
    |   #( max:MAX distinct = resultExpr[true] )
        {
            candidateRD.addResult(RetrieveDesc.OP_MAX,
                max.getJQLType().getEnumType());
        }
    |   #( min:MIN distinct = resultExpr[true] )
        {
            candidateRD.addResult(RetrieveDesc.OP_MIN,
                min.getJQLType().getEnumType());
        }
    |   #( sum:SUM distinct = resultExpr[true] )
        {
            candidateRD.addResult(RetrieveDesc.OP_SUM,
                sum.getJQLType().getEnumType());
        }
    |   #( count:COUNT distinct = r:resultExpr[true] )
        {
            Type resultType = r.getJQLType();
            if (typetab.isPersistenceCapableType(resultType)) {
                List pkfields = ((ClassType)resultType).getKeyFieldNames();
                if (pkfields != null) {
                    candidateRD.addResult(RetrieveDesc.OP_COUNT_PC,
                        count.getJQLType().getEnumType());
                } else {
                    errorMsg.unsupported(r.getLine(), r.getColumn(),
                        I18NHelper.getMessage(messages,
                        "jqlc.codegeneration.resultexpr.missingpkfields", // NOI18N
                        resultType.getName()));
                }
            } else {
                candidateRD.addResult(RetrieveDesc.OP_COUNT,
                    count.getJQLType().getEnumType());
            }
        }
    |   #(  op1:FIELD_ACCESS tmp = expr1:resultExpr[false] i1:IDENT )
        {
            op1.getRetrieveDesc().addResult(i1.getText(), null, true);
        }
    |   #(  op2:NAVIGATION tmp = expr2:resultExpr[false] i2:IDENT )
        {
            RetrieveDesc from = expr2.getRetrieveDesc();
            RetrieveDesc to = op2.getRetrieveDesc();
            from.addResult(i2.getText(), to, outer);
        }
    |   #(  op3:VARIABLE ( name = col3:collectionExprResult )? )
        {
            if (col3 != null) {
                RetrieveDesc from = col3.getRetrieveDesc();
                RetrieveDesc to = op3.getRetrieveDesc();
                from.addResult(name, to, outer);
            }
        }
    |   THIS
    ;

collectionExprResult returns [String fieldName]
{   
    fieldName = null; 
    boolean tmp;
}
    :   #( FIELD_ACCESS tmp = resultExpr[false] name1:IDENT )
        {  fieldName = name1.getText(); }
    |   #( NAVIGATION tmp = resultExpr[false] name2:IDENT )
        {  fieldName = name2.getText(); }
    |   #( TYPECAST . fieldName = collectionExprResult )
    |   #( NOT_IN fieldName = collectionExprResult )
    ;

// ----------------------------------
// rules: filer expression
//
// NOTE: the code generator traverses operands of binary operations in reverse order.
// The reason is that the RetrieveDesc processes the constriant stack in a LIFO way. 
// This means, the code generator has to process the right operand first, 
// then the left operand and finally the operation.
// ----------------------------------

filter
{   
    errorMsg.setContext("setFilter"); //NOI18N
}
    :   #( FILTER_DEF expr:. )
        {
            switch (expr.getType()) {
            case VALUE:
                // constant filter
                Object value = expr.getValue();
                if (value instanceof Boolean) 
                {
                    // Note, in the case of a true filter do not add
                    // any constraints to the candidateRD

                    if (!((Boolean)value).booleanValue())
                    {
                        // false filter => unset candidateRD
                        candidateRD = null;
                    }
                }
                else
                {
                    errorMsg.fatal(I18NHelper.getMessage(messages,
                        "jqlc.codegeneration.filter.nonbooleanvalue", //NOI18N
                        String.valueOf(value)));
                }
                break;
            case FIELD_ACCESS:
                // The entire filter consists of a boolean field only.
                // Map this to 'booleanField <> FALSE'. Note, the runtime will
                // create a JDBC parameter for the literal FALSE and call 
                // setBoolean to bind the value.
                RetrieveDesc rd = expr.getRetrieveDesc();
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, Boolean.FALSE);
                expression(expr);
                rd.addConstraint(null, RetrieveDesc.OP_NE, null);
                break;
            default:
                expression(expr);
                break;
            }
        }
    ;

expression 
    :   ( primary )=> primary
    |   bitwiseExpr
    |   conditionalExpr
    |   relationalExpr
    |   binaryArithmeticExpr
    |   unaryArithmeticExpr
    |   complementExpr
    ;

// This rule transforms an access expression of a boolean field into an
// equal operation: expr == true.
booleanOperationArgument
    : e:expression
      {
           if (#e.getType() == FIELD_ACCESS) {
               RetrieveDesc rd = #e.getRetrieveDesc();
               rd.addConstraint(null, RetrieveDesc.OP_VALUE, Boolean.TRUE);
               rd.addConstraint(null, RetrieveDesc.OP_EQ, null);
           }
      }
    ;

bitwiseExpr 
    :   #( op1:BAND left1:. right1:booleanOperationArgument )
        {  
            booleanOperationArgument(left1);
            // do not generate boolean operation if one of the operands is variable constraint
            if (pushesValueOnStack(left1) && pushesValueOnStack(right1))
                op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_AND, null); 
        }
    |   #( op2:BOR  left2:. right2:booleanOperationArgument )
        {
            booleanOperationArgument(left2);
            // do not generate boolean operation if one of the operands is variable constraint
            if (pushesValueOnStack(left2) && pushesValueOnStack(right2))
                op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_OR, null); 
        }
    |   #( op3:BXOR left3:. right3:booleanOperationArgument )
        {  
            booleanOperationArgument(left3);
            errorMsg.unsupported(op3.getLine(), op3.getColumn(),
                I18NHelper.getMessage(messages, 
                    "jqlc.codegeneration.generic.unsupportedop", // NOI18N
                    op3.getText()));
        }
    ;

conditionalExpr 
    :   #( op1:AND left1:. right1:booleanOperationArgument )
        {  
            booleanOperationArgument(left1);
            // do not generate boolean operation if one of the operands is variable constraint
            if (pushesValueOnStack(left1) && pushesValueOnStack(right1))
                op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_AND, null); 
        }
    |   #( op2:OR  left2:. right2:booleanOperationArgument )
        {    
            booleanOperationArgument(left2);
            // do not generate boolean operation if one of the operands is variable constraint
            if (pushesValueOnStack(left2) && pushesValueOnStack(right2))
                op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_OR, null); 
        }
    ;

relationalExpr 
    :   ( fieldComparison )=> fieldComparison
    |   ( objectComparison )=> objectComparison
    |   ( collectionComparison )=> collectionComparison
    |   ( parameterComparison )=> parameterComparison
    |   #( op1:EQUAL left1:. expression )
        {  
            expression(left1);
            op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_EQ, null); 
        }
    |   #( op2:NOT_EQUAL left2:. expression )
        {  
            expression(left2);
            op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_NE, null); 
        }
    |   #( op3:LT left3:. expression )
        {  
            expression(left3);
            op3.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LT, null); 
        }
    |   #( op4:GT left4:. expression )
        {  
            expression(left4);
            op4.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_GT, null); 
        }
    |   #( op5:LE left5:. expression )
        {  
            expression(left5);
            op5.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LE, null); 
        }
    |   #( op6:GE left6:. expression )
        {  
            expression(left6);
            op6.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_GE, null); 
        }
    ;

fieldComparison
    :   #(EQUAL fieldComparisonOperands[RetrieveDesc.OP_EQ] )
    |   #(NOT_EQUAL fieldComparisonOperands[RetrieveDesc.OP_NE] )
    |   #(LT fieldComparisonOperands[RetrieveDesc.OP_LT] )
    |   #(LE fieldComparisonOperands[RetrieveDesc.OP_LE] )
    |   #(GT fieldComparisonOperands[RetrieveDesc.OP_GT] )
    |   #(GE fieldComparisonOperands[RetrieveDesc.OP_GE] )
    ;

fieldComparisonOperands [int operation]
{   
    String leftName = null;
    String rightName = null;
    Object value = null;
}
    :   value = constantValue rightName = f1:fieldAccess
        {
            // case constant relop field
            generateSimpleFieldValueComparison(f1.getRetrieveDesc(), rightName, 
                                               getSwappedOp(operation), value);
        }
    |   p1:PARAMETER rightName = f2:fieldAccess
        {
            // case parameter relop field
            // Support for fixed-width char pk columns
            f2.getRetrieveDesc().addConstraint(rightName, RetrieveDesc.OP_FIELD, null); 
            f2.getRetrieveDesc().addConstraint(null,
                RetrieveDesc.OP_PARAMETER, 
                paramtab.getParameterInfoForParamName(p1.getText(), rightName));
            f2.getRetrieveDesc().addConstraint(null, operation, null);
        }
    |   leftName = f3:fieldAccess 
        (   value = constantValue 
            {
                // case field relop constant
                generateSimpleFieldValueComparison(f3.getRetrieveDesc(), leftName, 
                                                   operation, value);
            }
        |   rightName = f4:fieldAccess 
            {
                // case field relop field
                f3.getRetrieveDesc().addConstraint(leftName, operation, 
                                                   f4.getRetrieveDesc(), rightName);
            }
        |   p2:PARAMETER
            {
                // case field relop parameter
                // Support for fixed-width char pk columns
                f3.getRetrieveDesc().addConstraint(null,
                    RetrieveDesc.OP_PARAMETER, 
                    paramtab.getParameterInfoForParamName(p2.getText(), leftName));
                f3.getRetrieveDesc().addConstraint(leftName, RetrieveDesc.OP_FIELD, null);
                f3.getRetrieveDesc().addConstraint(null, operation, null);
            }
        )
    ;

objectComparison
{
    Object value = null;
}
    :   #( OBJECT_EQUAL objectComparisonOperands[RetrieveDesc.OP_EQ] ) 
    |   #( OBJECT_NOT_EQUAL objectComparisonOperands[RetrieveDesc.OP_NE] )
    ;

objectComparisonOperands [int operation]
{   
    Object value = null;
}
    :   value = v1:constantValue d1:dbValue
        // case constant relop dbvalue
        {
            if ((value == null) && (d1.getType() == NAVIGATION))
            {
                JQLAST expr = (JQLAST)d1.getFirstChild();
                JQLAST ident = (JQLAST)expr.getNextSibling();
                // now handle navigation source
                expression(expr);
                // now generate IS NULL constraint
                generateSimpleFieldValueComparison(expr.getRetrieveDesc(), ident.getText(), 
                                                   getSwappedOp(operation), value);
            }
            else
            {
                if (d1.getType() == NAVIGATION) navigation(d1);
                generateDbValueConstantComparison(d1.getRetrieveDesc(), (ClassType)d1.getJQLType(), 
                                                  getSwappedOp(operation), value, v1.getJQLType());
            }
        }
    |   d2:dbValue
        (   value = v2:constantValue 
            // case dbvalue relop constant
            {
                if ((value == null) && (d2.getType() == NAVIGATION))
                {
                    JQLAST expr = (JQLAST)d2.getFirstChild();
                    JQLAST ident = (JQLAST)expr.getNextSibling();
                    // now handle navigation source
                    expression(expr);
                    // now generate IS NULL constraint
                    generateSimpleFieldValueComparison(expr.getRetrieveDesc(), ident.getText(), 
                                                       operation, value);
                }
                else
                {
                    if (d2.getType() == NAVIGATION) navigation(d2);
                    generateDbValueConstantComparison(d2.getRetrieveDesc(), 
                                                      (ClassType)d2.getJQLType(), 
                                                      operation, value, v2.getJQLType());
                }
            }
        |   d3:dbValue
            // case dbvalue relop dbvalue
            {
                if (d2.getType() == NAVIGATION) navigation(d2);
                if (d3.getType() == NAVIGATION) navigation(d3);
                generateDbValueDbValueComparison(d2.getRetrieveDesc(), 
                                                 (ClassType)d2.getJQLType(), 
                                                 operation, 
                                                 d3.getRetrieveDesc(), 
                                                 (ClassType)d3.getJQLType());
            }
        )
    ;

parameterComparison
    :   #(EQUAL parameterComparisonOperands[RetrieveDesc.OP_EQ] )
    |   #(NOT_EQUAL parameterComparisonOperands[RetrieveDesc.OP_NE] )
    |   #(OBJECT_EQUAL parameterComparisonOperands[RetrieveDesc.OP_EQ] )
    |   #(OBJECT_NOT_EQUAL parameterComparisonOperands[RetrieveDesc.OP_NE] )
    ;

parameterComparisonOperands [int operation]
{
    Object value = null;
}
    :   p1:PARAMETER value = v1:constantValue
        {
            generateParameterValueComparison(v1.getRetrieveDesc(), p1.getText(),
                operation, value);
        }
    |   value = v2:constantValue p2:PARAMETER
        {
            generateParameterValueComparison(v2.getRetrieveDesc(), p2.getText(),
                operation, value);
        }
    ;

dbValue
{
    String name = null;
}
    :   THIS
    |   variableAccess
    |   #(  NAVIGATION . IDENT )   
        // do not use non-terminal navigation here, because navigation 
        // creates a RetrieveDesc for the relationship navigation and 
        // we must not create this in the case of relship == null
    ;

collectionComparison
    :   #( eq:COLLECTION_EQUAL . . )
        {
            errorMsg.unsupported(eq.getLine(), eq.getColumn(),
                I18NHelper.getMessage(messages, 
                    "jqlc.codegeneration.collectioncomparison.nonnull")); // NOI18N
        }
    |   #( ne:COLLECTION_NOT_EQUAL . . )
        {
            errorMsg.unsupported(ne.getLine(), ne.getColumn(),
                I18NHelper.getMessage(messages, 
                    "jqlc.codegeneration.collectioncomparison.nonnull")); // NOI18N
        }
    ;

binaryArithmeticExpr 
    :   #( op1:PLUS left1:. right1:. )
        {
            // Optimize indexOf + <intValue>: 
            // The SQL database returns an index starting with 1, so we need 
            // to decrement the returned index. We can do the derement at compile
            // timeCombine, if the other operand is a constant int value.
            if ((left1.getType() == INDEXOF) && 
                (right1.getType() == VALUE) && 
                (right1.getValue() instanceof Integer))
            {
                // case: indexOf() + intValue
                indexOf(left1, ((Integer)right1.getValue()).intValue());
            }
            else if ((right1.getType() == INDEXOF) && 
                (left1.getType() == VALUE) && 
                (left1.getValue() instanceof Integer))
            {
                // case: intValue + indexOf()
                indexOf(right1, ((Integer)left1.getValue()).intValue());
            }
            else
            {
                expression(right1);
                expression(left1);
                op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_ADD, null); 
            }
        }
    |   #( op2:CONCAT left2:. expression )
        {
            expression(left2);
            op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_CONCAT, null); 
        }
    |   #( op3:MINUS left3:. right3:. )
        {
            // Optimize indexOf + <intValue>: 
            // The SQL database returns an index starting with 1, so we need 
            // to decrement the returned index. We can do the derement at compile
            // timeCombine, if the other operand is a constant int value.
            if ((left3.getType() == INDEXOF) && 
                (right3.getType() == VALUE) && 
                (right3.getValue() instanceof Integer))
            {
                // case: indexOf - intValue 
                // treated as indexOf + -intValue
                indexOf(left3, -((Integer)right3.getValue()).intValue());
            }
            else
            {
                expression(right3);
                expression(left3);
                op3.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_SUB, null); 
            }
        }
    |   #( op4:STAR left4:. expression )
        {
            expression(left4);
            op4.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_MUL, null); 
        }
    |   #( op5:DIV left5:. expression )
        {
            expression(left5);
            op5.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_DIV, null); 
        }
    |   #( op6:MOD left6:. expression )
        {
            expression(left6);
            op6.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_MOD, null);
        }
    ;

unaryArithmeticExpr 
{   
    Object value = null; 
}
    :   #(   UNARY_PLUS expression )
        // no action needed, just ignore the unary plus
    |   #(   op2:UNARY_MINUS
            (
                ( constantValue )=> value = constantValue
                {
                    value = negate(value, op2.getJQLType());
                    op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, value);
                }
            |
                expression 
                { 
                    // map -value to 0 - value
                    op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                                                       getZeroValue(op2.getJQLType()));
                    op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_SUB, null); 
                }
            )
        )
    ;

complementExpr 
    :   #( op1:BNOT expression )
        { 
            // map ~value to -1 - value (which is equivalent to (-value)-1)
            op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                                                getMinusOneValue(op1.getJQLType()));
            op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_SUB, null); 
        }
    |   #(  op2:LNOT expr:. )
        {   if (expr.getType() == FIELD_ACCESS) {
                // The NOT operand is a boolean field.
                // Map this to 'booleanField = FALSE'. Note, the runtime will
                // create a JDBC parameter for the literal FALSE and call 
                // setBoolean to bind the value.
                RetrieveDesc rd = op2.getRetrieveDesc();
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, Boolean.FALSE); 
                expression(expr);
                rd.addConstraint(null, RetrieveDesc.OP_EQ, null);
            }
            else {
                expression(expr);
                op2.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_NOT, null); 
            }
        }
    ;

primary 
{   
    Object value; 
    String name;
}
    :   #( TYPECAST type expression )
        { /* code gen for cast? */ }
    |   value = v:constantValue
        {
            if (value == null)
            {
                errorMsg.fatal(I18NHelper.getMessage(messages, "jqlc.codegeneration.primary.null")); //NOI18N
            }
            else if (value instanceof Boolean)
            {
                boolean booleanValue = ((Boolean)value).booleanValue();
                RetrieveDesc rd = v.getRetrieveDesc();
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, new Integer(0)); 
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, new Integer(0)); 
                rd.addConstraint(null, (booleanValue?RetrieveDesc.OP_EQ:RetrieveDesc.OP_NE), null); 
            }
            else
            {
                v.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, value); 
            }
        }
    |   p:PARAMETER 
        {
            p.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_PARAMETER, 
                paramtab.getParameterInfoForParamName(p.getText()));
        }
    |   THIS
    |   name = f:fieldAccess
        {
            f.getRetrieveDesc().addConstraint(name, RetrieveDesc.OP_FIELD, null);
        }
    |   navigation
    |   variableAccess
    |   #(  CONTAINS . VARIABLE )
        // code moved to variable access
    |   #(  NOT_CONTAINS . VARIABLE )
        // code moved to variable access
    |   startsWith
    |   endsWith
    |   isEmpty
    |   like
    |   substring
    |   indexOf[0]
    |   length
    |   abs
    |   sqrt
    ;

constantValue returns [Object value]
{   
    value = null; 
}
    :   v:VALUE
        {
            value = v.getValue();
        }
    ;


fieldAccess returns [String fieldName]
{   
    fieldName = null; 
}
    :   #( FIELD_ACCESS expression name:IDENT )
        {  fieldName = name.getText(); }
    ;

navigation
    :   #(  n:NAVIGATION expr:expression i:IDENT )
        {
            RetrieveDesc from = expr.getRetrieveDesc();
            RetrieveDesc to = n.getRetrieveDesc();
            from.addConstraint(i.getText(), to);
        }
    ;

variableAccess
{
    String name = null;
}
    :   #(  var:VARIABLE ( name = col:collectionExpr )? )
        {
            
            RetrieveDesc varRD = var.getRetrieveDesc();
            if (!boundRetrieveDescs.contains(varRD))
            {
                if (col != null) 
                {
                    if (col.getType() == NOT_IN)
                        col.getRetrieveDesc().addConstraint(name, RetrieveDesc.OP_NOTIN, varRD);
                    else if (USE_IN)
                        // generate OP_IN if USE_IN property is set
                        col.getRetrieveDesc().addConstraint(name, RetrieveDesc.OP_IN, varRD);
                    else
                        // otherwise generate regular join
                        col.getRetrieveDesc().addConstraint(name, varRD);
                }
                else
                {
                    candidateRD.addConstraint(null, varRD);
                }
                boundRetrieveDescs.add(varRD);
            }
        }
    ;

collectionExpr returns [String fieldName]
{   
    fieldName = null; 
}
    :   #( FIELD_ACCESS expression name1:IDENT )
        {  fieldName = name1.getText(); }
    |   #( NAVIGATION expression name2:IDENT )
        {  fieldName = name2.getText(); }
    |   #( TYPECAST . fieldName = collectionExpr )
    |   #( NOT_IN fieldName = collectionExpr )
    ;

startsWith
{
    Object value = null;
    JQLAST pattern = null;
}
    :   #(  op1:STARTS_WITH string:. 
            {
                // I need to store a pointer to the second operand of startsWith here.
                // See second alternative below.
                pattern = (JQLAST)string.getNextSibling();
            }
            ( 
                ( constantValue )=> value = constantValue
                {
                    if (string.getType() == FIELD_ACCESS)
                    {
                        // case 1 fieldAccess constantValue
                        String fieldName = fieldAccess(string);
                        op1.getRetrieveDesc().addConstraint(fieldName, RetrieveDesc.OP_LIKE, 
                            ((String)value) + WILDCARD_PATTERN);
                    }
                    else
                    {
                        // case 2 expression constantValue
                        op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                            ((String)value) + WILDCARD_PATTERN);
                        expression(string);
                        op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LIKE, null);
                    }
                }
            |   {
                    // I have to access the tree matched by rule expression before 
                    // the rule is entered. Variable pattern points to that tree and 
                    // needs to be initilaized before!
                    pattern.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                                                            WILDCARD_PATTERN);
                }
                expression
                {
                    // case 3 expression expression
                    pattern.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_CONCAT, null);
                    expression(string);
                    op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LIKE, null);
                }
            )
        )
    ;

endsWith
{
    Object value = null;
}
    :   #(  op1:ENDS_WITH string:. 
            ( 
                ( constantValue )=> value = constantValue
                {
                    if (string.getType() == FIELD_ACCESS)
                    {
                        // case 1 fieldAccess constantValue
                        String fieldName = fieldAccess(string);
                        op1.getRetrieveDesc().addConstraint(fieldName, RetrieveDesc.OP_LIKE, 
                            WILDCARD_PATTERN + ((String)value));
                    }
                    else
                    {
                        // case 2 expression constantValue
                        op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                            WILDCARD_PATTERN + ((String)value));
                        expression(string);
                        op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LIKE, null);
                    }
                }
            |   pattern:expression
                {
                    // case 3 expression expression
                    pattern.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE,
                                                            WILDCARD_PATTERN);
                    pattern.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_CONCAT, null);
                    expression(string);
                    op1.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LIKE, null);
                }
            )
        )
    ;

isEmpty
{ 
    String name = null;
}
    :   #(op:IS_EMPTY name = collectionExpr)
        {
            op.getRetrieveDesc().addConstraint(name, RetrieveDesc.OP_NULL, null);
        }
    ;

like
{   
    int opCode = RetrieveDesc.OP_LIKE;
}
    :   #( op:LIKE string:. pattern:. opCode = escape ) 
        {
            expression(pattern);
            expression(string);
            op.getRetrieveDesc().addConstraint(null, opCode, null);
        }
    ;

escape returns [int opCode]
{   
    // The default is no ESCAPE definition => OP_LIKE
    opCode = RetrieveDesc.OP_LIKE;
}
    :   expression
        {
            opCode = RetrieveDesc.OP_LIKE_ESCAPE;
        }
    |   // empty rule
    ;

substring
    :   // JDOQL:        string.substring(begin, end) ->
        // RetrieveDesc: SUBSTRING(string, begin + 1, end - begin)
        #( op:SUBSTRING string:. begin:. end:. ) 
        {
            RetrieveDesc rd = op.getRetrieveDesc();
            if ((begin.getType() == VALUE) && (end.getType() == VALUE))
            {
                // Optimization: begin and end are constant values =>
                // calculate start and length of SQL SUBSTRING function 
                // at compile time.
                // Note, Semantic ensures begin and end are int or Integer values.
                int beginValue = (begin.getValue() != null) ? 
                    ((Integer)begin.getValue()).intValue() : 0;
                int endValue = (end.getValue() != null) ? 
                    ((Integer)end.getValue()).intValue() : 0;
                if (beginValue < 0) 
                {
                    errorMsg.error(begin.getLine(), begin.getColumn(),
                        I18NHelper.getMessage(messages, 
                            "jqlc.codegeneration.substring.beginnegative", // NOI18N
                            String.valueOf(beginValue)));
                }
                else if (endValue < beginValue) 
                {
                    errorMsg.error(op.getLine(), op.getColumn(),
                        I18NHelper.getMessage(messages, 
                            "jqlc.codegeneration.substring.beginlargerend", // NOI18N
                            String.valueOf(beginValue), String.valueOf(endValue)));
                }
                // SQL length = end - begin
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, 
                    new Integer(endValue-beginValue));
                // SQL start index = begin + 1 
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, 
                    new Integer(beginValue+1));
            }
            else
            {
                // At least one of begin or end is a non constant value =>
                // generate the arguments start and length of the SQL SUBSTRING 
                // function as binary plus/minus expressions.
                // The next 3 line denote the SQL length = end - begin
                expression(begin);
                expression(end);
                rd.addConstraint(null, RetrieveDesc.OP_SUB, null);
                // The next 3 lines denote the SQL start index = begin + 1 
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, new Integer(1));
                expression(begin);
                rd.addConstraint(null, RetrieveDesc.OP_ADD, null);
            }
            // now push the string on the constraint stack
            expression(string);
            rd.addConstraint(null, RetrieveDesc.OP_SUBSTRING, null);
        }
    ;

// incr denotes the value that need to be added to result of POSITION
indexOf [int incr]
{
    int opCode = RetrieveDesc.OP_POSITION;
}
    :   // JDOQL:        string.indexOf(pattern) ->
        // RetrieveDesc: POSITION(string, pattern) - 1
        // JDOQL:        string.indexOf(pattern, begin) ->
        // RetrieveDesc: POSITION_START(string, pattern, begin + 1) - 1
        #( op:INDEXOF string:. pattern:. opCode = fromIndex ) 
        {
            RetrieveDesc rd = op.getRetrieveDesc();
            // the 3 lines denote the SQL function POSITION OR POSITION_START
            expression(pattern);
            expression(string);
            rd.addConstraint(null, opCode, null);
            // SQL handles indexes starting from 1 =>
            // decrement the returned value to make it Java like!
            incr--;
            if (incr != 0)
            {
                rd.addConstraint(null, RetrieveDesc.OP_VALUE, new Integer(incr));
                rd.addConstraint(null, RetrieveDesc.OP_ADD, null);
            }
        }
    ;

fromIndex returns [int opCode]
{
    // The default is no start definition => OP_POSITION
    opCode = RetrieveDesc.OP_POSITION;
}
    :   e:.
        {
            opCode = RetrieveDesc.OP_POSITION_START;
            // Java indexOf method use indexes starting with 0, 
            // where SQL starts with 1, so we need to add 1
            if (e.getType() == VALUE)
            {
                // Optimization: calulate index at compile time, 
                // if start is a constant value.
                // Note, Semantic ensures begin and end are int or Integer values.
                int value = (e.getValue() != null) ? 
                    ((Integer)e.getValue()).intValue() : 0;
                e.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                    new Integer(value + 1));
            }
            else
            {
                e.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_VALUE, 
                    new Integer(1));
                expression(e);
                e.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_ADD, null);
            }
        }
    |   // empty rule
    ;

length
    :   #( op:LENGTH expression )
        {
            op.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_LENGTH, null);
        }
    ;

abs
    :   #( op:ABS expression )
        {
            op.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_ABS, null);
        }
    ;

sqrt
    :   #( op:SQRT expression )
        {
            op.getRetrieveDesc().addConstraint(null, RetrieveDesc.OP_SQRT, null);
        }
    ;

type
    :   TYPENAME
    |   primitiveType
    ;

primitiveType
    :   BOOLEAN
    |   BYTE
    |   CHAR
    |   SHORT
    |   INT
    |   FLOAT
    |   LONG
    |   DOUBLE
    ;

// ----------------------------------
// rules: RetrieveDesc handling
// ----------------------------------

prepareRetrieveDescs
{
    Map usedRD = new HashMap();
}
    :   #(  q:QUERY
            checkRetrieveDesc[usedRD] // candidate class
            ( #( PARAMETER_DEF . . ) )*
            ( #( VARIABLE_DEF . . ) )*
            ( #( ORDERING_DEF 
                    ( ASCENDING | DESCENDING ) 
                    ordering:checkRetrieveDesc[usedRD]
                    { propagateRetrieveDesc(ordering, candidateRD); }
                )
            )*
            ( #( RESULT_DEF result:checkRetrieveDesc[usedRD]
                    { propagateRetrieveDesc(result, candidateRD); }
                )
            )?
            #( FILTER_DEF 
                filter:checkRetrieveDesc[usedRD]
                { propagateRetrieveDesc(filter, candidateRD); }
            )
        )
    ;

checkRetrieveDesc [Map usedRD]
    :   c:CLASS_DEF
        {
            // check persistence capable
            ClassType candidateClass = (ClassType)c.getJQLType();
            candidateRD = createRetrieveDesc("this", candidateClass); //NOI18N
            candidateRD.setPrefetchEnabled(prefetchEnabled);
        }
    |   #( cast:TYPECAST type expr1:checkRetrieveDesc[usedRD] )
        {
            cast.setRetrieveDesc(expr1.getRetrieveDesc());
        }

    //  constantValue not necessary here, this is covered by the last rule 

    |   t:THIS
        { 
            t.setRetrieveDesc(candidateRD); 
        }
    |   #(var:VARIABLE ( checkRetrieveDesc[usedRD] )? )
        {
            RetrieveDesc to = (RetrieveDesc)usedRD.get(var.getText());
            if (to == null)
            {
                to = createRetrieveDesc(var.getText(), (ClassType)var.getJQLType());
                usedRD.put(var.getText(), to);
            }
            var.setRetrieveDesc(to);
        }
    |   #(notIn:NOT_IN notInArg:checkRetrieveDesc[usedRD])
        {
            #notIn.setRetrieveDesc(#notInArg.getRetrieveDesc());
        }
    |   #(fa:FIELD_ACCESS expr4:checkRetrieveDesc[usedRD] i:IDENT)
        {
            fa.setRetrieveDesc(expr4.getRetrieveDesc());
            i.setRetrieveDesc(expr4.getRetrieveDesc());
        }
    |   #(n:NAVIGATION checkRetrieveDesc[usedRD] IDENT)
        {
            RetrieveDesc to = (RetrieveDesc)usedRD.get(n.getText());
            if (to == null)
            {
                to = createRetrieveDesc(n.getText(), (ClassType)n.getJQLType());
                usedRD.put(n.getText(), to);
            }
            n.setRetrieveDesc(to);
        }
    |   #(CONTAINS checkRetrieveDesc[usedRD] checkRetrieveDesc[usedRD])
    |   #(NOT_CONTAINS checkRetrieveDesc[usedRD] checkRetrieveDesc[usedRD])
    |   #(sw:STARTS_WITH expr7:checkRetrieveDesc[usedRD] checkRetrieveDesc[usedRD])
        {
            sw.setRetrieveDesc(expr7.getRetrieveDesc());
        }
    |   #(ew:ENDS_WITH expr8:checkRetrieveDesc[usedRD] checkRetrieveDesc[usedRD])
        {
            ew.setRetrieveDesc(expr8.getRetrieveDesc());
        }
    |   #(ie:IS_EMPTY expr9:checkRetrieveDesc[usedRD])
        {
            ie.setRetrieveDesc(expr9.getRetrieveDesc());
        }
    |   #(like:LIKE string10:checkRetrieveDesc[usedRD] 
            pattern10:checkRetrieveDesc[usedRD] ( escape10:checkRetrieveDesc[usedRD] )? )
        {
            like.setRetrieveDesc(getCommonRetrieveDesc(string10, pattern10, escape10));
        }
    |   #(substr:SUBSTRING string11:checkRetrieveDesc[usedRD] 
            lower11:checkRetrieveDesc[usedRD] upper11:checkRetrieveDesc[usedRD] )
        {
            substr.setRetrieveDesc(getCommonRetrieveDesc(string11, lower11, upper11));
        }
    |   #(indexOf:INDEXOF string12:checkRetrieveDesc[usedRD] 
            pattern12:checkRetrieveDesc[usedRD] ( start12:checkRetrieveDesc[usedRD] )? )
        {
            indexOf.setRetrieveDesc(getCommonRetrieveDesc(string12, pattern12, start12));
        }
    |   #(len:LENGTH expr13:checkRetrieveDesc[usedRD])
        {
            len.setRetrieveDesc(expr13.getRetrieveDesc());
        }
    |   #(abs:ABS expr14:checkRetrieveDesc[usedRD])
        {
            abs.setRetrieveDesc(expr14.getRetrieveDesc());
        }
    |   #(sqrt:SQRT expr15:checkRetrieveDesc[usedRD])
        {
            sqrt.setRetrieveDesc(expr15.getRetrieveDesc());
        }

        // binary operations

    |   #( op1:BAND      left1:. right1:. )
        {   checkAndOpRetrieveDesc(op1, left1, right1, usedRD); }
    |   #( op2:BOR       left2:checkRetrieveDesc[new HashMap(usedRD)] 
                         right2:checkRetrieveDesc[new HashMap(usedRD)] )
        { op2.setRetrieveDesc(getCommonRetrieveDesc(left2, right2)); }
    |   #( op3:BXOR      left3:checkRetrieveDesc[new HashMap()] 
                         right3:checkRetrieveDesc[new HashMap()] )
        { op3.setRetrieveDesc(getCommonRetrieveDesc(left3, right3)); }
    |   #( op4:AND      left4:. right4:. )
        {   checkAndOpRetrieveDesc(op4, left4, right4, usedRD); }
    |   #( op5:OR        left5:checkRetrieveDesc[new HashMap(usedRD)] 
                         right5:checkRetrieveDesc[new HashMap(usedRD)] )
        { op5.setRetrieveDesc(getCommonRetrieveDesc(left5, right5)); }
    |   #( op6:EQUAL     left6:checkRetrieveDesc[usedRD] right6:checkRetrieveDesc[usedRD] )
        { op6.setRetrieveDesc(getCommonRetrieveDesc(left6, right6)); }
    |   #( op7:NOT_EQUAL left7:checkRetrieveDesc[usedRD] right7:checkRetrieveDesc[usedRD] )
        { op7.setRetrieveDesc(getCommonRetrieveDesc(left7, right7)); }
    |   #( op8:LT        left8:checkRetrieveDesc[usedRD] right8:checkRetrieveDesc[usedRD] )
        { op8.setRetrieveDesc(getCommonRetrieveDesc(left8, right8)); }
    |   #( op9:GT        left9:checkRetrieveDesc[usedRD] right9:checkRetrieveDesc[usedRD] )
        { op9.setRetrieveDesc(getCommonRetrieveDesc(left9, right9)); }
    |   #( op10:LE        left10:checkRetrieveDesc[usedRD] right10:checkRetrieveDesc[usedRD] )
        { op10.setRetrieveDesc(getCommonRetrieveDesc(left10, right10)); }
    |   #( op11:GE        left11:checkRetrieveDesc[usedRD] right11:checkRetrieveDesc[usedRD] )
        { op11.setRetrieveDesc(getCommonRetrieveDesc(left11, right11)); }
    |   #( op12:OBJECT_EQUAL     left12:checkRetrieveDesc[usedRD] right12:checkRetrieveDesc[usedRD] )
        { op12.setRetrieveDesc(getObjectComparisonRetrieveDesc(left12, right12)); }
    |   #( op13:OBJECT_NOT_EQUAL left13:checkRetrieveDesc[usedRD] right13:checkRetrieveDesc[usedRD] )
        { op13.setRetrieveDesc(getObjectComparisonRetrieveDesc(left13, right13)); }
    |   #( op14:COLLECTION_EQUAL left14:checkRetrieveDesc[usedRD] right14:checkRetrieveDesc[usedRD] )
        { op14.setRetrieveDesc(getCommonRetrieveDesc(left14, right14)); }
    |   #( op15:COLLECTION_NOT_EQUAL left15:checkRetrieveDesc[usedRD] right15:checkRetrieveDesc[usedRD] )
        { op15.setRetrieveDesc(getCommonRetrieveDesc(left15, right15)); }
    |   #( op16:PLUS      left16:checkRetrieveDesc[usedRD] right16:checkRetrieveDesc[usedRD] )
        { op16.setRetrieveDesc(getCommonRetrieveDesc(left16, right16)); }
    |   #( op17:CONCAT    left17:checkRetrieveDesc[usedRD] right17:checkRetrieveDesc[usedRD] )
        { op17.setRetrieveDesc(getCommonRetrieveDesc(left17, right17)); }
    |   #( op18:MINUS     left18:checkRetrieveDesc[usedRD] right18:checkRetrieveDesc[usedRD] )
        { op18.setRetrieveDesc(getCommonRetrieveDesc(left18, right18)); }
    |   #( op19:STAR      left19:checkRetrieveDesc[usedRD] right19:checkRetrieveDesc[usedRD] )
        { op19.setRetrieveDesc(getCommonRetrieveDesc(left19, right19)); }
    |   #( op20:DIV       left20:checkRetrieveDesc[usedRD] right20:checkRetrieveDesc[usedRD] )
        { op20.setRetrieveDesc(getCommonRetrieveDesc(left20, right20)); }
    |   #( op21:MOD       left21:checkRetrieveDesc[usedRD] right21:checkRetrieveDesc[usedRD] )
        { op21.setRetrieveDesc(getCommonRetrieveDesc(left21, right21)); }

        // unary operations

    |   #( uop1:UNARY_PLUS  arg1:checkRetrieveDesc[usedRD] )
        {  uop1.setRetrieveDesc(arg1.getRetrieveDesc()); }
    |   #( uop2:UNARY_MINUS arg2:checkRetrieveDesc[usedRD] )
        {  uop2.setRetrieveDesc(arg2.getRetrieveDesc()); }
    |   #( uop3:BNOT        arg3:checkRetrieveDesc[usedRD] )
        {  uop3.setRetrieveDesc(arg3.getRetrieveDesc()); }
    |   #( uop4:LNOT        arg4:checkRetrieveDesc[usedRD] )
        {  uop4.setRetrieveDesc(arg4.getRetrieveDesc()); }
    |   #( d:DISTINCT arg5:checkRetrieveDesc[usedRD] )
        {  d.setRetrieveDesc(arg5.getRetrieveDesc()); }
    |   #( avg:AVG arg6:checkRetrieveDesc[usedRD] )
        {  avg.setRetrieveDesc(arg6.getRetrieveDesc()); }
    |   #( max:MAX arg7:checkRetrieveDesc[usedRD] )
        {  max.setRetrieveDesc(arg7.getRetrieveDesc()); }
    |   #( min:MIN arg8:checkRetrieveDesc[usedRD] )
        {  min.setRetrieveDesc(arg8.getRetrieveDesc()); }
    |   #( sum:SUM arg9:checkRetrieveDesc[usedRD] )
        {  sum.setRetrieveDesc(arg9.getRetrieveDesc()); }
    |   #( count:COUNT arg10:checkRetrieveDesc[usedRD] )
        {  count.setRetrieveDesc(arg10.getRetrieveDesc()); }
    |   .
    ; 
