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

The following examples show how to use org.apache.calcite.sql.type.SqlTypeUtil#isNumeric() . 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: ReduceDecimalsRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode expand(RexCall call) {
    ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
    for (RexNode operand : call.getOperands()) {
        if (SqlTypeUtil.isNumeric(operand.getType())) {
            opBuilder.add(accessValue(operand));
        } else {
            opBuilder.add(operand);
        }
    }

    RexNode newCall = builder.makeCall(call.getType(), call.getOperator(), opBuilder.build());
    if (SqlTypeUtil.isDecimal(call.getType())) {
        return encodeValue(newCall, call.getType());
    } else {
        return newCall;
    }
}
 
Example 2
Source File: ReduceDecimalsRule.java    From calcite with Apache License 2.0 6 votes vote down vote up
public RexNode expand(RexCall call) {
  ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
  for (RexNode operand : call.operands) {
    if (SqlTypeUtil.isNumeric(operand.getType())) {
      opBuilder.add(accessValue(operand));
    } else {
      opBuilder.add(operand);
    }
  }

  RexNode newCall =
      builder.makeCall(call.getType(), call.getOperator(),
          opBuilder.build());
  if (SqlTypeUtil.isDecimal(call.getType())) {
    return encodeValue(
        newCall,
        call.getType());
  } else {
    return newCall;
  }
}
 
Example 3
Source File: NumericOrDefaultReturnTypeInference.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
	int nOperands = opBinding.getOperandCount();
	List<RelDataType> types = new ArrayList<>();
	for (int i = startTypeIdx; i < nOperands; i++) {
		RelDataType type = opBinding.getOperandType(i);
		if (SqlTypeUtil.isNumeric(type)) {
			types.add(type);
		} else {
			return opBinding.getOperandType(defaultTypeIdx);
		}
	}
	return opBinding.getTypeFactory().leastRestrictive(types);
}
 
Example 4
Source File: NumericExceptFirstOperandChecker.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
	for (int i = 1; i < callBinding.getOperandCount(); i++) {
		if (!SqlTypeUtil.isNumeric(callBinding.getOperandType(i))) {
			if (!throwOnFailure) {
				return false;
			}
			throw callBinding.newValidationSignatureError();
		}
	}
	return true;
}
 
Example 5
Source File: NumericOrDefaultReturnTypeInference.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
	int nOperands = opBinding.getOperandCount();
	List<RelDataType> types = new ArrayList<>();
	for (int i = startTypeIdx; i < nOperands; i++) {
		RelDataType type = opBinding.getOperandType(i);
		if (SqlTypeUtil.isNumeric(type)) {
			types.add(type);
		} else {
			return opBinding.getOperandType(defaultTypeIdx);
		}
	}
	return opBinding.getTypeFactory().leastRestrictive(types);
}
 
Example 6
Source File: NumericExceptFirstOperandChecker.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override
public boolean checkOperandTypes(SqlCallBinding callBinding, boolean throwOnFailure) {
	for (int i = 1; i < callBinding.getOperandCount(); i++) {
		if (!SqlTypeUtil.isNumeric(callBinding.getOperandType(i))) {
			if (!throwOnFailure) {
				return false;
			}
			throw callBinding.newValidationSignatureError();
		}
	}
	return true;
}
 
Example 7
Source File: AbstractTypeCoercion.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Finds a wider type when one or both types are decimal type.
 * If the wider decimal type's precision/scale exceeds system limitation,
 * this rule will truncate the decimal type to the max precision/scale.
 * For decimal and fractional types, returns a decimal type
 * which has the higher precision of the two.
 *
 * <p>The default implementation depends on the max precision/scale of the type system,
 * you can override it based on the specific system requirement in
 * {@link org.apache.calcite.rel.type.RelDataTypeSystem}.
 */
public RelDataType getWiderTypeForDecimal(RelDataType type1, RelDataType type2) {
  if (!SqlTypeUtil.isDecimal(type1) && !SqlTypeUtil.isDecimal(type2)) {
    return null;
  }
  // For Calcite `DECIMAL` default to have max allowed precision,
  // so just return decimal type.
  // This is based on the RelDataTypeSystem implementation,
  // subclass should override it correctly.
  if (SqlTypeUtil.isNumeric(type1) && SqlTypeUtil.isNumeric(type2)) {
    return factory.leastRestrictive(ImmutableList.of(type1, type2));
  }
  return null;
}
 
Example 8
Source File: TypeCoercionImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * For NUMERIC and STRING operands, cast STRING to data type of the other operand.
 **/
protected boolean binaryArithmeticWithStrings(
    SqlCallBinding binding,
    RelDataType left,
    RelDataType right) {
  // For expression "NUMERIC <OP> CHARACTER",
  // PostgreSQL and MS-SQL coerce the CHARACTER operand to NUMERIC,
  // i.e. for '9':VARCHAR(1) / 2: INT, '9' would be coerced to INTEGER,
  // while for '9':VARCHAR(1) / 3.3: DOUBLE, '9' would be coerced to DOUBLE.
  // They do not allow both CHARACTER operands for binary arithmetic operators.

  // MySQL and Oracle would coerce all the string operands to DOUBLE.

  // Keep sync with PostgreSQL and MS-SQL because their behaviors are more in
  // line with the SQL standard.
  if (SqlTypeUtil.isString(left) && SqlTypeUtil.isNumeric(right)) {
    // If the numeric operand is DECIMAL type, coerce the STRING operand to
    // max precision/scale DECIMAL.
    if (SqlTypeUtil.isDecimal(right)) {
      right = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
    }
    return coerceOperandType(binding.getScope(), binding.getCall(), 0, right);
  } else if (SqlTypeUtil.isNumeric(left) && SqlTypeUtil.isString(right)) {
    if (SqlTypeUtil.isDecimal(left)) {
      left = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
    }
    return coerceOperandType(binding.getScope(), binding.getCall(), 1, left);
  }
  return false;
}
 
Example 9
Source File: AbstractTypeCoercion.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Type coercion based on the inferred type from passed in operand
 * and the {@link SqlTypeFamily} defined in the checkers,
 * e.g. the {@link org.apache.calcite.sql.type.FamilyOperandTypeChecker}.
 *
 * <p>Caution that we do not cast from NUMERIC to NUMERIC.
 * See <a href="https://docs.google.com/spreadsheets/d/1GhleX5h5W8-kJKh7NMJ4vtoE78pwfaZRJl88ULX_MgU/edit?usp=sharing">CalciteImplicitCasts</a>
 * for the details.
 *
 * @param in       Inferred operand type
 * @param expected Expected {@link SqlTypeFamily} of registered SqlFunction
 * @return common type of implicit cast, null if we do not find any
 */
public RelDataType implicitCast(RelDataType in, SqlTypeFamily expected) {
  List<SqlTypeFamily> numericFamilies = ImmutableList.of(
      SqlTypeFamily.NUMERIC,
      SqlTypeFamily.DECIMAL,
      SqlTypeFamily.APPROXIMATE_NUMERIC,
      SqlTypeFamily.EXACT_NUMERIC,
      SqlTypeFamily.INTEGER);
  List<SqlTypeFamily> dateTimeFamilies = ImmutableList.of(SqlTypeFamily.DATE,
      SqlTypeFamily.TIME, SqlTypeFamily.TIMESTAMP);
  // If the expected type is already a parent of the input type, no need to cast.
  if (expected.getTypeNames().contains(in.getSqlTypeName())) {
    return in;
  }
  // Cast null type (usually from null literals) into target type.
  if (SqlTypeUtil.isNull(in)) {
    return expected.getDefaultConcreteType(factory);
  }
  if (SqlTypeUtil.isNumeric(in) && expected == SqlTypeFamily.DECIMAL) {
    return factory.decimalOf(in);
  }
  // FLOAT/DOUBLE -> DECIMAL
  if (SqlTypeUtil.isApproximateNumeric(in) && expected == SqlTypeFamily.EXACT_NUMERIC) {
    return factory.decimalOf(in);
  }
  // DATE to TIMESTAMP
  if (SqlTypeUtil.isDate(in) && expected == SqlTypeFamily.TIMESTAMP) {
    return factory.createSqlType(SqlTypeName.TIMESTAMP);
  }
  // TIMESTAMP to DATE.
  if (SqlTypeUtil.isTimestamp(in) && expected == SqlTypeFamily.DATE) {
    return factory.createSqlType(SqlTypeName.DATE);
  }
  // If the function accepts any NUMERIC type and the input is a STRING,
  // returns the expected type family's default type.
  // REVIEW Danny 2018-05-22: same with MS-SQL and MYSQL.
  if (SqlTypeUtil.isCharacter(in) && numericFamilies.contains(expected)) {
    return expected.getDefaultConcreteType(factory);
  }
  // STRING + DATE -> DATE;
  // STRING + TIME -> TIME;
  // STRING + TIMESTAMP -> TIMESTAMP
  if (SqlTypeUtil.isCharacter(in) && dateTimeFamilies.contains(expected)) {
    return expected.getDefaultConcreteType(factory);
  }
  // STRING + BINARY -> VARBINARY
  if (SqlTypeUtil.isCharacter(in) && expected == SqlTypeFamily.BINARY) {
    return expected.getDefaultConcreteType(factory);
  }
  // If we get here, `in` will never be STRING type.
  if (SqlTypeUtil.isAtomic(in)
      && (expected == SqlTypeFamily.STRING
      || expected == SqlTypeFamily.CHARACTER)) {
    return expected.getDefaultConcreteType(factory);
  }
  return null;
}
 
Example 10
Source File: BigQuerySqlDialect.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Override public boolean supportsImplicitTypeCoercion(RexCall call) {
  return super.supportsImplicitTypeCoercion(call)
          && RexUtil.isLiteral(call.getOperands().get(0), false)
          && !SqlTypeUtil.isNumeric(call.type);
}