Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c6cec81

Browse files
committed
Fix: Handle (n > 0 and err == io.EOF) in CopyFromReader as per io.Reader documentation
1 parent 0b00887 commit c6cec81

2 files changed

Lines changed: 94 additions & 1 deletion

File tree

copy_from.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func (c *Conn) CopyFromReader(r io.Reader, sql string) error {
298298
sp := len(buf)
299299
for {
300300
n, err := r.Read(buf[5:cap(buf)])
301-
if err == io.EOF {
301+
if err == io.EOF && n == 0 {
302302
break
303303
}
304304
buf = buf[0 : n+5]

copy_from_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package pgx_test
22

33
import (
4+
"compress/gzip"
5+
"fmt"
6+
"io/ioutil"
7+
"os"
48
"reflect"
9+
"strconv"
510
"strings"
611
"testing"
712
"time"
@@ -639,3 +644,91 @@ func TestConnCopyFromReaderNoTableError(t *testing.T) {
639644

640645
ensureConnValid(t, conn)
641646
}
647+
648+
func TestConnCopyFromGzipReader(t *testing.T) {
649+
t.Parallel()
650+
651+
conn := mustConnect(t, *defaultConnConfig)
652+
defer closeConn(t, conn)
653+
654+
mustExec(t, conn, `create temporary table foo(
655+
a int4,
656+
b varchar
657+
)`)
658+
659+
f, err := ioutil.TempFile("", "*")
660+
if err != nil {
661+
t.Fatalf("Unexpected error for ioutil.TempFile: %v", err)
662+
}
663+
664+
gw := gzip.NewWriter(f)
665+
666+
inputRows := [][]interface{}{}
667+
for i := 0; i < 1000; i++ {
668+
val := strconv.Itoa(i * i)
669+
inputRows = append(inputRows, []interface{}{int32(i), val})
670+
_, err = gw.Write([]byte(fmt.Sprintf("%d,\"%s\"\n", i, val)))
671+
if err != nil {
672+
t.Errorf("Unexpected error for gw.Write: %v", err)
673+
}
674+
}
675+
676+
err = gw.Close()
677+
if err != nil {
678+
t.Fatalf("Unexpected error for gw.Close: %v", err)
679+
}
680+
681+
_, err = f.Seek(0, 0)
682+
if err != nil {
683+
t.Fatalf("Unexpected error for f.Seek: %v", err)
684+
}
685+
686+
gr, err := gzip.NewReader(f)
687+
if err != nil {
688+
t.Fatalf("Unexpected error for gzip.NewReader: %v", err)
689+
}
690+
691+
err = conn.CopyFromReader(gr, "COPY foo FROM STDIN WITH (FORMAT csv)")
692+
if err != nil {
693+
t.Errorf("Unexpected error for CopyFromReader: %v", err)
694+
}
695+
696+
err = gr.Close()
697+
if err != nil {
698+
t.Errorf("Unexpected error for gr.Close: %v", err)
699+
}
700+
701+
err = f.Close()
702+
if err != nil {
703+
t.Errorf("Unexpected error for f.Close: %v", err)
704+
}
705+
706+
err = os.Remove(f.Name())
707+
if err != nil {
708+
t.Errorf("Unexpected error for os.Remove: %v", err)
709+
}
710+
711+
rows, err := conn.Query("select * from foo")
712+
if err != nil {
713+
t.Errorf("Unexpected error for Query: %v", err)
714+
}
715+
716+
var outputRows [][]interface{}
717+
for rows.Next() {
718+
row, err := rows.Values()
719+
if err != nil {
720+
t.Errorf("Unexpected error for rows.Values(): %v", err)
721+
}
722+
outputRows = append(outputRows, row)
723+
}
724+
725+
if rows.Err() != nil {
726+
t.Errorf("Unexpected error for rows.Err(): %v", rows.Err())
727+
}
728+
729+
if !reflect.DeepEqual(inputRows, outputRows) {
730+
t.Errorf("Input rows and output rows do not equal")
731+
}
732+
733+
ensureConnValid(t, conn)
734+
}

0 commit comments

Comments
 (0)