code: func (b *planBuilder) rewrite(expr ast.ExprNode, p LogicalPlan, aggMapper map[*ast.AggregateFuncExpr]int, asScalar bool) (
  	expression.Expression, LogicalPlan, error) {
  	er := &expressionRewriter{
  		p:        p,
  		aggrMap:  aggMapper,
  		b:        b,
  		asScalar: asScalar,
  		ctx:      b.ctx,
  	}
  	if p != nil {
  		er.schema = p.GetSchema()
  	}
  	expr.Accept(er)
  	if er.err != nil {
  		return nil, nil, errors.Trace(er.err)
  	}
  	if !asScalar && len(er.ctxStack) == 0 {
  		return nil, er.p, nil
  	}
  	if len(er.ctxStack) != 1 {
  		return nil, nil, errors.Errorf("context len %v is invalid", len(er.ctxStack))
  	}
  	if getRowLen(er.ctxStack[0]) != 1 {
  		return nil, nil, ErrOperandColumns.GenByArgs(1)
  	}
  	result := expression.FoldConstant(b.ctx, er.ctxStack[0])
  	return result, er.p, nil
  }
docs: // rewrite function rewrites ast expr to expression.Expression.
  // aggMapper maps ast.AggregateFuncExpr to the columns offset in p's output schema.
  // asScalar means whether this expression must be treated as a scalar expression.
  // And this function returns a result expression, a new plan that may have apply or semi-join.