private void normalizeSorts(
     SchemaContext pc, Map<RewriteKey, ExpressionNode> projMap, Edge<?, ?> in) {
   @SuppressWarnings("unchecked")
   MultiEdge<?, SortingSpecification> min = (MultiEdge<?, SortingSpecification>) in;
   for (SortingSpecification ss : min.getMulti()) {
     ExpressionNode target = ss.getTarget();
     if (target instanceof AliasInstance) continue;
     else if (target instanceof LiteralExpression) {
       // i.e. order by 1,2,3
       LiteralExpression le = (LiteralExpression) target;
       Object value = le.getValue(pc);
       if (value instanceof Long) {
         Long index = (Long) value;
         if ((index.intValue() - 1) < projection.size()) {
           target = ExpressionUtils.getTarget(projection.get(index.intValue() - 1));
         }
       }
     }
     ExpressionNode inProjection = projMap.get(target.getRewriteKey());
     if (inProjection != null) {
       ExpressionAlias ea = (ExpressionAlias) inProjection.getParent();
       AliasInstance ai = ea.buildAliasInstance();
       ss.getTargetEdge().set(ai);
     }
   }
 }
  protected SelectStatement buildAggCommand(SelectStatement in) {
    SelectStatement out = CopyVisitor.copy(in);
    // we're going to build
    // select Name, max(Engine), max(Version), max(Row_format),
    // sum(Rows), avg(Avg_row_length), sum(Data_length),
    // max(Max_data_length), sum(Index_length),
    // sum(Data_free), max(Auto_increment), min(Create_time),
    // max(Update_time), max(Check_time),
    // max(Collation), null /*Checksum*/, max(Create_options), max(Comment) from temp1 group by Name

    // eventually we will build another temp table of rewrite info (visible name, auto_inc values)
    // and join
    // but for now this is good enough

    List<ExpressionNode> proj = new ArrayList<ExpressionNode>();
    ExpressionAlias nameColumn = null;
    for (ExpressionNode en : out.getProjection()) {
      ExpressionAlias ea = (ExpressionAlias) en;
      ColumnInstance ci = (ColumnInstance) ea.getTarget();
      String cn = ci.getColumn().getName().getUnquotedName().get();
      FunctionCall fc = null;
      if (maxedColumns.contains(cn)) {
        fc = new FunctionCall(FunctionName.makeMax(), ci);
      } else if (summedColumns.contains(cn)) {
        fc = new FunctionCall(FunctionName.makeSum(), ci);
      } else if ("Name".equals(cn)) {
        fc = null;
        nameColumn = ea;
      } else if ("Avg_row_length".equals(cn)) {
        fc =
            new FunctionCall(
                FunctionName.makeRound(), new FunctionCall(FunctionName.makeAvg(), ci));
      } else if ("Create_time".equals(cn)) {
        fc = new FunctionCall(FunctionName.makeMin(), ci);
      } else if ("Checksum".equals(cn)) {
        fc = null;
        ea =
            new ExpressionAlias(
                LiteralExpression.makeNullLiteral(),
                new NameAlias(ci.getColumn().getName().getUnqualified()),
                false);
      } else {
        throw new SchemaException(Pass.PLANNER, "Unknown show status column: " + cn);
      }
      if (fc != null) {
        ea =
            new ExpressionAlias(
                fc, new NameAlias(ci.getColumn().getName().getUnqualified()), false);
      }
      proj.add(ea);
    }
    out.setProjection(proj);
    SortingSpecification ngb = new SortingSpecification(nameColumn.buildAliasInstance(), true);
    ngb.setOrdering(Boolean.FALSE);
    out.getGroupBysEdge().add(ngb);

    return out;
  }
 public SelectStatement setGroupBy(List<SortingSpecification> order) {
   groupBys.set(order);
   SortingSpecification.setOrdering(order, Boolean.FALSE);
   return this;
 }