use of org.apache.calcite.sql.type.SqlTypeName in project calcite by apache.
the class RelDataTypeHolder method getFieldOrInsert.
/**
* Get field if exists, otherwise inserts a new field. The new field by default will have "any"
* type, except for the dynamic star field.
*
* @param fieldName Request field name
* @param caseSensitive Case Sensitive
* @return A pair of RelDataTypeField and Boolean. Boolean indicates whether a new field is added
* to this holder.
*/
Pair<RelDataTypeField, Boolean> getFieldOrInsert(String fieldName, boolean caseSensitive) {
// First check if this field name exists in our field list
for (RelDataTypeField f : fields) {
if (Util.matches(caseSensitive, f.getName(), fieldName)) {
return Pair.of(f, false);
}
// A dynamic star field matches any field
if (f.getType().getSqlTypeName() == SqlTypeName.DYNAMIC_STAR) {
return Pair.of(f, false);
}
}
final SqlTypeName typeName = DynamicRecordType.isDynamicStarColName(fieldName) ? SqlTypeName.DYNAMIC_STAR : SqlTypeName.ANY;
// This field does not exist in our field list; add it
RelDataTypeField newField = new RelDataTypeFieldImpl(fieldName, fields.size(), typeFactory.createTypeWithNullability(typeFactory.createSqlType(typeName), true));
// Add the name to our list of field names
fields.add(newField);
return Pair.of(newField, true);
}
use of org.apache.calcite.sql.type.SqlTypeName in project calcite by apache.
the class RexLiteral method toLiteral.
/**
* Converts a value to a temporary literal, for the purposes of generating a
* digest. Literals of type ROW and MULTISET require that their components are
* also literals.
*/
private static RexLiteral toLiteral(RelDataType type, Comparable<?> value) {
final SqlTypeName typeName = strictTypeName(type);
switch(typeName) {
case ROW:
assert value instanceof List : "value must implement List: " + value;
final List<Comparable<?>> fieldValues = (List) value;
final List<RelDataTypeField> fields = type.getFieldList();
final List<RexLiteral> fieldLiterals = FlatLists.of(Functions.generate(fieldValues.size(), i -> toLiteral(fields.get(i).getType(), fieldValues.get(i))));
return new RexLiteral((Comparable) fieldLiterals, type, typeName);
case MULTISET:
assert value instanceof List : "value must implement List: " + value;
final List<Comparable<?>> elementValues = (List) value;
final List<RexLiteral> elementLiterals = FlatLists.of(Functions.generate(elementValues.size(), i -> toLiteral(castNonNull(type.getComponentType()), elementValues.get(i))));
return new RexLiteral((Comparable) elementLiterals, type, typeName);
default:
return new RexLiteral(value, type, typeName);
}
}
use of org.apache.calcite.sql.type.SqlTypeName in project calcite by apache.
the class RexBuilder method makeCast.
/**
* Creates a call to the CAST operator, expanding if possible, and optionally
* also preserving nullability.
*
* <p>Tries to expand the cast, and therefore the result may be something
* other than a {@link RexCall} to the CAST operator, such as a
* {@link RexLiteral}.
*
* @param type Type to cast to
* @param exp Expression being cast
* @param matchNullability Whether to ensure the result has the same
* nullability as {@code type}
* @return Call to CAST operator
*/
public RexNode makeCast(RelDataType type, RexNode exp, boolean matchNullability) {
final SqlTypeName sqlType = type.getSqlTypeName();
if (exp instanceof RexLiteral) {
RexLiteral literal = (RexLiteral) exp;
Comparable value = literal.getValueAs(Comparable.class);
SqlTypeName typeName = literal.getTypeName();
if (canRemoveCastFromLiteral(type, value, typeName)) {
switch(typeName) {
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
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:
assert value instanceof BigDecimal;
typeName = type.getSqlTypeName();
switch(typeName) {
case BIGINT:
case INTEGER:
case SMALLINT:
case TINYINT:
case FLOAT:
case REAL:
case DECIMAL:
BigDecimal value2 = (BigDecimal) value;
final BigDecimal multiplier = baseUnit(literal.getTypeName()).multiplier;
final BigDecimal divider = literal.getTypeName().getEndUnit().multiplier;
value = value2.multiply(multiplier).divide(divider, 0, RoundingMode.HALF_DOWN);
break;
default:
break;
}
// Not all types are allowed for literals
switch(typeName) {
case INTEGER:
typeName = SqlTypeName.BIGINT;
break;
default:
break;
}
break;
default:
break;
}
final RexLiteral literal2 = makeLiteral(value, type, typeName);
if (type.isNullable() && !literal2.getType().isNullable() && matchNullability) {
return makeAbstractCast(type, literal2);
}
return literal2;
}
} else if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.isInterval(exp.getType())) {
return makeCastIntervalToExact(type, exp);
} else if (sqlType == SqlTypeName.BOOLEAN && SqlTypeUtil.isExactNumeric(exp.getType())) {
return makeCastExactToBoolean(type, exp);
} else if (exp.getType().getSqlTypeName() == SqlTypeName.BOOLEAN && SqlTypeUtil.isExactNumeric(type)) {
return makeCastBooleanToExact(type, exp);
}
return makeAbstractCast(type, exp);
}
use of org.apache.calcite.sql.type.SqlTypeName in project calcite by apache.
the class RexUtil method canAssignFrom.
/**
* 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();
final RelDataType type1Final = type1;
SqlTypeFamily family = requireNonNull(name1.getFamily(), () -> "SqlTypeFamily is null for type " + type1Final + ", SqlTypeName " + name1);
if (family == name2.getFamily()) {
switch(family) {
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:
// - RelDataType.PRECISION_NOT_SPECIFIED (-1) if not applicable for this type
return type1.getPrecision() >= type2.getPrecision();
}
}
return false;
}
use of org.apache.calcite.sql.type.SqlTypeName in project calcite by apache.
the class SqlLiteralChainOperator method inferReturnType.
// Result type is the same as all the args, but its size is the
// total size.
// REVIEW mb 8/8/04: Possibly this can be achieved by combining
// the strategy useFirstArgType with a new transformer.
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
// Here we know all the operands have the same type,
// which has a size (precision), but not a scale.
RelDataType ret = opBinding.getOperandType(0);
SqlTypeName typeName = ret.getSqlTypeName();
assert typeName.allowsPrecNoScale() : "LiteralChain has impossible operand type " + typeName;
int size = 0;
for (RelDataType type : opBinding.collectOperandTypes()) {
size += type.getPrecision();
assert type.getSqlTypeName() == typeName;
}
return opBinding.getTypeFactory().createSqlType(typeName, size);
}
Aggregations