code: func (cc *clientConn) writeChunks(ctx context.Context, rs ResultSet, binary bool, serverStatus uint16) error {
  	data := cc.alloc.AllocWithLen(4, 1024)
  	req := rs.NewRecordBatch()
  	gotColumnInfo := false
  	for {
  		// Here server.tidbResultSet implements Next method.
  		err := rs.Next(ctx, req)
  		if err != nil {
  			return err
  		}
  		if !gotColumnInfo {
  			// We need to call Next before we get columns.
  			// Otherwise, we will get incorrect columns info.
  			columns := rs.Columns()
  			err = cc.writeColumnInfo(columns, serverStatus)
  			if err != nil {
  				return err
  			}
  			gotColumnInfo = true
  		}
  		rowCount := req.NumRows()
  		if rowCount == 0 {
  			break
  		}
  		for i := 0; i < rowCount; i++ {
  			data = data[0:4]
  			if binary {
  				data, err = dumpBinaryRow(data, rs.Columns(), req.GetRow(i))
  			} else {
  				data, err = dumpTextRow(data, rs.Columns(), req.GetRow(i))
  			}
  			if err != nil {
  				return err
  			}
  			if err = cc.writePacket(data); err != nil {
  				return err
  			}
  		}
  	}
  	return cc.writeEOF(serverStatus)
  }
docs: // writeChunks writes data from a Chunk, which filled data by a ResultSet, into a connection.
  // binary specifies the way to dump data. It throws any error while dumping data.
  // serverStatus, a flag bit represents server information