示例#1
0
 /**
  * Initialize the order by list. This call may extend the expressions list.
  *
  * @param session the session
  * @param expressions the select list expressions
  * @param expressionSQL the select list SQL snippets
  * @param orderList the order by list
  * @param visible the number of visible columns in the select list
  * @param mustBeInResult all order by expressions must be in the select list
  * @param filters the table filters
  */
 static void initOrder(
     Session session,
     ArrayList<Expression> expressions,
     ArrayList<String> expressionSQL,
     ArrayList<SelectOrderBy> orderList,
     int visible,
     boolean mustBeInResult,
     ArrayList<TableFilter> filters) {
   Database db = session.getDatabase();
   for (SelectOrderBy o : orderList) {
     Expression e = o.expression;
     if (e == null) {
       continue;
     }
     // special case: SELECT 1 AS A FROM DUAL ORDER BY A
     // (oracle supports it, but only in order by, not in group by and
     // not in having):
     // SELECT 1 AS A FROM DUAL ORDER BY -A
     boolean isAlias = false;
     int idx = expressions.size();
     if (e instanceof ExpressionColumn) {
       // order by expression
       ExpressionColumn exprCol = (ExpressionColumn) e;
       String tableAlias = exprCol.getOriginalTableAliasName();
       String col = exprCol.getOriginalColumnName();
       for (int j = 0; j < visible; j++) {
         boolean found = false;
         Expression ec = expressions.get(j);
         if (ec instanceof ExpressionColumn) {
           // select expression
           ExpressionColumn c = (ExpressionColumn) ec;
           found = db.equalsIdentifiers(col, c.getColumnName());
           if (found && tableAlias != null) {
             String ca = c.getOriginalTableAliasName();
             if (ca == null) {
               found = false;
               if (filters != null) {
                 // select id from test order by test.id
                 for (int i = 0, size = filters.size(); i < size; i++) {
                   TableFilter f = filters.get(i);
                   if (db.equalsIdentifiers(f.getTableAlias(), tableAlias)) {
                     found = true;
                     break;
                   }
                 }
               }
             } else {
               found = db.equalsIdentifiers(ca, tableAlias);
             }
           }
         } else if (!(ec instanceof Alias)) {
           continue;
         } else if (tableAlias == null && db.equalsIdentifiers(col, ec.getAlias())) {
           found = true;
         } else {
           Expression ec2 = ec.getNonAliasExpression();
           if (ec2 instanceof ExpressionColumn) {
             ExpressionColumn c2 = (ExpressionColumn) ec2;
             String ta = exprCol.getSQL();
             String tb = c2.getSQL();
             String s2 = c2.getColumnName();
             found = db.equalsIdentifiers(col, s2);
             if (!db.equalsIdentifiers(ta, tb)) {
               found = false;
             }
           }
         }
         if (found) {
           idx = j;
           isAlias = true;
           break;
         }
       }
     } else {
       String s = e.getSQL();
       if (expressionSQL != null) {
         for (int j = 0, size = expressionSQL.size(); j < size; j++) {
           String s2 = expressionSQL.get(j);
           if (db.equalsIdentifiers(s2, s)) {
             idx = j;
             isAlias = true;
             break;
           }
         }
       }
     }
     if (!isAlias) {
       if (mustBeInResult) {
         throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL());
       }
       expressions.add(e);
       String sql = e.getSQL();
       expressionSQL.add(sql);
     }
     o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1));
     Expression expr = expressions.get(idx).getNonAliasExpression();
     o.expression = expr;
   }
 }
示例#2
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;
 }