*/
public DataTypeDescriptor resolveArithmeticOperation(DataTypeDescriptor leftType,
DataTypeDescriptor rightType,
String operator)
throws StandardException {
TypeId rightTypeId = rightType.getTypeId();
TypeId leftTypeId = leftType.getTypeId();
boolean nullable = leftType.isNullable() || rightType.isNullable();
if (operator.equals(PLUS_OP) || operator.equals(MINUS_OP))
{
// date/time and interval
TypeId datetimeType;
if ((datetimeType = rightTypeId).isDateTimeTimeStampTypeId() && leftTypeId.isIntervalTypeId() ||
(datetimeType = leftTypeId).isDateTimeTimeStampTypeID() && rightTypeId.isIntervalTypeId())
// Let specific datetime type resolve it.
return getTypeCompiler(datetimeType).resolveArithmeticOperation(rightType, leftType, operator);
// interval and interval
int typeFormatId = 0;
if (leftTypeId.isIntervalTypeId() && rightTypeId.isIntervalTypeId())
// two intervals are exactly the same
if (leftTypeId == rightTypeId)
return leftType.getNullabilityType(nullable);
// two intervals are of the same *type*
else if ((typeFormatId = leftTypeId.getTypeFormatId()) == rightTypeId.getTypeFormatId())
return new DataTypeDescriptor(typeFormatId == TypeId.FormatIds.INTERVAL_DAY_SECOND_ID ?
TypeId.INTERVAL_SECOND_ID : TypeId.INTERVAL_MONTH_ID,
nullable);
// varchar
DataTypeDescriptor varcharType;
if ((varcharType = leftType).getTypeId().isStringTypeId() && rightTypeId.isIntervalTypeId()||
(varcharType = rightType).getTypeId().isStringTypeId() && leftTypeId.isIntervalTypeId()
&& operator.equals(PLUS_OP)) // when left is interval, only + is legal
return new DataTypeDescriptor(varcharType.getPrecision() > 10 ? TypeId.DATETIME_ID : TypeId.DATE_ID, nullable);
}
else if (operator.equals(TIMES_OP) || operator.equals(DIVIDE_OP) || operator.equals(DIV_OP))
{
// numeric / varchar and interval
TypeId intervalId = null;
if ((intervalId = leftTypeId).isIntervalTypeId() &&
(rightTypeId.isNumericTypeId() || rightTypeId.isStringTypeId())||
(intervalId = rightTypeId).isIntervalTypeId() &&
(leftTypeId.isNumericTypeId() || leftTypeId.isStringTypeId()) &&
operator.equals(TIMES_OP)) // when right is interval, only * is legal