/*******************************************************************************
 * 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
 *     04/01/2011-2.3 Guy Pelletier 
 *       - 337323: Multi-tenant with shared schema support (part 2)
 *     09/09/2011-2.3.1 Guy Pelletier 
 *       - 356197: Add new VPD type to MultitenantType
 ******************************************************************************/  
package org.eclipse.persistence.queries;

import java.util.*;
import java.sql.*;

import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.sessions.remote.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ResultSetRecord;
import org.eclipse.persistence.internal.sessions.SimpleResultSetRecord;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.tools.profiler.QueryMonitor;

/**
 * <p><b>Purpose</b>:
 * Concrete class for all read queries involving a collection of objects.
 * <p>
 * <p><b>Responsibilities</b>:
 * Return a container of the objects generated by the query.
 * Implements the inheritance feature when dealing with abstract descriptors
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class ReadAllQuery extends ObjectLevelReadQuery {
    /** Used for collection and stream support. */
    protected ContainerPolicy containerPolicy;

    /** Used for Oracle HierarchicalQuery support */
    protected Expression startWithExpression;
    protected Expression connectByExpression;
    protected List<Expression> orderSiblingsByExpressions;

    /**
     * PUBLIC:
     * Return a new read all query.
     * A reference class must be specified before execution.
     * It is better to provide the class and expression builder on construction to ensure a single expression builder is used.
     * If no selection criteria is specified this will read all objects of the class from the database.
     */
    public ReadAllQuery() {
        super();
        setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
    }

    /**
     * PUBLIC:
     * Return a new read all query.
     * It is better to provide the class and expression builder on construction to ensure a single expression builder is used.
     * If no selection criteria is specified this will read all objects of the class from the database.
     */
    public ReadAllQuery(Class classToRead) {
        this();
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read all query for the class and the selection criteria.
     */
    public ReadAllQuery(Class classToRead, Expression selectionCriteria) {
        this();
        this.referenceClass = classToRead;
        setSelectionCriteria(selectionCriteria);
    }

    /**
     * PUBLIC:
     * Return a new read all query for the class.
     * The expression builder must be used for all associated expressions used with the query.
     */
    public ReadAllQuery(Class classToRead, ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
        this.referenceClass = classToRead;
    }

    /**
     * PUBLIC:
     * Return a new read all query.
     * The call represents a database interaction such as SQL, Stored Procedure.
     */
    public ReadAllQuery(Class classToRead, Call call) {
        this();
        this.referenceClass = classToRead;
        setCall(call);
    }

    /**
     * PUBLIC:
     * Return a query by example query to find all objects matching the attributes of the example object.
     */
    public ReadAllQuery(Object exampleObject, QueryByExamplePolicy policy) {
        this();
        setExampleObject(exampleObject);
        setQueryByExamplePolicy(policy);
    }

    /**
     * PUBLIC:
     * The expression builder should be provide on creation to ensure only one is used.
     */
    public ReadAllQuery(ExpressionBuilder builder) {
        this();
        this.defaultBuilder = builder;
    }

    /**
     * PUBLIC:
     * Create a read all query with the database call.
     */
    public ReadAllQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * PUBLIC:
     * Order the query results by the object's attribute or query key name.
     */
    public void addAscendingOrdering(String queryKeyName) {
        addOrdering(getExpressionBuilder().get(queryKeyName).ascending());
    }

    /**
     * INTERNAL:
     * <P> This method is called by the object builder when building an original.
     * It will cause the original to be cached in the query results if the query
     * is set to do so.
     */
    @Override
    public void cacheResult(Object unwrappedOriginal) {
        Collection container = (Collection)getTemporaryCachedQueryResults();
        if (container == null) {
            container = (Collection)getContainerPolicy().containerInstance();
            setTemporaryCachedQueryResults(container);
        }
        getContainerPolicy().addInto(unwrappedOriginal, container, getSession());
    }

    /**
     * INTERNAL:
     * The cache check is done before the prepare as a hit will not require the work to be done.
     */
    @Override
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
        // Check for in-memory only query.
        if (shouldCheckCacheOnly()) {
            // assert !isReportQuery();
            if (shouldUseWrapperPolicy()) {
                getContainerPolicy().setElementDescriptor(this.descriptor);
            }

            // PERF: Fixed to not query each unit of work cache (is not conforming),
            // avoid hashtable and primary key indexing.
            // At some point we may need to support some kind of in-memory with conforming option,
            // but we do not currently allow this.
            AbstractSession rootSession = session;
            while (rootSession.isUnitOfWork()) {
                rootSession = ((UnitOfWorkImpl)rootSession).getParent();
            }
            Vector allCachedVector = rootSession.getIdentityMapAccessor().getAllFromIdentityMap(getSelectionCriteria(), getReferenceClass(), translationRow, getInMemoryQueryIndirectionPolicyState(), false);

            // Must ensure that all of the objects returned are correctly registered in the unit of work.
            if (session.isUnitOfWork()) {
                allCachedVector = ((UnitOfWorkImpl)session).registerAllObjects(allCachedVector);
            }

            this.isCacheCheckComplete = true;

            return getContainerPolicy().buildContainerFromVector(allCachedVector, session);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Check to see if a custom query should be used for this query.
     * This is done before the query is copied and prepared/executed.
     * null means there is none.
     */
    @Override
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
        Boolean useCustomQuery = isCustomQueryUsed;

        checkDescriptor(session);
        // Check if user defined a custom query.
        if (useCustomQuery == null) {
            setIsCustomQueryUsed((!isUserDefined()) && isExpressionQuery() && (getSelectionCriteria() == null) && isDefaultPropertiesQuery() && (!hasOrderByExpressions()) && (this.descriptor.getQueryManager().hasReadAllQuery()));
            // Value of isCustomQueryUsed is updated by setIsCustomQueryUsed method.
            useCustomQuery = isCustomQueryUsed;
        }
        if (useCustomQuery != null && useCustomQuery.booleanValue()) {
            ReadAllQuery customQuery = this.descriptor.getQueryManager().getReadAllQuery();
            if (this.accessors != null) {
                customQuery = (ReadAllQuery) customQuery.clone();
                customQuery.setIsExecutionClone(true);
                customQuery.setAccessors(this.accessors);
            }
            isCustomQueryUsed = useCustomQuery;
            return customQuery;
        }
        isCustomQueryUsed = useCustomQuery;
        return null;
    }

    /**
     * INTERNAL:
     * Clone the query.
     */
    @Override
    public Object clone() {
        ReadAllQuery cloneQuery = (ReadAllQuery)super.clone();

        // Don't use setters as that will trigger unprepare
        cloneQuery.containerPolicy = this.containerPolicy.clone(cloneQuery);

        return cloneQuery;
    }

    /**
     * INTERNAL:
     * Conform the result if specified.
     */
    protected Object conformResult(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
        if (getSelectionCriteria() != null) {
            ExpressionBuilder builder = getSelectionCriteria().getBuilder();
            builder.setSession(unitOfWork.getRootSession(null));
            builder.setQueryClass(getReferenceClass());
        }
        
        // If the query is redirected then the collection returned might no longer
        // correspond to the original container policy.  CR#2342-S.M.
        ContainerPolicy cp;
        if (getRedirector() != null) {
            cp = ContainerPolicy.buildPolicyFor(result.getClass());
        } else {
            cp = getContainerPolicy();
        }

        // This code is now a great deal different...  For one, registration is done
        // as part of conforming.  Also, this should only be called if one actually
        // is conforming.
        // First scan the UnitOfWork for conforming instances.
        // This will walk through the entire cache of registered objects.
        // Let p be objects from result not in the cache.
        // Let c be objects from cache.
        // Presently p intersect c = empty set, but later p subset c.
        // By checking cache now doesConform will be called p fewer times.
        Map<Object, Object> indexedInterimResult = unitOfWork.scanForConformingInstances(getSelectionCriteria(), getReferenceClass(), arguments, this);
        
        Cursor cursor = null;
        // In the case of cursors just conform/register the initially read collection.
        if (cp.isCursorPolicy()) {
            cursor = (Cursor)result;
            cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
            // In nested UnitOfWork session might have been session of the parent.
            cursor.setSession(unitOfWork);
            result = cursor.getObjectCollection();
            // for later incremental conforming...
            cursor.setInitiallyConformingIndex(indexedInterimResult);
            cursor.setSelectionCriteriaClone(getSelectionCriteria());
            cursor.setTranslationRow(arguments);
        }

        // Now conform the result from the database.
        // Remove any deleted or changed objects that no longer conform.
        // Deletes will only work for simple queries, queries with or's or anyof's may not return
        // correct results when untriggered indirection is in the model.		
        List fromDatabase = null;

        // When building directly from rows, one of the performance benefits
        // is that we no longer have to wrap and then unwrap the originals.
        // result is just a vector, not a container of wrapped originals.
        if (buildDirectlyFromRows) {
            List<AbstractRecord> rows = (List<AbstractRecord>)result;
            int size = rows.size();
            fromDatabase = new ArrayList(size);
            for (int index = 0; index < size; index++) {
                AbstractRecord row = rows.get(index);
                // null is placed in the row collection for 1-m joining to filter duplicate rows.
                if (row != null) {
                    Object clone = conformIndividualResult(buildObject(row), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
                    if (clone != null) {
                        fromDatabase.add(clone);
                    }
                }
            }
        } else {
            fromDatabase = new ArrayList(cp.sizeFor(result));
            AbstractSession sessionToUse = unitOfWork.getParent();
            for (Object iter = cp.iteratorFor(result); cp.hasNext(iter);) {
                Object object = cp.next(iter, sessionToUse);
                Object clone = conformIndividualResult(registerIndividualResult(object, null, unitOfWork, null, null), unitOfWork, arguments, getSelectionCriteria(), indexedInterimResult);
                if (clone != null) {
                    fromDatabase.add(clone);
                }
            }
        }

        // Now add the unwrapped conforming instances into an appropriate container.  
        // Wrapping is done automatically.
        // Make sure a vector of exactly the right size is returned.
        Object conformedResult = cp.containerInstance(indexedInterimResult.size() + fromDatabase.size());
        for (Iterator enumtr = indexedInterimResult.values().iterator(); enumtr.hasNext();) {
            Object eachClone = enumtr.next();
            cp.addInto(eachClone, conformedResult, unitOfWork);
        }
        int size = fromDatabase.size();
        for (int index = 0; index < size; index++) {
            Object eachClone = fromDatabase.get(index);
            cp.addInto(eachClone, conformedResult, unitOfWork);
        }

        if (cursor != null) {
            cursor.setObjectCollection((List)conformedResult);

            // For nested UOW must copy all in object collection to
            // initiallyConformingIndex, as some of these could have been from 
            // the parent UnitOfWork.
            if (unitOfWork.isNestedUnitOfWork()) {
                for (Object clone : cursor.getObjectCollection()) {
                    indexedInterimResult.put(clone, clone);
                }
            }
            return cursor;
        } else {
            return conformedResult;
        }
    }

    /**
     * INTERNAL:
     * Execute the query. If there are cached results return those.
     * This must override the super to support result caching.
     *
     * @param session - the session in which the receiver will be executed.
     * @return An object or vector, the result of executing the query.
     * @exception DatabaseException - an error has occurred on the database
     */
    @Override
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {        
        if (shouldCacheQueryResults()) {
            if (getContainerPolicy().overridesRead()) {
                throw QueryException.cannotCacheCursorResultsOnQuery(this);
            }
            if (shouldConformResultsInUnitOfWork()) {
                throw QueryException.cannotConformAndCacheQueryResults(this);
            }
            if (isPrepared()) {// only prepared queries can have cached results.
                Object queryResults = getQueryResults(session, row, true);
                if (queryResults != null) {
                    if (QueryMonitor.shouldMonitor()) {
                        QueryMonitor.incrementReadAllHits(this);
                    }
                    session.incrementProfile(SessionProfiler.CacheHits, this);
                    // bug6138532 - check for "cached no results" (InvalidObject singleton) in query 
                    // results, and return an empty container instance as configured
                    if (queryResults == InvalidObject.instance) {
                        return getContainerPolicy().containerInstance(0);
                    }
                    Collection results = (Collection)queryResults;
                    if (session.isUnitOfWork()) {
                        ContainerPolicy policy = getContainerPolicy();
                        Object resultCollection = policy.containerInstance(results.size());
                        Object iterator = policy.iteratorFor(results);
                        while (policy.hasNext(iterator)) {
                            Object result = ((UnitOfWorkImpl)session).registerExistingObject(policy.next(iterator, session), this.descriptor, null, true);
                            policy.addInto(result, resultCollection, session);
                        }
                        return resultCollection;
                    }
                    return results;
                }
            }
            session.incrementProfile(SessionProfiler.CacheMisses, this);
        }
        if (QueryMonitor.shouldMonitor()) {
            QueryMonitor.incrementReadAllMisses(this);
        }
        return super.execute(session, row);
    }

    /**
     * INTERNAL:
     * Execute the query.
     * Get the rows and build the object from the rows.
     * @exception  DatabaseException - an error has occurred on the database
     * @return java.lang.Object collection of objects resulting from execution of query.
     */
    @Override
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
        Object result = null;
        
        if (this.containerPolicy.overridesRead()) {
            this.executionTime = System.currentTimeMillis();
            return this.containerPolicy.execute();
        }

        if (this.descriptor.isDescriptorForInterface()) {
            Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
            this.executionTime = System.currentTimeMillis();
            return returnValue;
        }

        if (this.descriptor.hasTablePerClassPolicy() && this.descriptor.isAbstract()) {
            result = this.containerPolicy.containerInstance();
        } else {
            Object sopObject = getTranslationRow().getSopObject();
            boolean useOptimization = false;
            if (sopObject == null) {
                useOptimization = usesResultSetAccessOptimization(); 
            }        
            
            if (useOptimization) {
                DatabaseCall call = ((DatasourceCallQueryMechanism)this.queryMechanism).selectResultSet();
                this.executionTime = System.currentTimeMillis();
                Statement statement = call.getStatement();
                ResultSet resultSet = call.getResult();
                DatabaseAccessor dbAccessor = (DatabaseAccessor)getAccessor();
                boolean exceptionOccured = false;
                try {
                    if (this.session.isUnitOfWork()) {
                        result = registerResultSetInUnitOfWork(resultSet, call.getFields(), call.getFieldsArray(), (UnitOfWorkImpl)this.session, this.translationRow); 
                    } else {
                        result = this.containerPolicy.containerInstance();
                        this.descriptor.getObjectBuilder().buildObjectsFromResultSetInto(this, resultSet, call.getFields(), call.getFieldsArray(), result);
                    }
                } catch (SQLException exception) {
                    exceptionOccured = true;
                    DatabaseException commException = dbAccessor.processExceptionForCommError(this.session, exception, call);
                    if (commException != null) {
                        throw commException;
                    }
                    throw DatabaseException.sqlException(exception, call, dbAccessor, this.session, false);
                } finally {
                    try {
                        if (resultSet != null) {
                            resultSet.close();
                        }
                        if (dbAccessor != null) {
                            if (statement != null) {
                                dbAccessor.releaseStatement(statement, call.getSQLString(), call, this.session);
                            }
                        }
                        if (call.hasAllocatedConnection()) {
                            getExecutionSession().releaseConnectionAfterCall(this);
                        }
                    } catch (RuntimeException cleanupException) {
                        if (!exceptionOccured) {
                            throw cleanupException;
                        }
                    } catch (SQLException cleanupSQLException) {
                        if (!exceptionOccured) {
                            throw DatabaseException.sqlException(cleanupSQLException, call, dbAccessor, this.session, false);
                        }
                    }
                }                
            } else {
                List<AbstractRecord> rows;
                if (sopObject != null) {
                    Object valuesIterator = this.containerPolicy.iteratorFor(getTranslationRow().getSopObject());
                    int size = this.containerPolicy.sizeFor(sopObject);
                    rows =  new ArrayList<AbstractRecord>(size);
                    while (this.containerPolicy.hasNext(valuesIterator)) {
                        Object memberSopObject = this.containerPolicy.next(valuesIterator, this.session);
                        DatabaseRecord memberRow = new DatabaseRecord(0);
                        memberRow.setSopObject(memberSopObject);
                        rows.add(memberRow);                        
                    }
                    this.executionTime = System.currentTimeMillis();
                } else {
                    rows = getQueryMechanism().selectAllRows();
                    this.executionTime = System.currentTimeMillis();
                    
                    // If using 1-m joins, must set all rows.
                    if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
                        this.joinedAttributeManager.setDataResults(rows, this.session);
                    }
                    // Batch fetching in IN requires access to the rows to build the id array.
                    if ((this.batchFetchPolicy != null) && this.batchFetchPolicy.isIN()) {
                        this.batchFetchPolicy.setDataResults(rows);
                    }
                }
        
                if (this.session.isUnitOfWork()) {
                    result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl)this.session, this.translationRow, true);// 
                } else {
                    if (rows instanceof ThreadCursoredList) {
                        result = this.containerPolicy.containerInstance();
                    } else {
                        result = this.containerPolicy.containerInstance(rows.size());
                    }
                    this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
                }
        
                if (sopObject != null) {
                	if (!this.descriptor.getObjectBuilder().isSimple()) {
	                	// remove sopObject so it's not stuck in any value holder.
	                	for (AbstractRecord row : rows) {
	                		row.setSopObject(null);
	                	}
                	}
                } else {
	                if (this.shouldIncludeData) {
	                    ComplexQueryResult complexResult = new ComplexQueryResult();
	                    complexResult.setResult(result);
	                    complexResult.setData(rows);
	                    result = complexResult;
	                }
                }
            }
        }

        // Add the other (already registered) results and return them.
        if (this.descriptor.hasTablePerClassPolicy()) {
            result = this.containerPolicy.concatenateContainers(
                    result, this.descriptor.getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this), this.session);
        }

        // If the results were empty, then ensure they get cached still.
        if (shouldCacheQueryResults() && this.containerPolicy.isEmpty(result)) {
            this.temporaryCachedQueryResults = InvalidObject.instance();
        }
        
        return result;
    }

    /**
     * INTERNAL:
     * Execute the query building the objects directly from the database result-set.
     * @exception  DatabaseException - an error has occurred on the database
     * @return an ArrayList of the resulting objects.
     */
    @Override
    protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException {
        AbstractSession session = this.session;
        DatabasePlatform platform = session.getPlatform();
        DatabaseCall call = ((DatasourceCallQueryMechanism)this.queryMechanism).selectResultSet();
        Statement statement = call.getStatement();
        ResultSet resultSet = call.getResult();
        DatabaseAccessor accessor = (DatabaseAccessor)getAccessor();
        boolean exceptionOccured = false;
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            List results = new ArrayList();
            ObjectBuilder builder = this.descriptor.getObjectBuilder();
            while (resultSet.next()) {
                results.add(builder.buildObjectFromResultSet(this, this.joinedAttributeManager, resultSet, session, accessor, metaData, platform, call.getFields(), call.getFieldsArray()));
            }
            return results;
        } catch (SQLException exception) {
            exceptionOccured = true;
            DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
            if (commException != null) {
                throw commException;
            }
            throw DatabaseException.sqlException(exception, call, accessor, session, false);
        } finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    accessor.releaseStatement(statement, call.getSQLString(), call, session);
                }
                if (accessor != null) {
                    session.releaseReadConnection(accessor);
                }
            } catch (SQLException exception) {
                if (!exceptionOccured) {
                    //in the case of an external connection pool the connection may be null after the statement release
                    // if it is null we will be unable to check the connection for a comm error and
                    //therefore must return as if it was not a comm error.
                    DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
                    if (commException != null) {
                        throw commException;
                    }
                    throw DatabaseException.sqlException(exception, call, accessor, session, false);
                }
            }
        }
    }
    
    /**
     * INTERNAL:
     * Extract the correct query result from the transporter.
     */
    @Override
    public Object extractRemoteResult(Transporter transporter) {
        return ((DistributedSession)getSession()).getObjectsCorrespondingToAll(transporter.getObject(), transporter.getObjectDescriptors(), new IdentityHashMap(), this, getContainerPolicy());
    }

    /**
     * INTERNAL:
     * Return the query's container policy.
     */
    public ContainerPolicy getContainerPolicy() {
        return containerPolicy;
    }

    /**
     * INTERNAL:
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
     * See ClassDescriptor for their types.
     */
    @Override
    protected QueryRedirector getDefaultRedirector() {
        return descriptor.getDefaultReadAllQueryRedirector();
    }

    /**
     * PUBLIC:
     * @return Expression - the start with expression used to generated the hierarchical query clause in
     * Oracle
     */
    public Expression getStartWithExpression() {
        return startWithExpression;
    }

    /**
     * PUBLIC:
     * @return Expression - the connect by expression used to generate the hierarchical query caluse in Oracle
     */
    public Expression getConnectByExpression() {
        return connectByExpression;
    }

    /**
     * PUBLIC:
     * @return List<Expression> - the ordering expressions used to generate the hierarchical query clause in Oracle
     */
    public List<Expression> getOrderSiblingsByExpressions() {
        return orderSiblingsByExpressions;
    }

    /**
     * INTERNAL:
     * Verify that we have hierarchical query expressions
     */
    public boolean hasHierarchicalExpressions() {
        return ((this.startWithExpression != null) || (this.connectByExpression != null) || (this.orderSiblingsByExpressions != null));
    }
    
    /**
     * INTERNAL:
     * Return true if the query uses default properties.
     * This is used to determine if this query is cacheable.
     * i.e. does not use any properties that may conflict with another query
     * with the same JPQL or selection criteria.
     */
    @Override
    public boolean isDefaultPropertiesQuery() {
        return super.isDefaultPropertiesQuery()
            && (!hasBatchReadAttributes())
            && (!hasHierarchicalExpressions())
            && (!this.containerPolicy.isCursorPolicy());
    }
    
    /**
     * INTERNAL:
     * Return if the query is equal to the other.
     * This is used to allow dynamic expression query SQL to be cached.
     */
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!super.equals(object)) {
            return false;
        }
        ReadAllQuery query = (ReadAllQuery) object;
        if (!this.containerPolicy.equals(query.containerPolicy)) {
            return false;
        }
        return true;
    }
    
    /**
     * PUBLIC:
     * Return if this is a read all query.
     */
    @Override
    public boolean isReadAllQuery() {
        return true;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    protected void prepare() throws QueryException {
        if ((!isReportQuery()) && prepareFromCachedQuery()) {
            return;
        }
        super.prepare();

        this.containerPolicy.prepare(this, getSession());

        if (hasJoining() && isExpressionQuery()) {
            // 1-m join fetching with pagination requires an order by.
            if (this.joinedAttributeManager.isToManyJoin()
                    && ((this.maxRows > 0) || (this.firstResult > 0) || this.containerPolicy.isCursorPolicy())) {
                if (!hasOrderByExpressions()) {
                    for (DatabaseField primaryKey : this.descriptor.getPrimaryKeyFields()) {
                        addOrdering(getExpressionBuilder().getField(primaryKey));
                    }
                }
            }
        }

        if (this.containerPolicy.overridesRead()) {
            return;
        }

        if (this.descriptor.isDescriptorForInterface()) {
            return;
        }
        
        prepareSelectAllRows();

        if (!isReportQuery()) {
            // should be called after prepareSelectRow so that the call knows whether it returns ResultSet
            prepareResultSetAccessOptimization();
        }
    }
    
    /**
     * INTERNAL:
     * Prepare the query from the prepared query.
     * This allows a dynamic query to prepare itself directly from a prepared query instance.
     * This is used in the JPQL parse cache to allow preparsed queries to be used to prepare
     * dynamic queries.
     * This only copies over properties that are configured through JPQL.
     */
    @Override
    public void prepareFromQuery(DatabaseQuery query) {
        super.prepareFromQuery(query);
        if (query.isReadAllQuery()) {
            ReadAllQuery readQuery = (ReadAllQuery)query;
            this.containerPolicy = readQuery.containerPolicy;
            if (readQuery.hasHierarchicalExpressions()) {
                this.orderSiblingsByExpressions = readQuery.orderSiblingsByExpressions;
                this.connectByExpression = readQuery.connectByExpression;
                this.startWithExpression = readQuery.startWithExpression;
            }
        }
    }

    /**
     * INTERNAL:
     * Set the properties needed to be cascaded into the custom query.
     */
    @Override
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
        super.prepareCustomQuery(customQuery);
        ReadAllQuery customReadQuery = (ReadAllQuery)customQuery;
        customReadQuery.containerPolicy = this.containerPolicy;
        customReadQuery.cascadePolicy = this.cascadePolicy;
        customReadQuery.shouldRefreshIdentityMapResult = this.shouldRefreshIdentityMapResult;
        customReadQuery.shouldMaintainCache = this.shouldMaintainCache;
        customReadQuery.shouldUseWrapperPolicy = this.shouldUseWrapperPolicy;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();
        
        this.containerPolicy.prepareForExecution();
        
        // Modifying the translation row here will modify it on the original 
        // query which is not good. So we have to clone the translation row if
        // we are going to append tenant discriminator fields to it.
        if (descriptor.hasMultitenantPolicy()) {
            translationRow = translationRow.clone();
            descriptor.getMultitenantPolicy().addFieldsToRow(translationRow, getSession());
        }
    }

    /**
     * INTERNAL:
     * Prepare the mechanism.
     */
    protected void prepareSelectAllRows() {
        getQueryMechanism().prepareSelectAllRows();
    }

    /**
     * INTERNAL:
     * All objects queried via a UnitOfWork get registered here.  If the query
     * went to the database.
     * <p>
     * Involves registering the query result individually and in totality, and
     * hence refreshing / conforming is done here.
     *
     * @param result may be collection (read all) or an object (read one),
     * or even a cursor.  If in transaction the shared cache will
     * be bypassed, meaning the result may not be originals from the parent
     * but raw database rows.
     * @param unitOfWork the unitOfWork the result is being registered in.
     * @param arguments the original arguments/parameters passed to the query
     * execution.  Used by conforming
     * @param buildDirectlyFromRows If in transaction must construct
     * a registered result from raw database rows.
     *
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
     */
    @Override
    public Object registerResultInUnitOfWork(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
        // For bug 2612366: Conforming results in UOW extremely slow.
        // Replacing results with registered versions in the UOW is a part of 
        // conforming and is now done while conforming to maximize performance.
        if (unitOfWork.hasCloneMapping() // PERF: Avoid conforming empty uow.
                    && (shouldConformResultsInUnitOfWork() || this.descriptor.shouldAlwaysConformResultsInUnitOfWork())) {
            return conformResult(result, unitOfWork, arguments, buildDirectlyFromRows);
        }

        // When building directly from rows, one of the performance benefits
        // is that we no longer have to wrap and then unwrap the originals.
        // result is just a vector, not a collection of wrapped originals.
        // Also for cursors the initial connection is automatically registered.
        if (buildDirectlyFromRows) {
            List<AbstractRecord> rows = (List<AbstractRecord>)result;
            ContainerPolicy cp = this.containerPolicy;
            int size = rows.size();
            Object clones = cp.containerInstance(size);
            if(cp.shouldAddAll()) {
                List clonesIn = new ArrayList(size);
                List<AbstractRecord> rowsIn = new ArrayList(size);
                for (int index = 0; index < size; index++) {
                    AbstractRecord row = rows.get(index);

                    // null is placed in the row collection for 1-m joining to filter duplicate rows.
                    if (row != null) {
                        Object clone = buildObject(row);
                        clonesIn.add(clone);
                        rowsIn.add(row);
                    }
                }
                cp.addAll(clonesIn, clones, unitOfWork, rowsIn, this, null, true);
            } else {
                boolean quickAdd = (clones instanceof Collection) && !this.descriptor.getObjectBuilder().hasWrapperPolicy();
                if (this.descriptor.getCachePolicy().shouldPrefetchCacheKeys()
                        && shouldMaintainCache() 
                        && ! shouldRetrieveBypassCache()
                        && ((!(unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive())
                                && ! unitOfWork.wasTransactionBegunPrematurely()
                                && !this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()
                                && ! this.descriptor.getCachePolicy().shouldIsolateProtectedObjectsInUnitOfWork())
                                || (unitOfWork.isClassReadOnly(this.getReferenceClass(), this.getDescriptor())))){
                    Object[] pkList = new Object[size];
                    for (int i = 0; i< size; ++i){
                        pkList[i] = getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(rows.get(i), session);
                    }
                    setPrefetchedCacheKeys(unitOfWork.getParentIdentityMapSession(this).getIdentityMapAccessorInstance().getAllCacheKeysFromIdentityMapWithEntityPK(pkList, descriptor));
                }
                for (int index = 0; index < size; index++) {
                    AbstractRecord row = rows.get(index);

                    // null is placed in the row collection for 1-m joining to filter duplicate rows.
                    if (row != null) {
                        Object clone = buildObject(row);
                        if (quickAdd) {
                            ((Collection)clones).add(clone);
                        } else {
                            cp.addInto(clone, clones, unitOfWork, row, this, null, true);
                        }
                    }
                }
            }
            return clones;
        }

        ContainerPolicy cp;
        Cursor cursor = null;

        // If the query is redirected then the collection returned might no longer
        // correspond to the original container policy.  CR#2342-S.M.
        if (getRedirector() != null) {
            cp = ContainerPolicy.buildPolicyFor(result.getClass());
        } else {
            cp = this.containerPolicy;
        }

        // In the case of cursors just register the initially read collection.
        if (cp.isCursorPolicy()) {
            cursor = (Cursor)result;
            // In nested UnitOfWork session might have been session of the parent.
            cursor.setSession(unitOfWork);
            cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
            result = cursor.getObjectCollection();
        }

        Object clones = cp.containerInstance(cp.sizeFor(result));
        AbstractSession sessionToUse = unitOfWork.getParent();
        for (Object iter = cp.iteratorFor(result); cp.hasNext(iter);) {
            Object object = cp.next(iter, sessionToUse);
            Object clone = registerIndividualResult(object, null, unitOfWork, this.joinedAttributeManager, null);
            cp.addInto(clone, clones, unitOfWork);
        }
        if (cursor != null) {
            cursor.setObjectCollection((Vector)clones);
            return cursor;
        } else {
            return clones;
        }
    }

    /**
     * INTERNAL:
     * Version of the previous method for ResultSet optimization.
     *
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
     */
    public Object registerResultSetInUnitOfWork(ResultSet resultSet, Vector fields, DatabaseField[] fieldsArray, UnitOfWorkImpl unitOfWork, AbstractRecord arguments) throws SQLException {
        // TODO: add support for Conforming results in UOW - currently conforming in uow is not compatible with ResultSet optimization.

        ContainerPolicy cp = this.containerPolicy;
        Object clones = cp.containerInstance();
        ResultSetMetaData metaData = resultSet.getMetaData();
        boolean hasNext = resultSet.next();
        if (hasNext) {
            // TODO: possibly add support for SortedListContainerPolicy (cp.shouldAddAll() == true) - this policy currently is not compatible with ResultSet optimization 
            boolean quickAdd = (clones instanceof Collection) && !this.descriptor.getObjectBuilder().hasWrapperPolicy();
            DatabaseAccessor dbAccessor = (DatabaseAccessor)getAccessor();
            boolean useSimple = this.descriptor.getObjectBuilder().isSimple();  
            AbstractSession executionSession = getExecutionSession();
            DatabasePlatform platform = dbAccessor.getPlatform();
            boolean optimizeData = platform.shouldOptimizeDataConversion();
            if (useSimple) {
                // None of the fields are relational - the row could be reused, just clear all the values.
                SimpleResultSetRecord row = new SimpleResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                if (this.descriptor.isDescriptorTypeAggregate()) {
                    // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                    row.setShouldKeepValues(true);
                }
                while (hasNext) {
                    Object clone = buildObject(row);
                    if (quickAdd) {
                        ((Collection)clones).add(clone);
                    } else {
                        // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                        cp.addInto(clone, clones, unitOfWork);                            
                    }
                    row.reset(); 
                    hasNext = resultSet.next(); 
                }
            } else {
                boolean shouldKeepRow = this.descriptor.getObjectBuilder().shouldKeepRow();
                while (hasNext) {
                    ResultSetRecord row = new ResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                    Object clone = buildObject(row);
                    if (quickAdd) {
                        ((Collection)clones).add(clone);
                    } else {
                        // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                        cp.addInto(clone, clones, unitOfWork);
                    }
                    
                    if (shouldKeepRow) {
                        if (row.hasResultSet()) {
                        	// ResultSet has not been fully triggered - that means the cached object was used. 
                        	// Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                        	// Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                            row.removeResultSet();
                        } else {
                            row.removeNonIndirectionValues();
                        }
                    }
                    hasNext = resultSet.next(); 
                }
            }
        }
        return clones;
    }

    /**
     * INTERNAL:
     * Execute the query through remote session.
     */
    @Override
    public Object remoteExecute() {
        if (this.containerPolicy.overridesRead()) {
            return this.containerPolicy.remoteExecute();
        }

        Object cacheHit = checkEarlyReturn(this.session, this.translationRow);
        if (cacheHit != null) {
            return cacheHit;
        }

        return super.remoteExecute();
    }

    /**
     * INTERNAL:
     * replace the value holders in the specified result object(s)
     */
    @Override
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
        return controller.replaceValueHoldersInAll(object, getContainerPolicy());
    }

    /**
     * PUBLIC:
     * Set the container policy. Used to support different containers
     * (e.g. Collections, Maps).
     */
    public void setContainerPolicy(ContainerPolicy containerPolicy) {
        // CR#... a container policy is always required, default is vector,
        // required for deployment XML.
        if (containerPolicy == null) {
            return;
        }
        this.containerPolicy = containerPolicy;
        setIsPrepared(false);
    }

    /**
     * PUBLIC:
     * Set the Hierarchical Query Clause for the query
     * <p>Example:
     * <p>Expression startWith = builder.get("id").equal(new Integer(100)); //can be any expression which identifies a set of employees
     * <p>Expression connectBy = builder.get("managedEmployees"); //indicated the relationship that the hierarchy is based on, must be self-referential
     * <p>Vector orderBy = new Vector();
     * <p>orderBy.addElement(builder.get("startDate"));
     * <p>readAllQuery.setHierarchicalQueryClause(startWith, connectBy, orderBy);
     *
     * <p>This query would generate SQL like this:
     * <p>SELECT * FROM EMPLOYEE START WITH ID=100 CONNECT BY PRIOR ID = MANAGER_ID ORDER SIBLINGS BY START_DATE
     * 
     * @param startWith Describes the START WITH clause of the query - null if not needed
     * @param connectBy This should be a query key expression which indicates an attribute who's mapping describes the hierarchy
     * @param orderSiblingsExpressions Contains expressions which indicate fields to be included in the ORDER SIBLINGS BY clause - null if not required
     */
    public void setHierarchicalQueryClause(Expression startWith, Expression connectBy, List<Expression> orderSiblingsExpressions) {
        this.startWithExpression = startWith;
        this.connectByExpression = connectBy;
        this.orderSiblingsByExpressions = orderSiblingsExpressions;
        setIsPrepared(false);
    }

    /**
     * PUBLIC:
     * Configure the mapping to use an instance of the specified container class
     * to hold the target objects.
     * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Collection interface.
     * <p>jdk1.1.x: The container class must be a subclass of Vector.
     */
    public void useCollectionClass(Class concreteClass) {
        // Set container policy.
        setContainerPolicy(ContainerPolicy.buildPolicyFor(concreteClass));

    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * The initial read size is 10 and page size is 5.
     */
    public void useCursoredStream() {
        useCursoredStream(10, 5);
    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * @param initialReadSize the initial number of objects to read
     * @param pageSize the number of objects to read when more objects
     * are needed from the database
     */
    public void useCursoredStream(int initialReadSize, int pageSize) {
        setContainerPolicy(new CursoredStreamPolicy(this, initialReadSize, pageSize));
    }

    /**
     * PUBLIC:
     * Use a CursoredStream as the result collection.
     * @param initialReadSize the initial number of objects to read
     * @param pageSize the number of objects to read when more objects
     * are needed from the database
     * @param sizeQuery a query that will return the size of the result set;
     * this must be set if an expression is not used (i.e. custom SQL)
     */
    public void useCursoredStream(int initialReadSize, int pageSize, ValueReadQuery sizeQuery) {
        setContainerPolicy(new CursoredStreamPolicy(this, initialReadSize, pageSize, sizeQuery));
    }

    /**
     * PUBLIC:
     * Configure the query to use an instance of the specified container class
     * to hold the result objects. The key used to index the value in the Map
     * is the value returned by a call to the specified zero-argument method.
     * The method must be implemented by the class (or a superclass) of the
     * value to be inserted into the Map.
     * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Map interface.
     * <p>jdk1.1.x: The container class must be a subclass of Hashtable.
     * <p>The referenceClass must set before calling this method.
     */
    public void useMapClass(Class concreteClass, String methodName) {
        // the reference class has to be specified before coming here
        if (getReferenceClass() == null) {
            throw QueryException.referenceClassMissing(this);
        }
        ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass);
        policy.setKeyName(methodName, getReferenceClass().getName());
        setContainerPolicy(policy);
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     */
    public void useScrollableCursor() {
        useScrollableCursor(10);
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     * @param pageSize the number of elements to be read into a the cursor
     * when more elements are needed from the database.
     */
    public void useScrollableCursor(int pageSize) {
        setContainerPolicy(new ScrollableCursorPolicy(this, pageSize));
    }

    /**
     * PUBLIC:
     * Use a ScrollableCursor as the result collection.
     * @param policy the scrollable cursor policy allows for additional result set options.
     * Example:<p>
     * ScrollableCursorPolicy policy = new ScrollableCursorPolicy()<p>
     * policy.setResultSetType(ScrollableCursorPolicy.TYPE_SCROLL_INSENSITIVE);<p>
     * query.useScrollableCursor(policy);<p>
     */
    public void useScrollableCursor(ScrollableCursorPolicy policy) {
        policy.setQuery(this);
        setContainerPolicy(policy);
    }

    /**
     * INTERNAL:
     * Indicates whether the query can use ResultSet optimization.
     * The method is called when the query is prepared, 
     * so it should refer only to the attributes that cannot be altered without re-preparing the query.
     * If the query is a clone and the original has been already prepared
     * this method will be called to set a (transient and therefore set to null) usesResultSetOptimization attribute. 
     */
    @Override
    public boolean supportsResultSetAccessOptimizationOnPrepare() {
        if (!super.supportsResultSetAccessOptimizationOnPrepare()) {
            return false;
        }
        return !this.containerPolicy.isMappedKeyMapPolicy() && !this.containerPolicy.shouldAddAll() &&  // MappedKeyMapPolicy requires the whole row, OrderListContainerPolicy requires all rows.
                !this.descriptor.shouldAlwaysConformResultsInUnitOfWork();  // will be supported when conformResult method is adapted to use ResultSet;  
    }

    /**
     * INTERNAL:
     * Indicates whether the query can use ResultSet optimization.
     * Note that the session must be already set.
     * The method is called when the query is executed, 
     * so it should refer only to the attributes that can be altered without re-preparing the query.
     */
    public boolean supportsResultSetAccessOptimizationOnExecute() {
        if (!super.supportsResultSetAccessOptimizationOnExecute()) {
            return false;
        }
        return !shouldConformResultsInUnitOfWork(); // could be supported if conformResult method is adapted to use ResultSetAccessOptimization
    }
}
