// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@

package org.trafodion.jdbc.t4;

import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.LogRecord;

/**
 * <p>
 * JDBC Type 4 TrafT4Statement class.
 * </p>
 * <p>
 * Description: The <code>TrafT4Statement</code> class is an implementation of
 * the <code>java.sql.Statement</code> interface.
 * </p>
 */
public class TrafT4Statement extends HPT4Handle implements java.sql.Statement {
	// java.sql.Statement interface Methods

	public void addBatch(String sql) throws SQLException {
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("addBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "addBatch", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("addBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (batchCommands_ == null) {
			batchCommands_ = new ArrayList();
		}


		batchCommands_.add(sql);
	}

	public void cancel() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "cancel", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("cancel");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		// Donot clear warning, since the warning may pertain to
		// previous opertation and it is not yet seen by the application
		//
		// We must decide if this statement is currently being processed or
		// if it has a result set associated with it, and if that
		// result set is currently active (i.e. we are fetching rows).
		if ((ist_.t4statement_ != null && ist_.t4statement_.m_processing == true)
				|| (resultSet_ != null && resultSet_[result_set_offset] != null
						&& resultSet_[result_set_offset].irs_ != null
						&& resultSet_[result_set_offset].irs_.t4resultSet_ != null && resultSet_[result_set_offset].irs_.t4resultSet_.m_processing == true))
			ist_.cancel();
	}

	public void clearBatch() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "clearBatch", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("clearBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		batchCommands_.clear();
	}

	/**
	 * Closes the statement object. Synchronized to prevent the same resource
	 * issued free command twice on the server.
	 * 
	 * @throws SQLException
	 */
	synchronized public void close() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "close", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("close");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (isClosed_) {
			return;
		}

		try {
			if (connection_._isClosed() == false) {
				for (int i = 0; i < num_result_sets_; i++) {
					if (resultSet_[i] != null) {
						resultSet_[i].close(false);
					}
				}
				ist_.close();
			}
		} finally {
			isClosed_ = true;
			connection_.removeElement(pRef_);
			initResultSets();
		}
	}

	void initResultSets() {
		num_result_sets_ = 1;
		result_set_offset = 0;
		resultSet_[result_set_offset] = null;
	}

	// ------------------------------------------------------------------
	/**
	 * This method will execute an operation.
	 * 
	 * @return true
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */

	public boolean execute() throws SQLException {
		try {
			ist_.executeDirect(queryTimeout_, this);
		} catch (SQLException se) {
			performConnectionErrorChecks(se);
			throw se;
		}
		return true;
	} // end execute

	// ------------------------------------------------------------------

	public boolean execute(String sql) throws SQLException {
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("execute");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "execute", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("execute");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateExecDirectInvocation(sql);
		try {
			ist_.execute(TRANSPORT.SRVR_API_SQLEXECDIRECT, 0, 0, null, queryTimeout_, sql_, this);

			checkSQLWarningAndClose();
		} catch (SQLException se) {
			try {
				if (num_result_sets_ == 1 && resultSet_[result_set_offset] == null)
					;
				{
					internalClose();
				}
			} catch (SQLException closeException) {
				se.setNextException(closeException);
			}
			performConnectionErrorChecks(se);
			throw se;
		}
		if (resultSet_[result_set_offset] != null) {
			return true;
		} else {
			return false;
		}
	}

	public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, autoGeneratedKeys);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "execute", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, autoGeneratedKeys);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("execute");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		boolean ret;

		if (autoGeneratedKeys == TrafT4Statement.NO_GENERATED_KEYS) {
			ret = execute(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public boolean execute(String sql, int[] columnIndexes) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnIndexes);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "execute", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnIndexes);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("execute");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		boolean ret;

		if (columnIndexes == null) {
			ret = execute(sql);
		} else if (columnIndexes.length == 0) {
			ret = execute(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public boolean execute(String sql, String[] columnNames) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnNames);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "execute", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnNames);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("execute");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		boolean ret;

		if (columnNames == null) {
			ret = execute(sql);
		} else if (columnNames.length == 0) {
			ret = execute(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public int[] executeBatch() throws SQLException, BatchUpdateException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeBatch", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		try {
			int i = 0;
			SQLException se;

			validateExecDirectInvocation();
			if ((batchCommands_ == null) || (batchCommands_.isEmpty())) {
				return new int[]

				{};
			}

			batchRowCount_ = new int[batchCommands_.size()];
			for (i = 0; i < batchCommands_.size(); i++) {
				String sql = (String) batchCommands_.get(i);

				if (sql == null) {
					se = HPT4Messages.createSQLException(connection_.props_, this.ist_.ic_.getLocale(),
							"batch_command_failed", "Invalid SQL String");
					throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
				}

				sqlStmtType_ = ist_.getSqlStmtType(sql);

				if (sqlStmtType_ == TRANSPORT.TYPE_SELECT) {
					se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
							"select_in_batch_not_supported", null);
					throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
				} else if (sqlStmtType_ == TRANSPORT.TYPE_STATS) {
					se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
							"infostats_invalid_error", null);
					throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
				} else if (sqlStmtType_ == TRANSPORT.TYPE_CONFIG) {
					se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
							"config_cmd_invalid_error", null);
					throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
				}
				ist_.setTransactionStatus(connection_, sql);
			}

			Object[] commands = batchCommands_.toArray();
			int[] batchRowCount = new int[commands.length];
			String sql;
			int rowCount = 0;

			try {
				for (i = 0; i < commands.length; i++) {
					sql = String.valueOf(commands[i]);

					validateExecDirectInvocation(sql);

					ist_.execute(TRANSPORT.SRVR_API_SQLEXECDIRECT, 0, 0, null, queryTimeout_, sql_, this);

					checkSQLWarningAndClose();

					batchRowCount[i] = batchRowCount_[0]; // the member will
					// be set by
					// execute...keep
					// them in our local
					// array
					rowCount += ist_.getRowCount();
				}
				// CTS requirement.
				if (commands.length < 1) {
					batchRowCount = new int[] {};
				}
			} catch (SQLException e) {
				ist_.setRowCount(rowCount);
				batchRowCount_ = new int[i];
				System.arraycopy(batchRowCount, 0, batchRowCount_, 0, i);

				BatchUpdateException be;

				se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"batch_command_failed", null);
				be = new BatchUpdateException(se.getMessage(), se.getSQLState(), batchRowCount_);
				be.setNextException(e);

				try {
					if (resultSet_[result_set_offset] == null) {
						internalClose();
					}
				} catch (SQLException closeException) {
					be.setNextException(closeException);
				}
				performConnectionErrorChecks(e);

				throw be;
			}

			ist_.setRowCount(rowCount);
			batchRowCount_ = new int[i];
			System.arraycopy(batchRowCount, 0, batchRowCount_, 0, i);
			return batchRowCount_;
		} finally {
			clearBatch();
		}

	}

	public ResultSet executeQuery(String sql) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeQuery", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeQuery");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		validateExecDirectInvocation(sql);
		if (sqlStmtType_ != TRANSPORT.TYPE_SELECT && sqlStmtType_ != TRANSPORT.TYPE_STATS) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "non_select_invalid",
					null);
		}
		try {
			ist_.execute(TRANSPORT.SRVR_API_SQLEXECDIRECT, 0, 0, null, queryTimeout_, sql_, this);

			checkSQLWarningAndClose();
		} catch (SQLException se) {
			try {
				if (resultSet_[result_set_offset] == null) {
					internalClose();
				}
			} catch (SQLException closeException) {
				se.setNextException(closeException);
			}
			performConnectionErrorChecks(se);
			throw se;
		}
		return resultSet_[result_set_offset];
	}

	public int executeUpdate(String sql) throws SQLException {
		long count = executeUpdate64(sql);

		if (count > Integer.MAX_VALUE)
			this.setSQLWarning(null, "numeric_out_of_range", null);

		return (int) count;
	}

	public long executeUpdate64(String sql) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeUpdate", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeUpdate");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateExecDirectInvocation(sql);
		// 7708
		if (sqlStmtType_ == TRANSPORT.TYPE_SELECT && (ist_.stmtIsLock != true)) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "select_invalid", null);
		}
		try {
			ist_.execute(TRANSPORT.SRVR_API_SQLEXECDIRECT, 0, 0, null, queryTimeout_, sql_, this);

			checkSQLWarningAndClose();
		} catch (SQLException se) {
			try {
				if (resultSet_[result_set_offset] == null) {
					internalClose();
				}
			} catch (SQLException closeException) {
				se.setNextException(closeException);
			}
			performConnectionErrorChecks(se);
			throw se;
		}
		return ist_.getRowCount();
	}

	public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, autoGeneratedKeys);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeUpdate", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, autoGeneratedKeys);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeUpdate");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int ret;

		if (autoGeneratedKeys == TrafT4Statement.NO_GENERATED_KEYS) {
			ret = executeUpdate(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnIndexes);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeUpdate", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnIndexes);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeUpdate");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int ret;

		if (columnIndexes == null) {
			ret = executeUpdate(sql);
		} else if (columnIndexes.length == 0) {
			ret = executeUpdate(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public int executeUpdate(String sql, String[] columnNames) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnNames);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "executeUpdate", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, columnNames);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("executeUpdate");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int ret;

		if (columnNames == null) {
			ret = executeUpdate(sql);
		} else if (columnNames.length == 0) {
			ret = executeUpdate(sql);
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"auto_generated_keys_not_supported", null);
		}
		return ret;
	}

	public Connection getConnection() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getConnection", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getConnection");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		return connection_;
	}

	public int getFetchDirection() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getFetchDirection", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getFetchDirection");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return fetchDirection_;
	}

	public int getFetchSize() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getFetchSize", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getFetchSize");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return fetchSize_;
	}

	public ResultSet getGeneratedKeys() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getGeneratedKeys", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getGeneratedKeys");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
				"auto_generated_keys_not_supported", null);
	}

	public int getMaxFieldSize() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getMaxFieldSize", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getMaxFieldSize");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return maxFieldSize_;
	}

	public int getMaxRows() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getMaxRows", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getMaxRows");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return maxRows_;
	}

	public boolean getMoreResults() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getMoreResults", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getMoreResults");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return getMoreResults(Statement.CLOSE_CURRENT_RESULT);
	}

	public boolean getMoreResults(int current) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, current);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getMoreResults", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, current);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getMoreResults");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		switch (current) {
		case Statement.CLOSE_ALL_RESULTS:
			for (int i = 0; i <= result_set_offset; i++) {
				if (resultSet_[i] != null) {
					resultSet_[i].close();
				}
			}
			break;
		case Statement.KEEP_CURRENT_RESULT:
			break;
		case Statement.CLOSE_CURRENT_RESULT: // this is the default action
		default:
			if (resultSet_[result_set_offset] != null) {
				resultSet_[result_set_offset].close();
			}
			break;
		}
		ist_.setRowCount(-1);
		if (result_set_offset < num_result_sets_ - 1) {
			result_set_offset++;
			return true;
		}
		return false;
	}

	public int getQueryTimeout() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getQueryTimeout", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getQueryTimeout");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return queryTimeout_;
	}

	public ResultSet getResultSet() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getResultSet", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getResultSet");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return resultSet_[result_set_offset];
	}

	public int getResultSetConcurrency() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getResultSetConcurrency", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getResultSetConcurrency");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return resultSetConcurrency_;
	}

	public int getResultSetHoldability() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getResultSetHoldability", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getResultSetHoldability");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return resultSetHoldability_;
	}

	public int getResultSetType() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getResultSetType", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getResultSetType");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		return resultSetType_;
	}

	public int getUpdateCount() throws SQLException {
		long count = getUpdateCount64();

		if (count > Integer.MAX_VALUE)
			this.setSQLWarning(null, "numeric_out_of_range", null);

		return (int) count;
	}

	public long getUpdateCount64() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "getUpdateCount", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("getUpdateCount");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (ist_ == null) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_statement_handle", null);
		}

		// Spec wants -1 when the resultset is current and no more rows.
		long count = ist_.getRowCount();
		if ((count == 0) && resultSet_ != null && resultSet_[result_set_offset] != null) {
			count = -1;
		}

		return count;
	}

	// ------------------------------------------------------------------
	/**
	 * This method will get the operation ID for this statement. -1 is returned
	 * if the operation ID has not been set.
	 * 
	 * @retrun The operation ID or -1 if the operation ID has not been set.
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public short getOperationID() throws SQLException {
		return operationID_;
	} // end getOperationID

	// ------------------------------------------------------------------
	/**
	 * This method will get the operation buffer for this statement. Null is
	 * returned if the operation buffer has not been set.
	 * 
	 * @retrun The operation buffer or null if the operation ID has not been
	 *         set.
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public byte[] getOperationBuffer() throws SQLException {
		// System.out.println("in getOperation");
		return operationBuffer_;
	}

	// ------------------------------------------------------------------
	/**
	 * This method will get the operation reply buffer for this statement. Null
	 * is returned if the operation reply buffer has not been set.
	 * 
	 * @retrun The operation reply buffer or null.
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public byte[] getOperationReplyBuffer() throws SQLException {
		// System.out.println("in getOperationReplyBuffer");
		return operationReply_;
	}

	// ------------------------------------------------------------------

	public void setCursorName(String name) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, name);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setCursorName", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, name);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setCursorName");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		// TODO: May need to check the Statement STATE
		cursorName_ = name;
	}

	public void setEscapeProcessing(boolean enable) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, enable);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setEscapeProcessing", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, enable);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setEscapeProcessing");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		escapeProcess_ = enable;

	}

	public void setFetchDirection(int direction) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, direction);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setFetchDirection", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, direction);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setFetchDirection");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		switch (direction) {
		case ResultSet.FETCH_FORWARD:
			fetchDirection_ = direction;
			break;
		case ResultSet.FETCH_REVERSE:
		case ResultSet.FETCH_UNKNOWN:
			fetchDirection_ = ResultSet.FETCH_FORWARD;
			break;
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_fetch_direction", null);
		}
	}

	public void setFetchSize(int rows) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, rows);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setFetchSize", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, rows);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setFetchSize");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (rows < 0) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_fetch_size",
					null);
		} else if (rows == 0) {
			fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		} else {
			fetchSize_ = rows;
		}
	}

	public void setMaxFieldSize(int max) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, max);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setMaxFieldSize", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, max);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setMaxFieldSize");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (max < 0) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_maxFieldSize_value", null);
		}
		maxFieldSize_ = max;
	}

	public void setMaxRows(int max) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, max);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setMaxRows", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, max);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setMaxRows");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (max < 0) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_maxRows_value",
					null);
		}
		maxRows_ = max;
	}

	public void setQueryTimeout(int seconds) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, seconds);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "setQueryTimeout", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, seconds);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("setQueryTimeout");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		//HPT4Messages.throwUnsupportedFeatureException(connection_.props_, connection_.getLocale(), "setQueryTimeout()");
		
		if (seconds < 0) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_queryTimeout_value", null);
		}
		queryTimeout_ = seconds;
	}

	// ------------------------------------------------------------------
	/**
	 * This method will set the operation ID for this statement.
	 * 
	 * @param opID
	 *            the operation ID to associate with this statement.
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public void setOperationID(short opID) throws SQLException {
		operationID_ = opID;
	} // end setOperationID

	// ------------------------------------------------------------------
	/**
	 * This method will set the operation buffer for this statement.
	 * 
	 * @param The
	 *            operation buffer.
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public void setOperationBuffer(byte[] opBuffer) throws SQLException {
		operationBuffer_ = opBuffer;
	}


	void validateExecDirectInvocation(String sql) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "validateExecDirectInvocation", "", p);
		}

		validateExecDirectInvocation();
		sqlStmtType_ = ist_.getSqlStmtType(sql);
		ist_.setTransactionStatus(connection_, sql);
                sql_ = sql;

	}

	void validateExecDirectInvocation() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "validateExecDirectInvocation", "", p);
		}
		ist_.setRowCount(-1);
		clearWarnings();
		if (isClosed_) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_statement",
					null);
		}
		try {
			// connection_.getServerHandle().isConnectionOpen();
			connection_.isConnectionOpen();

			// close the previous resultset, if any
			for (int i = 0; i < num_result_sets_; i++) {
				if (resultSet_[i] != null) {
					resultSet_[i].close();
				}
			}
		} catch (SQLException se) {
			performConnectionErrorChecks(se);
			throw se;
		}
	}
	
	// This functions ensure that Database Resources are cleaned up,
	// but leave the java Statement object
	// intact.
	void internalClose() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "internalClose", "", p);
		}
		if (connection_._isClosed() == false) {
			ist_.close();
		}
	}

	private void setResultSet(HPT4Desc[] outputDesc) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, outputDesc);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "setResultSet", "", p);
		}
		initResultSets();
		if (outputDesc != null) {
			resultSet_[result_set_offset] = new TrafT4ResultSet(this, outputDesc);
		} else {
			resultSet_[result_set_offset] = null;
		}
	}

	public void setTransactionToJoin(byte[] txid) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, txid);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "setTransactionToJoin", "", p);
		}

		this.transactionToJoin = txid;
	}

	void setMultipleResultSets(int num_result_sets, HPT4Desc[][] output_descriptors, String[] stmt_labels,
			String[] proxySyntax) throws SQLException {
		if (num_result_sets < 1)
			return;

		resultSet_ = new TrafT4ResultSet[num_result_sets];
		num_result_sets_ = num_result_sets;
		for (int i = 0; i < num_result_sets; i++) {
			HPT4Desc[] desc = output_descriptors[i];
			if (desc == null) {
				resultSet_[i] = null;
			} else {
				resultSet_[i] = new TrafT4ResultSet(this, desc, stmt_labels[i], true);
				resultSet_[i].proxySyntax_ = proxySyntax[i];
			}
		}
	}

	// ----------------------------------------------------------------------------------
	void setExecute2Outputs(byte[] values, short rowsAffected, boolean endOfData, String[] proxySyntax, HPT4Desc[] desc)
			throws SQLException {
		num_result_sets_ = 1;
		result_set_offset = 0;

		// if NO DATA FOUND is returned from the server, desc = null but
		// we still want to save our descriptors from PREPARE
		if (desc != null)
			outputDesc_ = desc;

		resultSet_ = new TrafT4ResultSet[num_result_sets_];

		if (outputDesc_ != null) {
			resultSet_[result_set_offset] = new TrafT4ResultSet(this, outputDesc_);
			resultSet_[result_set_offset].proxySyntax_ = proxySyntax[result_set_offset];

			if (rowsAffected == 0) {
				if (endOfData == true) {
					resultSet_[result_set_offset].setFetchOutputs(new ObjectArray[0], 0, true);
				}
			} else {
				 if(resultSet_[result_set_offset].keepRawBuffer_ == true)
			          resultSet_[result_set_offset].rawBuffer_ = values;
				 
				resultSet_[result_set_offset].irs_.setExecute2FetchOutputs(resultSet_[result_set_offset], 1, true,
						values);
			}
		} else {
			resultSet_[result_set_offset] = null;
		}
	}

	// Constructors with access specifier as "default"
	TrafT4Statement() {
		if (T4Properties.t4GlobalLogger.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(null);
			T4Properties.t4GlobalLogger.logp(Level.FINE, "TrafT4Statement", "<init>", "", p);
		}
		resultSet_ = new TrafT4ResultSet[1];
		initResultSets();
	}

	/*
	 * * For closing statements using label.
	 */
	TrafT4Statement(TrafT4Connection connection, String stmtLabel) throws SQLException {
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, stmtLabel);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "<init>", "", p);
		}
		if (connection.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("Note, this constructor was called before the previous constructor");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection.props_.getLogWriter().println(temp);
		}
		int hashcode;

		connection_ = connection;
		operationID_ = -1;

		resultSetType_ = ResultSet.TYPE_FORWARD_ONLY;
		resultSetConcurrency_ = ResultSet.CONCUR_READ_ONLY;
		resultSetHoldability_ = TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT;
		queryTimeout_ = connection_.getServerHandle().getQueryTimeout();

		stmtLabel_ = stmtLabel;
		fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		maxRows_ = 0;
		fetchDirection_ = ResultSet.FETCH_FORWARD;
		pRef_ = new WeakReference(this, connection_.refStmtQ_);
		ist_ = new InterfaceStatement(this);
		connection_.addElement(pRef_, stmtLabel_);

		resultSet_ = new TrafT4ResultSet[1];
		initResultSets();
	}

	TrafT4Statement(TrafT4Connection connection) throws SQLException {
		this(connection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT);
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "<init>",
					"Note, this constructor was called before the previous constructor", p);
		}
		if (connection.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("<init>");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection.props_.getLogWriter().println(temp);
		}
		resultSet_ = new TrafT4ResultSet[1];
		roundingMode_ = connection_.props_.getRoundingMode();
		initResultSets();
	}

	TrafT4Statement(TrafT4Connection connection, int resultSetType, int resultSetConcurrency) throws SQLException {
		this(connection, resultSetType, resultSetConcurrency, TrafT4ResultSet.CLOSE_CURSORS_AT_COMMIT);
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "<init>",
					"Note, this constructor was called before the previous constructor", p);
		}
		if (connection.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("<init>");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection.props_.getLogWriter().println(temp);
		}
		resultSet_ = new TrafT4ResultSet[1];
		roundingMode_ = connection_.props_.getRoundingMode();
		initResultSets();
	}
	TrafT4Statement(TrafT4Connection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability,
			String stmtLabel) throws SQLException {
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "<init>", "", p);
		}
		if (connection.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("<init>");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection.props_.getLogWriter().println(temp);
		}
		int hashcode;

		connection_ = connection;
		operationID_ = -1;

		if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
				&& resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_resultset_type", null);
		}

		if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
			resultSetType_ = ResultSet.TYPE_SCROLL_INSENSITIVE;
			connection_.setSQLWarning(null, "scrollResultSetChanged", null);
			//setSQLWarning(null, "scrollResultSetChanged", null);
		} else {
			resultSetType_ = resultSetType;
		}
		if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_resultset_concurrency", null);
		}

		if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
				&& (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
					null);
		}

		resultSetConcurrency_ = resultSetConcurrency;
		resultSetHoldability_ = resultSetHoldability;
		queryTimeout_ = connection_.getServerHandle().getQueryTimeout();

		stmtLabel_ = stmtLabel;
		fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		maxRows_ = 0;
		fetchDirection_ = ResultSet.FETCH_FORWARD;

		connection_.gcStmts();
		pRef_ = new WeakReference(this, connection_.refStmtQ_);
		ist_ = new InterfaceStatement(this);
		connection_.addElement(pRef_, stmtLabel_);
		roundingMode_ = connection_.props_.getRoundingMode();

		resultSet_ = new TrafT4ResultSet[1];
	}

	TrafT4Statement(TrafT4Connection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4Statement", "<init>", "", p);
		}
		if (connection.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4Statement");
			lr.setSourceMethodName("<init>");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection.props_.getLogWriter().println(temp);
		}
		int hashcode;

		connection_ = connection;
		operationID_ = -1;

		if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE
				&& resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_resultset_type", null);
		}

		if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) {
			resultSetType_ = ResultSet.TYPE_SCROLL_INSENSITIVE;
			connection_.setSQLWarning(null, "scrollResultSetChanged", null);
			//setSQLWarning(null, "scrollResultSetChanged", null);
		} else {
			resultSetType_ = resultSetType;
		}
		if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_resultset_concurrency", null);
		}

		if ((resultSetHoldability != 0) && (resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT)
				&& (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_holdability",
					null);
		}

		resultSetConcurrency_ = resultSetConcurrency;
		resultSetHoldability_ = resultSetHoldability;
		queryTimeout_ = connection_.getServerHandle().getQueryTimeout();

		stmtLabel_ = generateStmtLabel();
		fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		maxRows_ = 0;
		fetchDirection_ = ResultSet.FETCH_FORWARD;

		connection_.gcStmts();
		pRef_ = new WeakReference(this, connection_.refStmtQ_);
		ist_ = new InterfaceStatement(this);
		connection_.addElement(pRef_, stmtLabel_);

		resultSet_ = new TrafT4ResultSet[1];
		roundingMode_ = connection_.props_.getRoundingMode();
		initResultSets();
	}

	//max length for a label is 32 characters.
	String generateStmtLabel() {
		String id = String.valueOf(this.connection_.ic_.getSequenceNumber());
		if(id.length() > 24) {
			id = id.substring(id.length()-24);
		}
	
		return "SQL_CUR_" + id;
	}
	
	// Database statement are not deallocated when there is a
	// SQLWarning or SQLException or when a resultSet is produced
	void checkSQLWarningAndClose() {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4Statement", "checkSQLWarningAndClose", "", p);
		}
		if (sqlWarning_ != null) {
			if (resultSet_[result_set_offset] == null) {
				try {
					internalClose();
				} catch (SQLException closeException1) {
				}
			}
		}
	}

	public void setRoundingMode(int roundingMode) {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, roundingMode);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setRoundingMode", "", p);
		}
		roundingMode_ = Utility.getRoundingMode(roundingMode);
	}

	public void setRoundingMode(String roundingMode) {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, roundingMode);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setRoundingMode", "", p);
		}
		roundingMode_ = Utility.getRoundingMode(roundingMode);
	}

	void closeErroredConnection(HPT4Exception sme) {
		connection_.closeErroredConnection(sme);
	}

	/**
	 * Use this method to retrieve the statement-label name that was used when
	 * creating the statement through the Trafodion connectivity service. You can
	 * subsequently use the name retrieved as the cursor name when invoking
	 * INFOSTATS to gather resource statistics through either the
	 * <code>executeQuery(String sql)</code> or
	 * <code>execute(String sql)</code> methods.
	 */
	public String getStatementLabel() {
		return new String(stmtLabel_);
	}

	/**
	 * Returns the raw SQL associated with the statement
	 * 
	 * @return the SQL text
	 */
	public String getSQL() {
		return this.sql_;
	}

	/**
	 * Returns the MXCS statement handle
	 * 
	 * @return the MXCS statement handle
	 */
	public int getStmtHandle() {
		return this.ist_.stmtHandle_;
	}

	// static fields
	public static final int NO_GENERATED_KEYS = 2;
	// Fields
	TrafT4Connection connection_;
	int resultSetType_;
	int resultSetConcurrency_;
	String sql_;
	int queryTimeout_;
	int maxRows_;
	int maxFieldSize_;
	int fetchSize_;
	int fetchDirection_;
	boolean escapeProcess_;
	String cursorName_ = "";
	TrafT4ResultSet[] resultSet_; // Added for SPJ RS - SB 11/21/2005
	int num_result_sets_; // Added for SPJ RS - SB 11/21/2005
	int result_set_offset; // Added for SPJ RS - SB 11/21/2005
	String stmtLabel_;
	short sqlStmtType_;
	boolean isClosed_;
	ArrayList batchCommands_;
	int[] batchRowCount_;
	WeakReference pRef_;
	int resultSetHoldability_;
	InterfaceStatement ist_;

	int inputParamsLength_;
	int outputParamsLength_;
	int inputDescLength_;
	int outputDescLength_;

	int inputParamCount_;
	int outputParamCount_;

	int roundingMode_ = BigDecimal.ROUND_HALF_EVEN;

	HPT4Desc[] inputDesc_, outputDesc_;

	short operationID_;
	byte[] operationBuffer_;
	byte[] operationReply_;

	boolean usingRawRowset_;
	ByteBuffer rowwiseRowsetBuffer_;

	byte[] transactionToJoin;
	
	int _lastCount = -1;

	/**
	 * @return the inputParamsLength_
	 */
	public int getInputParamsLength_() {
		return inputParamsLength_;
	}

	/**
	 * @return the outputParamsLength_
	 */
	public int getOutputParamsLength_() {
		return outputParamsLength_;
	}

	public Object unwrap(Class iface) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean isWrapperFor(Class iface) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean isClosed() throws SQLException {
		// TODO Auto-generated method stub
                return isClosed_;
	}

	public void setPoolable(boolean poolable) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public boolean isPoolable() throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	public void closeOnCompletion() throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public boolean isCloseOnCompletion() throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

}
