Both in AggregateImplementation and AggregationClient, the evaluation of the current minimum value is like:
min = (min == null || ci.compare(result, min) < 0) ? result : min;
The LongColumnInterpreter takes null value is treated as the least value, while the above expression takes min as the greater value when it is null. Thus, the real minimum value gets discarded if a null value comes later.
max() could also be wrong if a different ColumnInterpreter other than LongColumnInterpreter treats null value differently (as the greatest).