Java Code Examples for org.apache.calcite.sql.type.SqlTypeName#getFamily()

The following examples show how to use org.apache.calcite.sql.type.SqlTypeName#getFamily() . 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: TypeInferenceUtils.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Given a {@link SqlTypeName} and nullability, create a RelDataType from the RelDataTypeFactory
 *
 * @param typeFactory RelDataTypeFactory used to create the RelDataType
 * @param sqlTypeName the given SqlTypeName
 * @param isNullable  the nullability of the created RelDataType
 * @return RelDataType Type of call
 */
public static RelDataType createCalciteTypeWithNullability(RelDataTypeFactory typeFactory,
                                                           SqlTypeName sqlTypeName,
                                                           boolean isNullable) {
  RelDataType type;
  if (sqlTypeName.getFamily() == SqlTypeFamily.INTERVAL_DAY_TIME) {
    type = typeFactory.createSqlIntervalType(
        new SqlIntervalQualifier(
            TimeUnit.DAY,
            TimeUnit.MINUTE,
            SqlParserPos.ZERO));
  } else if (sqlTypeName.getFamily() == SqlTypeFamily.INTERVAL_YEAR_MONTH) {
    type = typeFactory.createSqlIntervalType(
        new SqlIntervalQualifier(
            TimeUnit.YEAR,
            TimeUnit.MONTH,
            SqlParserPos.ZERO));
  } else if (sqlTypeName == SqlTypeName.VARCHAR) {
    type = typeFactory.createSqlType(sqlTypeName, Types.MAX_VARCHAR_LENGTH);
  } else {
    type = typeFactory.createSqlType(sqlTypeName);
  }
  return typeFactory.createTypeWithNullability(type, isNullable);
}
 
Example 2
Source File: RelDataTypeSystemImpl.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public int getNumTypeRadix(SqlTypeName typeName) {
  if (typeName.getFamily() == SqlTypeFamily.NUMERIC
      && getDefaultPrecision(typeName) != -1) {
    return 10;
  }
  return 0;
}
 
Example 3
Source File: RexUtil.java    From Bats with Apache License 2.0 5 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) {
    final SqlTypeName name1 = type1.getSqlTypeName();
    final SqlTypeName name2 = type2.getSqlTypeName();
    if (name1.getFamily() == name2.getFamily()) {
        switch (name1.getFamily()) {
        case NUMERIC:
            return name1.compareTo(name2) >= 0;
        default:
            return true;
        }
    }
    return false;
}
 
Example 4
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 5
Source File: RepeatFamilyOperandTypeChecker.java    From flink with Apache License 2.0 5 votes vote down vote up
public boolean checkSingleOperandType(
	SqlCallBinding callBinding,
	SqlNode node,
	boolean throwOnFailure) {

	if (SqlUtil.isNullLiteral(node, false)) {
		if (throwOnFailure) {
			throw callBinding.getValidator().newValidationError(node,
				RESOURCE.nullIllegal());
		} else {
			return false;
		}
	}

	RelDataType type = callBinding.getValidator().deriveType(
		callBinding.getScope(),
		node);
	SqlTypeName typeName = type.getSqlTypeName();

	// Pass type checking for operators if it's of type 'ANY'.
	if (typeName.getFamily() == SqlTypeFamily.ANY) {
		return true;
	}

	if (!family.getTypeNames().contains(typeName)) {
		if (throwOnFailure) {
			throw callBinding.newValidationSignatureError();
		}
		return false;
	}
	return true;
}
 
Example 6
Source File: SqlDatePartOperator.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public boolean checkSingleOperandType(SqlCallBinding callBinding, SqlNode node,
    int iFormalOperand, boolean throwOnFailure) {

  // check that the input is a literal.
  if(!super.checkSingleOperandType(callBinding, node, iFormalOperand, throwOnFailure)) {
    return false;
  }

  final RelDataType type = callBinding.getValidator().deriveType(callBinding.getScope(), node);
  final SqlTypeName typeName = type.getSqlTypeName();

  // Pass type checking for operators if it's of type 'ANY'.
  if (typeName.getFamily() == SqlTypeFamily.ANY) {
    return true;
  }

  if(!(typeName == SqlTypeName.CHAR || typeName == SqlTypeName.VARCHAR)) {
    if(throwOnFailure) {
      throw callBinding.newValidationSignatureError();
    }
    return false;
  }

  final SqlLiteral literal = (SqlLiteral) node;
  final String value = ((NlsString)literal.getValue()).getValue();
  if(validStrings.contains(value.toLowerCase())) {
    return true;
  }

  if(throwOnFailure) {
    throw callBinding.newValidationSignatureError();
    //throw new SqlValidatorException(String.format("DATE_PART function only accepts the following values for a date type: %s.", Joiner.on(", ").join(validStrings)), null);
  }

  return false;
}
 
Example 7
Source File: DremioArgChecker.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
private boolean checkOp(Checker checker, SqlCallBinding callBinding, SqlNode node, int iFormalOperand,
    boolean throwOnFailure) {

  if (SqlUtil.isNullLiteral(node, false)) {
    if (throwOnFailure) {
      throw callBinding.getValidator().newValidationError(node,
          RESOURCE.nullIllegal());
    } else {
      return false;
    }
  }
  RelDataType type = callBinding.getValidator().deriveType(callBinding.getScope(), node);
  SqlTypeName typeName = type.getSqlTypeName();

  // Pass type checking for operators if it's of type 'ANY'.
  if (typeName.getFamily() == SqlTypeFamily.ANY && allowAny) {
    return true;
  }

  if (!checker.check(type)) {
    if (throwOnFailure) {
      throw callBinding.newValidationSignatureError();
    }
    return false;
  }
  return true;
}
 
Example 8
Source File: RelDataTypeSystemImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public int getNumTypeRadix(SqlTypeName typeName) {
  if (typeName.getFamily() == SqlTypeFamily.NUMERIC
      && getDefaultPrecision(typeName) != -1) {
    return 10;
  }
  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: DruidExpressions.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Translates Calcite rexNode to Druid Expression when possible
 * @param rexNode rexNode to convert to a Druid Expression
 * @param inputRowType input row type of the rexNode to translate
 * @param druidRel Druid query
 *
 * @return Druid Expression or null when can not convert the RexNode
 */
@Nullable
public static String toDruidExpression(
    final RexNode rexNode,
    final RelDataType inputRowType,
    final DruidQuery druidRel) {
  SqlKind kind = rexNode.getKind();
  SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();

  if (kind == SqlKind.INPUT_REF) {
    final RexInputRef ref = (RexInputRef) rexNode;
    final String columnName = inputRowType.getFieldNames().get(ref.getIndex());
    if (columnName == null) {
      return null;
    }
    if (druidRel.getDruidTable().timestampFieldName.equals(columnName)) {
      return DruidExpressions.fromColumn(DruidTable.DEFAULT_TIMESTAMP_COLUMN);
    }
    return DruidExpressions.fromColumn(columnName);
  }

  if (rexNode instanceof RexCall) {
    final SqlOperator operator = ((RexCall) rexNode).getOperator();
    final DruidSqlOperatorConverter conversion = druidRel.getOperatorConversionMap()
        .get(operator);
    if (conversion == null) {
      //unknown operator can not translate
      return null;
    } else {
      return conversion.toDruidExpression(rexNode, inputRowType, druidRel);
    }
  }
  if (kind == SqlKind.LITERAL) {
    // Translate literal.
    if (RexLiteral.isNullLiteral(rexNode)) {
      //case the filter/project might yield to unknown let Calcite deal with this for now
      return null;
    } else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
      return DruidExpressions.numberLiteral((Number) RexLiteral
          .value(rexNode));
    } else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
      // Calcite represents DAY-TIME intervals in milliseconds.
      final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
      return DruidExpressions.numberLiteral(milliseconds);
    } else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
      // Calcite represents YEAR-MONTH intervals in months.
      final long months = ((Number) RexLiteral.value(rexNode)).longValue();
      return DruidExpressions.numberLiteral(months);
    } else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
      return
          DruidExpressions.stringLiteral(RexLiteral.stringValue(rexNode));
    } else if (SqlTypeName.DATE == sqlTypeName
        || SqlTypeName.TIMESTAMP == sqlTypeName
        || SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE == sqlTypeName) {
      return DruidExpressions.numberLiteral(
          DruidDateTimeUtils.literalValue(rexNode));
    } else if (SqlTypeName.BOOLEAN == sqlTypeName) {
      return DruidExpressions.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0);
    }
  }
  // Not Literal/InputRef/RexCall or unknown type?
  return null;
}
 
Example 11
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;
}