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

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     05/24/2011-2.3 Guy Pelletier
//       - 345962: Join fetch query when using tenant discriminator column fails.
//     02/08/2012-2.4 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/27/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
package org.eclipse.persistence.internal.databaseaccess;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.expressions.ParameterExpression;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.queries.CallQueryMechanism;
import org.eclipse.persistence.internal.queries.DatabaseQueryMechanism;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDataTypeDescriptor;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ModifyQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.sessions.DatabaseRecord;

/**
 * INTERNAL:
 * <b>Purpose</b>: Used as an abstraction of a database invocation.
 * A call is an SQL string or procedure call with parameters.
 */
public abstract class DatabaseCall extends DatasourceCall {
    /**
     * JPA 2.1 NamedStoredProcedureQuery execute API implementation.
     */
    protected boolean executeReturnValue;

    /**
     * Following fields are used to bind MaxResults and FirstRow settings into
     * the query instead of using the values stored in the call.
     */
    public static final DatabaseField MAXROW_FIELD = new DatabaseField("EclipseLink-MaxResults");
    public static final DatabaseField FIRSTRESULT_FIELD = new DatabaseField("EclipseLink-FirstRow");

    /**
     * Indicates if the FirstRow value in this call object is to be ignored. If
     * true, it should mean it has been built into the SQL statement directly
     * ex: using Oracle Rownum support
     */
    protected boolean ignoreFirstRowSetting;

    /**
     * Indicates if the MaxResults value in this call object is to be ignored.
     * If true, it should mean it has been built into the SQL statement directly
     * ex: using Oracle Rownum support
     */
    protected boolean ignoreMaxResultsSetting;

    // The result and statement are cached for cursor selects.
    transient protected Statement statement;
    transient protected ResultSet result;

    // The call may specify that its parameters should be bound.
    protected Boolean usesBinding;

    // Bound calls can use prepared statement caching.
    protected Boolean shouldCacheStatement;

    // The returned fields.
    transient protected Vector fields;
    // PERF: fields array
    transient protected DatabaseField[] fieldsArray;

    // Field matching is required for custom SQL when the fields order is not known.
    protected boolean isFieldMatchingRequired;

    // optimistic locking determination is required for batch writing
    protected boolean hasOptimisticLock;
    protected boolean isResultSetScrollable;

    // JDK 1.2 supports initial fetch size for the result set.
    protected int resultSetFetchSize;

    // JDK 1.2 supports various types of results set
    protected int resultSetType;

    // JDK 1.2 supports various types of concurrency on results set
    protected int resultSetConcurrency;

    //query timeout limit in seconds
    protected int queryTimeout;

    //query timeout unit
    protected TimeUnit queryTimeoutUnit;

    //max rows returned in the result set by the call
    protected int maxRows;

    //firstResult set into the result set by the call
    protected int firstResult;

    //contain field - value pairs for LOB fields used to the
    //streaming operation during the writing (to the table)
    private transient AbstractRecord contexts;

    /** Allow for a single cursored output parameter. */
    protected boolean isCursorOutputProcedure;

    /** Allow for multiple cursored output parameter. */
    protected boolean isMultipleCursorOutputProcedure;

    // This parameter is here to determine if we should expect a ResultSet back from the call
    // We need to know this information in order to call the correct JDBC API
    protected Boolean returnsResultSet;

    // Whether the call has to build output row
    protected boolean shouldBuildOutputRow;

    // Callable statement is required if there is an output parameter
    protected boolean isCallableStatementRequired;

    /** Support multiple result sets. */
    protected boolean hasMultipleResultSets;

    /**
     * Support returning multiple results sets instead of just one list, i.e.
     * support multiple results set mappings.
     */
    protected boolean returnMultipleResultSetCollections;

    /** The SQL string to execute. */
    protected String sqlString;

    /** Indicates whether the call has allocated connection. May be set if the call has not finished */
    protected boolean hasAllocatedConnection;

    /**
     * Define if this query is compatible with batch writing.
     * Some queries, such as DDL are not compatible.
     */
    protected boolean isBatchExecutionSupported;

    /**
     * Keep a list of the output cursors.
     */
    protected List<DatabaseField> outputCursors;

    protected DatabaseCall() {
        super.shouldProcessTokenInQuotes = false;
        this.usesBinding = null;
        this.shouldCacheStatement = null;
        this.isFieldMatchingRequired = false;
        this.queryTimeout = 0;
        this.queryTimeoutUnit = null;
        this.maxRows = 0;
        this.resultSetFetchSize = 0;
        this.isCursorOutputProcedure = false;
        this.shouldBuildOutputRow = false;
        this.returnsResultSet = null;
        this.isBatchExecutionSupported = true;
    }

    /**
     * Return if the call returns multiple result sets.
     */
    public boolean hasMultipleResultSets() {
        return hasMultipleResultSets;
    }

    /**
     * Set if the call returns multiple result sets.
     */
    public void setHasMultipleResultSets(boolean hasMultipleResultSets) {
        this.hasMultipleResultSets = hasMultipleResultSets;
    }

    /**
     * INTERNAL:
     */
    public void appendIn(Object inObject) {
        getParameters().add(inObject);
        getParameterTypes().add(IN);
    }

    /**
     * INTERNAL:
     */
    public void appendInOut(DatabaseField inoutField) {
        Object[] inOut = { inoutField, inoutField };
        getParameters().add(inOut);
        getParameterTypes().add(INOUT);
    }

    /**
     * INTERNAL:
     */
    public void appendInOut(Object inValueOrField, DatabaseField outField) {
        Object[] inOut = { inValueOrField, outField };
        getParameters().add(inOut);
        getParameterTypes().add(INOUT);
    }

    /**
     * INTERNAL:
     */
    public void appendOut(DatabaseField outField) {
        getParameters().add(outField);
        getParameterTypes().add(OUT);
    }

    /**
     * INTERNAL:
     */
    public void appendOutCursor(DatabaseField outField) {
        getParameters().add(outField);
        getParameterTypes().add(OUT_CURSOR);
        getOutputCursors().add(outField);
    }

    /**
     * Add the parameter.
     * If using binding bind the parameter otherwise let the platform print it.
     * The platform may also decide to bind the value.
     */
    @Override
    public void appendParameter(Writer writer, Object parameter, AbstractSession session) {
        if (Boolean.TRUE.equals(usesBinding)) {
            bindParameter(writer, parameter);
        } else {
            session.getPlatform().appendParameter(this, writer, parameter);
        }
    }

    /**
     * Bind the parameter. Binding is determined by the call and second the platform.
     */
    public void bindParameter(Writer writer, Object parameter) {
        if (parameter instanceof Collection) {
            throw QueryException.inCannotBeParameterized(getQuery());
        }

        try {
            writer.write("?");
        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }
        getParameters().add(parameter);
    }

    /**
     * Return the appropriate mechanism,
     * with the call added as necessary.
     */
    @Override
    public DatabaseQueryMechanism buildNewQueryMechanism(DatabaseQuery query) {
        return new CallQueryMechanism(query, this);
    }

    /**
     * INTERNAL:
     * Return Record containing output fields and values.
     * Called only if shouldBuildOutputRow method returns true.
     */
    public AbstractRecord buildOutputRow(CallableStatement statement, DatabaseAccessor accessor, AbstractSession session) throws SQLException {
        AbstractRecord row = new DatabaseRecord();
        int size = this.parameters.size();
        for (int index = 0; index < size; index++) {
            Object parameter = this.parameters.get(index);
            if (parameter instanceof OutputParameterForCallableStatement) {
                OutputParameterForCallableStatement outParameter = (OutputParameterForCallableStatement)parameter;
                if (!outParameter.isCursor() || !isCursorOutputProcedure()) {
                    Object value = getOutputParameterValue(statement, index, session);
                    DatabaseField field = outParameter.getOutputField();
                    if (value instanceof Struct){
                        ClassDescriptor descriptor = session.getDescriptor(field.getType());
                        if ((descriptor != null) && descriptor.isObjectRelationalDataTypeDescriptor()) {
                            AbstractRecord nestedRow = ((ObjectRelationalDataTypeDescriptor)descriptor).buildRowFromStructure((Struct)value);
                            ReadObjectQuery query = new ReadObjectQuery();
                            query.setSession(session);
                            value = descriptor.getObjectBuilder().buildNewInstance();
                            descriptor.getObjectBuilder().buildAttributesIntoObject(value, null, nestedRow, query, null, null, false, this.getQuery().getSession());
                        }
                    } else if ((value instanceof Array) && (field.isObjectRelationalDatabaseField())) {
                        value = ObjectRelationalDataTypeDescriptor.buildContainerFromArray((Array)value, (ObjectRelationalDatabaseField)field, session);
                    } else if (value instanceof ResultSet) {
                        // Support multiple out cursors, put list of records in row.
                        ResultSet resultSet = (ResultSet)value;
                        setFields(null);
                        matchFieldOrder(resultSet, accessor, session);
                        value = accessor.processResultSet(resultSet, this, statement, session);
                    }
                    row.put(field, value);
                }
            }
        }

        return row;
    }

    /**
     * Return the appropriate mechanism,
     * with the call added as necessary.
     */
    @Override
    public DatabaseQueryMechanism buildQueryMechanism(DatabaseQuery query, DatabaseQueryMechanism mechanism) {
        if (mechanism.isCallQueryMechanism() && (mechanism instanceof CallQueryMechanism)) {
            // Must also add the call singleton...
            CallQueryMechanism callMechanism = ((CallQueryMechanism)mechanism);
            if (!callMechanism.hasMultipleCalls()) {
                callMechanism.addCall(callMechanism.getCall());
                callMechanism.setCall(null);
            }
            callMechanism.addCall(this);
            return mechanism;
        } else {
            return buildNewQueryMechanism(query);
        }
    }

    /**
     * INTERNAL:
     * Returns INOUT parameter. The first parameter is value to pass in, the second DatabaseField for out.
     */
    @Override
    protected Object createInOutParameter(Object inValue, Object outParameter, AbstractSession session) {
        if (outParameter instanceof OutputParameterForCallableStatement) {
            return new InOutputParameterForCallableStatement(inValue, (OutputParameterForCallableStatement)outParameter);
        }
        if (outParameter instanceof DatabaseField) {
            return new InOutputParameterForCallableStatement(inValue, (DatabaseField)outParameter, session);
        }

        //should never happen
        return null;
    }

    /**
     * INTERNAL:
     * Return the SQL string for the call.
     */
    public String getCallString() {
        return getSQLString();
    }

    /**
     * The fields expected by the calls result set.
     * null means that the fields are unknown and should be built from the result set.
     */
    public Vector getFields() {
        return fields;
    }

    /**
     * INTERNAL:
     * The array of fields returned by the call.
     */
    public DatabaseField[] getFieldsArray() {
        return fieldsArray;
    }

    /**
     * INTERNAL:
     * Unfortunately can't avoid referencing query and descriptor:
     * the call should be performed after the translateCustomSQL (in SQLCall)
     * in the middle of prepare method (no parameter available earlier).
     *
     */
    protected DatabaseField getFieldWithTypeFromDescriptor(DatabaseField outField) {
        if (getQuery().getDescriptor() != null) {
            return getQuery().getDescriptor().getTypedField(outField);
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Return 1-based index of out cursor parameter, or -1.
     */
    public int getCursorOutIndex() {
        int size = getParameters().size();
        for (int i = 0; i < size; i++) {
            Object parameter = this.parameters.get(i);
            if (parameter instanceof OutputParameterForCallableStatement) {
                if (((OutputParameterForCallableStatement)parameter).isCursor()) {
                    return i + 1;
                }
            }
        }
        return -1;
    }

    /**
     * After an execute call the return value can be retrieved here.
     */
    public boolean getExecuteReturnValue() {
        return executeReturnValue;
    }

    /**
     * get first result
     */
    public int getFirstResult() {
        return this.firstResult;
    }

    /**
     * Return the SQL string for logging purposes.
     */
    @Override
    public String getLogString(Accessor accessor) {
        if (hasParameters()) {
            StringWriter writer = new StringWriter();
            writer.write(getSQLString());
            writer.write(Helper.cr());
            if (hasParameters()) {
                AbstractSession session = null;
                if (getQuery() != null) {
                    session = getQuery().getSession();
                }
                appendLogParameters(getParameters(), accessor, writer, session);
            }
            return writer.toString();
        } else {
            return getSQLString();
        }
    }

    /**
     * Print the parameters to the write for logging purposes.
     */
    public static void appendLogParameters(Collection parameters, Accessor accessor, StringWriter writer, AbstractSession session) {
        writer.write("\tbind => [");

        if (session == null || session.shouldDisplayData()) {
            for (Iterator paramsEnum = parameters.iterator(); paramsEnum.hasNext();) {
                Object parameter = paramsEnum.next();
                if (parameter instanceof DatabaseField) {
                    writer.write("null");
                } else {
                    if (session != null) {
                        parameter = session.getPlatform().convertToDatabaseType(parameter);
                    }
                    writer.write(String.valueOf(parameter));
                }
                if (paramsEnum.hasNext()) {
                    writer.write(", ");
                } else {
                    writer.write("]");
                }
            }
        } else {
            String parameterString = parameters.size() == 1 ? " parameter" : " parameters";
            writer.write(parameters.size() + parameterString + " bound]");
        }
    }

    /**
     * get max rows returned from the call
     */
    public int getMaxRows() {
        return this.maxRows;
    }

    /**
     * INTERNAL
     * Returns the fields to be used in output row.
     */
    public Vector getOutputRowFields() {
        Vector fields = new Vector();
        int size = getParameters().size();
        for (int i = 0; i < size; i++) {
            Integer parameterType = this.parameterTypes.get(i);
            Object parameter = this.parameters.get(i);
            if (parameterType == OUT) {
                fields.add(parameter);
            } else if (parameterType == INOUT) {
                fields.add(((Object[])parameter)[1]);
            }
        }
        return fields;
    }

    /**
     * INTERNAL:
     * Return the output cursors for this stored procedure call.
     */
    public List<DatabaseField> getOutputCursors() {
        if (outputCursors == null) {
            outputCursors = new ArrayList<>();
        }

        return outputCursors;
    }

    /**
     * INTERNAL:
     * Return the query string (SQL) of the call.
     */
    @Override
    public String getQueryString() {
        return getSQLString();
    }

    /**
     * Get timeout limit from the call
     */
    public int getQueryTimeout() {
        return this.queryTimeout;
    }

    /**
     * The result set is stored for the return value of cursor selects.
     */
    public ResultSet getResult() {
        return result;
    }

    /**
     * ADVANCED:
     * This method returns a value that represents if the customer has set whether or not EclipseLink should expect
     * the stored procedure to returning a JDBC ResultSet.  The result of the method corresponds
     * to false, true.
     */
    public boolean getReturnsResultSet() {
        if (returnsResultSet == null) {
            return !shouldBuildOutputRow();
        } else {
            return returnsResultSet;
        }
    }

    public int getResultSetConcurrency() {
        return resultSetConcurrency;
    }

    public int getResultSetFetchSize() {
        return resultSetFetchSize;
    }

    public int getResultSetType() {
        return resultSetType;
    }

    /**
     * Return the SQL string that will be executed.
     */
    public String getSQLString() {
        return sqlString;
    }

    /**
     * The statement is stored for the return value of cursor selects.
     */
    public Statement getStatement() {
        return statement;
    }

    /**
     * This check is needed only when doing batch writing.
     */
    public boolean hasOptimisticLock() {
        return hasOptimisticLock;
    }

    /**
     * Return true if there are output cursors on this call.
     */
    public boolean hasOutputCursors() {
        return outputCursors != null && ! outputCursors.isEmpty();
    }

    /**
     * Callable statement is required if there is an output parameter.
     */
    protected boolean isCallableStatementRequired() {
        return isCallableStatementRequired;
    }

    /**
     * Return if the call is dynamic SQL call.
     * This means the call has no parameters, is not using binding,
     * is not a stored procedure (CallableStatement), or cursor.
     * This means that a Statement, not a PreparedStatement will be used for the call.
     */
    protected boolean isDynamicCall(AbstractSession session) {
        return DatabaseAccessor.shouldUseDynamicStatements && (!usesBinding(session)) && (!isResultSetScrollable()) && (!hasParameters());
    }

    /**
     * Used for Oracle result sets through procedures.
     */
    public boolean isCursorOutputProcedure() {
        return isCursorOutputProcedure;
    }

    /**
     * The return type is one of, NoReturn, ReturnOneRow or ReturnManyRows.
     */
    @Override
    public boolean isCursorReturned() {
        return this.returnType == RETURN_CURSOR;
    }

    /**
     * Return if field matching is required.
     * Field matching is required for custom SQL statements where the result set field order is not known.
     */
    public boolean isFieldMatchingRequired() {
        return isFieldMatchingRequired;
    }

    /**
     * Return whether all the results of the call have been returned.
     */
    @Override
    public boolean isFinished() {
        return !isCursorReturned() && !isExecuteUpdate();
    }

    /**
     * Used for Oracle result sets through procedures.
     */
    public boolean isMultipleCursorOutputProcedure() {
        return this.isMultipleCursorOutputProcedure;
    }

    /**
     * Return true for procedures with any output (or in/out) parameters and no cursors
     */
    public boolean isNonCursorOutputProcedure() {
        return !isCursorOutputProcedure() && shouldBuildOutputRow();
    }

    public boolean isResultSetScrollable() {
        return isResultSetScrollable;
    }

    /**
     * Allow for the field order to be matched if required.
     * This is required for custom SQL.
     */
    public void matchFieldOrder(ResultSet resultSet, DatabaseAccessor accessor, AbstractSession session) {
        if ((getFields() != null) && (!isFieldMatchingRequired())) {
            return;
        }
        setFields(accessor.buildSortedFields(getFields(), resultSet, session));
    }

    /**
     * INTERNAL:
     * Allow pre-printing of the SQL string for fully bound calls, to save from reprinting.
     * Should be called before translation.
     */
    @Override
    public void prepare(AbstractSession session) {
        if (this.isPrepared) {
            return;
        }
        prepareInternal(session);
        this.isPrepared = true;
    }

    /**
     * INTERNAL:
     * Called by prepare method only. May be overridden.
     */
    protected void prepareInternal(AbstractSession session) {
        prepareInternalParameters(session);
    }

    /**
     * INTERNAL:
     * Called by prepareInternal method only. May be overridden.
     */
    protected void prepareInternalParameters(AbstractSession session) {
        if (isCursorOutputProcedure()) {
            // 1. If there are no OUT_CURSOR parameters - change the first OUT to OUT_CURSOR;
            // 2. If there are multiple OUT_CURSOR parameters - throw Validation exception
            int nFirstOutParameterIndex = -1;
            boolean hasFoundOutCursor = false;
            int size = this.parameters.size();
            for (int index = 0; index < size; index++) {
                Integer parameterType = this.parameterTypes.get(index);
                if (parameterType == DatasourceCall.OUT_CURSOR) {
                    if (hasFoundOutCursor) {
                        // one cursor has been already found
                        throw ValidationException.multipleCursorsNotSupported(toString());
                    } else {
                        hasFoundOutCursor = true;
                    }
                } else if (parameterType == DatasourceCall.OUT) {
                    if (nFirstOutParameterIndex == -1) {
                        nFirstOutParameterIndex = index;
                    }
                } else if (parameterType == null) {
                    // setCustomSQLArgumentType method was called when custom SQL is not used
                    throw ValidationException.wrongUsageOfSetCustomArgumentTypeMethod(toString());
                }
            }
            if (!hasFoundOutCursor && (nFirstOutParameterIndex >= 0)) {
                this.parameterTypes.set(nFirstOutParameterIndex, DatasourceCall.OUT_CURSOR);
            }
        }

        int size = getParameters().size();
        for (int i = 0; i < size; i++) {
            Object parameter = this.parameters.get(i);
            Integer parameterType = this.parameterTypes.get(i);
            if (parameterType == MODIFY) {
                // in case the field's type is not set, the parameter type is set to CUSTOM_MODIFY.
                DatabaseField field = (DatabaseField)parameter;
                if ((field.getType() == null) || session.getPlatform().shouldUseCustomModifyForCall(field)) {
                    this.parameterTypes.set(i, CUSTOM_MODIFY);
                }
            } else if (parameterType == INOUT) {
                // In case there is a type in outField, outParameter is created.
                // During translate call, either outParameter or outField is used for
                // creating inOut parameter.
                setShouldBuildOutputRow(true);
                setIsCallableStatementRequired(true);
                DatabaseField outField = (DatabaseField)((Object[])parameter)[1];
                if (outField.getType() == null) {
                    DatabaseField typeOutField = getFieldWithTypeFromDescriptor(outField);
                    if (typeOutField != null) {
                        outField = typeOutField.clone();
                    }
                }
                if (outField.getType() != null) {
                    // outParameter contains all the info for registerOutputParameter call.
                    OutputParameterForCallableStatement outParameter = new OutputParameterForCallableStatement(outField, session);
                    ((Object[])parameter)[1] = outParameter;
                }
            } else if ((parameterType == OUT) || (parameterType == OUT_CURSOR)) {
                boolean isCursor = parameterType == OUT_CURSOR;
                if (!isCursor) {
                    setShouldBuildOutputRow(true);
                }
                setIsCallableStatementRequired(true);
                DatabaseField outField = (DatabaseField)parameter;
                if (outField.getType() == null) {
                    DatabaseField typeOutField = getFieldWithTypeFromDescriptor(outField);
                    if (typeOutField != null) {
                        outField = typeOutField.clone();
                    }
                }

                // outParameter contains all the info for registerOutputParameter call.
                OutputParameterForCallableStatement outParameter = new OutputParameterForCallableStatement(outField, session, isCursor);
                this.parameters.set(i, outParameter);
                this.parameterTypes.set(i, parameterType);
            }
        }
        if (this.returnsResultSet == null) {
            setReturnsResultSet(!isCallableStatementRequired());
        }
        // if there is nothing returned and we are not using optimistic locking then batch
        //if it is a StoredProcedure with in/out or out parameters then do not batch
        //logic may be weird but we must not batch if we are not using JDBC batchwriting and we have parameters
        // we may want to refactor this some day
        this.isBatchExecutionSupported = (isNothingReturned()
                && (!hasOptimisticLock() || session.getPlatform().canBatchWriteWithOptimisticLocking(this))
                && (!shouldBuildOutputRow())
                && (session.getPlatform().usesJDBCBatchWriting() || (!hasParameters()))
                && (!isLOBLocatorNeeded()))
                && (getQuery().isModifyQuery() && ((ModifyQuery)getQuery()).isBatchExecutionSupported());
    }

    /**
     * INTERNAL:
     * Prepare the JDBC statement, this may be parameterize or a call statement.
     * If caching statements this must check for the pre-prepared statement and re-bind to it.
     */
    public Statement prepareStatement(DatabaseAccessor accessor, AbstractRecord translationRow, AbstractSession session) throws SQLException {
        //#Bug5200836 pass shouldUnwrapConnection flag to indicate whether or not using unwrapped connection.
        Statement statement = accessor.prepareStatement(this, session);

        // Setup the max rows returned and query timeout limit.
        if (this.queryTimeout > 0 && this.queryTimeoutUnit != null) {
            long timeout = TimeUnit.SECONDS.convert(this.queryTimeout, this.queryTimeoutUnit);

            if(timeout > Integer.MAX_VALUE){
                timeout = Integer.MAX_VALUE;
            }

            //Round up the timeout if SECONDS are larger than the given units
            if(TimeUnit.SECONDS.compareTo(this.queryTimeoutUnit) > 0 && this.queryTimeout % 1000 > 0){
                timeout += 1;
            }
            statement.setQueryTimeout((int)timeout);
        }
        if (!this.ignoreMaxResultsSetting && this.maxRows > 0) {
            statement.setMaxRows(this.maxRows);
        }
        if (this.resultSetFetchSize > 0) {
            statement.setFetchSize(this.resultSetFetchSize);
        }

        if (this.parameters == null) {
            return statement;
        }
        List parameters = getParameters();
        int size = parameters.size();
        for (int index = 0; index < size; index++) {
            session.getPlatform().setParameterValueInDatabaseCall(parameters.get(index), (PreparedStatement)statement, index+1, session);
        }

        return statement;
    }

    /**
     * Return true if the multiple results 'lists' should be returned.
     */
    public boolean returnMultipleResultSetCollections() {
        return returnMultipleResultSetCollections;
    }

    /**
     * The fields expected by the calls result set.
     */
    public void setFields(Vector fields) {
        this.fields = fields;
        if (fields != null) {
            int size = fields.size();
            this.fieldsArray = new DatabaseField[size];
            for (int index = 0; index < size; index++) {
                this.fieldsArray[index] = (DatabaseField)fields.get(index);
            }
        } else {
            this.fieldsArray = null;
        }
    }

    /**
     * The firstResult set on the result set
     */
    public void setFirstResult(int firstResult) {
        this.firstResult = firstResult;
    }

    /**
     * This check is needed only when doing batch writing and we hit on optimistic locking.
     */
    public void setHasOptimisticLock(boolean hasOptimisticLock) {
        this.hasOptimisticLock = hasOptimisticLock;
    }

    /**
     * INTERNAL:
     * Sets the ignoreFirstRowSetting flag. If true, FirstResult option are
     * assumed built into the SQL string and ignored if set in the call, and
     * instead are added as query arguments.
     * Default is false.
     */
    public void setIgnoreFirstRowSetting(boolean ignoreFirstRowSetting){
        this.ignoreFirstRowSetting = ignoreFirstRowSetting;
    }

    /**
     * INTERNAL:
     * Sets the ignoreMaxResultsSetting flag. If true, MaxRows option are
     * assumed built into the SQL string and ignored if set in the call, and
     * instead are added as query arguments.
     * Default is false.
     */
    public void setIgnoreMaxResultsSetting(boolean ignoreMaxResultsSetting){
        this.ignoreMaxResultsSetting = ignoreMaxResultsSetting;
    }

    /**
     * Callable statement is required if there is an output parameter.
     */
    protected void setIsCallableStatementRequired(boolean isCallableStatementRequired) {
        this.isCallableStatementRequired = isCallableStatementRequired;
    }

    /**
     * Used for Oracle result sets through procedures.
     */
    public void setIsCursorOutputProcedure(boolean isCursorOutputProcedure) {
        this.isCursorOutputProcedure = isCursorOutputProcedure;
    }

    /**
     * Field matching is required for custom SQL statements where the result set field order is not known.
     */
    public void setIsFieldMatchingRequired(boolean isFieldMatchingRequired) {
        this.isFieldMatchingRequired = isFieldMatchingRequired;
    }

    /**
     * Used for Oracle result sets through procedures.
     */
    public void setIsMultipleCursorOutputProcedure(boolean isMultipleCursorOutputProcedure) {
        this.isMultipleCursorOutputProcedure = isMultipleCursorOutputProcedure;
    }

    public void setIsResultSetScrollable(boolean isResultSetScrollable) {
        this.isResultSetScrollable = isResultSetScrollable;
    }

    /**
     * set query max returned row size to the JDBC Statement
     */
    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    /**
     * INTERNAL:
     * Set the query string (SQL) of the call.
     */
    @Override
    public void setQueryString(String queryString) {
        setSQLStringInternal(queryString);
    }

    /**
     * set query timeout limit to the JDBC Statement
     */
    public void setQueryTimeout(int queryTimeout) {
        this.queryTimeout = queryTimeout;
    }

    /**
     * set query timeout limit unit to the JDBC Statement
     */
    public void setQueryTimeoutUnit(TimeUnit queryTimeoutUnit) {
        this.queryTimeoutUnit = queryTimeoutUnit;
    }

    /**
     * The result set is stored for the return value of cursor selects.
     */
    public void setResult(ResultSet result) {
        this.result = result;
    }

    public void setResultSetConcurrency(int resultSetConcurrency) {
        this.resultSetConcurrency = resultSetConcurrency;
    }

    /**
     * INTERNAL:
     * Set the SQL string.
     */
    protected void setSQLStringInternal(String sqlString) {
        this.sqlString = sqlString;
    }

    public void setResultSetFetchSize(int resultSetFetchSize) {
        this.resultSetFetchSize = resultSetFetchSize;
    }

    public void setResultSetType(int resultSetType) {
        this.resultSetType = resultSetType;
    }

    /**
     * PUBLIC:
     * Use this method to tell EclipseLink that the stored procedure will be returning a JDBC ResultSet
     */
    public void setReturnsResultSet(boolean returnsResultSet) {
        this.returnsResultSet = returnsResultSet;
    }

    /**
     * Set if the call returns multiple result sets.
     */
    public void setReturnMultipleResultSetCollections(boolean returnMultipleResultSetCollections) {
        this.returnMultipleResultSetCollections = returnMultipleResultSetCollections;
    }

    /**
     * INTERNAL:
     * Set whether the call has to build output row
     */
    protected void setShouldBuildOutputRow(boolean shouldBuildOutputRow) {
        this.shouldBuildOutputRow = shouldBuildOutputRow;
    }

    /**
     * Bound calls can use prepared statement caching.
     */
    public void setShouldCacheStatement(boolean shouldCacheStatement) {
        this.shouldCacheStatement = shouldCacheStatement;
    }

    /**
     * The statement is stored for the return value of cursor selects.
     */
    public void setStatement(Statement statement) {
        this.statement = statement;
    }

    /**
     * The call may specify that its parameters should be bound.
     */
    public void setUsesBinding(boolean usesBinding) {
        this.usesBinding = usesBinding;
    }

    /**
     * Set whether the call has to build output row
     */
    public boolean shouldBuildOutputRow() {
        return this.shouldBuildOutputRow;
    }

    /**
     * Bound calls can use prepared statement caching.
     */
    public boolean shouldCacheStatement(AbstractSession session) {
        return shouldCacheStatement(session.getPlatform());
    }

    /**
     * Bound calls can use prepared statement caching.
     */
    public boolean shouldCacheStatement(DatabasePlatform databasePlatform) {
        //CR4272  If result set is scrollable, do not cache statement since scrollable cursor can not be used for cached statement
        if (isResultSetScrollable()) {
            return false;
        }
        if (this.shouldCacheStatement == null) {
            return databasePlatform.shouldCacheAllStatements();
        } else {
            return this.shouldCacheStatement;
        }
    }

    /**
     * INTERNAL:
     * Returns the ignoreFirstRowSetting flag. If true, FirstResult option is
     * assumed built into the SQL string and ignored if set in the call.
     */
    public boolean shouldIgnoreFirstRowSetting(){
        return this.ignoreFirstRowSetting;
    }

    /**
     * INTERNAL:
     * Returns the ignoreMaxResultsSetting flag. If true, MaxRows option is
     * assumed built into the SQL string and ignored if set in the call.
     */
    public boolean shouldIgnoreMaxResultsSetting(){
        return this.ignoreMaxResultsSetting;
    }

    /**
     * INTERNAL:
     * Print the SQL string.
     */
    @Override
    public String toString() {
        String str = Helper.getShortClassName(getClass());
        if (getSQLString() == null) {
            return str;
        } else {
            return str + "(" + getSQLString() + ")";
        }
    }

    /**
     * INTERNAL:
     * Allow the call to translate from the translation for predefined calls.
     */
    @Override
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
        if (!isPrepared()) {
            throw ValidationException.cannotTranslateUnpreparedCall(toString());
        }
        if (usesBinding(session) && (this.parameters != null)) {
            boolean hasParameterizedIN = false;
            List parameters = getParameters();
            List<Integer> parameterTypes = getParameterTypes();
            int size = parameters.size();
            List parametersValues = new ArrayList(size);
            for (int index = 0; index < size; index++) {
                Object parameter = parameters.get(index);
                Object parameterType = parameterTypes.get(index);
                if (parameterType == MODIFY) {
                    DatabaseField field = (DatabaseField)parameter;
                    Object value = modifyRow.get(field);
                    // If the value is null, the field is passed as the value so the type can be obtained from the field.
                    if (value == null) {
                        // The field from the modify row is used, as the calls field may not have the type,
                        // but if the field is missing the calls field may also have the type.
                        value = modifyRow.getField(field);
                        if (value == null) {
                            value = field;
                        }
                    }
                    parametersValues.add(value);
                } else if (parameterType == CUSTOM_MODIFY) {
                    DatabaseField field = (DatabaseField)parameter;
                    Object value = modifyRow.get(field);
                    value = session.getPlatform().getCustomModifyValueForCall(this, value, field, true);
                    //Bug#8200836 needs use unwrapped connection
                    if ((value!=null) && (value instanceof BindCallCustomParameter) &&  (((BindCallCustomParameter)value).shouldUseUnwrappedConnection())){
                        this.isNativeConnectionRequired=true;
                    }

                    // If the value is null, the field is passed as the value so the type can be obtained from the field.
                    if (value == null) {
                        // The field from the modify row is used, as the calls field may not have the type,
                        // but if the field is missing the calls field may also have the type.
                        value = modifyRow.getField(field);
                        if (value == null) {
                            value = field;
                        }
                    }
                    parametersValues.add(value);
                } else if (parameterType == TRANSLATION) {
                    Object value = null;
                    DatabaseField field = null;
                    if (parameter instanceof ParameterExpression) {
                        field = ((ParameterExpression)parameter).getField();
                        value = ((ParameterExpression)parameter).getValue(translationRow, query, session);
                    } else {
                        field = (DatabaseField)parameter;
                        value = translationRow.get(field);
                        if (value == null) {// Backward compatibility double check.
                            value = modifyRow.get(field);
                        }
                    }
                    if (value instanceof Collection) {
                        // Must re-translate IN parameters.
                        hasParameterizedIN = true;
                    }
                    // If the value is null, the field is passed as the value so the type can be obtained from the field.
                    if ((value == null) && (field != null)) {
                        if (!this.query.hasNullableArguments() || !this.query.getNullableArguments().contains(field)) {
                            value = translationRow.getField(field);
                            // The field from the row is used, as the calls field may not have the type,
                            // but if the field is missing the calls field may also have the type.
                            if (value == null) {
                                value = field;
                            }
                            parametersValues.add(value);
                        }
                    } else {
                        parametersValues.add(value);
                    }
                } else if (parameterType == LITERAL) {
                    parametersValues.add(parameter);
                } else if (parameterType == IN) {
                    Object value = getValueForInParameter(parameter, translationRow, modifyRow, session, true);
                    // Returning this means the parameter was optional and should not be included.
                    if (value != this) {
                        parametersValues.add(value);
                    }
                } else if (parameterType == INOUT) {
                    Object value = getValueForInOutParameter(parameter, translationRow, modifyRow, session);
                    parametersValues.add(value);
                } else if (parameterType == OUT || parameterType == OUT_CURSOR) {
                    if (parameter != null) {
                        ((OutputParameterForCallableStatement) parameter).getOutputField().setIndex(index);
                    }
                    parametersValues.add(parameter);
                }
            }
            setParameters(parametersValues);
            // If an IN parameter was found must translate SQL.
            if (hasParameterizedIN) {
                translateQueryStringForParameterizedIN(translationRow, modifyRow, session);
            }
            return;
        }

        translateQueryString(translationRow, modifyRow, session);
    }

    /**
     * INTERNAL:
     * Translate only IN() parameter values (List parameters).
     */
    public void translateQueryStringForParameterizedIN(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
        int lastIndex = 0;
        int parameterIndex = 0;
        String queryString = getQueryString();
        Writer writer = new CharArrayWriter(queryString.length() + 50);
        try {
            // PERF: This method is heavily optimized do not touch anything unless you know "very well" what your doing.
            List parameters = getParameters();
            List parametersValues = new ArrayList(parameters.size());
            while (lastIndex != -1) {
                int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex);
                String token;
                if (tokenIndex == -1) {
                    token = queryString.substring(lastIndex, queryString.length());
                    lastIndex = -1;
                } else {
                    token = queryString.substring(lastIndex, tokenIndex);
                }
                writer.write(token);
                if (tokenIndex != -1) {
                    // Process next parameter.
                    Object parameter = parameters.get(parameterIndex);
                    // Parameter expressions are used for nesting and correct mapping conversion of the value.
                    if (parameter instanceof Collection) {
                        Collection values = (Collection)parameter;
                        writer.write("(");
                        if ((values.size() > 0) && (values.iterator().next() instanceof List)) {
                            // Support nested lists.
                            int size = values.size();
                            Iterator valuesIterator = values.iterator();
                            for (int index = 0; index < size; index++) {
                                List nestedValues = (List)valuesIterator.next();
                                parametersValues.addAll(nestedValues);
                                int nestedSize = nestedValues.size();
                                writer.write("(");
                                for (int nestedIndex = 0; nestedIndex < nestedSize; nestedIndex++) {
                                    writer.write("?");
                                    if ((nestedIndex + 1) < nestedSize) {
                                        writer.write(",");
                                    }
                                }
                                writer.write(")");
                                if ((index + 1) < size) {
                                    writer.write(",");
                                }
                            }
                        } else {
                            parametersValues.addAll(values);
                            int size = values.size();

                            int limit = ((DatasourcePlatform)session.getDatasourcePlatform()).getINClauseLimit();
                            //The database platform has a limit for the IN clause so we need to reformat the clause
                            if(limit > 0) {
                                boolean not = token.endsWith(" NOT IN ");
                                String subToken = token.substring(0, token.length() - (not ? " NOT IN " : " IN ").length());
                                int spaceIndex = subToken.lastIndexOf(' ');
                                int braceIndex = subToken.lastIndexOf('(');
                                String fieldName = subToken.substring((spaceIndex > braceIndex ? spaceIndex : braceIndex) + 1);
                                String inToken = not ? ") AND " + fieldName + " NOT IN (" : ") OR " + fieldName + " IN (";

                                for (int index = 0; index < size; index++) {
                                    writer.write("?");
                                    if ((index + 1) < size) {
                                        if (index > 0 && (index + 1) % limit == 0) {
                                            writer.write(inToken);
                                        } else  {
                                            writer.write(",");
                                        }
                                    }
                                }
                            } else {
                                for (int index = 0; index < size; index++) {
                                    writer.write("?");
                                    if ((index + 1) < size) {
                                        writer.write(",");
                                    }
                                }
                            }
                        }
                        writer.write(")");
                    } else {
                        parametersValues.add(parameter);
                        writer.write("?");
                    }
                    lastIndex = tokenIndex + 1;
                    parameterIndex++;
                }
            }
            setParameters(parametersValues);
            setQueryString(writer.toString());

        } catch (IOException exception) {
            throw ValidationException.fileError(exception);
        }
    }

    /**
     * The call may specify that its parameters should be bound.
     */
    public boolean usesBinding(AbstractSession session) {
        return usesBinding(session.getPlatform());
    }

    /**
     * The call may specify that its parameters should be bound.
     */
    public boolean usesBinding(DatabasePlatform databasePlatform) {
        if (this.usesBinding == null) {
            return databasePlatform.shouldBindAllParameters();
        } else {
            return this.usesBinding;
        }
    }

    /**
     * INTERNAL
     * Indicates whether usesBinding has been set.
     */
    public boolean isUsesBindingSet() {
        return this.usesBinding != null;
    }

    /**
     * INTERNAL:
     * Return if the locator is required for the LOB (BLOB and CLOB) writing.
     */
    public boolean isLOBLocatorNeeded() {
        return contexts != null;
    }

    /**
     * INTERNAL:
     * Add a field - value pair for LOB field into the context.
     */
    public void addContext(DatabaseField field, Object value) {
        if (this.contexts == null) {
            this.contexts = new DatabaseRecord(2);
        }
        this.contexts.add(field, value);
        this.isBatchExecutionSupported = false;
    }

    /**
     * INTERNAL:
     * Return the contexts (for LOB)
     */
    public AbstractRecord getContexts() {
        return contexts;
    }

    /**
     * INTERNAL:
     * Set the contexts (for LOB)
     */
    public void setContexts(AbstractRecord contexts) {
        this.contexts = contexts;
    }

    /**
     * An execute return value will be set here after the call.
     */
    public void setExecuteReturnValue(boolean value) {
        executeReturnValue = value;
    }

    /**
     * PUBLIC:
     * Used for Oracle result sets through procedures.
     * The first OUT parameter is set as a cursor output.
     */
    public void useUnnamedCursorOutputAsResultSet() {
        setIsCursorOutputProcedure(true);
    }

    /**
     * INTERNAL:
     * Return if this query is compatible with batch writing.
     * Some queries, such as DDL are not compatible.
     */
    public boolean isBatchExecutionSupported() {
        return isBatchExecutionSupported;
    }

    /**
     * INTERNAL:
     * Set if this query is compatible with batch writing.
     * Some queries, such as DDL are not compatible.
     */
    public void setBatchExecutionSupported(boolean isBatchExecutionSupported) {
        this.isBatchExecutionSupported = isBatchExecutionSupported;
    }

    /**
     * INTERNAL:
     */
    public boolean hasAllocatedConnection() {
        return this.hasAllocatedConnection;
    }

    /**
     * INTERNAL:
     */
    public void setHasAllocatedConnection(boolean hasAllocatedConnection) {
        this.hasAllocatedConnection = hasAllocatedConnection;
    }

    /**
     * 
     * INTERNAL:
     * 
     * Get the return object from the statement. Use the parameter index to determine what return object to get.
     * @param statement SQL/JDBC statement to call stored procedure/function
     * @param index 0-based index in the argument list
     * @param session Active database session (in connected state).
     */
    public Object getOutputParameterValue(CallableStatement statement, int index, AbstractSession session) throws SQLException {
        return session.getPlatform().getParameterValueFromDatabaseCall(statement, index + 1, session);
    }

    /**
     * 
     * INTERNAL:
     * 
     * Get the return object from the statement. Use the parameter name to determine what return object to get.
     * @param statement SQL/JDBC statement to call stored procedure/function
     * @param name parameter name
     * @param session Active database session (in connected state).
     */
    public Object getOutputParameterValue(CallableStatement statement, String name, AbstractSession session) throws SQLException {
        return session.getPlatform().getParameterValueFromDatabaseCall(statement, name, session);
    }
}
