code: func (s *Session) Prepare(query string) (QueryType, uint64, *ParameterFieldSet, *ResultFieldSet, error) {
  	s.mu.Lock()
  	defer s.mu.Unlock()
  
  	if err := s.writeRequest(mtPrepare, false, command(query)); err != nil {
  		return QtNone, 0, nil, nil, err
  	}
  
  	var id uint64
  	var prmFieldSet *ParameterFieldSet
  	var resultFieldSet *ResultFieldSet
  
  	f := func(p replyPart) {
  
  		switch p := p.(type) {
  
  		case *statementID:
  			p.id = &id
  		case *parameterMetadata:
  			prmFieldSet = newParameterFieldSet(p.numArg)
  			p.prmFieldSet = prmFieldSet
  		case *resultMetadata:
  			resultFieldSet = newResultFieldSet(p.numArg)
  			p.resultFieldSet = resultFieldSet
  		}
  	}
  
  	if err := s.readReply(f); err != nil {
  		return QtNone, 0, nil, nil, err
  	}
  
  	return s.sh.functionCode.queryType(), id, prmFieldSet, resultFieldSet, nil
  }
docs: // Prepare prepares a sql statement.