new SimplifyExpressions(metadata, sqlParser),
new UnaliasSymbolReferences(),
new PruneRedundantProjections(),
new SetFlatteningOptimizer(),
new MaterializeSamplePullUp(),
new LimitPushDown(), // Run the LimitPushDown after flattening set operators to make it easier to do the set flattening
new PredicatePushDown(metadata, sqlParser, splitManager, featuresConfig.isExperimentalSyntaxEnabled()),
new PredicatePushDown(metadata, sqlParser, splitManager, featuresConfig.isExperimentalSyntaxEnabled()), // Run predicate push down one more time in case we can leverage new information from generated partitions
new MergeProjections(),
new SimplifyExpressions(metadata, sqlParser), // Re-run the SimplifyExpressions to simplify any recomposed expressions from other optimizations
new UnaliasSymbolReferences(), // Run again because predicate pushdown might add more projections