/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 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
//     07/16/2009-2.0 Guy Pelletier
//       - 277039: JPA 2.0 Cache Usage Settings
//     10/15/2010-2.2 Guy Pelletier
//       - 322008: Improve usability of additional criteria applied to queries at the session/EM
//     10/29/2010-2.2 Michael O'Brien
//       - 325167: Make reserved # bind parameter char generic to enable native SQL pass through
//     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.
//     06/30/2011-2.3.1 Guy Pelletier
//       - 341940: Add disable/enable allowing native queries
//     07/13/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     11/05/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     08/11/2012-2.5 Guy Pelletier
//       - 393867: Named queries do not work when using EM level Table Per Tenant Multitenancy.
//     08/11/2014-2.5 Rick Curtis
//       - 440594: Tolerate invalid NamedQuery at EntityManager creation.
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
package org.eclipse.persistence.queries;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.io.*;

import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.config.ParameterDelimiterType;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.expressions.*;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.sessions.remote.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.SessionProfiler;

/**
 * <p>
 * <b>Purpose</b>: Abstract class for all database query objects. DatabaseQuery
 * is a visible class to the EclipseLink user. Users create an appropriate query
 * by creating an instance of a concrete subclasses of DatabaseQuery.
 *
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li>Provide a common protocol for query objects.
 * <li>Defines a generic execution interface.
 * <li>Provides query property values
 * <li>Holds arguments to the query
 * </ul>
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public abstract class DatabaseQuery implements Cloneable, Serializable {
    /** INTERNAL: Property used for batch fetching in non object queries. */
    public static final String BATCH_FETCH_PROPERTY = "BATCH_FETCH_PROPERTY";

    /**
     * Queries can be given a name and registered with a descriptor to allow
     * common queries to be reused.
     */
    protected String name;

    /**
     * Arguments can be given and specified to predefined queries to allow
     * reuse.
     */
    protected List<String> arguments;

    /**
     * PERF: Argument fields are cached in prepare to avoid rebuilding on each
     * execution.
     */
    protected List<DatabaseField> argumentFields;

    /**
     * Arguments values can be given and specified to predefined queries to
     * allow reuse.
     */
    protected List<Object> argumentValues;

    /** Needed to differentiate queries with the same name. */
    protected List<Class> argumentTypes;

    /** Used to build a list of argumentTypes by name pre-initialization */
    protected List<String> argumentTypeNames;

    /** Used for parameter retreival in JPQL **/
    public enum ParameterType {POSITIONAL, NAMED}

    protected List<ParameterType> argumentParameterTypes;

    /** The descriptor cached on the prepare for object level queries. */
    protected transient ClassDescriptor descriptor;

    /** The list of descriptors this query deals with. Set via JPA processing for table per tenant queries */
    protected List<ClassDescriptor> descriptors;

    /**
     * The query mechanism determines the mechanism on how the database will be
     * accessed.
     */
    protected DatabaseQueryMechanism queryMechanism;

    /**
     * A redirector allows for a queries execution to be the execution of a
     * piece of code.
     */
    protected QueryRedirector redirector;

    /**
     * Can be set to true in the case there is a redirector or a default
     * redirector but the user does not want the query redirected.
     */
    protected boolean doNotRedirect = false;

    /** Flag used for a query to bypass the identitymap and unit of work. */

    // Bug#3476483 - Restore shouldMaintainCache to previous state after reverse
    // of bug fix 3240668
    protected boolean shouldMaintainCache;

    /** JPA flags to control the shared cache */
    protected boolean shouldRetrieveBypassCache = false;
    protected boolean shouldStoreBypassCache = false;

    /**
     * Property used to override a persistence unit level that disallows native
     * SQL queries.
     * @see org.eclipse.persistence.sessions.Project#setAllowNativeSQLQueries(boolean) Project.setAllowNativeSQLQueries(boolean)
     */
    protected Boolean allowNativeSQLQuery;

    /** Internally used by the mappings as a temporary store. */
    protected Map<Object, Object> properties;

    /**
     * Only used after the query is cloned for execution to store the session
     * under which the query was executed.
     */
    protected transient AbstractSession session;

    /**
     * Only used after the query is cloned for execution to store the execution
     * session under which the query was executed.
     */
    protected transient AbstractSession executionSession;

    /**
     * Connection to use for database access, required for server session
     * connection pooling.
     * There can be multiple connections with partitioning and replication.
     */
    protected transient Collection<Accessor> accessors;

    /**
     * Mappings and the descriptor use parameterized mechanisms that will be
     * translated with the data from the row.
     */
    protected AbstractRecord translationRow;

    /**
     * Internal flag used to bypass user define queries when executing one for
     * custom sql/query support.
     */
    protected boolean isUserDefined;

    /**
     * Internal flag used to bypass user define queries when executing one for
     * custom sql/query support.
     */
    protected boolean isUserDefinedSQLCall;

    /** Policy that determines how the query will cascade to its object's parts. */
    protected int cascadePolicy;

    /** Used to override the default session in the session broker. */
    protected String sessionName;

    /** Queries prepare common stated in themselves. */
    protected boolean isPrepared;

    /** Used to indicate whether or not the call needs to be cloned. */
    protected boolean shouldCloneCall;

    /**
     * Allow for the prepare of queries to be turned off, this allow for dynamic
     * non-pre SQL generated queries.
     */
    protected boolean shouldPrepare;

    /**
     * List of arguments to check for null.
     * If any are null, the query needs to be re-prepared.
     */
    protected List<DatabaseField> nullableArguments;

    /** Bind all arguments to the SQL statement. */

    // Has False, Undefined or True value. In case of Undefined -
    // Session's shouldBindAllParameters() defines whether to bind or not.
    protected Boolean shouldBindAllParameters;

    /**
     * Cache the prepared statement, this requires full parameter binding as
     * well.
     */

    // Has False, Undefined or True value. In case of Undefined -
    // Session's shouldCacheAllStatements() defines whether to cache or not.
    protected Boolean shouldCacheStatement;

    /** Use the WrapperPolicy for the objects returned by the query */
    protected boolean shouldUseWrapperPolicy;

    /**
     * Table per class requires multiple query executions. Internally we prepare
     * those queries and cache them against the source mapping's selection
     * query. When queries are executed they are cloned so we need a mechanism
     * to keep a reference back to the actual selection query so that we can
     * successfully look up and chain query executions within a table per class
     * inheritance hierarchy.
     */
    protected DatabaseMapping sourceMapping;

    /**
     * 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
     */
    protected int queryTimeout;

    protected TimeUnit queryTimeoutUnit;

    /* Used as default for read, means shallow write for modify. */
    public static final int NoCascading = 1;

    /*
     * Used as default for write, used for refreshing to refresh the whole
     * object.
     */
    public static final int CascadePrivateParts = 2;

    /*
     * Currently not supported, used for deep write/refreshes/reads in the
     * future.
     */
    public static final int CascadeAllParts = 3;

    /* Used by the unit of work. */
    public static final int CascadeDependentParts = 4;

    /*
     * Used by aggregate Collections: As aggregates delete at update time,
     * cascaded deletes must know to stop when entering postDelete for a
     * particular mapping. Only used by the aggregate collection when update is
     * occurring in a UnitOfWork CR 2811
     */
    public static final int CascadeAggregateDelete = 5;

    /*
     * Used when refreshing should check the mappings to determine if a
     * particular mapping should be cascaded.
     */
    public static final int CascadeByMapping = 6;

    /** Used for adding hints to the query string in oracle */
    protected String hintString;

    /*
     * Stores the FlushMode of this Query. This is only applicable when executed
     * in a flushable UnitOfWork and will be ignored otherwise.
     */
    protected Boolean flushOnExecute;

    /**
     * PERF: Determines if the query has already been cloned for execution, to
     * avoid duplicate cloning.
     */
    protected boolean isExecutionClone;

    /** PERF: Store if this query will use the descriptor custom query. */
    protected volatile Boolean isCustomQueryUsed;

    /** Allow connection unwrapping to be configured. */
    protected boolean isNativeConnectionRequired;

    /**
     * Return the name to use for the query in performance monitoring.
     */
    protected transient String monitorName;

    /** Allow additional validation to be performed before using the update call cache */
    protected boolean shouldValidateUpdateCallCacheUse;

    /** Allow queries to be targeted at specific connection pools. */
    protected PartitioningPolicy partitioningPolicy;


    /** Allow the reserved pound char used to delimit bind parameters to be overridden */
    protected String parameterDelimiter;

    /**
     * PUBLIC: Initialize the state of the query
     */
    protected DatabaseQuery() {
        this.shouldMaintainCache = true;
        // bug 3524620: lazy-init query mechanism
        // this.queryMechanism = new ExpressionQueryMechanism(this);
        this.isUserDefined = false;
        this.cascadePolicy = NoCascading;
        this.isPrepared = false;
        this.shouldUseWrapperPolicy = true;
        this.queryTimeout = DescriptorQueryManager.DefaultTimeout;
        this.queryTimeoutUnit = DescriptorQueryManager.DefaultTimeoutUnit;
        this.shouldPrepare = true;
        this.shouldCloneCall = false;
        this.shouldBindAllParameters = null;
        this.shouldCacheStatement = null;
        this.isExecutionClone = false;
        this.shouldValidateUpdateCallCacheUse = false;
        this.parameterDelimiter = ParameterDelimiterType.DEFAULT;
    }

    /**
     * PUBLIC:
     * Return the query's partitioning policy.
     */
    public PartitioningPolicy getPartitioningPolicy() {
        return partitioningPolicy;
    }

    /**
     * PUBLIC:
     * Set the query's partitioning policy.
     * A PartitioningPolicy is used to partition, load-balance or replicate data across multiple difference databases
     * or across a database cluster such as Oracle RAC.
     * Partitioning can provide improved scalability by allowing multiple database machines to service requests.
     * Setting a policy on a query will override the descriptor and session defaults.
     */
    public void setPartitioningPolicy(PartitioningPolicy partitioningPolicy) {
        this.partitioningPolicy = partitioningPolicy;
    }

    /**
     * INTERNAL:
     * Return the name to use for the query in performance monitoring.
     */
    public String getMonitorName() {
        if (monitorName == null) {
            resetMonitorName();
        }
        return monitorName;
    }

    /**
     * INTERNAL:
     * Return the name to use for the query in performance monitoring.
     */
    public void resetMonitorName() {
        if (getReferenceClassName() == null) {
            this.monitorName = getClass().getSimpleName() + ":" + getName();
        } else {
            this.monitorName = getClass().getSimpleName() + ":" + getReferenceClassName() + ":" + getName();
        }
    }

    /**
     * PUBLIC: Add the argument named argumentName. This will cause the
     * translation of references of argumentName in the receiver's expression,
     * with the value of the argument as supplied to the query in order from
     * executeQuery()
     */
    public void addArgument(String argumentName) {
        addArgument(argumentName, Object.class);
    }

    /**
     * PUBLIC: Add the argument named argumentName and its class type. This will
     * cause the translation of references of argumentName in the receiver's
     * expression, with the value of the argument as supplied to the query in
     * order from executeQuery(). Specifying the class type is important if
     * identically named queries are used but with different argument lists.
     */
    public void addArgument(String argumentName, Class type) {
        addArgument(argumentName, type, false);
    }

    /**
     * INTERNAL: Add the argument named argumentName.  This method was added to maintain
     * information about whether parameters are positional or named for JPQL query introspeciton
     * API
     */
    public void addArgument(String argumentName, Class type, ParameterType parameterType) {
        addArgument(argumentName, type, parameterType, false);
    }

    /**
     * PUBLIC: Add the argument named argumentName and its class type. This will
     * cause the translation of references of argumentName in the receiver's
     * expression, with the value of the argument as supplied to the query in
     * order from executeQuery(). Specifying the class type is important if
     * identically named queries are used but with different argument lists.
     * If the argument can be null, and null must be treated differently in the
     * generated SQL, then nullable should be set to true.
     */
    public void addArgument(String argumentName, Class type, boolean nullable) {
        getArguments().add(argumentName);
        getArgumentTypes().add(type);
        if(type != null) {
            getArgumentTypeNames().add(type.getName());
        }
        if (nullable) {
            getNullableArguments().add(new DatabaseField(argumentName));
        }
    }

    /**
     * INTERNAL: Add the argument named argumentName.  This method was added to maintain
     * information about whether parameters are positional or named for JPQL query introspeciton
     * API
     */
    public void addArgument(String argumentName, Class type, ParameterType argumentParameterType, boolean nullable) {
        addArgument(argumentName, type, nullable);
        getArgumentParameterTypes().add(argumentParameterType);
    }

    /**
     * PUBLIC: Add the argument named argumentName and its class type. This will
     * cause the translation of references of argumentName in the receiver's
     * expression, with the value of the argument as supplied to the query in
     * order from executeQuery(). Specifying the class type is important if
     * identically named queries are used but with different argument lists.
     */
    public void addArgument(String argumentName, String typeAsString) {
        getArguments().add(argumentName);
        // bug 3197587
        getArgumentTypes().add(Helper.getObjectClass(ConversionManager.loadClass(typeAsString)));
        getArgumentTypeNames().add(typeAsString);
    }

    /**
     * INTERNAL: Add an argument to the query, but do not resolve the class yet.
     * This is useful for building a query without putting the domain classes on
     * the classpath for the Mapping Workbench.
     */
    public void addArgumentByTypeName(String argumentName, String typeAsString) {
        getArguments().add(argumentName);
        getArgumentTypeNames().add(typeAsString);
    }

    /**
     * PUBLIC: Add the argumentValue. Argument values must be added in the same
     * order the arguments are defined.
     */
    public void addArgumentValue(Object argumentValue) {
        getArgumentValues().add(argumentValue);
    }

    /**
     * PUBLIC: Add the argumentValues to the query. Argument values must be
     * added in the same order the arguments are defined.
     */
    public void addArgumentValues(List theArgumentValues) {
        getArgumentValues().addAll(theArgumentValues);
    }

    /**
     * PUBLIC: Used to define a store procedure or SQL query. This may be used
     * for multiple SQL executions to be mapped to a single query. This cannot
     * be used for cursored selects, delete alls or does exists.
     */
    public void addCall(Call call) {
        setQueryMechanism(call.buildQueryMechanism(this, getQueryMechanism()));
        // Must un-prepare is prepare as the SQL may change.
        setIsPrepared(false);
    }

    /**
     * PUBLIC: Used to define a statement level query. This may be used for
     * multiple SQL executions to be mapped to a single query. This cannot be
     * used for cursored selects, delete all(s) or does exists.
     */
    public void addStatement(SQLStatement statement) {
        // bug 3524620: lazy-init query mechanism
        if (!hasQueryMechanism()) {
            setQueryMechanism(new StatementQueryMechanism(this));
        } else if (!getQueryMechanism().isStatementQueryMechanism()) {
            setQueryMechanism(new StatementQueryMechanism(this));
        }
        ((StatementQueryMechanism) getQueryMechanism()).getSQLStatements().addElement(statement);
        // Must un-prepare is prepare as the SQL may change.
        setIsPrepared(false);
    }

    /**
     * PUBLIC: Bind all arguments to any SQL statement.
     */
    public void bindAllParameters() {
        setShouldBindAllParameters(true);
    }

    /**
     * INTERNAL: In the case of EJBQL, an expression needs to be generated.
     * Build the required expression.
     */
    protected void buildSelectionCriteria(AbstractSession session) {
        this.getQueryMechanism().buildSelectionCriteria(session);
    }

    /**
     * PUBLIC: Cache the prepared statements, this requires full parameter
     * binding as well.
     */
    public void cacheStatement() {
        setShouldCacheStatement(true);
    }

    /**
     * PUBLIC: Cascade the query and its properties on the queries object(s) and
     * all objects related to the queries object(s). This includes private and
     * independent relationships, but not read-only relationships. This will
     * still stop on uninstantiated indirection objects except for deletion.
     * Great caution should be used in using the property as the query may
     * effect a large number of objects. This policy is used by the unit of work
     * to ensure persistence by reachability.
     */
    public void cascadeAllParts() {
        setCascadePolicy(CascadeAllParts);
    }

    /**
     * PUBLIC: Cascade the query and its properties on the queries object(s) and
     * all related objects where the mapping has been set to cascade the merge.
     */
    public void cascadeByMapping() {
        setCascadePolicy(CascadeByMapping);
    }

    /**
     * INTERNAL: Used by unit of work, only cascades constraint dependencies.
     */
    public void cascadeOnlyDependentParts() {
        setCascadePolicy(CascadeDependentParts);
    }

    /**
     * PUBLIC: Cascade the query and its properties on the queries object(s) and
     * all privately owned objects related to the queries object(s). This is the
     * default for write and delete queries. This policy should normally be used
     * for refreshing, otherwise you could refresh half of any object.
     */
    public void cascadePrivateParts() {
        setCascadePolicy(CascadePrivateParts);
    }

    /**
     * INTERNAL: Ensure that the descriptor has been set.
     */
    public void checkDescriptor(AbstractSession session) throws QueryException {
    }

    /**
     * INTERNAL: Check to see if this query already knows the return value
     * without performing any further work.
     */
    public Object checkEarlyReturn(AbstractSession session, AbstractRecord translationRow) {
        return null;
    }

    /**
     * INTERNAL: Check to see if a custom query should be used for this query.
     * This is done before the query is copied and prepared/executed. null means
     * there is none.
     */
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
        return null;
    }

    /**
     * INTERNAL: Check to see if this query needs to be prepare and prepare it.
     * The prepare is done on the original query to ensure that the work is not
     * repeated.
     */
    public void checkPrepare(AbstractSession session, AbstractRecord translationRow) {
        this.checkPrepare(session, translationRow, false);
    }

    /**
     * INTERNAL: Call the prepare on the query.
     */
    public void prepareInternal(AbstractSession session) {
        setSession(session);
        try {
            prepare();
        } finally {
            setSession(null);
        }
    }

    /**
     * INTERNAL: Check to see if this query needs to be prepare and prepare it.
     * The prepare is done on the original query to ensure that the work is not
     * repeated.
     */
    public void checkPrepare(AbstractSession session, AbstractRecord translationRow, boolean force) {
        try {
            // This query is first prepared for global common state, this must be synced.
            if (!this.isPrepared) {// Avoid the monitor is already prepare, must
                // If this query will use the custom query, do not prepare.
                if ((!force) && (!this.shouldPrepare || !((DatasourcePlatform)session.getDatasourcePlatform()).shouldPrepare(this)
                        || (checkForCustomQuery(session, translationRow) != null))) {
                    return;
                }
                // check again for concurrency.
                // Profile the query preparation time.
                session.startOperationProfile(SessionProfiler.QueryPreparation, this, SessionProfiler.ALL);
                // Prepared queries cannot be custom as then they would never have
                // been prepared.
                synchronized (this) {
                    if (!isPrepared()) {
                        // When custom SQL is used there is a possibility that the
                        // SQL contains the # token (for stored procedures or temporary tables).
                        // Avoid this by telling the call if this is custom SQL with parameters.
                        // This must not be called for SDK calls.
                        if ((isReadQuery() || isDataModifyQuery()) && isCallQuery() && (getQueryMechanism() instanceof CallQueryMechanism)
                                && ((translationRow == null) || (translationRow.isEmpty() && !translationRow.hasSopObject()))) {
                            // Must check for read object queries as the row will be
                            // empty until the prepare.
                            if (isReadObjectQuery() || isUserDefined()) {
                                ((CallQueryMechanism) getQueryMechanism()).setCallHasCustomSQLArguments();
                            }
                        } else if (isCallQuery() && (getQueryMechanism() instanceof CallQueryMechanism)) {
                            ((CallQueryMechanism) getQueryMechanism()).setCallHasCustomSQLArguments();
                        }
                        setSession(session);// Session is required for some init stuff.
                        prepare();
                        setSession(null);
                        setIsPrepared(true);// MUST not set prepare until done as
                        // other thread may hit before finishing the prepare.
                    }
                }
                // Profile the query preparation time.
                session.endOperationProfile(SessionProfiler.QueryPreparation, this, SessionProfiler.ALL);
            }
        } catch (QueryException knownFailure) {
            // Set the query, as prepare can be called directly.
            if (knownFailure.getQuery() == null) {
                knownFailure.setQuery(this);
                knownFailure.setSession(session);
            }
            throw knownFailure;
        } catch (EclipseLinkException knownFailure) {
            throw knownFailure;
        } catch (RuntimeException unexpectedFailure) {
            throw QueryException.prepareFailed(unexpectedFailure, this);
        }
    }

    /**
     * INTERNAL: Clone the query
     */
    @Override
    public Object clone() {
        try {
            DatabaseQuery cloneQuery = (DatabaseQuery) super.clone();

            // partial fix for 3054240
            // need to pay attention to other components of the query, too MWN
            if (cloneQuery.properties != null) {
                if (cloneQuery.properties.isEmpty()) {
                    cloneQuery.properties = null;
                } else {
                    cloneQuery.properties = new HashMap(this.properties);
                }
            }

            // bug 3524620: now that the query mechanism is lazy-init'd,
            // only clone the query mechanism if we have one.
            if (this.queryMechanism != null) {
                cloneQuery.queryMechanism = this.queryMechanism.clone(cloneQuery);
            }
            cloneQuery.isPrepared = this.isPrepared; // Setting some things may trigger unprepare.
            return cloneQuery;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    /**
     * INTERNAL Used to give the subclasses opportunity to copy aspects of the
     * cloned query to the original query.
     */
    protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
        // no-op for this class
    }

    /**
     * INTERNAL: Convert all the class-name-based settings in this query to
     * actual class-based settings This method is implemented by subclasses as
     * necessary.
     *
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        // note: normally we would fix the argument types here, but they are
        // already
        // lazily instantiated
    }

    /**
     * PUBLIC: Do not Bind all arguments to any SQL statement.
     */
    public void dontBindAllParameters() {
        setShouldBindAllParameters(false);
    }

    /**
     * PUBLIC: Don't cache the prepared statements, this requires full parameter
     * binding as well.
     */
    public void dontCacheStatement() {
        setShouldCacheStatement(false);
    }

    /**
     * PUBLIC: Do not cascade the query and its properties on the queries
     * object(s) relationships. This does not effect the queries private parts
     * but only the object(s) direct row-level attributes. This is the default
     * for read queries and can be used in writing if it is known that only
     * row-level attributes changed, or to resolve circular foreign key
     * dependencies.
     */
    public void dontCascadeParts() {
        setCascadePolicy(NoCascading);
    }

    /**
     * PUBLIC: Set for the identity map (cache) to be ignored completely. The
     * cache check will be skipped and the result will not be put into the
     * identity map. This can be used to retrieve the exact state of an object
     * on the database. By default the identity map is always maintained.
     */
    public void dontMaintainCache() {
        setShouldMaintainCache(false);
    }

    /**
     * INTERNAL: Execute the query
     *
     * @exception DatabaseException
     *                - an error has occurred on the database.
     * @exception OptimisticLockException
     *                - an error has occurred using the optimistic lock feature.
     * @return - the result of executing the query.
     */
    public abstract Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException;

    /**
     * INTERNAL: Override query execution where Session is a UnitOfWork.
     * <p>
     * If there are objects in the cache return the results of the cache lookup.
     *
     * @param unitOfWork
     *            - the session in which the receiver will be executed.
     * @param translationRow
     *            - the arguments
     * @exception DatabaseException
     *                - an error has occurred on the database.
     * @exception OptimisticLockException
     *                - an error has occurred using the optimistic lock feature.
     * @return An object, the result of executing the query.
     */
    public Object executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
        return execute(unitOfWork, translationRow);
    }

    /**
     * INTERNAL: Execute the query. If there are objects in the cache return the
     * results of the cache lookup.
     *
     * @param session
     *            - the session in which the receiver will be executed.
     * @exception DatabaseException
     *                - an error has occurred on the database.
     * @exception OptimisticLockException
     *                - an error has occurred using the optimistic lock feature.
     * @return An object, the result of executing the query.
     */
    public Object execute(AbstractSession session, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
        DatabaseQuery queryToExecute = this;
        // JPQL call may not have defined the reference class yet, so need to use prepare.
        if (isJPQLCallQuery() && isObjectLevelReadQuery()) {
            ((ObjectLevelReadQuery)this).checkPrePrepare(session);
        } else {
            checkDescriptor(session);
        }
        QueryRedirector localRedirector = getRedirectorForQuery();
        // refactored redirection for bug 3241138
        if (localRedirector != null) {
            return redirectQuery(localRedirector, queryToExecute, session, translationRow);
        }

        // Bug 5529564 - If this is a user defined selection query (custom SQL),
        // prepare the query before hand so that we may look up the correct fk
        // values from the query parameters when checking early return.
        if (queryToExecute.isCustomSelectionQuery() && queryToExecute.shouldPrepare()) {
            queryToExecute.checkPrepare(session, translationRow);
        }

        // This allows the query to check the cache or return early without
        // doing any work.
        Object earlyReturn = queryToExecute.checkEarlyReturn(session, translationRow);
        // If know not to exist (checkCacheOnly, deleted, null primary key),
        // return null.
        if (earlyReturn == InvalidObject.instance) {
            return null;
        }
        if (earlyReturn != null) {
            return earlyReturn;
        }

        boolean hasCustomQuery = false;
        if (!isPrepared() && shouldPrepare()) {
            // Prepared queries cannot be custom as then they would never have
            // been prepared.
            DatabaseQuery customQuery = checkForCustomQuery(session, translationRow);
            if (customQuery != null) {
                hasCustomQuery = true;
                // The custom query will be used not the original.
                queryToExecute = customQuery;
            }
        }

        // PERF: Queries need to be cloned for execution as they may be
        // concurrently reused, and execution specific state is stored in the
        // clone.
        // In some case the query is known to be a one off, or cloned elsewhere
        // so the query keeps track if it has been cloned already.
        queryToExecute = session.prepareDatabaseQuery(queryToExecute);

        boolean prepare = queryToExecute.shouldPrepare(translationRow, session);
        if (prepare) {
            queryToExecute.checkPrepare(session, translationRow);
        }

        // Then cloned for concurrency and repeatable execution.
        if (!queryToExecute.isExecutionClone()) {
            queryToExecute = (DatabaseQuery) queryToExecute.clone();
        }
        // Check for query argument values.
        if ((this.argumentValues != null) && (!this.argumentValues.isEmpty()) && translationRow.isEmpty()) {
            translationRow = rowFromArguments(this.argumentValues, session);
        }
        queryToExecute.setTranslationRow(translationRow);

        // If the prepare has been disable the clone is prepare dynamically to
        // not parameterize the SQL.
        if (!prepare) {
            queryToExecute.setIsPrepared(false);
            queryToExecute.setTranslationRow(translationRow);
            queryToExecute.checkPrepare(session, translationRow, true);
        }
        queryToExecute.setSession(session);
        if (hasCustomQuery) {
            prepareCustomQuery(queryToExecute);
            localRedirector = queryToExecute.getRedirector();
            // refactored redirection for bug 3241138
            if (localRedirector != null) {
                return redirectQuery(localRedirector, queryToExecute, session, queryToExecute.getTranslationRow());
            }
        }
        queryToExecute.prepareForExecution();

        // Then executed.
        Object result = queryToExecute.executeDatabaseQuery();

        // Give the subclasses the opportunity to retrieve aspects of the cloned
        // query.
        clonedQueryExecutionComplete(queryToExecute, session);
        return result;
    }

    /**
     * INTERNAL: Extract the correct query result from the transporter.
     */
    public Object extractRemoteResult(Transporter transporter) {
        return transporter.getObject();
    }

    /**
     * INTERNAL: Return the accessor.
     */
    public Accessor getAccessor() {
        if ((this.accessors == null) || (this.accessors.size() == 0)) {
            return null;
        }
        if (this.accessors instanceof List) {
            return ((List<Accessor>)this.accessors).get(0);
        }
        return this.accessors.iterator().next();
    }

    /**
     * INTERNAL: Return the accessors.
     */
    public Collection<Accessor> getAccessors() {
        return this.accessors;
    }

    /**
     * INTERNAL: Return the arguments for use with the pre-defined query option
     */
    public List<String> getArguments() {
        if (this.arguments == null) {
            this.arguments = new ArrayList<>();
        }
        return this.arguments;
    }

    /**
     * INTERNAL:
     * Used to calculate parameter types in JPQL
     */
    public List<ParameterType> getArgumentParameterTypes(){
        if (argumentParameterTypes == null){
            this.argumentParameterTypes = new ArrayList<>();
        }
        return this.argumentParameterTypes;
    }

    /**
     * INTERNAL: Return the argumentTypes for use with the pre-defined query
     * option
     */
    public List<Class> getArgumentTypes() {
        if ((this.argumentTypes == null) || (this.argumentTypes.isEmpty() && (this.argumentTypeNames != null) && !this.argumentTypeNames.isEmpty())) {
            this.argumentTypes = new ArrayList<>();
            // Bug 3256198 - lazily initialize the argument types from their
            // class names
            if (this.argumentTypeNames != null) {
                Iterator<String> args = this.argumentTypeNames.iterator();
                while (args.hasNext()) {
                    String argumentTypeName = args.next();
                    this.argumentTypes.add(Helper.getObjectClass(ConversionManager.loadClass(argumentTypeName)));
                }
            }
        }
        return this.argumentTypes;
    }

    /**
     * INTERNAL: Return the argumentTypeNames for use with the pre-defined query
     * option These are used pre-initialization to construct the argumentTypes
     * list.
     */
    public List<String> getArgumentTypeNames() {
        if (argumentTypeNames == null) {
            argumentTypeNames = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
        }
        return argumentTypeNames;
    }

    /**
     * INTERNAL: Set the argumentTypes for use with the pre-defined query option
     */
    public void setArgumentTypes(List<Class> argumentTypes) {
        this.argumentTypes = argumentTypes;
        // bug 3256198 - ensure the list of type names matches the argument
        // types.
        getArgumentTypeNames().clear();
        for (Class type : argumentTypes) {
            this.argumentTypeNames.add(type.getName());
        }
    }

    /**
     * INTERNAL: Set the argumentTypes for use with the pre-defined query option
     */
    public void setArgumentTypeNames(List<String> argumentTypeNames) {
        this.argumentTypeNames = argumentTypeNames;
    }

    /**
     * INTERNAL: Set the arguments for use with the pre-defined query option.
     * Maintain the argumentTypes as well.
     */
    public void setArguments(List<String> arguments) {
        List<Class> types = new ArrayList<>(arguments.size());
        List<String> typeNames = new ArrayList<>(arguments.size());
        List<DatabaseField> typeFields = new ArrayList<>(arguments.size());
        int size = arguments.size();
        for (int index = 0; index < size; index++) {
            types.add(Object.class);
            typeNames.add("java.lang.Object");
            DatabaseField field = new DatabaseField(arguments.get(index));
            typeFields.add(field);
        }
        this.arguments = arguments;
        this.argumentTypes = types;
        this.argumentTypeNames = typeNames;
        this.argumentFields = typeFields;
    }

    /**
     * INTERNAL: Return the argumentValues for use with argumented queries.
     */
    public List<Object> getArgumentValues() {
        if (this.argumentValues == null) {
            this.argumentValues = new ArrayList<>();
        }
        return this.argumentValues;
    }

    /**
     * INTERNAL: Set the argumentValues for use with argumented queries.
     */
    public void setArgumentValues(List<Object> theArgumentValues) {
        this.argumentValues = theArgumentValues;
    }

    /**
     * OBSOLETE: Return the call for this query. This call contains the SQL and
     * argument list.
     *
     * @see #getDatasourceCall()
     */
    public DatabaseCall getCall() {
        Call call = getDatasourceCall();
        if (call instanceof DatabaseCall) {
            return (DatabaseCall) call;
        } else {
            return null;
        }
    }

    /**
     * ADVANCED: Return the call for this query. This call contains the SQL and
     * argument list.
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, org.eclipse.persistence.sessions.Record) prepareCall(Session, Record)
     */
    public Call getDatasourceCall() {
        Call call = null;
        if (this.queryMechanism instanceof DatasourceCallQueryMechanism) {
            DatasourceCallQueryMechanism mechanism = (DatasourceCallQueryMechanism) this.queryMechanism;
            call = mechanism.getCall();
            // If has multiple calls return the first one.
            if ((call == null) && mechanism.hasMultipleCalls()) {
                call = (Call) mechanism.getCalls().get(0);
            }
        }
        if ((call == null) && (this.queryMechanism != null) && this.queryMechanism.isJPQLCallQueryMechanism()) {
            call = ((JPQLCallQueryMechanism) this.queryMechanism).getJPQLCall();
        }
        return call;
    }

    /**
     * ADVANCED: Return the calls for this query. This method can be called for
     * queries with multiple calls This call contains the SQL and argument list.
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, org.eclipse.persistence.sessions.Record) prepareCall(Session, Record)
     */
    public List getDatasourceCalls() {
        List calls = new Vector();
        if (getQueryMechanism() instanceof DatasourceCallQueryMechanism) {
            DatasourceCallQueryMechanism mechanism = (DatasourceCallQueryMechanism) getQueryMechanism();

            // If has multiple calls return the first one.
            if (mechanism.hasMultipleCalls()) {
                calls = mechanism.getCalls();
            } else {
                calls.add(mechanism.getCall());
            }
        }
        if ((calls.isEmpty()) && getQueryMechanism().isJPQLCallQueryMechanism()) {
            calls.add(((JPQLCallQueryMechanism) getQueryMechanism()).getJPQLCall());
        }
        return calls;
    }

    /**
     * INTERNAL: Return the cascade policy.
     */
    public int getCascadePolicy() {
        return cascadePolicy;
    }

    /**
     * INTERNAL: Return the descriptor assigned with the reference class
     */
    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * INTERNAL:
     * This is here only for JPA queries and currently only populated for JPA
     * queries. JPAQuery is a jpa class and currently not part of the core.
     */
    public List<ClassDescriptor> getDescriptors() {
        return null;
    }

    /**
     * INTERNAL:
     * TopLink_sessionName_domainClass.  Cached in properties
     */
     public String getDomainClassNounName(String sessionName) {
        if (getProperty("DMSDomainClassNounName") == null) {
            StringBuilder buffer = new StringBuilder("EclipseLink");
            if (sessionName != null) {
                buffer.append(sessionName);
            }
            if (getReferenceClassName() != null) {
                buffer.append("_");
                buffer.append(getReferenceClassName());
            }
            setProperty("DMSDomainClassNounName", buffer.toString());
        }
        return (String)getProperty("DMSDomainClassNounName");
     }

    /**
     * PUBLIC: Return the name of the query
     */
    public String getName() {
        return name;
    }

    /**
     * INTERNAL:
     * Return the String used to delimit an SQL parameter.
     */
    public String getParameterDelimiter() {
        if(null == parameterDelimiter || parameterDelimiter.length() == 0) {
            parameterDelimiter = ParameterDelimiterType.DEFAULT;
        }
        return parameterDelimiter;
    }

    /**
     * INTERNAL:
     * Return the char used to delimit an SQL parameter.
     */
    public char getParameterDelimiterChar() {
        return getParameterDelimiter().charAt(0);
    }

    /**
     * INTERNAL: Property support for use by mappings.
     */
    public Map<Object, Object> getProperties() {
        if (this.properties == null) {
            // Lazy initialize to conserve space and allocation time.
            this.properties = new HashMap();
        }
        return this.properties;
    }

    /**
     * INTERNAL: Property support used by mappings to store temporary stuff in
     * the query.
     */
    public synchronized Object getProperty(Object property) {
        if (this.properties == null) {
            return null;
        }
        return this.properties.get(property);
    }

    /**
     * INTERNAL:
     * TopLink_sessionName_domainClass_queryClass_queryName (if exist).  Cached in properties
     */
    public String getQueryNounName(String sessionName) {
        if (getProperty("DMSQueryNounName") == null) {
            StringBuilder buffer = new StringBuilder(getDomainClassNounName(sessionName));
            buffer.append("_");
            buffer.append(getClass().getSimpleName());
            if (getName() != null) {
                buffer.append("_");
                buffer.append(getName());
            }
            setProperty("DMSQueryNounName", buffer.toString());
        }
        return (String)getProperty("DMSQueryNounName");
    }

    /**
     * INTERNAL: Return the mechanism assigned to the query
     */
    public DatabaseQueryMechanism getQueryMechanism() {
        // Bug 3524620 - lazy init
        if (this.queryMechanism == null) {
            this.queryMechanism = new ExpressionQueryMechanism(this);
        }
        return this.queryMechanism;
    }

    /**
     * INTERNAL: Check if the mechanism has been set yet, used for lazy init.
     */
    public boolean hasQueryMechanism() {
        return (this.queryMechanism != null);
    }

    /**
     * PUBLIC: Return the number of seconds the driver will wait for a Statement
     * to execute to the given number of seconds.
     *
     * @see DescriptorQueryManager#getQueryTimeout()
     */
    public int getQueryTimeout() {
        return queryTimeout;
    }

    /**
     * PUBLIC: Return the unit of time the driver will wait for a Statement to
     * execute.
     * 
     * @see DescriptorQueryManager#getQueryTimeoutUnit()
     */
    public TimeUnit getQueryTimeoutUnit() {
        return queryTimeoutUnit;
    }

    /**
     * INTERNAL: Returns the specific default redirector for this query type.
     * There are numerous default query redirectors. See ClassDescriptor for
     * their types.
     */
    protected QueryRedirector getDefaultRedirector() {
        return this.descriptor.getDefaultQueryRedirector();
    }

    /**
     * PUBLIC: Return the query redirector. A redirector can be used in a query
     * to replace its execution with the execution of code. This can be used for
     * named or parameterized queries to allow dynamic configuration of the
     * query base on the query arguments.
     *
     * @see QueryRedirector
     */
    public QueryRedirector getRedirectorForQuery() {
        if (doNotRedirect) {
            return null;
        }
        if (redirector != null) {
            return redirector;
        }
        if (descriptor != null) {
            return getDefaultRedirector();
        }
        return null;
    }

    /**
     * PUBLIC: Return the query redirector. A redirector can be used in a query
     * to replace its execution with the execution of code. This can be used for
     * named or parameterized queries to allow dynamic configuration of the
     * query base on the query arguments.
     *
     * @see QueryRedirector
     */
    public QueryRedirector getRedirector() {
        if (doNotRedirect) {
            return null;
        }
        return redirector;
    }

    /**
     * PUBLIC: Return the domain class associated with this query. By default
     * this is null, but should be overridden in subclasses.
     */
    public Class getReferenceClass() {
        return null;
    }

    /**
     * INTERNAL: return the name of the reference class. Added for Mapping
     * Workbench removal of classpath dependency. Overridden by subclasses.
     */
    public String getReferenceClassName() {
        return null;
    }

    /**
     * PUBLIC: Return the selection criteria of the query. This should only be
     * used with expression queries, null will be returned for others.
     */
    public Expression getSelectionCriteria() {
        if (this.queryMechanism == null) {
            return null;
        }
        return this.queryMechanism.getSelectionCriteria();
    }

    /**
     * INTERNAL:
     * TopLink_sessionName_domainClass_queryClass_queryName (if exist)_operationName (if exist).  Cached in properties
     */
    public String getSensorName(String operationName, String sessionName) {
        if (operationName == null) {
            return getQueryNounName(sessionName);
        }

        Hashtable sensorNames = (Hashtable)getProperty("DMSSensorNames");
        if (sensorNames == null) {
            sensorNames = new Hashtable();
            setProperty("DMSSensorNames", sensorNames);
        }
        Object sensorName = sensorNames.get(operationName);
        if (sensorName == null) {
            StringBuilder buffer = new StringBuilder(getQueryNounName(sessionName));
            buffer.append("_");
            buffer.append(operationName);
            sensorName = buffer.toString();
            sensorNames.put(operationName, sensorName);
        }
        return (String)sensorName;
    }

    /**
     * INTERNAL: Return the current session.
     */
    public AbstractSession getSession() {
        return session;
    }

    /**
     * INTERNAL: Return the execution session. This is the session used to build
     * objects returned by the query.
     */
    public AbstractSession getExecutionSession() {
        if (this.executionSession == null) {
            if (getSession() != null) {
                this.executionSession = getSession().getExecutionSession(this);
            }
        }
        return this.executionSession;
    }

    /**
     * INTERNAL: Set the execution session. This is the session used to build
     * objects returned by the query.
     */
    protected void setExecutionSession(AbstractSession executionSession) {
        this.executionSession = executionSession;
    }

    /**
     * PUBLIC: Return the name of the session that the query should be executed
     * under. This can be with the session broker to override the default
     * session.
     */
    public String getSessionName() {
        return sessionName;
    }

    /**
     * PUBLIC: Return the SQL statement of the query. This can only be used with
     * statement queries.
     */
    public SQLStatement getSQLStatement() {
        return ((StatementQueryMechanism) getQueryMechanism()).getSQLStatement();
    }

    /**
     * PUBLIC: Return the JPQL string of the query.
     */
    public String getJPQLString() {
        return getEJBQLString();
    }

    /**
     * PUBLIC: Return the EJBQL string of the query.
     */
    public String getEJBQLString() {
        if (!(getQueryMechanism().isJPQLCallQueryMechanism())) {
            return null;
        }
        JPQLCall call = ((JPQLCallQueryMechanism) getQueryMechanism()).getJPQLCall();
        return call.getEjbqlString();
    }

    /**
     * PUBLIC: Return the current database hint string of the query.
     */
    public String getHintString() {
        return hintString;
    }

    /**
     * ADVANCED: Return the SQL string of the query. This can be used for SQL
     * queries. This can also be used for normal queries if they have been
     * prepared, (i.e. query.prepareCall()).
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, org.eclipse.persistence.sessions.Record) prepareCall(Session, Record)
     */
    public String getSQLString() {
        Call call = getDatasourceCall();
        if (call == null) {
            return null;
        }
        if (!(call instanceof SQLCall)) {
            return null;
        }

        return ((SQLCall) call).getSQLString();
    }

    /**
     * ADVANCED: Return the SQL strings of the query. Used for queries with
     * multiple calls This can be used for SQL queries. This can also be used
     * for normal queries if they have been prepared, (i.e.
     * query.prepareCall()).
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, org.eclipse.persistence.sessions.Record) prepareCall(Session, Record)
     */
    public List getSQLStrings() {
        List calls = getDatasourceCalls();
        if ((calls == null) || calls.isEmpty()) {
            return null;
        }
        Vector returnSQL = new Vector(calls.size());
        Iterator iterator = calls.iterator();
        while (iterator.hasNext()) {
            Call call = (Call) iterator.next();
            if (!(call instanceof SQLCall)) {
                return null;
            }
            returnSQL.addElement(((SQLCall) call).getSQLString());
        }
        return returnSQL;
    }

    /**
     * INTERNAL: Returns the internal tri-state value of shouldBindParameters
     * used far cascading these settings
     */
    public Boolean getShouldBindAllParameters() {
        return this.shouldBindAllParameters;
    }

    /**
     * INTERNAL:
     */
    public DatabaseMapping getSourceMapping() {
        return sourceMapping;
    }

    /**
     * ADVANCED: This can be used to access a queries translated SQL if they
     * have been prepared, (i.e. query.prepareCall()). The Record argument is
     * one of (Record, XMLRecord) that contains the query arguments.
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, Record)
     */
    public String getTranslatedSQLString(org.eclipse.persistence.sessions.Session session, Record translationRow) {
        prepareCall(session, translationRow);
        // CR#2859559 fix to use Session and Record interfaces not impl classes.
        CallQueryMechanism queryMechanism = (CallQueryMechanism) getQueryMechanism();
        if (queryMechanism.getCall() == null) {
            return null;
        }
        SQLCall call = (SQLCall) queryMechanism.getCall().clone();
        call.setUsesBinding(false);
        call.translate((AbstractRecord) translationRow, queryMechanism.getModifyRow(), (AbstractSession) session);
        return call.getSQLString();
    }

    /**
     * ADVANCED: This can be used to access a queries translated SQL if they
     * have been prepared, (i.e. query.prepareCall()). This method can be used
     * for queries with multiple calls.
     *
     * @see #prepareCall(org.eclipse.persistence.sessions.Session, org.eclipse.persistence.sessions.Record) prepareCall(Session, Record)
     */
    public List getTranslatedSQLStrings(org.eclipse.persistence.sessions.Session session, Record translationRow) {
        prepareCall(session, translationRow);
        CallQueryMechanism queryMechanism = (CallQueryMechanism) getQueryMechanism();
        if ((queryMechanism.getCalls() == null) || queryMechanism.getCalls().isEmpty()) {
            return null;
        }
        Vector calls = new Vector(queryMechanism.getCalls().size());
        Iterator iterator = queryMechanism.getCalls().iterator();
        while (iterator.hasNext()) {
            SQLCall call = (SQLCall) iterator.next();
            call = (SQLCall) call.clone();
            call.setUsesBinding(false);
            call.translate((AbstractRecord) translationRow, queryMechanism.getModifyRow(), (AbstractSession) session);
            calls.add(call.getSQLString());
        }
        return calls;
    }

    /**
     * INTERNAL: Return the row for translation
     */
    public AbstractRecord getTranslationRow() {
        return translationRow;
    }

    /**
     * INTERNAL: returns true if the accessor has already been set. The
     * getAccessor() will attempt to lazily initialize it.
     */
    public boolean hasAccessor() {
        return this.accessors != null;
    }

    /**
     * INTERNAL: Return if any properties exist in the query.
     */
    public boolean hasProperties() {
        return (properties != null) && (!properties.isEmpty());
    }

    /**
     * INTERNAL: Return if any arguments exist in the query.
     */
    public boolean hasArguments() {
        return (arguments != null) && (!arguments.isEmpty());
    }

    /**
     * PUBLIC: Return if a name of the session that the query should be executed
     * under has been specified. This can be with the session broker to override
     * the default session.
     */
    public boolean hasSessionName() {
        return sessionName != null;
    }

    /**
     * PUBLIC: Session's shouldBindAllParameters() defines whether to bind or
     * not (default setting)
     */
    public void ignoreBindAllParameters() {
        this.shouldBindAllParameters = null;
    }

    /**
     * PUBLIC: Session's shouldCacheAllStatements() defines whether to cache or
     * not (default setting)
     */
    public void ignoreCacheStatement() {
        this.shouldCacheStatement = null;
    }

    /**
     * PUBLIC: Return true if this query uses SQL, a stored procedure, or SDK
     * call.
     */
    public boolean isCallQuery() {
        return (this.queryMechanism != null) && this.queryMechanism.isCallQueryMechanism();
    }

    /**
     * INTERNAL: Returns true if this query has been created as the result of
     * cascading a delete of an aggregate collection in a UnitOfWork CR 2811
     */
    public boolean isCascadeOfAggregateDelete() {
        return this.cascadePolicy == CascadeAggregateDelete;
    }

    /**
     * PUBLIC: Return if this is a data modify query.
     */
    public boolean isDataModifyQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is a data read query.
     */
    public boolean isDataReadQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is a value read query.
     */
    public boolean isValueReadQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is a direct read query.
     */
    public boolean isDirectReadQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is a delete all query.
     */
    public boolean isDeleteAllQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is a delete object query.
     */
    public boolean isDeleteObjectQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this query uses an expression query mechanism
     */
    public boolean isExpressionQuery() {
        return (this.queryMechanism == null) || this.queryMechanism.isExpressionQueryMechanism();
    }

    /**
     * PUBLIC: Return true if this is a modify all query.
     */
    public boolean isModifyAllQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is a modify query.
     */
    public boolean isModifyQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is an update all query.
     */
    public boolean isUpdateAllQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is an update object query.
     */
    public boolean isUpdateObjectQuery() {
        return false;
    }

    /**
     * PUBLIC: If executed against a RepeatableWriteUnitOfWork if this attribute
     * is true EclipseLink will write changes to the database before executing
     * the query.
     */
    public Boolean getFlushOnExecute() {
        return this.flushOnExecute;
    }

    /**
     * PUBLIC: Return true if this is an insert object query.
     */
    public boolean isInsertObjectQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is an object level modify query.
     */
    public boolean isObjectLevelModifyQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is an object level read query.
     */
    public boolean isObjectLevelReadQuery() {
        return false;
    }

    /**
     * PUBLIC: Return if this is an object building query.
     */
    public boolean isObjectBuildingQuery() {
        return false;
    }

    /**
     * INTERNAL: Queries are prepared when they are executed and then do not
     * need to be prepared on subsequent executions. This method returns true if
     * this query has been prepared. Updating the settings on a query will
     * 'un-prepare' the query.
     */
    public boolean isPrepared() {
        return isPrepared;
    }

    /**
     * PUBLIC: Return true if this is a read all query.
     */
    public boolean isReadAllQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is a read object query.
     */
    public boolean isReadObjectQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is a read query.
     */
    public boolean isReadQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is a report query.
     */
    public boolean isReportQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this is a result set mapping query.
     */
    public boolean isResultSetMappingQuery() {
        return false;
    }

    /**
     * PUBLIC: Return true if this query uses an SQL query mechanism .
     */
    public boolean isSQLCallQuery() {
        // BUG#2669342 CallQueryMechanism and isCallQueryMechanism have
        // different meaning as SDK return true but isn't.
        Call call = getDatasourceCall();
        return (call != null) && (call instanceof SQLCall);
    }

    /**
     * PUBLIC: Return true if this query uses an JPQL query mechanism .
     */
    public boolean isJPQLCallQuery() {
        return ((this.queryMechanism != null)
                && this.queryMechanism.isJPQLCallQueryMechanism()
                && ((JPQLCallQueryMechanism)this.queryMechanism).getJPQLCall() != null);
    }

    /**
     * INTERNAL: Return true if the query is a custom user defined query.
     */
    public boolean isUserDefined() {
        return isUserDefined;
    }

    /**
     * INTERNAL: Return true if the query is a custom user defined SQL call query.
     */
    public boolean isUserDefinedSQLCall() {
        return this.isUserDefinedSQLCall;
    }

    /**
     * INTERNAL: Return true if the query uses default properties. This is used
     * to determine if this query is cacheable. i.e. does not use any properties
     * that may conflict with another query with the same EJBQL or selection
     * criteria.
     */
    public boolean isDefaultPropertiesQuery() {
        return (!this.isUserDefined) && (this.shouldPrepare) && (this.queryTimeout == DescriptorQueryManager.DefaultTimeout)
            && (this.hintString == null) && (this.shouldBindAllParameters == null) && (this.shouldCacheStatement == null) && (this.shouldUseWrapperPolicy);
    }

    /**
     * PUBLIC: Return true if this is a write object query.
     */
    public boolean isWriteObjectQuery() {
        return false;
    }

    /**
     * PUBLIC: Set for the identity map (cache) to be maintained. This is the
     * default.
     */
    public void maintainCache() {
        setShouldMaintainCache(true);
    }

    /**
     * INTERNAL: This is different from 'prepareForExecution' in that this is
     * called on the original query, and the other is called on the copy of the
     * query. This query is copied for concurrency so this prepare can only
     * setup things that will apply to any future execution of this query.
     *
     * Resolve the queryTimeout using the DescriptorQueryManager if required.
     */
    protected void prepare() throws QueryException {
        // If the queryTimeout is DefaultTimeout, resolve using the
        // DescriptorQueryManager.
        if (this.queryTimeout == DescriptorQueryManager.DefaultTimeout) {
            if (this.descriptor == null) {
                setQueryTimeout(this.session.getQueryTimeoutDefault());
                if(this.session.getQueryTimeoutUnitDefault() == null) {
                    this.session.setQueryTimeoutUnitDefault(DescriptorQueryManager.DefaultTimeoutUnit);
                }
                setQueryTimeoutUnit(this.session.getQueryTimeoutUnitDefault());
            } else {
                int timeout = this.descriptor.getQueryManager().getQueryTimeout();
                // No timeout means none set, so use the session default.
                if ((timeout == DescriptorQueryManager.DefaultTimeout) || (timeout == DescriptorQueryManager.NoTimeout)) {
                    timeout = this.session.getQueryTimeoutDefault();
                }
                setQueryTimeout(timeout);

                //Bug #456067
                TimeUnit timeoutUnit = this.descriptor.getQueryManager().getQueryTimeoutUnit();
                if(timeoutUnit == DescriptorQueryManager.DefaultTimeoutUnit) {
                    timeoutUnit = this.session.getQueryTimeoutUnitDefault();
                }
                setQueryTimeoutUnit(timeoutUnit);
            }
        }

        this.argumentFields = buildArgumentFields();

        getQueryMechanism().prepare();
        resetMonitorName();
    }

    /**
     * INTERNAL: Copy all setting from the query. This is used to morph queries
     * from one type to the other. By default this calls prepareFromQuery, but
     * additional properties may be required to be copied as prepareFromQuery
     * only copies properties that affect the SQL.
     */
    public void copyFromQuery(DatabaseQuery query) {
        prepareFromQuery(query);
        this.cascadePolicy = query.cascadePolicy;
        this.flushOnExecute = query.flushOnExecute;
        this.arguments = query.arguments;
        this.nullableArguments = query.nullableArguments;
        this.argumentTypes = query.argumentTypes;
        this.argumentTypeNames = query.argumentTypeNames;
        this.argumentValues = query.argumentValues;
        this.queryTimeout = query.queryTimeout;
        this.redirector = query.redirector;
        this.sessionName = query.sessionName;
        this.shouldBindAllParameters = query.shouldBindAllParameters;
        this.shouldCacheStatement = query.shouldCacheStatement;
        this.shouldMaintainCache = query.shouldMaintainCache;
        this.shouldPrepare = query.shouldPrepare;
        this.shouldUseWrapperPolicy = query.shouldUseWrapperPolicy;
        this.properties = query.properties;
        this.doNotRedirect = query.doNotRedirect;
        this.shouldRetrieveBypassCache = query.shouldRetrieveBypassCache;
        this.shouldStoreBypassCache = query.shouldStoreBypassCache;
        this.parameterDelimiter = query.parameterDelimiter;
        this.shouldCloneCall = query.shouldCloneCall;
        this.partitioningPolicy = query.partitioningPolicy;
    }

    /**
     * INTERNAL: Prepare the query from the prepared query. This allows a
     * dynamic query to prepare itself directly from a prepared query instance.
     * This is used in the JPQL parse cache to allow preparsed queries to be
     * used to prepare dynamic queries. This only copies over properties that
     * are configured through JPQL.
     */
    public void prepareFromQuery(DatabaseQuery query) {
        setQueryMechanism((DatabaseQueryMechanism) query.getQueryMechanism().clone());
        getQueryMechanism().setQuery(this);
        this.descriptor = query.descriptor;
        this.hintString = query.hintString;
        this.isCustomQueryUsed = query.isCustomQueryUsed;
        this.argumentFields = query.argumentFields;
        // this.properties = query.properties; - Cannot set properties and CMP
        // stores finders there.
    }

    /**
     * ADVANCED: Pre-generate the call/SQL for the query. This method takes a
     * Session and an implementor of Record (DatebaseRow or XMLRecord). This can
     * be used to access the SQL for a query without executing it. To access the
     * call use, query.getCall(), or query.getSQLString() for the SQL. Note the
     * SQL will have argument markers in it (i.e. "?"). To translate these use
     * query.getTranslatedSQLString(session, translationRow).
     *
     * @see #getCall()
     * @see #getSQLString()
     * @see #getTranslatedSQLString(org.eclipse.persistence.sessions.Session,
     *      Record)
     */
    public void prepareCall(org.eclipse.persistence.sessions.Session session, Record translationRow) throws QueryException {
        // CR#2859559 fix to use Session and Record interfaces not impl classes.
        checkPrepare((AbstractSession) session, (AbstractRecord) translationRow, true);
    }

    /**
     * INTERNAL: Set the properties needed to be cascaded into the custom query.
     */
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
        // Nothing by default.
    }

    /**
     * INTERNAL: Prepare the receiver for execution in a session. In particular,
     * set the descriptor of the receiver to the ClassDescriptor for the
     * appropriate class for the receiver's object.
     */
    public void prepareForExecution() throws QueryException {
    }

    protected void prepareForRemoteExecution() {
    }

    /**
     * INTERNAL: Use a EclipseLink redirector to redirect this query to a
     * method. Added for bug 3241138
     *
     */
    public Object redirectQuery(QueryRedirector redirector, DatabaseQuery queryToRedirect, AbstractSession session, AbstractRecord translationRow) {
        if (redirector == null) {
            return null;
        }
        DatabaseQuery queryToExecute = (DatabaseQuery) queryToRedirect.clone();
        queryToExecute.setRedirector(null);

        // since we deal with a clone when using a redirector, the descriptor
        // will
        // get set on the clone, but not on the original object. So before
        // returning
        // the results, set the descriptor from the clone onto this object
        // (original
        // query) - GJPP, BUG# 2692956
        Object toReturn = redirector.invokeQuery(queryToExecute, translationRow, session);
        setDescriptor(queryToExecute.getDescriptor());
        return toReturn;
    }

    protected Object remoteExecute() {
        this.session.startOperationProfile(SessionProfiler.Remote, this, SessionProfiler.ALL);
        Transporter transporter = ((DistributedSession) this.session).getRemoteConnection().remoteExecute((DatabaseQuery) this.clone());
        this.session.endOperationProfile(SessionProfiler.Remote, this, SessionProfiler.ALL);
        return extractRemoteResult(transporter);
    }

    /**
     * INTERNAL:
     */
    public Object remoteExecute(AbstractSession session) {
        setSession(session);
        prepareForRemoteExecution();
        return remoteExecute();
    }

    /**
     * INTERNAL: Property support used by mappings.
     */
    public void removeProperty(Object property) {
        getProperties().remove(property);
    }

    /**
     * INTERNAL: replace the value holders in the specified result object(s)
     */
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
        // by default, do nothing
        return null;
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is retrieved by the find methods
     * and by the execution of queries. Calling this method will set a retrieve
     * bypass to true.
     */
    public void retrieveBypassCache() {
        setShouldRetrieveBypassCache(true);
    }

    /**
     * INTERNAL: Build the list of arguments fields from the argument names and
     * types.
     */
    public List<DatabaseField> buildArgumentFields() {
        List<String> arguments = getArguments();
        List<Class> argumentTypes = getArgumentTypes();
        List argumentFields = new ArrayList(arguments.size());
        int size = arguments.size();
        for (int index = 0; index < size; index++) {
            DatabaseField argumentField = new DatabaseField(arguments.get(index));
            argumentField.setType(argumentTypes.get(index));
            argumentFields.add(argumentField);
        }

        return argumentFields;
    }

    /**
     * INTERNAL: Translate argumentValues into a database row.
     */
    public AbstractRecord rowFromArguments(List argumentValues, AbstractSession session) throws QueryException {
        List<DatabaseField> argumentFields = this.argumentFields;

        // PERF: argumentFields are set in prepare, but need to be built if
        // query is not prepared.
        if (!isPrepared() || (argumentFields == null)) {
            argumentFields = buildArgumentFields();
        }

        if (argumentFields.size() != argumentValues.size()) {
            throw QueryException.argumentSizeMismatchInQueryAndQueryDefinition(this);
        }

        int argumentsSize = argumentFields.size();
        AbstractRecord row = new DatabaseRecord(argumentsSize);
        for (int index = 0; index < argumentsSize; index++) {
            row.put(argumentFields.get(index), argumentValues.get(index));
        }

        return row;
    }

    /**
     * INTERNAL:
     * Set the list of connection accessors to execute the query on.
     */
    public void setAccessors(Collection<Accessor> accessors) {
        this.accessors = accessors;
    }

    /**
     * INTERNAL: Set the accessor, the query must always use the same accessor
     * for database access. This is required to support connection pooling.
     */
    public void setAccessor(Accessor accessor) {
        if (accessor == null) {
            this.accessors = null;
            return;
        }
        List<Accessor> accessors = new ArrayList(1);
        accessors.add(accessor);
        this.accessors = accessors;
    }

    /**
     * PUBLIC: Used to define a store procedure or SQL query.
     */
    public void setDatasourceCall(Call call) {
        if (call == null) {
            return;
        }
        setQueryMechanism(call.buildNewQueryMechanism(this));
    }

    /**
     * PUBLIC: Used to define a store procedure or SQL query.
     */
    public void setCall(Call call) {
        setDatasourceCall(call);
        isUserDefinedSQLCall = true;
    }

    /**
     * INTERNAL: Set the cascade policy.
     */
    public void setCascadePolicy(int policyConstant) {
        cascadePolicy = policyConstant;
    }

    /**
     * INTERNAL: Set the descriptor for the query.
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        // If the descriptor changed must unprepare as the SQL may change.
        if (this.descriptor != descriptor) {
            setIsPrepared(false);
        }
        this.descriptor = descriptor;
    }

    /**
     * PUBLIC: Set the JPQL string of the query. If arguments are required in
     * the string they will be preceded by ":" then the argument name. The JPQL
     * arguments must also be added as argument to the query.
     */
    public void setJPQLString(String jpqlString) {
        setEJBQLString(jpqlString);
    }

    /**
     * PUBLIC: Set the EJBQL string of the query. If arguments are required in
     * the string they will be preceded by "?" then the argument number.
     */
    public void setEJBQLString(String ejbqlString) {
        // Added the check for when we are building the query from the
        // deployment XML
        if ((ejbqlString != null) && (!ejbqlString.equals(""))) {
            JPQLCallQueryMechanism mechanism = new JPQLCallQueryMechanism(this, new JPQLCall(ejbqlString));
            setQueryMechanism(mechanism);
        }
    }

    /**
     * PUBLIC: If executed against a RepeatableWriteUnitOfWork if this attribute
     * is true EclipseLink will write changes to the database before executing
     * the query.
     */
    public void setFlushOnExecute(Boolean flushMode) {
        this.flushOnExecute = flushMode;
    }

    /**
     * Used to set a database hint string on the query. This should be the full
     * hint string including the comment delimiters. The hint string will be
     * generated into the SQL string after the SELECT/INSERT/UPDATE/DELETE
     * instruction.
     * <p>
     * <b>Example:</b>
     * <pre>
     * readAllQuery.setHintString("/*+ index(scott.emp ix_emp) * /");
     * </pre>
     * would result in SQL like:
     * <pre>select /*+ index(scott.emp ix_emp) * / from scott.emp emp_alias</pre>
     * <p>
     * This method will cause a query to re-prepare if it has already been
     * executed.
     *
     * @param newHintString
     *            the hint string to be added into the SQL call.
     */
    public void setHintString(String newHintString) {
        hintString = newHintString;
        setIsPrepared(false);
    }

    /**
     * INTERNAL: If changes are made to the query that affect the derived SQL or
     * Call parameters the query needs to be prepared again.
     * <p>
     * Automatically called internally.
     */
    public void setIsPrepared(boolean isPrepared) {
        this.isPrepared = isPrepared;
        if (!isPrepared) {
            this.isCustomQueryUsed = null;
            if (this.queryMechanism != null) {
                this.queryMechanism.unprepare();
            }
        }
    }

    /**
     * INTERNAL: PERF: Return if the query is an execution clone. This allow the
     * clone during execution to be avoided in the cases when the query has
     * already been clone elsewhere.
     */
    public boolean isExecutionClone() {
        return isExecutionClone;
    }

    /**
     * INTERNAL: PERF: Set if the query is an execution clone. This allow the
     * clone during execution to be avoided in the cases when the query has
     * already been clone elsewhere.
     */
    public void setIsExecutionClone(boolean isExecutionClone) {
        this.isExecutionClone = isExecutionClone;
    }

    /**
     * INTERNAL: PERF: Return if this query will use the descriptor custom query
     * instead of executing itself.
     */
    public Boolean isCustomQueryUsed() {
        return this.isCustomQueryUsed;
    }

    /**
     * INTERNAL: If the query mechanism is a call query mechanism and there are
     * no arguments on the query then it must be a foreign reference custom
     * selection query.
     */
    protected boolean isCustomSelectionQuery() {
        return getQueryMechanism().isCallQueryMechanism() && getArguments().isEmpty();
    }

    /**
     * INTERNAL: PERF: Set if this query will use the descriptor custom query
     * instead of executing itself.
     * @param isCustomQueryUsed Custom query flag as {@code boolean}.
     */
    protected void setIsCustomQueryUsed(final boolean isCustomQueryUsed) {
        this.isCustomQueryUsed = isCustomQueryUsed;
    }

    /**
     * INTERNAL: Set if the query is a custom user defined query.
     */
    public void setIsUserDefined(boolean isUserDefined) {
        this.isUserDefined = isUserDefined;
    }

    /**
     * INTERNAL: Set if the query is a custom user defined sql call query.
     */
    public void setIsUserDefinedSQLCall(boolean isUserDefinedSQLCall) {
        this.isUserDefinedSQLCall = isUserDefinedSQLCall;
    }

    /**
     * PUBLIC: Set the query's name. Queries can be named and added to a
     * descriptor or the session and then referenced by name.
     */
    public void setName(String queryName) {
        name = queryName;
    }

    /**
     * INTERNAL:
     * Set the String char used to delimit an SQL parameter.
     */
    public void setParameterDelimiter(String aParameterDelimiter) {
        // 325167: if the parameterDelimiter is invalid - use the default # symbol
        if(null == aParameterDelimiter || aParameterDelimiter.length() == 0) {
            aParameterDelimiter = ParameterDelimiterType.DEFAULT;
        }
        parameterDelimiter = aParameterDelimiter;
    }

    /**
     * INTERNAL: Property support used by mappings.
     */
    public void setProperties(Map<Object, Object> properties) {
        this.properties = properties;
    }

    /**
     * INTERNAL: Property support used by mappings to store temporary stuff.
     */
    public synchronized void setProperty(Object property, Object value) {
        getProperties().put(property, value);
    }

    /**
     * Set the query mechanism for the query.
     */
    protected void setQueryMechanism(DatabaseQueryMechanism queryMechanism) {
        this.queryMechanism = queryMechanism;
        // Must un-prepare is prepare as the SQL may change.
        setIsPrepared(false);
    }

    /**
     * PUBLIC: Set the number of seconds the driver will wait for a Statement to
     * execute to the given number of seconds. If the limit is exceeded, a
     * DatabaseException is thrown.
     *
     * queryTimeout - the new query timeout limit in seconds; DefaultTimeout is
     * the default, which redirects to DescriptorQueryManager's queryTimeout.
     *
     * @see DescriptorQueryManager#setQueryTimeout(int)
     *
     */
    public void setQueryTimeout(int queryTimeout) {
        this.queryTimeout = queryTimeout;
        this.shouldCloneCall = true;
    }

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

    /**
     * PUBLIC: Set the query redirector. A redirector can be used in a query to
     * replace its execution with the execution of code. This can be used for
     * named or parameterized queries to allow dynamic configuration of the
     * query base on the query arguments.
     *
     * @see QueryRedirector
     */
    public void setRedirector(QueryRedirector redirector) {
        this.redirector = redirector;
        this.doNotRedirect = false;
        this.setIsPrepared(false);
    }

    /**
     * PUBLIC: To any user of this object. Set the selection criteria of the
     * query. This method be used when dealing with expressions.
     */
    public void setSelectionCriteria(Expression expression) {
        // Do not overwrite the call if the expression is null.
        if ((expression == null) && (!getQueryMechanism().isExpressionQueryMechanism())) {
            return;
        }
        if (!getQueryMechanism().isExpressionQueryMechanism()) {
            setQueryMechanism(new ExpressionQueryMechanism(this, expression));
        } else {
            ((ExpressionQueryMechanism) getQueryMechanism()).setSelectionCriteria(expression);
        }

        // Must un-prepare is prepare as the SQL may change.
        setIsPrepared(false);
    }

    /**
     * INTERNAL: Set the session for the query
     */
    public void setSession(AbstractSession session) {
        this.session = session;
        this.executionSession = null;
    }

    /**
     * PUBLIC: Set the name of the session that the query should be executed
     * under. This can be with the session broker to override the default
     * session.
     */
    public void setSessionName(String sessionName) {
        this.sessionName = sessionName;
    }

    /**
     * PUBLIC: Bind all arguments to any SQL statement.
     */
    public void setShouldBindAllParameters(boolean shouldBindAllParameters) {
        this.shouldBindAllParameters = shouldBindAllParameters;
        setIsPrepared(false);
    }

    /**
     * INTERNAL: Sets the internal tri-state value of shouldBindAllParams Used
     * to cascade this value to other queries
     */
    public void setShouldBindAllParameters(Boolean bindAllParams) {
        this.shouldBindAllParameters = bindAllParams;
    }

    /**
     * PUBLIC: Cache the prepared statements, this requires full parameter
     * binding as well.
     */
    public void setShouldCacheStatement(boolean shouldCacheStatement) {
        this.shouldCacheStatement = shouldCacheStatement;
        setIsPrepared(false);
    }

    /**
     * PUBLIC: Set if the identity map (cache) should be used or not. If not the
     * cache check will be skipped and the result will not be put into the
     * identity map. By default the identity map is always maintained.
     */
    public void setShouldMaintainCache(boolean shouldMaintainCache) {
        this.shouldMaintainCache = shouldMaintainCache;
    }

    /**
     * PUBLIC: Set if the query should be prepared. EclipseLink automatically
     * prepares queries to generate their SQL only once, one each execution of
     * the query the SQL does not need to be generated again only the arguments
     * need to be translated. This option is provide to disable this
     * optimization as in can cause problems with certain types of queries that
     * require dynamic SQL based on their arguments.
     * <p>
     * These queries include:
     * <ul>
     * <li>Expressions that make use of 'equal' where the argument value has the
     * potential to be null, this can cause problems on databases that require
     * IS NULL, instead of = NULL.
     * <li>Expressions that make use of 'in' and that use parameter binding,
     * this will cause problems as the in values must be bound individually.
     * </ul>
     */
    public void setShouldPrepare(boolean shouldPrepare) {
        this.shouldPrepare = shouldPrepare;
        setIsPrepared(false);
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is retrieved by the find methods
     * and by the execution of queries.
     */
    public void setShouldRetrieveBypassCache(boolean shouldRetrieveBypassCache) {
        this.shouldRetrieveBypassCache = shouldRetrieveBypassCache;
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is read from the database and when
     * data is committed into the database.
     */
    public void setShouldStoreBypassCache(boolean shouldStoreBypassCache) {
        this.shouldStoreBypassCache = shouldStoreBypassCache;
    }

    /**
     * INTERNAL:
     * Set if additional validation should be performed before the query uses
     * the update call cache.
     */
    public void setShouldValidateUpdateCallCacheUse(boolean shouldCheckUpdateCallCacheUse) {
        this.shouldValidateUpdateCallCacheUse = shouldCheckUpdateCallCacheUse;
    }

    /**
     * ADVANCED: The wrapper policy can be enable on a query.
     */
    public void setShouldUseWrapperPolicy(boolean shouldUseWrapperPolicy) {
        this.shouldUseWrapperPolicy = shouldUseWrapperPolicy;
    }

    /**
     * INTERNAL:
     */
    public void setSourceMapping(DatabaseMapping sourceMapping) {
        this.sourceMapping = sourceMapping;
    }

    /**
     * PUBLIC: To any user of this object. Set the SQL statement of the query.
     * This method should only be used when dealing with statement objects.
     */
    public void setSQLStatement(SQLStatement sqlStatement) {
        setQueryMechanism(new StatementQueryMechanism(this, sqlStatement));
    }

    /**
     * PUBLIC: To any user of this object. Set the SQL string of the query. This
     * method should only be used when dealing with user defined SQL strings. If
     * arguments are required in the string they will be preceded by "#" then
     * the argument name. Warning: Allowing an unverified SQL string to be
     * passed into this method makes your application vulnerable to SQL
     * injection attacks.
     */
    public void setSQLString(String sqlString) {
        // Added the check for when we are building the query from the
        // deployment XML
        if ((sqlString != null) && (!sqlString.equals(""))) {
            setCall(new SQLCall(sqlString));
        }
    }

    /**
     * INTERNAL: Set the row for translation
     */
    public void setTranslationRow(AbstractRecord translationRow) {
        this.translationRow = translationRow;
    }

    /**
     * PUBLIC: Bind all arguments to any SQL statement.
     */
    public boolean shouldBindAllParameters() {
        return Boolean.TRUE.equals(shouldBindAllParameters);
    }

    /**
     * INTERNAL:
     * Return true if this individual query should allow native a SQL call
     * to be issued.
     */
    public boolean shouldAllowNativeSQLQuery(boolean projectAllowsNativeQueries) {
        // If allow native SQL query is undefined, use the project setting
        // otherwise use the allow native SQL setting.
        return (allowNativeSQLQuery == null) ? projectAllowsNativeQueries : allowNativeSQLQuery;
    }

    /**
     * PUBLIC: Cache the prepared statements, this requires full parameter
     * binding as well.
     */
    public boolean shouldCacheStatement() {
        return Boolean.TRUE.equals(shouldCacheStatement);
    }

    /**
     * PUBLIC: Flag used to determine if all parts should be cascaded
     */
    public boolean shouldCascadeAllParts() {
        return this.cascadePolicy == CascadeAllParts;
    }

    /**
     * PUBLIC: Mappings should be checked to determined if the current operation
     * should be cascaded to the objects referenced.
     */
    public boolean shouldCascadeByMapping() {
        return this.cascadePolicy == CascadeByMapping;
    }

    /**
     * INTERNAL: Flag used for unit of works cascade policy.
     */
    public boolean shouldCascadeOnlyDependentParts() {
        return this.cascadePolicy == CascadeDependentParts;
    }

    /**
     * PUBLIC: Flag used to determine if any parts should be cascaded
     */
    public boolean shouldCascadeParts() {
        return this.cascadePolicy != NoCascading;
    }

    /**
     * PUBLIC: Flag used to determine if any private parts should be cascaded
     */
    public boolean shouldCascadePrivateParts() {
        return (this.cascadePolicy == CascadePrivateParts) || (this.cascadePolicy == CascadeAllParts);
    }

    /**
     * INTERNAL: Flag used to determine if the call needs to be cloned.
     */
    public boolean shouldCloneCall() {
        return shouldCloneCall;
    }

    /**
     * PUBLIC: Local shouldBindAllParameters() should be ignored, Session's
     * shouldBindAllParameters() should be used.
     */
    public boolean shouldIgnoreBindAllParameters() {
        return shouldBindAllParameters == null;
    }

    /**
     * PUBLIC: Local shouldCacheStatement() should be ignored, Session's
     * shouldCacheAllStatements() should be used.
     */
    public boolean shouldIgnoreCacheStatement() {
        return shouldCacheStatement == null;
    }

    /**
     * PUBLIC: Return if the identity map (cache) should be used or not. If not
     * the cache check will be skipped and the result will not be put into the
     * identity map. By default the identity map is always maintained.
     */
    public boolean shouldMaintainCache() {
        return shouldMaintainCache;
    }

    /**
     * PUBLIC: Return if the query should be prepared. EclipseLink automatically
     * prepares queries to generate their SQL only once, one each execution of
     * the query the SQL does not need to be generated again only the arguments
     * need to be translated. This option is provide to disable this
     * optimization as in can cause problems with certain types of queries that
     * require dynamic SQL based on their arguments.
     * <p>
     * These queries include:
     * <ul>
     * <li>Expressions that make use of 'equal' where the argument value has the
     * potential to be null, this can cause problems on databases that require
     * IS NULL, instead of = NULL.
     * <li>Expressions that make use of 'in' and that use parameter binding,
     * this will cause problems as the in values must be bound individually.
     * </ul>
     */
    public boolean shouldPrepare() {
        return shouldPrepare;
    }

    /**
     * INTERNAL:
     * Check if the query should be prepared, or dynamic, depending on the arguments.
     * This allows null parameters to affect the SQL, such as stored procedure default values,
     * or IS NULL, or insert defaults.
     */
    public boolean shouldPrepare(AbstractRecord translationRow, AbstractSession session) {
        if (!this.shouldPrepare) {
            return false;
        }
        if (!((DatasourcePlatform)session.getDatasourcePlatform()).shouldPrepare(this)) {
            this.shouldPrepare = false;
            return false;
        }
        if (this.nullableArguments != null) {
            for (DatabaseField argument : this.nullableArguments) {
                if (translationRow.get(argument) == null) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is retrieved by the find methods
     * and by the execution of queries.
     */
    public boolean shouldRetrieveBypassCache() {
        return this.shouldRetrieveBypassCache;
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is read from the database and when
     * data is committed into the database.
     */
    public boolean shouldStoreBypassCache() {
        return this.shouldStoreBypassCache;
    }

    /**
     * ADVANCED: The wrapper policy can be enabled on a query.
     */
    public boolean shouldUseWrapperPolicy() {
        return shouldUseWrapperPolicy;
    }

    /**
     * ADVANCED:
     * Return true if additional validation should be performed before the query uses
     * the update call cache, false otherwise.
     */
    public boolean shouldValidateUpdateCallCacheUse() {
        return shouldValidateUpdateCallCacheUse;
    }

    /**
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
     * flag specifies the behavior when data is read from the database and when
     * data is committed into the database. Calling this method will set a store
     * bypass to true.
     *
     * Note: For a cache store mode of REFRESH, see refreshIdentityMapResult()
     * from ObjectLevelReadQuery.
     */
    public void storeBypassCache() {
        setShouldStoreBypassCache(true);
    }

    @Override
    public String toString() {
        String referenceClassString = "";
        String nameString = "";
        String queryString = "";
        if (getReferenceClass() != null) {
            referenceClassString = "referenceClass=" + getReferenceClass().getSimpleName() + " ";
        }
        if ((getName() != null) && (!getName().equals(""))) {
            nameString = "name=\"" + getName() + "\" ";
        }
        if (isSQLCallQuery()) {
            queryString = "sql=\"" + getSQLString() + "\"";
        } else if (isJPQLCallQuery()) {
            queryString = "jpql=\"" + getJPQLString() + "\"";
        }
        return getClass().getSimpleName() + "(" + nameString + referenceClassString + queryString + ")";
    }

    /**
     * ADVANCED: Set if the descriptor requires usage of a native (unwrapped)
     * JDBC connection. This may be required for some Oracle JDBC support when a
     * wrapping DataSource is used.
     */
    public void setIsNativeConnectionRequired(boolean isNativeConnectionRequired) {
        this.isNativeConnectionRequired = isNativeConnectionRequired;
    }

    /**
     * ADVANCED: Return if the descriptor requires usage of a native (unwrapped)
     * JDBC connection. This may be required for some Oracle JDBC support when a
     * wrapping DataSource is used.
     */
    public boolean isNativeConnectionRequired() {
        return isNativeConnectionRequired;
    }

    /**
     * This method is used in combination with redirected queries. If a
     * redirector is set on the query or there is a default redirector on the
     * Descriptor setting this value to true will force EclipseLink to ignore
     * the redirector during execution. This setting will be used most often
     * when reexecuting the query within a redirector.
     */
    public boolean getDoNotRedirect() {
        return doNotRedirect;
    }

    /**
     * This method is used in combination with redirected queries. If a
     * redirector is set on the query or there is a default redirector on the
     * Descriptor setting this value to true will force EclipseLink to ignore
     * the redirector during execution. This setting will be used most often
     * when reexecuting the query within a redirector.
     */
    public void setDoNotRedirect(boolean doNotRedirect) {
        this.doNotRedirect = doNotRedirect;
    }

    /**
     * INTERNAL:
     * Return temporary map of batched objects.
     */
    public Map<Object, Object> getBatchObjects() {
        return (Map<Object, Object>)getProperty(BATCH_FETCH_PROPERTY);
    }

    /**
     * INTERNAL:
     * Set temporary map of batched objects.
     */
    public void setBatchObjects(Map<Object, Object> batchObjects) {
        setProperty(BATCH_FETCH_PROPERTY, batchObjects);
    }

    /**
     * INTERNAL:
     * Set to true if this individual query should be marked to bypass a
     * persistence unit level disallow SQL queries flag.
     */
    public void setAllowNativeSQLQuery(Boolean allowNativeSQLQuery) {
        this.allowNativeSQLQuery = allowNativeSQLQuery;
    }

    /**
     * INTERNAL:
     * Return if the query has any nullable arguments.
     */
    public boolean hasNullableArguments() {
        return (this.nullableArguments != null) && !this.nullableArguments.isEmpty();
    }

    /**
     * INTERNAL:
     * Return the list of arguments to check for null.
     * If any are null, the query needs to be re-prepared.
     */
    public List<DatabaseField> getNullableArguments() {
        if (this.nullableArguments == null) {
            this.nullableArguments = new ArrayList<>();
        }
        return nullableArguments;
    }

    /**
     * INTERNAL:
     * Set the list of arguments to check for null.
     * If any are null, the query needs to be re-prepared.
     */
    public void setNullableArguments(List<DatabaseField> nullableArguments) {
        this.nullableArguments = nullableArguments;
    }
}
