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

The following examples show how to use org.apache.calcite.rel.type.RelDataType#getPrecision() . 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: RelNodeConvertor.java    From Mycat2 with GNU General Public License v3.0 6 votes vote down vote up
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 2
Source File: FlinkReturnTypes.java    From flink with 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 3
Source File: TypeInferenceUtils.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
  final RelDataTypeFactory factory = opBinding.getTypeFactory();

  boolean isNullable = true;
  int precision = 0;
  for(RelDataType relDataType : opBinding.collectOperandTypes()) {
    if(!relDataType.isNullable()) {
      isNullable = false;
    }

    // If the underlying columns cannot offer information regarding the precision (i.e., the length) of the VarChar,
    // Dremio uses the largest to represent it
    if(relDataType.getPrecision() == TypeHelper.VARCHAR_DEFAULT_CAST_LEN
        || relDataType.getPrecision() == RelDataType.PRECISION_NOT_SPECIFIED) {
      precision = TypeHelper.VARCHAR_DEFAULT_CAST_LEN;
    } else {
      precision += relDataType.getPrecision();
    }
  }

  return factory.createTypeWithNullability(
      factory.createSqlType(SqlTypeName.VARCHAR, precision),
      isNullable);
}
 
Example 4
Source File: FlinkReturnTypes.java    From flink with 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 5
Source File: TypeInferenceUtils.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {

  // If the underlying columns cannot offer information regarding the precision of the VarChar,
  // Drill uses the largest to represent it.
  int totalPrecision = 0;
  for (RelDataType relDataType : opBinding.collectOperandTypes()) {
    if (isScalarStringType(relDataType.getSqlTypeName()) && relDataType.getPrecision() != RelDataType.PRECISION_NOT_SPECIFIED) {
      totalPrecision += relDataType.getPrecision();
    } else {
      totalPrecision = Types.MAX_VARCHAR_LENGTH;
      break;
    }
  }

  totalPrecision = totalPrecision > Types.MAX_VARCHAR_LENGTH ? Types.MAX_VARCHAR_LENGTH : totalPrecision;
  boolean isNullable = isNullIfNull && isNullable(opBinding.collectOperandTypes());

  return opBinding.getTypeFactory().createTypeWithNullability(
      opBinding.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, totalPrecision),
      isNullable);
}
 
Example 6
Source File: RelToSqlConverter.java    From quark with 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 7
Source File: MaterializationExpander.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private static boolean isSumAggOutput(RelDataType type1, RelDataType type2) {
  if (type1.getSqlTypeName() == SqlTypeName
    .DECIMAL && type2.getSqlTypeName() == SqlTypeName.DECIMAL) {
    // output of sum aggregation is always 38,inputScale
    return type1.getPrecision() == 38 && type1.getScale() == type2.getScale();
  }
  return false;
}
 
Example 8
Source File: SqlTypeUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Computes the maximum number of bytes required to represent a value of a
 * type having user-defined precision. This computation assumes no overhead
 * such as length indicators and NUL-terminators. Complex types for which
 * multiple representations are possible (e.g. DECIMAL or TIMESTAMP) return
 * 0.
 *
 * @param type type for which to compute storage
 * @return maximum bytes, or 0 for a fixed-width type or type with unknown
 * maximum
 */
public static int getMaxByteSize(RelDataType type) {
  SqlTypeName typeName = type.getSqlTypeName();

  if (typeName == null) {
    return 0;
  }

  switch (typeName) {
  case CHAR:
  case VARCHAR:
    return (int) Math.ceil(
        ((double) type.getPrecision())
            * type.getCharset().newEncoder().maxBytesPerChar());

  case BINARY:
  case VARBINARY:
    return type.getPrecision();

  case MULTISET:

    // TODO Wael Jan-24-2005: Need a better way to tell fennel this
    // number. This a very generic place and implementation details like
    // this doesnt belong here. Waiting to change this once we have blob
    // support
    return 4096;

  default:
    return 0;
  }
}
 
Example 9
Source File: RexUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Returns whether the conversion from {@code source} to {@code target} type
 * 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.
 * @param source source type
 * @param target target type
 * @return true iff the conversion is a loss-less cast
 */
@API(since = "1.22", status = API.Status.EXPERIMENTAL)
public static boolean isLosslessCast(RelDataType source, RelDataType target) {
  final SqlTypeName sourceSqlTypeName = source.getSqlTypeName();
  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 10
Source File: DrillRelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
public static boolean areRowTypesCompatible(RelDataType rowType1, RelDataType rowType2, boolean compareNames,
        boolean allowSubstring) {
    if (rowType1 == rowType2) {
        return true;
    }
    if (compareNames) {
        // if types are not identity-equal, then either the names or
        // the types must be different
        return false;
    }
    if (rowType2.getFieldCount() != rowType1.getFieldCount()) {
        return false;
    }
    final List<RelDataTypeField> f1 = rowType1.getFieldList();
    final List<RelDataTypeField> f2 = rowType2.getFieldList();
    for (Pair<RelDataTypeField, RelDataTypeField> pair : Pair.zip(f1, f2)) {
        final RelDataType type1 = pair.left.getType();
        final RelDataType type2 = pair.right.getType();
        // If one of the types is ANY comparison should succeed
        if (type1.getSqlTypeName() == SqlTypeName.ANY || type2.getSqlTypeName() == SqlTypeName.ANY) {
            continue;
        }
        if (type1.getSqlTypeName() != type2.getSqlTypeName()) {
            if (allowSubstring
                    && (type1.getSqlTypeName() == SqlTypeName.CHAR && type2.getSqlTypeName() == SqlTypeName.CHAR)
                    && (type1.getPrecision() <= type2.getPrecision())) {
                return true;
            }

            // Check if Drill implicit casting can resolve the incompatibility
            List<TypeProtos.MinorType> types = Lists.newArrayListWithCapacity(2);
            types.add(Types.getMinorTypeFromName(type1.getSqlTypeName().getName()));
            types.add(Types.getMinorTypeFromName(type2.getSqlTypeName().getName()));
            return TypeCastRules.getLeastRestrictiveType(types) != null;
        }
    }
    return true;
}
 
Example 11
Source File: RexUtil.java    From Bats with 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 File: SqlTypeUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Computes the maximum number of bytes required to represent a value of a
 * type having user-defined precision. This computation assumes no overhead
 * such as length indicators and NUL-terminators. Complex types for which
 * multiple representations are possible (e.g. DECIMAL or TIMESTAMP) return
 * 0.
 *
 * @param type type for which to compute storage
 * @return maximum bytes, or 0 for a fixed-width type or type with unknown
 * maximum
 */
public static int getMaxByteSize(RelDataType type) {
  SqlTypeName typeName = type.getSqlTypeName();

  if (typeName == null) {
    return 0;
  }

  switch (typeName) {
  case CHAR:
  case VARCHAR:
    return (int) Math.ceil(
        ((double) type.getPrecision())
            * type.getCharset().newEncoder().maxBytesPerChar());

  case BINARY:
  case VARBINARY:
    return type.getPrecision();

  case MULTISET:

    // TODO Wael Jan-24-2005: Need a better way to tell fennel this
    // number. This a very generic place and implementation details like
    // this doesnt belong here. Waiting to change this once we have blob
    // support
    return 4096;

  default:
    return 0;
  }
}
 
Example 13
Source File: MysqlSqlDialect.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public SqlNode getCastSpec(RelDataType type) {
  switch (type.getSqlTypeName()) {
  case VARCHAR:
    // MySQL doesn't have a VARCHAR type, only CHAR.
    int vcMaxPrecision = this.getTypeSystem().getMaxPrecision(SqlTypeName.CHAR);
    int precision = type.getPrecision();
    if (vcMaxPrecision > 0 && precision > vcMaxPrecision) {
      precision = vcMaxPrecision;
    }
    return new SqlDataTypeSpec(
        new SqlBasicTypeNameSpec(SqlTypeName.CHAR, precision, SqlParserPos.ZERO),
        SqlParserPos.ZERO);
  case INTEGER:
  case BIGINT:
    return new SqlDataTypeSpec(
        new SqlAlienSystemTypeNameSpec(
            "SIGNED",
            type.getSqlTypeName(),
            SqlParserPos.ZERO),
        SqlParserPos.ZERO);
  case TIMESTAMP:
    return new SqlDataTypeSpec(
        new SqlAlienSystemTypeNameSpec(
            "DATETIME",
            type.getSqlTypeName(),
            SqlParserPos.ZERO),
        SqlParserPos.ZERO);
  }
  return super.getCastSpec(type);
}
 
Example 14
Source File: RexLiteral.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Computes if data type can be omitted from the digset.
 * <p>For instance, {@code 1:BIGINT} has to keep data type while {@code 1:INT}
 * should be represented as just {@code 1}.
 *
 * <p>Implementation assumption: this method should be fast. In fact might call
 * {@link NlsString#getValue()} which could decode the string, however we rely on the cache there.
 *
 * @see RexLiteral#computeDigest(RexDigestIncludeType)
 * @param value value of the literal
 * @param type type of the literal
 * @return NO_TYPE when type can be omitted, ALWAYS otherwise
 */
private static RexDigestIncludeType shouldIncludeType(Comparable value, RelDataType type) {
  if (type.isNullable()) {
    // This means "null literal", so we require a type for it
    // There might be exceptions like AND(null, true) which are handled by RexCall#computeDigest
    return RexDigestIncludeType.ALWAYS;
  }
  // The variable here simplifies debugging (one can set a breakpoint at return)
  // final ensures we set the value in all the branches, and it ensures the value is set just once
  final RexDigestIncludeType includeType;
  if (type.getSqlTypeName() == SqlTypeName.BOOLEAN
      || type.getSqlTypeName() == SqlTypeName.INTEGER
      || type.getSqlTypeName() == SqlTypeName.SYMBOL) {
    // We don't want false:BOOLEAN NOT NULL, so we don't print type information for
    // non-nullable BOOLEAN and INTEGER
    includeType = RexDigestIncludeType.NO_TYPE;
  } else if (type.getSqlTypeName() == SqlTypeName.CHAR
          && value instanceof NlsString) {
    NlsString nlsString = (NlsString) value;

    // Ignore type information for 'Bar':CHAR(3)
    if ((
        (nlsString.getCharset() != null && type.getCharset().equals(nlsString.getCharset()))
        || (nlsString.getCharset() == null
        && SqlCollation.IMPLICIT.getCharset().equals(type.getCharset())))
        && nlsString.getCollation().equals(type.getCollation())
        && ((NlsString) value).getValue().length() == type.getPrecision()) {
      includeType = RexDigestIncludeType.NO_TYPE;
    } else {
      includeType = RexDigestIncludeType.ALWAYS;
    }
  } else if (type.getPrecision() == 0 && (
             type.getSqlTypeName() == SqlTypeName.TIME
          || type.getSqlTypeName() == SqlTypeName.TIMESTAMP
          || type.getSqlTypeName() == SqlTypeName.DATE)) {
    // Ignore type information for '12:23:20':TIME(0)
    // Note that '12:23:20':TIME WITH LOCAL TIME ZONE
    includeType = RexDigestIncludeType.NO_TYPE;
  } else {
    includeType = RexDigestIncludeType.ALWAYS;
  }
  return includeType;
}
 
Example 15
Source File: MoreRelOptUtil.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
private static boolean checkRowTypesCompatiblity(
    RelDataType rowType1,
    RelDataType rowType2,
    boolean compareNames,
    boolean allowSubstring,
    boolean insertOp) {
  if (rowType1 == rowType2) {
    return true;
  }
  if (compareNames) {
    // if types are not identity-equal, then either the names or
    // the types must be different
    return false;
  }
  if (rowType2.getFieldCount() != rowType1.getFieldCount()) {
    return false;
  }
  final List<RelDataTypeField> f1 = rowType1.getFieldList();
  final List<RelDataTypeField> f2 = rowType2.getFieldList();
  for (Pair<RelDataTypeField, RelDataTypeField> pair : Pair.zip(f1, f2)) {
    final RelDataType type1 = pair.left.getType();
    final RelDataType type2 = pair.right.getType();
    // If one of the types is ANY comparison should succeed
    if (type1.getSqlTypeName() == SqlTypeName.ANY
      || type2.getSqlTypeName() == SqlTypeName.ANY) {
      continue;
    }
    if (!(type1.toString().equals(type2.toString()))) {
      if (allowSubstring
          && (type1.getSqlTypeName() == SqlTypeName.CHAR && type2.getSqlTypeName() == SqlTypeName.CHAR)
          && (type1.getPrecision() <= type2.getPrecision())) {
        continue;
      }

      // Check if Dremio implicit casting can resolve the incompatibility
      List<TypeProtos.MinorType> types = Lists.newArrayListWithCapacity(2);
      TypeProtos.MinorType minorType1 = Types.getMinorTypeFromName(type1.getSqlTypeName().getName());
      TypeProtos.MinorType minorType2 = Types.getMinorTypeFromName(type2.getSqlTypeName().getName());
      types.add(minorType1);
      types.add(minorType2);
      if (insertOp) {
        // Insert is more strict than normal select in terms of implicit casts
        // Return false if TypeCastRules do not allow implicit cast
        if (TypeCastRules.isCastable(minorType1, minorType2, true) &&
          TypeCastRules.getLeastRestrictiveTypeForInsert(types) != null) {
          if (TypeCastRules.isCastSafeFromDataTruncation(type1, type2)) {
            continue;
          }
        }
      } else {
        if (TypeCastRules.getLeastRestrictiveType(types) != null) {
          continue;
        }
      }

      return false;
    }
  }
  return true;
}
 
Example 16
Source File: RelMdSize.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Estimates the average size (in bytes) of a value of a type.
 *
 * <p>We assume that the proportion of nulls is negligible, even if the type
 * is nullable.
 */
public Double averageTypeValueSize(RelDataType type) {
  switch (type.getSqlTypeName()) {
  case BOOLEAN:
  case TINYINT:
    return 1d;
  case SMALLINT:
    return 2d;
  case INTEGER:
  case REAL:
  case DECIMAL:
  case DATE:
  case TIME:
  case TIME_WITH_LOCAL_TIME_ZONE:
  case INTERVAL_YEAR:
  case INTERVAL_YEAR_MONTH:
  case INTERVAL_MONTH:
    return 4d;
  case BIGINT:
  case DOUBLE:
  case FLOAT: // sic
  case TIMESTAMP:
  case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
  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:
    return 8d;
  case BINARY:
    return (double) type.getPrecision();
  case VARBINARY:
    return Math.min((double) type.getPrecision(), 100d);
  case CHAR:
    return (double) type.getPrecision() * BYTES_PER_CHARACTER;
  case VARCHAR:
    // Even in large (say VARCHAR(2000)) columns most strings are small
    return Math.min((double) type.getPrecision() * BYTES_PER_CHARACTER, 100d);
  case ROW:
    double average = 0.0;
    for (RelDataTypeField field : type.getFieldList()) {
      average += averageTypeValueSize(field.getType());
    }
    return average;
  default:
    return null;
  }
}
 
Example 17
Source File: PlanExecutor.java    From quark with Apache License 2.0 4 votes vote down vote up
private static int getPrecision(RelDataType type) {
  return type.getPrecision() == RelDataType.PRECISION_NOT_SPECIFIED
      ? 0
      : type.getPrecision();
}
 
Example 18
Source File: CalcitePrepareImpl.java    From calcite with Apache License 2.0 4 votes vote down vote up
private static int getPrecision(RelDataType type) {
  return type.getPrecision() == RelDataType.PRECISION_NOT_SPECIFIED
      ? 0
      : type.getPrecision();
}
 
Example 19
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;
}
 
Example 20
Source File: RelDecorrelator.java    From calcite with Apache License 2.0 2 votes vote down vote up
/** Returns whether one type is just a widening of another.
 *
 * <p>For example:<ul>
 * <li>{@code VARCHAR(10)} is a widening of {@code VARCHAR(5)}.
 * <li>{@code VARCHAR(10)} is a widening of {@code VARCHAR(10) NOT NULL}.
 * </ul>
 */
private boolean isWidening(RelDataType type, RelDataType type1) {
  return type.getSqlTypeName() == type1.getSqlTypeName()
      && type.getPrecision() >= type1.getPrecision();
}