code: func (e *ExecuteExec) Build() error {
  	ok, err := IsPointGetWithPKOrUniqueKeyByAutoCommit(e.ctx, e.plan)
  	if err != nil {
  		return err
  	}
  	if ok {
  		err = e.ctx.InitTxnWithStartTS(math.MaxUint64)
  	}
  	if err != nil {
  		return err
  	}
  	b := newExecutorBuilder(e.ctx, e.is)
  	stmtExec := b.build(e.plan)
  	if b.err != nil {
  		log.Warn("rebuild plan in EXECUTE statement failed", zap.String("labelName of PREPARE statement", e.name))
  		return errors.Trace(b.err)
  	}
  	e.stmtExec = stmtExec
  	CountStmtNode(e.stmt, e.ctx.GetSessionVars().InRestrictedSQL)
  	logExpensiveQuery(e.stmt, e.plan)
  	return nil
  }
docs: // Build builds a prepared statement into an executor.
  // After Build, e.StmtExec will be used to do the real execution.