lidAndLengths[i][1] = 32767;
} else {
// Flow the data as CLOB data if the data too large to for LONGVARCHAR
byte[] ba = s.getBytes(Typdef.UTF8ENCODING);
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
ClientClob c = new ClientClob(
netAgent_, bais, Typdef.UTF8ENCODING, ba.length);
// inputRow[i] = c;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(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());
}
}
break;
case Types.INTEGER:
// lid: PROTOCOL_TYPE_NINTEGER, length override: 4
// dataFormat: Integer
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NINTEGER;
lidAndLengths[i][1] = 4;
break;
case Types.BIT:
case Types.BOOLEAN:
if ( netAgent_.netConnection_.databaseMetaData_.
serverSupportsBooleanParameterTransport() )
{
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NBOOLEAN;
lidAndLengths[i][1] = 1;
}
else
{
// If the server doesn't support BOOLEAN parameters,
// send the parameter as a SMALLINT instead.
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NSMALL;
lidAndLengths[i][1] = 2;
if (inputRow[i] instanceof Boolean) {
Boolean bool = (Boolean) inputRow[i];
inputRow[i] = Short.valueOf(
bool.booleanValue() ? (short) 1 : 0);
}
}
break;
case Types.SMALLINT:
case Types.TINYINT:
// lid: PROTOCOL_TYPE_NSMALL, length override: 2
// dataFormat: Short
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NSMALL;
lidAndLengths[i][1] = 2;
break;
case Types.REAL:
// lid: PROTOCOL_TYPE_NFLOAT4, length override: 4
// dataFormat: Float
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT4;
lidAndLengths[i][1] = 4;
break;
case Types.DOUBLE:
case Types.FLOAT:
// lid: PROTOCOL_TYPE_NFLOAT8, length override: 8
// dataFormat: Double
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NFLOAT8;
lidAndLengths[i][1] = 8;
break;
case Types.NUMERIC:
case 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.
BigDecimal bigDecimal = (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 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 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 Types.TIMESTAMP:
// for input, output, and inout parameters
// lid: PROTOCOL_TYPE_NTIMESTAMP, length overrid: 26 or 29
// dataFormat: java.sql.Timestamp
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NTIMESTAMP;
lidAndLengths[i][1] = DateTime.getTimestampLength( netAgent_.netConnection_.serverSupportsTimestampNanoseconds() );
break;
case 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 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
byte[] ba = s.getBytes(Typdef.UTF8ENCODING);
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
ClientClob c = new ClientClob(
netAgent_, bais, Typdef.UTF8ENCODING, ba.length);
// inputRow[i] = c;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(i, c);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
lidAndLengths[i][1] = buildPlaceholderLength(c.length());
}
break;
case Types.BINARY:
case 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.
ClientBlob b = new ClientBlob(ba, netAgent_, 0);
// inputRow[i] = b;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(i, b);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
}
break;
case 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.
ClientBlob b = new ClientBlob(ba, netAgent_, 0);
// inputRow[i] = b;
// Place the new Lob in the promototedParameter_ collection for
// NetStatementRequest use
promototedParameters_.put(i, b);
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
}
break;
case Types.JAVA_OBJECT:
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NUDT;
lidAndLengths[i][1] = 32767;
break;
case Types.BLOB:
Blob b = (Blob) inputRow[i];
if (b == null) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
lidAndLengths[i][1] =
buildPlaceholderLength(parameterMetaData.sqlLength_[i]);
} else if (b instanceof ClientBlob &&
((ClientBlob)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 ClientBlob &&
( (ClientBlob) b).willBeLayerBStreamed() ){
//Correspond to totalLength 0 as default length for unknown
lidAndLengths[i][1] = 0x8002;
}else {
lidAndLengths[i][1] = buildPlaceholderLength(b.length());
}
} catch (SQLException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH), e);
}
}
break;
case Types.CLOB:
{
// use columnMeta.singleMixedByteOrDouble_ to decide protocolType
Clob c = (Clob) inputRow[i];
boolean isExternalClob = !(c instanceof ClientClob);
long lobLength = 0;
boolean doesLayerBStreaming = false;
if (c == null) {
lobLength = parameterMetaData.sqlLength_[i];
} else if (c instanceof ClientClob &&
((ClientClob)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 (SQLException e) {
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_ERROR_GETTING_BLOB_LENGTH),
e);
}