/*
 * 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
 */

/*
 * Optimizer.g
 *
 * Created on June 11, 2001
 */

header
{
    package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc;
    
    import java.util.*;
    
    import java.math.BigDecimal;
    import java.math.BigInteger;

    import com.sun.jdo.api.persistence.support.JDOFatalUserException;
    import org.glassfish.persistence.common.I18NHelper;
    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 optimizer pass of the JQL compiler.
 * It takes the typed AST as produced by the smenatic analysis and
 * converts it into a simpler but equivalent typed AST.
 * 
 * @author  Michael Bouschen
 * @version 0.1
 */
class Optimizer extends TreeParser;

options
{
    importVocab = JQL;
    buildAST = true;
    defaultErrorHandler = false;
    ASTLabelType = "JQLAST"; //NOI18N
}

{
    /**
     * I18N support
     */
    protected final static ResourceBundle messages = 
        I18NHelper.loadBundle(Optimizer.class);
    
    /**
     * type table 
     */
    protected TypeTable typetab;
    
    /**
     * query parameter table
     */
    protected ParameterTable paramtab;
    
    /**
     *
     */
    protected ErrorMsg errorMsg;

    /**
     *
     */
    public void init(TypeTable typetab, ParameterTable paramtab, 
                     ErrorMsg errorMsg)
    {
        this.typetab = typetab;
        this.paramtab = paramtab;
        this.errorMsg = errorMsg;
    }

    /**
     *
     */
    public void reportError(RecognitionException ex) {
        errorMsg.fatal("Optimizer error", ex); //NOI18N
    }

    /**
     *
     */
    public void reportError(String s) {
        errorMsg.fatal("Optimizer error: " + s); //NOI18N
    }

    /**
     * Converts the string argument into a single char.
     */
    protected static char parseChar(String text)
    {
        char first = text.charAt(0);
        if (first == '\\')
        {
            //found escape => check the next char
            char second = text.charAt(1);
            switch (second)
            {
            case 'n': return '\n';
            case 'r': return '\r';
            case 't': return '\t';
            case 'b': return '\b';
            case 'f': return '\f';
            case 'u': 
                // unicode spec
                return (char)Integer.parseInt(text.substring(2, text.length()), 16);
            case '0':            
            case '1':
            case '2':
            case '3':            
            case '4':
            case '5':            
            case '6':
            case '7': 
                // octal spec 
                return (char)Integer.parseInt(text.substring(1, text.length()), 8);
            default : return second;
            }
        }
        return first;
    }
    

    /**
     * Check an AND operation (BAND, AND) for constant operands 
     * that could be optimized.
     * @param op the AND operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkAnd(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if (isBooleanValueAST(left))
        {
            ast = handleValueAndExpr(op, left.getValue(), right);
        }
        else if (isBooleanValueAST(right))
        {
            ast = handleValueAndExpr(op, right.getValue(), left);
        }
        return ast;
    }

    /**
     * Check an OR operation (BOR, OR) for constant operands 
     * that could be optimized.
     * @param op the OR operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkOr(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if (isBooleanValueAST(left))
        {
            ast = handleValueOrExpr(op, left.getValue(), right);
        }
        else if (isBooleanValueAST(right))
        {
            ast = handleValueOrExpr(op, right.getValue(), left);
        }
        return ast;
    }

    /**
     * Check a equality operation (EQUAL, NOT_EQUAL) for constant operands
     * that could be optimized.
     * @param op the equality operator
     * @param left the left operand
     * @param right the right operand
     * @param negate true for not equal operation, false otherwise
     * @return optimized JQLAST 
     */
    protected JQLAST checkEqualityOp(JQLAST op, JQLAST left, JQLAST right, 
                                     boolean negate)
    {
        JQLAST ast = op;

        // case <VALUE> <op> <VALUE> 
        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            ast = handleValueEqValue(op, left, right, negate);
        }
        // case <boolean VALUE> <op> <expr>
        else if (isBooleanValueAST(left))
        {
            ast = handleBooleanValueEqExpr(op, left.getValue(), right, negate);
        }
        // case <expr> <op> <boolean VALUE>
        else if (isBooleanValueAST(right))
        {
            ast = handleBooleanValueEqExpr(op, right.getValue(), left, negate);
        }
        return ast;
    }

    /**
     * Check a object equality operation (OBJECT_EQUAL, OBJECT_NOT_EQUAL) 
     * for constant operands that could be optimized.
     * @param op the object equality operator
     * @param left the left operand
     * @param right the right operand
     * @param negate true for not equal operation, false otherwise
     * @return optimized JQLAST 
     */
    protected JQLAST checkObjectEqualityOp(JQLAST op, JQLAST left, JQLAST right,
                                           boolean negate)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            ast = handleValueEqValue(op, left, right, negate);
        }
        return ast;
    }

    /**
     * Check a collection equality operation (COLLECTION_EQUAL, 
     * COLLECTION_NOT_EQUAL) for constant operands that could be optimized.
     * @param op the collection equality operator
     * @param left the left operand
     * @param right the right operand
     * @param negate true for not equal operation, false otherwise
     * @return optimized JQLAST 
     */
    protected JQLAST checkCollectionEqualityOp(JQLAST op, JQLAST left, 
                                               JQLAST right, boolean negate)
    {
        JQLAST ast = op;
        boolean isLeftConstant = (left.getType() == VALUE);
        boolean isRightConstant = (right.getType() == VALUE);
        
        if (isLeftConstant && isRightConstant)
        {
            ast = handleValueEqValue(op, left, right, negate);
        }
        else if ((isLeftConstant && (left.getValue() == null) && isNonConstantCollection(right)) || 
                 (isRightConstant && (right.getValue() == null) && isNonConstantCollection(left))) 
        {
            // This optimization is datastore dependend. 
            // In TP we know a collection returned by the datastore is never null.
            // null == <collection field> -> false
            // <collection field> == null -> false
            // null != <collection field> -> true
            // <collection field> != null -> true
            ast.setType(VALUE);
            ast.setValue(new Boolean(negate));
            ast.setFirstChild(null);
        }

        return ast;
    }

    /**
     * Check a logical not operation (LNOT) for a constant operand 
     * that could be optimized.
     * @param op the logical not operator
     * @param arg the operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkLogicalNotOp(JQLAST op, JQLAST arg)
    {
        JQLAST ast = op;

        if (arg.getType() == VALUE)
        {
            // !value may be calculated at compile time.
            Object valueObj = arg.getValue();
            boolean value = (valueObj instanceof Boolean) ? 
                            ((Boolean)valueObj).booleanValue() : false;
            arg.setType(VALUE);
            arg.setValue(new Boolean(!value));
            arg.setNextSibling(null);
            ast = arg;
        }
        else
        {
            ast = deMorgan(arg);
        }
        return ast;
    }

    /**
     * Check a binary plus operation (PLUS) for constant operands
     * that could be optimized.
     * @param op the plus operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkBinaryPlusOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (leftValue == null)
                value = rightValue;
            else if (rightValue == null)
                value = leftValue;
            else
            {
                Type type = op.getJQLType();
                
                if (type instanceof NumericWrapperClassType)
                    type = ((NumericWrapperClassType)type).getPrimitiveType();
                
                if (type.equals(typetab.intType))
                    value = new Integer(((Number)leftValue).intValue() + 
                        ((Number)rightValue).intValue());
                else if (type.equals(typetab.longType))
                    value = new Long(((Number)leftValue).longValue() + 
                        ((Number)rightValue).longValue());
                else if (type.equals(typetab.floatType))
                    value = new Float(((Number)leftValue).floatValue() + 
                        ((Number)rightValue).floatValue());
                else if (type.equals(typetab.doubleType))
                    value = new Double(((Number)leftValue).doubleValue() + 
                        ((Number)rightValue).doubleValue());
                else if (type.equals(typetab.bigDecimalType))
                    value = getBigDecimalValue(leftValue).add(
                       getBigDecimalValue(rightValue));
                else if (type.equals(typetab.bigIntegerType))
                    value = getBigIntegerValue(leftValue).add(
                        getBigIntegerValue(rightValue));
                else 
                    errorMsg.fatal(I18NHelper.getMessage(messages,
                        "jqlc.optimizer.checkbinaryplusop.invalidtype", //NOI18N
                        String.valueOf(type)));
            }
            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }
    
    /**
     * Check a string concatenation operation (CONCAT) for constant operands
     * that could be optimized.
     * @param op the concat operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkConcatOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (leftValue == null)
                value = rightValue;
            else if (rightValue == null)
                value = leftValue;
            else 
                value = leftValue.toString() + rightValue.toString();
            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }

    /**
     * Check a binary minus operation (MINUS) for constant operands
     * that could be optimized.
     * @param op the minus operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkBinaryMinusOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (rightValue == null)
                value = leftValue;
            else
            {
                if (leftValue == null)
                    leftValue = new Integer(0);
                
                Type type = op.getJQLType();
                
                if (type instanceof NumericWrapperClassType)
                    type = ((NumericWrapperClassType)type).getPrimitiveType();
                
                if (type.equals(typetab.intType))
                    value = new Integer(((Number)leftValue).intValue() -
                        ((Number)rightValue).intValue());
                else if (type.equals(typetab.longType))
                    value = new Long(((Number)leftValue).longValue() -
                        ((Number)rightValue).longValue());
                else if (type.equals(typetab.floatType))
                    value = new Float(((Number)leftValue).floatValue() - 
                        ((Number)rightValue).floatValue());
                else if (type.equals(typetab.doubleType))
                    value = new Double(((Number)leftValue).doubleValue() - 
                        ((Number)rightValue).doubleValue());
                else if (type.equals(typetab.bigDecimalType))
                    value = getBigDecimalValue(leftValue).subtract(
                       getBigDecimalValue(rightValue));
                else if (type.equals(typetab.bigIntegerType))
                    value = getBigIntegerValue(leftValue).subtract(
                        getBigIntegerValue(rightValue));
                else 
                    errorMsg.fatal(I18NHelper.getMessage(messages,
                        "jqlc.optimizer.checkbinaryminusop.invalidtype", //NOI18N
                        String.valueOf(type)));
            }
            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }
    
    /**
     * Check a binary multiplication operation (STAR) for constant operands
     * that could be optimized.
     * @param op the multiplication operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkMultiplicationOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (leftValue == null)
                leftValue = new Integer(0);
            if (rightValue == null)
                rightValue = new Integer(0);
            Type type = op.getJQLType();
                
            if (type instanceof NumericWrapperClassType)
                type = ((NumericWrapperClassType)type).getPrimitiveType();
                
            if (type.equals(typetab.intType))
                value = new Integer(((Number)leftValue).intValue() *
                    ((Number)rightValue).intValue());
            else if (type.equals(typetab.longType))
                value = new Long(((Number)leftValue).longValue() *
                    ((Number)rightValue).longValue());
            else if (type.equals(typetab.floatType))
                value = new Float(((Number)leftValue).floatValue() * 
                    ((Number)rightValue).floatValue());
            else if (type.equals(typetab.doubleType))
                value = new Double(((Number)leftValue).doubleValue() * 
                    ((Number)rightValue).doubleValue());
            else if (type.equals(typetab.bigDecimalType))
                value = getBigDecimalValue(leftValue).multiply(
                    getBigDecimalValue(rightValue));
            else if (type.equals(typetab.bigIntegerType))
                value = getBigIntegerValue(leftValue).multiply(
                    getBigIntegerValue(rightValue));
            else 
                errorMsg.fatal(I18NHelper.getMessage(messages,
                    "jqlc.optimizer.checkmultiplicationop.invalidtype", //NOI18N
                    String.valueOf(type)));

            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }
    
    /**
     * Check a binary division operation (DIV) for constant operands
     * that could be optimized.
     * @param op the division operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkDivisionOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (leftValue == null)
                leftValue = new Integer(0);
            if (rightValue == null)
                // division by zero!
                rightValue = new Integer(0);

            Type type = op.getJQLType();
            
            if (type instanceof NumericWrapperClassType)
                type = ((NumericWrapperClassType)type).getPrimitiveType();
                
            if (type.equals(typetab.intType))
                value = new Integer(((Number)leftValue).intValue() /
                    ((Number)rightValue).intValue());
            else if (type.equals(typetab.longType))
                value = new Long(((Number)leftValue).longValue() /
                    ((Number)rightValue).longValue());
            else if (type.equals(typetab.floatType))
                value = new Float(((Number)leftValue).floatValue() / 
                    ((Number)rightValue).floatValue());
            else if (type.equals(typetab.doubleType))
                value = new Double(((Number)leftValue).doubleValue() / 
                    ((Number)rightValue).doubleValue());
            else if (type.equals(typetab.bigDecimalType))
                value = getBigDecimalValue(leftValue).divide(
                   getBigDecimalValue(rightValue), BigDecimal.ROUND_HALF_EVEN);
            else if (type.equals(typetab.bigIntegerType))
                value = getBigIntegerValue(leftValue).divide(
                    getBigIntegerValue(rightValue));
            else 
                errorMsg.fatal(I18NHelper.getMessage(messages,
                    "jqlc.optimizer.checkdivisionop.invalidtype", //NOI18N
                    String.valueOf(type)));

            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }
    
    /**
     * Check a binary modular operation (MOD) for constant operands
     * that could be optimized.
     * @param op the mod operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkModOp(JQLAST op, JQLAST left, JQLAST right)
    {
        JQLAST ast = op;

        if ((left.getType() == VALUE) && (right.getType() == VALUE))
        {
            Object leftValue = left.getValue();
            Object rightValue = right.getValue();
            Object value = null;
            if (leftValue == null)
                leftValue = new Integer(0);
            if (rightValue == null)
                // division by zero!
                rightValue = new Integer(0);

            Type type = op.getJQLType();
            
            if (type instanceof NumericWrapperClassType)
                type = ((NumericWrapperClassType)type).getPrimitiveType();
                
            if (type.equals(typetab.intType))
                value = new Integer(((Number)leftValue).intValue() %
                    ((Number)rightValue).intValue());
            else if (type.equals(typetab.longType))
                value = new Long(((Number)leftValue).longValue() %
                    ((Number)rightValue).longValue());
            else if (type.equals(typetab.floatType))
                value = new Float(((Number)leftValue).floatValue() % 
                    ((Number)rightValue).floatValue());
            else if (type.equals(typetab.doubleType))
                value = new Double(((Number)leftValue).doubleValue() % 
                    ((Number)rightValue).doubleValue());
            else if (type.equals(typetab.bigDecimalType))
            {
                BigDecimal leftBigDecimal = getBigDecimalValue(leftValue);
                BigDecimal rightBigDecimal = getBigDecimalValue(rightValue);
                //use ROUND_HALF_EVEN so that it is consistent with div
                BigDecimal quotient = leftBigDecimal.divide(rightBigDecimal,
                    0, BigDecimal.ROUND_HALF_EVEN);
                value = leftBigDecimal.subtract(
                    rightBigDecimal.multiply(quotient));
            }
            else if (type.equals(typetab.bigIntegerType))
                value = getBigIntegerValue(leftValue).remainder(
                    getBigIntegerValue(rightValue));
            else 
                errorMsg.fatal(I18NHelper.getMessage(messages,
                    "jqlc.optimizer.checkmodop.invalidtype", //NOI18N
                    String.valueOf(type)));

            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }

    /**
     * Check a unary minus operation (UNARY_MINUS) for a constant operand
     * that could be optimized.
     * @param op the unary minus operator
     * @param arg the operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkUnaryMinusOp(JQLAST op, JQLAST arg)
    {
        JQLAST ast = op;
        
        if (arg.getType() == VALUE)
        {
            Object value = arg.getValue();
            Type type = op.getJQLType();
            Object negate = null;
            
            if (type instanceof NumberType)
                negate = ((NumberType)type).negate((Number)value);
            else 
                errorMsg.fatal(I18NHelper.getMessage(messages,
                    "jqlc.optimizer.checkunaryminusop.invalidtype", //NOI18N
                    String.valueOf(type)));
            
            ast.setType(VALUE);
            ast.setValue(negate);
            ast.setFirstChild(null);
        }
        return ast;
    }

    /**
     * Check a cast operation for a constant operand
     * that could be optimized.
     * @param op the cast operator
     * @param castType the cast type
     * @param expr the non constant operand
     * @return optimized JQLAST 
     */
    protected JQLAST checkCastOp(JQLAST op, JQLAST castType, JQLAST expr)
    {
        JQLAST ast = op;
        
        if (expr.getType() == VALUE)
        {
            Object value = expr.getValue();
            Type type = op.getJQLType();
            if (type instanceof NumericWrapperClassType)
                type = ((NumericWrapperClassType)type).getPrimitiveType();
                
            if (type.equals(typetab.intType))
                value = new Integer(((Number)value).intValue());
            else if (type.equals(typetab.longType))
                value = new Long(((Number)value).longValue());
            else if (type.equals(typetab.floatType))
                value = new Float(((Number)value).floatValue());
            else if (type.equals(typetab.doubleType))
                value = new Double(((Number)value).doubleValue());
            else if (type.equals(typetab.bigDecimalType))
                value = getBigDecimalValue(value);
            else if (type.equals(typetab.bigIntegerType))
                value = getBigIntegerValue(value);
            else if (type.equals(typetab.byteType))
                value = new Byte((byte)((Number)value).intValue());
            else if (type.equals(typetab.shortType))
                value = new Short((short)((Number)value).intValue());
            else if (type.equals(typetab.charType))
                value = new Character((char)((Number)value).intValue());
            
            // If non of the above type applies, leave the value as it is

            // convert the TYPECAST op into a VALUE
            ast.setType(VALUE);
            ast.setValue(value);
            ast.setFirstChild(null);
        }
        return ast;
    }

    /**
     * Converts the specified value into a BigDecimal value. 
     * @param value value to be converted
     * @return BigDecimal representation
     */
    protected BigDecimal getBigDecimalValue(Object value)
    {
        BigDecimal ret = null;
        if (value instanceof Number)
            ret = (BigDecimal)typetab.bigDecimalType.getValue((Number)value);
        else
            errorMsg.fatal(I18NHelper.getMessage(messages,
                "jqlc.optimizer.getbigdecimalvalue.notnumber", //NOI18N
                String.valueOf(value)));

        return ret;
    }

    /**
     * Converts the specified value into a BigInteger value. 
     * @param value value to be converted
     * @return BigInteger representation
     */
    protected BigInteger getBigIntegerValue(Object value)
    {
        BigInteger ret = null;

        if (value instanceof Number)
            ret = (BigInteger)typetab.bigIntegerType.getValue((Number)value);
        else
            errorMsg.fatal(I18NHelper.getMessage(messages,
                "jqlc.optimizer.getbigintegervalue.notnumber", //NOI18N
                String.valueOf(value)));

        return ret;
    }
    
    /**
     * This method is called in the case of an equality operation having two 
     * constant operands. It calculates the result of this constant operation 
     * and returns a JQLAST node representing a constant boolean value.
     * @param op the equality operator
     * @param left the left operand
     * @param right the right operand
     * @param negate true for not equal operation, false otherwise
     * @return optimized JQLAST 
     */
    protected JQLAST handleValueEqValue(JQLAST op, JQLAST left, JQLAST right, 
                                        boolean negate)
    {
        Object leftValue = left.getValue();
        Object rightValue = right.getValue();
        boolean value = false;
        
        if ((leftValue == null) && (rightValue == null))
        {
            // both values are null -> true
            value = true;
        }
        else if ((leftValue != null) && (rightValue != null))
        {
            // both values are not null -> use equals
            value = leftValue.equals(rightValue);
        }
        else
        {
            // one value is null, the other is not null -> false
            value = false;
        }
        if (negate) 
        {
            value = !value;
        }
        op.setType(VALUE);
        op.setValue(new Boolean(value));
        op.setFirstChild(null);
        return op;
    }

    /**
     * This method is called in the case of an equality operation having 
     * a boolean constant operand and a non constant operand. 
     * It returns the non constant operand either as it is or inverted, 
     * depending on the equality operation.
     * @param op the equality operator
     * @param value the contant boolean value
     * @param expr the non constant operand
     * @param negate true for not equal operation, false otherwise
     * @return optimized JQLAST 
     */
    private JQLAST handleBooleanValueEqExpr(JQLAST op, Object value, 
                                            JQLAST expr, boolean negate)
    {
        JQLAST ast;
        boolean skip = (value instanceof Boolean) ? 
                       ((Boolean)value).booleanValue() : false;
        if (negate) skip = !skip;

        if (skip)
        {
            // expr == true -> expr
            // expr != false -> expr
            ast = expr;
        }
        else 
        {
            // if expr is a equality op or a not op the invert operation may be "inlined":
            //   (expr1 == expr2) != true -> expr1 != expr2
            //   (expr1 != expr2) != true -> expr1 == expr2
            //   !expr != true -> expr
            //   !expr == false -> expr
            // Otherwise wrap the expr with a not op
            //   expr != true -> !expr
            //   expr == false -> !expr
            switch (expr.getType())
            {
            case EQUAL:
                expr.setType(NOT_EQUAL);
                expr.setText("!="); //NOI18N
                ast = expr;
                break;
            case NOT_EQUAL:
                expr.setType(EQUAL);
                expr.setText("=="); //NOI18N
                ast = expr;
                break;
            case LNOT:
                ast = (JQLAST)expr.getFirstChild();
                break;
            default:
                op.setType(LNOT);
                op.setText("!"); //NOI18N
                op.setFirstChild(expr);
                ast = op;
            }
            expr.setNextSibling(null);
        }
        return ast;
    }

    /**
     * This method is called in the case of an AND operation having at least 
     * one constant operand. If the constant operand evaluates to true it 
     * returns the other operand. If it evaluates to false it returns an AST
     * representing the constant boolean value false.
     * @param op the AND operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    private JQLAST handleValueAndExpr(JQLAST op, Object value, JQLAST expr)
    {
        JQLAST ast;

        if ((value instanceof Boolean) && ((Boolean)value).booleanValue())
        {
            // true AND expr -> expr
            // expr AND true -> expr
            expr.setNextSibling(null);
            ast = expr;
        }
        else
        {
            // false AND expr -> false
            // expr AND false -> false
            op.setType(VALUE);
            op.setText("false"); //NOI18N
            op.setValue(new Boolean(false));
            op.setFirstChild(null);
            ast = op;
        }
        return ast;
    }

    /**
     * This method is called in the case of an OR operation having at least 
     * one constant operand. If the constant operand evaluates to false it 
     * returns the other operand. If it evaluates to true it returns an AST
     * representing the constant boolean value true.
     * @param op the AND operator
     * @param left the left operand
     * @param right the right operand
     * @return optimized JQLAST 
     */
    private JQLAST handleValueOrExpr(JQLAST op, Object value, JQLAST expr)
    {
        JQLAST ast;

        if ((value instanceof Boolean) && ((Boolean)value).booleanValue())
        {
            // true OR expr -> true
            // expr OR true -> true
            op.setType(VALUE);
            op.setText("true"); //NOI18N
            op.setValue(new Boolean(true));
            op.setFirstChild(null);
            ast = op;
        }
        else
        {
            // false OR expr -> expr
            // expr OR false -> expr
            expr.setNextSibling(null);
            ast = expr;
        }
        return ast;
    }

    /**
     * Returns true if the specified AST represents a constant boolean value.
     */
    protected boolean isBooleanValueAST(JQLAST ast)
    {
        return (ast.getType() == VALUE) && 
               (typetab.booleanType.equals(ast.getJQLType()));
    }

    /**
     * Returns true if the specified AST represents a datastore value. 
     */
    protected boolean isNonConstantCollection(JQLAST ast)
    {
        switch (ast.getType())
        {
        case FIELD_ACCESS :
        case NAVIGATION :
            return true;
        case TYPECAST :
            JQLAST expr = (JQLAST)ast.getFirstChild().getNextSibling();
            return isNonConstantCollection(expr);
        default:
            return false;
        }
    }

    /**
     * Implements DeMorgans rule: 
     * <br>
     * NOT (a AND b) -> NOT a OR NOT b
     * <br>
     * NOT (a OR b) -> NOT a AND NOT b
     * <br>
     * NOT (NOT a) -> a
     * <br>
     * The method assumes that the tree passed as an argument does not include 
     * the initial NOT. Note, this method checks for contains clauses, because 
     * they require special treatement.
     */
    protected JQLAST deMorgan(JQLAST tree)
    {
        JQLAST result = null;
        JQLAST left = null;
        JQLAST right = null;
        switch (tree.getType()) 
        {
        case AND:
        case BAND:
            left = (JQLAST)tree.getFirstChild();
            right = (JQLAST)left.getNextSibling();
            String leftVar = getVariableFromContainsClause(left);
            String rightVar = getVariableFromContainsClause(right);
            if (leftVar != null)
            {
                // found AND ( CONTAINS, right ), so check right for special
                // variable treatement
                result = buildAST(tree, left, deMorgan(right, leftVar));
            }
            else if (rightVar != null)
            {
                // found AND ( left, CONTAINS, ), so check left for special
                // variable treatement
                result = buildAST(tree, right, deMorgan(left, rightVar));
            }
            else
            {
                invertNode(tree);
                result = buildAST(tree, deMorgan(left), deMorgan(right));
            }
            break;
        case OR:
        case BOR:
            left = (JQLAST)tree.getFirstChild();
            right = (JQLAST)left.getNextSibling();
            invertNode(tree);
            result = buildAST(tree, deMorgan(left), deMorgan(right));
            break;
        case LNOT:
            // This is !(!arg) => return arg
            result = (JQLAST)tree.getFirstChild();
            break;
        default:
            // wrap arg into not operator
            result = buildAST(new JQLAST(LNOT, "!", typetab.booleanType), tree);
            break;
        }       
        return result;
    }

    /**
     * This overloaded deMorgan method implements special treatment of variable 
     * access expressions in the case of !contains. The method keeps an expression
     * accessing the specified variable as it is, but it inverts an expression NOT
     * accessing the variable following regular DeMorgan rules.
     */
    protected JQLAST deMorgan(JQLAST tree, String var)
    {
        JQLAST result = tree;
        switch (tree.getType()) 
        {
        case AND:
        case BAND:
        case OR:
        case BOR:
            JQLAST left = (JQLAST)tree.getFirstChild();
            JQLAST right = (JQLAST)left.getNextSibling();
            if (!includesVariableAccess(left, var) ||
                !includesVariableAccess(right, var))
            {
                invertNode(tree);
            }
            result = buildAST(tree, deMorgan(left, var), deMorgan(right, var));
            break;
        default:
            if (!includesVariableAccess(tree, var))
            {
                result = deMorgan(tree);
            }
            break;
        }
        return result;
    }

    /** 
     * Checks the specified tree being a CONATAINS clause. If yes it returns 
     * the variable used in the contains clause. Otherwise it returns null.
     */
    protected String getVariableFromContainsClause(JQLAST tree)
    {
        switch (tree.getType())
        {
        case CONTAINS:
        case NOT_CONTAINS:
            return tree.getFirstChild().getNextSibling().getText();
        default:
            return null;
        }
    }
    
    /**
     * Checks whether the specified tree accesses the variable with the 
     * specified name. Accessing means either this node or of of the subnodes 
     * has the type VARIABLE. 
     * NOTE, the method is intended to be used in the ! contains case only!
     * If it find a variable access node of the form
     * <br>
     * #(VARIABLE collection)
     * it maps it to
     * #(VARIABLE #(NOT_IN (collection))
     * <br>
     * This incdicates a variable belonging to a !contains clause.
     */
    protected boolean includesVariableAccess(AST tree, String var)
    {
        if ((tree == null) || (var == null))
            return false;

        boolean found = false;
        JQLAST child = (JQLAST)tree.getFirstChild();
        if ((tree.getType() == VARIABLE) && (tree.getText().equals(var)) && 
            (child != null))
        {
            found = true;
            if (child.getType() != NOT_IN)
            {
                tree.setFirstChild(buildAST(
                    new JQLAST(NOT_IN, "notIn", typetab.booleanType), child));
            }
        }
        for (AST node = tree.getFirstChild(); node != null; node = node.getNextSibling())
        {
            if (includesVariableAccess(node, var))
                found = true;
        }
        return found;
    }

    /** 
     * Inverts the specified node: AND -> OR, == -> !=, etc.
     */
    protected void invertNode(JQLAST node)
    {
        switch(node.getType())
        {
        case AND:
            node.setType(OR);
            node.setText("||");
            break;
        case BAND:
            node.setType(BOR);
            node.setText("|");
            break;
        case OR:
            node.setType(AND);
            node.setText("&&");
            break;
        case BOR:
            node.setType(BAND);
            node.setText("&");
            break;
        case EQUAL:
            node.setType(NOT_EQUAL);
            node.setText("!=");
            break;
        case NOT_EQUAL:
            node.setType(EQUAL);
            node.setText("==");
            break;
        case LT:
            node.setType(GE);
            node.setText(">=");
            break;
        case LE:
            node.setType(GT);
            node.setText(">");
            break;
        case GT:
            node.setType(LE);
            node.setText("<=");
            break;
        case GE:
            node.setType(LT);
            node.setText("<");
            break;
        }
    }

    /** Builds a binary tree. */
    protected JQLAST buildAST(JQLAST root, JQLAST left, JQLAST right)
    {
        root.setFirstChild(left);
        left.setNextSibling(right);
        right.setNextSibling(null);
        return root;
    }

    /** */
    protected JQLAST buildAST(JQLAST root, JQLAST arg)
    {
        root.setFirstChild(arg);
        arg.setNextSibling(null);
        return root;
    }
}

// rules

query
    :   #(  q:QUERY
            candidateClass
            parameters
            variables
            ordering
            result
            filter
        )
    ;

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

candidateClass
{   
    errorMsg.setContext("setCandidates"); //NOI18N
}
    :   CLASS_DEF
    ;

// ----------------------------------
// 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 IDENT )
    ;

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

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

orderSpec
    :   #(  ORDERING_DEF ( ASCENDING | DESCENDING ) expression )
    ;

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

result
{   
    errorMsg.setContext("setResult"); //NOI18N
}
    :   #( r:RESULT_DEF resultExpr )
    |   // empty rule
    ;

resultExpr
    :   #( DISTINCT resultExpr )
    |   #( AVG resultExpr )
    |   #( MAX resultExpr )
    |   #( MIN resultExpr )
    |   #( SUM resultExpr )
    |   #( COUNT resultExpr )
    |   expression
    ;

// ----------------------------------
// rules: filer expression
// ----------------------------------

filter
{   
    errorMsg.setContext("setFilter"); //NOI18N
}
    :   #( FILTER_DEF expression )
    ;

expression 
    :   primary
    |   bitwiseExpr
    |   conditionalExpr
    |   relationalExpr
    |   binaryArithmeticExpr
    |   unaryArithmeticExpr
    |   complementExpr
    ;

bitwiseExpr 
    :   #( op1:BAND left1:expression right1:expression )
        {
            #bitwiseExpr = checkAnd(#op1, #left1, #right1);
        }
    |   #( op2:BOR  left2:expression right2:expression )
        {
            #bitwiseExpr = checkOr(#op2, #left2, #right2);
        }
    |   #( op3:BXOR left3:expression right3:expression )
    ;

conditionalExpr 
    :   #( op1:AND left1:expression right1:expression )
        {
            #conditionalExpr = checkAnd(#op1, #left1, #right1);
        }
    |   #( op2:OR  left2:expression right2:expression )
        {
            #conditionalExpr = checkOr(#op2, #left2, #right2);
        }
   ;

relationalExpr
    :   #( op1:EQUAL left1:expression right1:expression )
        {
            #relationalExpr = checkEqualityOp(#op1, #left1, #right1, false);
        }
    |   #( op2:NOT_EQUAL left2:expression right2:expression )
        {
            #relationalExpr = checkEqualityOp(#op2, #left2, #right2, true);
        }
    |   #( op3:OBJECT_EQUAL left3:expression right3:expression ) 
        {
            #relationalExpr = checkObjectEqualityOp(#op3, #left3, #right3, false);
        }
    |   #( op4:OBJECT_NOT_EQUAL left4:expression right4:expression )
        {
            #relationalExpr = checkObjectEqualityOp(#op4, #left4, #right4, true);
        }
    |   #( op5:COLLECTION_EQUAL left5:expression right5:expression )
        {
            #relationalExpr = checkCollectionEqualityOp(#op5, #left5, #right5, false);
        }
    |   #( op6:COLLECTION_NOT_EQUAL left6:expression right6:expression )
        {
            #relationalExpr = checkCollectionEqualityOp(#op6, #left6, #right6, true);
        }
    |   #( LT expression expression )
    |   #( GT expression expression )
    |   #( LE expression expression )
    |   #( GE expression expression )
    ;

binaryArithmeticExpr 
    :   #( op1:PLUS   left1:expression right1:expression )
        {
            #binaryArithmeticExpr = checkBinaryPlusOp(#op1, #left1, #right1);
        }
    |   #( op2:CONCAT left2:expression right2:expression )
        {
            #binaryArithmeticExpr = checkConcatOp(#op2, #left2, #right2);
        }
    |   #( op3:MINUS  left3:expression right3:expression )
        {
            #binaryArithmeticExpr = checkBinaryMinusOp(#op3, #left3, #right3);
        }
    |   #( op4:STAR   left4:expression right4:expression )
        {
            #binaryArithmeticExpr = checkMultiplicationOp(#op4, #left4, #right4);
        }
    |   #( op5:DIV    left5:expression right5:expression )
        {
            #binaryArithmeticExpr = checkDivisionOp(#op5, #left5, #right5);
        }
    |   #( op6:MOD    left6:expression right6:expression )
        {
            #binaryArithmeticExpr = checkModOp(#op6, #left6, #right6);
        }
    ;

unaryArithmeticExpr 
    :   #( UNARY_PLUS expression )
    |   ( unaryMinusLiteralExpr )=> unaryMinusLiteralExpr
    |   #( op2:UNARY_MINUS arg2:expression )
        {
            #unaryArithmeticExpr = checkUnaryMinusOp(#op2, #arg2);
        }
    ;

unaryMinusLiteralExpr
    :   #( UNARY_MINUS ( i:INT_LITERAL | l:LONG_LITERAL ) )
        {
            JQLAST li = (#i != null) ? #i : #l;
            li.setText("-" + li.getText());
            // calling literal here directly does not work properly
            // the following logic need to be in sync with that of literal
            li.setValue(#literalHelper(li));
            li.setType(VALUE);
            #unaryMinusLiteralExpr = #li;
        }
    ;

complementExpr 
    :   #( op1:BNOT arg1:expression )
    |   #( op2:LNOT arg2:expression )
        {
            #complementExpr = checkLogicalNotOp(#op2, #arg2);
        }
    ;

primary 
    :   castExpr
    |   literal
    |   VALUE
    |   THIS
    |   parameter
    |   staticFieldAccess
    |   fieldAccess
    |   navigation
    |   variableAccess
    |   #( CONTAINS expression VARIABLE )
    |   #( NOT_CONTAINS expression VARIABLE )
    |   startsWith
    |   endsWith
    |   isEmpty
    |   like
    |   substring
    |   indexOf
    |   length
    |   abs
    |   sqrt
    ;

castExpr
    :   #( c:TYPECAST t:type e:expression )
        {
            #castExpr = checkCastOp(#c, #t, #e);
        }
    ;

literal
{ 
    Object value = null; 
}
    :   value = l:literalHelper
        {
            #l.setType(VALUE);
            #l.setValue(value);
        }
    ;

literalHelper returns [Object value]
{ 
    value = null; 
}
    :   TRUE
        { value = new Boolean(true); }
    |   FALSE
        { value = new Boolean(false); }
    |   i:INT_LITERAL
        {
            try
            {
                value = Integer.decode(i.getText());
            }
            catch (NumberFormatException ex)
            {
                errorMsg.error(i.getLine(), i.getColumn(),
                    I18NHelper.getMessage(messages, 
                        "jqlc.optimizer.literal.invalid",  //NOI18N
                        i.getJQLType().getName(), i.getText()));
            }
        }
    |   l:LONG_LITERAL
        {   
            String txt = l.getText();
            char last = txt.charAt(txt.length() - 1);
            if ((last == 'l') || (last == 'L'))
            {
                txt = txt.substring(0, txt.length() - 1);
            }
            try
            {
                value = Long.decode(txt);
            }
            catch (NumberFormatException ex)
            {
                errorMsg.error(l.getLine(), l.getColumn(),
                    I18NHelper.getMessage(messages, 
                        "jqlc.optimizer.literal.invalid",  //NOI18N
                        l.getJQLType().getName(), l.getText()));
            }
        }
    |   f:FLOAT_LITERAL
        {  
            String txt = f.getText();
            char last = txt.charAt(txt.length() - 1);
            if ((last == 'f') || (last == 'F'))
            {
                txt = txt.substring(0, txt.length() - 1);
            }
            try
            {
                value = new Float(txt);
            }
            catch (NumberFormatException ex)
            {
                errorMsg.error(f.getLine(), f.getColumn(),
                    I18NHelper.getMessage(messages, 
                        "jqlc.optimizer.literal.invalid",  //NOI18N
                        f.getJQLType().getName(), f.getText()));
            }
        }
    |   d:DOUBLE_LITERAL
        {  
            String txt = d.getText();
            char last = txt.charAt(txt.length() - 1);
            if ((last == 'd') || (last == 'd'))
            {
                txt = txt.substring(0, txt.length() - 1);
            }
            try
            {
                value = new Double(txt);
            }
            catch (NumberFormatException ex)
            {
                errorMsg.error(d.getLine(), d.getColumn(),
                    I18NHelper.getMessage(messages, 
                        "jqlc.optimizer.literal.invalid",  //NOI18N
                        d.getJQLType().getName(), d.getText()));
            }
        }
    |   c:CHAR_LITERAL
        { value = new Character(parseChar(c.getText())); }
    |   s:STRING_LITERAL
        { value = s.getText(); }
    |   n:NULL
        { value = null; }
    ;

parameter
    :   p:PARAMETER
        { 
            if (paramtab.inline(#p.getText())) {
                #p.setType(VALUE);
                #p.setValue(paramtab.getValueByName(#p.getText()));     
            }
        }
    ;

staticFieldAccess
{   
    Object value = null; 
}
    :   #( s:STATIC_FIELD_ACCESS t:TYPENAME i:IDENT)
        {
            // Calculate the value of the static field at compile time
            // and treat it as constant value.
            ClassType classType = (ClassType)t.getJQLType();
            FieldInfo fieldInfo = classType.getFieldInfo(i.getText());
            try
            {
                value = fieldInfo.getField().get(null);
                #s.setType(VALUE);
                #s.setValue(value);
                #s.setFirstChild(null);
            }
            catch (IllegalAccessException e) 
            {
                throw new JDOFatalUserException(
                    I18NHelper.getMessage(messages, 
                        "jqlc.optimizer.staticfieldaccess.illegal",  //NOI18N
                        i.getText(), classType.getName()), e);
            }
        }
    ;

fieldAccess
    :   #( f:FIELD_ACCESS o:expression name:IDENT )
        {
            if (#o.getType() == VALUE)
            {
                // If the object of the field access is a constant value, 
                // evaluate the field access at compile time and 
                // treat the expression as constant value.
                Object object = #o.getValue();
                ClassType classType = (ClassType)#o.getJQLType();
                Object value = CodeGeneration.getFieldValue(classType, object, 
                                                            #name.getText());
                #f.setType(VALUE);
                #f.setValue(value);
                #f.setFirstChild(null);
            }
        }
    ;

navigation
    :   #(  n:NAVIGATION o:expression name:IDENT )
        {
            if (#o.getType() == VALUE)
            {
                // If the object of the navigation is a constant value, 
                // evaluate the field access at compile time and 
                // treat the expression as constant value.
                Object object = #o.getValue();
                ClassType classType = (ClassType)#o.getJQLType();
                Object value = CodeGeneration.getFieldValue(classType, object, 
                                                            #name.getText());
                #n.setType(VALUE);
                #n.setValue(value);
                #n.setFirstChild(null);
            }
        }
    ;

variableAccess
    :   #( VARIABLE ( expression )? )
    ;

startsWith
    :   #( STARTS_WITH expression expression ) 
    ;

endsWith
    :   #( ENDS_WITH expression expression ) 
    ;

isEmpty
    :   #( op:IS_EMPTY e:expression)
        {
            if (#e.getType() == VALUE)
            {
                // If the expression that specifies the collection is a constant value, 
                // evaluate the isEmpty call at compile time and treat the expression 
                // as constant value.
                Object object = #e.getValue();
                Object value = null;
                if (object == null)
                {
                    value = new Boolean(false);
                }
                else if (object instanceof Collection)
                {
                    value = new Boolean(((Collection)object).isEmpty());
                }
                else
                {
                    errorMsg.fatal(I18NHelper.getMessage(messages, "jqlc.optimizer.isempty.requirecollection")); //NOI18N
                }
                #op.setType(VALUE);
                #op.setValue(value);
                #op.setFirstChild(null);
            }
        }
    ;

like
    :   #( LIKE expression expression ( expression )? ) 
    ;

substring
    :   #( SUBSTRING expression expression expression ) 
    ;

indexOf
    :   #( INDEXOF expression expression ( expression )? ) 
    ;

length
    :   #( LENGTH expression )
    ;

abs
    :   #( ABS expression )
    ;

sqrt
    :   #( SQRT expression )
    ;

// ----------------------
// types
// ----------------------

type
    :   TYPENAME
    |   primitiveType
    ;

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