/** * Return type t such that values from both t1 and t2 can be assigned to t without loss of * precision. Returns INVALID_TYPE if there is no such type or if any of t1 and t2 is * INVALID_TYPE. */ public static ColumnType getAssignmentCompatibleType(ColumnType t1, ColumnType t2) { if (!t1.isValid() || !t2.isValid()) return INVALID; if (t1.equals(t2)) return t1; if (t1.isDecimal() || t2.isDecimal()) { if (t1.isNull()) return t2; if (t2.isNull()) return t1; // Allow casts between decimal and numeric types by converting // numeric types to the containing decimal type. ColumnType t1Decimal = t1.getMinResolutionDecimal(); ColumnType t2Decimal = t2.getMinResolutionDecimal(); if (t1Decimal.isInvalid() || t2Decimal.isInvalid()) return ColumnType.INVALID; Preconditions.checkState(t1Decimal.isDecimal()); Preconditions.checkState(t2Decimal.isDecimal()); if (t1Decimal.isSupertypeOf(t2Decimal)) return t1; if (t2Decimal.isSupertypeOf(t1Decimal)) return t2; return TypesUtil.getDecimalAssignmentCompatibleType(t1Decimal, t2Decimal); } PrimitiveType smallerType = (t1.type_.ordinal() < t2.type_.ordinal() ? t1.type_ : t2.type_); PrimitiveType largerType = (t1.type_.ordinal() > t2.type_.ordinal() ? t1.type_ : t2.type_); PrimitiveType result = compatibilityMatrix[smallerType.ordinal()][largerType.ordinal()]; Preconditions.checkNotNull(result); return createType(result); }
/* Returns true if this decimal type is a supertype of the other decimal type. * e.g. (10,3) is a super type of (3,3) but (5,4) is not a supertype of (3,0). * To be a super type of another decimal, the number of digits before and after * the decimal point must be greater or equal. */ public boolean isSupertypeOf(ColumnType o) { Preconditions.checkState(isDecimal()); Preconditions.checkState(o.isDecimal()); if (isWildcardDecimal()) return true; return scale_ >= o.scale_ && precision_ - scale_ >= o.precision_ - o.scale_; }