Пример #1
0
 @Override
 public ResultInterface queryMeta() {
   int columnCount = left.getColumnCount();
   LocalResult result = new LocalResult(session, expressionArray, columnCount);
   result.done();
   return result;
 }
Пример #2
0
 /**
  * Execute the query, writing the result to the target result.
  *
  * @param limit the maximum number of rows to return
  * @param target the target result (null will return the result)
  * @return the result set (if the target is not set).
  */
 LocalResult query(int limit, ResultTarget target) {
   fireBeforeSelectTriggers();
   if (noCache || !session.getDatabase().getOptimizeReuseResults()) {
     return queryWithoutCache(limit, target);
   }
   Value[] params = getParameterValues();
   long now = session.getDatabase().getModificationDataId();
   if (isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR)) {
     if (lastResult != null && !lastResult.isClosed() && limit == lastLimit) {
       if (sameResultAsLast(session, params, lastParameters, lastEvaluated)) {
         lastResult = lastResult.createShallowCopy(session);
         if (lastResult != null) {
           lastResult.reset();
           return lastResult;
         }
       }
     }
   }
   lastParameters = params;
   closeLastResult();
   LocalResult r = queryWithoutCache(limit, target);
   lastResult = r;
   this.lastEvaluated = now;
   lastLimit = limit;
   return r;
 }
Пример #3
0
 private void closeTemporaryResults() {
   if (temporaryResults != null) {
     for (LocalResult result : temporaryResults) {
       result.close();
     }
     temporaryResults = null;
   }
 }
Пример #4
0
 /**
  * Remember the result set and close it as soon as the transaction is committed (if it needs to be
  * closed). This is done to delete temporary files as soon as possible, and free object ids of
  * temporary tables.
  *
  * @param result the temporary result set
  */
 public void addTemporaryResult(LocalResult result) {
   if (!result.needToClose()) {
     return;
   }
   if (temporaryResults == null) {
     temporaryResults = New.hashSet();
   }
   if (temporaryResults.size() < 100) {
     // reference at most 100 result sets to avoid memory problems
     temporaryResults.add(result);
   }
 }
Пример #5
0
 private void closeLastResult() {
   if (lastResult != null) {
     lastResult.close();
   }
 }
Пример #6
0
 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;
 }
Пример #7
0
 public ResultInterface queryMeta() {
   LocalResult result = new LocalResult(session, expressionArray, visibleColumnCount);
   result.done();
   return result;
 }
Пример #8
0
 private void queryGroup(int columnCount, LocalResult result) {
   ValueHashMap<HashMap<Expression, Object>> groups = ValueHashMap.newInstance();
   int rowNumber = 0;
   setCurrentRowNumber(0);
   ValueArray defaultGroup = ValueArray.get(new Value[0]);
   while (topTableFilter.next()) {
     setCurrentRowNumber(rowNumber + 1);
     if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
       Value key;
       rowNumber++;
       if (groupIndex == null) {
         key = defaultGroup;
       } else {
         Value[] keyValues = new Value[groupIndex.length];
         // update group
         for (int i = 0; i < groupIndex.length; i++) {
           int idx = groupIndex[i];
           Expression expr = expressions.get(idx);
           keyValues[i] = expr.getValue(session);
         }
         key = ValueArray.get(keyValues);
       }
       HashMap<Expression, Object> values = groups.get(key);
       if (values == null) {
         values = new HashMap<Expression, Object>();
         groups.put(key, values);
       }
       currentGroup = values;
       currentGroupRowId++;
       int len = columnCount;
       for (int i = 0; i < len; i++) {
         if (groupByExpression == null || !groupByExpression[i]) {
           Expression expr = expressions.get(i);
           expr.updateAggregate(session);
         }
       }
       if (sampleSize > 0 && rowNumber >= sampleSize) {
         break;
       }
     }
   }
   if (groupIndex == null && groups.size() == 0) {
     groups.put(defaultGroup, new HashMap<Expression, Object>());
   }
   ArrayList<Value> keys = groups.keys();
   for (Value v : keys) {
     ValueArray key = (ValueArray) v;
     currentGroup = groups.get(key);
     Value[] keyValues = key.getList();
     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)) {
       continue;
     }
     row = keepOnlyDistinct(row, columnCount);
     result.addRow(row);
   }
 }
Пример #9
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;
 }
Пример #10
0
 public Cursor find(Session session, SearchRow first, SearchRow last) {
   if (recursive) {
     if (view.getRecursiveResult() != null) {
       ResultInterface r = view.getRecursiveResult();
       r.reset();
       return new ViewCursor(table, r);
     }
     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();
     ResultInterface r = left.query(0);
     LocalResult result = union.getEmptyResult();
     while (r.next()) {
       result.addRow(r.currentRow());
     }
     Query right = union.getRight();
     r.reset();
     view.setRecursiveResult(r);
     while (true) {
       r = right.query(0);
       if (r.getRowCount() == 0) {
         break;
       }
       while (r.next()) {
         result.addRow(r.currentRow());
       }
       r.reset();
       view.setRecursiveResult(r);
     }
     return new ViewCursor(table, result);
   }
   ArrayList<Parameter> paramList = query.getParameters();
   for (int i = 0; originalParameters != null && i < originalParameters.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(table, result);
 }