@Override
 public Void visitGroupByOperator(GroupByOperator op, Pair<LogicalVariable, LogicalVariable> pair)
     throws AlgebricksException {
   subst(pair.first, pair.second, op.getGroupByList());
   subst(pair.first, pair.second, op.getDecorList());
   for (ILogicalPlan p : op.getNestedPlans()) {
     for (Mutable<ILogicalOperator> r : p.getRoots()) {
       OperatorManipulationUtil.substituteVarRec(
           (AbstractLogicalOperator) r.getValue(), pair.first, pair.second, goThroughNts, ctx);
     }
   }
   substVarTypes(op, pair);
   return null;
 }
 @Override
 public Void visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {
   for (ILogicalPlan p : op.getNestedPlans()) {
     for (Mutable<ILogicalOperator> r : p.getRoots()) {
       VariableUtilities.getLiveVariables(r.getValue(), schemaVariables);
     }
   }
   for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getGroupByList()) {
     if (p.first != null) {
       schemaVariables.add(p.first);
     }
   }
   for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getDecorList()) {
     if (p.first != null) {
       schemaVariables.add(p.first);
     } else {
       ILogicalExpression e = p.second.getValue();
       if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
         schemaVariables.add(((VariableReferenceExpression) e).getVariableReference());
       }
     }
   }
   return null;
 }