| 79 | } |
| 80 | |
| 81 | func (rs *rows) Next(dest []driver.Value) (resErr error) { |
| 82 | if rs.done { |
| 83 | return io.EOF |
| 84 | } |
| 85 | if err := rs.cn.err.getForNext(); err != nil { |
| 86 | return err |
| 87 | } |
| 88 | |
| 89 | for { |
| 90 | t, err := rs.cn.recv1Buf(&rs.rb) |
| 91 | if err != nil { |
| 92 | return rs.cn.handleError(err) |
| 93 | } |
| 94 | switch t { |
| 95 | case proto.ErrorResponse: |
| 96 | resErr = parseError(&rs.rb, "") |
| 97 | case proto.CommandComplete, proto.EmptyQueryResponse: |
| 98 | if t == proto.CommandComplete { |
| 99 | rs.result, rs.tag, err = rs.cn.parseComplete(rs.rb.string()) |
| 100 | if err != nil { |
| 101 | return rs.cn.handleError(err) |
| 102 | } |
| 103 | } |
| 104 | continue |
| 105 | case proto.ReadyForQuery: |
| 106 | rs.cn.processReadyForQuery(&rs.rb) |
| 107 | rs.done = true |
| 108 | if resErr != nil { |
| 109 | return rs.cn.handleError(resErr) |
| 110 | } |
| 111 | return io.EOF |
| 112 | case proto.DataRow: |
| 113 | n := rs.rb.int16() |
| 114 | if resErr != nil { |
| 115 | rs.cn.err.set(driver.ErrBadConn) |
| 116 | return fmt.Errorf("pq: unexpected DataRow after error %s", resErr) |
| 117 | } |
| 118 | if n < len(dest) { |
| 119 | dest = dest[:n] |
| 120 | } |
| 121 | for i := range dest { |
| 122 | l := rs.rb.int32() |
| 123 | if l == -1 { |
| 124 | dest[i] = nil |
| 125 | continue |
| 126 | } |
| 127 | dest[i], err = decode(&rs.cn.parameterStatus, rs.rb.next(l), rs.colTyps[i].OID, rs.colFmts[i]) |
| 128 | if err != nil { |
| 129 | return rs.cn.handleError(err) |
| 130 | } |
| 131 | } |
| 132 | return rs.cn.handleError(resErr) |
| 133 | case proto.RowDescription: |
| 134 | next := parsePortalRowDescribe(&rs.rb) |
| 135 | rs.next = &next |
| 136 | return io.EOF |
| 137 | default: |
| 138 | return fmt.Errorf("pq: unexpected message after execute: %q", t) |