/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.internal.expressions;

import java.io.*;
import java.util.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.history.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * Used for expressions that have 0 to n children.
 * These include not, between and all functions.
 */
public class FunctionExpression extends BaseExpression {
    protected Vector children;
    protected ExpressionOperator operator;
    protected transient ExpressionOperator platformOperator;
    protected Class resultType;

    public FunctionExpression() {
        this.children = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(2);
        this.resultType = null;
    }
    
    /**
     * INTERNAL:
     * Return if the expression is equal to the other.
     * This is used to allow dynamic expression's SQL to be cached.
     * This must be over written by each subclass.
     */
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!super.equals(object)) {
            return false;
        }
        FunctionExpression expression = (FunctionExpression) object;
        if ((this.operator != expression.getOperator()) && ((this.operator == null) || (!this.operator.equals(expression.getOperator())))) {
            return false;
        }
        List children = getChildren();
        List otherChildren = expression.getChildren();        
        int size = children.size();
        if (size != otherChildren.size()) {
            return false;
        }
        for (int index = 0; index < size; index++) {
            if (!children.get(index).equals(otherChildren.get(index))) {
                return false;
            }
        }
        return true;
    }
        
    /**
     * INTERNAL:
     * Compute a consistent hash-code for the expression.
     * This is used to allow dynamic expression's SQL to be cached.
     */
    public int computeHashCode() {
        int hashCode = super.computeHashCode();
        if (this.operator != null) {
            hashCode = hashCode + this.operator.hashCode();
        }
        List children = getChildren();     
        int size = children.size();
        for (int index = 0; index < size; index++) {
            hashCode = hashCode + children.get(index).hashCode();
        }
        return hashCode;
    }

    public void addChild(Expression child) {
        getChildren().addElement(child);
    }

    /**
     * INTERNAL:
     * Find the alias for a given table
     */
    public DatabaseTable aliasForTable(DatabaseTable table) {
        return getBaseExpression().aliasForTable(table);
    }

    public Expression asOf(AsOfClause clause) {
        final AsOfClause finalClause = clause;
        ExpressionIterator iterator = new ExpressionIterator() {
            public void iterate(Expression each) {
                if (each.isDataExpression()) {
                    each.asOf(finalClause);
                }
            }

            public boolean shouldIterateOverSubSelects() {
                return true;
            }
        };
        iterator.iterateOn(this);
        return this;
    }

    /**
     * INTERNAL:
     */
    public Expression create(Expression base, Object singleArgument, ExpressionOperator anOperator) {
        baseExpression = base;
        addChild(base);
        Expression localBase = base;
        if(anOperator.isFunctionOperator()) {
            ExpressionBuilder builder = getBuilder();
            if(builder != null) {
                localBase = builder;
            }
        }
        Expression arg = Expression.from(singleArgument, localBase);
        addChild(arg);
        setOperator(anOperator);
        return this;
    }
    
    /**
     * INTERNAL: 
     * added for Trim support.  TRIM([trim_character FROM] string_primary)
     */
    public Expression createWithBaseLast(Expression base, Object singleArgument, ExpressionOperator anOperator) {
        baseExpression = base;
        Expression localBase = base;
        if(anOperator.isFunctionOperator()) {
            ExpressionBuilder builder = getBuilder();
            if(builder != null) {
                localBase = builder;
            }
        }
        Expression arg = Expression.from(singleArgument, localBase);
        addChild(arg);
        addChild(base);
        setOperator(anOperator);
        return this;
    }

    /**
     * INTERNAL:
     */
    @Override
    public Expression create(Expression base, List arguments, ExpressionOperator anOperator) {
        this.baseExpression = base;
        setOperator(anOperator);
        addChild(base);
        Expression localBase = base;
        if (anOperator.isFunctionOperator()) {
            ExpressionBuilder builder = getBuilder();
            if (builder != null) {
                localBase = builder;
            }
        }
        for (Object argument : arguments) {
            Expression arg = Expression.from(argument, localBase);
            addChild(arg);
        }
        return this;
    }

    /**
     * INTERNAL:
     * Used for debug printing.
     */
    public String descriptionOfNodeType() {
        return "Function";
    }

    /**
     * INTERNAL:
     * Check if the object conforms to the expression in memory.
     * This is used for in-memory querying.
     * If the expression in not able to determine if the object conform throw a not supported exception.
     */
    public boolean doesConform(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) {
        int selector = this.operator.getSelector();
        
        // Must check for NOT and negate entire base expression.
        if (selector == ExpressionOperator.Not) {
            return !getBaseExpression().doesConform(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);
        }

        // Conform between or in function.
        if ((selector == ExpressionOperator.Between) || (selector == ExpressionOperator.NotBetween)
                || (selector == ExpressionOperator.In) || (selector == ExpressionOperator.NotIn) 
                || (selector == ExpressionOperator.Like) || (selector == ExpressionOperator.Regexp)
                || (selector == ExpressionOperator.NotLike)) {
            // Extract the value from the left side.
            Object leftValue = getBaseExpression().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);

            // Extract the value from the arguments, skip the first child which is the base.
            int size = this.children.size();
            Vector rightValue = new Vector(size);
            for (int index = 1; index < size; index++) {
                Object valueFromRight;
                Object child = this.children.get(index);
                if (child instanceof Expression) {
                    valueFromRight = ((Expression)child).valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);
                } else {
                    valueFromRight = child;
                }
                //If valueFromRight is a Vector, then there is only one child other than the base, e.g. valueFromRight is a collection of constants.  
                //Then it should be the vector to be compared with.  Don't add it to another collection.
                if (valueFromRight instanceof Vector) {
                    rightValue = (Vector)valueFromRight;
                //Single values should be added to the rightValue, which will be compared with leftValue.
                } else {
                    rightValue.add(valueFromRight);
                }
            }

            // If left is anyof collection of values, check each one.
            // If the right had an anyof not supported will be thrown from the operator.
            if (leftValue instanceof Vector) {
                for (Object tempLeft : (Vector)leftValue) {
                    if (this.operator.doesRelationConform(tempLeft, rightValue)) {
                        return true;
                    }
                }

                // Only return false if none of the values match.
                return false;
            } else {
                return this.operator.doesRelationConform(leftValue, rightValue);
            }
        } else if ((selector == ExpressionOperator.IsNull) || (selector == ExpressionOperator.NotNull)) {
            // Extract the value from the left side.
            Object leftValue = getBaseExpression().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);

            // If left is anyof collection of values, check each one.
            if (leftValue instanceof Vector) {
                for (Object tempLeft : (Vector)leftValue) {
                    if (this.operator.doesRelationConform(tempLeft, null)) {
                        return true;
                    }
                }

                // Only return false if none of the values match.
                return false;
            } else {
                return this.operator.doesRelationConform(leftValue, null);
            }
        }

        // No other relation functions are supported.
        // Non-relation functions are supported through valueFromObject().
        throw QueryException.cannotConformExpression();
    }

    public Vector getChildren() {
        return children;
    }

    /**
     * INTERNAL: Not to be confused with the public getField(String)
     * This returns a collection of all fields associated with this object. Really
     * only applies to query keys representing an object or to expression builders.
     *
     */
    @Override
    public Vector getFields() {
        return getBaseExpression().getFields();
    }

    /**
     * INTERNAL:
     */
    @Override
    public List<DatabaseField> getSelectionFields(ReadQuery query) {
        return getBaseExpression().getSelectionFields(query);
    }

    public ExpressionOperator getOperator() {
        return operator;
    }

    public ExpressionOperator getPlatformOperator(DatabasePlatform platform) {
        if (platformOperator == null) {
            initializePlatformOperator(platform);
        }
        return platformOperator;
    }
    
    public Class getResultType() {
        return resultType;
    }

    public boolean hasResultType() {
        return resultType != null;
    }
    
    /**
     * INTERNAL:
     */
    public void initializePlatformOperator(DatabasePlatform platform) {
        if (this.operator.isComplete()) {
            platformOperator = this.operator;
            return;
        }
        platformOperator = platform.getOperator(this.operator.getSelector());
        if (platformOperator == null) {
            throw QueryException.invalidOperator(this.operator.toString());
        }
    }

    public boolean isFunctionExpression() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if the represents an object comparison.
     */
    protected boolean isObjectComparison() {
        int selector = this.operator.getSelector();
        if (((selector != ExpressionOperator.IsNull) && (selector != ExpressionOperator.NotNull)) || (this.children.size() != 1)) {
            if (((selector != ExpressionOperator.InSubQuery) && (selector != ExpressionOperator.NotInSubQuery))
                    || (this.children.size() != 2)) {
                return false;
            }
        }

        Expression base = getBaseExpression();
        //bug 384641 - check that directCollections are not treated as object comparisons
        return (base.isObjectExpression() && (!((ObjectExpression)base).isAttribute()) && 
                !((ObjectExpression)base).isDirectCollection() );
    }

    /**
     * INTERNAL:
     * For iterating using an inner class
     */
    public void iterateOn(ExpressionIterator iterator) {
        super.iterateOn(iterator);
        for (Enumeration childrenEnum = this.children.elements(); childrenEnum.hasMoreElements();) {
            Expression child = (Expression)childrenEnum.nextElement();
            child.iterateOn(iterator);
        }
    }

    /**
     * INTERNAL:
     * Normalize into a structure that is printable.
     * Also compute printing information such as outer joins.
     * This checks for object isNull, notNull, in and notIn comparisons.
     */
    public Expression normalize(ExpressionNormalizer normalizer) {
        //This method has no validation but we should still make the method call for consistency
        //bug # 2956674
        //validation is moved into normalize to ensure that expressions are valid before we attempt to work with them
        validateNode();
        if (this.children.isEmpty()) {
            return this;
        }
        
        // Ensure session has been set.
        ExpressionBuilder builder = getBuilder();
        if ((builder != null) && (builder.getSession() == null)) {
            builder.setSession(normalizer.getSession().getRootSession(null));
        }
        
        if (this.operator.getSelector() == ExpressionOperator.Count) {
            // Attempting to count an Entity and not an attribute.  Need to augment this expression.
            // This is normally normalized in ReportQuery, but can get to here in a having clause.
            prepareObjectAttributeCount(normalizer, null, null, null);
        }

        if (!isObjectComparison()) {
            for (int index = 0; index < this.children.size(); index++) {
                this.children.set(index, ((Expression)this.children.get(index)).normalize(normalizer));
            }
            return this;
        } else {
            //if not normalizing we must still validate the corresponding node to make sure that they are valid
            //bug # 2956674
            for (int index = 0; index < this.children.size(); index++) {
                ((Expression)this.children.get(index)).validateNode();
            }
        }

        // This code is executed only in the case of an is[not]Null, or [not]in on an
        // object attribute.
        ObjectExpression base = (ObjectExpression)getBaseExpression();

        // For cr2334, fix code so that normalize is first called on base expressions.
        // I.e. if base itself had a base expression this expression would not be normalized.
        if (base.getBaseExpression() != null) {
            base.getBaseExpression().normalize(normalizer);
        }

        // Check for IN with objects, "e IN (Select e2 from Employee e2)".
        if ((this.operator.getSelector() == ExpressionOperator.InSubQuery)
                || (this.operator.getSelector() == ExpressionOperator.NotInSubQuery)) {
            // Switch object comparison to compare on primary key.
            if (this.children.size() != 2) {
                throw QueryException.invalidExpression(this);
            }
            // Check if the left is for a 1-1 mapping, then optimize to compare on foreign key to avoid join.
            DatabaseMapping mapping = null;
            if (base.isQueryKeyExpression()) {
                mapping = base.getMapping();
            }
            List<DatabaseField> sourceFields = null;
            List<DatabaseField> targetFields = null;
            if ((mapping != null) && mapping.isOneToOneMapping()
                    && (!((OneToOneMapping)mapping).hasRelationTableMechanism())
                    && (!((OneToOneMapping)mapping).hasCustomSelectionQuery())) {
                base = (ObjectExpression)base.getBaseExpression();
                Map<DatabaseField, DatabaseField> targetToSourceKeyFields = ((OneToOneMapping)mapping).getTargetToSourceKeyFields();
                sourceFields = new ArrayList(targetToSourceKeyFields.size());
                targetFields = new ArrayList(targetToSourceKeyFields.size());
                for (Map.Entry<DatabaseField, DatabaseField> entry : targetToSourceKeyFields.entrySet()) {
                    sourceFields.add(entry.getValue());
                    targetFields.add(entry.getKey());
                }
            } else {
                mapping = null;
                sourceFields = base.getDescriptor().getPrimaryKeyFields();
                targetFields = sourceFields;
            }
            if (sourceFields.size() != 1) {
                base = (ObjectExpression)getBaseExpression();
                // For composite ids an exists and subselect is used.
                SubSelectExpression subSelectExp = (SubSelectExpression)this.children.get(1);
                ReportQuery subQuery = subSelectExp.getSubQuery();
                
                // some db (derby) require that in EXIST(SELECT...) subquery returns a single column
                subQuery.getItems().clear();
                subQuery.addItem("one", new ConstantExpression(Integer.valueOf(1), subQuery.getExpressionBuilder()));
                
                Expression subSelectCriteria = subQuery.getSelectionCriteria();
                ExpressionBuilder subBuilder = subQuery.getExpressionBuilder();
                Expression newExp;
                // Any or Some
                if (this.operator.getSelector() == ExpressionOperator.InSubQuery) {
                    subSelectCriteria = subBuilder.equal(base).and(subSelectCriteria);
                } else {
                    subSelectCriteria = subBuilder.notEqual(base).and(subSelectCriteria);
                }
                subQuery.setSelectionCriteria(subSelectCriteria);
                newExp = builder.exists(subQuery);
                return newExp.normalize(normalizer);
            }
            Expression newBase = base.getField(sourceFields.get(0));
            setBaseExpression(newBase);
            this.children.set(0, newBase);
            Expression right = (Expression)this.children.get(1);
            if (right.isSubSelectExpression()) {
                // Check for sub-select, need to replace sub-selects on object to select its id.
                ReportQuery query = ((SubSelectExpression)right).getSubQuery();
                if (query.getItems().size() != 1) {
                    throw QueryException.invalidExpression(this);                    
                }
                ReportItem item = query.getItems().get(0);
                item.setAttributeExpression(item.getAttributeExpression().getField(targetFields.get(0)));
            } else {
                throw QueryException.invalidExpression(this);
            }
            // Still need to normalize the children.
            for (int index = 0; index < this.children.size(); index++) {
                this.children.set(index, ((Expression)this.children.get(index)).normalize(normalizer));
            }
            return this;
        }
        // else isNull/notNull
        
        Expression foreignKeyJoin = null;
        if (base.getMapping() == null) {
            // Is an expression builder, transform to a null primary key expression.
            foreignKeyJoin = base.getDescriptor().getObjectBuilder().buildPrimaryKeyExpressionFromKeys(null, getSession());
            foreignKeyJoin = foreignKeyJoin.rebuildOn(base);
        } else {
            // Switch to null foreign key comparison (i.e. get('c').isNull() to getField('C_ID').isNull()).
            // For bug 3105559 also must handle aggregates: get("period").isNull();
            foreignKeyJoin = base.getMapping().buildObjectJoinExpression(base, (Object)null, getSession());
        }

        if (this.operator.getSelector() == ExpressionOperator.NotNull) {
            foreignKeyJoin = foreignKeyJoin.not();
        }
        return foreignKeyJoin.normalize(normalizer);
    }

    /**
     * INTERNAL:
     * Used for cloning.
     */
    protected void postCopyIn(Map alreadyDone) {
        super.postCopyIn(alreadyDone);
        Vector oldChildren = children;
        children = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
        for (int i = 0; i < oldChildren.size(); i++) {
            addChild((((Expression)oldChildren.elementAt(i)).copiedVersionFrom(alreadyDone)));
        }
    }

    /**
     * INTERNAL:
     * Print SQL using the operator.
     */
    public void printSQL(ExpressionSQLPrinter printer) {
        // If all children are parameters, some databases don't allow binding.
        if (printer.getPlatform().isDynamicSQLRequiredForFunctions() && !this.children.isEmpty()) {
            boolean allParams = true;
            for (Iterator iterator = this.children.iterator(); iterator.hasNext(); ) {
                Expression child = (Expression)iterator.next();
                if (!(child.isParameterExpression() || child.isConstantExpression())) {
                    allParams = false;
                }
            }
            if (allParams) {
                printer.getCall().setUsesBinding(false);                
            }
        }
        ExpressionOperator realOperator;
        realOperator = getPlatformOperator(printer.getPlatform());
        realOperator.printCollection(this.children, printer);
    }

    /**
     * INTERNAL:
     * Print java for project class generation
     */
    public void printJava(ExpressionJavaPrinter printer) {
        ExpressionOperator realOperator = getPlatformOperator(printer.getPlatform());
        realOperator.printJavaCollection(this.children, printer);
    }

    /**
     * INTERNAL:
     * This expression is built on a different base than the one we want. Rebuild it and
     * return the root of the new tree
     */
    public Expression rebuildOn(Expression newBase) {
        Expression newLocalBase = getBaseExpression().rebuildOn(newBase);
        Vector newChildren = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(this.children.size());
        for (int i = 1; i < this.children.size(); i++) {// Skip the first one, since it's also the base
            newChildren.addElement(((Expression)children.elementAt(i)).rebuildOn(newBase));
        }
        newLocalBase.setSelectIfOrderedBy(getBaseExpression().selectIfOrderedBy());
        FunctionExpression rebuilt = (FunctionExpression) newLocalBase.performOperator(this.operator, newChildren);
        rebuilt.setResultType(this.getResultType()); //copy over result type.
        return rebuilt;
    }

    /**
     * INTERNAL:
     * Search the tree for any expressions (like SubSelectExpressions) that have been
     * built using a builder that is not attached to the query.  This happens in case of an Exists
     * call using a new ExpressionBuilder().  This builder needs to be replaced with one from the query.
     */
    public void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder){
        getBaseExpression().resetPlaceHolderBuilder(queryBuilder);
        for (int i = this.children.size()-1; i > 0; i--) {// Skip the first one, since it's also the base
            ((Expression)children.elementAt(i)).resetPlaceHolderBuilder(queryBuilder);
        }
    }
    // Set the local base expression, ie the one on the other side of the operator
    // Most types will ignore this, since they don't need it.
    public void setLocalBase(Expression exp) {
        getBaseExpression().setLocalBase(exp);
    }

    public void setOperator(ExpressionOperator theOperator) {
        operator = theOperator;
    }
    
    public void setResultType(Class resultType) {
        this.resultType = resultType;
    }

    /**
     * INTERNAL:
     * Rebuild myself against the base, with the values of parameters supplied by the context
     * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping)
     * into part of some larger expression. You normally would not call this directly, instead calling twist
     * See the comment there for more details"
     */
    @Override
    public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) {
        if (this.children.isEmpty()) {
            return (Expression)clone();
        }
        Vector newChildren = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(this.children.size());

        // For functions the base is the first child, we only want the arguments so start at the second.
        for (int index = 1; index < this.children.size(); index++) {
            newChildren.addElement(((Expression)children.elementAt(index)).twistedForBaseAndContext(newBase, context, oldBase));
        }

        // Aply the function to the twisted old base.
        Expression oldBaseExp = (Expression)this.children.elementAt(0);
        return oldBaseExp.twistedForBaseAndContext(newBase, context, oldBase).performOperator(this.operator, newChildren);
    }

    /**
     * INTERNAL:
     * Return the value for in memory comparison.
     * This is only valid for valueable expressions.
     */
    public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) {
        Object baseValue = getBaseExpression().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);
        Vector arguments = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(this.children.size());
        for (int index = 1; index < this.children.size(); index++) {
            if (this.children.elementAt(index) instanceof Expression) {
                arguments.addElement(((Expression)this.children.elementAt(index)).valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered));
            } else {
                arguments.addElement(this.children.elementAt(index));
            }
        }
        if (baseValue instanceof Vector) {// baseValue might be a vector, so the individual values must be extracted before applying the function call to them
            Vector baseVector = new Vector();
            for (Enumeration valuesToCompare = ((Vector)baseValue).elements();
                     valuesToCompare.hasMoreElements();) {
                Object baseObject = valuesToCompare.nextElement();
                if (baseObject == null) {
                    baseVector.addElement(baseObject);
                } else {
                    baseVector.addElement(this.operator.applyFunction(baseObject, arguments));
                }
            }
            return baseVector;
        } else {
            // Do not apply functions to null, just leave as null.
            if (baseValue == null) {
                return null;
            } else {
                return this.operator.applyFunction(baseValue, arguments);
            }
        }
    }

    /**
     * INTERNAL:
     * Used to print a debug form of the expression tree.
     */
    public void writeDescriptionOn(BufferedWriter writer) throws IOException {
        writer.write(operator.toString());
    }

    /**
     * INTERNAL: called from SQLSelectStatement.writeFieldsFromExpression(...)
     */
    @Override
    public void writeFields(ExpressionSQLPrinter printer, Vector newFields, SQLSelectStatement statement) {
        //print ", " before each selected field except the first one
        if (printer.isFirstElementPrinted()) {
            printer.printString(", ");
        } else {
            printer.setIsFirstElementPrinted(true);
        }

        if (getBaseExpression().isDataExpression()) {
            DatabaseField field = ((DataExpression)getBaseExpression()).getField();

            if (field == null) {
                // This means the select wants a *.
                field = new DatabaseField("*");
            } else {
                // Clone the field since we will change its type.
                field = field.clone();
            }
            
            // If the result type is set, use it.
            field.setSqlType(DatabaseField.NULL_SQL_TYPE);
            //we also cache the JDBC type now so reset it as well.
            if (hasResultType()) {
                field.setType(getResultType());
            } else {
                // If the function is anything but min or max, null out the
                // field type. The type will be calculated based on the
                // function.
                int selector = this.operator.getSelector();
                if (selector != ExpressionOperator.Maximum && selector != ExpressionOperator.Minimum) {
                    field.setType(null);
                }   
            }

            newFields.addElement(field);
        } else {
            // This field is a complex function value so any name can be used.
            DatabaseField field = new DatabaseField("*");
            // If the result type is set, use it.
            field.setSqlType(DatabaseField.NULL_SQL_TYPE);
            field.setType(getResultType());
            newFields.addElement(field);
        }

        printSQL(printer);
    }

    /**
     * INTERNAL:
     * Used in SQL printing.
     */
    public void writeSubexpressionsTo(BufferedWriter writer, int indent) throws IOException {
        if (baseExpression != null) {
            baseExpression.toString(writer, indent);
        }
    }
    
    /**
     * INTERNAL:
     * JPQL allows count([distinct] e), where e can be an object, not just a single field,
     * however the database only allows a single field, so object needs to be translated to a single field.
     * If the descriptor has a single pk, it is used, otherwise any pk is used if distinct, otherwise a subselect is used.
     * If the object was obtained through an outer join, then the subselect also will not work, so an error is thrown.
     */
    public void prepareObjectAttributeCount(ExpressionNormalizer normalizer, ReportItem item, ReportQuery query, Map clonedExpressions) {
        // ** Note that any of the arguments may be null depending on the caller.
        if (getOperator().getSelector() == ExpressionOperator.Count) {
            Expression baseExp = getBaseExpression();
            boolean distinctUsed = false;
            if (baseExp.isFunctionExpression() && (((FunctionExpression)baseExp).getOperator().getSelector() == ExpressionOperator.Distinct)) {
                distinctUsed = true;
                baseExp = ((FunctionExpression)baseExp).getBaseExpression();
            }
            boolean outerJoin = false;
            ClassDescriptor newDescriptor = null;
            AbstractSession session = null;
            if (query != null) {
                session = query.getSession();
            } else {
                session = normalizer.getSession();
            }
            if (baseExp.isQueryKeyExpression()) {
                // now need to find out if it is a direct to field or something else.
                ClassDescriptor descriptor = null;
                if (query == null) {
                    descriptor = ((QueryKeyExpression) baseExp).getDescriptor();
                } else {
                    descriptor = query.getDescriptor();
                }
                DatabaseMapping mapping = baseExp.getLeafMapping(query, descriptor, session);
                if ((mapping != null) && !mapping.isAbstractDirectMapping()) {
                    outerJoin = ((QueryKeyExpression)baseExp).shouldUseOuterJoin();
                    if (mapping.isAggregateMapping()){
                        newDescriptor = mapping.getDescriptor();
                        baseExp = ((QueryKeyExpression)baseExp).getBaseExpression();
                    } else {
                        newDescriptor = mapping.getReferenceDescriptor();
                    }
                } else {
                    QueryKey queryKey = getLeafQueryKeyFor(query, baseExp, descriptor, session);
                    if ((queryKey != null) && queryKey.isForeignReferenceQueryKey()){
                        outerJoin = ((QueryKeyExpression) baseExp).shouldUseOuterJoin();
                        newDescriptor = session.getDescriptor(((ForeignReferenceQueryKey)queryKey).getReferenceClass());
                    }
                }
            } else if (baseExp.isExpressionBuilder()) {
                if (((ExpressionBuilder)baseExp).getQueryClass() == null) {
                    if (item != null) {
                        item.setResultType(ClassConstants.INTEGER);
                    }
                } else {
                    newDescriptor = session.getDescriptor(((ExpressionBuilder)baseExp).getQueryClass());
                }
            }
            
            if (newDescriptor != null) {
                // At this point we are committed to rewriting the query.
                if ((newDescriptor.getPrimaryKeyFields().size() == 1) || !distinctUsed) {
                    // case 1: single PK =>
                    // treat COUNT(entity) as COUNT(entity.pk)
                    Expression countArg = baseExp.getField(newDescriptor.getPrimaryKeyFields().get(0));
                    if (distinctUsed) {
                        countArg = countArg.distinct();
                    }
                    setBaseExpression(countArg);
                    getChildren().set(0, countArg);
                } else if (((DatabasePlatform)session.getPlatform(newDescriptor.getJavaClass())).supportsCountDistinctWithMultipleFields()) {                            
                    // case 3, is database allows multiple fields, then just print them
                    // treat COUNT(distinct entity) as COUNT(distinct entity.pk1, entity.pk2)
                    List args = new ArrayList(newDescriptor.getPrimaryKeyFields().size());
                    Expression firstField = null;
                    for (DatabaseField field : newDescriptor.getPrimaryKeyFields()) {
                        if (firstField == null) {
                            firstField = baseExp.getField(field);
                        } else {
                            args.add(baseExp.getField(field));
                        }
                    }
                    
                    ExpressionOperator anOperator = new ExpressionOperator();
                    anOperator.setType(ExpressionOperator.FunctionOperator);
                    Vector v = NonSynchronizedVector.newInstance(args.size());
                    v.addElement("DISTINCT ");
                    for (int index = 0; index < args.size(); index++) {
                        v.add(", ");
                    }
                    v.add("");
                    anOperator.printsAs(v);
                    anOperator.bePrefix();
                    anOperator.setNodeClass(ClassConstants.FunctionExpression_Class);
                    Expression distinctFunction = anOperator.expressionForArguments(firstField, args);
                    
                    setBaseExpression(distinctFunction);
                    getChildren().set(0, distinctFunction);
                } else if (!outerJoin && (query != null)) {
                    // case 4: composite PK and DISTINCT, but no
                    // outer join => previous solution using
                    // COUNT(*) and EXISTS subquery
                    // TODO, this doesn't really work for most cases (joins, other things selected, group by),
                    // this should probably be removed and throw an error,
                    // or changed to just concat all the pks together.
                    
                    // If this is a subselect baseExp is yet uncloned,
                    // and will miss out if moved now from items into a selection criteria.
                    if (clonedExpressions != null) {
                        if (clonedExpressions.get(baseExp.getBuilder()) != null) {
                            baseExp = baseExp.copiedVersionFrom(clonedExpressions);
                        } else {
                            baseExp = baseExp.rebuildOn(query.getExpressionBuilder());
                        }
                    }
                    
                    // Now the reference class of the query needs to be reversed.
                    // See the bug description for an explanation.
                    ExpressionBuilder countBuilder = baseExp.getBuilder();
                    ExpressionBuilder outerBuilder ;
                    
                    ReportQuery subSelect = new ReportQuery(query.getReferenceClass(), countBuilder);
                    query.getSession().getPlatform().retrieveFirstPrimaryKeyOrOne(subSelect);
                    
                    // Make sure the outerBuilder does not appear on the left of the subselect.
                    // Putting a builder on the left is desirable to trigger an optimization.
                    if (query.getSelectionCriteria() != null) {
                        outerBuilder = new ExpressionBuilder(newDescriptor.getJavaClass());
                        query.setExpressionBuilder(outerBuilder);
                        subSelect.setSelectionCriteria(baseExp.equal(outerBuilder).and(query.getSelectionCriteria()));
                    } else {
                        outerBuilder = new ExpressionBuilder(newDescriptor.getJavaClass());
                        query.setExpressionBuilder(outerBuilder);
                        subSelect.setSelectionCriteria(baseExp.equal(outerBuilder));
                    }
                    query.setNonFetchJoinAttributeExpressions(null);
                    query.setSelectionCriteria(outerBuilder.exists(subSelect));
                    setBaseExpression(outerBuilder);
                    getChildren().set(0, outerBuilder);
                    query.setReferenceClass(newDescriptor.getJavaClass());
                    query.changeDescriptor(session);
                } else {
                    // case 4: composite PK, DISTINCT, outer join => 
                    // not supported, throw exception
                    DatabaseQuery reportQuery = query;
                    if (query == null) {
                        reportQuery = normalizer.getStatement().getQuery();
                    }
                    throw QueryException.distinctCountOnOuterJoinedCompositePK(newDescriptor, reportQuery);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Lookup the query key for this item.
     * If an aggregate of foreign mapping is found it is traversed.
     */
    protected QueryKey getLeafQueryKeyFor(DatabaseQuery query, Expression expression, ClassDescriptor rootDescriptor, AbstractSession session) throws QueryException {
        // Check for database field expressions or place holder
        if ((expression == null) || (expression.isFieldExpression())) {
            return null;
        }

        if (!(expression.isQueryKeyExpression())) {
            return null;
        }
        
        QueryKeyExpression qkExpression = (QueryKeyExpression)expression;
        Expression baseExpression = qkExpression.getBaseExpression();

        ClassDescriptor descriptor = baseExpression.getLeafDescriptor(query, rootDescriptor, session);
        return descriptor.getQueryKeyNamed(qkExpression.getName());
    }

    protected DatabaseMapping getMappingOfFirstPrimaryKey(ClassDescriptor descriptor) {
        if (descriptor != null) {
            for (Iterator i = descriptor.getMappings().iterator(); i.hasNext(); ) {
                DatabaseMapping m = (DatabaseMapping)i.next();
                if (m.isPrimaryKeyMapping()) {
                    return m;
                }
            }
        }
        return null;
    }


}
