@SuppressWarnings("unchecked")
@Override
public int compare(WritableComparable a, WritableComparable b)
{
PigNullableWritable wa = (PigNullableWritable)a;
PigNullableWritable wb = (PigNullableWritable)b;
if ((wa.getIndex() & PigNullableWritable.mqFlag) != 0) { // this is a multi-query index
if ((wa.getIndex() & PigNullableWritable.idxSpace) < (wb.getIndex() & PigNullableWritable.idxSpace)) return -1;
else if ((wa.getIndex() & PigNullableWritable.idxSpace) > (wb.getIndex() & PigNullableWritable.idxSpace)) return 1;
// If equal, we fall through
}
// wa and wb are guaranteed to be not null, POLocalRearrange will create a tuple anyway even if main key and secondary key
// are both null; however, main key can be null, we need to check for that using the same logic we have in PigNullableWritable
Object valuea = null;
Object valueb = null;
try {
// Get the main key from compound key
valuea = ((Tuple)wa.getValueAsPigType()).get(0);
valueb = ((Tuple)wb.getValueAsPigType()).get(0);
} catch (ExecException e) {
throw new RuntimeException("Unable to access tuple field", e);
}
if (!wa.isNull() && !wb.isNull()) {
int result = DataType.compare(valuea, valueb);
// If any of the field inside tuple is null, then we do not merge keys
// See PIG-927
if (result == 0 && valuea instanceof Tuple && valueb instanceof Tuple)
{
try {
for (int i=0;i<((Tuple)valuea).size();i++)
if (((Tuple)valueb).get(i)==null)
return (wa.getIndex()&PigNullableWritable.idxSpace) - (wb.getIndex()&PigNullableWritable.idxSpace);
} catch (ExecException e) {
throw new RuntimeException("Unable to access tuple field", e);
}
}
return result;
} else if (valuea==null && valueb==null) {
// If they're both null, compare the indicies
if ((wa.getIndex() & PigNullableWritable.idxSpace) < (wb.getIndex() & PigNullableWritable.idxSpace)) return -1;
else if ((wa.getIndex() & PigNullableWritable.idxSpace) > (wb.getIndex() & PigNullableWritable.idxSpace)) return 1;
else return 0;
}
else if (valuea==null) return -1;
else return 1;
}