private void queryQuick(int columnCount, ResultTarget result) { Value[] row = new Value[columnCount]; for (int i = 0; i < columnCount; i++) { Expression expr = expressions.get(i); row[i] = expr.getValue(session); } result.addRow(row); }
private void queryFlat(int columnCount, ResultTarget result, long limitRows) { // limitRows must be long, otherwise we get an int overflow // if limitRows is at or near Integer.MAX_VALUE // limitRows is never 0 here if (limitRows > 0 && offsetExpr != null) { int offset = offsetExpr.getValue(session).getInt(); if (offset > 0) { limitRows += offset; } } int rowNumber = 0; setCurrentRowNumber(0); ArrayList<Row> forUpdateRows = null; if (isForUpdateMvcc) { forUpdateRows = New.arrayList(); } while (topTableFilter.next()) { setCurrentRowNumber(rowNumber + 1); if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { Value[] row = new Value[columnCount]; for (int i = 0; i < columnCount; i++) { Expression expr = expressions.get(i); row[i] = expr.getValue(session); } if (isForUpdateMvcc) { topTableFilter.lockRowAdd(forUpdateRows); } result.addRow(row); rowNumber++; if ((sort == null || sortUsingIndex) && limitRows > 0 && result.getRowCount() >= limitRows) { break; } if (sampleSize > 0 && rowNumber >= sampleSize) { break; } } } if (isForUpdateMvcc) { topTableFilter.lockRows(forUpdateRows); } }
private void addGroupSortedRow(Value[] keyValues, int columnCount, ResultTarget result) { Value[] row = new Value[columnCount]; for (int j = 0; groupIndex != null && j < groupIndex.length; j++) { row[groupIndex[j]] = keyValues[j]; } for (int j = 0; j < columnCount; j++) { if (groupByExpression != null && groupByExpression[j]) { continue; } Expression expr = expressions.get(j); row[j] = expr.getValue(session); } if (isHavingNullOrFalse(row)) { return; } row = keepOnlyDistinct(row, columnCount); result.addRow(row); }
private void queryDistinct(ResultTarget result, long limitRows) { // limitRows must be long, otherwise we get an int overflow // if limitRows is at or near Integer.MAX_VALUE // limitRows is never 0 here if (limitRows > 0 && offsetExpr != null) { int offset = offsetExpr.getValue(session).getInt(); if (offset > 0) { limitRows += offset; } } int rowNumber = 0; setCurrentRowNumber(0); Index index = topTableFilter.getIndex(); SearchRow first = null; int columnIndex = index.getColumns()[0].getColumnId(); while (true) { setCurrentRowNumber(rowNumber + 1); Cursor cursor = index.findNext(session, first, null); if (!cursor.next()) { break; } SearchRow found = cursor.getSearchRow(); Value value = found.getValue(columnIndex); if (first == null) { first = topTableFilter.getTable().getTemplateSimpleRow(true); } first.setValue(columnIndex, value); Value[] row = {value}; result.addRow(row); rowNumber++; if ((sort == null || sortUsingIndex) && limitRows > 0 && rowNumber >= limitRows) { break; } if (sampleSize > 0 && rowNumber >= sampleSize) { break; } } }
protected LocalResult queryWithoutCache(int maxRows, ResultTarget target) { int limitRows = maxRows == 0 ? -1 : maxRows; if (limitExpr != null) { Value v = limitExpr.getValue(session); int l = v == ValueNull.INSTANCE ? -1 : v.getInt(); if (limitRows < 0) { limitRows = l; } else if (l >= 0) { limitRows = Math.min(l, limitRows); } } int columnCount = expressions.size(); LocalResult result = null; if (target == null || !session.getDatabase().getSettings().optimizeInsertFromSelect) { result = createLocalResult(result); } if (sort != null && (!sortUsingIndex || distinct)) { result = createLocalResult(result); result.setSortOrder(sort); } if (distinct && !isDistinctQuery) { result = createLocalResult(result); result.setDistinct(); } if (randomAccessResult) { result = createLocalResult(result); result.setRandomAccess(); } if (isGroupQuery && !isGroupSortedQuery) { result = createLocalResult(result); } if (limitRows >= 0 || offsetExpr != null) { result = createLocalResult(result); } topTableFilter.startQuery(session); topTableFilter.reset(); boolean exclusive = isForUpdate && !isForUpdateMvcc; if (isForUpdateMvcc) { if (isGroupQuery) { throw DbException.getUnsupportedException("FOR UPDATE && GROUP"); } else if (distinct) { throw DbException.getUnsupportedException("FOR UPDATE && DISTINCT"); } else if (isQuickAggregateQuery) { throw DbException.getUnsupportedException("FOR UPDATE && AGGREGATE"); } else if (topTableFilter.getJoin() != null) { throw DbException.getUnsupportedException("FOR UPDATE && JOIN"); } else if (topTableFilter.getJoin() != null) { throw DbException.getUnsupportedException("FOR UPDATE && JOIN"); } } topTableFilter.lock(session, exclusive, exclusive); ResultTarget to = result != null ? result : target; if (limitRows != 0) { if (isQuickAggregateQuery) { queryQuick(columnCount, to); } else if (isGroupQuery) { if (isGroupSortedQuery) { queryGroupSorted(columnCount, to); } else { queryGroup(columnCount, result); } } else if (isDistinctQuery) { queryDistinct(to, limitRows); } else { queryFlat(columnCount, to, limitRows); } } if (offsetExpr != null) { result.setOffset(offsetExpr.getValue(session).getInt()); } if (limitRows >= 0) { result.setLimit(limitRows); } if (result != null) { result.done(); if (target != null) { while (result.next()) { target.addRow(result.currentRow()); } result.close(); return null; } return result; } return null; }
@Override protected LocalResult queryWithoutCache(int maxRows, ResultTarget target) { if (maxRows != 0) { // maxRows is set (maxRows 0 means no limit) int l; if (limitExpr == null) { l = -1; } else { Value v = limitExpr.getValue(session); l = v == ValueNull.INSTANCE ? -1 : v.getInt(); } if (l < 0) { // for limitExpr, 0 means no rows, and -1 means no limit l = maxRows; } else { l = Math.min(l, maxRows); } limitExpr = ValueExpression.get(ValueInt.get(l)); } if (session.getDatabase().getSettings().optimizeInsertFromSelect) { if (unionType == UNION_ALL && target != null) { if (sort == null && !distinct && maxRows == 0 && offsetExpr == null && limitExpr == null) { left.query(0, target); right.query(0, target); return null; } } } int columnCount = left.getColumnCount(); LocalResult result = new LocalResult(session, expressionArray, columnCount); if (sort != null) { result.setSortOrder(sort); } if (distinct) { left.setDistinct(true); right.setDistinct(true); result.setDistinct(); } if (randomAccessResult) { result.setRandomAccess(); } switch (unionType) { case UNION: case EXCEPT: left.setDistinct(true); right.setDistinct(true); result.setDistinct(); break; case UNION_ALL: break; case INTERSECT: left.setDistinct(true); right.setDistinct(true); break; default: DbException.throwInternalError("type=" + unionType); } ResultInterface l = left.query(0); ResultInterface r = right.query(0); l.reset(); r.reset(); switch (unionType) { case UNION_ALL: case UNION: { while (l.next()) { result.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { result.addRow(convert(r.currentRow(), columnCount)); } break; } case EXCEPT: { while (l.next()) { result.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { result.removeDistinct(convert(r.currentRow(), columnCount)); } break; } case INTERSECT: { LocalResult temp = new LocalResult(session, expressionArray, columnCount); temp.setDistinct(); temp.setRandomAccess(); while (l.next()) { temp.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { Value[] values = convert(r.currentRow(), columnCount); if (temp.containsDistinct(values)) { result.addRow(values); } } break; } default: DbException.throwInternalError("type=" + unionType); } if (offsetExpr != null) { result.setOffset(offsetExpr.getValue(session).getInt()); } if (limitExpr != null) { Value v = limitExpr.getValue(session); if (v != ValueNull.INSTANCE) { result.setLimit(v.getInt()); } } result.done(); if (target != null) { while (result.next()) { target.addRow(result.currentRow()); } result.close(); return null; } return result; }