@Override
 public Void visitRunningAggregateOperator(
     RunningAggregateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
     throws AlgebricksException {
   List<LogicalVariable> variables = op.getVariables();
   int n = variables.size();
   for (int i = 0; i < n; i++) {
     if (variables.get(i).equals(pair.first)) {
       variables.set(i, pair.second);
     } else {
       op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);
     }
   }
   substVarTypes(op, pair);
   return null;
 }
  @Override
  public void contributeRuntimeOperator(
      IHyracksJobBuilder builder,
      JobGenContext context,
      ILogicalOperator op,
      IOperatorSchema opSchema,
      IOperatorSchema[] inputSchemas,
      IOperatorSchema outerPlanSchema)
      throws AlgebricksException {
    RunningAggregateOperator ragg = (RunningAggregateOperator) op;
    List<LogicalVariable> variables = ragg.getVariables();
    List<Mutable<ILogicalExpression>> expressions = ragg.getExpressions();
    int[] outColumns = new int[variables.size()];
    for (int i = 0; i < outColumns.length; i++) {
      outColumns[i] = opSchema.findVariable(variables.get(i));
    }
    IRunningAggregateEvaluatorFactory[] runningAggFuns =
        new IRunningAggregateEvaluatorFactory[expressions.size()];
    IExpressionRuntimeProvider expressionRuntimeProvider = context.getExpressionRuntimeProvider();
    for (int i = 0; i < runningAggFuns.length; i++) {
      StatefulFunctionCallExpression expr =
          (StatefulFunctionCallExpression) expressions.get(i).getValue();
      runningAggFuns[i] =
          expressionRuntimeProvider.createRunningAggregateFunctionFactory(
              expr,
              context.getTypeEnvironment(op.getInputs().get(0).getValue()),
              inputSchemas,
              context);
    }

    // TODO push projections into the operator
    int[] projectionList = JobGenHelper.projectAllVariables(opSchema);

    RunningAggregateRuntimeFactory runtime =
        new RunningAggregateRuntimeFactory(outColumns, runningAggFuns, projectionList);

    // contribute one Asterix framewriter
    RecordDescriptor recDesc =
        JobGenHelper.mkRecordDescriptor(context.getTypeEnvironment(op), opSchema, context);
    builder.contributeMicroOperator(ragg, runtime, recDesc);
    // and contribute one edge from its child
    ILogicalOperator src = ragg.getInputs().get(0).getValue();
    builder.contributeGraphEdge(src, 0, ragg, 0);
  }