in phoenix-core-client/src/main/java/org/apache/phoenix/schema/types/PDataType.java [166:260]
public final int compareTo(byte[] lhs, int lhsOffset, int lhsLength, SortOrder lhsSortOrder, byte[] rhs,
int rhsOffset, int rhsLength, SortOrder rhsSortOrder, PDataType rhsType) {
Preconditions.checkNotNull(lhsSortOrder);
Preconditions.checkNotNull(rhsSortOrder);
if (this.isBytesComparableWith(rhsType)) { // directly compare the bytes
// Special case as we may be comparing two arrays that have different separator characters due to PHOENIX-2067
if (!this.isArrayType() || !rhsType.isArrayType() ||
PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) {
// Ignore trailing zero bytes if fixed byte length (for example TIMESTAMP compared to DATE)
if (lhsLength != rhsLength && this.isFixedWidth() && rhsType.isFixedWidth() && this.getByteSize() != null && rhsType.getByteSize() != null) {
if (lhsLength > rhsLength) {
int minOffset = lhsOffset + rhsLength;
for (int i = lhsOffset + lhsLength - 1; i >= minOffset && lhsSortOrder.normalize(lhs[i]) == 0; i--,lhsLength--) {
}
} else {
int minOffset = rhsOffset + lhsLength;
for (int i = rhsOffset + rhsLength - 1; i >= minOffset && rhsSortOrder.normalize(rhs[i]) == 0; i--,rhsLength--) {
}
}
}
return compareTo(lhs, lhsOffset, lhsLength, lhsSortOrder, rhs, rhsOffset, rhsLength, rhsSortOrder);
}
}
PDataCodec lhsCodec = this.getCodec();
if ( lhsCodec == null ) {
byte[] rhsConverted;
Object o = this.toObject(rhs, rhsOffset, rhsLength, rhsType, rhsSortOrder);
// No lhs native type representation, so convert rhsType to bytes representation of lhs type
// Due to PHOENIX-2067, favor the array that is already in the new format so we don't have to convert both.
if ( this.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) {
rhsConverted = ((PArrayDataType)this).toBytes(o, PArrayDataType.arrayBaseType(this), lhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength));
} else {
rhsConverted = this.toBytes(o);
if (lhsSortOrder == SortOrder.DESC) {
lhs = SortOrder.invert(lhs, lhsOffset, new byte[lhsLength], 0, lhsLength);
lhsOffset = 0;
}
}
return Bytes.compareTo(lhs, lhsOffset, lhsLength, rhsConverted, 0, rhsConverted.length);
}
PDataCodec rhsCodec = rhsType.getCodec();
if (rhsCodec == null) {
byte[] lhsConverted;
Object o = rhsType.toObject(lhs, lhsOffset, lhsLength, this, lhsSortOrder);
// No rhs native type representation, so convert lhsType to bytes representation of rhs type
// Due to PHOENIX-2067, favor the array that is already in the new format so we don't have to convert both.
if ( rhsType.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength) == PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength)) {
lhsConverted = ((PArrayDataType)rhsType).toBytes(o, PArrayDataType.arrayBaseType(rhsType), rhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength));
} else {
lhsConverted = rhsType.toBytes(o);
if (rhsSortOrder == SortOrder.DESC) {
rhs = SortOrder.invert(rhs, rhsOffset, new byte[rhsLength], 0, rhsLength);
}
}
return Bytes.compareTo(lhsConverted, 0, lhsConverted.length, rhs, rhsOffset, rhsLength);
}
// convert to native and compare
if ( (this.isCoercibleTo(PLong.INSTANCE) || this.isCoercibleTo(PDate.INSTANCE)) &&
(rhsType.isCoercibleTo(PLong.INSTANCE) || rhsType.isCoercibleTo(PDate.INSTANCE)) ) {
return Longs.compare(this.getCodec().decodeLong(lhs, lhsOffset, lhsSortOrder), rhsType.getCodec()
.decodeLong(rhs, rhsOffset, rhsSortOrder));
} else if (isDoubleOrFloat(this) && isDoubleOrFloat(rhsType)) { // native double to double comparison
return Doubles.compare(this.getCodec().decodeDouble(lhs, lhsOffset, lhsSortOrder), rhsType.getCodec()
.decodeDouble(rhs, rhsOffset, rhsSortOrder));
} else { // native float/double to long comparison
float fvalue = 0.0F;
double dvalue = 0.0;
long lvalue = 0;
boolean isFloat = false;
int invert = 1;
if (this.isCoercibleTo(PLong.INSTANCE)) {
lvalue = this.getCodec().decodeLong(lhs, lhsOffset, lhsSortOrder);
} else if (this.getClass() == PFloat.class) {
isFloat = true;
fvalue = this.getCodec().decodeFloat(lhs, lhsOffset, lhsSortOrder);
} else if (this.isCoercibleTo(PDouble.INSTANCE)) {
dvalue = this.getCodec().decodeDouble(lhs, lhsOffset, lhsSortOrder);
}
if (rhsType.isCoercibleTo(PLong.INSTANCE)) {
lvalue = rhsType.getCodec().decodeLong(rhs, rhsOffset, rhsSortOrder);
} else if (rhsType == PFloat.INSTANCE) {
invert = -1;
isFloat = true;
fvalue = rhsType.getCodec().decodeFloat(rhs, rhsOffset, rhsSortOrder);
} else if (rhsType.isCoercibleTo(PDouble.INSTANCE)) {
invert = -1;
dvalue = rhsType.getCodec().decodeDouble(rhs, rhsOffset, rhsSortOrder);
}
// Invert the comparison if float/double value is on the RHS
return invert * (isFloat ? compareFloatToLong(fvalue, lvalue) : compareDoubleToLong(dvalue, lvalue));
}
}