/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     10/15/2010-2.2 Guy Pelletier
//       - 322008: Improve usability of additional criteria applied to queries at the session/EM
//     04/01/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 2)
//     05/24/2011-2.3 Guy Pelletier
//       - 345962: Join fetch query when using tenant discriminator column fails.
//     08/18/2011-2.3.1 Guy Pelletier
//       - 355093: Add new 'includeCriteria' flag to Multitenant metadata
//     09/09/2011-2.3.1 Guy Pelletier
//       - 356197: Add new VPD type to MultitenantType
//     08/01/2012-2.5 Chris Delahunt
//       - 371950: JPA Metadata caching
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
//     IBM - Bug 537795: CASE THEN and ELSE scalar expression Constants should not be casted to CASE operand type
package org.eclipse.persistence.descriptors;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.expressions.CompoundExpression;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.expressions.SubSelectExpression;
import org.eclipse.persistence.internal.helper.ConcurrentFixedCache;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
import org.eclipse.persistence.internal.queries.ReportItem;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.DeleteObjectQuery;
import org.eclipse.persistence.queries.DoesExistQuery;
import org.eclipse.persistence.queries.InsertObjectQuery;
import org.eclipse.persistence.queries.JPAQueryBuilder;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.QueryResultsCachePolicy;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.UpdateObjectQuery;
import org.eclipse.persistence.queries.WriteObjectQuery;

/**
 * <p><b>Purpose</b>: The query manager allows for the database operations that EclipseLink
 * performs to be customized by the application.  For each descriptor a query can be
 * given that controls how a operation will occur.  A common example is if the application
 * requires a stored procedure to be used to insert the object, it can override the SQL call
 * in the insert query that EclipseLink will use to insert the object.
 * Queries can be customized to extend EclipseLink behavior, access non-relational data or use stored
 * procedures or customized SQL calls.
 * <p>
 * The queries that can be customized include:
 * <ul>
 * <li> insertQuery - used to insert the object
 * <li> updateQuery - used to update the object
 * <li> readObjectQuery - used to read a single object by primary key
 * <li> readAllQuery - used to read all of the objects of the class
 * <li> doesExistQuery - used to determine whether an insert or update should occur
 * <li> deleteQuery - used to delete the object
 * </ul>
 *
 * @see ClassDescriptor
 */
public class DescriptorQueryManager implements Cloneable, Serializable {
    protected InsertObjectQuery insertQuery;
    protected UpdateObjectQuery updateQuery;
    protected ReadObjectQuery readObjectQuery;
    protected ReadAllQuery readAllQuery;
    protected DeleteObjectQuery deleteQuery;
    protected DoesExistQuery doesExistQuery;
    protected ClassDescriptor descriptor;
    protected boolean hasCustomMultipleTableJoinExpression;
    protected String additionalCriteria;
    protected transient Expression additionalJoinExpression;
    protected transient Expression multipleTableJoinExpression;
    protected Map<String, List<DatabaseQuery>> queries;
    protected transient Map<DatabaseTable, Expression> tablesJoinExpressions;
    /** PERF: Update call cache for avoiding regenerated update SQL. */
    protected transient ConcurrentFixedCache cachedUpdateCalls;
    /** PERF: Expression query call cache for avoiding regenerated dynamic query SQL. */
    protected transient ConcurrentFixedCache cachedExpressionQueries;

    /**
     * queryTimeout has three possible settings: DefaultTimeout, NoTimeout, and 1..N
     * This applies to both DatabaseQuery.queryTimeout and DescriptorQueryManager.queryTimeout
     *
     * DatabaseQuery.queryTimeout:
     * - DefaultTimeout: get queryTimeout from DescriptorQueryManager
     * - NoTimeout, 1..N: overrides queryTimeout in DescriptorQueryManager
     *
     * DescriptorQueryManager.queryTimeout:
     * - DefaultTimeout: get queryTimeout from parent DescriptorQueryManager. If there is no
     * parent, default to NoTimeout
     * - NoTimeout, 1..N: overrides parent queryTimeout
     */
    public static final int NoTimeout = 0;
    public static final int DefaultTimeout = -1;
    protected int queryTimeout;

    public static final TimeUnit DefaultTimeoutUnit = TimeUnit.MILLISECONDS;
    protected TimeUnit queryTimeoutUnit;

    /**
     * INTERNAL:
     * Initialize the state of the descriptor query manager
     */
    public DescriptorQueryManager() {
        this.queries = new LinkedHashMap<>(5);
        setDoesExistQuery(new DoesExistQuery());// Always has a does exist.
        this.setQueryTimeout(DefaultTimeout);
        this.setQueryTimeoutUnit(DefaultTimeoutUnit);
    }

    /**
     * ADVANCED:
     * Set the max size of the expression query cache for avoiding regenerated dynamic query SQL.
     */
    public void setExpressionQueryCacheMaxSize(int maxSize) {
        this.cachedExpressionQueries = new ConcurrentFixedCache(maxSize);
    }

    /**
     * ADVANCED:
     * Return the max size of the expression query cache for avoiding regenerated dynamic query SQL.
     */
    public int getExpressionQueryCacheMaxSize() {
        return getCachedExpressionQueries().getMaxSize();
    }

    /**
     * PUBLIC:
     * Add the query to the descriptor queries with the given name
     * @param name This is the name of the query.  It will be set on the query and used to look it up.
     * @param query This is the query that will be added.  If the query being added has parameters, the
     * existing list of queries will be checked for matching queries.  If a matching query exists,
     * it will be replaced.
     */
    public void addQuery(String name, DatabaseQuery query) {
        query.setName(name);
        addQuery(query);
    }

    /**
     * PUBLIC:
     * Add the query to the session queries
     * @param query DatabaseQuery This is the query that will be added.  If the query being added has parameters, the
     * existing list of queries will be checked for matching queries.  If a matching query exists,
     * it will be replaced.
     */
    public synchronized void addQuery(DatabaseQuery query) {
        if (query instanceof ObjectLevelReadQuery && (query.getReferenceClassName() == null)) {
            ((ObjectLevelReadQuery)query).setReferenceClassName(getDescriptor().getJavaClassName());

            // try to set the reference ClassNotFoundException since it should only happen on the MW in which
            // case we will lazily initialize the reference class at a later point.
            try {
                ((ObjectLevelReadQuery)query).setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }

            //this is an optimization
            query.setDescriptor(getDescriptor());
        }

        // Add query has been synchronized for bug 3355199.
        // Additionally code has been added to ensure that the same query is not added twice.
        List<DatabaseQuery> queriesByName = getQueries().get(query.getName());
        if (queriesByName == null) {
            // lazily create Vector in Hashtable.
            queriesByName = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
            getQueries().put(query.getName(), queriesByName);
        } else {
            int argumentTypesSize = 0;
            if (query.getArguments() != null) {
                argumentTypesSize = query.getArguments().size();
            }
            List<String> argumentTypes = new ArrayList<>(argumentTypesSize);
            for (int i = 0; i < argumentTypesSize; i++) {
                argumentTypes.add(query.getArgumentTypeNames().get(i));
            }

            // Search for a query with the same parameters and replace it if one is found
            for (int i = 0; i < queriesByName.size(); i++) {
                DatabaseQuery currentQuery = queriesByName.get(i);

                // Here we are checking equality instead of assignability.  If you look at getQuery()
                // it is the other way around.
                // The reason we do this is we are replacing a query and we want to make sure we are
                // replacing the exact same one. - TW
                if (argumentTypes.equals(currentQuery.getArgumentTypeNames())) {
                    queriesByName.set(i, query);
                    return;
                }
            }
        }
        queriesByName.add(query);
    }

    /**
     * PUBLIC:
     * Assume that if the objects primary key does not include null then it must exist.
     * This may be used if the application guarantees or does not care about the existence check.
     */
    public void assumeExistenceForDoesExist() {
        getDoesExistQuery().assumeExistenceForDoesExist();
    }

    /**
     * PUBLIC:
     * Assume that the object does not exist. This may be used if the application guarantees or
     * does not care about the existence check.  This will always force an insert to be called.
     */
    public void assumeNonExistenceForDoesExist() {
        getDoesExistQuery().assumeNonExistenceForDoesExist();
    }

    /**
     * PUBLIC:
     * Default behavior.
     * Assume that if the objects primary key does not include null and it
     * is in the cache, then is must exist.
     */
    public void checkCacheForDoesExist() {
        getDoesExistQuery().checkCacheForDoesExist();
    }

    /**
     * PUBLIC:
     * Perform does exist check on the database
     */
    public void checkDatabaseForDoesExist() {
        getDoesExistQuery().checkDatabaseForDoesExist();
    }

    /**
     * INTERNAL:
     * Clone the query manager
     */
    @Override
    public Object clone() {
        DescriptorQueryManager manager = null;
        try {
            manager = (DescriptorQueryManager)super.clone();
        } catch (Exception exception) {
            throw new AssertionError(exception);
        }

        // Bug 3037701 - clone the queries
        manager.setQueries(new LinkedHashMap<>(getQueries().size()));//bug5677655
        Iterator<List<DatabaseQuery>> iterator = queries.values().iterator();
        while (iterator.hasNext()) {
            Iterator<DatabaseQuery> queriesForKey = iterator.next().iterator();
            while (queriesForKey.hasNext()) {
                DatabaseQuery initialQuery = queriesForKey.next();
                DatabaseQuery clonedQuery = (DatabaseQuery)initialQuery.clone();
                clonedQuery.setDescriptor(manager.getDescriptor());
                manager.addQuery(clonedQuery);
            }
        }
        manager.setDoesExistQuery((DoesExistQuery)getDoesExistQuery().clone());
        if (getReadAllQuery() != null) {
            manager.setReadAllQuery((ReadAllQuery)getReadAllQuery().clone());
        }
        if (getReadObjectQuery() != null) {
            manager.setReadObjectQuery((ReadObjectQuery)getReadObjectQuery().clone());
        }
        if (getUpdateQuery() != null) {
            manager.setUpdateQuery((UpdateObjectQuery)getUpdateQuery().clone());
        }
        if (getInsertQuery() != null) {
            manager.setInsertQuery((InsertObjectQuery)getInsertQuery().clone());
        }
        if (getDeleteQuery() != null) {
            manager.setDeleteQuery((DeleteObjectQuery)getDeleteQuery().clone());
        }

        return manager;
    }

    /**
     * PUBLIC:
     * Return true if the query is defined on the session
     */
    public boolean containsQuery(String queryName) {
        return queries.containsKey(queryName);
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this Query Manager to actual class-based
     * settings
     * This method is implemented by subclasses as necessary.
     */
    public void convertClassNamesToClasses(ClassLoader classLoader){
        Iterator<List<DatabaseQuery>> queryVectors = getQueries().values().iterator();
        while (queryVectors.hasNext()){
            Iterator<DatabaseQuery> queries = queryVectors.next().iterator();
            while (queries.hasNext()){
                queries.next().convertClassNamesToClasses(classLoader);
            }
        }
        if (getReadObjectQuery() != null) {
            getReadObjectQuery().convertClassNamesToClasses(classLoader);
        }
        if (getReadAllQuery() != null) {
            getReadAllQuery().convertClassNamesToClasses(classLoader);
        }
    }

    /**
     * ADVANCED:
     * Returns the join expression that should be appended to all of the descriptors expressions
     * Contains any multiple table or inheritance dependencies
     */
    public Expression getAdditionalJoinExpression() {
        return additionalJoinExpression;
    }

    /**
     * ADVANCED:
     * Return the receiver's delete query.
     * This should be an instance of a valid subclass of DeleteObjectQuery.
     * If specified this is used by the descriptor to delete itself and its private parts from the database.
     * This gives the user the ability to define exactly how to delete the data from the database,
     * or access data external from the database or from some other framework.
     */
    public DeleteObjectQuery getDeleteQuery() {
        return deleteQuery;
    }

    /**
     * ADVANCED:
     * Return the receiver's delete SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * <p>
     *    Example, "delete from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public String getDeleteSQLString() {
        if (getDeleteQuery() == null) {
            return null;
        }

        return getDeleteQuery().getSQLString();
    }

    /**
     * INTERNAL:
     * Return the descriptor associated with this descriptor query manager
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * ADVANCED:
     * Return the receiver's  does exist query.
     * This should be an instance of a valid subclass of DoesExistQuery.
     * If specified this is used by the descriptor to query existence of an object in the database.
     * This gives the user the ability to define exactly how to query existence from the database,
     * or access data external from the database or from some other framework.
     */
    public DoesExistQuery getDoesExistQuery() {
        return doesExistQuery;
    }

    /**

     * ADVANCED:
     * Return the receiver's does exist SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with there own SQL or procedure call.
     * The arguments are translated from the fields of the source row, through replacing the field names marked by '#'
     * with the values for those fields.
     * This must return null if the object does not exist, otherwise return a database row.
     * <p>
     * Example, "select EMPLOYEE_ID from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public String getDoesExistSQLString() {
        if (getDoesExistQuery() == null) {
            return null;
        }

        return getDoesExistQuery().getSQLString();
    }

    /**
     * INTERNAL:
     * This method is explicitly used by the Builder only.
     */
    public String getExistenceCheck() {
        if (getDoesExistQuery().shouldAssumeExistenceForDoesExist()) {
            return "Assume existence";
        } else if (getDoesExistQuery().shouldAssumeNonExistenceForDoesExist()) {
            return "Assume non-existence";
        } else if (getDoesExistQuery().shouldCheckCacheForDoesExist()) {
            return "Check cache";
        } else if (getDoesExistQuery().shouldCheckDatabaseForDoesExist()) {
            return "Check database";
        } else {
            // Default.
            return "Check cache";
        }
    }

    /**
      * ADVANCED:
      * Return the receiver's insert query.
      * This should be an instance of a valid subclass of InsertObjectQuery.
      * If specified this is used by the descriptor to insert itself into the database.
      * If the receiver uses sequence numbers, this query must return the updated sequence value.
      * This gives the user the ability to define exactly how to insert the data into the database,
      * or access data external from the database or from some other framework.
      */
    public InsertObjectQuery getInsertQuery() {
        return insertQuery;
    }

    /**
     * ADVANCED:
     * Return the receiver's insert SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * <p>
     * Example, "insert into EMPLOYEE (F_NAME, L_NAME) values (#F_NAME, #L_NAME)".
     */
    public String getInsertSQLString() {
        if (getInsertQuery() == null) {
            return null;
        }

        return getInsertQuery().getSQLString();
    }

    /**
     * ADVANCED:
     * This is normally generated for descriptors that have multiple tables.
     * However, if the additional table does not reference the primary tables primary key,
     * this expression may be set directly.
     */
    public Expression getMultipleTableJoinExpression() {
        return multipleTableJoinExpression;
    }

    /**
     * PUBLIC:
     * Return the pre-defined queries for the descriptor.
     * The Map returned contains Lists of queries.
     *
     * @see #getAllQueries()
     */
    public Map<String, List<DatabaseQuery>> getQueries() {
        return queries;
    }

    /**
     * PUBLIC:
     * Return the pre-defined queries for the descriptor.  The Vector returned
     * contains all queries for this descriptor.
     *
     * @see #getQueries()
     */
    public Vector getAllQueries() {
        Vector<DatabaseQuery> allQueries = new Vector<>();
        for (Iterator<List<DatabaseQuery>> vectors = getQueries().values().iterator(); vectors.hasNext();) {
            allQueries.addAll(vectors.next());
        }
        return allQueries;
    }

    /**
     * INTERNAL:
     * Set pre-defined queries for the descriptor.  Converts the Vector to a hashtable
     */
    public void setAllQueries(Vector vector) {
        for (Enumeration enumtr = vector.elements(); enumtr.hasMoreElements();) {
            addQuery((DatabaseQuery)enumtr.nextElement());
        }
    }

    /**
     * PUBLIC:
     * set the pre-defined queries for the descriptor.  Used to write out deployment XML
     */
    public void setQueries(Map map) {
        queries = map;
    }

    /**
     * PUBLIC:
     * Return the query name from the set of pre-defined queries
     * If only one query exists with this name, it will be returned.
     * If there are multiple queries of this name, this method will search for a query
     * with no arguments and return the first one it finds.
     *
     * @see #getQuery(String, Vector)
     */
    public DatabaseQuery getQuery(String queryName) {
        return getQuery(queryName, null);
    }

    /**
     * PUBLIC:
     * Return the query from the set of pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * This method should be used if the Session has multiple queries with the same name but
     * different arguments.
     * If only one query exists, it will be returned regardless of the arguments.
     * If multiple queries exist, the first query that has corresponding argument types will be returned
     *
     * @see #getQuery(String)
     */
    public DatabaseQuery getQuery(String name, Vector arguments) {
        DatabaseQuery query = getLocalQuery(name, arguments);

        // CR#3711: Check if a query with the same name exists for this descriptor.
        // If not, recursively check descriptors of parent classes.  If nothing is
        // found in parents, return null.
        if (query == null) {
            DatabaseQuery parentQuery = getQueryFromParent(name, arguments);
            if ((parentQuery != null) && parentQuery.isReadQuery()) {
                parentQuery = (DatabaseQuery)parentQuery.clone();
                ((ObjectLevelReadQuery)parentQuery).setReferenceClass(this.descriptor.getJavaClass());
                addQuery(name, parentQuery);
            }
            return parentQuery;
        }
        return query;
    }

    /**
     * INTENAL:
     * Return the query from the set of pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * Only returns those queries locally defined, not superclass's queries
     * If only one query exists, it will be returned regardless of the arguments.
     * If multiple queries exist, the first query that has corresponding argument types will be returned
     *
     * @see #getQuery(String)
     */
    public DatabaseQuery getLocalQuery(String name, Vector arguments) {
        List<DatabaseQuery> queries = getQueries().get(name);

        if (queries == null) {
            return null;
        }

        // Short circuit the simple, most common case of only one query.
        if (queries.size() == 1) {
            return queries.get(0);
        }

        // CR#3754; Predrag; mar 19/2002;
        // We allow multiple named queries with the same name but
        // different argument set; we can have only one query with
        // no arguments; Vector queries is not sorted;
        // When asked for the query with no parameters the
        // old version did return the first query - wrong:
        // return (DatabaseQuery) queries.firstElement();
        int argumentTypesSize = 0;
        if (arguments != null) {
            argumentTypesSize = arguments.size();
        }
        Vector argumentTypes = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(argumentTypesSize);
        for (int i = 0; i < argumentTypesSize; i++) {
            argumentTypes.addElement(arguments.elementAt(i).getClass());
        }
        return getLocalQueryByArgumentTypes(name, argumentTypes);

    }

    /**
     * INTERNAL:
     * Return the query from the set of pre-defined queries with the given name and argument types.
     * This allows for common queries to be pre-defined, reused and executed by name.
     * Only returns those queries locally defined, not superclass's queries
     * If only one query exists, it will be returned regardless of the arguments.
     * If multiple queries exist, the first query that has corresponding argument types will be returned
     *
     * @see #getQuery(String)
     */
    public DatabaseQuery getLocalQueryByArgumentTypes(String name, List argumentTypes) {
        List<DatabaseQuery> queries = getQueries().get(name);

        if (queries == null) {
            return null;
        }

        // Short circuit the simple, most common case of only one query.
        if (queries.size() == 1) {
            return queries.get(0);
        }

        for (DatabaseQuery query : queries) {
            // BUG#2698755
            // This check was backward, we default the type to Object
            // Was checking Object is descendant of String not other way.
            if (Helper.areTypesAssignable(query.getArgumentTypes(), argumentTypes)) {
                return query;
            }
        }

        return null;

    }

    /**
     * INTERNAL:
     * CR#3711: Check if the class for this descriptor has a parent class.
     * Then search this parent's descriptor for a query with the same name
     * and arguments.  If nothing found, return null.
     *
     * This method should only be used recursively by getQuery().
     */
    protected DatabaseQuery getQueryFromParent(String name, Vector arguments) {
        ClassDescriptor descriptor = this.descriptor;
        if (descriptor.hasInheritance()) {
            InheritancePolicy inheritancePolicy = descriptor.getInheritancePolicy();
            ClassDescriptor parent = inheritancePolicy.getParentDescriptor();

            // if parent exists, check for the query
            if (parent != null) {
                return parent.getQueryManager().getQuery(name, arguments);
            }
        }
        return null;
    }

    /**
      * ADVANCED:
      * Return the receiver's read query.
      * This should be an instance of a valid subclass of ReadAllQuery.
      */
    public ReadAllQuery getReadAllQuery() {
        return readAllQuery;
    }

    /**
     * ADVANCED:
     * Return the receiver's read SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the read arguments row,
     * through replacing the field names marked by '#' with the values for those fields.
     * Note that this is only used on readAllObjects(Class), and not when an expression is provided.
     * <p>
     * Example, "select * from EMPLOYEE"
     */
    public String getReadAllSQLString() {
        if (getReadAllQuery() == null) {
            return null;
        }

        return getReadAllQuery().getSQLString();
    }

    /**
     * ADVANCED:
     * Return the receiver's read query.
     * This should be an instance of a valid subclass of ReadObjectQuery.
     * If specified this is used by the descriptor to read itself from the database.
     * The read arguments must be the primary key of the object only.
     * This gives the user the ability to define exactly how to read the object from the database,
     * or access data external from the database or from some other framework.
     */
    public ReadObjectQuery getReadObjectQuery() {
        return readObjectQuery;
    }

    /**
     * ADVANCED:
     * Return the receiver's read SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the read arguments row,
     * through replacing the field names marked by '#' with the values for those fields.
     * This must accept only the primary key of the object as arguments.
     * <p>
     * Example, "select * from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID"
     */
    public String getReadObjectSQLString() {
        if (getReadObjectQuery() == null) {
            return null;
        }

        return getReadObjectQuery().getSQLString();
    }

    /**
      * ADVANCED:
      * Return the receiver's update query.
      * This should be an instance of a valid subclass of UpdateObjectQuery.
      * If specified this is used by the descriptor to insert itself into the database.
      * If the receiver uses optimistic locking this must raise an error on optimistic lock failure.
      * This gives the user the ability to define exactly how to update the data into the database,
      * or access data external from the database or from some other framework.
      */
    public UpdateObjectQuery getUpdateQuery() {
        return updateQuery;
    }

    /**
     * ADVANCED:
     * Return the receiver's update SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with there own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * This must check the optimistic lock field and raise an error on optimistic lock failure.
     * <p>
     * Example, "update EMPLOYEE set F_NAME to #F_NAME, L_NAME to #L_NAME where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public String getUpdateSQLString() {
        if (getUpdateQuery() == null) {
            return null;
        }

        return getUpdateQuery().getSQLString();
    }

    /**
     * ADVANCED:
     * Return true if an additional criteria has been set on this query manager.
     */
    public boolean hasAdditionalCriteria() {
        return additionalCriteria != null;
    }

    /**
     * INTERNAL:
     * Return if a custom join expression is used.
     */
    public boolean hasCustomMultipleTableJoinExpression() {
        return hasCustomMultipleTableJoinExpression;
    }

    /**
     * INTERNAL:
     * Flag that specifies if a delete query is available
     */
    public boolean hasDeleteQuery() {
        return (deleteQuery != null);
    }

    /**
     * INTERNAL:
     * Flag that specifies if a does exist query is available
     */
    public boolean hasDoesExistQuery() {
        return (doesExistQuery != null);
    }

    /**
     * INTERNAL:
     * Flag that specifies if a insert query is available
     */
    public boolean hasInsertQuery() {
        return (insertQuery != null);
    }

    /**
     * INTERNAL:
     * Flag that specifies if a read all query is available
     */
    public boolean hasReadAllQuery() {
        return (readAllQuery != null);
    }

    /**
     * INTERNAL:
     * Flag that specifies if a read object  query is available
     */
    public boolean hasReadObjectQuery() {
        return (readObjectQuery != null);
    }

    /**
     * INTERNAL:
     * Flag that specifies if a update query is available
     */
    public boolean hasUpdateQuery() {
        return (updateQuery != null);
    }

    /**
     * INTERNAL:
     * populate the queries with the descriptor.
     */
    private void populateQueries() {

        /* CR2260
         * Description:
         *   NullPointerException accessing null descriptor
         * Fix:
         *   Initialize queries with an instantiated descriptor at this point
         */
        if (getInsertQuery() != null) {
            getInsertQuery().setDescriptor(descriptor);
        }
        if (getUpdateQuery() != null) {
            getUpdateQuery().setDescriptor(descriptor);
        }
        if (getReadObjectQuery() != null) {
            getReadObjectQuery().setReferenceClass(getDescriptor().getJavaClass());
            getReadObjectQuery().setDescriptor(descriptor);
        }
        if (getDeleteQuery() != null) {
            getDeleteQuery().setDescriptor(descriptor);
        }
        if (getReadAllQuery() != null) {
            getReadAllQuery().setReferenceClass(getDescriptor().getJavaClass());
            getReadAllQuery().setDescriptor(descriptor);
        }
        for (Iterator it = getAllQueries().iterator(); it.hasNext();) {
            ((DatabaseQuery)it.next()).setDescriptor(descriptor);
        }
    }

    /**
     * INTERNAL:
     * Post initialize the mappings
     */
    public void initialize(AbstractSession session) {
        this.initializeQueryTimeout(session);

        if (getDescriptor().isAggregateDescriptor()) {
            return;
        }

        if (getMultipleTableJoinExpression() != null) {
            // Combine new multiple table expression to additional join expression
            setAdditionalJoinExpression(getMultipleTableJoinExpression().and(getAdditionalJoinExpression()));
        }

        if (getDescriptor().isAggregateCollectionDescriptor()) {
            return;
        }

        // Configure default query cache for all named queries.
        QueryResultsCachePolicy defaultQueryCachePolicy = session.getProject().getDefaultQueryResultsCachePolicy();
        if (defaultQueryCachePolicy != null && !getDescriptor().getCachePolicy().isIsolated()) {
            for (List<DatabaseQuery> queries : getQueries().values()) {
                for (DatabaseQuery query : queries) {
                    if (query.isReadQuery()) {
                        ReadQuery readQuery = (ReadQuery)query;
                        if (!readQuery.shouldCacheQueryResults()) {
                            readQuery.setQueryResultsCachePolicy(defaultQueryCachePolicy.clone());
                        }
                    }
                }
            }
        }

        getDescriptor().initialize(this, session);
    }

    /**
     * INTERNAL:
     * Initialize the queryTimeout to:
     *
     * NoTimeout: If queryTimeout is DefaultTimeout, either directly or via inheritance.
     * Parent's Timeout: If queryTimeout is something other than DefaultTimeout via my parent.
     */
    public void initializeQueryTimeout(AbstractSession session) {
        //if queryTimeout is DefaultTimeout, try to get my parent's queryTimeout
        if (getQueryTimeout() == DefaultTimeout) {
            if (getDescriptor().hasInheritance() && (this.getDescriptor().getInheritancePolicy().getParentDescriptor() != null)) {
                setQueryTimeout(this.getParentDescriptorQueryManager().getQueryTimeout());
            }
        }
        if (getQueryTimeoutUnit().equals(DefaultTimeoutUnit)) {
            if (getDescriptor().hasInheritance() && (this.getDescriptor().getInheritancePolicy().getParentDescriptor() != null)) {
                setQueryTimeoutUnit(this.getParentDescriptorQueryManager().getQueryTimeoutUnit());
            }
        }

        //if I have DefaultTimeout (via parent or not), set to NoTimeout
        if (getQueryTimeout() == DefaultTimeout) {
            setQueryTimeout(NoTimeout);
        }
    }

    /**
     * INTERNAL:
     * Get the parent DescriptorQueryManager.
     * Caution must be used in using this method as it expects the descriptor
     * to have inheritance.
     * Calling this when the descriptor that does not use inheritance will cause problems, #hasInheritance() must
     * always first be called.
     */
    public DescriptorQueryManager getParentDescriptorQueryManager() {
        return this.descriptor.getInheritancePolicy().getParentDescriptor().getQueryManager();
    }

    /**
     * INTERNAL:
     * Execute the post delete operation for the query
     */
    public void postDelete(DeleteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            List<DatabaseMapping> mappings = builder.getRelationshipMappings();
            int size = mappings.size();
            for (int index = 0; index < size; index++) {
                mappings.get(index).postDelete(query);
            }
        }
    }

    /**
     * INTERNAL:
     * Post initializations after mappings are initialized.
     */
    public void postInitialize(AbstractSession session) throws DescriptorException {
        // If the additional criteria is specified, append it to the additional
        // join expression. We do this in postInitialize after all the mappings
        // have been fully initialized.
        if (additionalCriteria != null) {
            if (getDescriptor().hasInheritance() && getDescriptor().getInheritancePolicy().hasView()) {
                throw DescriptorException.additionalCriteriaNotSupportedWithInheritanceViews(getDescriptor());
            }

            JPAQueryBuilder queryBuilder = session.getQueryBuilder();
            Expression selectionCriteria = queryBuilder.buildSelectionCriteria(
               getDescriptor().getAlias(),
               additionalCriteria,
               session
            );

            updatePropertyParameterExpression(selectionCriteria);
            additionalJoinExpression = selectionCriteria.and(additionalJoinExpression);
        }

        if (additionalJoinExpression != null) {
            // The make sure the additional join expression has the correct
            // context, rebuild the additional join expression on a new
            // expression builder.
            additionalJoinExpression = additionalJoinExpression.rebuildOn(new ExpressionBuilder());
        }
    }

    /**
     * INTERNAL:
     * This method will walk the given expression and mark any parameter
     * expressions as property expressions. This is done when additional
     * criteria has been specified and parameter values must be resolved
     * through session properties.
     *
     * @see #postInitialize
     */
    protected void updatePropertyParameterExpression(Expression exp) {
        if (exp.isCompoundExpression()) {
            updatePropertyParameterExpression(((CompoundExpression) exp).getFirstChild());
            updatePropertyParameterExpression(((CompoundExpression) exp).getSecondChild());
        } else if (exp.isFunctionExpression()) {
            for (Expression e : ((FunctionExpression) exp).getChildren()) {
                updatePropertyParameterExpression(e);
            }
        } else if (exp.isSubSelectExpression()) {
            ReportQuery subSelectQuery = ((SubSelectExpression) exp).getSubQuery();
            for (ReportItem item : subSelectQuery.getItems()) {
                updatePropertyParameterExpression(item.getAttributeExpression());
            }
        }

        if (exp.isParameterExpression()) {
            ((ParameterExpression) exp).setIsProperty(true);
        }
    }

    /**
     * INTERNAL:
     * Execute the post insert operation for the query
     */
    public void postInsert(WriteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            List<DatabaseMapping> mappings = builder.getRelationshipMappings();
            int size = mappings.size();
            for (int index = 0; index < size; index++) {
                mappings.get(index).postInsert(query);
            }
        }
    }

    /**
     * INTERNAL:
     * Execute the post update operation for the query
     */
    public void postUpdate(WriteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            // PERF: Only process changed mappings.
            ObjectChangeSet changeSet = query.getObjectChangeSet();
            if ((changeSet != null) && (!changeSet.isNew())) {
                List<org.eclipse.persistence.sessions.changesets.ChangeRecord> changeRecords = changeSet.getChanges();
                int size = changeRecords.size();
                for (int index = 0; index < size; index++) {
                    ChangeRecord record = (ChangeRecord)changeRecords.get(index);
                    record.getMapping().postUpdate(query);
                }
            } else {
                List<DatabaseMapping> mappings = builder.getRelationshipMappings();
                int size = mappings.size();
                for (int index = 0; index < size; index++) {
                    mappings.get(index).postUpdate(query);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Execute the pre delete operation for the query
     */
    public void preDelete(DeleteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            List<DatabaseMapping> mappings = builder.getRelationshipMappings();
            int size = mappings.size();
            for (int index = 0; index < size; index++) {
                mappings.get(index).preDelete(query);
            }
        }
    }

    /**
     * INTERNAL:
     * Initialize the query manager.
     * Any custom queries must be inherited from the parent before any initialization.
     */
    public void preInitialize(AbstractSession session) {
        if (getDescriptor().isAggregateDescriptor()) {
            return;
        }

        // Must inherit parent query customization if not redefined.
        if (getDescriptor().isChildDescriptor()) {
            DescriptorQueryManager parentQueryManager = getDescriptor().getInheritancePolicy().getParentDescriptor().getQueryManager();

            if ((!hasInsertQuery()) && (parentQueryManager.hasInsertQuery())) {
                setInsertQuery((InsertObjectQuery)parentQueryManager.getInsertQuery().clone());
            }
            if ((!hasUpdateQuery()) && (parentQueryManager.hasUpdateQuery())) {
                setUpdateQuery((UpdateObjectQuery)parentQueryManager.getUpdateQuery().clone());
            }
            if ((!hasDeleteQuery()) && (parentQueryManager.hasDeleteQuery())) {
                setDeleteQuery((DeleteObjectQuery)parentQueryManager.getDeleteQuery().clone());
            }
            if ((!hasReadObjectQuery()) && (parentQueryManager.hasReadObjectQuery())) {
                setReadObjectQuery((ReadObjectQuery)parentQueryManager.getReadObjectQuery().clone());
            }
            if ((!hasReadAllQuery()) && (parentQueryManager.hasReadAllQuery())) {
                setReadAllQuery((ReadAllQuery)parentQueryManager.getReadAllQuery().clone());
            }
            if ((!getDoesExistQuery().isUserDefined()) && getDoesExistQuery().shouldCheckCacheForDoesExist()) {
                setDoesExistQuery(((DoesExistQuery)parentQueryManager.getDoesExistQuery().clone()));
            }
        }
    }

    /**
     * INTERNAL:
     * Execute the pre insert  operation for the query.
     */
    public void preInsert(WriteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            List<DatabaseMapping> mappings = builder.getRelationshipMappings();
            int size = mappings.size();
            for (int index = 0; index < size; index++) {
                mappings.get(index).preInsert(query);
            }
        }
    }

    /**
     * INTERNAL:
     * Execute the pre update operation for the query
     */
    public void preUpdate(WriteObjectQuery query) {
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        // PERF: Only process relationships.
        if (!builder.isSimple()) {
            // PERF: Only process changed mappings.
            ObjectChangeSet changeSet = query.getObjectChangeSet();
            if ((changeSet != null) && (!changeSet.isNew())) {
                List<org.eclipse.persistence.sessions.changesets.ChangeRecord> changeRecords = changeSet.getChanges();
                int size = changeRecords.size();
                for (int index = 0; index < size; index++) {
                    ChangeRecord record = (ChangeRecord)changeRecords.get(index);
                    record.getMapping().preUpdate(query);
                }
            } else {
                List<DatabaseMapping> mappings = builder.getRelationshipMappings();
                int size = mappings.size();
                for (int index = 0; index < size; index++) {
                    mappings.get(index).preUpdate(query);
                }
            }
        }
    }

    /**
     * PUBLIC:
     * Remove all queries with the given query name from the set of pre-defined queries
     *
     * @see #removeQuery(String, Vector)
     */
    public void removeQuery(String queryName) {
        queries.remove(queryName);
    }

    /**
     * PUBLIC:
     * Remove the specific query with the given queryName and argumentTypes.
     *
     * @see #removeQuery(String)
     */
    public void removeQuery(String queryName, Vector argumentTypes) {
        List<DatabaseQuery> queries = getQueries().get(queryName);
        if (queries != null) {
            DatabaseQuery query = null;
            for (DatabaseQuery q : queries) {
                if (Helper.areTypesAssignable(argumentTypes, q.getArgumentTypes())) {
                    query = q;
                    break;
                }
            }
            if (query != null) {
                queries.remove(query);
            }
        }
    }

    /**
     * ADVANCED:
     * Set the additional join criteria that will be used to form the additional
     * join expression. The additionalCriteria is a jpql fragment at this point.
     * @see #setAdditionalJoinExpression
     */
    public void setAdditionalCriteria(String additionalCriteria) {
        this.additionalCriteria = additionalCriteria;
    }

    /**
     * ADVANCED:
     * Set the additional join expression. Used in conjunction with
     * multiple tables and inheritance relationships.
     * This can also be used if a sub-expression is always required to be
     * appended to all queries.  Such as tables that are shared based on a type field
     * without inheritance.
     */
    public void setAdditionalJoinExpression(Expression additionalJoinExpression) {
        this.additionalJoinExpression = additionalJoinExpression;
    }

    /**
     * ADVANCED:
     * Set the receiver's delete query.
     * This should be an instance of a valid subclass of DeleteObjectQuery.
     * If specified this is used by the descriptor to delete itself and its private parts from the database.
     * This gives the user the ability to define exactly how to delete the data from the database,
     * or access data external from the database or from some other framework.
     */
    public void setDeleteQuery(DeleteObjectQuery query) {
        this.deleteQuery = query;
        if (query == null) {
            return;
        }
        query.setIsUserDefined(true);
        query.setDescriptor(getDescriptor());
        if (query.isCallQuery()) {
            query.setIsFullRowRequired(true);
        }
    }

    /**
     * ADVANCED:
     * Set the receiver's delete SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     *    Example, "delete from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public void setDeleteSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }

        DeleteObjectQuery query = new DeleteObjectQuery();
        query.setSQLString(sqlString);
        setDeleteQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's delete call.
     * This allows the user to override the delete operation.
     */
    public void setDeleteCall(Call call) {
        if (call == null) {
            return;
        }
        DeleteObjectQuery query = new DeleteObjectQuery();
        query.setCall(call);
        setDeleteQuery(query);
    }

    /**
     * INTERNAL:
     * Set the descriptor.
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
        //Gross alert: This is for the case when we are reading from XML, and
        //we have to compensate for no descriptor available at read time.  - JL
        populateQueries();

    }

    /**
     * ADVANCED:
     * Set the receiver's  does exist query.
     * This should be an instance of a valid subclass of DoesExistQuery.
     * If specified this is used by the descriptor to query existence of an object in the database.
     * This gives the user the ability to define exactly how to query existence from the database,
     * or access data external from the database or from some other framework.
     */
    public void setDoesExistQuery(DoesExistQuery query) {
        this.doesExistQuery = query;
        if (query == null) {
            return;
        }
        this.doesExistQuery.setIsUserDefined(true);
        this.doesExistQuery.setDescriptor(getDescriptor());
    }

    /**
     * ADVANCED:
     * Set the receiver's does exist SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with there own SQL or procedure call.
     * The arguments are translated from the fields of the source row, through replacing the field names marked by '#'
     * with the values for those fields.
     * This must return null if the object does not exist, otherwise return a database row.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     * Example, "select EMPLOYEE_ID from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public void setDoesExistSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }
        getDoesExistQuery().setSQLString(sqlString);
        getDoesExistQuery().checkDatabaseForDoesExist();
    }

    /**
     * ADVANCED:
     * Set the receiver's does exist call.
     * This allows the user to override the does exist operation.
     */
    public void setDoesExistCall(Call call) {
        if (call == null) {
            return;
        }
        getDoesExistQuery().setCall(call);
    }

    /**
     * INTERNAL:
     * This method is explicitly used by the Builder only.
     */
    public void setExistenceCheck(String token) throws DescriptorException {
        if (token.equals("Check cache")) {
            checkCacheForDoesExist();
        } else if (token.equals("Check database")) {
            checkDatabaseForDoesExist();
        } else if (token.equals("Assume existence")) {
            assumeExistenceForDoesExist();
        } else if (token.equals("Assume non-existence")) {
            assumeNonExistenceForDoesExist();
        } else {
            throw DescriptorException.setExistenceCheckingNotUnderstood(token, getDescriptor());
        }
    }

    /**
     * INTENAL:
     * Set if a custom join expression is used.
     */
    protected void setHasCustomMultipleTableJoinExpression(boolean hasCustomMultipleTableJoinExpression) {
        this.hasCustomMultipleTableJoinExpression = hasCustomMultipleTableJoinExpression;
    }

    /**
     * ADVANCED:
     * Set the receiver's insert query.
     * This should be an instance of a valid subclass of InsertObjectQuery.
     * If specified this is used by the descriptor to insert itself into the database.
     * This gives the user the ability to define exactly how to insert the data into the database,
     * or access data external from the database or from some other framework.
     */
    public void setInsertQuery(InsertObjectQuery insertQuery) {
        this.insertQuery = insertQuery;
        if (insertQuery == null) {
            return;
        }
        this.insertQuery.setIsUserDefined(true);
        this.insertQuery.setDescriptor(getDescriptor());
    }

    /**
     * ADVANCED:
     * Set the receiver's insert call.
     * This allows the user to override the insert operation.
     */
    public void setInsertCall(Call call) {
        if (call == null) {
            return;
        }
        InsertObjectQuery query = new InsertObjectQuery();
        query.setCall(call);
        setInsertQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's insert SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     * Example, "insert into EMPLOYEE (F_NAME, L_NAME) values (#F_NAME, #L_NAME)".
     */
    public void setInsertSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }

        InsertObjectQuery query = new InsertObjectQuery();
        query.setSQLString(sqlString);
        setInsertQuery(query);
    }

    /**
     * ADVANCED:
     * Return the receiver's insert call.
     * This allows the user to override the insert operation.
     */
    public Call getInsertCall() {
        if (getInsertQuery() == null) {
            return null;
        }
        return getInsertQuery().getDatasourceCall();
    }

    /**
     * ADVANCED:
     * Return the receiver's update call.
     * This allows the user to override the update operation.
     */
    public Call getUpdateCall() {
        if (getUpdateQuery() == null) {
            return null;
        }
        return getUpdateQuery().getDatasourceCall();
    }

    /**
     * ADVANCED:
     * Return the receiver's delete call.
     * This allows the user to override the delete operation.
     */
    public Call getDeleteCall() {
        if (getDeleteQuery() == null) {
            return null;
        }
        return getDeleteQuery().getDatasourceCall();
    }

    /**
     * ADVANCED:
     * Return the receiver's read-object call.
     * This allows the user to override the read-object operation.
     */
    public Call getReadObjectCall() {
        if (getReadObjectQuery() == null) {
            return null;
        }
        return getReadObjectQuery().getDatasourceCall();
    }

    /**
     * ADVANCED:
     * Return the receiver's read-all call.
     * This allows the user to override the read-all operation.
     */
    public Call getReadAllCall() {
        if (getReadAllQuery() == null) {
            return null;
        }
        return getReadAllQuery().getDatasourceCall();
    }

    /**
     * ADVANCED:
     * Return the receiver's does-exist call.
     * This allows the user to override the does-exist operation.
     */
    public Call getDoesExistCall() {
        if (getDoesExistQuery() == null) {
            return null;
        }
        return getDoesExistQuery().getDatasourceCall();
    }

    /**
     * INTERNAL:
     * Used in case descriptor has additional tables:
     * each additional table mapped to an expression joining it.
     */
    public Map<DatabaseTable, Expression> getTablesJoinExpressions() {
        if (tablesJoinExpressions == null) {
            tablesJoinExpressions = new HashMap<>();
        }
        return tablesJoinExpressions;
    }

    /**
     * INTERNAL:
     * Used to set the multiple table join expression that was generated by EclipseLink as opposed
     * to a custom one supplied by the user.
     * @see #setMultipleTableJoinExpression(Expression)
     */
    public void setInternalMultipleTableJoinExpression(Expression multipleTableJoinExpression) {
        this.multipleTableJoinExpression = multipleTableJoinExpression;
    }

    /**
     * ADVANCED:
     * This is normally generated for descriptors that have multiple tables.
     * However, if the additional table does not reference the primary table's primary key,
     * this expression may be set directly.
     */
    public void setMultipleTableJoinExpression(Expression multipleTableJoinExpression) {
        this.multipleTableJoinExpression = multipleTableJoinExpression;
        setHasCustomMultipleTableJoinExpression(true);
    }

    /**
     * ADVANCED:
     * Set the receiver's read all query.
     * This should be an instance of a valid subclass of ReadAllQuery.
     * If specified this is used by the descriptor to read all instances of its class from the database.
     * This gives the user the ability to define exactly how to read all objects from the database,
     * or access data external from the database or from some other framework.
     * Note that this is only used on readAllObjects(Class), and not when an expression is provided.
     */
    public void setReadAllQuery(ReadAllQuery query) {
        this.readAllQuery = query;
        if (query == null) {
            return;
        }

        this.readAllQuery.setIsUserDefined(true);

        /* CR2260 - Steven Vo
         * Description:
         *  NullPointerException accessing null descriptor
         * Fix:
         *   Setting query's descriptor and reference class when descriptor is not null.
         *   Otherwise, wait until the descriptor is set.See populateQueries() that is
         *   called by setDescriptor()
         */
        if (this.getDescriptor() != null) {
            this.readAllQuery.setDescriptor(getDescriptor());
            this.readAllQuery.setReferenceClassName(getDescriptor().getJavaClassName());
            try {
                readAllQuery.setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }
        }
    }

    /**
     * ADVANCED:
     * Set the receiver's read SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the read arguments row,
     * through replacing the field names marked by '#' with the values for those fields.
     * Note that this is only used on readAllObjects(Class), and not when an expression is provided.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     * Example, "select * from EMPLOYEE"
     */
    public void setReadAllSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }

        ReadAllQuery query = new ReadAllQuery();
        query.setSQLString(sqlString);
        setReadAllQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's read all call.
     * This allows the user to override the read all operation.
     * Note that this is only used on readAllObjects(Class), and not when an expression is provided.
     */
    public void setReadAllCall(Call call) {
        if (call == null) {
            return;
        }
        ReadAllQuery query = new ReadAllQuery();
        query.setCall(call);
        setReadAllQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's read query.
     * This should be an instance of a valid subclass of ReadObjectQuery
     * If specified this is used by the descriptor to read itself from the database.
     * The read arguments must be the primary key of the object only.
     * This gives the user the ability to define exactly how to read the object from the database,
     * or access data external from the database or from some other framework.
     */
    public void setReadObjectQuery(ReadObjectQuery query) {
        this.readObjectQuery = query;
        if (query == null) {
            return;
        }
        this.readObjectQuery.setIsUserDefined(true);

        /* CR2260 - Steven Vo
         * Description:
         *  NullPointerException accessing null descriptor
         * Fix:
         *   Setting query's descriptor and reference class when descriptor is not null.
         *   Otherwise, wait until the descriptor is set.See populateQueries() that is
         *   called by setDescriptor()
         */
        if (this.getDescriptor() != null) {
            this.readObjectQuery.setDescriptor(getDescriptor());
            this.readObjectQuery.setReferenceClassName(getDescriptor().getJavaClassName());
            try {
                readObjectQuery.setReferenceClass(getDescriptor().getJavaClass());
            } catch (ConversionException exception) {
            }
        }
    }

    /**
     * ADVANCED:
     * Set the receiver's read SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with their own SQL or procedure call.
     * The arguments are translated from the fields of the read arguments row,
     * through replacing the field names marked by '#' with the values for those fields.
     * This must accept only the primary key of the object as arguments.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     * Example, "select * from EMPLOYEE where EMPLOYEE_ID = #EMPLOYEE_ID"
     */
    public void setReadObjectSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }

        ReadObjectQuery query = new ReadObjectQuery();
        query.setSQLString(sqlString);
        setReadObjectQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's read object call.
     * This allows the user to override the read object operation.
     * This must accept only the primary key of the object as arguments.
     */
    public void setReadObjectCall(Call call) {
        if (call == null) {
            return;
        }
        ReadObjectQuery query = new ReadObjectQuery();
        query.setCall(call);
        setReadObjectQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's update query.
     * This should be an instance of a valid subclass of UpdateObjectQuery.
     * If specified this is used by the descriptor to update itself in the database.
     * If the receiver uses optimistic locking this must raise an error on optimistic lock failure.
     * This gives the user the ability to define exactly how to update the data into the database,
     * or access data external from the database or from some other framework.
     */
    public void setUpdateQuery(UpdateObjectQuery updateQuery) {
        this.updateQuery = updateQuery;
        if (updateQuery == null) {
            return;
        }
        this.updateQuery.setIsUserDefined(true);
        this.updateQuery.setDescriptor(getDescriptor());
    }

    /**
     * ADVANCED:
     * Set the receiver's update SQL string.
     * This allows the user to override the SQL generated by EclipseLink, with there own SQL or procedure call.
     * The arguments are translated from the fields of the source row,
     * through replacing the field names marked by '#' with the values for those fields.
     * This must check the optimistic lock field and raise an error on optimistic lock failure.
     * Warning: Allowing an unverified SQL string to be passed into this
     * method makes your application vulnerable to SQL injection attacks.
     * <p>
     * Example, "update EMPLOYEE set F_NAME to #F_NAME, L_NAME to #L_NAME where EMPLOYEE_ID = #EMPLOYEE_ID".
     */
    public void setUpdateSQLString(String sqlString) {
        if (sqlString == null) {
            return;
        }

        UpdateObjectQuery query = new UpdateObjectQuery();
        query.setSQLString(sqlString);
        setUpdateQuery(query);
    }

    /**
     * ADVANCED:
     * Set the receiver's update call.
     * This allows the user to override the update operation.
     */
    public void setUpdateCall(Call call) {
        if (call == null) {
            return;
        }
        UpdateObjectQuery query = new UpdateObjectQuery();
        query.setCall(call);
        setUpdateQuery(query);
    }

    /**
     * PUBLIC:
     * Return the number of seconds queries will wait for their Statement to execute.
     *
     * - DefaultTimeout: get queryTimeout from parent DescriptorQueryManager. If there is no
     * parent, default to NoTimeout
     * - NoTimeout, 1..N: overrides parent queryTimeout
     */
    public int getQueryTimeout() {
        return queryTimeout;
    }

    public TimeUnit getQueryTimeoutUnit() {
        return queryTimeoutUnit;
    }

    /**
     * PUBLIC:
     * Set the number of seconds that queries will wait for their Statement to execute.
     * If the limit is exceeded, a DatabaseException is thrown.
     *
     * - DefaultTimeout: get queryTimeout from parent DescriptorQueryManager. If there is no
     * parent, default to NoTimeout
     * - NoTimeout, 1..N: overrides parent queryTimeout
     */
    public void setQueryTimeout(int queryTimeout) {
        this.queryTimeout = queryTimeout;
    }

    public void setQueryTimeoutUnit(TimeUnit queryTimeoutUnit) {
        this.queryTimeoutUnit = queryTimeoutUnit;
    }

    /**
     * INTERNAL:
     * Returns the collection of cached Update calls.
     */
    private ConcurrentFixedCache getCachedUpdateCalls() {
        if (cachedUpdateCalls == null) {
            this.cachedUpdateCalls = new ConcurrentFixedCache(10);
        }
        return this.cachedUpdateCalls;
    }

    /**
     * INTERNAL:
     * Returns the collection of cached expression queries.
     */
    private ConcurrentFixedCache getCachedExpressionQueries() {
        if (cachedExpressionQueries == null) {
            this.cachedExpressionQueries = new ConcurrentFixedCache(20);
        }
        return this.cachedExpressionQueries;
    }

    /**
     * ADVANCED:
     * Return the size of the update call cache.
     * The update call cache is used to cache the update SQL to avoid regeneration.
     * Since every update with different fields produces different SQL,
     * this cache allows caching of the update SQL based on the fields being updated.
     * The default cache size is 10, the update call cache can be disabled through setting the size to 0.
     */
    public int getUpdateCallCacheSize() {
        return getCachedUpdateCalls().getMaxSize();
    }

    /**
     * ADVANCED:
     * Set the size of the update call cache.
     * The update call cache is used to cache the update SQL to avoid regeneration.
     * Since every update with different fields produces different SQL,
     * this cache allows caching of the update SQL based on the fields being updated.
     * The default cache size is 10, the update call cache can be disabled through setting the size to 0.
     */
    public void setUpdateCallCacheSize(int updateCallCacheSize) {
        getCachedUpdateCalls().setMaxSize(updateCallCacheSize);
    }

    /**
     * INTERNAL:
     * Return the cached update SQL call based on the updated fields.
     * PERF: Allow caching of the update SQL call to avoid regeneration.
     */
    public Vector getCachedUpdateCalls(Vector updateFields) {
        return (Vector) getCachedUpdateCalls().get(updateFields);
    }

    /**
     * INTERNAL:
     * Cache a clone of the update SQL calls based on the updated fields.
     * If the max size is reached, do not cache the call.
     * The call's query must be dereferenced in order to allow the GC of a related session.
     * PERF: Allow caching of the update SQL call to avoid regeneration.
     */
    public void putCachedUpdateCalls(Vector updateFields, Vector updateCalls) {
        Vector vectorToCache = updateCalls;
        if (!updateCalls.isEmpty()) {
            int updateCallsSize = updateCalls.size();
            vectorToCache = new NonSynchronizedVector(updateCallsSize);
            for (int i = 0; i < updateCallsSize; i++) {
                DatasourceCall updateCall = (DatasourceCall)updateCalls.get(i);
                // clone call and dereference query for DatasourceCall and EJBQLCall
                DatasourceCall clonedUpdateCall = (DatasourceCall) updateCall.clone();
                clonedUpdateCall.setQuery(null);
                vectorToCache.add(clonedUpdateCall);
            }
        }
        getCachedUpdateCalls().put(updateFields, vectorToCache);
    }

    /**
     * INTERNAL:
     * Return the cached SQL call for the expression query.
     * PERF: Allow caching of expression query SQL call to avoid regeneration.
     */
    public DatabaseQuery getCachedExpressionQuery(DatabaseQuery query) {
        return (DatabaseQuery) getCachedExpressionQueries().get(query);
    }

    /**
     * INTERNAL:
     * Set the cached SQL call for the expression query.
     * PERF: Allow caching of expression query SQL call to avoid regeneration.
     */
    public void putCachedExpressionQuery(DatabaseQuery query) {
        getCachedExpressionQueries().put(query, query);
    }

    /**
     * INTERNAL:
     * Remove the cached expression query.
     * PERF: Allow caching of expression query SQL call to avoid regeneration.
     */
    public void removeCachedExpressionQuery(DatabaseQuery query) {
        getCachedExpressionQueries().remove(query);
    }

}
