// @@@ 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.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.nio.ByteBuffer;
import java.sql.Array;
import java.sql.BatchUpdateException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.LogRecord;

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

		if (inputDesc_ == null) {
			return;
		}

		// Check if all parameters are set for current set
		checkIfAllParamsSet();
		// Add to the number of Rows Count
		if (rowsValue_ == null) {
			rowsValue_ = new ArrayList();
		}
		rowsValue_.add(paramsValue_);
		paramRowCount_++;
		paramsValue_ = new Object[inputDesc_.length];
		if (isAnyLob_ && (lobObjects_ == null)) {
			lobObjects_ = new ArrayList();
			// Clear the isValueSet_ flag in inputDesc_ and add the lob objects
			// to the lobObject List
		}
		for (int i = 0; i < inputDesc_.length; i++) {
			// If isAnyLob_ is false: inputDesc_.paramValue_ for all
			// parameters should be null
			// If isAnyLob_ is true: one or more inputDesc_.parmValue will not
			// be null, based on the number of LOB columns in the query
			if (inputDesc_[i].paramValue_ != null) {
				lobObjects_.add(inputDesc_[i].paramValue_);
				inputDesc_[i].paramValue_ = null;
			}
			inputDesc_[i].isValueSet_ = false;
		}
	}

	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, "TrafT4PreparedStatement", "clearBatch", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("clearBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		if (inputDesc_ == null) {
			return;
		}
		if (rowsValue_ != null) {
			rowsValue_.clear();
		}
		if (lobObjects_ != null) {
			lobObjects_.clear();
		}
		paramRowCount_ = 0;
		// Clear the isValueSet_ flag in inputDesc_
		for (int i = 0; i < inputDesc_.length; i++) {
			inputDesc_[i].isValueSet_ = false;
			paramsValue_[i] = null;
			inputDesc_[i].paramValue_ = null;
		}
		isAnyLob_ = false;
		batchRowCount_ = new int[] {};
	}

	public void clearParameters() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "clearParameters", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("clearParameters");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		// Clear the isValueSet_ flag in inputDesc_
		if (inputDesc_ == null) {
			return;
		}

		for (int i = 0; i < inputDesc_.length; i++) {
			inputDesc_[i].isValueSet_ = false;
			paramsValue_[i] = null;
			inputDesc_[i].paramValue_ = null;
		}
		isAnyLob_ = false;
	}

	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, "TrafT4PreparedStatement", "close", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			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) {
				if (!connection_.isStatementCachingEnabled()) {
					super.close();
				} else {
					logicalClose();
				}
			}
		} catch (SQLException e) {
			performConnectionErrorChecks(e);
			throw e;
		} finally {
			isClosed_ = true;
			if (!connection_.isStatementCachingEnabled()) {
				connection_.removeElement(pRef_);
			}
		}

	}

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

		validateExecuteInvocation();

		// *******************************************************************
		// * If LOB is involved with autocommit enabled we throw an exception
		// *******************************************************************
		if (isAnyLob_ && (connection_.getAutoCommit())) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_lob_commit_state", null);
		}
		if (inputDesc_ != null) {
			if (!usingRawRowset_)
				valueArray = getValueArray();
			inDescLength = inputDesc_.length;
		}

		execute(paramRowCount_ + 1, inDescLength, valueArray, queryTimeout_, isAnyLob_); // LOB
		// Support
		// - SB
		// 9/28/04

		// if (resultSet_[result_set_offset] != null)
		if (resultSet_ != null && resultSet_[result_set_offset] != null) {
			return true;
		} else {
			if (isAnyLob_) {


			}
			return false;
		}
	}

	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, "TrafT4PreparedStatement", "executeBatch", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("executeBatch");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

		try {
			clearWarnings();
			HPT4Exception se;
			Object[] valueArray = null;

			if (inputDesc_ == null) {
				se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"batch_command_failed", null);
				throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
			}
			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]);
			}
			if (connection_._isClosed()) {
				se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "invalid_connection",
						null);
				connection_.closeErroredConnection(se);
				throw new BatchUpdateException(se.getMessage(), se.getSQLState(), new int[0]);
			}
			if (isAnyLob_ && (connection_.getAutoCommit())) {
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"invalid_lob_commit_state", null);
			}

			int prc = usingRawRowset_ ? (paramRowCount_ + 1) : paramRowCount_;

			if (paramRowCount_ < 1) {
				if (!connection_.props_.getDelayedErrorMode()) {
					return (new int[] {});
				}
			} 

			try {
				if (!usingRawRowset_)
					valueArray = getValueArray();

				execute(prc, inputDesc_.length, valueArray, queryTimeout_, lobObjects_ != null);


			} catch (SQLException e) {
				BatchUpdateException be;
				se = HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"batch_command_failed", null);
				if (batchRowCount_ == null) // we failed before execute
				{
					batchRowCount_ = new int[paramRowCount_];
					Arrays.fill(batchRowCount_, -3);
				}
				be = new BatchUpdateException(se.getMessage(), se.getSQLState(), batchRowCount_);
				be.setNextException(e);

				throw be;
			}

			if (connection_.props_.getDelayedErrorMode()) {
				_lastCount = paramRowCount_;
			}

			return batchRowCount_;
		} finally {
			clearBatch();
		}
	}

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

		validateExecuteInvocation();
		if (sqlStmtType_ != TRANSPORT.TYPE_SELECT) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "non_select_invalid",
					null);
		}

		if (inputDesc_ != null) {
			if (!usingRawRowset_)
				valueArray = getValueArray();
			inDescLength = inputDesc_.length;
		}
		execute(paramRowCount_ + 1, inDescLength, valueArray, queryTimeout_, isAnyLob_); // LOB
		// Support
		// - SB
		// 9/28/04
		return resultSet_[result_set_offset];
	}

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

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

		return (int) count;
	}

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

		validateExecuteInvocation();
		// if (sqlStmtType_ == TRANSPORT.TYPE_SELECT)
		if (sqlStmtType_ == TRANSPORT.TYPE_SELECT && (ist_.stmtIsLock != true)) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "select_invalid", null);
		}

		if (usingRawRowset_ == false) {
			if (inputDesc_ != null) {
				if (!usingRawRowset_)
					valueArray = getValueArray();
				inDescLength = inputDesc_.length;
			}
		} else {
			valueArray = this.paramsValue_; // send it along raw in case we need
			// it
			paramRowCount_ -= 1; // we need to make sure that paramRowCount
			// stays exactly what we set it to since we
			// add one during execute
		}

		// *******************************************************************
		// * If LOB is involved with autocommit enabled we throw an exception
		// *******************************************************************
		if (isAnyLob_ && (connection_.getAutoCommit())) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_lob_commit_state", null);
		}

		execute(paramRowCount_ + 1, inDescLength, valueArray, queryTimeout_, isAnyLob_); 
		if (isAnyLob_) {


		}
		return ist_.getRowCount();
	}

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

		if (outputDesc_ != null) {
			return new HPT4ResultSetMetaData(this, outputDesc_);
		} else {
			return null;
		}
	}

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

	// JDK 1.2
	public void setArray(int parameterIndex, Array x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setArray", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setArray");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		HPT4Messages.throwUnsupportedFeatureException(connection_.props_, connection_.getLocale(), "setArray()");
	}

	public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setAsciiStream", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setAsciiStream");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long dataLocator;

		validateSetInvocation(parameterIndex);

		dataType = inputDesc_[parameterIndex - 1].dataType_;

		switch (dataType) {

			
		case Types.CHAR:
		case Types.VARCHAR:
		case Types.LONGVARCHAR:
		case Types.BINARY:  // At this time Database does not have
			// this column data type 
		case Types.VARBINARY:  // At this time Database does not
			// have this column data type //#endif-java
		case Types.LONGVARBINARY:  // At this time Database does not
			// have this column data type 
			byte[] buffer = new byte[length];
			try {
				x.read(buffer);
			} catch (java.io.IOException e) {
				Object[] messageArguments = new Object[1];
				messageArguments[0] = e.getMessage();
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
						messageArguments);
			}

			try {
				addParamValue(parameterIndex, new String(buffer, "ASCII"));
			} catch (java.io.UnsupportedEncodingException e) {
				Object[] messageArguments = new Object[1];
				messageArguments[0] = e.getMessage();
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"unsupported_encoding", messageArguments);
			}
			break;
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_datatype_for_column", null);
		}
	}

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

		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());

		if (x != null) {
			Utility.checkDecimalTruncation(parameterIndex, connection_.getLocale(), x,
					inputDesc_[parameterIndex - 1].precision_, inputDesc_[parameterIndex - 1].scale_);
			addParamValue(parameterIndex, x.toString());
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setBinaryStream",
					"setBinaryStream", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setBinaryStream");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long dataLocator;

		validateSetInvocation(parameterIndex);

		dataType = inputDesc_[parameterIndex - 1].dataType_;

		switch (dataType) {
		

		case Types.DOUBLE:
		case Types.DECIMAL:
		case Types.NUMERIC:
		case Types.FLOAT:
		case Types.BIGINT:
		case Types.INTEGER:
		case Types.SMALLINT:
		case Types.TINYINT:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_datatype_for_column", null);
		case Types.CHAR:
		case Types.VARCHAR:
		case Types.LONGVARCHAR:
		case Types.BINARY: // At this time Database does not have
			// this column data type 
		case Types.VARBINARY:  // At this time Database does not
			// have this column data type 
		case Types.LONGVARBINARY:  // At this time Database does not
			// have this column data type 
			byte[] buffer2 = new byte[length];

			try {
				int temp = x.read(buffer2);
			} catch (java.io.IOException e) {
				Object[] messageArguments = new Object[1];
				messageArguments[0] = e.getMessage();
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
						messageArguments);
			}
			addParamValue(parameterIndex, buffer2);
			break;
		default:
			byte[] buffer = new byte[length];

			try {
				x.read(buffer);
			} catch (java.io.IOException e) {
				Object[] messageArguments = new Object[1];
				messageArguments[0] = e.getMessage();
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
						messageArguments);
			}

			// addParamValue(parameterIndex, new String(buffer));
			// just pass the raw buffer.
			addParamValue(parameterIndex, buffer);
		}
	}

	/*
	 * Sets the designated parameter to the given <tt>Blob</tt> object. The
	 * driver converts this to an SQL <tt>BLOB</tt> value when it sends it to
	 * the database.
	 * 
	 * @param i the first parameter is 1, the second is 2, ... @param x a <tt>Blob</tt>
	 * object that maps an SQL <tt>BLOB</tt> value
	 * 
	 * @throws SQLException invalid data type for column
	 */
	public void setBlob(int parameterIndex, Blob x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setBlob", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setBlob");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long dataLocator;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		switch (dataType) {
		
			
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_datatype_for_column", null);
		}
	}

	public void setBoolean(int parameterIndex, boolean x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setBoolean", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setBoolean");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		if (x) {
			addParamValue(parameterIndex, "1"); // true
		} else {
			addParamValue(parameterIndex, "0"); // false
		}
	}

	public void setByte(int parameterIndex, byte x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setByte", "setByte", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setByte");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		addParamValue(parameterIndex, Byte.toString(x));
	}

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

		byte[] tmpArray = new byte[x.length];
		System.arraycopy(x, 0, tmpArray, 0, x.length);
		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		switch (dataType) {
		
			
		case Types.CHAR:
		case Types.VARCHAR:
		case Types.LONGVARCHAR:
		case Types.BINARY:
		case Types.VARBINARY:
		case Types.LONGVARBINARY:
			addParamValue(parameterIndex, tmpArray);
			break;
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
	}

	public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, reader, length);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setCharacterStream", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, reader, length);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setCharacterStream");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		char[] value;
		int dataType;
		long dataLocator;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		switch (dataType) {
		

		case Types.DECIMAL:
		case Types.DOUBLE:
		case Types.FLOAT:
		case Types.NUMERIC:
		case Types.BIGINT:
		case Types.INTEGER:
		case Types.SMALLINT:
		case Types.TINYINT:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_datatype_for_column", null);

		default:
			value = new char[length];
			try {
				int valuePos = reader.read(value);
				if (valuePos < 1) {
					Object[] messageArguments = new Object[1];
					messageArguments[0] = "No data to read from the Reader";
					throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
							messageArguments);
				}

				while (valuePos < length) {
					char temp[] = new char[length - valuePos];
					int tempReadLen = reader.read(temp, 0, length - valuePos);
					System.arraycopy(temp, 0, value, valuePos, tempReadLen);
					valuePos += tempReadLen;
				}
			} catch (java.io.IOException e) {
				Object[] messageArguments = new Object[1];
				messageArguments[0] = e.getMessage();
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
						messageArguments);
			}
			addParamValue(parameterIndex, new String(value));
			break;
		}
	}

	/**
	 * Sets the designated parameter to the given <tt>Clob</tt> object. The
	 * driver converts this to an SQL <tt>CLOB</tt> value when it sends it to
	 * the database.
	 * 
	 * @param parameterIndex
	 *            the first parameter is 1, the second is 2, ...
	 * @param x
	 *            a <tt>Clob</tt> object that maps an SQL <tt>CLOB</tt>
	 * 
	 * @throws SQLException
	 *             invalid data type for column, or restricted data type.
	 */
	public void setClob(int parameterIndex, Clob x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setClob", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setClob");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long dataLocator;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		switch (dataType) {
		
			
		case Types.DECIMAL:
		case Types.DOUBLE:
		case Types.FLOAT:
		case Types.NUMERIC:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_datatype_for_column", null);
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
	}

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

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.DATE && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		if (x != null) {
			if (dataType == Types.TIMESTAMP) {
				t1 = new Timestamp(x.getTime());
				addParamValue(parameterIndex, t1.toString());
			} else {
				addParamValue(parameterIndex, x.toString());
			}
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setDate", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setDate");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long dateValue;
		Date adjustedDate;
		Timestamp t1;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.DATE && dataType != Types.TIME && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		// Ignore the cal, since SQL would expect it to store it in the local
		// time zone
		if (x != null) {
			if (dataType == Types.TIMESTAMP) {
				t1 = new Timestamp(x.getTime());
				addParamValue(parameterIndex, t1.toString());
			} else {
				addParamValue(parameterIndex, x.toString());
			}
		} else {
			addParamValue(parameterIndex, null);

		}
	}

	public void setDouble(int parameterIndex, double x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setDouble", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setDouble");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		addParamValue(parameterIndex, Double.toString(x));
		inputDesc_[parameterIndex - 1].isValueSet_ = true;
	}

	public void setFloat(int parameterIndex, float x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setFloat", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setFloat");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		addParamValue(parameterIndex, Float.toString(x));
	}

	public void setInt(int parameterIndex, int x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setInt", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setInt");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		addParamValue(parameterIndex, Integer.toString(x));
	}

	public void setLong(int parameterIndex, long x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setLong", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setLong");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		Utility.checkLongBoundary(connection_.getLocale(), BigDecimal.valueOf(x));
		addParamValue(parameterIndex, Long.toString(x));
	}

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

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

	public void setObject(int parameterIndex, Object x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setObject", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setObject");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		if (x == null) {
			setNull(parameterIndex, Types.NULL);
		} else if (x instanceof BigDecimal) {
			setBigDecimal(parameterIndex, (BigDecimal) x);
		} else if (x instanceof java.sql.Date) {
			setDate(parameterIndex, (Date) x);
		} else if (x instanceof java.sql.Time) {
			setTime(parameterIndex, (Time) x);
		} else if (x instanceof java.sql.Timestamp) {
			setTimestamp(parameterIndex, (Timestamp) x);
		} else if (x instanceof Double) {
			setDouble(parameterIndex, ((Double) x).doubleValue());
		} else if (x instanceof Float) {
			setFloat(parameterIndex, ((Float) x).floatValue());
		} else if (x instanceof Long) {
			setLong(parameterIndex, ((Long) x).longValue());
		} else if (x instanceof Integer) {
			setInt(parameterIndex, ((Integer) x).intValue());
		} else if (x instanceof Short) {
			setShort(parameterIndex, ((Short) x).shortValue());
		} else if (x instanceof Byte) {
			setByte(parameterIndex, ((Byte) x).byteValue());
		} else if (x instanceof Boolean) {
			setBoolean(parameterIndex, ((Boolean) x).booleanValue());
		} else if (x instanceof String) {
			setString(parameterIndex, x.toString());
		} else if (x instanceof byte[]) {
			setBytes(parameterIndex, (byte[]) x);
		} else if (x instanceof Clob) {
			setClob(parameterIndex, (Clob) x);
		} else if (x instanceof Blob) {
			setBlob(parameterIndex, (Blob) x);
			/*
			 * else if (x instanceof DataWrapper) {
			 * validateSetInvocation(parameterIndex); setObject(parameterIndex,
			 * x, inputDesc_[parameterIndex - 1].dataType_); }
			 */
		} else if (x instanceof BigInteger) {
			setBigDecimal(parameterIndex, new BigDecimal((BigInteger) x));
		} else {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"object_type_not_supported", null);
		}
	}

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

	public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, targetSqlType, scale);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setObject", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, targetSqlType, scale);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setObject");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		BigDecimal tmpbd;
		int precision;
		Locale locale = connection_.getLocale();

		if (x == null) {
			setNull(parameterIndex, Types.NULL);
		} else {
			switch (targetSqlType) {
			case Types.CHAR:
			case Types.VARCHAR:
			case Types.LONGVARCHAR:
                        case Types.BLOB:
                        case Types.CLOB:
				setString(parameterIndex, x.toString());
				break;
			case Types.VARBINARY:
			case Types.BINARY:
			case Types.LONGVARBINARY:
				setBytes(parameterIndex, (byte[]) x);
				break;
			case Types.TIMESTAMP:
				if (x instanceof Timestamp) {
					setTimestamp(parameterIndex, (Timestamp) x);
				} else if (x instanceof Date) {
					setTimestamp(parameterIndex, Timestamp.valueOf(x.toString() + " 00:00:00.0"));
				} else {
					setString(parameterIndex, x.toString());
				}
				break;
			case Types.TIME:
				if (x instanceof Time) {
					setTime(parameterIndex, (Time) x);
				} else if (x instanceof Date) {
					setTime(parameterIndex, new Time(((Date) x).getTime()));
				} else if (x instanceof Timestamp) {
					setTime(parameterIndex, new Time(((Timestamp) x).getTime()));
				} else {
					setString(parameterIndex, x.toString());
				}
				break;
			case Types.DATE:
				try {
					if (x instanceof Date) {
						setDate(parameterIndex, (Date) x);
					} else if (x instanceof Time) {
						setDate(parameterIndex, new Date(((Time) x).getTime()));
					} else if (x instanceof Timestamp) {
						setDate(parameterIndex, new Date(((Timestamp) x).getTime()));
					} else {
						setDate(parameterIndex, Date.valueOf(x.toString()));
					}
				} catch (IllegalArgumentException iex) {
					throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
							"invalid_parameter_value", x.toString());
				}
				break;
			case Types.BOOLEAN:
				setBoolean(parameterIndex, (Boolean.valueOf(x.toString())).booleanValue());
				break;
			case Types.SMALLINT:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				Utility.checkShortBoundary(locale, tmpbd);
				//Utility.checkLongTruncation(parameterIndex, tmpbd);
				setShort(parameterIndex, tmpbd.shortValue());
				break;
			case Types.INTEGER:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				//Utility.checkLongTruncation(parameterIndex, tmpbd);
				//Utility.checkIntegerBoundary(locale, tmpbd);
				setInt(parameterIndex, tmpbd.intValue());
				break;
			case Types.BIGINT:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				Utility.checkLongBoundary(locale, tmpbd);
				//Utility.checkLongTruncation(parameterIndex, tmpbd);
				setLong(parameterIndex, tmpbd.longValue());
				break;
			case Types.DECIMAL:
				// precision = getPrecision(parameterIndex - 1);
				tmpbd = Utility.getBigDecimalValue(locale, x);
				tmpbd = Utility.setScale(tmpbd, scale, BigDecimal.ROUND_HALF_EVEN);
				// Utility.checkDecimalBoundary(locale, tmpbd, precision);
				setBigDecimal(parameterIndex, tmpbd);
				break;
			case Types.NUMERIC:
				// precision = getPrecision(parameterIndex - 1);
				tmpbd = Utility.getBigDecimalValue(locale, x);
				tmpbd = Utility.setScale(tmpbd, scale, BigDecimal.ROUND_HALF_EVEN);
				// Utility.checkDecimalBoundary(locale, tmpbd, precision);
				setBigDecimal(parameterIndex, tmpbd);
				break;
			case Types.TINYINT:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				tmpbd = Utility.setScale(tmpbd, scale, roundingMode_);
				Utility.checkTinyintBoundary(locale, tmpbd);
				setShort(parameterIndex, tmpbd.shortValue());
				break;
			case Types.FLOAT:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				Utility.checkFloatBoundary(locale, tmpbd);
				setDouble(parameterIndex, tmpbd.doubleValue());
				break;
			case Types.DOUBLE:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				Utility.checkDoubleBoundary(locale, tmpbd);
				setDouble(parameterIndex, tmpbd.doubleValue());
				break;
			case Types.REAL:
				tmpbd = Utility.getBigDecimalValue(locale, x);
				setFloat(parameterIndex, tmpbd.floatValue());
				break;
			case Types.OTHER:
				if (inputDesc_[parameterIndex].fsDataType_ == InterfaceResultSet.SQLTYPECODE_INTERVAL) {
					if (x instanceof byte[]) {
						addParamValue(parameterIndex, x);
					} else if (x instanceof String) {
						addParamValue(parameterIndex, x);
					} else {
						throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
								"conversion_not_allowed", null);
					}
					break;
				}
			case Types.ARRAY:
			case Types.BIT:
			case Types.DATALINK:
			case Types.DISTINCT:
			case Types.JAVA_OBJECT:
			case Types.STRUCT:
			default:
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"object_type_not_supported", null);
			}
		}
	}

	// JDK 1.2
	public void setRef(int i, Ref x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, i, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setRef", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, i, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setRef");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(i);
		HPT4Messages.throwUnsupportedFeatureException(connection_.props_, connection_.getLocale(), "setRef()");
	}

	public void setShort(int parameterIndex, short x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setShort", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setShort");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		inputDesc_[parameterIndex - 1].checkValidNumericConversion(connection_.getLocale());
		addParamValue(parameterIndex, Short.toString(x));
	}

	public void setString(int parameterIndex, String x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setString", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setString");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		int dataType = inputDesc_[parameterIndex - 1].dataType_;

		switch (dataType) {
		case Types.CHAR:
		case Types.VARCHAR:
		case Types.LONGVARCHAR:
		case Types.DATE:
		case Types.TIME:
		case Types.TIMESTAMP:
		case Types.OTHER: // This type maps to the Database 
			// INTERVAL
			addParamValue(parameterIndex, x);
			break;
			
			
		case Types.ARRAY:
		case Types.BINARY:
		case Types.BIT:
		case Types.DATALINK:
		case Types.JAVA_OBJECT:
		case Types.REF:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"datatype_not_supported", null);
		case Types.BIGINT:
		case Types.INTEGER:
		case Types.SMALLINT:
		case Types.TINYINT:
		case Types.DECIMAL:
		case Types.NUMERIC:
			if (x != null) {
				x = x.trim(); // SQLJ is using numeric string with
				// leading/trailing whitespace
			}
			setObject(parameterIndex, x, dataType);
			break;
		case Types.BLOB:
		case Types.BOOLEAN:
		case Types.DOUBLE:
		case Types.FLOAT:
		case Types.LONGVARBINARY:
		case Types.NULL:
		case Types.REAL:
		case Types.VARBINARY:
			setObject(parameterIndex, x, dataType);
			break;
		default:
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"fetch_output_inconsistent", null);
		}

	}

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

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.TIME && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		if (x != null) {
			if (dataType == Types.TIMESTAMP) {
				t1 = new Timestamp(x.getTime());
				addParamValue(parameterIndex, t1.toString());
			} else {
				addParamValue(parameterIndex, x.toString());
			}
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setTime", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setTime");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long timeValue;
		Time adjustedTime;
		Timestamp t1;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.TIME && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		// Ignore the cal, since SQL would expect it to store it in the local
		// time zone
		if (x != null) {
			if (dataType == Types.TIMESTAMP) {
				t1 = new Timestamp(x.getTime());
				addParamValue(parameterIndex, t1.toString());
			} else {
				addParamValue(parameterIndex, x.toString());
			}
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setTimestamp", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setTimestamp");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		Date d1;
		Time t1;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.DATE && dataType != Types.TIME && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		if (x != null) {
			switch (dataType) {
			case Types.DATE:
				d1 = new Date(x.getTime());
				addParamValue(parameterIndex, d1.toString());
				break;
			case Types.TIME:
				t1 = new Time(x.getTime());
				addParamValue(parameterIndex, t1.toString());
				break;
			default:
				addParamValue(parameterIndex, x.toString());
				break;
			}
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setTimestamp", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, cal);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setTimestamp");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		int dataType;
		long timeValue;
		Timestamp adjustedTime;
		Date d1;
		Time t1;

		validateSetInvocation(parameterIndex);
		dataType = inputDesc_[parameterIndex - 1].dataType_;
		if (dataType != Types.CHAR && dataType != Types.VARCHAR && dataType != Types.LONGVARCHAR
				&& dataType != Types.DATE && dataType != Types.TIME && dataType != Types.TIMESTAMP) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "restricted_data_type",
					null);
		}
		// Ignore the cal, since SQL would expect it to store it in the local
		// time zone
		if (x != null) {
			switch (dataType) {
			case Types.DATE:
				d1 = new Date(x.getTime());
				addParamValue(parameterIndex, d1.toString());
				break;
			case Types.TIME:
				t1 = new Time(x.getTime());
				addParamValue(parameterIndex, t1.toString());
				break;
			default:
				addParamValue(parameterIndex, x.toString());
				break;
			}
		} else {
			addParamValue(parameterIndex, null);
		}
	}

	public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setUnicodeStream", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x, length);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setUnicodeStream");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		byte[] buffer = new byte[length]; // length = number of bytes in
		// stream
		validateSetInvocation(parameterIndex);
		String s;

		if (x == null) {
			addParamValue(parameterIndex, null);
		} else {
			int dataType = inputDesc_[parameterIndex - 1].dataType_;
			switch (dataType) {
			case Types.DECIMAL:
			case Types.DOUBLE:
			case Types.FLOAT:
			case Types.NUMERIC:
			case Types.SMALLINT:
			case Types.INTEGER:
			case Types.BIGINT:
			case Types.TINYINT:
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
						"invalid_datatype_for_column", null);
			default:
				try {
					x.read(buffer, 0, length);
				} catch (java.io.IOException e) {
					Object[] messageArguments = new Object[1];
					messageArguments[0] = e.getMessage();
					throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "io_exception",
							messageArguments);
				}
				try {
					s = new String(buffer, "UnicodeBig");
					addParamValue(parameterIndex, s);
				} catch (java.io.UnsupportedEncodingException e) {
					Object[] messageArguments = new Object[1];
					messageArguments[0] = e.getMessage();
					throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
							"unsupported_encoding", messageArguments);
				}
				break;
			}
		}
	}

	public void setURL(int parameterIndex, URL x) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setURL", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setURL");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		validateSetInvocation(parameterIndex);
		HPT4Messages.throwUnsupportedFeatureException(connection_.props_, connection_.getLocale(), "setURL()");
	} // end setURL

	// -------------------------------------------------------------------------------------------
	/**
	 * This method will associate user defined data with the prepared statement.
	 * The user defined data must be in SQL/MX rowwise rowset format.
	 * 
	 * @param numRows
	 *            the number of rows contained in buffer
	 * @param buffer
	 *            a buffer containing the rows
	 * 
	 * @exception A
	 *                SQLException is thrown
	 */
	public void setDataBuffer(int numRows, ByteBuffer buffer) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, numRows, buffer);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "setDataBuffer", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, numRows, buffer);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("setDataBuffer");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		usingRawRowset_ = true;
		paramRowCount_ = numRows;
		rowwiseRowsetBuffer_ = buffer;
	} // end setDataBufferBuffer

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

	// Other methods
	protected void validateExecuteInvocation() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "validateExecuteInvocation", "", p);
		}
		clearWarnings();
		if (isClosed_) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "stmt_closed", null);
		}
		// 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();
			}
		}
		if (paramRowCount_ > 0 && usingRawRowset_ == false) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"function_sequence_error", null);
		}

		if (usingRawRowset_ == false)
			checkIfAllParamsSet();

	}

	private void checkIfAllParamsSet() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "checkIfAllParamsSet", "", p);
		}
		int paramNumber;

		if (inputDesc_ == null) {
			return;
		}
		for (paramNumber = 0; paramNumber < inputDesc_.length; paramNumber++) {
			if (!inputDesc_[paramNumber].isValueSet_) {
				Object[] messageArguments = new Object[2];
				messageArguments[0] = new Integer(paramNumber + 1);
				messageArguments[1] = new Integer(paramRowCount_ + 1);
				throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "parameter_not_set",
						messageArguments);
			}
		}
	}

	private void validateSetInvocation(int parameterIndex) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "validateSetInvocation", "", p);
		}
		if (isClosed_) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "stmt_closed", null);
		}
		// connection_.getServerHandle().isConnectionOpen();
		connection_.isConnectionOpen();
		if (inputDesc_ == null) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_parameter_index", null);
		}
		if (parameterIndex < 1 || parameterIndex > inputDesc_.length) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"invalid_parameter_index", null);
		}
		if (inputDesc_[parameterIndex - 1].paramMode_ == DatabaseMetaData.procedureColumnOut) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(), "is_a_output_parameter",
					null);
		}
	}

	void addParamValue(int parameterIndex, Object x) {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, parameterIndex, x);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "addParamValue", "", p);
		}

		paramsValue_[parameterIndex - 1] = x;
		inputDesc_[parameterIndex - 1].isValueSet_ = true;
	}

	Object[] getValueArray() {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "getValueArray", "", p);
		}
		Object[] valueArray;
		int length;
		int i;
		int j;
		int index;
		Object[] rows;

		if (paramRowCount_ > 0) {
			valueArray = new Object[(paramRowCount_ + 1) * inputDesc_.length];
			length = rowsValue_.size();
			for (i = 0, index = 0; i < length; i++) {
				rows = (Object[]) rowsValue_.get(i);
				for (j = 0; j < rows.length; j++, index++) {
					valueArray[index] = rows[j];
				}
			}
		} else {
			valueArray = paramsValue_;
		}
		return valueArray;
	}

	void logicalClose() throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "logicalClose", "", p);
		}
		isClosed_ = true;
		if (rowsValue_ != null) {
			rowsValue_.clear();
			
		}
		if (lobObjects_ != null) {
			lobObjects_.clear();

		}
		paramRowCount_ = 0;
		for (int i = 0; i < num_result_sets_; i++) {
			if (resultSet_[i] != null) {
				resultSet_[i].close();
				// Clear the isValueSet_ flag in inputDesc_
			}
		}
		result_set_offset = 0;
		resultSet_[result_set_offset] = null;
		if (inputDesc_ != null) {
			for (int i = 0; i < inputDesc_.length; i++) {
				inputDesc_[i].isValueSet_ = false;
				paramsValue_[i] = null;
			}
		}
		isAnyLob_ = false;
		if (!connection_.closePreparedStatement(connection_, sql_, resultSetType_, resultSetConcurrency_,
				resultSetHoldability_)) {
			this.close(true); // if the statement is not in the cache
			// hardclose it afterall
		}

	}

	// ----------------------------------------------------------------------------------
	// Method used by JNI Layer to update the results of Prepare
	void setPrepareOutputs(HPT4Desc[] inputDesc, HPT4Desc[] outputDesc, int inputParamCount, int outputParamCount)
			throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, inputDesc, outputDesc, inputParamCount,
					outputParamCount);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "setPrepareOutputs", "", p);
		}
		inputDesc_ = inputDesc;
		outputDesc_ = outputDesc;
		paramRowCount_ = 0;

		// Prepare updares inputDesc_ and outputDesc_
		if (inputDesc_ != null) {
			paramsValue_ = new Object[inputDesc_.length];
		} else {
			paramsValue_ = null;
		}
	} // end setPrepareOutputs

	// ----------------------------------------------------------------------------------
	void setPrepareOutputs2(HPT4Desc[] inputDesc, HPT4Desc[] outputDesc, int inputParamCount, int outputParamCount,
			int inputParamsLength, int outputParamsLength, int inputDescLength, int outputDescLength)
			throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, inputDesc, outputDesc, inputParamCount,
					outputParamCount, inputParamsLength, outputParamsLength, inputDescLength, outputDescLength);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "setPrepareOutputs2", "", p);
		}
		inputParamCount_ = inputParamCount;
		outputParamCount_ = outputParamCount;
		inputParamsLength_ = inputParamsLength;
		outputParamsLength_ = outputParamsLength;
		inputDescLength_ = inputDescLength;
		outputDescLength_ = outputDescLength;
		setPrepareOutputs(inputDesc, outputDesc, inputParamCount, outputParamCount);
	} // end setPrepareOutputs2

	// ----------------------------------------------------------------------------------
	// Method used by JNI layer to update the results of Execute
	void setExecuteOutputs(int rowCount) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, rowCount);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "setExecuteOutputs", "", p);
		}
		batchRowCount_ = new int[1];
		batchRowCount_[0] = rowCount;
		num_result_sets_ = 1;
		result_set_offset = 0;
		if (outputDesc_ != null) {
			resultSet_[result_set_offset] = new TrafT4ResultSet(this, outputDesc_);
		} else {
			resultSet_[result_set_offset] = null;
		}
	}

	/*
	 * //----------------------------------------------------------------------------------
	 * void setExecuteSingletonOutputs(SQLValue_def[] sqlValue_def_array, short
	 * rowsAffected) throws SQLException { batchRowCount_ = new int[1];
	 * batchRowCount_[0] = rowsAffected; if (outputDesc_ != null) { resultSet_ =
	 * new TrafT4ResultSet(this, outputDesc_); } else { resultSet_ = null; } if
	 * (rowsAffected == 0) { resultSet_.setFetchOutputs(new ObjectRow[0], 0, true, 0); }
	 * else { resultSet_.irs_.setSingletonFetchOutputs(resultSet_, rowsAffected,
	 * true, 0, sqlValue_def_array); } }
	 */

	// ----------------------------------------------------------------------------------
	// Method used by JNI layer to update the results of Execute
	void setExecuteBatchOutputs(int[] rowCount) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, rowCount);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "setExecuteBatchOutputs", "", p);
		}
		num_result_sets_ = 1;
		result_set_offset = 0;
		if (outputDesc_ != null) {
			resultSet_[result_set_offset] = new TrafT4ResultSet(this, outputDesc_);
		} else {
			resultSet_[result_set_offset] = null;
		}
		batchRowCount_ = rowCount;
	}

	void reuse(TrafT4Connection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "reuse", "", p);
		}
		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;
			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);
		}
		resultSetConcurrency_ = resultSetConcurrency;
		resultSetHoldability_ = resultSetHoldability;
		queryTimeout_ = connection_.getServerHandle().getQueryTimeout();
		fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		maxRows_ = 0;
		fetchDirection_ = ResultSet.FETCH_FORWARD;
		isClosed_ = false;
	}

	public void close(boolean hardClose) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, hardClose);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "close", "", p);
		}

		if (connection_._isClosed()) {
			return;
		}
		try {
			if (hardClose) {
				ist_.close();
			} else {
				logicalClose();
			}
		} catch (SQLException e) {
			performConnectionErrorChecks(e);
			throw e;
		} finally {
			isClosed_ = true;
			if (hardClose) {
				connection_.removeElement(pRef_);
			}
		}

	}


	TrafT4PreparedStatement(TrafT4Connection connection, String sql, String stmtLabel) throws SQLException {
		this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, connection.holdability_,
				stmtLabel);
		connection.ic_.t4props_.setUseArrayBinding(false);
		connection.ic_.t4props_.setBatchRecovery(false);
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "",
					"Note, this call is before previous constructor call.", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
	}

	// Constructors with access specifier as "default"
	TrafT4PreparedStatement(TrafT4Connection connection, String sql) throws SQLException {
		this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, connection.holdability_);
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "",
					"Note, this call is before previous constructor call.", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
	}

	TrafT4PreparedStatement(TrafT4Connection connection, String sql, int resultSetType, int resultSetConcurrency)
			throws SQLException {
		this(connection, sql, resultSetType, resultSetConcurrency, connection.holdability_);
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "",
					"Note, this call is before previous constructor call.", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}

	}
	TrafT4PreparedStatement(TrafT4Connection connection, String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability, String stmtLabel) throws SQLException {
		super(connection, resultSetType, resultSetConcurrency, resultSetHoldability, stmtLabel);
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "",
					"Note, this call is before previous constructor call.", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		// connection_.getServerHandle().isConnectionOpen();
		connection_.isConnectionOpen();
		sqlStmtType_ = ist_.getSqlStmtType(sql);
		if (sqlStmtType_ == TRANSPORT.TYPE_STATS) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"infostats_invalid_error", null);
		} else if (sqlStmtType_ == TRANSPORT.TYPE_CONFIG) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"config_cmd_invalid_error", null);
		}
		ist_.setTransactionStatus(connection_, sql);
		sql_ = sql;


		// stmtLabel_ = generateStmtLabel();
		stmtLabel_ = stmtLabel;
		// System.out.println("TrafT4PreparedStatement stmtLabel_ " + stmtLabel_);

		usingRawRowset_ = false;
	}

	TrafT4PreparedStatement(TrafT4Connection connection, String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability) throws SQLException {
		super(connection, resultSetType, resultSetConcurrency, resultSetHoldability);
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "",
					"Note, this call is before previous constructor call.", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, connection, sql, resultSetType,
					resultSetConcurrency, resultSetHoldability);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		// connection_.getServerHandle().isConnectionOpen();
		connection_.isConnectionOpen();
		sqlStmtType_ = ist_.getSqlStmtType(sql);
		if (sqlStmtType_ == TRANSPORT.TYPE_STATS) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"infostats_invalid_error", null);
		} else if (sqlStmtType_ == TRANSPORT.TYPE_CONFIG) {
			throw HPT4Messages.createSQLException(connection_.props_, connection_.getLocale(),
					"config_cmd_invalid_error", null);
		}
		ist_.setTransactionStatus(connection_, sql);
		sql_ = sql;


		//stmtLabel_ = generateStmtLabel();

		usingRawRowset_ = false;
	}

	TrafT4PreparedStatement(TrafT4Connection connection, String moduleName, int moduleVersion, long moduleTimestamp,
			String stmtName, boolean isSelect, int holdability) {
		if (connection.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, moduleName, moduleVersion,
					moduleTimestamp, stmtName, isSelect, holdability);
			connection.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "", "", p);
		}
		try {
			if (connection.props_.getLogWriter() != null) {
				LogRecord lr = new LogRecord(Level.FINE, "");
				Object p[] = T4LoggingUtilities.makeParams(connection.props_, connection, moduleName, moduleVersion,
						moduleTimestamp, stmtName, isSelect, holdability);
				lr.setParameters(p);
				lr.setSourceClassName("TrafT4PreparedStatement");
				lr.setSourceMethodName("");
				T4LogFormatter lf = new T4LogFormatter();
				String temp = lf.format(lr);
				connection.props_.getLogWriter().println(temp);
			}
		} catch (SQLException se) {
			// ignore
		}
		connection_ = connection;
		moduleName_ = moduleName;
		moduleVersion_ = moduleVersion;
		moduleTimestamp_ = moduleTimestamp;
		stmtLabel_ = stmtName;
		sqlStmtType_ = (isSelect) ? TRANSPORT.TYPE_SELECT : TRANSPORT.TYPE_UNKNOWN;
		usingRawRowset_ = false;

		// Make Sure you initialize the other fields to the right value
		fetchSize_ = TrafT4ResultSet.DEFAULT_FETCH_SIZE;
		maxRows_ = 0;
		fetchDirection_ = ResultSet.FETCH_FORWARD;
		queryTimeout_ = connection_.getServerHandle().getQueryTimeout();
		resultSetType_ = ResultSet.TYPE_FORWARD_ONLY;
		resultSetHoldability_ = holdability;
		usingRawRowset_ = false;
	}

	// Interface methods
	public void prepare(String sql, int queryTimeout, int holdability) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, queryTimeout, holdability);
			connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PreparedStatement", "prepare", "", p);
		}
		if (connection_.props_.getLogWriter() != null) {
			LogRecord lr = new LogRecord(Level.FINE, "");
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, sql, queryTimeout, holdability);
			lr.setParameters(p);
			lr.setSourceClassName("TrafT4PreparedStatement");
			lr.setSourceMethodName("prepare");
			T4LogFormatter lf = new T4LogFormatter();
			String temp = lf.format(lr);
			connection_.props_.getLogWriter().println(temp);
		}
		try {
			super.ist_.prepare(sql, queryTimeout, this);
		} catch (SQLException e) {
			performConnectionErrorChecks(e);
			throw e;
		}
	};

	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, "SQLMXPreparedStatement", "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("SQLMXPreparedStatement");
			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_fetchSize_value", null);
		}
		if (rows > 0) {
			fetchSize_ = rows;
		}
		// If the value specified is zero, then the hint is ignored.
	}

	private void execute(int paramRowCount, int paramCount, Object[] paramValues, int queryTimeout, boolean isAnyLob
	) throws SQLException {
		if (connection_.props_.t4Logger_.isLoggable(Level.FINER) == true) {
			Object p[] = T4LoggingUtilities.makeParams(connection_.props_, paramRowCount, paramCount, paramValues,
					queryTimeout, isAnyLob);
			connection_.props_.t4Logger_.logp(Level.FINER, "TrafT4PreparedStatement", "execute", "", p);
		}
		try {
			ist_.execute(TRANSPORT.SRVR_API_SQLEXECUTE2, paramRowCount, paramCount, paramValues, queryTimeout, null,
					this);
		} catch (SQLException e) {
			performConnectionErrorChecks(e);
			throw e;
		}
	};

	/*
	 * protected void setSingleton(boolean value) { singleton_ = value; }
	 * protected boolean getSingleton() { return singleton_; }
	 */

	/**
	 * Use this method to retrieve the statement type that was used when
	 * creating the statement through the connectivity service. ie. SELECT,
	 * UPDATE, DELETE, INSERT.
	 */
	public String getStatementType() {
		String stmtType = "";

		switch (sqlStmtType_) {
		case TRANSPORT.TYPE_SELECT:
			stmtType = "SELECT";
			break;
		case TRANSPORT.TYPE_UPDATE:
			stmtType = "UPDATE";
			break;
		case TRANSPORT.TYPE_DELETE:
			stmtType = "DELETE";
			break;
		case TRANSPORT.TYPE_INSERT:
		case TRANSPORT.TYPE_INSERT_PARAM:
			stmtType = "INSERT";
			break;
		case TRANSPORT.TYPE_CREATE:
			stmtType = "CREATE";
			break;
		case TRANSPORT.TYPE_GRANT:
			stmtType = "GRANT";
			break;
		case TRANSPORT.TYPE_DROP:
			stmtType = "DROP";
			break;
		case TRANSPORT.TYPE_CALL:
			stmtType = "CALL";
			break;
		case TRANSPORT.TYPE_EXPLAIN:
			stmtType = "EXPLAIN";
			break;
		case TRANSPORT.TYPE_STATS:
			stmtType = "INFOSTATS";
			break;
		case TRANSPORT.TYPE_CONFIG:
			stmtType = "CONFIG";
			break;
		default:
			stmtType = "";
			break;
		}

		return stmtType;
	}

	/**
	 * Use this method to retrieve the statement type that was used when
	 * creating the statement through the connectivity service. ie. SELECT,
	 * UPDATE, DELETE, INSERT.
	 */
	public short getStatementTypeShort() {
		return sqlStmtType_;
	}

	/**
	 * Use this method to retrieve the statement type that was used when
	 * creating the statement through the connectivity service. ie. SELECT,
	 * UPDATE, DELETE, INSERT.
	 */
	public int getStatementTypeInt() {
		return ist_.getSqlQueryType();
	}

	ArrayList getKeyColumns() {
		return keyColumns;
	}

	void setKeyColumns(ArrayList keyColumns) {
		this.keyColumns = keyColumns;
	}

	ArrayList keyColumns = null;

	int paramRowCount_;
	String moduleName_;
	int moduleVersion_;
	long moduleTimestamp_;
	boolean isAnyLob_; 
	ArrayList lobObjects_; 

	ArrayList rowsValue_;
	Object[] paramsValue_;

	// boolean singleton_ = false;

	// ================ SQL Statement type ====================
	public static final short TYPE_UNKNOWN = 0;
	public static final short TYPE_SELECT = 0x0001;
	public static final short TYPE_UPDATE = 0x0002;
	public static final short TYPE_DELETE = 0x0004;
	public static final short TYPE_INSERT = 0x0008;
	public static final short TYPE_EXPLAIN = 0x0010;
	public static final short TYPE_CREATE = 0x0020;
	public static final short TYPE_GRANT = 0x0040;
	public static final short TYPE_DROP = 0x0080;
	public static final short TYPE_INSERT_PARAM = 0x0100;
	public static final short TYPE_SELECT_CATALOG = 0x0200;
	public static final short TYPE_SMD = 0x0400;
	public static final short TYPE_CALL = 0x0800;
	public static final short TYPE_STATS = 0x1000;
	public static final short TYPE_CONFIG = 0x2000;

	// =================== SQL Query ===================
	public static final int SQL_OTHER = -1;
	public static final int SQL_UNKNOWN = 0;
	public static final int SQL_SELECT_UNIQUE = 1;
	public static final int SQL_SELECT_NON_UNIQUE = 2;
	public static final int SQL_INSERT_UNIQUE = 3;
	public static final int SQL_INSERT_NON_UNIQUE = 4;
	public static final int SQL_UPDATE_UNIQUE = 5;
	public static final int SQL_UPDATE_NON_UNIQUE = 6;
	public static final int SQL_DELETE_UNIQUE = 7;
	public static final int SQL_DELETE_NON_UNIQUE = 8;
	public static final int SQL_CONTROL = 9;
	public static final int SQL_SET_TRANSACTION = 10;
	public static final int SQL_SET_CATALOG = 11;
	public static final int SQL_SET_SCHEMA = 12;

	// =================== new identifiers ===================
	public static final int SQL_CREATE_TABLE = SQL_SET_SCHEMA + 1;
	public static final int SQL_CREATE_VIEW = SQL_CREATE_TABLE + 1;
	public static final int SQL_CREATE_INDEX = SQL_CREATE_VIEW + 1;
	public static final int SQL_CREATE_UNIQUE_INDEX = SQL_CREATE_INDEX + 1;
	public static final int SQL_CREATE_SYNONYM = SQL_CREATE_UNIQUE_INDEX + 1;
	public static final int SQL_CREATE_VOLATILE_TABLE = SQL_CREATE_SYNONYM + 1;;
	public static final int SQL_CREATE_MV = SQL_CREATE_VOLATILE_TABLE + 1;
	public static final int SQL_CREATE_MVG = SQL_CREATE_MV + 1;
	public static final int SQL_CREATE_MP_ALIAS = SQL_CREATE_MVG + 1;
	public static final int SQL_CREATE_PROCEDURE = SQL_CREATE_MP_ALIAS + 1;
	public static final int SQL_CREATE_TRIGGER = SQL_CREATE_PROCEDURE + 1;
	public static final int SQL_CREATE_SET_TABLE = SQL_CREATE_TRIGGER + 1;
	public static final int SQL_CREATE_MULTISET_TABLE = SQL_CREATE_SET_TABLE + 1;

	public static final int SQL_DROP_TABLE = SQL_CREATE_MULTISET_TABLE + 1;
	public static final int SQL_DROP_VIEW = SQL_DROP_TABLE + 1;
	public static final int SQL_DROP_INDEX = SQL_DROP_VIEW + 1;
	public static final int SQL_DROP_SYNONYM = SQL_DROP_INDEX + 1;
	public static final int SQL_DROP_VOLATILE_TABLE = SQL_DROP_SYNONYM + 1;;
	public static final int SQL_DROP_MV = SQL_DROP_VOLATILE_TABLE + 1;
	public static final int SQL_DROP_MVG = SQL_DROP_MV + 1;
	public static final int SQL_DROP_MP_ALIAS = SQL_DROP_MVG + 1;
	public static final int SQL_DROP_PROCEDURE = SQL_DROP_MP_ALIAS + 1;
	public static final int SQL_DROP_TRIGGER = SQL_DROP_PROCEDURE + 1;
	public static final int SQL_DROP_SET_TABLE = SQL_DROP_TRIGGER + 1;
	public static final int SQL_DROP_MULTISET_TABLE = SQL_DROP_SET_TABLE + 1;

	public static final int SQL_ALTER_TABLE = SQL_DROP_MULTISET_TABLE + 1;
	public static final int SQL_ALTER_INDEX = SQL_ALTER_TABLE + 1;
	public static final int SQL_ALTER_TRIGGER = SQL_ALTER_INDEX + 1;
	public static final int SQL_ALTER_MP_ALIAS = SQL_ALTER_TRIGGER + 1;
	public boolean isClosed() throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	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;
	}

	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 void setRowId(int parameterIndex, RowId x) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setNString(int parameterIndex, String value)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}
	
	public void setNCharacterStream(int parameterIndex, Reader value,
			long length) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setNClob(int parameterIndex, NClob value) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setClob(int parameterIndex, Reader reader, long length)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setBlob(int parameterIndex, InputStream inputStream, long length)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setNClob(int parameterIndex, Reader reader, long length)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setSQLXML(int parameterIndex, SQLXML xmlObject)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setAsciiStream(int parameterIndex, InputStream x, long length)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setBinaryStream(int parameterIndex, InputStream x, long length)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setCharacterStream(int parameterIndex, Reader reader,
			long length) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setAsciiStream(int parameterIndex, InputStream x)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setBinaryStream(int parameterIndex, InputStream x)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setCharacterStream(int parameterIndex, Reader reader)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setNCharacterStream(int parameterIndex, Reader value)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setClob(int parameterIndex, Reader reader) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setBlob(int parameterIndex, InputStream inputStream)
			throws SQLException {
		// TODO Auto-generated method stub
		
	}

	public void setNClob(int parameterIndex, Reader reader) throws SQLException {
		// TODO Auto-generated method stub
		
	}

}
