Merge branch 'manniwood-add-null-oid'

pull/191/head
Jack Christensen 2016-09-27 08:51:15 -05:00
commit a9199847a8
3 changed files with 52 additions and 42 deletions

View File

@ -53,12 +53,6 @@ func (s *startupMessage) Bytes() (buf []byte) {
return buf
}
// Oid (Object Identifier Type) is, according to https://www.postgresql.org/docs/current/static/datatype-oid.html,
// used internally by PostgreSQL as a primary key for various system tables. It is currently implemented
// as an unsigned four-byte integer. Its definition can be found in src/include/postgres_ext.h
// in the PostgreSQL sources.
type Oid uint32
type FieldDescription struct {
Name string
Table Oid

View File

@ -383,6 +383,51 @@ func (n NullInt32) Encode(w *WriteBuf, oid Oid) error {
return encodeInt32(w, oid, n.Int32)
}
// Oid (Object Identifier Type) is, according to https://www.postgresql.org/docs/current/static/datatype-oid.html,
// used internally by PostgreSQL as a primary key for various system tables. It is currently implemented
// as an unsigned four-byte integer. Its definition can be found in src/include/postgres_ext.h
// in the PostgreSQL sources.
type Oid uint32
// NullOid represents a Command Identifier (Oid) that may be null. NullOid implements the
// Scanner and Encoder interfaces so it may be used both as an argument to
// Query[Row] and a destination for Scan.
//
// If Valid is false then the value is NULL.
type NullOid struct {
Oid Oid
Valid bool // Valid is true if Oid is not NULL
}
func (n *NullOid) Scan(vr *ValueReader) error {
if vr.Type().DataType != OidOid {
return SerializationError(fmt.Sprintf("NullOid.Scan cannot decode OID %d", vr.Type().DataType))
}
if vr.Len() == -1 {
n.Oid, n.Valid = 0, false
return nil
}
n.Valid = true
n.Oid = decodeOid(vr)
return vr.Err()
}
func (n NullOid) FormatCode() int16 { return BinaryFormatCode }
func (n NullOid) Encode(w *WriteBuf, oid Oid) error {
if oid != OidOid {
return SerializationError(fmt.Sprintf("NullOid.Encode cannot encode into OID %d", oid))
}
if !n.Valid {
w.WriteInt32(-1)
return nil
}
return encodeOid(w, oid, n.Oid)
}
// Xid is PostgreSQL's Transaction ID type.
//
// In later versions of PostgreSQL, it is the type used for the backend_xid
@ -406,7 +451,7 @@ type Xid uint32
// If Valid is false then the value is NULL.
type NullXid struct {
Xid Xid
Valid bool // Valid is true if Int32 is not NULL
Valid bool // Valid is true if Xid is not NULL
}
func (n *NullXid) Scan(vr *ValueReader) error {
@ -458,7 +503,7 @@ type Cid uint32
// If Valid is false then the value is NULL.
type NullCid struct {
Cid Cid
Valid bool // Valid is true if Int32 is not NULL
Valid bool // Valid is true if Cid is not NULL
}
func (n *NullCid) Scan(vr *ValueReader) error {
@ -513,7 +558,7 @@ type Tid struct {
// If Valid is false then the value is NULL.
type NullTid struct {
Tid Tid
Valid bool // Valid is true if Int32 is not NULL
Valid bool // Valid is true if Tid is not NULL
}
func (n *NullTid) Scan(vr *ValueReader) error {

View File

@ -551,39 +551,6 @@ func TestInetCidrTranscodeWithJustIP(t *testing.T) {
}
}
func TestOid(t *testing.T) {
t.Parallel()
conn := mustConnect(t, *defaultConnConfig)
defer closeConn(t, conn)
tests := []struct {
sql string
value pgx.Oid
}{
{"select $1::oid", 0},
{"select $1::oid", 1},
{"select $1::oid", 4294967295},
}
for i, tt := range tests {
expected := tt.value
var actual pgx.Oid
err := conn.QueryRow(tt.sql, expected).Scan(&actual)
if err != nil {
t.Errorf("%d. Unexpected failure: %v (sql -> %v, value -> %v)", i, err, tt.sql, expected)
continue
}
if actual != expected {
t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, expected, actual, tt.sql)
}
ensureConnValid(t, conn)
}
}
func TestNullX(t *testing.T) {
t.Parallel()
@ -595,6 +562,7 @@ func TestNullX(t *testing.T) {
i16 pgx.NullInt16
i32 pgx.NullInt32
c pgx.NullChar
oid pgx.NullOid
xid pgx.NullXid
cid pgx.NullCid
tid pgx.NullTid
@ -619,6 +587,9 @@ func TestNullX(t *testing.T) {
{"select $1::int2", []interface{}{pgx.NullInt16{Int16: 1, Valid: false}}, []interface{}{&actual.i16}, allTypes{i16: pgx.NullInt16{Int16: 0, Valid: false}}},
{"select $1::int4", []interface{}{pgx.NullInt32{Int32: 1, Valid: true}}, []interface{}{&actual.i32}, allTypes{i32: pgx.NullInt32{Int32: 1, Valid: true}}},
{"select $1::int4", []interface{}{pgx.NullInt32{Int32: 1, Valid: false}}, []interface{}{&actual.i32}, allTypes{i32: pgx.NullInt32{Int32: 0, Valid: false}}},
{"select $1::oid", []interface{}{pgx.NullOid{Oid: 1, Valid: true}}, []interface{}{&actual.oid}, allTypes{oid: pgx.NullOid{Oid: 1, Valid: true}}},
{"select $1::oid", []interface{}{pgx.NullOid{Oid: 1, Valid: false}}, []interface{}{&actual.oid}, allTypes{oid: pgx.NullOid{Oid: 0, Valid: false}}},
{"select $1::oid", []interface{}{pgx.NullOid{Oid: 4294967295, Valid: true}}, []interface{}{&actual.oid}, allTypes{oid: pgx.NullOid{Oid: 4294967295, Valid: true}}},
{"select $1::xid", []interface{}{pgx.NullXid{Xid: 1, Valid: true}}, []interface{}{&actual.xid}, allTypes{xid: pgx.NullXid{Xid: 1, Valid: true}}},
{"select $1::xid", []interface{}{pgx.NullXid{Xid: 1, Valid: false}}, []interface{}{&actual.xid}, allTypes{xid: pgx.NullXid{Xid: 0, Valid: false}}},
{"select $1::xid", []interface{}{pgx.NullXid{Xid: 4294967295, Valid: true}}, []interface{}{&actual.xid}, allTypes{xid: pgx.NullXid{Xid: 4294967295, Valid: true}}},