@@ -377,15 +377,16 @@ abstract class QueryPlan[PlanType <: QueryPlan[PlanType]] extends TreeNode[PlanT
377377 // As the root of the expression, Alias will always take an arbitrary exprId, we need to
378378 // normalize that for equality testing, by assigning expr id from 0 incrementally. The
379379 // alias name doesn't matter and should be erased.
380- Alias (normalizeExprId(a.child), " " )(ExprId (id), a.qualifier, isGenerated = a.isGenerated)
380+ val normalizedChild = QueryPlan .normalizeExprId(a.child, allAttributes)
381+ Alias (normalizedChild, " " )(ExprId (id), a.qualifier, isGenerated = a.isGenerated)
381382
382383 case ar : AttributeReference if allAttributes.indexOf(ar.exprId) == - 1 =>
383384 // Top level `AttributeReference` may also be used for output like `Alias`, we should
384385 // normalize the epxrId too.
385386 id += 1
386387 ar.withExprId(ExprId (id))
387388
388- case other => normalizeExprId(other)
389+ case other => QueryPlan . normalizeExprId(other, allAttributes )
389390 }.withNewChildren(canonicalizedChildren)
390391 }
391392
@@ -395,24 +396,6 @@ abstract class QueryPlan[PlanType <: QueryPlan[PlanType]] extends TreeNode[PlanT
395396 */
396397 protected def preCanonicalized : PlanType = this
397398
398- /**
399- * Normalize the exprIds in the given expression, by updating the exprId in `AttributeReference`
400- * with its referenced ordinal from input attributes. It's similar to `BindReferences` but we
401- * do not use `BindReferences` here as the plan may take the expression as a parameter with type
402- * `Attribute`, and replace it with `BoundReference` will cause error.
403- */
404- def normalizeExprId [T <: Expression ](e : T , input : AttributeSeq = allAttributes): T = {
405- e.transformUp {
406- case s : SubqueryExpression => s.canonicalize(input)
407- case ar : AttributeReference =>
408- val ordinal = input.indexOf(ar.exprId)
409- if (ordinal == - 1 ) {
410- ar
411- } else {
412- ar.withExprId(ExprId (ordinal))
413- }
414- }.canonicalized.asInstanceOf [T ]
415- }
416399
417400 /**
418401 * Returns true when the given query plan will return the same results as this query plan.
@@ -439,3 +422,24 @@ abstract class QueryPlan[PlanType <: QueryPlan[PlanType]] extends TreeNode[PlanT
439422 */
440423 lazy val allAttributes : AttributeSeq = children.flatMap(_.output)
441424}
425+
426+ object QueryPlan {
427+ /**
428+ * Normalize the exprIds in the given expression, by updating the exprId in `AttributeReference`
429+ * with its referenced ordinal from input attributes. It's similar to `BindReferences` but we
430+ * do not use `BindReferences` here as the plan may take the expression as a parameter with type
431+ * `Attribute`, and replace it with `BoundReference` will cause error.
432+ */
433+ def normalizeExprId [T <: Expression ](e : T , input : AttributeSeq ): T = {
434+ e.transformUp {
435+ case s : SubqueryExpression => s.canonicalize(input)
436+ case ar : AttributeReference =>
437+ val ordinal = input.indexOf(ar.exprId)
438+ if (ordinal == - 1 ) {
439+ ar
440+ } else {
441+ ar.withExprId(ExprId (ordinal))
442+ }
443+ }.canonicalized.asInstanceOf [T ]
444+ }
445+ }
0 commit comments