ImmutableList.Builder<PlanOptimizer> builder = ImmutableList.builder();
builder.add(new ImplementSampleAsFilter(),
new SimplifyExpressions(metadata),
new PruneUnreferencedOutputs(),
new UnaliasSymbolReferences(),
new PruneRedundantProjections(),
new SetFlatteningOptimizer(),
new LimitPushDown(), // Run the LimitPushDown after flattening set operators to make it easier to do the set flattening
new PredicatePushDown(metadata),
new MergeProjections(),
new SimplifyExpressions(metadata), // Re-run the SimplifyExpressions to simplify any recomposed expressions from other optimizations
new UnaliasSymbolReferences(), // Run again because predicate pushdown might add more projections
new PruneUnreferencedOutputs(), // Prune outputs again in case predicate pushdown move predicates all the way into the table scan
new PruneRedundantProjections()); // Run again because predicate pushdown might add more projections
// TODO: figure out how to improve the set flattening optimizer so that it can run at any point
this.optimizers = builder.build();
}