// call setNull() and provide the type information. Otherwise, we won't
// 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;
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
// input only:
// if null and describe input - use describe input precision and scale
// if not null and describe input - calculate precision and actual scale from data
// if null and no describe input - guess with precision 1 scale 0
// if not null and no describe input - calculate precision and actual scale from data
// output only:
// use largest precision/scale based on registered scale from registerOutParameter
// inout:
// if null - use largest precision/scale based on scale from registerOutParameter
// if not null - write bigDecimal () pass registered scale so it can pad, you don't even
// have to look at the actual scale at this level.
/*
if (parameterMetaData.isGuessed) {
java.math.BigDecimal bigDecimal = (java.math.BigDecimal) inputRow[i];
int precision = Utils.computeBigDecimalPrecision (bigDecimal);
lidAndLengths[i][1] = (precision << 8) + // use precision above
(bigDecimal.scale() << 0);
}
*/
// Split this entire method into two parts, the first method is called only once and the inputRow is not passed,!!
// the second method is called for every inputRow and overrides inputDA lengths/scales based upon the acutal data!
// for decimal and blob columns only
int precision = parameterMetaData.sqlPrecision_[i];
int scale = parameterMetaData.sqlScale_[i];
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NDECIMAL;
lidAndLengths[i][1] = (precision << 8) + (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 {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBBYTES;
try {
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;
if (c == null) {
lobLength = parameterMetaData.sqlLength_[i];
} 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 {
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;
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
} else if (((Clob) c).isUnicodeStream()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
} else if (((Clob) c).isAsciiStream()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCSBCS;
lidAndLengths[i][1] = buildPlaceholderLength(lobLength);
} else if (((Clob) c).isString()) {
lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NLOBCMIXED;
lidAndLengths[i][1] = buildPlaceholderLength(((Clob) c).getUTF8Length());
}
}
break;
default :
throw new SqlException(netAgent_.logWriter_,
new ClientMessageId(SQLState.UNRECOGNIZED_JAVA_SQL_TYPE),
new Integer(jdbcType));
}
if (!parameterMetaData.nullable_[i]) {
lidAndLengths[i][0]--;
}
}
return overrideMap;
}
catch ( java.sql.SQLException se )
{
throw new SqlException(se);
}
}