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 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 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 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;
 }
Beispiel #6
0
 @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;
 }