}
@Override
public Cursor find(Session session, SearchRow first, SearchRow last) {
if (recursive) {
ResultInterface recResult = view.getRecursiveResult();
if (recResult != null) {
recResult.reset();
return new ViewCursor(this, recResult, first, last);
}
if (query == null) {
query = (Query) createSession.prepare(querySQL, true);
planSQL = query.getPlanSQL();
}
if (!(query instanceof SelectUnion)) {
throw DbException.get(ErrorCode.SYNTAX_ERROR_2, "recursive queries without UNION ALL");
}
SelectUnion union = (SelectUnion) query;
if (union.getUnionType() != SelectUnion.UNION_ALL) {
throw DbException.get(ErrorCode.SYNTAX_ERROR_2, "recursive queries without UNION ALL");
}
Query left = union.getLeft();
// to ensure the last result is not closed
left.disableCache();
LocalResult r = (LocalResult) left.query(0);
LocalResult result = union.getEmptyResult();
while (r.next()) {
result.addRow(r.currentRow());
}
Query right = union.getRight();
r.reset();
view.setRecursiveResult(r);
// to ensure the last result is not closed
right.disableCache();
while (true) {
r = (LocalResult) right.query(0);
if (r.getRowCount() == 0) {
break;
}
while (r.next()) {
result.addRow(r.currentRow());
}
r.reset();
view.setRecursiveResult(r);
}
view.setRecursiveResult(null);
result.done();
return new ViewCursor(this, result, first, last);
}
ArrayList<Parameter> paramList = query.getParameters();
if (originalParameters != null) {
for (int i = 0, size = originalParameters.size(); i < size; i++) {
Parameter orig = originalParameters.get(i);
int idx = orig.getIndex();
Value value = orig.getValue(session);
setParameter(paramList, idx, value);
}
}
int len;
if (first != null) {
len = first.getColumnCount();
} else if (last != null) {
len = last.getColumnCount();
} else {
len = 0;
}
int idx = originalParameters == null ? 0 : originalParameters.size();
idx += view.getParameterOffset();
for (int i = 0; i < len; i++) {
if (first != null) {
Value v = first.getValue(i);
if (v != null) {
int x = idx++;
setParameter(paramList, x, v);
}
}
// for equality, only one parameter is used (first == last)
if (last != null && indexMasks[i] != IndexCondition.EQUALITY) {
Value v = last.getValue(i);
if (v != null) {
int x = idx++;
setParameter(paramList, x, v);
}
}
}
ResultInterface result = query.query(0);
return new ViewCursor(this, result, first, last);
}