Example #1
0
  @Override
  public boolean canConvertFrom(Type otherType) {

    if (otherType.typeCode == Types.SQL_ALL_TYPES) {
      return true;
    }

    if (otherType.isNumberType()) {
      return true;
    }

    if (otherType.isIntervalType()) {
      return true;
    }

    if (otherType.isCharacterType()) {
      return true;
    }

    return false;
  }
Example #2
0
  @Override
  public Object convertToType(SessionInterface session, Object a, Type otherType) {

    if (a == null) {
      return a;
    }

    if (otherType.typeCode == typeCode) {
      switch (typeCode) {
        case Types.SQL_NUMERIC:
        case Types.SQL_DECIMAL:
          if (otherType.scale == scale && otherType.precision <= precision) {
            return a;
          }
          break;

        default:
          return a;
      }
    }

    if (otherType.isIntervalType()) {
      int endType = ((IntervalType) otherType).endIntervalType;

      switch (endType) {
        case Types.SQL_INTERVAL_YEAR:
        case Types.SQL_INTERVAL_MONTH:
        case Types.SQL_INTERVAL_DAY:
        case Types.SQL_INTERVAL_HOUR:
        case Types.SQL_INTERVAL_MINUTE:
          {
            Long value = ValuePool.getLong(((IntervalType) otherType).convertToLong(a));

            return convertToType(session, value, Type.SQL_BIGINT);
          }
        case Types.SQL_INTERVAL_SECOND:
          {
            long seconds = ((IntervalSecondData) a).units;
            long nanos = ((IntervalSecondData) a).nanos;
            BigDecimal value = ((DTIType) otherType).getSecondPart(seconds, nanos);

            return value;
          }
      }
    }

    switch (otherType.typeCode) {
      case Types.SQL_CLOB:
        a = ((ClobData) a).getSubString(session, 0L, (int) ((ClobData) a).length(session));

        // fall through
      case Types.SQL_CHAR:
      case Types.SQL_VARCHAR:
      case Types.VARCHAR_IGNORECASE:
        {
          a = session.getScanner().convertToNumber((String) a, this);

          return convertToDefaultType(session, a);
        }
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
      case Types.SQL_BIGINT:
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        break;

      default:
        throw Error.error(ErrorCode.X_42561);
    }

    switch (this.typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        return convertToInt(a, this.typeCode);

      case Types.SQL_BIGINT:
        return convertToLong(a);

      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        return convertToDouble(a);

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        BigDecimal value = convertToDecimal(a);

        return convertToTypeLimits(session, value);

      default:
        throw Error.error(ErrorCode.X_42561);
    }
  }
Example #3
0
  /**
   * Returns a SQL type "wide" enough to represent the result of the expression.<br>
   * A type is "wider" than the other if it can represent all its numeric values.<br>
   * Arithmetic operation terms are promoted to a type that can represent the resulting values and
   * avoid incorrect results.
   *
   * <p>FLOAT/REAL/DOUBLE used in an operation results in the same type, regardless of the type of
   * the other operand. When the result or the expression is converted to the type of the target
   * column for storage, an exception is thrown if the resulting value cannot be stored in the
   * column
   *
   * <p>Types narrower than INTEGER (int) are promoted to INTEGER. The order of promotion is as
   * follows
   *
   * <p>INTEGER, BIGINT, NUMERIC/DECIMAL
   *
   * <p>TINYINT and SMALLINT in any combination return INTEGER<br>
   * TINYINT/SMALLINT/INTEGER and INTEGER return BIGINT<br>
   * TINYINT/SMALLINT/INTEGER and BIGINT return NUMERIC/DECIMAL<br>
   * BIGINT and BIGINT return NUMERIC/DECIMAL<br>
   * REAL/FLOAT/DOUBLE and any type return REAL/FLOAT/DOUBLE<br>
   * NUMERIC/DECIMAL any type other than REAL/FLOAT/DOUBLE returns NUMERIC/DECIMAL<br>
   * In the case of NUMERIC/DECIMAL returned, the result precision is always large enough to express
   * any value result, while the scale depends on the operation:<br>
   * For ADD/SUBTRACT/DIVIDE, the scale is the larger of the two<br>
   * For MULTIPLY, the scale is the sum of the two scales<br>
   */
  @Override
  public Type getCombinedType(Type other, int operation) {

    if (other.typeCode == Types.SQL_ALL_TYPES) {
      other = this;
    }

    switch (operation) {
      case OpTypes.ADD:
        break;

      case OpTypes.MULTIPLY:
        if (other.isIntervalType()) {
          return other.getCombinedType(this, OpTypes.MULTIPLY);
        }
        break;

      case OpTypes.DIVIDE:
      case OpTypes.SUBTRACT:
      default:

        // all derivatives of equality ops or comparison ops
        return getAggregateType(other);
    }

    // resolution for ADD and MULTIPLY only
    if (!other.isNumberType()) {
      throw Error.error(ErrorCode.X_42562);
    }

    if (typeWidth == DOUBLE_WIDTH || ((NumberType) other).typeWidth == DOUBLE_WIDTH) {
      return Type.SQL_DOUBLE;
    }

    int sum = typeWidth + ((NumberType) other).typeWidth;

    if (sum <= INTEGER_WIDTH) {
      return Type.SQL_INTEGER;
    }

    if (sum <= BIGINT_WIDTH) {
      return Type.SQL_BIGINT;
    }

    int newScale;
    long newDigits;

    switch (operation) {

        //            case OpCodes.DIVIDE :
        //            case OpCodes.SUBTRACT :
      case OpTypes.ADD:
        newScale = scale > other.scale ? scale : other.scale;
        newDigits =
            precision - scale > other.precision - other.scale
                ? precision - scale
                : other.precision - other.scale;

        newDigits++;
        break;

      case OpTypes.MULTIPLY:
        newDigits = precision - scale + other.precision - other.scale;
        newScale = scale + other.scale;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }

    return getNumberType(Types.SQL_DECIMAL, newScale + newDigits, newScale);
  }