/*
 * 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 args = this.argumentTypeNames.iterator();
                while (args.hasNext()) {
                    String argumentTypeName = (String) 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 arguments = getArguments();
        List argumentTypes = getArgumentTypes();
        List argumentFields = new ArrayList(arguments.size());
        int size = arguments.size();
        for (int index = 0; index < size; index++) {
            DatabaseField argumentField = new DatabaseField((String) arguments.get(index));
            argumentField.setType((Class) 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;
    }
}
