Java Code Examples for org.apache.calcite.rel.type.RelDataType#getScale()

The following examples show how to use org.apache.calcite.rel.type.RelDataType#getScale() . 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 Project: Bats   File: SqlDialect.java    License: Apache License 2.0 6 votes vote down vote up
public SqlNode getCastSpec(RelDataType type) {
  if (type instanceof BasicSqlType) {
    int precision = type.getPrecision();
    switch (type.getSqlTypeName()) {
    case VARCHAR:
      // if needed, adjust varchar length to max length supported by the system
      int maxPrecision = getTypeSystem().getMaxPrecision(type.getSqlTypeName());
      if (type.getPrecision() > maxPrecision) {
        precision = maxPrecision;
      }
    }
    return new SqlDataTypeSpec(
        new SqlIdentifier(type.getSqlTypeName().name(), SqlParserPos.ZERO),
            precision,
            type.getScale(),
            type.getCharset() != null
                && supportsCharSet()
                ? type.getCharset().name()
                : null,
            null,
            SqlParserPos.ZERO);
  }
  return SqlTypeUtil.convertTypeToSpec(type);
}
 
Example 2
Source Project: calcite   File: ReduceDecimalsRule.java    License: Apache License 2.0 6 votes vote down vote up
private RexNode expandDivide(RexCall call, List<RexNode> operands) {
  RelDataType outType = call.getType();
  RexNode dividend =
      builder.makeCall(
          call.getOperator(),
          ensureType(
              real8,
              accessValue(operands.get(0))),
          ensureType(
              real8,
              accessValue(operands.get(1))));
  int scaleDifference = outType.getScale() - scaleA + scaleB;
  RexNode rescale =
      builder.makeCall(
          SqlStdOperatorTable.MULTIPLY,
          dividend,
          makeApproxScaleFactor(scaleDifference));
  return encodeValue(rescale, outType);
}
 
Example 3
Source Project: flink   File: FlinkReturnTypes.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
	final RelDataType numType = opBinding.getOperandType(0);
	if (numType.getSqlTypeName() != SqlTypeName.DECIMAL) {
		return numType;
	}
	final BigDecimal lenVal;
	if (opBinding.getOperandCount() == 1) {
		lenVal = BigDecimal.ZERO;
	} else if (opBinding.getOperandCount() == 2) {
		lenVal = getArg1Literal(opBinding); // may return null
	} else {
		throw new AssertionError();
	}
	if (lenVal == null) {
		return numType; //
	}
	// ROUND( decimal(p,s), r )
	final int p = numType.getPrecision();
	final int s = numType.getScale();
	final int r = lenVal.intValueExact();
	DecimalType dt = FlinkTypeSystem.inferRoundType(p, s, r);
	return opBinding.getTypeFactory().createSqlType(
		SqlTypeName.DECIMAL, dt.getPrecision(), dt.getScale());
}
 
Example 4
private static List<FieldType> getFields(RelNode relNode) {
    RelDataType rowType = relNode.getRowType();
    List<RelDataTypeField> fieldList = rowType.getFieldList();
    ArrayList<FieldType> fieldSchemas = new ArrayList<>(fieldList.size());
    for (RelDataTypeField relDataTypeField : fieldList) {
        String name = relDataTypeField.getName();
        RelDataType type = relDataTypeField.getType();
        SqlTypeName sqlTypeName = type.getSqlTypeName();
        boolean nullable = type.isNullable();
        Integer precision = null;
        Integer scale = null;
        if (sqlTypeName.allowsPrec()) {
            precision = type.getPrecision();
        }
        if (sqlTypeName.allowsScale()) {
            scale = type.getScale();
        }
        fieldSchemas.add(new FieldType(name, ExprExplain.type(sqlTypeName), nullable, precision, scale));
    }
    return fieldSchemas;
}
 
Example 5
Source Project: dremio-oss   File: TypeCastRules.java    License: Apache License 2.0 6 votes vote down vote up
public static boolean isCastSafeFromDataTruncation(RelDataType type1, RelDataType type2) {
  switch ((type1.getSqlTypeName())) {
    case TINYINT:
    case SMALLINT:
    case INTEGER:
    case FLOAT:
    case BIGINT:
    case DOUBLE:
      // cast to decimal is allowed if target type has enough digits to the left of decimal point
      return (type2.getSqlTypeName() != SqlTypeName.DECIMAL) ||
        (type2.getPrecision() - type2.getScale() >= getMaxPrecision(type1.getSqlTypeName()));
    case DECIMAL:
      switch (type2.getSqlTypeName()) {
        case DECIMAL:
          return ( (type2.getScale() >= type1.getScale()) &&
            (type2.getPrecision() - type2.getScale() >= type1.getPrecision() - type1.getScale()));
        case FLOAT:
        case DOUBLE:
          return true;
        default:
          return false;
      }
    default:
      return true;
  }
}
 
Example 6
Source Project: flink   File: FlinkReturnTypes.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
	final RelDataType numType = opBinding.getOperandType(0);
	if (numType.getSqlTypeName() != SqlTypeName.DECIMAL) {
		return numType;
	}
	final BigDecimal lenVal;
	if (opBinding.getOperandCount() == 1) {
		lenVal = BigDecimal.ZERO;
	} else if (opBinding.getOperandCount() == 2) {
		lenVal = getArg1Literal(opBinding); // may return null
	} else {
		throw new AssertionError();
	}
	if (lenVal == null) {
		return numType; //
	}
	// ROUND( decimal(p,s), r )
	final int p = numType.getPrecision();
	final int s = numType.getScale();
	final int r = lenVal.intValueExact();
	DecimalType dt = LogicalTypeMerging.findRoundDecimalType(p, s, r);
	return opBinding.getTypeFactory().createSqlType(
		SqlTypeName.DECIMAL, dt.getPrecision(), dt.getScale());
}
 
Example 7
Source Project: calcite   File: ReduceDecimalsRule.java    License: Apache License 2.0 6 votes vote down vote up
private RexNode expandPlusMinus(RexCall call, List<RexNode> operands) {
  RelDataType outType = call.getType();
  int outScale = outType.getScale();
  return encodeValue(
      builder.makeCall(
          call.getOperator(),
          ensureScale(
              accessValue(operands.get(0)),
              scaleA,
              outScale),
          ensureScale(
              accessValue(operands.get(1)),
              scaleB,
              outScale)),
      outType);
}
 
Example 8
Source Project: Bats   File: ReduceDecimalsRule.java    License: Apache License 2.0 5 votes vote down vote up
private RexNode expandPlusMinus(RexCall call, List<RexNode> operands) {
    RelDataType outType = call.getType();
    int outScale = outType.getScale();
    return encodeValue(
            builder.makeCall(call.getOperator(), ensureScale(accessValue(operands.get(0)), scaleA, outScale),
                    ensureScale(accessValue(operands.get(1)), scaleB, outScale)),
            outType);
}
 
Example 9
Source Project: Bats   File: ReduceDecimalsRule.java    License: Apache License 2.0 5 votes vote down vote up
private RexNode expandDivide(RexCall call, List<RexNode> operands) {
    RelDataType outType = call.getType();
    RexNode dividend = builder.makeCall(call.getOperator(), ensureType(real8, accessValue(operands.get(0))),
            ensureType(real8, accessValue(operands.get(1))));
    int scaleDifference = outType.getScale() - scaleA + scaleB;
    RexNode rescale = builder.makeCall(SqlStdOperatorTable.MULTIPLY, dividend,
            makeApproxScaleFactor(scaleDifference));
    return encodeValue(rescale, outType);
}
 
Example 10
Source Project: Bats   File: ReduceDecimalsRule.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Detect, in a generic, but strict way, whether it is possible to
 * simplify a reinterpret cast. The rules are as follows:
 *
 * <ol>
 * <li>If value is not the same basic type as outer, then we cannot
 * simplify
 * <li>If the value is nullable but the inner or outer are not, then we
 * cannot simplify.
 * <li>If inner is nullable but outer is not, we cannot simplify.
 * <li>If an overflow check is required from either inner or outer, we
 * cannot simplify.
 * <li>Otherwise, given the same type, and sufficient nullability
 * constraints, we can simplify.
 * </ol>
 *
 * @param outer outer call to reinterpret
 * @param inner inner call to reinterpret
 * @param value inner value
 * @return whether the two reinterpret casts can be removed
 */
private boolean canSimplify(RexCall outer, RexCall inner, RexNode value) {
    RelDataType outerType = outer.getType();
    RelDataType innerType = inner.getType();
    RelDataType valueType = value.getType();
    boolean outerCheck = RexUtil.canReinterpretOverflow(outer);
    boolean innerCheck = RexUtil.canReinterpretOverflow(inner);

    if ((outerType.getSqlTypeName() != valueType.getSqlTypeName())
            || (outerType.getPrecision() != valueType.getPrecision())
            || (outerType.getScale() != valueType.getScale())) {
        return false;
    }
    if (valueType.isNullable() && (!innerType.isNullable() || !outerType.isNullable())) {
        return false;
    }
    if (innerType.isNullable() && !outerType.isNullable()) {
        return false;
    }

    // One would think that we could go from Nullable -> Not Nullable
    // since we are substituting a general type with a more specific
    // type. However the optimizer doesn't like it.
    if (valueType.isNullable() != outerType.isNullable()) {
        return false;
    }
    if (innerCheck || outerCheck) {
        return false;
    }
    return true;
}
 
Example 11
Source Project: Bats   File: RexUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Returns whether the input is a 'loss-less' cast, that is, a cast from which
 * the original value of the field can be certainly recovered.
 *
 * <p>For instance, int &rarr; bigint is loss-less (as you can cast back to
 * int without loss of information), but bigint &rarr; int is not loss-less.
 *
 * <p>The implementation of this method does not return false positives.
 * However, it is not complete.
 */
public static boolean isLosslessCast(RexNode node) {
    if (!node.isA(SqlKind.CAST)) {
        return false;
    }
    final RelDataType source = ((RexCall) node).getOperands().get(0).getType();
    final SqlTypeName sourceSqlTypeName = source.getSqlTypeName();
    final RelDataType target = node.getType();
    final SqlTypeName targetSqlTypeName = target.getSqlTypeName();
    // 1) Both INT numeric types
    if (SqlTypeFamily.INTEGER.getTypeNames().contains(sourceSqlTypeName)
            && SqlTypeFamily.INTEGER.getTypeNames().contains(targetSqlTypeName)) {
        return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0;
    }
    // 2) Both CHARACTER types: it depends on the precision (length)
    if (SqlTypeFamily.CHARACTER.getTypeNames().contains(sourceSqlTypeName)
            && SqlTypeFamily.CHARACTER.getTypeNames().contains(targetSqlTypeName)) {
        return targetSqlTypeName.compareTo(sourceSqlTypeName) >= 0
                && source.getPrecision() <= target.getPrecision();
    }
    // 3) From NUMERIC family to CHARACTER family: it depends on the precision/scale
    if (sourceSqlTypeName.getFamily() == SqlTypeFamily.NUMERIC
            && targetSqlTypeName.getFamily() == SqlTypeFamily.CHARACTER) {
        int sourceLength = source.getPrecision() + 1; // include sign
        if (source.getScale() != -1 && source.getScale() != 0) {
            sourceLength += source.getScale() + 1; // include decimal mark
        }
        return target.getPrecision() >= sourceLength;
    }
    // Return FALSE by default
    return false;
}
 
Example 12
Source Project: Bats   File: SqlConverter.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Creates a call to the CAST operator, expanding if possible, and optionally
 * also preserving nullability.
 *
 * <p>Tries to expand the cast, and therefore the result may be something
 * other than a {@link org.apache.calcite.rex.RexCall} to the CAST operator, such as a
 * {@link RexLiteral} if {@code matchNullability} is false.
 *
 * @param type             Type to cast to
 * @param exp              Expression being cast
 * @param matchNullability Whether to ensure the result has the same
 *                         nullability as {@code type}
 * @return Call to CAST operator
 */
@Override
public RexNode makeCast(RelDataType type, RexNode exp, boolean matchNullability) {
  if (matchNullability) {
    return makeAbstractCast(type, exp);
  }
  // for the case when BigDecimal literal has a scale or precision
  // that differs from the value from specified RelDataType, cast cannot be removed
  // TODO: remove this code when CALCITE-1468 is fixed
  if (type.getSqlTypeName() == SqlTypeName.DECIMAL && exp instanceof RexLiteral) {
    if (type.getPrecision() < 1) {
      throw UserException.validationError()
          .message("Expected precision greater than 0, but was %s.", type.getPrecision())
          .build(logger);
    }
    if (type.getScale() > type.getPrecision()) {
      throw UserException.validationError()
          .message("Expected scale less than or equal to precision, " +
              "but was scale %s and precision %s.", type.getScale(), type.getPrecision())
          .build(logger);
    }
    RexLiteral literal = (RexLiteral) exp;
    Comparable value = literal.getValueAs(Comparable.class);
    if (value instanceof BigDecimal) {
      BigDecimal bigDecimal = (BigDecimal) value;
      DecimalUtility.checkValueOverflow(bigDecimal, type.getPrecision(), type.getScale());
      if (bigDecimal.scale() != type.getScale() || bigDecimal.precision() != type.getPrecision()) {
        return makeAbstractCast(type, exp);
      }
    }
  }
  return super.makeCast(type, exp, false);
}
 
Example 13
Source Project: Bats   File: View.java    License: Apache License 2.0 5 votes vote down vote up
public Field(String name, RelDataType dataType) {
  this.name = name;
  this.type = dataType.getSqlTypeName();
  this.isNullable = dataType.isNullable();
  this.intervalQualifier = dataType.getIntervalQualifier();
  switch (dataType.getSqlTypeName()) {
    case CHAR:
    case BINARY:
    case VARBINARY:
    case VARCHAR:
      this.precision = dataType.getPrecision();
      break;
    case DECIMAL:
      this.precision = dataType.getPrecision();
      this.scale = dataType.getScale();
      break;
    case INTERVAL_YEAR:
    case INTERVAL_YEAR_MONTH:
    case INTERVAL_MONTH:
    case INTERVAL_DAY:
    case INTERVAL_DAY_HOUR:
    case INTERVAL_DAY_MINUTE:
    case INTERVAL_DAY_SECOND:
    case INTERVAL_HOUR:
    case INTERVAL_HOUR_MINUTE:
    case INTERVAL_HOUR_SECOND:
    case INTERVAL_MINUTE:
    case INTERVAL_MINUTE_SECOND:
    case INTERVAL_SECOND:
      this.precision = dataType.getIntervalQualifier().getStartPrecisionPreservingDefault();
      break;
    case MAP:
      keyType = new Field(dataType.getKeyType());
      valueType = new Field(dataType.getValueType());
      break;
  }
}
 
Example 14
Source Project: dremio-oss   File: DremioSqlDialect.java    License: Apache License 2.0 5 votes vote down vote up
protected static SqlNode getVarcharWithPrecision(DremioSqlDialect dialect, RelDataType type, int precision) {
  return new SqlDataTypeSpec(
    new SqlIdentifier(type.getSqlTypeName().name(), SqlParserPos.ZERO),
    precision,
    type.getScale(),
    type.getCharset() != null && dialect.supportsCharSet()
      ? type.getCharset().name() : null,
    null,
    SqlParserPos.ZERO);
}
 
Example 15
Source Project: quark   File: RelToSqlConverter.java    License: Apache License 2.0 5 votes vote down vote up
private SqlNode toSql(RelDataType type) {
  switch (dialect.getDatabaseProduct()) {
    case MYSQL:
      switch (type.getSqlTypeName()) {
        case VARCHAR:
          // MySQL doesn't have a VARCHAR type, only CHAR.
          return new SqlDataTypeSpec(new SqlIdentifier("CHAR", POS),
              type.getPrecision(), -1, null, null, POS);
        case INTEGER:
          return new SqlDataTypeSpec(new SqlIdentifier("_UNSIGNED", POS),
              type.getPrecision(), -1, null, null, POS);
      }
      break;
  }
  if (type instanceof BasicSqlType) {
    return new SqlDataTypeSpec(
        new SqlIdentifier(type.getSqlTypeName().name(), POS),
        type.getPrecision(),
        type.getScale(),
        type.getCharset() != null
            && dialect.supportsCharSet()
            ? type.getCharset().name()
            : null,
        null,
        POS);
  }

  return SqlTypeUtil.convertTypeToSpec(type);
  //throw new AssertionError(type); // TODO: implement
}
 
Example 16
Source Project: Bats   File: SqlTypeUtil.java    License: Apache License 2.0 4 votes vote down vote up
/** Returns whether a type's scale is set. */
public static boolean hasScale(RelDataType type) {
  return type.getScale() != Integer.MIN_VALUE;
}
 
Example 17
Source Project: dremio-oss   File: View.java    License: Apache License 2.0 4 votes vote down vote up
public FieldType(String name, RelDataType dataType) {
  this.name = name;
  this.type = dataType.getSqlTypeName();

  Integer p = null;
  Integer s = null;

  switch (dataType.getSqlTypeName()) {
  case CHAR:
  case BINARY:
  case VARBINARY:
  case VARCHAR:
    p = dataType.getPrecision();
    break;
  case DECIMAL:
    p = dataType.getPrecision();
    s = dataType.getScale();
    break;
  case TIME:
  case TIMESTAMP:
    p = dataType.getPrecision();
    break;
  case INTERVAL_YEAR:
  case INTERVAL_YEAR_MONTH:
  case INTERVAL_MONTH:
  case INTERVAL_DAY:
  case INTERVAL_DAY_HOUR:
  case INTERVAL_DAY_MINUTE:
  case INTERVAL_DAY_SECOND:
  case INTERVAL_HOUR:
  case INTERVAL_HOUR_MINUTE:
  case INTERVAL_HOUR_SECOND:
  case INTERVAL_MINUTE:
  case INTERVAL_MINUTE_SECOND:
  case INTERVAL_SECOND:
    p = dataType.getIntervalQualifier().getStartPrecisionPreservingDefault();
  default:
    break;
  }

  this.precision = p;
  this.scale = s;
  this.intervalQualifier = dataType.getIntervalQualifier();
  this.isNullable = dataType.isNullable();
}
 
Example 18
Source Project: calcite   File: RexUtil.java    License: 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;
}
 
Example 19
Source Project: calcite   File: CalcitePrepareImpl.java    License: Apache License 2.0 4 votes vote down vote up
private static int getScale(RelDataType type) {
  return type.getScale() == RelDataType.SCALE_NOT_SPECIFIED
      ? 0
      : type.getScale();
}
 
Example 20
Source Project: quark   File: PlanExecutor.java    License: Apache License 2.0 4 votes vote down vote up
private static int getScale(RelDataType type) {
  return type.getScale() == RelDataType.SCALE_NOT_SPECIFIED
      ? 0
      : type.getScale();
}