// be able to guess the right PROTOCOL type to send to the server, and an
// exception is thrown.
if (jdbcType == 0) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_INVALID_JDBC_TYPE_FOR_PARAM),
new Integer(i));
}
switch (jdbcType) {
case java.sql.Types.CHAR:
case java.sql.Types.VARCHAR:
// lid: PROTOCOL_TYPE_NVARMIX, length override: 32767 (max)
// dataFormat: String
// this won't work if 1208 is not supported
s = (String) inputRow[i];
// assumes UTF-8 characters at most 3 bytes long
// Flow the String as a VARCHAR
if (s == null || s.length() <= 32767 / 3) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARMIX;
lidAndLengths[i][1] = 32767;
} else {
// Flow the data as CLOB data if the data too large to for LONGVARCHAR
java.io.ByteArrayInputStream bais = null;
byte[] ba = null;
try {
ba = s.getBytes("UTF-8");
bais = new java.io.ByteArrayInputStream(ba);
Clob c = new Clob(netAgent_, bais, "UTF-8", ba.length);
// inputRow[i] = c;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(new Integer(i), c);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
if( c.willBeLayerBStreamed() ){
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(c.length());
}
} catch (java.io.UnsupportedEncodingException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
"byte array", "Clob", e);
}
}
break;
case java.sql.Types.INTEGER:
// lid: PROTOCOL_TYPE_NINTEGER, length override: 4
// dataFormat: Integer
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NINTEGER;
lidAndLengths[i][1] = 4;
break;
case java.sql.Types.BOOLEAN:
case java.sql.Types.SMALLINT:
case java.sql.Types.TINYINT:
case java.sql.Types.BIT:
// lid: PROTOCOL_TYPE_NSMALL, length override: 2
// dataFormat: Short
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NSMALL;
lidAndLengths[i][1] = 2;
break;
case java.sql.Types.REAL:
// lid: PROTOCOL_TYPE_NFLOAT4, length override: 4
// dataFormat: Float
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT4;
lidAndLengths[i][1] = 4;
break;
case java.sql.Types.DOUBLE:
case java.sql.Types.FLOAT:
// lid: PROTOCOL_TYPE_NFLOAT8, length override: 8
// dataFormat: Double
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT8;
lidAndLengths[i][1] = 8;
break;
case java.sql.Types.NUMERIC:
case java.sql.Types.DECIMAL:
// lid: PROTOCOL_TYPE_NDECIMAL
// dataFormat: java.math.BigDecimal
// if null - guess with precision 1, scale 0
// if not null - get scale from data and calculate maximum precision.
// DERBY-2073. Get scale and precision from data so we don't lose fractional digits.
java.math.BigDecimal bigDecimal = (java.math.BigDecimal) inputRow[i];
int scale;
int precision;
if (bigDecimal == null)
{
scale = 0;
precision = 1;
}
else
{
// adjust scale if it is negative. Packed Decimal cannot handle
// negative scale. We don't want to change the original
// object so make a new one.
if (bigDecimal.scale() < 0)
{
bigDecimal = bigDecimal.setScale(0);
inputRow[i] = bigDecimal;
}
scale = bigDecimal.scale();
precision = Utils.computeBigDecimalPrecision(bigDecimal);
}
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NDECIMAL;
lidAndLengths[i][1] = (precision << 8) + // use precision above
(scale << 0);
break;
case java.sql.Types.DATE:
// for input, output, and inout parameters
// lid: PROTOCOL_TYPE_NDATE, length override: 8
// dataFormat: java.sql.Date
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NDATE;
lidAndLengths[i][1] = 10;
break;
case java.sql.Types.TIME:
// for input, output, and inout parameters
// lid: PROTOCOL_TYPE_NTIME, length override: 8
// dataFormat: java.sql.Time
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NTIME;
lidAndLengths[i][1] = 8;
break;
case java.sql.Types.TIMESTAMP:
// for input, output, and inout parameters
// lid: PROTOCOL_TYPE_NTIME, length overrid: 26
// dataFormat: java.sql.Timestamp
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NTIMESTAMP;
lidAndLengths[i][1] = 26;
break;
case java.sql.Types.BIGINT:
// if SQLAM < 6 this should be mapped to decimal (19,0) in common layer
// if SQLAM >=6, lid: PROTOCOL_TYPE_NINTEGER8, length override: 8
// dataFormat: Long
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NINTEGER8;
lidAndLengths[i][1] = 8;
break;
case java.sql.Types.LONGVARCHAR:
// Is this the right thing to do // should this be 32700
s = (String) inputRow[i];
if (s == null || s.length() <= 32767 / 3) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGMIX;
lidAndLengths[i][1] = 32767;
} else {
// Flow the data as CLOB data if the data too large to for LONGVARCHAR
java.io.ByteArrayInputStream bais = null;
byte[] ba = null;
try {
ba = s.getBytes("UTF-8");
bais = new java.io.ByteArrayInputStream(ba);
Clob c = new Clob(netAgent_, bais, "UTF-8", ba.length);
// inputRow[i] = c;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(new Integer(i), c);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
lidAndLengths[i][1] = buildPlaceholderLength(c.length());
} catch (java.io.UnsupportedEncodingException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
"byte array", "Clob");
}
}
break;
case java.sql.Types.BINARY:
case java.sql.Types.VARBINARY:
byte[] ba = (byte[]) inputRow[i];
if (ba == null) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARBYTE;
lidAndLengths[i][1] = 32767;
} else if (ba.length <= 32767) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NVARBYTE;
lidAndLengths[i][1] = 32767;
} else {
// Promote to a BLOB. Only reach this path in the absence of describe information.
Blob b = new Blob(ba, netAgent_, 0);
// inputRow[i] = b;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(new Integer(i), b);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
}
break;
case java.sql.Types.LONGVARBINARY:
ba = (byte[]) inputRow[i];
if (ba == null) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGVARBYTE;
lidAndLengths[i][1] = 32767;
} else if (ba.length <= 32767) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLONGVARBYTE;
lidAndLengths[i][1] = 32767;
} else {
// Promote to a BLOB. Only reach this path in the absensce of describe information.
Blob b = new Blob(ba, netAgent_, 0);
// inputRow[i] = b;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(new Integer(i), b);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
}
break;
case java.sql.Types.BLOB:
java.sql.Blob b = (java.sql.Blob) inputRow[i];
if (b == null) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] =
buildPlaceholderLength(parameterMetaData.sqlLength_[i]);
} else if (b instanceof Blob && ((Blob)b).isLocator()){
//we are sending locators.
//Here the LID local identifier in the FDODSC
//FD:OCA descriptor should be initialized as
//to contain a BLOB locator.
lidAndLengths[i][0] =
DRDAConstants.DRDA_TYPE_NLOBLOC;
lidAndLengths[i][1] = 4;
} else {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
try {
if( b instanceof Blob &&
( (Blob) b).willBeLayerBStreamed() ){
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(b.length());
}
} catch (java.sql.SQLException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH), e);
}
}
break;
case java.sql.Types.CLOB:
{
// use columnMeta.singleMixedByteOrDouble_ to decide protocolType
java.sql.Clob c = (java.sql.Clob) inputRow[i];
boolean isExternalClob = !(c instanceof org.apache.derby.client.am.Clob);
long lobLength = 0;
boolean doesLayerBStreaming = false;
if (c == null) {
lobLength = parameterMetaData.sqlLength_[i];
} else if (c instanceof Clob && ((Clob)c).isLocator()) {
//The inputRow contains an Integer meaning that
//we are sending locators.
//Here the LID local identifier in the FDODSC
//FD:OCA descriptor should be initialized as
//to contain a CLOB locator.
lidAndLengths[i][0] =
DRDAConstants.DRDA_TYPE_NCLOBLOC;
lidAndLengths[i][1] = 4;
} else if (isExternalClob) {
try {
lobLength = c.length();
} catch (java.sql.SQLException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
e);
}
} else {
if( ( (Clob) c ).willBeLayerBStreamed() ){
doesLayerBStreaming = true;
}else{
lobLength = ((Clob) c).length();
}
}
if (c == null) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
} else if (isExternalClob) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCDBCS;
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
} else if (((Clob) c).isCharacterStream()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCDBCS;
if( doesLayerBStreaming ) {
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
}
} else if (((Clob) c).isUnicodeStream()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
if( doesLayerBStreaming ) {
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
}
} else if (((Clob) c).isAsciiStream()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCSBCS;
if( doesLayerBStreaming ) {
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
}
} else if (((Clob) c).isString()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
if( doesLayerBStreaming ) {
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
}
}
}
break;
default :
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.UNRECOGNIZED_JAVA_SQL_TYPE),
new Integer(jdbcType));
}
if (!parameterMetaData.nullable_[i]) {
lidAndLengths[i][0]--;