internal/protocol/session.go
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
}
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
}
// Prepare prepares a sql statement.