diff --git a/.travis.yml b/.travis.yml index 82df2a0a..7821b744 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,12 +45,18 @@ env: - PQGOSSLTESTS=1 - PQSSLCERTTEST_PATH=$PWD/certs matrix: - - PGVERSION=9.4 - - PGVERSION=9.3 - - PGVERSION=9.2 - - PGVERSION=9.1 - - PGVERSION=9.0 - - PGVERSION=8.4 + - PGVERSION=9.4 PGTEST_BINARY_MODE=on + - PGVERSION=9.3 PGTEST_BINARY_MODE=on + - PGVERSION=9.2 PGTEST_BINARY_MODE=on + - PGVERSION=9.1 PGTEST_BINARY_MODE=on + - PGVERSION=9.0 PGTEST_BINARY_MODE=on + - PGVERSION=8.4 PGTEST_BINARY_MODE=on + - PGVERSION=9.4 PGTEST_BINARY_MODE=off + - PGVERSION=9.3 PGTEST_BINARY_MODE=off + - PGVERSION=9.2 PGTEST_BINARY_MODE=off + - PGVERSION=9.1 PGTEST_BINARY_MODE=off + - PGVERSION=9.0 PGTEST_BINARY_MODE=off + - PGVERSION=8.4 PGTEST_BINARY_MODE=off script: - go test -v ./... diff --git a/conn.go b/conn.go index 3071bbd5..2f6ebe1e 100644 --- a/conn.go +++ b/conn.go @@ -594,7 +594,6 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co } } - func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err error) { b := cn.writeBuf('Q') b.string(q) @@ -748,8 +747,8 @@ func (cn *conn) Query(query string, args []driver.Value) (_ driver.Rows, err err st.exec(args) return &rows{ - cn: cn, - cols: st.cols, + cn: cn, + cols: st.cols, rowTyps: st.rowTyps, }, nil } @@ -1306,8 +1305,8 @@ func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { st.exec(v) return &rows{ - cn: st.cn, - cols: st.cols, + cn: st.cn, + cols: st.cols, rowTyps: st.rowTyps, }, nil } @@ -1412,11 +1411,11 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { } type rows struct { - cn *conn - cols []string + cn *conn + cols []string rowTyps []oid.Oid - done bool - rb readBuf + done bool + rb readBuf } func (rs *rows) Close() error { diff --git a/conn_test.go b/conn_test.go index 6c3c6b54..9efa4c33 100644 --- a/conn_test.go +++ b/conn_test.go @@ -7,6 +7,7 @@ import ( "io" "os" "reflect" + "strings" "testing" "time" ) @@ -15,6 +16,10 @@ type Fatalistic interface { Fatal(args ...interface{}) } +func forceBinaryMode() bool { + return os.Getenv("PGTEST_BINARY_MODE") == "on" +} + func openTestConnConninfo(conninfo string) (*sql.DB, error) { datname := os.Getenv("PGDATABASE") sslmode := os.Getenv("PGSSLMODE") @@ -32,6 +37,10 @@ func openTestConnConninfo(conninfo string) (*sql.DB, error) { os.Setenv("PGCONNECT_TIMEOUT", "20") } + if forceBinaryMode() && !strings.HasPrefix(conninfo, "postgres://") { + conninfo = conninfo + " binary_mode=on" + } + return sql.Open("postgres", conninfo) } diff --git a/encode_test.go b/encode_test.go index 9a33ee08..5c37c960 100644 --- a/encode_test.go +++ b/encode_test.go @@ -407,13 +407,13 @@ func TestByteaToText(t *testing.T) { b := []byte("hello world") row := db.QueryRow("SELECT $1::text", b) - var result []byte + var result string err := row.Scan(&result) if err != nil { t.Fatal(err) } - if string(result) != string(b) { + if result != string(b) { t.Fatalf("expected %v but got %v", b, result) } } @@ -436,6 +436,78 @@ func TestTextToBytea(t *testing.T) { } } +func TestByteaToUUID(t *testing.T) { + db := openTestConn(t) + defer db.Close() + + b := []byte("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11") + row := db.QueryRow("SELECT $1::uuid", b) + + var result []byte + err := row.Scan(&result) + if forceBinaryMode() { + pqErr := err.(*Error) + if pqErr == nil { + t.Errorf("Expected to get error") + } else if pqErr.Code != "22P03" { + t.Fatalf("Expected to get invalid binary encoding error (22P03), got %s", pqErr.Code) + } + } else { + if err != nil { + t.Fatal(err) + } + + if string(result) != string(b) { + t.Fatalf("expected %v but got %v", b, result) + } + } +} + +func TestStringToUUID(t *testing.T) { + db := openTestConn(t) + defer db.Close() + + s := "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11" + row := db.QueryRow("SELECT $1::uuid", s) + + var result string + err := row.Scan(&result) + if err != nil { + t.Fatal(err) + } + + if result != s { + t.Fatalf("expected %v but got %v", s, result) + } +} + +func TestByteaToInt(t *testing.T) { + db := openTestConn(t) + defer db.Close() + + expected := 12345678 + b := []byte(fmt.Sprintf("%d", expected)) + row := db.QueryRow("SELECT $1::int", b) + + var result int + err := row.Scan(&result) + if forceBinaryMode() { + pqErr := err.(*Error) + if pqErr == nil { + t.Errorf("Expected to get error") + } else if pqErr.Code != "22P03" { + t.Fatalf("Expected to get invalid binary encoding error (22P03), got %s", pqErr.Code) + } + } else { + if err != nil { + t.Fatal(err) + } + if result != expected { + t.Fatalf("expected %v but got %v", expected, result) + } + } +} + func TestByteaOutputFormatEncoding(t *testing.T) { input := []byte("\\x\x00\x01\x02\xFF\xFEabcdefg0123") want := []byte("\\x5c78000102fffe6162636465666730313233")