/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 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
//     Zoltan NAGY & tware - updated support for MaxRows
//     11/01/2010-2.2 Guy Pelletier
//       - 322916: getParameter on Query throws NPE
//     11/09/2010-2.1 Michael O'Brien
//       - 329089: PERF: EJBQueryImpl.setParamenterInternal() move indexOf check inside non-native block
//     02/08/2012-2.4 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     06/20/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     07/13/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     08/24/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     09/13/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     09/27/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
package org.eclipse.persistence.internal.jpa;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
import jakarta.persistence.LockTimeoutException;
import jakarta.persistence.Parameter;
import jakarta.persistence.ParameterMode;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.QueryTimeoutException;
import jakarta.persistence.StoredProcedureQuery;
import jakarta.persistence.TemporalType;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.jpa.querydef.ParameterExpressionImpl;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ResultSetMappingQuery;
import org.eclipse.persistence.queries.SQLResultSetMapping;
import org.eclipse.persistence.queries.StoredProcedureCall;

/**
 * Concrete JPA query class. The JPA query wraps a StoredProcesureQuery which
 * is executed.
 */
public class StoredProcedureQueryImpl extends QueryImpl implements StoredProcedureQuery {
    protected boolean hasMoreResults;

    // Call will be returned from an execute. From it you can get the result set.
    protected DatabaseCall executeCall;
    protected Statement executeStatement;
    protected int executeResultSetIndex = -1;

    // If the procedure returns output cursor(s), we'll use them to satisfy
    // getResultList and getSingleResult calls so keep track of our index.
    protected int outputCursorIndex = -1;
    protected boolean isOutputCursorResultSet = false;

    /**
     * Base constructor for StoredProcedureQueryImpl. Initializes basic variables.
     */
    protected StoredProcedureQueryImpl(EntityManagerImpl entityManager) {
        super(entityManager);
    }

    /**
     * Create an StoredProcedureQueryImpl with a DatabaseQuery.
     */
    public StoredProcedureQueryImpl(DatabaseQuery query, EntityManagerImpl entityManager) {
        super(query, entityManager);
    }

    /**
     * Create an StoredProcedureQueryImpl with a query name.
     */
    public StoredProcedureQueryImpl(String name, EntityManagerImpl entityManager) {
        super(entityManager);
        this.queryName = name;
    }

    /**
     * Build the given result set into a list objects. Assumes there is an
     * execute call available and therefore should not be called unless an
     * execute statement was issued by the user.
     */
    protected List buildResultRecords(ResultSet resultSet) {
        try {
            AbstractSession session = (AbstractSession) getActiveSession();
            DatabaseAccessor accessor = (DatabaseAccessor) executeCall.getQuery().getAccessor();

            executeCall.setFields(null);
            executeCall.matchFieldOrder(resultSet, accessor, session);
            ResultSetMetaData metaData = resultSet.getMetaData();

            List<AbstractRecord> result =  new Vector<>();
            while (resultSet.next()) {
                result.add(accessor.fetchRow(executeCall.getFields(), executeCall.getFieldsArray(), resultSet, metaData, session));
            }

            // The result set must be closed in case the statement is cached and not closed.
            resultSet.close();

            return result;
        } catch (Exception e) {
            setRollbackOnly();
            throw new PersistenceException(e);
        }
    }

    /**
     * Build a ResultSetMappingQuery from a sql result set mapping name and a
     * stored procedure call.
     *
     * This is called from a named stored procedure that employs result set
     * mapping name(s) which should be available from the session.
     */
    public static DatabaseQuery buildResultSetMappingNameQuery(List<String> resultSetMappingNames, StoredProcedureCall call) {
        ResultSetMappingQuery query = new ResultSetMappingQuery();
        call.setReturnMultipleResultSetCollections(call.hasMultipleResultSets() && ! call.isMultipleCursorOutputProcedure());
        query.setCall(call);
        query.setIsUserDefined(true);
        query.setSQLResultSetMappingNames(resultSetMappingNames);
        return query;
    }

    /**
     * Build a ResultSetMappingQuery from a sql result set mapping name and a
     * stored procedure call.
     *
     * This is called from a named stored procedure that employs result set
     * mapping name(s) which should be available from the session.
     */
    public static DatabaseQuery buildResultSetMappingNameQuery(List<String> resultSetMappingNames, StoredProcedureCall call, Map<String, Object> hints, ClassLoader classLoader, AbstractSession session) {
        // apply any query hints
        DatabaseQuery hintQuery = applyHints(hints, buildResultSetMappingNameQuery(resultSetMappingNames, call) , classLoader, session);

        // apply any query arguments
        applyArguments(call, hintQuery);

        return hintQuery;
    }

    /**
     * Build a ResultSetMappingQuery from the sql result set mappings given
     *  a stored procedure call.
     *
     * This is called from a named stored procedure query that employs result
     * class name(s). The resultSetMappings are build from these class name(s)
     * and are not available from the session.
     */
    public static DatabaseQuery buildResultSetMappingQuery(List<SQLResultSetMapping> resultSetMappings, StoredProcedureCall call) {
        ResultSetMappingQuery query = new ResultSetMappingQuery();
        call.setReturnMultipleResultSetCollections(call.hasMultipleResultSets() && ! call.isMultipleCursorOutputProcedure());
        query.setCall(call);
        query.setIsUserDefined(true);
        query.setSQLResultSetMappings(resultSetMappings);
        return query;
    }

    /**
     * Build a ResultSetMappingQuery from the sql result set mappings given
     *  a stored procedure call.
     *
     * This is called from a named stored procedure query that employs result
     * class name(s). The resultSetMappings are build from these class name(s)
     * and are not available from the session.
     */
    public static DatabaseQuery buildResultSetMappingQuery(List<SQLResultSetMapping> resultSetMappings, StoredProcedureCall call, Map<String, Object> hints, ClassLoader classLoader, AbstractSession session) {
        // apply any query hints
        DatabaseQuery hintQuery = applyHints(hints, buildResultSetMappingQuery(resultSetMappings, call), classLoader, session);

        // apply any query arguments
        applyArguments(call, hintQuery);

        return hintQuery;
    }

    /**
     * Build a ReadAllQuery from a class and stored procedure call.
     */
    public static DatabaseQuery buildStoredProcedureQuery(Class resultClass, StoredProcedureCall call, Map<String, Object> hints, ClassLoader classLoader, AbstractSession session) {
        DatabaseQuery query = new ReadAllQuery(resultClass);
        query.setCall(call);
        query.setIsUserDefined(true);

        // apply any query hints
        query = applyHints(hints, query, classLoader, session);

        // apply any query arguments
        applyArguments(call, query);

        return query;
    }

    /**
     * Build a DataReadQuery with the stored procedure call given.
     */
    public static DatabaseQuery buildStoredProcedureQuery(StoredProcedureCall call, Map<String, Object> hints, ClassLoader classLoader, AbstractSession session) {
        DataReadQuery query = new DataReadQuery();
        query.setResultType(DataReadQuery.AUTO);

        query.setCall(call);
        query.setIsUserDefined(true);

        // apply any query hints
        DatabaseQuery hintQuery = applyHints(hints, query, classLoader, session);

        // apply any query arguments
        applyArguments(call, hintQuery);

        return hintQuery;
    }

    /**
     * Build a ResultSetMappingQuery from a sql result set mapping name and a
     * stored procedure call.
     */
    public static DatabaseQuery buildStoredProcedureQuery(String sqlResultSetMappingName, StoredProcedureCall call, Map<String, Object> hints, ClassLoader classLoader, AbstractSession session) {
        ResultSetMappingQuery query = new ResultSetMappingQuery();
        query.setSQLResultSetMappingName(sqlResultSetMappingName);
        query.setCall(call);
        query.setIsUserDefined(true);

        // apply any query hints
        DatabaseQuery hintQuery = applyHints(hints, query, classLoader, session);

        // apply any query arguments
        applyArguments(call, hintQuery);

        return hintQuery;
    }

    /**
     * Call this method to close any open connections to the database.
     */
    @Override
    public void close() {
        if (executeCall != null) {
            DatabaseQuery query = executeCall.getQuery();
            AbstractSession session = query.getSession();

            // Release the accessors acquired for the query.
            for (Accessor accessor : query.getAccessors()) {
                session.releaseReadConnection(accessor);
            }

            try {
                if (executeStatement != null) {
                    DatabaseAccessor accessor = (DatabaseAccessor) query.getAccessor();
                    accessor.releaseStatement(executeStatement, query.getSQLString(), executeCall, session);
                }
            } catch (SQLException exception) {
                // Catch the exception and log a message.
                session.log(SessionLog.WARNING, SessionLog.CONNECTION, "exception_caught_closing_statement", exception);
            }
        }

        executeCall = null;
        executeStatement = null;
    }

    /**
     * Returns true if the first result corresponds to a result set, and false
     * if it is an update count or if there are no results other than through
     * INOUT and OUT parameters, if any.
     * @return true if first result corresponds to result set
     * @throws QueryTimeoutException if the query execution exceeds the query
     * timeout value set and only the statement is rolled back
     * @throws PersistenceException if the query execution exceeds the query
     * timeout value set and the transaction is rolled back
     */
    @Override
    public boolean execute() {
        try {
            entityManager.verifyOpen();

            if (! getDatabaseQueryInternal().isResultSetMappingQuery()) {
                throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_execute"));
            }

            getResultSetMappingQuery().setIsExecuteCall(true);
            executeCall = (DatabaseCall) executeReadQuery();
            executeStatement = executeCall.getStatement();

            // Add this query to the entity manager open queries list.
            // The query will be closed in the following cases:
            // Within a transaction:
            //  - on commit
            //  - on rollback
            // Outside of a transaction:
            //  - em close
            // Other safeguards, we will close the query if/when
            //  - we hit the end of the results.
            //  - this query is garbage collected (finalize method)
            //
            // Deferring closing the call avoids having to go through all the
            // results now (and building all the result objects) and things
            // remain on a as needed basis from the statement.
            entityManager.addOpenQuery(this);

            hasMoreResults = executeCall.getExecuteReturnValue();

            // If execute returned false but we have output cursors then return
            // true and build the results from the output cursors.
            if (!hasMoreResults && getCall().hasOutputCursors()) {
                hasMoreResults = true;
                outputCursorIndex = 0;
                isOutputCursorResultSet = true;
            }

            return hasMoreResults;
        } catch (LockTimeoutException exception) {
            throw exception;
        } catch (PersistenceException exception) {
            setRollbackOnly();
            throw exception;
        } catch (IllegalStateException e){
            setRollbackOnly();
            throw e;
        } catch (RuntimeException exception) {
            setRollbackOnly();
            throw new PersistenceException(exception);
        }
    }

    /**
     * Execute an update or delete statement (from a stored procedure query).
     * @return the number of entities updated or deleted
     */
    @Override
    public int executeUpdate() {
        try {
            // Need to throw TransactionRequiredException if there is no active transaction
            entityManager.checkForTransaction(true);

            // Legacy: we could have a data read query or a read all query, so
            // clearly we shouldn't be executing an update on it. As of JPA 2.1
            // API we always create a result set mapping query to interact with
            // a stored procedure.
            // Also if the result set mapping query has result set mappings
            // defined, then it's clearly expecting result sets and we can be
            // preemptive in throwing an exception.
            if (! getDatabaseQueryInternal().isResultSetMappingQuery() || getResultSetMappingQuery().hasResultSetMappings()) {
                throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_execute_update"));
            }

            // If the return value is true indicating a result set then throw an exception.
            if (execute()) {
                if (getActiveSession().getPlatform().isJDBCExecuteCompliant()) {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_execute_update"));
                } else {
                    return getUpdateCount();
                }
            } else {
                return getUpdateCount();
            }
        } catch (LockTimeoutException exception) {
            throw exception;
        } catch (PersistenceException e) {
            setRollbackOnly();
            throw e;
        } catch (IllegalStateException e){
            setRollbackOnly();
            throw e;
        } catch (RuntimeException exception) {
            setRollbackOnly();
            throw new PersistenceException(exception);
        } finally {
            close(); // Close the connection once we're done.
        }
    }

    /**
     * Finalize method in case the query is not closed.
     */
    @Override
    public void finalize() {
        close();
    }

    /**
     * Return the stored procedure call associated with this query.
     */
    protected StoredProcedureCall getCall() {
        return (StoredProcedureCall) getDatabaseQueryInternal().getCall();
    }

    /**
     * Return the internal map of parameters.
     */
    @Override
    protected Map<String, Parameter<?>> getInternalParameters() {
        if (parameters == null) {
            parameters = new HashMap<String, Parameter<?>>();

            int index = 0;

            for (Object parameter : getCall().getParameters()) {
                Integer parameterType = getCall().getParameterTypes().get(index);
                String argumentName = getCall().getProcedureArgumentNames().get(index);

                DatabaseField field = null;

                if (parameterType == DatasourceCall.INOUT) {
                    field = (DatabaseField) ((Object[]) parameter)[0];
                } else if (parameterType == DatasourceCall.IN) {
                    field = (DatabaseField) parameter;
                } else if (parameterType == DatasourceCall.OUT || parameterType == DatasourceCall.OUT_CURSOR) {
                    if (parameter instanceof OutputParameterForCallableStatement) {
                        field = ((OutputParameterForCallableStatement) parameter).getOutputField();
                    } else {
                        field = (DatabaseField) parameter;
                    }
                }

                // If field is not null (one we care about) then add it, otherwise continue.
                if (field != null) {
                    // If the argument name is null then it is a positional parameter.
                    if (argumentName == null) {
                        parameters.put(field.getName(), new ParameterExpressionImpl(null, field.getType(), Integer.parseInt(field.getName())));
                    } else {
                        parameters.put(field.getName(), new ParameterExpressionImpl(null, field.getType(), field.getName()));
                    }
                }

                ++index;
            }
        }

        return parameters;
    }

    /**
     * Used to retrieve the values passed back from the procedure through INOUT
     * and OUT parameters. For portability, all results corresponding to result
     * sets and update counts must be retrieved before the values of output
     * parameters.
     * @param position parameter position
     * @return the result that is passed back through the parameter
     * @throws IllegalArgumentException if the position does not correspond to a
     * parameter of the query or is not an INOUT or OUT parameter
     */
    @Override
    public Object getOutputParameterValue(int position) {
        entityManager.verifyOpen();

        if (isValidCallableStatement()) {
            try {
                Object obj = executeCall.getOutputParameterValue((CallableStatement) executeStatement, position - 1, entityManager.getAbstractSession());

                if (obj instanceof ResultSet) {
                    // If a result set is returned we have to build the objects.
                    return getResultSetMappingQuery().buildObjectsFromRecords(buildResultRecords((ResultSet) obj), ++executeResultSetIndex);
                } else {
                    return obj;
                }
            } catch (Exception exception) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa21_invalid_parameter_position", new Object[] { position, exception.getMessage() }), exception);
            }
        }

        return null;
    }

    /**
     * Used to retrieve the values passed back from the procedure through INOUT
     * and OUT parameters. For portability, all results corresponding to result
     * sets and update counts must be retrieved before the values of output
     * parameters.
     * @param parameterName name of the parameter as registered or specified in
     *        metadata
     * @return the result that is passed back through the parameter
     * @throws IllegalArgumentException if the parameter name does not
     * correspond to a parameter of the query or is not an INOUT or OUT parameter
     */
    @Override
    public Object getOutputParameterValue(String parameterName) {
        entityManager.verifyOpen();

        if (isValidCallableStatement()) {
            try {
                Object obj = executeCall.getOutputParameterValue((CallableStatement) executeStatement, parameterName, entityManager.getAbstractSession());

                if (obj instanceof ResultSet) {
                    // If a result set is returned we have to build the objects.
                    return getResultSetMappingQuery().buildObjectsFromRecords(buildResultRecords((ResultSet) obj), ++executeResultSetIndex);
                }
                return obj;
            } catch (Exception exception) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa21_invalid_parameter_name", new Object[] { parameterName, exception.getMessage() }), exception);
            }
        }

        return null;
    }

    private boolean hasPositionalParameters() {
        for (Parameter parameter: this.getParameters()) {
            if (parameter.getName() != null) {
                return false;
            }
        }
        return true;
    }

    /**
     * Execute the query and return the query results as a List.
     * @return a list of the results
     */
    @Override
    public List getResultList() {
        // bug51411440: need to throw IllegalStateException if query
        // executed on closed em
        this.entityManager.verifyOpenWithSetRollbackOnly();
        try {
            // If there is no execute statement, the user has not called
            // execute and is simply calling getResultList directly on the query.
            if (executeStatement == null) {
                // If it's not a result set mapping query (as of JPA 2.1 we
                // always create a result set mapping query to interact with a
                // stored procedure) then throw an exception.
                if (! getDatabaseQueryInternal().isResultSetMappingQuery()) {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_get_result_list"));
                }

                // If the return value is false indicating no result set then throw an exception.
                if (execute()) {
                    return getResultList();
                } else {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_get_result_list"));
                }
            } else {
                if (hasMoreResults()) {
                    if (isOutputCursorResultSet) {
                        // Return result set list for the current outputCursorIndex.
                        List results = null;
                        if (hasPositionalParameters()) {
                            results = (List) getOutputParameterValue(getCall().getOutputCursors().get(outputCursorIndex++).getIndex() + 1);
                        } else {
                            results = (List) getOutputParameterValue(getCall().getOutputCursors().get(outputCursorIndex++).getName());
                        }

                        // Update the hasMoreResults flag.
                        hasMoreResults = (outputCursorIndex < getCall().getOutputCursors().size());

                        return results;
                    } else {
                        // Build the result records first.
                        List result = buildResultRecords(executeStatement.getResultSet());

                        // Move the result pointer.
                        moveResultPointer();

                        return getResultSetMappingQuery().buildObjectsFromRecords(result, ++executeResultSetIndex);
                    }
                } else {
                    return null;
                }
            }
        } catch (LockTimeoutException e) {
            throw e;
        } catch (PersistenceException e) {
            setRollbackOnly();
            throw e;
        } catch (IllegalStateException e) {
            setRollbackOnly();
            throw e;
        } catch (Exception e) {
            setRollbackOnly();
            throw new PersistenceException(e);
        }
    }

    /**
     * Return the ResultSetMappingQuery for this stored procedure query.
     * NOTE: Methods assumes associated database query is a ResultSetMappingQuery.
     */
    protected ResultSetMappingQuery getResultSetMappingQuery() {
        if (executeCall != null) {
            return (ResultSetMappingQuery) executeCall.getQuery();
        } else {
            return (ResultSetMappingQuery) getDatabaseQuery();
        }
    }

    /**
     * Execute the query and return the single query result.
     * @return a single result object.
     */
    @Override
    public Object getSingleResult() {
        // bug51411440: need to throw IllegalStateException if query
        // executed on closed em
        this.entityManager.verifyOpenWithSetRollbackOnly();
        try {
            // If there is no execute statement, the user has not called
            // execute and is simply calling getSingleResult directly on the query.
            if (executeStatement == null) {
                // If it's not a result set mapping query (as of JPA 2.1 we
                // always create a result set mapping query to interact with a
                // stored procedure) then throw an exception.
                if (! getDatabaseQueryInternal().isResultSetMappingQuery()) {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_get_single_result"));
                }

                // If the return value is true indicating a result set then
                // build and return the single result.
                if (execute()) {
                    return getSingleResult();
                } else {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("incorrect_spq_query_for_get_result_list"));
                }
            } else {
                if (hasMoreResults()) {
                    // Build the result records first.
                    List results;

                    if (isOutputCursorResultSet) {
                        // Return result set list for the current outputCursorIndex.
                        if (hasPositionalParameters()) {
                            results = (List) getOutputParameterValue(getCall().getOutputCursors().get(outputCursorIndex++).getIndex() + 1);
                        } else {
                            results = (List) getOutputParameterValue(getCall().getOutputCursors().get(outputCursorIndex++).getName());
                        }

                        // Update the hasMoreResults flag.
                        hasMoreResults = (outputCursorIndex < getCall().getOutputCursors().size());
                    } else {
                        // Build the result records first.
                        List result = buildResultRecords(executeStatement.getResultSet());

                        // Move the result pointer.
                        moveResultPointer();

                        results = getResultSetMappingQuery().buildObjectsFromRecords(result, ++executeResultSetIndex);
                    }

                    if (results.size() > 1) {
                        throwNonUniqueResultException(ExceptionLocalization.buildMessage("too_many_results_for_get_single_result", null));
                    } else if (results.isEmpty()) {
                        throwNoResultException(ExceptionLocalization.buildMessage("no_entities_retrieved_for_get_single_result", null));
                    }

                    // TODO: if hasMoreResults is true, we 'could' and maybe should throw an exception here.

                    return results.get(0);
                } else {
                    return null;
                }
            }
        } catch (LockTimeoutException e) {
            throw e;
        } catch (PersistenceException e) {
            setRollbackOnly();
            throw e;
        } catch (IllegalStateException e) {
            setRollbackOnly();
            throw e;
        } catch (Exception e) {
            setRollbackOnly();
            throw new PersistenceException(e);
        } finally {
            close(); // Close the connection once we're done.
        }
    }

    /**
     * Returns the update count or -1 if there is no pending result
     * or if the next result is not an update count.
     * @return update count or -1 if there is no pending result or
     * if the next result is not an update count
     * @throws QueryTimeoutException if the query execution exceeds
     * the query timeout value set and only the statement is
     * rolled back
     * @throws PersistenceException if the query execution exceeds
     * the query timeout value set and the transaction
     * is rolled back
     */
    @Override
    public int getUpdateCount() {
        entityManager.verifyOpenWithSetRollbackOnly();

        if (executeStatement != null) {
            try {
                int updateCount = executeStatement.getUpdateCount();

                // Moving the result pointer when -1 is reached doesn't seem
                // to be an issue for the jbdc driver, however as a safeguard,
                // once -1 is reached don't bother trying to move the pointer
                // as there is no need to do so.
                if (updateCount > -1) {
                    moveResultPointer();
                }
                return updateCount;
            } catch (SQLException e) {
                throw getDetailedException(DatabaseException.sqlException(e, executeCall, executeCall.getQuery().getAccessor(), executeCall.getQuery().getSession(), false));
            }
        }

        return -1;
    }

    /**
     * Returns true if the next result corresponds to a result set, and false if
     * it is an update count or if there are no results other than through INOUT
     * and OUT parameters, if any.
     *
     * @return true if next result corresponds to result set
     * @throws QueryTimeoutException if the query execution exceeds the query
     * timeout value set and only the statement is rolled back
     * @throws PersistenceException if the query execution exceeds the query
     * timeout value set and the transaction is rolled back
     */
    @Override
    public boolean hasMoreResults() {
        entityManager.verifyOpen();

        return hasMoreResults;
    }

    /**
     * Returns true if the execute statement for this query is 1) not null (i.e.
     * query has been executed and 2) is an instance of callable statement,
     * meaning there are out parameters associated with it.
     */
    protected boolean isValidCallableStatement() {
        if (executeStatement == null) {
            throw new IllegalStateException(ExceptionLocalization.buildMessage("jpa21_invalid_call_on_un_executed_query"));
        }

        if (! (executeStatement instanceof CallableStatement)) {
            throw new IllegalStateException(ExceptionLocalization.buildMessage("jpa21_invalid_call_with_no_output_parameters"));
        }

        return true;
    }

    /**
     * INTERNAL:
     * Move the pointer up and update our has more results flag.
     * Once there are no result sets left, this will always return false.
     */
    private void moveResultPointer() {
        try {
            hasMoreResults = executeStatement.getMoreResults();
        } catch (SQLException e) {
            // swallow it.
            hasMoreResults = false;
        }
    }

    /**
     * Register a positional parameter. All positional parameters must be
     * registered.
     *
     * @param position parameter position
     * @param type type of the parameter
     * @param mode parameter mode
     * @return the same query instance
     */
    @Override
    public StoredProcedureQuery registerStoredProcedureParameter(int position, Class type, ParameterMode mode) {
        entityManager.verifyOpenWithSetRollbackOnly();
        StoredProcedureCall call = (StoredProcedureCall) getDatabaseQuery().getCall();

        if (mode.equals(ParameterMode.IN)) {
            call.addUnamedArgument(String.valueOf(position), type);
        } else if (mode.equals(ParameterMode.OUT)) {
            call.addUnamedOutputArgument(String.valueOf(position), type);
        } else if (mode.equals(ParameterMode.INOUT)) {
            call.addUnamedInOutputArgument(String.valueOf(position), String.valueOf(position), type);
        } else if (mode.equals(ParameterMode.REF_CURSOR)) {
            call.useUnnamedCursorOutputAsResultSet(position);
        }

        // Force a re-calculate of the parameters.
        this.parameters = null;

        return this;
    }

    /**
     * Register a named parameter. When using parameter names, all parameters
     * must be registered in the order in which they occur in the parameter list
     * of the stored procedure.
     *
     * @param parameterName name of the parameter as registered or
     *        specified in metadata
     * @param type type of the parameter
     * @param mode parameter mode
     * @return the same query instance
     */
    @Override
    public StoredProcedureQuery registerStoredProcedureParameter(String parameterName, Class type, ParameterMode mode) {
        entityManager.verifyOpenWithSetRollbackOnly();
        StoredProcedureCall call = (StoredProcedureCall) getDatabaseQuery().getCall();

        if (mode.equals(ParameterMode.IN)) {
            call.addNamedArgument(parameterName, parameterName, type);
        } else if (mode.equals(ParameterMode.OUT)) {
            call.addNamedOutputArgument(parameterName, parameterName, type);
        } else if (mode.equals(ParameterMode.INOUT)) {
            call.addNamedInOutputArgument(parameterName, parameterName, parameterName, type);
        } else if (mode.equals(ParameterMode.REF_CURSOR)) {
            call.useNamedCursorOutputAsResultSet(parameterName);
        }

        // Force a re-calculate of the parameters.
        this.parameters = null;

        return this;
    }

    /**
     * Set the position of the first result to retrieve.
     *
     * @param startPosition
     *            position of the first result, numbered from 0
     * @return the same query instance
     */
    @Override
    public StoredProcedureQueryImpl setFirstResult(int startPosition) {
        throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_not_supported", new Object[]{"setFirstResult", "StoredProcedureQuery"}));
    }

    /**
     * Set the flush mode type to be used for the query execution.
     * The flush mode type applies to the query regardless of the
     * flush mode type in use for the entity manager.
     * @param flushMode flush mode
     * @return the same query instance
     */
    @Override
    public StoredProcedureQueryImpl setFlushMode(FlushModeType flushMode) {
        return (StoredProcedureQueryImpl) super.setFlushMode(flushMode);
    }

    /**
     * Set a query property or hint. The hints elements may be used to specify
     * query properties and hints. Properties defined by this specification must
     * be observed by the provider. Vendor-specific hints that are not
     * recognized by a provider must be silently ignored. Portable applications
     * should not rely on the standard timeout hint. Depending on the database
     * in use, this hint may or may not be observed.
     *
     * @param hintName name of the property or hint
     * @param value value for the property or hint
     * @return the same query instance
     * @throws IllegalArgumentException if the second argument is not valid for
     * the implementation
     */
    @Override
    public StoredProcedureQuery setHint(String hintName, Object value) {
        try {
            entityManager.verifyOpen();
            setHintInternal(hintName, value);
            return this;
        } catch (RuntimeException e) {
            setRollbackOnly();
            throw e;
        }
    }

    /**
     * Set the lock mode type to be used for the query execution.
     *
     * @throws IllegalStateException
     *             if not a Java Persistence query language SELECT query
     */
    @Override
    public StoredProcedureQueryImpl setLockMode(LockModeType lockMode) {
        return (StoredProcedureQueryImpl) super.setLockMode(lockMode);
    }

    /**
     * Set the maximum number of results to retrieve.
     *
     * @return the same query instance
     */
    @Override
    public StoredProcedureQueryImpl setMaxResults(int maxResult) {
        throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_not_supported", new Object[]{"setMaxResults", "StoredProcedureQuery"}));
    }

    /**
     * Bind an instance of java.util.Calendar to a positional parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if position does not correspond to a
     * positional parameter of the query or if the value argument is of
     * incorrect type
     */
    @Override
    public StoredProcedureQuery setParameter(int position, Calendar value, TemporalType temporalType) {
        entityManager.verifyOpenWithSetRollbackOnly();
        return setParameter(position, convertTemporalType(value, temporalType));
    }

    /**
     * Bind an instance of java.util.Date to a positional parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if position does not correspond to a
     * positional parameter of the query or if the value argument is of
     * incorrect type
     */
    @Override
    public StoredProcedureQuery setParameter(int position, Date value, TemporalType temporalType) {
        entityManager.verifyOpenWithSetRollbackOnly();
        return setParameter(position, convertTemporalType(value, temporalType));
    }

    /**
     * Bind an argument to a positional parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if position does not correspond to a
     * positional parameter of the query or if the argument is of incorrect type
     */
    @Override
    public StoredProcedureQuery setParameter(int position, Object value) {
        try {
            entityManager.verifyOpen();
            setParameterInternal(position, value);
            return this;
        } catch (RuntimeException e) {
            setRollbackOnly();
            throw e;
        }
    }

    /**
     * Bind an instance of java.util.Calendar to a Parameter object.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter does not correspond to
     * a parameter of the query
     */
    @Override
    public StoredProcedureQuery setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType) {
        if (param == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NULL_PARAMETER_PASSED_TO_SET_PARAMETER"));
        }
        //bug 402686: type validation
        String position = getParameterId(param);
        ParameterExpressionImpl parameter = (ParameterExpressionImpl) this.getInternalParameters().get(position);
        if (parameter == null ) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NO_PARAMETER_WITH_NAME", new Object[] { param.toString(), this.databaseQuery }));
        }
        if (!parameter.getParameterType().equals(param.getParameterType())) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("INCORRECT_PARAMETER_TYPE", new Object[] { position, param.getParameterType() }));
        }
        return this.setParameter(position, value, temporalType);
    }

    /**
     * Bind an instance of java.util.Date to a Parameter object.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter does not correspond to
     * a parameter of the query
     */
    @Override
    public StoredProcedureQuery setParameter(Parameter<Date> param, Date value, TemporalType temporalType) {
        if (param == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NULL_PARAMETER_PASSED_TO_SET_PARAMETER"));
        }
        //bug 402686: type validation
        String position = getParameterId(param);
        ParameterExpressionImpl parameter = (ParameterExpressionImpl) this.getInternalParameters().get(position);
        if (parameter == null ) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NO_PARAMETER_WITH_NAME", new Object[] { param.toString(), this.databaseQuery }));
        }
        if (!parameter.getParameterType().equals(param.getParameterType())) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("INCORRECT_PARAMETER_TYPE", new Object[] { position, param.getParameterType() }));
        }
        return this.setParameter(position, value, temporalType);
    }

    /**
     * Bind the value of a Parameter object.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter does not correspond to
     * a parameter of the query
     */
    @Override
    public <T> StoredProcedureQuery setParameter(Parameter<T> param, T value) {
        if (param == null) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NULL_PARAMETER_PASSED_TO_SET_PARAMETER"));
        }
        //bug 402686: type validation
        String position = getParameterId(param);
        ParameterExpressionImpl parameter = (ParameterExpressionImpl) this.getInternalParameters().get(position);
        if (parameter == null ) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NO_PARAMETER_WITH_NAME", new Object[] { param.toString(), this.databaseQuery }));
        }
        if (!parameter.getParameterType().equals(param.getParameterType())) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("INCORRECT_PARAMETER_TYPE", new Object[] { position, param.getParameterType() }));
        }
        return this.setParameter(position, value);
    }

    /**
     * Bind an instance of java.util.Calendar to a named parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter name does not
     * correspond to a parameter of the query or if the value argument is of
     * incorrect type
     */
    @Override
    public StoredProcedureQuery setParameter(String name, Calendar value, TemporalType temporalType) {
        entityManager.verifyOpenWithSetRollbackOnly();
        return setParameter(name, convertTemporalType(value, temporalType));
    }

    /**
     * Bind an instance of java.util.Date to a named parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter name does not
     * correspond to a parameter of the query or if the value argument is of
     * incorrect type
     */
    @Override
    public StoredProcedureQuery setParameter(String name, Date value, TemporalType temporalType) {
        entityManager.verifyOpenWithSetRollbackOnly();
        return setParameter(name, convertTemporalType(value, temporalType));
    }

    /**
     * Bind an argument to a named parameter.
     *
     * @return the same query instance
     * @throws IllegalArgumentException if the parameter name does not
     * correspond to a parameter of the query or if the argument is of incorrect
     * type
     */
    @Override
    public StoredProcedureQuery setParameter(String name, Object value) {
        try {
            entityManager.verifyOpen();
            setParameterInternal(name, value, false);
            return this;
        } catch (RuntimeException e) {
            setRollbackOnly();
            throw e;
        }
    }

    /**
     * Bind an argument to a named or indexed parameter.
     *
     * @param name
     *            the parameter name
     * @param value
     *            to bind
     * @param isIndex
     *            defines if index or named
     */
    @Override
    protected void setParameterInternal(String name, Object value, boolean isIndex) {
        Parameter<?> parameter = this.getInternalParameters().get(name);
        StoredProcedureCall call = (StoredProcedureCall) getDatabaseQuery().getCall();
        if (parameter == null) {
            if (isIndex) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-argument-index", new Object[] { name, call.getProcedureName() }));
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-argument-name", new Object[] { name, call.getProcedureName() }));
            }
        }
        if (!isValidActualParameter(value, parameter.getParameterType())) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object[] { name, value.getClass(), parameter.getParameterType(), call.getProcedureName() }));
        }
        this.parameterValues.put(name, value);
    }
}

