code: func (pe *projectionEliminater) eliminate(p LogicalPlan, replace map[string]*expression.Column, canEliminate bool) LogicalPlan {
  	proj, isProj := p.(*LogicalProjection)
  	childFlag := canEliminate
  	if _, isUnion := p.(*LogicalUnionAll); isUnion {
  		childFlag = false
  	} else if _, isAgg := p.(*LogicalAggregation); isAgg || isProj {
  		childFlag = true
  	} else if _, isWindow := p.(*LogicalWindow); isWindow {
  		childFlag = true
  	}
  	for i, child := range p.Children() {
  		p.Children()[i] = pe.eliminate(child, replace, childFlag)
  	}
  
  	switch x := p.(type) {
  	case *LogicalJoin:
  		x.schema = buildLogicalJoinSchema(x.JoinType, x)
  	case *LogicalApply:
  		x.schema = buildLogicalJoinSchema(x.JoinType, x)
  	default:
  		for _, dst := range p.Schema().Columns {
  			resolveColumnAndReplace(dst, replace)
  		}
  	}
  	p.replaceExprColumns(replace)
  
  	if !(isProj && canEliminate && canProjectionBeEliminatedLoose(proj)) {
  		return p
  	}
  	exprs := proj.Exprs
  	for i, col := range proj.Schema().Columns {
  		replace[string(col.HashCode(nil))] = exprs[i].(*expression.Column)
  	}
  	return p.Children()[0]
  }
docs: // eliminate eliminates the redundant projection in a logical plan.