public RelDataType inferReturnType(SqlOperatorBinding opBinding) { RelDataType type1 = opBinding.getOperandType(0); RelDataType type2 = opBinding.getOperandType(1); if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) { int p1 = type1.getPrecision(); int p2 = type2.getPrecision(); int s1 = type1.getScale(); int s2 = type2.getScale(); int scale = Math.max(s1, s2); assert scale <= SqlTypeName.MAX_NUMERIC_SCALE; int precision = Math.max(p1 - s1, p2 - s2) + scale + 1; precision = Math.min(precision, SqlTypeName.MAX_NUMERIC_PRECISION); assert precision > 0; RelDataType ret; ret = opBinding.getTypeFactory().createSqlType(SqlTypeName.DECIMAL, precision, scale); return ret; } } return null; }
/** * Returns true if a type is a simple cast of another type. It is if the cast type is nullable and * the cast is one of the following: * <li>x TO x * <li>char(n) TO varchar(m) * <li>varchar(n) TO varchar(m) * <li>x not null TO x nullable * * @param origType original type passed into the cast operand * @param castType type the operand will be casted to * @return true if the cast is simple */ private boolean isCastSimple(RelDataType origType, RelDataType castType) { SqlTypeName origTypeName = origType.getSqlTypeName(); SqlTypeName castTypeName = castType.getSqlTypeName(); if (!(castType.isNullable())) { return false; } Charset origCharset = origType.getCharset(); Charset castCharset = castType.getCharset(); if ((origCharset != null) || (castCharset != null)) { if ((origCharset == null) || (castCharset == null)) { return false; } if (!origCharset.equals(castCharset)) { return false; } } return ((origType == castType) || ((origTypeName == SqlTypeName.CHAR) && (castTypeName == SqlTypeName.VARCHAR)) || ((origTypeName == SqlTypeName.VARCHAR) && (castTypeName == SqlTypeName.VARCHAR)) || ((origTypeName == castTypeName) && (origType.getPrecision() == castType.getPrecision()) && ((origTypeName != SqlTypeName.DECIMAL) || (origType.getScale() == castType.getScale())) && (!origType.isNullable() && castType.isNullable()))); }
public int getFieldScale(int fieldOrdinal) { RelDataType type = getFieldType(fieldOrdinal); SqlTypeName typeName = type.getSqlTypeName(); if (typeName == null) { return 0; } if (typeName.allowsPrecScale(true, true)) { return type.getScale(); } else { return 0; } }
public RelDataType inferReturnType(SqlOperatorBinding opBinding) { RelDataType type1 = opBinding.getOperandType(0); if (SqlTypeUtil.isDecimal(type1)) { if (type1.getScale() == 0) { return type1; } else { int p = type1.getPrecision(); RelDataType ret; ret = opBinding.getTypeFactory().createSqlType(SqlTypeName.DECIMAL, p, 0); if (type1.isNullable()) { ret = opBinding.getTypeFactory().createTypeWithNullability(ret, true); } return ret; } } return null; }