Beispiel #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;
   }
 }
 public String getPlanSQL() {
   // can not use the field sqlStatement because the parameter
   // indexes may be incorrect: ? may be in fact ?2 for a subquery
   // but indexes may be set manually as well
   Expression[] exprList = expressions.toArray(new Expression[expressions.size()]);
   StatementBuilder buff = new StatementBuilder("SELECT");
   if (distinct) {
     buff.append(" DISTINCT");
   }
   for (int i = 0; i < visibleColumnCount; i++) {
     buff.appendExceptFirst(",");
     buff.append('\n');
     buff.append(StringUtils.indent(exprList[i].getSQL(), 4, false));
   }
   buff.append("\nFROM ");
   TableFilter filter = topTableFilter;
   if (filter != null) {
     buff.resetCount();
     int i = 0;
     do {
       buff.appendExceptFirst("\n");
       buff.append(filter.getPlanSQL(i++ > 0));
       filter = filter.getJoin();
     } while (filter != null);
   } else {
     buff.resetCount();
     int i = 0;
     for (TableFilter f : topFilters) {
       do {
         buff.appendExceptFirst("\n");
         buff.append(f.getPlanSQL(i++ > 0));
         f = f.getJoin();
       } while (f != null);
     }
   }
   if (condition != null) {
     buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL()));
   }
   if (groupIndex != null) {
     buff.append("\nGROUP BY ");
     buff.resetCount();
     for (int gi : groupIndex) {
       Expression g = exprList[gi];
       g = g.getNonAliasExpression();
       buff.appendExceptFirst(", ");
       buff.append(StringUtils.unEnclose(g.getSQL()));
     }
   }
   if (group != null) {
     buff.append("\nGROUP BY ");
     buff.resetCount();
     for (Expression g : group) {
       buff.appendExceptFirst(", ");
       buff.append(StringUtils.unEnclose(g.getSQL()));
     }
   }
   if (having != null) {
     // could be set in addGlobalCondition
     // in this case the query is not run directly, just getPlanSQL is
     // called
     Expression h = having;
     buff.append("\nHAVING ").append(StringUtils.unEnclose(h.getSQL()));
   } else if (havingIndex >= 0) {
     Expression h = exprList[havingIndex];
     buff.append("\nHAVING ").append(StringUtils.unEnclose(h.getSQL()));
   }
   if (sort != null) {
     buff.append("\nORDER BY ").append(sort.getSQL(exprList, visibleColumnCount));
   }
   if (orderList != null) {
     buff.append("\nORDER BY ");
     buff.resetCount();
     for (SelectOrderBy o : orderList) {
       buff.appendExceptFirst(", ");
       buff.append(StringUtils.unEnclose(o.getSQL()));
     }
   }
   if (limitExpr != null) {
     buff.append("\nLIMIT ").append(StringUtils.unEnclose(limitExpr.getSQL()));
     if (offsetExpr != null) {
       buff.append(" OFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL()));
     }
   }
   if (sampleSize != 0) {
     buff.append("\nSAMPLE_SIZE ").append(sampleSize);
   }
   if (isForUpdate) {
     buff.append("\nFOR UPDATE");
   }
   if (isQuickAggregateQuery) {
     buff.append("\n/* direct lookup */");
   }
   if (isDistinctQuery) {
     buff.append("\n/* distinct */");
   }
   if (sortUsingIndex) {
     buff.append("\n/* index sorted */");
   }
   if (isGroupQuery) {
     if (isGroupSortedQuery) {
       buff.append("\n/* group sorted */");
     }
   }
   // buff.append("\n/* cost: " + cost + " */");
   return buff.toString();
 }