@@ -20,10 +20,11 @@ package org.apache.spark.sql.catalyst.optimizer
2020import org .apache .spark .sql .catalyst .analysis .EliminateSubqueryAliases
2121import org .apache .spark .sql .catalyst .dsl .expressions ._
2222import org .apache .spark .sql .catalyst .dsl .plans ._
23- import org .apache .spark .sql .catalyst .expressions .Rand
23+ import org .apache .spark .sql .catalyst .expressions .{ Alias , Rand }
2424import org .apache .spark .sql .catalyst .plans .PlanTest
25- import org .apache .spark .sql .catalyst .plans .logical .{LocalRelation , LogicalPlan }
25+ import org .apache .spark .sql .catalyst .plans .logical .{LocalRelation , LogicalPlan , Project }
2626import org .apache .spark .sql .catalyst .rules .RuleExecutor
27+ import org .apache .spark .sql .types .MetadataBuilder
2728
2829class CollapseProjectSuite extends PlanTest {
2930 object Optimize extends RuleExecutor [LogicalPlan ] {
@@ -119,4 +120,22 @@ class CollapseProjectSuite extends PlanTest {
119120
120121 comparePlans(optimized, correctAnswer)
121122 }
123+
124+ test(" preserve top-level alias metadata while collapsing projects" ) {
125+ def hasMetadata (logicalPlan : LogicalPlan ): Boolean = {
126+ logicalPlan.asInstanceOf [Project ].projectList.exists(_.metadata.contains(" key" ))
127+ }
128+
129+ val metadata = new MetadataBuilder ().putLong(" key" , 1 ).build()
130+ val analyzed =
131+ Project (Seq (Alias (' a_with_metadata , " b" )()),
132+ Project (Seq (Alias (' a , " a_with_metadata" )(explicitMetadata = Some (metadata))),
133+ testRelation.logicalPlan)).analyze
134+ require(hasMetadata(analyzed))
135+
136+ val optimized = Optimize .execute(analyzed)
137+ val projects = optimized.collect { case p : Project => p }
138+ assert(projects.size === 1 )
139+ assert(hasMetadata(optimized))
140+ }
122141}
0 commit comments