/*
 * 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.
        Vector queriesByName = (Vector)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 = (DatabaseQuery)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 queriesForKey = ((Vector)iterator.next()).iterator();
            while (queriesForKey.hasNext()) {
                DatabaseQuery initialQuery = (DatabaseQuery)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 queries = ((Vector)queryVectors.next()).iterator();
            while (queries.hasNext()){
                ((DatabaseQuery)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 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) {
        Vector queries = (Vector)getQueries().get(name);

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

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

        // 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) {
        Vector queries = (Vector)getQueries().get(queryName);
        if (queries == null) {
            return;
        } else {
            DatabaseQuery query = null;
            for (Enumeration enumtr = queries.elements(); enumtr.hasMoreElements();) {
                query = (DatabaseQuery)enumtr.nextElement();
                if (Helper.areTypesAssignable(argumentTypes, query.getArgumentTypes())) {
                    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);
    }

}
