Example #1
0
 private RexNode makeCastExactToInterval(RelDataType toType, RexNode exp) {
   IntervalSqlType intervalType = (IntervalSqlType) toType;
   TimeUnit endUnit = intervalType.getIntervalQualifier().getEndUnit();
   if (endUnit == null) {
     endUnit = intervalType.getIntervalQualifier().getStartUnit();
   }
   int scale = 0;
   if (endUnit == TimeUnit.SECOND) {
     scale =
         Math.min(
             intervalType
                 .getIntervalQualifier()
                 .getFractionalSecondPrecision(typeFactory.getTypeSystem()),
             3);
   }
   BigDecimal multiplier =
       BigDecimal.valueOf(endUnit.multiplier).divide(BigDecimal.TEN.pow(scale));
   RelDataType decimalType =
       getTypeFactory()
           .createSqlType(SqlTypeName.DECIMAL, scale + intervalType.getPrecision(), scale);
   RexNode value = decodeIntervalOrDecimal(ensureType(decimalType, exp, true));
   if (multiplier.longValue() != 1) {
     value = makeCall(SqlStdOperatorTable.MULTIPLY, value, makeExactLiteral(multiplier));
   }
   return encodeIntervalOrDecimal(value, toType, false);
 }
Example #2
0
  /**
   * Returns the type the row which results when two relations are joined.
   *
   * <p>The resulting row type consists of the system fields (if any), followed by the fields of the
   * left type, followed by the fields of the right type. The field name list, if present, overrides
   * the original names of the fields.
   *
   * @param typeFactory Type factory
   * @param leftType Type of left input to join
   * @param rightType Type of right input to join
   * @param fieldNameList If not null, overrides the original names of the fields
   * @param systemFieldList List of system fields that will be prefixed to output row type;
   *     typically empty but must not be null
   * @return type of row which results when two relations are joined
   */
  public static RelDataType createJoinType(
      RelDataTypeFactory typeFactory,
      RelDataType leftType,
      RelDataType rightType,
      List<String> fieldNameList,
      List<RelDataTypeField> systemFieldList) {
    assert (fieldNameList == null)
        || (fieldNameList.size()
            == (systemFieldList.size() + leftType.getFieldCount() + rightType.getFieldCount()));
    List<String> nameList = new ArrayList<>();
    final List<RelDataType> typeList = new ArrayList<>();

    // Use a set to keep track of the field names; this is needed
    // to ensure that the contains() call to check for name uniqueness
    // runs in constant time; otherwise, if the number of fields is large,
    // doing a contains() on a list can be expensive.
    final Set<String> uniqueNameList =
        typeFactory.getTypeSystem().isSchemaCaseSensitive()
            ? new HashSet<String>()
            : new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
    addFields(systemFieldList, typeList, nameList, uniqueNameList);
    addFields(leftType.getFieldList(), typeList, nameList, uniqueNameList);
    if (rightType != null) {
      addFields(rightType.getFieldList(), typeList, nameList, uniqueNameList);
    }
    if (fieldNameList != null) {
      assert fieldNameList.size() == nameList.size();
      nameList = fieldNameList;
    }
    return typeFactory.createStructType(typeList, nameList);
  }
Example #3
0
 /** Creates a numeric literal. */
 public RexLiteral makeExactLiteral(BigDecimal bd) {
   RelDataType relType;
   int scale = bd.scale();
   long l = bd.unscaledValue().longValue();
   assert scale >= 0;
   assert scale <= typeFactory.getTypeSystem().getMaxNumericScale() : scale;
   assert BigDecimal.valueOf(l, scale).equals(bd);
   if (scale == 0) {
     if ((l >= Integer.MIN_VALUE) && (l <= Integer.MAX_VALUE)) {
       relType = typeFactory.createSqlType(SqlTypeName.INTEGER);
     } else {
       relType = typeFactory.createSqlType(SqlTypeName.BIGINT);
     }
   } else {
     int precision = bd.unscaledValue().toString().length();
     relType = typeFactory.createSqlType(SqlTypeName.DECIMAL, scale, precision);
   }
   return makeExactLiteral(bd, relType);
 }