mirror of https://github.com/jackc/pgx.git
Adds "char" type
parent
00bd3062e0
commit
818dcbf2b6
84
values.go
84
values.go
|
@ -18,6 +18,7 @@ import (
|
|||
const (
|
||||
BoolOid = 16
|
||||
ByteaOid = 17
|
||||
CharOid = 18
|
||||
Int8Oid = 20
|
||||
Int2Oid = 21
|
||||
Int4Oid = 23
|
||||
|
@ -88,6 +89,7 @@ func init() {
|
|||
"_varchar": BinaryFormatCode,
|
||||
"bool": BinaryFormatCode,
|
||||
"bytea": BinaryFormatCode,
|
||||
"char": BinaryFormatCode,
|
||||
"cidr": BinaryFormatCode,
|
||||
"date": BinaryFormatCode,
|
||||
"float4": BinaryFormatCode,
|
||||
|
@ -256,7 +258,53 @@ func (n NullString) Encode(w *WriteBuf, oid Oid) error {
|
|||
return encodeString(w, oid, n.String)
|
||||
}
|
||||
|
||||
// NullInt16 represents an smallint that may be null. NullInt16 implements the
|
||||
// The pgx.Char type is for PostgreSQL's special 8-bit-only
|
||||
// "char" type more akin to the C language's char type, or Go's byte type.
|
||||
// (Note that the name in PostgreSQL itself is "char" and not char.)
|
||||
// It gets used a lot
|
||||
// in PostgreSQL's system tables to hold a single ASCII character value.
|
||||
type Char byte
|
||||
|
||||
// NullChar represents a pgx.Char that may be null. NullChar implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan for prepared and unprepared queries.
|
||||
//
|
||||
// If Valid is false then the value is NULL.
|
||||
type NullChar struct {
|
||||
Char Char
|
||||
Valid bool // Valid is true if Char is not NULL
|
||||
}
|
||||
|
||||
func (n *NullChar) Scan(vr *ValueReader) error {
|
||||
if vr.Type().DataType != CharOid {
|
||||
return SerializationError(fmt.Sprintf("NullChar.Scan cannot decode OID %d", vr.Type().DataType))
|
||||
}
|
||||
|
||||
if vr.Len() == -1 {
|
||||
n.Char, n.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
n.Char = decodeChar(vr)
|
||||
return vr.Err()
|
||||
}
|
||||
|
||||
func (n NullChar) FormatCode() int16 { return BinaryFormatCode }
|
||||
|
||||
func (n NullChar) Encode(w *WriteBuf, oid Oid) error {
|
||||
if oid != CharOid {
|
||||
return SerializationError(fmt.Sprintf("NullChar.Encode cannot encode into OID %d", oid))
|
||||
}
|
||||
|
||||
if !n.Valid {
|
||||
w.WriteInt32(-1)
|
||||
return nil
|
||||
}
|
||||
|
||||
return encodeChar(w, oid, n.Char)
|
||||
}
|
||||
|
||||
// NullInt16 represents a smallint that may be null. NullInt16 implements the
|
||||
// Scanner and Encoder interfaces so it may be used both as an argument to
|
||||
// Query[Row] and a destination for Scan for prepared and unprepared queries.
|
||||
//
|
||||
|
@ -810,6 +858,8 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
|
|||
return encodeInt(wbuf, oid, arg)
|
||||
case uint:
|
||||
return encodeUInt(wbuf, oid, arg)
|
||||
case Char:
|
||||
return encodeChar(wbuf, oid, arg)
|
||||
case int8:
|
||||
return encodeInt8(wbuf, oid, arg)
|
||||
case uint8:
|
||||
|
@ -986,6 +1036,8 @@ func Decode(vr *ValueReader, d interface{}) error {
|
|||
return fmt.Errorf("%d is less than zero for uint64", n)
|
||||
}
|
||||
*v = uint64(n)
|
||||
case *Char:
|
||||
*v = decodeChar(vr)
|
||||
case *Oid:
|
||||
*v = decodeOid(vr)
|
||||
case *Xid:
|
||||
|
@ -1185,6 +1237,30 @@ func decodeInt8(vr *ValueReader) int64 {
|
|||
return vr.ReadInt64()
|
||||
}
|
||||
|
||||
func decodeChar(vr *ValueReader) Char {
|
||||
if vr.Len() == -1 {
|
||||
vr.Fatal(ProtocolError("Cannot decode null into char"))
|
||||
return Char(0)
|
||||
}
|
||||
|
||||
if vr.Type().DataType != CharOid {
|
||||
vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into char", vr.Type().DataType)))
|
||||
return Char(0)
|
||||
}
|
||||
|
||||
if vr.Type().FormatCode != BinaryFormatCode {
|
||||
vr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", vr.Type().FormatCode)))
|
||||
return Char(0)
|
||||
}
|
||||
|
||||
if vr.Len() != 1 {
|
||||
vr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for a char: %d", vr.Len())))
|
||||
return Char(0)
|
||||
}
|
||||
|
||||
return Char(vr.ReadByte())
|
||||
}
|
||||
|
||||
func decodeInt2(vr *ValueReader) int16 {
|
||||
if vr.Len() == -1 {
|
||||
vr.Fatal(ProtocolError("Cannot decode null into int16"))
|
||||
|
@ -1270,6 +1346,12 @@ func encodeUInt(w *WriteBuf, oid Oid, value uint) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func encodeChar(w *WriteBuf, oid Oid, value Char) error {
|
||||
w.WriteInt32(1)
|
||||
w.WriteByte(byte(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeInt8(w *WriteBuf, oid Oid, value int8) error {
|
||||
switch oid {
|
||||
case Int2Oid:
|
||||
|
|
|
@ -594,6 +594,7 @@ func TestNullX(t *testing.T) {
|
|||
s pgx.NullString
|
||||
i16 pgx.NullInt16
|
||||
i32 pgx.NullInt32
|
||||
c pgx.NullChar
|
||||
xid pgx.NullXid
|
||||
cid pgx.NullCid
|
||||
tid pgx.NullTid
|
||||
|
@ -621,6 +622,9 @@ func TestNullX(t *testing.T) {
|
|||
{"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}}},
|
||||
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 1, Valid: true}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 1, Valid: true}}},
|
||||
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 1, Valid: false}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 0, Valid: false}}},
|
||||
{"select $1::\"char\"", []interface{}{pgx.NullChar{Char: 255, Valid: true}}, []interface{}{&actual.c}, allTypes{c: pgx.NullChar{Char: 255, Valid: true}}},
|
||||
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 1, Valid: true}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 1, Valid: true}}},
|
||||
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 1, Valid: false}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 0, Valid: false}}},
|
||||
{"select $1::cid", []interface{}{pgx.NullCid{Cid: 4294967295, Valid: true}}, []interface{}{&actual.cid}, allTypes{cid: pgx.NullCid{Cid: 4294967295, Valid: true}}},
|
||||
|
|
Loading…
Reference in New Issue