blob: 8dbbc2f7f8bb7fac3c1d849db66b36854a1c3c97 [file] [log] [blame]
// @@@ 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.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.util.Properties;
import java.util.logging.Level;
class InterfaceResultSet {
InterfaceConnection ic_;
String stmtLabel_;
/* CHAR/CHARACTER */
static final int SQLTYPECODE_CHAR = 1;
/* NUMERIC */
static final int SQLTYPECODE_NUMERIC = 2;
static final int SQLTYPECODE_NUMERIC_UNSIGNED = -201;
/* DECIMAL */
static final int SQLTYPECODE_DECIMAL = 3;
static final int SQLTYPECODE_DECIMAL_UNSIGNED = -301;
static final int SQLTYPECODE_DECIMAL_LARGE = -302;
static final int SQLTYPECODE_DECIMAL_LARGE_UNSIGNED = -303;
/* INTEGER/INT */
static final int SQLTYPECODE_INTEGER = 4;
static final int SQLTYPECODE_INTEGER_UNSIGNED = -401;
static final int SQLTYPECODE_LARGEINT = -402;
/* SMALLINT */
static final int SQLTYPECODE_SMALLINT = 5;
static final int SQLTYPECODE_SMALLINT_UNSIGNED = -502;
static final int SQLTYPECODE_BPINT_UNSIGNED = -503;
/*
* DOUBLE depending on precision
*/
static final int SQLTYPECODE_FLOAT = 6;
/*
*/
static final int SQLTYPECODE_REAL = 7;
/*
*/
static final int SQLTYPECODE_DOUBLE = 8;
/* DATE,TIME,TIMESTAMP */
static final int SQLTYPECODE_DATETIME = 9;
/* TIMESTAMP */
static final int SQLTYPECODE_INTERVAL = 10;
/* no ANSI value 11 */
/* VARCHAR/CHARACTER VARYING */
static final int SQLTYPECODE_VARCHAR = 12;
/* SQL/MP stype VARCHAR with length prefix:
* */
static final int SQLTYPECODE_VARCHAR_WITH_LENGTH = -601;
static final int SQLTYPECODE_BLOB = -602;
static final int SQLTYPECODE_CLOB = -603;
/* LONG VARCHAR/ODBC CHARACTER VARYING */
static final int SQLTYPECODE_VARCHAR_LONG = -1; /* ## NEGATIVE??? */
/* no ANSI value 13 */
/* BIT */
static final int SQLTYPECODE_BIT = 14; /* not supported */
/* BIT VARYING */
static final int SQLTYPECODE_BITVAR = 15; /* not supported */
/* NCHAR -- CHAR(n) CHARACTER SET s -- where s uses two bytes per char */
static final int SQLTYPECODE_CHAR_DBLBYTE = 16;
/* NCHAR VARYING -- VARCHAR(n) CHARACTER SET s -- s uses 2 bytes per char */
static final int SQLTYPECODE_VARCHAR_DBLBYTE = 17;
/* Date/Time/TimeStamp related constants */
static final int SQLDTCODE_DATE = 1;
static final int SQLDTCODE_TIME = 2;
static final int SQLDTCODE_TIMESTAMP = 3;
static final int SQLDTCODE_MPDATETIME = 4;
static final int dateLength = 10;
static final int timeLength = 8;
static final int timestampLength = 26;
T4ResultSet t4resultSet_;
static Properties javaLangToJavaNio = null;
TrafT4ResultSet rs_;
InterfaceResultSet(TrafT4ResultSet rs) throws SQLException {
this.ic_ = ((TrafT4Connection) rs.connection_).getServerHandle();
stmtLabel_ = rs.stmtLabel_;
t4resultSet_ = new T4ResultSet(this);
rs_ = rs;
};
// -------------------------------------------------------------------
// from nskieee.cpp -- find the length for the data based on datatype
//
static int dataLengthFetchPerf(int SQLDataType, int SQLDateTimeCode, int SQLOctetLength, int maxRowLen,
int bufferLen, int ODBCDataType, int ODBCPrecision) {
int allocLength = 0;
switch (SQLDataType) {
case SQLTYPECODE_INTERVAL:
allocLength = SQLOctetLength;
break;
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
case SQLTYPECODE_VARCHAR_LONG:
case SQLTYPECODE_VARCHAR_DBLBYTE:
case SQLTYPECODE_BITVAR:
case SQLTYPECODE_BLOB:
case SQLTYPECODE_CLOB:
allocLength = bufferLen + 2;
break;
case SQLTYPECODE_CHAR:
// allocLength = SQLOctetLength - 1; // no null at the end
allocLength = SQLOctetLength;
if (maxRowLen > 0) {
allocLength = (allocLength > maxRowLen) ? (maxRowLen + 1) : (allocLength);
}
break;
case SQLTYPECODE_BIT:
case SQLTYPECODE_CHAR_DBLBYTE:
case SQLTYPECODE_VARCHAR:
allocLength = SQLOctetLength - 1; // no null at the end
if (maxRowLen > 0) {
allocLength = (allocLength > maxRowLen) ? (maxRowLen + 1) : (allocLength);
}
break;
case SQLTYPECODE_DATETIME:
switch (SQLDateTimeCode) {
case SQLDTCODE_DATE:
allocLength = dateLength;
break;
case SQLDTCODE_TIME:
if (ODBCDataType == java.sql.Types.OTHER) // For
// HPT4Desc.SQLDTCODE_HOUR_TO_FRACTION
{
allocLength = SQLOctetLength;
} else {
allocLength = timeLength;
}
break;
case SQLDTCODE_TIMESTAMP:
/*
* allocLength = timestampLength; if (SQLOctetLength <
* timestampLength) { allocLength = 19; // timestamp without
* fraction }
*/
allocLength = ODBCPrecision;
break;
default:
allocLength = SQLOctetLength;
break;
}
break;
default:
allocLength = SQLOctetLength; // exclude nullable
break;
}
return allocLength;
}
// -------------------------------------------------------------------
// get the column value data in String format
Object getFetchString(TrafT4Connection conn, int scale, int SQLDataType, int SQLDatetimeCode, int FSDataType,
byte[] ibuffer, int byteIndex, int byteLen, int SQLcharset, int ODBCDataType) throws SQLException {
Object retObj;
String tmpStr;
byte[] tbuffer;
BigDecimal tmpbd;
switch (SQLDataType) {
case SQLTYPECODE_CHAR:
tbuffer = new byte[byteLen];
System.arraycopy(ibuffer, byteIndex, tbuffer, 0, byteLen);
retObj = tbuffer;
break;
case SQLTYPECODE_VARCHAR:
tbuffer = new byte[byteLen];
System.arraycopy(ibuffer, byteIndex, tbuffer, 0, byteLen);
retObj = tbuffer;
break;
case SQLTYPECODE_INTERVAL:
tbuffer = new byte[byteLen];
System.arraycopy(ibuffer, byteIndex, tbuffer, 0, byteLen);
retObj = tbuffer;
break;
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
case SQLTYPECODE_VARCHAR_LONG:
case SQLTYPECODE_BLOB:
case SQLTYPECODE_CLOB:
tbuffer = new byte[byteLen - 2];
System.arraycopy(ibuffer, byteIndex + 2, tbuffer, 0, byteLen - 2);
// retObj = new String(tbuffer); Swastik for LOB Support 10/29/2004
retObj = tbuffer;
break;
case SQLTYPECODE_DATETIME:
tmpStr = new String(Bytes.read_chars(ibuffer, byteIndex, byteLen));
switch (SQLDatetimeCode) {
case SQLDTCODE_DATE:
retObj = Date.valueOf(tmpStr);
break;
case SQLDTCODE_TIMESTAMP:
retObj = Timestamp.valueOf(tmpStr);
break;
case SQLDTCODE_TIME:
// Need to add code here to check if it's
// HPT4Desc.SQLDTCODE_HOUR_TO_FRACTION
if (ODBCDataType != java.sql.Types.OTHER) {
retObj = Time.valueOf(tmpStr);
break;
} else {
// Do default processing as it is
// HPT4Desc.SQLDTCODE_HOUR_TO_FRACTION
}
default:
retObj = tmpStr;
break;
}
break;
case SQLTYPECODE_SMALLINT:
short sValue = Bytes.extractShort(ibuffer, byteIndex, this.ic_.getByteSwap());
retObj = new Short(sValue);
if (scale > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), scale);
}
break;
case SQLTYPECODE_SMALLINT_UNSIGNED:
retObj = new Integer(Bytes.extractUShort(ibuffer, byteIndex, this.ic_.getByteSwap()));
if (scale > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), scale);
}
break;
case SQLTYPECODE_INTEGER:
retObj = new Integer(Bytes.extractInt(ibuffer, byteIndex, this.ic_.getByteSwap()));
if (scale > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), scale);
}
break;
case SQLTYPECODE_INTEGER_UNSIGNED:
retObj = new Long(Bytes.extractUInt(ibuffer, byteIndex, this.ic_.getByteSwap()));
if (scale > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), scale);
}
break;
case SQLTYPECODE_LARGEINT:
tbuffer = new byte[byteLen];
System.arraycopy(ibuffer, byteIndex, tbuffer, 0, byteLen);
retObj = new BigInteger(tbuffer);
if (scale > 0) {
retObj = new BigDecimal((BigInteger) retObj, scale);
}
break;
case SQLTYPECODE_NUMERIC:
case SQLTYPECODE_NUMERIC_UNSIGNED:
switch (FSDataType) {
case 130:
case 131:
tmpStr = String.valueOf(Bytes.extractShort(ibuffer, byteIndex, this.ic_.getByteSwap()));
break;
case 132:
case 133:
tmpStr = String.valueOf(Bytes.extractInt(ibuffer, byteIndex, this.ic_.getByteSwap()));
break;
case 134:
tmpStr = String.valueOf(Bytes.extractLong(ibuffer, byteIndex, this.ic_.getByteSwap()));
break;
default:
throw HPT4Messages.createSQLException(conn.props_, conn.getLocale(), "restricted_data_type", null);
}
retObj = new BigDecimal((new BigInteger(tmpStr)), scale);
break;
case SQLTYPECODE_DECIMAL:
case SQLTYPECODE_DECIMAL_UNSIGNED:
case SQLTYPECODE_DECIMAL_LARGE:
case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED:
String retStr;
// check if the sign is minus (-80)
byte sign = (byte) (ibuffer[byteIndex] & (byte) (-80));
// first byte = inbyte - (-80)
if (sign == (byte) (-80)) {
byte firstByte = (byte) (ibuffer[byteIndex] - (byte) (-80));
retStr = "-" + firstByte + String.valueOf(Bytes.read_chars(ibuffer, byteIndex + 1, byteLen - 1));
} else {
retStr = String.valueOf(Bytes.read_chars(ibuffer, byteIndex, byteLen));
}
retObj = new BigDecimal(new BigInteger(retStr), scale);
break;
case SQLTYPECODE_REAL:
retObj = new Float(Float.intBitsToFloat(Bytes.extractInt(ibuffer, byteIndex, this.ic_.getByteSwap())));
break;
case SQLTYPECODE_DOUBLE:
case SQLTYPECODE_FLOAT:
retObj = new Double(Double.longBitsToDouble(Bytes.extractLong(ibuffer, byteIndex, this.ic_.getByteSwap())));
break;
case SQLTYPECODE_BIT:
case SQLTYPECODE_BITVAR:
case SQLTYPECODE_BPINT_UNSIGNED:
default:
throw HPT4Messages.createSQLException(conn.props_, conn.getLocale(), "restricted_data_type", null);
}
return retObj;
} // end getFetchString
private static String padZero(long i, int len) {
String s = String.valueOf(i);
while (s.length() < len)
s = '0' + s;
return s;
}
// -------------------------------------------------------------------
// get the column value data from Execute2 in String format
static Object getExecute2FetchString(TrafT4Connection conn, HPT4Desc desc, byte[] values, int noNullValue,
int ODBCDataType, boolean useOldDateFormat, boolean swap) throws SQLException {
Object retObj;
String tmpStr;
byte[] tbuffer;
BigDecimal tmpbd;
int length;
int year, month, day, hour, minute, second;
long nanoSeconds;
switch (desc.sqlDataType_) {
case SQLTYPECODE_CHAR:
length = desc.sqlOctetLength_;
tbuffer = new byte[length];
System.arraycopy(values, noNullValue, tbuffer, 0, length);
retObj = tbuffer;
break;
case SQLTYPECODE_VARCHAR:
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
case SQLTYPECODE_VARCHAR_LONG:
case SQLTYPECODE_BLOB:
case SQLTYPECODE_CLOB:
boolean shortLength = desc.precision_ < Math.pow(2, 15);
int dataOffset = noNullValue + ((shortLength) ? 2 : 4);
length = (shortLength) ? Bytes.extractShort(values, noNullValue, swap) : Bytes.extractInt(values, noNullValue, swap);
tbuffer = new byte[length];
int len = values.length - (dataOffset);
System.arraycopy(values, (dataOffset), tbuffer, 0, (length > len) ? len : length);
retObj = tbuffer;
break;
case SQLTYPECODE_INTERVAL:
length = desc.sqlOctetLength_;
tbuffer = new byte[length];
System.arraycopy(values, noNullValue, tbuffer, 0, length);
retObj = tbuffer;
break;
case SQLTYPECODE_DATETIME:
switch (desc.sqlDatetimeCode_) {
case SQLDTCODE_DATE:
if (!useOldDateFormat) // new date format, only for bulk move
{
// "yyyy-mm-dd"
year = Bytes.extractUShort(values, noNullValue, swap);
month = values[noNullValue + 2];
day = values[noNullValue + 3];
String t = padZero(year,4) + "-" + padZero(month,2) + "-" + padZero(day,2);
retObj = Date.valueOf(t);
} else {// do the old way
length = dateLength;
retObj = Date.valueOf(new String(Bytes.read_chars(values, noNullValue, length)));
}
break;
case SQLDTCODE_TIMESTAMP:
if (!useOldDateFormat) // new date format, if not SQLCatalogs
{
// yyyy-mm-dd hh:mm:ss.fffffffff
year = Bytes.extractUShort(values, noNullValue, swap);
month = values[noNullValue + 2];
day = values[noNullValue + 3];
hour = values[noNullValue + 4];
minute = values[noNullValue + 5];
second = values[noNullValue + 6];
if (desc.sqlPrecision_ > 0) {
nanoSeconds = Bytes.extractUInt(values, noNullValue + 7, swap);
if (nanoSeconds > 999999) // returned in microseconds
nanoSeconds = 0;
// apply leading 0's for string conversion
tmpStr = "" + nanoSeconds;
length = tmpStr.length();
for (int i = 0; i < desc.sqlPrecision_ - length; i++) {
tmpStr = "0" + tmpStr;
}
} else {
tmpStr = "0";
}
retObj = Timestamp.valueOf(padZero((int) year, 4) + "-" + padZero(month, 2) + "-" + padZero(day, 2)
+ " " + padZero(hour, 2) + ":" + padZero(minute, 2) + ":" + padZero(second, 2) + "."
+ tmpStr);
} else { // do the old way
length = desc.precision_;
retObj = Timestamp.valueOf(new String(Bytes.read_chars(values, noNullValue, length)));
}
break;
case SQLDTCODE_TIME:
if (ODBCDataType == java.sql.Types.OTHER) // For
// HPT4Desc.SQLDTCODE_HOUR_TO_FRACTION
{
length = desc.sqlOctetLength_;
retObj = new String(Bytes.read_chars(values, noNullValue, length));
} else {
length = timeLength;
if (!useOldDateFormat) // new date format, only for bulk
// move
{
// "hh:mm:ss"
hour = values[noNullValue];
minute = values[noNullValue + 1];
second = values[noNullValue + 2];
if (desc.sqlPrecision_ > 0) {
nanoSeconds = Bytes.extractUInt(values, noNullValue + 3, swap);
if (nanoSeconds > 999999) // returned in microseconds
nanoSeconds = 0;
String formatStr = "";
for(int i=0;i<desc.sqlPrecision_;i++)
formatStr += "0";
StringBuffer sb = new StringBuffer();
DecimalFormat format = new DecimalFormat("00");
format.format(hour, sb, new FieldPosition(0));
sb.append(':');
format.format(minute, sb, new FieldPosition(0));
sb.append(':');
format.format(second, sb, new FieldPosition(0));
sb.append('.');
format = new DecimalFormat(formatStr);
format.format(nanoSeconds, sb, new FieldPosition(0));
retObj = sb.toString();
} else {
retObj = Time.valueOf(String.valueOf(hour) + ":" + String.valueOf(minute) + ":"
+ String.valueOf(second));
}
} else
// do the old way
retObj = Time.valueOf(new String(Bytes.read_chars(values, noNullValue, length)));
}
break;
default:
length = desc.sqlOctetLength_;
retObj = new String(Bytes.read_chars(values, noNullValue, length));
break;
}
break;
case SQLTYPECODE_SMALLINT:
short sValue = Bytes.extractShort(values, noNullValue, swap);
retObj = new Short(sValue);
if (desc.scale_ > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), desc.scale_);
}
break;
case SQLTYPECODE_SMALLINT_UNSIGNED:
int signedSValue = Bytes.extractUShort(values, noNullValue, swap);
if (desc.scale_ > 0) {
tmpbd = new BigDecimal(new BigInteger(String.valueOf(signedSValue)), (int) desc.scale_);
} else {
tmpbd = new BigDecimal(String.valueOf(signedSValue));
}
retObj = tmpbd;
break;
case SQLTYPECODE_INTEGER:
retObj = new Integer(Bytes.extractInt(values, noNullValue,swap));
if (desc.scale_ > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), desc.scale_);
}
break;
case SQLTYPECODE_INTEGER_UNSIGNED:
retObj = new Long(Bytes.extractUInt(values, noNullValue, swap));
if (desc.scale_ > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), desc.scale_);
}
break;
case SQLTYPECODE_LARGEINT:
retObj = new Long(Bytes.extractLong(values, noNullValue, swap));
if (desc.scale_ > 0) {
retObj = new BigDecimal(new BigInteger(retObj.toString()), desc.scale_);
}
break;
case SQLTYPECODE_NUMERIC:
case SQLTYPECODE_NUMERIC_UNSIGNED:
tbuffer = new byte[desc.sqlOctetLength_];
System.arraycopy(values, noNullValue, tbuffer, 0, desc.sqlOctetLength_);
retObj = InterfaceUtilities.convertSQLBigNumToBigDecimal(tbuffer, desc.scale_, swap);
break;
case SQLTYPECODE_DECIMAL:
case SQLTYPECODE_DECIMAL_UNSIGNED:
case SQLTYPECODE_DECIMAL_LARGE:
case SQLTYPECODE_DECIMAL_LARGE_UNSIGNED:
String retStr;
// check if the sign is minus (-80)
byte sign = (byte) (values[noNullValue] & (byte) (-80));
// first byte = inbyte - (-80)
if (sign == (byte) (-80)) {
byte firstByte = (byte) (values[noNullValue] - (byte) (-80));
retStr = "-" + firstByte
+ String.valueOf(Bytes.read_chars(values, noNullValue + 1, desc.sqlOctetLength_ - 1));
} else {
retStr = String.valueOf(Bytes.read_chars(values, noNullValue, desc.sqlOctetLength_));
}
retObj = new BigDecimal(new BigInteger(retStr), desc.scale_);
break;
case SQLTYPECODE_REAL:
retObj = new Float(Float.intBitsToFloat(Bytes.extractInt(values, noNullValue, swap)));
break;
case SQLTYPECODE_DOUBLE:
case SQLTYPECODE_FLOAT:
retObj = new Double(Double.longBitsToDouble(Bytes.extractLong(values, noNullValue, swap)));
break;
case SQLTYPECODE_BIT:
case SQLTYPECODE_BITVAR:
case SQLTYPECODE_BPINT_UNSIGNED:
default:
throw HPT4Messages.createSQLException(conn.props_, conn.getLocale(), "restricted_data_type", null);
}
return retObj;
} // end getExecute2FetchString
// -------------------------------------------------------------------
void setFetchOutputs(TrafT4ResultSet rs, int rowsAffected, boolean endOfData, byte[] outputDataValue)
throws SQLException
{
ObjectArray[] rowArray;
Object[] columnArray;
Object columnValue;
int columnCount;
int rowIndex;
int columnIndex;
int byteIndex = 0;
short SQLDataInd = 0;
int byteLen = 0;
int maxRowLen = rs.connection_.ic_.getTransportBufferSize(); // maxRowLen
rowArray = new ObjectArray[rowsAffected];
// get the number of colums
columnCount = rs.getNoOfColumns();
for (rowIndex = 0; rowIndex < rowsAffected; rowIndex++) {
if (rs.connection_.props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, rs, outputDataValue, rowsAffected,
endOfData, 0);
String temp = "Reading row = " + rowIndex;
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "setFetchOutputs", temp, p);
}
columnArray = new Object[columnCount];
for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
if (rs.connection_.props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, rs, outputDataValue,
rowsAffected, endOfData, 0);
String temp = "Reading column = " + columnIndex;
rs.connection_.props_.t4Logger_
.logp(Level.FINEST, "InterfaceResultSet", "setFetchOutputs", temp, p);
}
SQLDataInd = new Byte(outputDataValue[byteIndex++]).shortValue();
if (rs.connection_.props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, rs, outputDataValue,
rowsAffected, endOfData, 0);
String temp = "Row = " + rowIndex + "," + "Column = " + columnIndex + " SQLDataInd is = "
+ SQLDataInd;
rs.connection_.props_.t4Logger_
.logp(Level.FINEST, "InterfaceResultSet", "setFetchOutputs", temp, p);
}
if (SQLDataInd == 0) {
short varDataLen;
if (outputDataValue.length > (byteIndex + 2)) {
varDataLen = Bytes.extractShort(outputDataValue, byteIndex, this.ic_.getByteSwap());
} else {
varDataLen = 0;
}
byteLen = dataLengthFetchPerf(rs.outputDesc_[columnIndex].sqlDataType_,
rs.outputDesc_[columnIndex].sqlDatetimeCode_, rs.outputDesc_[columnIndex].sqlOctetLength_,
maxRowLen, // maxLength
varDataLen, rs.outputDesc_[columnIndex].dataType_, rs.outputDesc_[columnIndex].precision_);
columnValue = getFetchString(rs.connection_, rs.outputDesc_[columnIndex].scale_,
rs.outputDesc_[columnIndex].sqlDataType_, rs.outputDesc_[columnIndex].sqlDatetimeCode_,
rs.outputDesc_[columnIndex].fsDataType_, outputDataValue, byteIndex, byteLen,
rs.outputDesc_[columnIndex].sqlCharset_, rs.outputDesc_[columnIndex].dataType_);
byteIndex = byteIndex + byteLen;
switch (rs.outputDesc_[columnIndex].sqlDataType_) {
case SQLTYPECODE_VARCHAR_WITH_LENGTH:
case SQLTYPECODE_VARCHAR_LONG:
case SQLTYPECODE_VARCHAR_DBLBYTE:
case SQLTYPECODE_BITVAR:
case SQLTYPECODE_CHAR:
case SQLTYPECODE_CHAR_DBLBYTE:
case SQLTYPECODE_VARCHAR:
case SQLTYPECODE_BLOB:
case SQLTYPECODE_CLOB:
byteIndex++;
break;
}
if (columnValue == null) {
throw HPT4Messages
.createSQLException(rs.connection_.props_, ic_.getLocale(), "null_data", null);
}
} else {
columnValue = null;
}
columnArray[columnIndex] = columnValue;
}
rowArray[rowIndex] = new ObjectArray(columnCount, columnArray);
}
rs.setFetchOutputs(rowArray, rowsAffected, endOfData);
}
// ----------------------------------------------------------------------------
void setExecute2FetchOutputs(TrafT4ResultSet rs, int rowsAffected, boolean endOfData, byte[] values)
throws SQLException {
if (rs.useOldDateFormat()) {
setFetchOutputs(rs, rowsAffected, endOfData, values);
return;
}
Object[] columnArray;
Object columnValue;
ObjectArray[] rowArray = new ObjectArray[rowsAffected];
int columnCount = rs.getNoOfColumns();
int rowIndex;
int columnIndex;
int byteIndex = 0;
int SQLDataInd = 0;
int byteLen = 0;
int maxRowLen = rs.connection_.ic_.getTransportBufferSize(); // maxRowLen
columnArray = new Object[columnCount];
int dataLength = 0;
if (rs.outputDesc_ != null && rs.outputDesc_.length > 0) {
dataLength = rs.outputDesc_[0].rowLength_;
}
int rowOffset = 0;
for (rowIndex = 0; rowIndex < rowsAffected; rowIndex++) {
rowOffset = rowIndex * dataLength;
for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
int noNullValueOffset = rs.outputDesc_[columnIndex].noNullValue_;
int nullValueOffset = rs.outputDesc_[columnIndex].nullValue_;
if (nullValueOffset != -1)
nullValueOffset += rowOffset;
if (noNullValueOffset != -1)
noNullValueOffset += rowOffset;
if (rs.connection_.props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, rs, endOfData, values);
String temp = "Processing column = " + columnIndex + ": noNullValueOffset = " + noNullValueOffset
+ ": nullValueOffset = " + nullValueOffset;
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "setExecute2FetchOutputs",
temp, p);
}
if (nullValueOffset != -1 && Bytes.extractShort(values, nullValueOffset, this.ic_.getByteSwap()) == -1) {
columnValue = null;
} else {
columnValue = getExecute2FetchString(rs.connection_, rs.outputDesc_[columnIndex], values,
noNullValueOffset, rs.outputDesc_[columnIndex].dataType_, rs.useOldDateFormat(), this.ic_.getByteSwap());
if (columnValue == null) {
throw HPT4Messages
.createSQLException(rs.connection_.props_, ic_.getLocale(), "null_data", null);
}
} // end if else
columnArray[columnIndex] = columnValue;
} // end for
rowArray[rowIndex] = new ObjectArray(columnCount, columnArray);
}
rs.setFetchOutputs(rowArray, rowsAffected, endOfData);
} // end setExectue2FetchOutputs
// ----------------------------------------------------------------------------
// Interface methods
boolean fetch(String stmtLabel, int maxRowCnt, int queryTimeout, int holdability, TrafT4ResultSet rs)
throws SQLException {
int sqlAsyncEnable = 0;
int stmtHandle = 0;
int stmtCharset = 1;
String cursorName = "";
int cursorCharset = 1;
String stmtOptions = "";
boolean endOfData = false;
boolean dataFound = false;
String sqlStmt = ""; // qs_interface
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, stmtLabel, maxRowCnt, queryTimeout,
holdability);
String temp = "Entering Fetch";
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "fetch", temp, p);
}
if (rs_.stmt_ != null && rs_.stmt_.sql_ != null) {
sqlStmt = rs_.stmt_.sql_.toUpperCase();
}
FetchReply fr;
try {
fr = t4resultSet_.Fetch(sqlAsyncEnable, queryTimeout, stmtHandle, stmtCharset, maxRowCnt, cursorName,
cursorCharset, stmtOptions);
} catch (SQLException tex) {
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, stmtLabel, maxRowCnt, queryTimeout,
holdability);
String temp = "SQLException while fetching.";
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "fetch", temp, p);
}
throw tex;
}
switch (fr.returnCode) {
case TRANSPORT.CEE_SUCCESS:
case TRANSPORT.SQL_SUCCESS_WITH_INFO:
// do warning processing
if (fr.errorList.length != 0) {
HPT4Messages.setSQLWarning(rs.connection_.props_, rs, fr.errorList);
}
//endOfData = (fr.rowsAffected < maxRowCnt) ? true : false;
if (fr.rowsAffected > 0) {
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, stmtLabel, maxRowCnt,
queryTimeout, holdability);
String temp = "Data Found. Setting fetch outputs";
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "fetch", temp, p);
}
if (rs.keepRawBuffer_ == true) {
rs.rawBuffer_ = fr.outValues;
}
setExecute2FetchOutputs(rs, fr.rowsAffected, endOfData, fr.outValues);
dataFound = true;
}
break;
case 100: // fix this
case odbc_SQLSvc_Fetch_exc_.odbc_SQLSvc_Fetch_SQLNoDataFound_exn_:
dataFound = false;
endOfData = true;
break;
default:
HPT4Messages.throwSQLException(rs.connection_.props_, fr.errorList);
}
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs.connection_.props_, stmtLabel, maxRowCnt, queryTimeout,
holdability);
String temp = "Exiting Fetch.";
rs.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "fetch", temp, p);
}
// see if the rows fetched is valid
return dataFound;
};
void close() throws SQLException {
ic_.isConnectionOpen();
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs_.connection_.props_);
String temp = "Closing resultset.";
rs_.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "close", temp, p);
}
int rval = 0;
CloseReply cry_ = null;
//
// If the query is non-unique, then close the result set (cursor).
// If the query was a unique select, then the result set was implicitly
// closed by NCS.
//
if (rs_ != null && rs_.stmt_ != null && rs_.stmt_.ist_ != null
&& rs_.stmt_.ist_.sqlQueryType_ != TRANSPORT.SQL_SELECT_UNIQUE) {
cry_ = t4resultSet_.Close();
switch (cry_.m_p1.exception_nr) {
case TRANSPORT.CEE_SUCCESS:
// ignore the SQLWarning for the static close
break;
case odbc_SQLSvc_Close_exc_.odbc_SQLSvc_Close_SQLError_exn_:
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs_.connection_.props_);
String temp = "odbc_SQLSvc_Close_SQLError_exn_";
rs_.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "close", temp, p);
}
HPT4Messages.throwSQLException(rs_.connection_.props_, cry_.m_p1.SQLError);
default:
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs_.connection_.props_);
String temp = "UnknownException occurred during close.";
rs_.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "close", temp, p);
}
throw HPT4Messages.createSQLException(rs_.connection_.props_, ic_.getLocale(),
"ids_unknown_reply_error", null);
} // end switch
} // end if
if (ic_.t4props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(rs_.connection_.props_);
String temp = "Closed resultset.";
rs_.connection_.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "close", temp, p);
}
};
// ----------------------------------------------------------------------------
static Object[] getExecute2Outputs(TrafT4Connection conn, HPT4Desc[] desc, byte[] values, boolean swap) throws SQLException
{
Object[] columnArray;
Object columnValue;
int columnIndex;
int columnCount = (desc == null) ? 0 : desc.length;
columnArray = new Object[columnCount];
for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
int noNullValueOffset = desc[columnIndex].noNullValue_;
int nullValueOffset = desc[columnIndex].nullValue_;
if (conn.props_.t4Logger_.isLoggable(Level.FINEST) == true) {
Object p[] = T4LoggingUtilities.makeParams(conn.props_, conn, desc, values);
String temp = "Processing column = " + columnIndex + ": noNullValueOffset = " + noNullValueOffset
+ ": nullValueOffset = " + nullValueOffset;
conn.props_.t4Logger_.logp(Level.FINEST, "InterfaceResultSet", "getExecute2Outputs", temp, p);
}
if ((nullValueOffset != -1 && Bytes.extractShort(values, nullValueOffset, swap) == -1)
|| (desc[columnIndex].paramMode_ == HPT4ParameterMetaData.parameterModeIn)) {
columnValue = null;
} else {
columnValue = getExecute2FetchString(conn, desc[columnIndex], values, noNullValueOffset,
desc[columnIndex].dataType_, false, swap);
if (columnValue == null) {
throw HPT4Messages.createSQLException(conn.props_, conn.getLocale(), "null_data", null);
}
} // end if else
columnArray[columnIndex] = columnValue;
} // end for
return columnArray;
} // end getExectue2Outputs
}