}
private List<Query> splitQueryBasedOnColumn(Column column) {
SelectItem maxItem = new SelectItem(FunctionType.MAX, column);
SelectItem minItem = new SelectItem(FunctionType.MIN, column);
Query q = new Query().from(column.getTable()).select(maxItem, minItem);
Row row = MetaModelHelper.executeSingleRowQuery(_dataContext, q);
long max = ceil((Number) row.getValue(maxItem));
long min = floor((Number) row.getValue(minItem));
long wholeRange = max - min;
List<Query> result = new ArrayList<Query>();
if (wholeRange <= 1) {
result.add(_query);
} else {
long numSplits = ceil(getRowCount() / _maxRows);
if (numSplits < 2) {
// Must as a minimum yield two new queries
numSplits = 2;
}
int splitInterval = (int) (wholeRange / numSplits);
for (int i = 0; i < numSplits; i++) {
q = _query.clone();
long lowLimit = min + (i * splitInterval);
long highLimit = lowLimit + splitInterval;
FilterItem lowerThanFilter = new FilterItem(new SelectItem(column), OperatorType.LESS_THAN, highLimit);
FilterItem higherThanFilter = new FilterItem(new SelectItem(column), OperatorType.GREATER_THAN,
lowLimit);
FilterItem equalsFilter = new FilterItem(new SelectItem(column), OperatorType.EQUALS_TO, lowLimit);
if (i == 0) {
// This is the first split query: no higherThan filter and
// include
// IS NULL
FilterItem nullFilter = new FilterItem(new SelectItem(column), OperatorType.EQUALS_TO, null);
FilterItem orFilterItem = new FilterItem(lowerThanFilter, nullFilter);
q.where(orFilterItem);
} else if (i + 1 == numSplits) {
// This is the lats split query: no lowerThan filter,
FilterItem orFilterItem = new FilterItem(higherThanFilter, equalsFilter);
q.where(orFilterItem);
} else {
higherThanFilter = new FilterItem(higherThanFilter, equalsFilter);
lowerThanFilter = new FilterItem(lowerThanFilter, equalsFilter);
q.where(higherThanFilter);
q.where(lowerThanFilter);
}
result.add(q);
}
}
return result;