Java Code Examples for org.apache.calcite.sql.type.SqlTypeUtil#isExactNumeric()

The following examples show how to use org.apache.calcite.sql.type.SqlTypeUtil#isExactNumeric() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DremioRexBuilder.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode makeCast(
  RelDataType type,
  RexNode exp,
  boolean matchNullability) {
  // Special case: bypassing Calcite for interval types
  if (!(exp instanceof RexLiteral)
      && SqlTypeUtil.isExactNumeric(type)
      && SqlTypeUtil.isInterval(exp.getType())) {
    return makeAbstractCast(type, exp);
  }
  RexNode castRexNode = super.makeCast(type, exp, matchNullability);

  // If we have a CAST(A, TYPE) and A is already of the same TYPE (including nullability),
  // then return just A.
  if (castRexNode instanceof RexCall
    && castRexNode.getKind() == SqlKind.CAST
    && castRexNode.getType().equals(((RexCall) castRexNode).getOperands().get(0).getType())) {
    return ((RexCall) castRexNode).getOperands().get(0);
  }

  return castRexNode;
}
 
Example 2
Source File: RelDataTypeFactoryImpl.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 *
 * <p>Implement RelDataTypeFactory with SQL 2003 compliant behavior. Let p1,
 * s1 be the precision and scale of the first operand Let p2, s2 be the
 * precision and scale of the second operand Let p, s be the precision and
 * scale of the result, Then the result type is a decimal with:
 *
 * <ul>
 * <li>p = p1 + p2</li>
 * <li>s = s1 + s2</li>
 * </ul>
 *
 * <p>p and s are capped at their maximum values
 *
 * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.26
 */
public RelDataType createDecimalProduct(
    RelDataType type1,
    RelDataType type2) {
  if (SqlTypeUtil.isExactNumeric(type1)
      && SqlTypeUtil.isExactNumeric(type2)) {
    if (SqlTypeUtil.isDecimal(type1)
        || SqlTypeUtil.isDecimal(type2)) {
      int p1 = type1.getPrecision();
      int p2 = type2.getPrecision();
      int s1 = type1.getScale();
      int s2 = type2.getScale();

      int scale = s1 + s2;
      scale = Math.min(scale, typeSystem.getMaxNumericScale());
      int precision = p1 + p2;
      precision =
          Math.min(
              precision,
              typeSystem.getMaxNumericPrecision());

      RelDataType ret;
      ret =
          createSqlType(
              SqlTypeName.DECIMAL,
              precision,
              scale);

      return ret;
    }
  }

  return null;
}
 
Example 3
Source File: RelDataTypeSystemImpl.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelDataType deriveDecimalTruncateType(RelDataTypeFactory typeFactory, RelDataType type1,
  Integer scale2) {
  if (!SqlTypeUtil.isExactNumeric(type1) || !SqlTypeUtil.isDecimal(type1)) {
    return null;
  }

  ArrowType.Decimal finalPrecisionScale = OutputDerivation.getDecimalOutputTypeForTruncate(type1.getPrecision(),
    type1.getScale(), scale2);

  return typeFactory.createSqlType(SqlTypeName.DECIMAL, finalPrecisionScale.getPrecision(),
    finalPrecisionScale.getScale());
}
 
Example 4
Source File: RelDataTypeSystemImpl.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelDataType deriveDecimalRoundType(RelDataTypeFactory typeFactory, RelDataType type1,
  Integer scale2) {
  if (!SqlTypeUtil.isExactNumeric(type1) || !SqlTypeUtil.isDecimal(type1)) {
    return null;
  }

  ArrowType.Decimal finalPrecisionScale = OutputDerivation.getDecimalOutputTypeForRound(type1.getPrecision(),
    type1.getScale(), scale2);

  return typeFactory.createSqlType(SqlTypeName.DECIMAL, finalPrecisionScale.getPrecision(),
    finalPrecisionScale.getScale());
}
 
Example 5
Source File: RelDataTypeSystemImpl.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private RelDataType getDecimalReturnType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2, DecimalTypeUtil
  .OperationType operationType) {
  if (!SqlTypeUtil.isExactNumeric(type1) || !SqlTypeUtil.isExactNumeric(type2) || (!SqlTypeUtil
    .isDecimal(type1) && !SqlTypeUtil.isDecimal(type2))) {
    return null;
  } else {
    ArrowType.Decimal operand1 = new ArrowType.Decimal(type1.getPrecision(), type1.getScale());
    ArrowType.Decimal operand2 = new ArrowType.Decimal(type2.getPrecision(), type2.getScale());
    ArrowType.Decimal output = DecimalTypeUtil.getResultTypeForOperation(operationType, operand1,
      operand2);
    return typeFactory.createSqlType(SqlTypeName.DECIMAL, output.getPrecision(), output.getScale());
  }
}
 
Example 6
Source File: RelDataTypeSystem.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Infers the return type of a decimal multiplication. Decimal
 * multiplication involves at least one decimal operand and requires both
 * operands to have exact numeric types.
 *
 * <p>The default implementation is SQL:2003 compliant.
 *
 * <p>Rules:
 *
 * <ul>
 * <li>Let p1, s1 be the precision and scale of the first operand</li>
 * <li>Let p2, s2 be the precision and scale of the second operand</li>
 * <li>Let p, s be the precision and scale of the result</li>
 * <li>Let d be the number of whole digits in the result</li>
 * <li>Then the result type is a decimal with:
 *   <ul>
 *   <li>p = p1 + p2)</li>
 *   <li>s = s1 + s2</li>
 *   </ul>
 * </li>
 * <li>p and s are capped at their maximum values</li>
 * </ul>
 *
 * <p>p and s are capped at their maximum values
 *
 * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.26
 *
 * @param typeFactory TypeFactory used to create output type
 * @param type1       Type of the first operand
 * @param type2       Type of the second operand
 * @return Result type for a decimal multiplication, or null if decimal
 * multiplication should not be applied to the operands
 */
default RelDataType deriveDecimalMultiplyType(RelDataTypeFactory typeFactory,
    RelDataType type1, RelDataType type2) {
  if (SqlTypeUtil.isExactNumeric(type1)
          && SqlTypeUtil.isExactNumeric(type2)) {
    if (SqlTypeUtil.isDecimal(type1)
            || SqlTypeUtil.isDecimal(type2)) {
      // Java numeric will always have invalid precision/scale,
      // use its default decimal precision/scale instead.
      type1 = RelDataTypeFactoryImpl.isJavaType(type1)
          ? typeFactory.decimalOf(type1)
          : type1;
      type2 = RelDataTypeFactoryImpl.isJavaType(type2)
          ? typeFactory.decimalOf(type2)
          : type2;
      int p1 = type1.getPrecision();
      int p2 = type2.getPrecision();
      int s1 = type1.getScale();
      int s2 = type2.getScale();

      int scale = s1 + s2;
      scale = Math.min(scale, getMaxNumericScale());
      int precision = p1 + p2;
      precision =
              Math.min(
                      precision,
                      getMaxNumericPrecision());

      RelDataType ret;
      ret = typeFactory.createSqlType(
                      SqlTypeName.DECIMAL,
                      precision,
                      scale);

      return ret;
    }
  }

  return null;
}
 
Example 7
Source File: RexUtil.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Returns whether a value of {@code type2} can be assigned to a variable
 * of {@code type1}.
 *
 * <p>For example:
 * <ul>
 *   <li>{@code canAssignFrom(BIGINT, TINYINT)} returns {@code true}</li>
 *   <li>{@code canAssignFrom(TINYINT, BIGINT)} returns {@code false}</li>
 *   <li>{@code canAssignFrom(BIGINT, VARCHAR)} returns {@code false}</li>
 * </ul>
 */
private static boolean canAssignFrom(RelDataType type1, RelDataType type2,
    RelDataTypeFactory typeFactory) {
  final SqlTypeName name1 = type1.getSqlTypeName();
  final SqlTypeName name2 = type2.getSqlTypeName();
  if (name1.getFamily() == name2.getFamily()) {
    switch (name1.getFamily()) {
    case NUMERIC:
      if (SqlTypeUtil.isExactNumeric(type1)
          && SqlTypeUtil.isExactNumeric(type2)) {
        int precision1;
        int scale1;
        if (name1 == SqlTypeName.DECIMAL) {
          type1 = typeFactory.decimalOf(type1);
          precision1 = type1.getPrecision();
          scale1 = type1.getScale();
        } else {
          precision1 = typeFactory.getTypeSystem().getMaxPrecision(name1);
          scale1 = typeFactory.getTypeSystem().getMaxScale(name1);
        }
        int precision2;
        int scale2;
        if (name2 == SqlTypeName.DECIMAL) {
          type2 = typeFactory.decimalOf(type2);
          precision2 = type2.getPrecision();
          scale2 = type2.getScale();
        } else {
          precision2 = typeFactory.getTypeSystem().getMaxPrecision(name2);
          scale2 = typeFactory.getTypeSystem().getMaxScale(name2);
        }
        return precision1 >= precision2
            && scale1 >= scale2;
      } else if (SqlTypeUtil.isApproximateNumeric(type1)
          && SqlTypeUtil.isApproximateNumeric(type2)) {
        return type1.getPrecision() >= type2.getPrecision()
            && type1.getScale() >= type2.getScale();
      }
      break;
    default:
      // getPrecision() will return:
      // - number of decimal digits for fractional seconds for datetime types
      // - length in characters for character types
      // - length in bytes for binary types
      // - RelDataType.PRECISION_NOT_SPECIFIED (-1) if not applicable for this type
      return type1.getPrecision() >= type2.getPrecision();
    }
  }
  return false;
}