Encode and decode between all integer types

fixes #138
alloc-reduction
Jack Christensen 2016-04-28 15:28:38 -05:00
parent 623ba1eeb1
commit 88acc7e19f
2 changed files with 423 additions and 106 deletions

View File

@ -416,9 +416,6 @@ func TestQueryRowCoreTypes(t *testing.T) {
type allTypes struct { type allTypes struct {
s string s string
i16 int16
i32 int32
i64 int64
f32 float32 f32 float32
f64 float64 f64 float64
b bool b bool
@ -435,9 +432,6 @@ func TestQueryRowCoreTypes(t *testing.T) {
expected allTypes expected allTypes
}{ }{
{"select $1::text", []interface{}{"Jack"}, []interface{}{&actual.s}, allTypes{s: "Jack"}}, {"select $1::text", []interface{}{"Jack"}, []interface{}{&actual.s}, allTypes{s: "Jack"}},
{"select $1::int2", []interface{}{int16(42)}, []interface{}{&actual.i16}, allTypes{i16: 42}},
{"select $1::int4", []interface{}{int32(42)}, []interface{}{&actual.i32}, allTypes{i32: 42}},
{"select $1::int8", []interface{}{int64(42)}, []interface{}{&actual.i64}, allTypes{i64: 42}},
{"select $1::float4", []interface{}{float32(1.23)}, []interface{}{&actual.f32}, allTypes{f32: 1.23}}, {"select $1::float4", []interface{}{float32(1.23)}, []interface{}{&actual.f32}, allTypes{f32: 1.23}},
{"select $1::float8", []interface{}{float64(1.23)}, []interface{}{&actual.f64}, allTypes{f64: 1.23}}, {"select $1::float8", []interface{}{float64(1.23)}, []interface{}{&actual.f64}, allTypes{f64: 1.23}},
{"select $1::bool", []interface{}{true}, []interface{}{&actual.b}, allTypes{b: true}}, {"select $1::bool", []interface{}{true}, []interface{}{&actual.b}, allTypes{b: true}},
@ -474,41 +468,290 @@ func TestQueryRowCoreTypes(t *testing.T) {
} }
} }
func TestQueryRowCoreUnsignedIntTypes(t *testing.T) { func TestQueryRowCoreIntegerEncoding(t *testing.T) {
t.Parallel() t.Parallel()
conn := mustConnect(t, *defaultConnConfig) conn := mustConnect(t, *defaultConnConfig)
defer closeConn(t, conn) defer closeConn(t, conn)
type allTypes struct { type allTypes struct {
ui uint
ui8 uint8
ui16 uint16 ui16 uint16
ui32 uint32 ui32 uint32
ui64 uint64 ui64 uint64
i int
i8 int8
i16 int16
i32 int32
i64 int64
} }
var actual, zero allTypes var actual, zero allTypes
tests := []struct { successfulEncodeTests := []struct {
sql string sql string
queryArgs []interface{} queryArg interface{}
scanArgs []interface{} scanArg interface{}
expected allTypes expected allTypes
}{ }{
{"select $1::int2", []interface{}{uint16(42)}, []interface{}{&actual.ui16}, allTypes{ui16: 42}}, // Check any integer type where value is within int2 range can be encoded
{"select $1::int4", []interface{}{uint32(42)}, []interface{}{&actual.ui32}, allTypes{ui32: 42}}, {"select $1::int2", int(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int8", []interface{}{uint64(42)}, []interface{}{&actual.ui64}, allTypes{ui64: 42}}, {"select $1::int2", int8(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", int16(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", int32(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", int64(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", uint(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", uint8(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", uint16(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", uint32(42), &actual.i16, allTypes{i16: 42}},
{"select $1::int2", uint64(42), &actual.i16, allTypes{i16: 42}},
// Check any integer type where value is within int4 range can be encoded
{"select $1::int4", int(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", int8(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", int16(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", int32(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", int64(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", uint(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", uint8(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", uint16(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", uint32(42), &actual.i32, allTypes{i32: 42}},
{"select $1::int4", uint64(42), &actual.i32, allTypes{i32: 42}},
// Check any integer type where value is within int8 range can be encoded
{"select $1::int8", int(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", int8(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", int16(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", int32(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", int64(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", uint(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", uint8(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", uint16(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", uint32(42), &actual.i64, allTypes{i64: 42}},
{"select $1::int8", uint64(42), &actual.i64, allTypes{i64: 42}},
} }
for i, tt := range tests { for i, tt := range successfulEncodeTests {
actual = zero actual = zero
err := conn.QueryRow(tt.sql, tt.queryArgs...).Scan(tt.scanArgs...) err := conn.QueryRow(tt.sql, tt.queryArg).Scan(tt.scanArg)
if err != nil { if err != nil {
t.Errorf("%d. Unexpected failure: %v (sql -> %v, queryArgs -> %v)", i, err, tt.sql, tt.queryArgs) t.Errorf("%d. Unexpected failure: %v (sql -> %v, queryArg -> %v)", i, err, tt.sql, tt.queryArg)
continue
} }
if actual != tt.expected { if actual != tt.expected {
t.Errorf("%d. Expected %v, got %v (sql -> %v, queryArgs -> %v)", i, tt.expected, actual, tt.sql, tt.queryArgs) t.Errorf("%d. Expected %v, got %v (sql -> %v, queryArg -> %v)", i, tt.expected, actual, tt.sql, tt.queryArg)
}
ensureConnValid(t, conn)
}
failedEncodeTests := []struct {
sql string
queryArg interface{}
}{
// Check any integer type where value is outside pg:int2 range cannot be encoded
{"select $1::int2", int(32769)},
{"select $1::int2", int32(32769)},
{"select $1::int2", int32(32769)},
{"select $1::int2", int64(32769)},
{"select $1::int2", uint(32769)},
{"select $1::int2", uint16(32769)},
{"select $1::int2", uint32(32769)},
{"select $1::int2", uint64(32769)},
// Check any integer type where value is outside pg:int4 range cannot be encoded
{"select $1::int4", int64(2147483649)},
{"select $1::int4", uint32(2147483649)},
{"select $1::int4", uint64(2147483649)},
// Check any integer type where value is outside pg:int8 range cannot be encoded
{"select $1::int8", uint64(9223372036854775809)},
}
for i, tt := range failedEncodeTests {
err := conn.QueryRow(tt.sql, tt.queryArg).Scan(nil)
if err == nil {
t.Errorf("%d. Expected failure to encode, but unexpectedly succeeded: %v (sql -> %v, queryArg -> %v)", i, err, tt.sql, tt.queryArg)
} else if !strings.Contains(err.Error(), "is greater than") {
t.Errorf("%d. Expected failure to encode, but got: %v (sql -> %v, queryArg -> %v)", i, err, tt.sql, tt.queryArg)
}
ensureConnValid(t, conn)
}
}
func TestQueryRowCoreIntegerDecoding(t *testing.T) {
t.Parallel()
conn := mustConnect(t, *defaultConnConfig)
defer closeConn(t, conn)
type allTypes struct {
ui uint
ui8 uint8
ui16 uint16
ui32 uint32
ui64 uint64
i int
i8 int8
i16 int16
i32 int32
i64 int64
}
var actual, zero allTypes
successfulDecodeTests := []struct {
sql string
scanArg interface{}
expected allTypes
}{
// Check any integer type where value is within Go:int range can be decoded
{"select 42::int2", &actual.i, allTypes{i: 42}},
{"select 42::int4", &actual.i, allTypes{i: 42}},
{"select 42::int8", &actual.i, allTypes{i: 42}},
{"select -42::int2", &actual.i, allTypes{i: -42}},
{"select -42::int4", &actual.i, allTypes{i: -42}},
{"select -42::int8", &actual.i, allTypes{i: -42}},
// Check any integer type where value is within Go:int8 range can be decoded
{"select 42::int2", &actual.i8, allTypes{i8: 42}},
{"select 42::int4", &actual.i8, allTypes{i8: 42}},
{"select 42::int8", &actual.i8, allTypes{i8: 42}},
{"select -42::int2", &actual.i8, allTypes{i8: -42}},
{"select -42::int4", &actual.i8, allTypes{i8: -42}},
{"select -42::int8", &actual.i8, allTypes{i8: -42}},
// Check any integer type where value is within Go:int16 range can be decoded
{"select 42::int2", &actual.i16, allTypes{i16: 42}},
{"select 42::int4", &actual.i16, allTypes{i16: 42}},
{"select 42::int8", &actual.i16, allTypes{i16: 42}},
{"select -42::int2", &actual.i16, allTypes{i16: -42}},
{"select -42::int4", &actual.i16, allTypes{i16: -42}},
{"select -42::int8", &actual.i16, allTypes{i16: -42}},
// Check any integer type where value is within Go:int32 range can be decoded
{"select 42::int2", &actual.i32, allTypes{i32: 42}},
{"select 42::int4", &actual.i32, allTypes{i32: 42}},
{"select 42::int8", &actual.i32, allTypes{i32: 42}},
{"select -42::int2", &actual.i32, allTypes{i32: -42}},
{"select -42::int4", &actual.i32, allTypes{i32: -42}},
{"select -42::int8", &actual.i32, allTypes{i32: -42}},
// Check any integer type where value is within Go:int64 range can be decoded
{"select 42::int2", &actual.i64, allTypes{i64: 42}},
{"select 42::int4", &actual.i64, allTypes{i64: 42}},
{"select 42::int8", &actual.i64, allTypes{i64: 42}},
{"select -42::int2", &actual.i64, allTypes{i64: -42}},
{"select -42::int4", &actual.i64, allTypes{i64: -42}},
{"select -42::int8", &actual.i64, allTypes{i64: -42}},
// Check any integer type where value is within Go:uint range can be decoded
{"select 128::int2", &actual.ui, allTypes{ui: 128}},
{"select 128::int4", &actual.ui, allTypes{ui: 128}},
{"select 128::int8", &actual.ui, allTypes{ui: 128}},
// Check any integer type where value is within Go:uint8 range can be decoded
{"select 128::int2", &actual.ui8, allTypes{ui8: 128}},
{"select 128::int4", &actual.ui8, allTypes{ui8: 128}},
{"select 128::int8", &actual.ui8, allTypes{ui8: 128}},
// Check any integer type where value is within Go:uint16 range can be decoded
{"select 42::int2", &actual.ui16, allTypes{ui16: 42}},
{"select 32768::int4", &actual.ui16, allTypes{ui16: 32768}},
{"select 32768::int8", &actual.ui16, allTypes{ui16: 32768}},
// Check any integer type where value is within Go:uint32 range can be decoded
{"select 42::int2", &actual.ui32, allTypes{ui32: 42}},
{"select 42::int4", &actual.ui32, allTypes{ui32: 42}},
{"select 2147483648::int8", &actual.ui32, allTypes{ui32: 2147483648}},
// Check any integer type where value is within Go:uint64 range can be decoded
{"select 42::int2", &actual.ui64, allTypes{ui64: 42}},
{"select 42::int4", &actual.ui64, allTypes{ui64: 42}},
{"select 42::int8", &actual.ui64, allTypes{ui64: 42}},
}
for i, tt := range successfulDecodeTests {
actual = zero
err := conn.QueryRow(tt.sql).Scan(tt.scanArg)
if err != nil {
t.Errorf("%d. Unexpected failure: %v (sql -> %v)", i, err, tt.sql)
continue
}
if actual != tt.expected {
t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.expected, actual, tt.sql)
}
ensureConnValid(t, conn)
}
failedDecodeTests := []struct {
sql string
scanArg interface{}
expectedErr string
}{
// Check any integer type where value is outside Go:int8 range cannot be decoded
{"select 128::int2", &actual.i8, "is greater than"},
{"select 128::int4", &actual.i8, "is greater than"},
{"select 128::int8", &actual.i8, "is greater than"},
{"select -129::int2", &actual.i8, "is less than"},
{"select -129::int4", &actual.i8, "is less than"},
{"select -129::int8", &actual.i8, "is less than"},
// Check any integer type where value is outside Go:int16 range cannot be decoded
{"select 32768::int4", &actual.i16, "is greater than"},
{"select 32768::int8", &actual.i16, "is greater than"},
{"select -32769::int4", &actual.i16, "is less than"},
{"select -32769::int8", &actual.i16, "is less than"},
// Check any integer type where value is outside Go:int32 range cannot be decoded
{"select 2147483648::int8", &actual.i32, "is greater than"},
{"select -2147483649::int8", &actual.i32, "is less than"},
// Check any integer type where value is outside Go:uint range cannot be decoded
{"select -1::int2", &actual.ui, "is less than"},
{"select -1::int4", &actual.ui, "is less than"},
{"select -1::int8", &actual.ui, "is less than"},
// Check any integer type where value is outside Go:uint8 range cannot be decoded
{"select 256::int2", &actual.ui8, "is greater than"},
{"select 256::int4", &actual.ui8, "is greater than"},
{"select 256::int8", &actual.ui8, "is greater than"},
{"select -1::int2", &actual.ui8, "is less than"},
{"select -1::int4", &actual.ui8, "is less than"},
{"select -1::int8", &actual.ui8, "is less than"},
// Check any integer type where value is outside Go:uint16 cannot be decoded
{"select 65536::int4", &actual.ui16, "is greater than"},
{"select 65536::int8", &actual.ui16, "is greater than"},
{"select -1::int2", &actual.ui16, "is less than"},
{"select -1::int4", &actual.ui16, "is less than"},
{"select -1::int8", &actual.ui16, "is less than"},
// Check any integer type where value is outside Go:uint32 range cannot be decoded
{"select 4294967296::int8", &actual.ui32, "is greater than"},
{"select -1::int2", &actual.ui32, "is less than"},
{"select -1::int4", &actual.ui32, "is less than"},
{"select -1::int8", &actual.ui32, "is less than"},
// Check any integer type where value is outside Go:uint64 range cannot be decoded
{"select -1::int2", &actual.ui64, "is less than"},
{"select -1::int4", &actual.ui64, "is less than"},
{"select -1::int8", &actual.ui64, "is less than"},
}
for i, tt := range failedDecodeTests {
err := conn.QueryRow(tt.sql).Scan(tt.scanArg)
if err == nil {
t.Errorf("%d. Expected failure to decode, but unexpectedly succeeded: %v (sql -> %v)", i, err, tt.sql)
} else if !strings.Contains(err.Error(), tt.expectedErr) {
t.Errorf("%d. Expected failure to decode, but got: %v (sql -> %v)", i, err, tt.sql)
} }
ensureConnValid(t, conn) ensureConnValid(t, conn)
@ -619,9 +862,8 @@ func TestQueryRowErrors(t *testing.T) {
{"select $1", []interface{}{"Jack"}, []interface{}{&actual.i16}, "could not determine data type of parameter $1 (SQLSTATE 42P18)"}, {"select $1", []interface{}{"Jack"}, []interface{}{&actual.i16}, "could not determine data type of parameter $1 (SQLSTATE 42P18)"},
{"select $1::badtype", []interface{}{"Jack"}, []interface{}{&actual.i16}, `type "badtype" does not exist`}, {"select $1::badtype", []interface{}{"Jack"}, []interface{}{&actual.i16}, `type "badtype" does not exist`},
{"SYNTAX ERROR", []interface{}{}, []interface{}{&actual.i16}, "SQLSTATE 42601"}, {"SYNTAX ERROR", []interface{}{}, []interface{}{&actual.i16}, "SQLSTATE 42601"},
{"select $1::text", []interface{}{"Jack"}, []interface{}{&actual.i16}, "Cannot decode oid 25 into int16"}, {"select $1::text", []interface{}{"Jack"}, []interface{}{&actual.i16}, "Cannot decode oid 25 into any integer type"},
{"select $1::point", []interface{}{int(705)}, []interface{}{&actual.s}, "cannot encode uint64 into oid 600"}, {"select $1::point", []interface{}{int(705)}, []interface{}{&actual.s}, "cannot encode int8 into oid 600"},
{"select 42::int4", []interface{}{}, []interface{}{&actual.i}, "Scan cannot decode into *int"},
} }
for i, tt := range tests { for i, tt := range tests {

243
values.go
View File

@ -53,6 +53,10 @@ const (
BinaryFormatCode = 1 BinaryFormatCode = 1
) )
const maxUint = ^uint(0)
const maxInt = int(maxUint >> 1)
const minInt = -maxInt - 1
// DefaultTypeFormats maps type names to their default requested format (text // DefaultTypeFormats maps type names to their default requested format (text
// or binary). In theory the Scanner interface should be the one to determine // or binary). In theory the Scanner interface should be the one to determine
// the format of the returned values. However, the query has already been // the format of the returned values. However, the query has already been
@ -623,6 +627,10 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
return encodeBool(wbuf, oid, arg) return encodeBool(wbuf, oid, arg)
case []bool: case []bool:
return encodeBoolSlice(wbuf, oid, arg) return encodeBoolSlice(wbuf, oid, arg)
case int:
return encodeInt(wbuf, oid, arg)
case uint:
return encodeUInt(wbuf, oid, arg)
case int8: case int8:
return encodeInt8(wbuf, oid, arg) return encodeInt8(wbuf, oid, arg)
case uint8: case uint8:
@ -651,8 +659,6 @@ func Encode(wbuf *WriteBuf, oid Oid, arg interface{}) error {
return encodeUInt64(wbuf, oid, arg) return encodeUInt64(wbuf, oid, arg)
case []uint64: case []uint64:
return encodeUInt64Slice(wbuf, oid, arg) return encodeUInt64Slice(wbuf, oid, arg)
case int:
return encodeInt(wbuf, oid, arg)
case float32: case float32:
return encodeFloat32(wbuf, oid, arg) return encodeFloat32(wbuf, oid, arg)
case []float32: case []float32:
@ -687,54 +693,84 @@ func Decode(vr *ValueReader, d interface{}) error {
switch v := d.(type) { switch v := d.(type) {
case *bool: case *bool:
*v = decodeBool(vr) *v = decodeBool(vr)
case *int64: case *int:
*v = decodeInt8(vr) n := decodeInt(vr)
if n < int64(minInt) {
return fmt.Errorf("%d is less than minimum value for int", n)
} else if n > int64(maxInt) {
return fmt.Errorf("%d is greater than maximum value for int", n)
}
*v = int(n)
case *int8:
n := decodeInt(vr)
if n < math.MinInt8 {
return fmt.Errorf("%d is less than minimum value for int8", n)
} else if n > math.MaxInt8 {
return fmt.Errorf("%d is greater than maximum value for int8", n)
}
*v = int8(n)
case *int16: case *int16:
*v = decodeInt2(vr) n := decodeInt(vr)
if n < math.MinInt16 {
return fmt.Errorf("%d is less than minimum value for int16", n)
} else if n > math.MaxInt16 {
return fmt.Errorf("%d is greater than maximum value for int16", n)
}
*v = int16(n)
case *int32: case *int32:
*v = decodeInt4(vr) n := decodeInt(vr)
if n < math.MinInt32 {
return fmt.Errorf("%d is less than minimum value for int32", n)
} else if n > math.MaxInt32 {
return fmt.Errorf("%d is greater than maximum value for int32", n)
}
*v = int32(n)
case *int64:
n := decodeInt(vr)
if n < math.MinInt64 {
return fmt.Errorf("%d is less than minimum value for int64", n)
} else if n > math.MaxInt64 {
return fmt.Errorf("%d is greater than maximum value for int64", n)
}
*v = int64(n)
case *uint:
n := decodeInt(vr)
if n < 0 {
return fmt.Errorf("%d is less than zero for uint8", n)
} else if maxInt == math.MaxInt32 && n > math.MaxUint32 {
return fmt.Errorf("%d is greater than maximum value for uint", n)
}
*v = uint(n)
case *uint8:
n := decodeInt(vr)
if n < 0 {
return fmt.Errorf("%d is less than zero for uint8", n)
} else if n > math.MaxUint8 {
return fmt.Errorf("%d is greater than maximum value for uint8", n)
}
*v = uint8(n)
case *uint16: case *uint16:
var valInt int16 n := decodeInt(vr)
switch vr.Type().DataType { if n < 0 {
case Int2Oid: return fmt.Errorf("%d is less than zero for uint16", n)
valInt = int16(decodeInt2(vr)) } else if n > math.MaxUint16 {
default: return fmt.Errorf("%d is greater than maximum value for uint16", n)
return fmt.Errorf("Can't convert OID %v to uint16", vr.Type().DataType)
} }
if valInt < 0 { *v = uint16(n)
return fmt.Errorf("%d is less than zero for uint16", valInt)
}
*v = uint16(valInt)
case *uint32: case *uint32:
var valInt int32 n := decodeInt(vr)
switch vr.Type().DataType { if n < 0 {
case Int2Oid: return fmt.Errorf("%d is less than zero for uint32", n)
valInt = int32(decodeInt2(vr)) } else if n > math.MaxUint32 {
case Int4Oid: return fmt.Errorf("%d is greater than maximum value for uint32", n)
valInt = decodeInt4(vr)
default:
return fmt.Errorf("Can't convert OID %v to uint32", vr.Type().DataType)
} }
if valInt < 0 { *v = uint32(n)
return fmt.Errorf("%d is less than zero for uint32", valInt)
}
*v = uint32(valInt)
case *uint64: case *uint64:
var valInt int64 n := decodeInt(vr)
switch vr.Type().DataType { if n < 0 {
case Int2Oid: return fmt.Errorf("%d is less than zero for uint64", n)
valInt = int64(decodeInt2(vr))
case Int4Oid:
valInt = int64(decodeInt4(vr))
case Int8Oid:
valInt = decodeInt8(vr)
default:
return fmt.Errorf("Can't convert OID %v to uint64", vr.Type().DataType)
} }
if valInt < 0 { *v = uint64(n)
return fmt.Errorf("%d is less than zero for uint64", valInt)
}
*v = uint64(valInt)
case *Oid: case *Oid:
*v = decodeOid(vr) *v = decodeOid(vr)
case *string: case *string:
@ -865,6 +901,20 @@ func encodeBool(w *WriteBuf, oid Oid, value bool) error {
return nil return nil
} }
func decodeInt(vr *ValueReader) int64 {
switch vr.Type().DataType {
case Int2Oid:
return int64(decodeInt2(vr))
case Int4Oid:
return int64(decodeInt4(vr))
case Int8Oid:
return int64(decodeInt8(vr))
}
vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into any integer type", vr.Type().DataType)))
return 0
}
func decodeInt8(vr *ValueReader) int64 { func decodeInt8(vr *ValueReader) int64 {
if vr.Len() == -1 { if vr.Len() == -1 {
vr.Fatal(ProtocolError("Cannot decode null into int64")) vr.Fatal(ProtocolError("Cannot decode null into int64"))
@ -913,6 +963,61 @@ func decodeInt2(vr *ValueReader) int16 {
return vr.ReadInt16() return vr.ReadInt16()
} }
func encodeInt(w *WriteBuf, oid Oid, value int) error {
switch oid {
case Int2Oid:
if value < math.MinInt16 {
return fmt.Errorf("%d is less than min pg:int2", value)
} else if value > math.MaxInt16 {
return fmt.Errorf("%d is greater than max pg:int2", value)
}
w.WriteInt32(2)
w.WriteInt16(int16(value))
case Int4Oid:
if value < math.MinInt32 {
return fmt.Errorf("%d is less than min pg:int4", value)
} else if value > math.MaxInt32 {
return fmt.Errorf("%d is greater than max pg:int4", value)
}
w.WriteInt32(4)
w.WriteInt32(int32(value))
case Int8Oid:
w.WriteInt32(8)
w.WriteInt64(int64(value))
default:
return fmt.Errorf("cannot encode %s into oid %v", "int8", oid)
}
return nil
}
func encodeUInt(w *WriteBuf, oid Oid, value uint) error {
switch oid {
case Int2Oid:
if value > math.MaxInt16 {
return fmt.Errorf("%d is greater than max pg:int2", value)
}
w.WriteInt32(2)
w.WriteInt16(int16(value))
case Int4Oid:
if value > math.MaxInt32 {
return fmt.Errorf("%d is greater than max pg:int4", value)
}
w.WriteInt32(4)
w.WriteInt32(int32(value))
case Int8Oid:
if value > math.MaxInt64 {
return fmt.Errorf("%d is greater than max pg:int8", value)
}
w.WriteInt32(8)
w.WriteInt64(int64(value))
default:
return fmt.Errorf("cannot encode %s into oid %v", "uint8", oid)
}
return nil
}
func encodeInt8(w *WriteBuf, oid Oid, value int8) error { func encodeInt8(w *WriteBuf, oid Oid, value int8) error {
switch oid { switch oid {
case Int2Oid: case Int2Oid:
@ -974,7 +1079,7 @@ func encodeUInt16(w *WriteBuf, oid Oid, value uint16) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(value)) w.WriteInt16(int16(value))
} else { } else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16) return fmt.Errorf("%d is greater than max int16 %d", value, math.MaxInt16)
} }
case Int4Oid: case Int4Oid:
w.WriteInt32(4) w.WriteInt32(4)
@ -996,7 +1101,7 @@ func encodeInt32(w *WriteBuf, oid Oid, value int32) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(value)) w.WriteInt16(int16(value))
} else { } else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16) return fmt.Errorf("%d is greater than max int16 %d", value, math.MaxInt16)
} }
case Int4Oid: case Int4Oid:
w.WriteInt32(4) w.WriteInt32(4)
@ -1018,14 +1123,14 @@ func encodeUInt32(w *WriteBuf, oid Oid, value uint32) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(value)) w.WriteInt16(int16(value))
} else { } else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16) return fmt.Errorf("%d is greater than max int16 %d", value, math.MaxInt16)
} }
case Int4Oid: case Int4Oid:
if value <= math.MaxInt32 { if value <= math.MaxInt32 {
w.WriteInt32(4) w.WriteInt32(4)
w.WriteInt32(int32(value)) w.WriteInt32(int32(value))
} else { } else {
return fmt.Errorf("%d is larger than max int32 %d", value, math.MaxInt32) return fmt.Errorf("%d is greater than max int32 %d", value, math.MaxInt32)
} }
case Int8Oid: case Int8Oid:
w.WriteInt32(8) w.WriteInt32(8)
@ -1044,14 +1149,14 @@ func encodeInt64(w *WriteBuf, oid Oid, value int64) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(value)) w.WriteInt16(int16(value))
} else { } else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16) return fmt.Errorf("%d is greater than max int16 %d", value, math.MaxInt16)
} }
case Int4Oid: case Int4Oid:
if value <= math.MaxInt32 { if value <= math.MaxInt32 {
w.WriteInt32(4) w.WriteInt32(4)
w.WriteInt32(int32(value)) w.WriteInt32(int32(value))
} else { } else {
return fmt.Errorf("%d is larger than max int32 %d", value, math.MaxInt32) return fmt.Errorf("%d is greater than max int32 %d", value, math.MaxInt32)
} }
case Int8Oid: case Int8Oid:
w.WriteInt32(8) w.WriteInt32(8)
@ -1070,14 +1175,14 @@ func encodeUInt64(w *WriteBuf, oid Oid, value uint64) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(value)) w.WriteInt16(int16(value))
} else { } else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16) return fmt.Errorf("%d is greater than max int16 %d", value, math.MaxInt16)
} }
case Int4Oid: case Int4Oid:
if value <= math.MaxInt32 { if value <= math.MaxInt32 {
w.WriteInt32(4) w.WriteInt32(4)
w.WriteInt32(int32(value)) w.WriteInt32(int32(value))
} else { } else {
return fmt.Errorf("%d is larger than max int32 %d", value, math.MaxInt32) return fmt.Errorf("%d is greater than max int32 %d", value, math.MaxInt32)
} }
case Int8Oid: case Int8Oid:
@ -1085,37 +1190,7 @@ func encodeUInt64(w *WriteBuf, oid Oid, value uint64) error {
w.WriteInt32(8) w.WriteInt32(8)
w.WriteInt64(int64(value)) w.WriteInt64(int64(value))
} else { } else {
return fmt.Errorf("%d is larger than max int64 %d", value, int64(math.MaxInt64)) return fmt.Errorf("%d is greater than max int64 %d", value, int64(math.MaxInt64))
}
default:
return fmt.Errorf("cannot encode %s into oid %v", "uint64", oid)
}
return nil
}
func encodeInt(w *WriteBuf, oid Oid, value int) error {
switch oid {
case Int2Oid:
if value <= math.MaxInt16 {
w.WriteInt32(2)
w.WriteInt16(int16(value))
} else {
return fmt.Errorf("%d is larger than max int16 %d", value, math.MaxInt16)
}
case Int4Oid:
if value <= math.MaxInt32 {
w.WriteInt32(4)
w.WriteInt32(int32(value))
} else {
return fmt.Errorf("%d is larger than max int32 %d", value, math.MaxInt32)
}
case Int8Oid:
if int64(value) <= int64(math.MaxInt64) {
w.WriteInt32(8)
w.WriteInt64(int64(value))
} else {
return fmt.Errorf("%d is larger than max int64 %d", value, int64(math.MaxInt64))
} }
default: default:
return fmt.Errorf("cannot encode %s into oid %v", "uint64", oid) return fmt.Errorf("cannot encode %s into oid %v", "uint64", oid)
@ -1716,7 +1791,7 @@ func encodeUInt16Slice(w *WriteBuf, oid Oid, slice []uint16) error {
w.WriteInt32(2) w.WriteInt32(2)
w.WriteInt16(int16(v)) w.WriteInt16(int16(v))
} else { } else {
return fmt.Errorf("%d is larger than max smallint %d", v, math.MaxInt16) return fmt.Errorf("%d is greater than max smallint %d", v, math.MaxInt16)
} }
} }
@ -1831,7 +1906,7 @@ func encodeUInt32Slice(w *WriteBuf, oid Oid, slice []uint32) error {
w.WriteInt32(4) w.WriteInt32(4)
w.WriteInt32(int32(v)) w.WriteInt32(int32(v))
} else { } else {
return fmt.Errorf("%d is larger than max integer %d", v, math.MaxInt32) return fmt.Errorf("%d is greater than max integer %d", v, math.MaxInt32)
} }
} }
@ -1946,7 +2021,7 @@ func encodeUInt64Slice(w *WriteBuf, oid Oid, slice []uint64) error {
w.WriteInt32(8) w.WriteInt32(8)
w.WriteInt64(int64(v)) w.WriteInt64(int64(v))
} else { } else {
return fmt.Errorf("%d is larger than max bigint %d", v, int64(math.MaxInt64)) return fmt.Errorf("%d is greater than max bigint %d", v, int64(math.MaxInt64))
} }
} }