/* Is there a ? parameter on the left? */
if (leftOperand.requiresTypeFromContext())
{
/* Set the left operand type to int. */
leftOperand.setType(
new DataTypeDescriptor(TypeId.INTEGER_ID, true));
}
/* Is there a ? parameter on the right? */
if ((rightOperand != null) && rightOperand.requiresTypeFromContext())
{
/* Set the right operand type to int. */
rightOperand.setType(
new DataTypeDescriptor(TypeId.INTEGER_ID, true));
}
bindToBuiltIn();
if (!leftOperand.getTypeId().isNumericTypeId() ||
(rightOperand != null && !rightOperand.getTypeId().isNumericTypeId()))
throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "SUBSTR", "FUNCTION");
/*
** Check the type of the receiver - this function is allowed only on
** string value types.
*/
receiverType = receiver.getTypeId();
switch (receiverType.getJDBCTypeId())
{
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
case Types.CLOB:
break;
default:
{
throwBadType("SUBSTR", receiverType.getSQLTypeName());
}
}
if (receiverType.getTypeFormatId() == StoredFormatIds.CLOB_TYPE_ID) {
// special case for CLOBs: if we start with a CLOB, we have to get
// a CLOB as a result (as opposed to a VARCHAR), because we can have a
// CLOB that is beyond the max length of VARCHAR (ex. "clob(100k)").
// This is okay because CLOBs, like VARCHARs, allow variable-length
// values (which is a must for the substr to actually work).
resultType = receiverType;
}
// Determine the maximum length of the result
int resultLen = receiver.getTypeServices().getMaximumWidth();
if (rightOperand != null && rightOperand instanceof ConstantNode)
{
if (((ConstantNode)rightOperand).getValue().getInt() < resultLen)
resultLen = ((ConstantNode)rightOperand).getValue().getInt();
}
/*
** The result type of substr is a string type
*/
setType(new DataTypeDescriptor(
resultType,
true,
resultLen
));
//Result of SUSBSTR should pick up the collation of the 1st argument