2
0

Replace SelectFunc with Query as core

This commit is contained in:
Jack Christensen
2014-06-28 17:07:31 -05:00
parent 288e2a2c51
commit d30ef1b8b9
11 changed files with 727 additions and 1270 deletions
+337 -198
View File
@@ -28,18 +28,23 @@ const (
TimestampTzOid = 1184
)
const (
TextFormatCode = 0
BinaryFormatCode = 1
)
// ValueTranscoder stores all the data necessary to encode and decode values from
// a PostgreSQL server
type ValueTranscoder struct {
// DecodeText decodes values returned from the server in text format
DecodeText func(*MessageReader, int32) interface{}
// DecodeBinary decodes values returned from the server in binary format
DecodeBinary func(*MessageReader, int32) interface{}
// Decode decodes values returned from the server
Decode func(qr *QueryResult, fd *FieldDescription, size int32) interface{}
// DecodeFormat is the preferred response format.
// Allowed values: TextFormatCode, BinaryFormatCode
DecodeFormat int16
// EncodeTo encodes values to send to the server
EncodeTo func(*WriteBuf, interface{}) error
// EncodeFormat is the format values are encoded for transmission.
// 0 = text
// 1 = binary
// Allowed values: TextFormatCode, BinaryFormatCode
EncodeFormat int16
}
@@ -55,86 +60,104 @@ func init() {
// bool
ValueTranscoders[BoolOid] = &ValueTranscoder{
DecodeText: decodeBoolFromText,
DecodeBinary: decodeBoolFromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeBool(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeBool,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// bytea
ValueTranscoders[ByteaOid] = &ValueTranscoder{
DecodeText: decodeByteaFromText,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeBytea(qr, fd, size) },
DecodeFormat: TextFormatCode,
EncodeTo: encodeBytea,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// int8
ValueTranscoders[Int8Oid] = &ValueTranscoder{
DecodeText: decodeInt8FromText,
DecodeBinary: decodeInt8FromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeInt8(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeInt8,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// int2
ValueTranscoders[Int2Oid] = &ValueTranscoder{
DecodeText: decodeInt2FromText,
DecodeBinary: decodeInt2FromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeInt2(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeInt2,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// int4
ValueTranscoders[Int4Oid] = &ValueTranscoder{
DecodeText: decodeInt4FromText,
DecodeBinary: decodeInt4FromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeInt4(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeInt4,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// text
ValueTranscoders[TextOid] = &ValueTranscoder{
DecodeText: decodeTextFromText,
EncodeTo: encodeText}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeText(qr, fd, size) },
DecodeFormat: TextFormatCode,
EncodeTo: encodeText,
EncodeFormat: TextFormatCode}
// float4
ValueTranscoders[Float4Oid] = &ValueTranscoder{
DecodeText: decodeFloat4FromText,
DecodeBinary: decodeFloat4FromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeFloat4(qr, fd, size) },
EncodeTo: encodeFloat4,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// float8
ValueTranscoders[Float8Oid] = &ValueTranscoder{
DecodeText: decodeFloat8FromText,
DecodeBinary: decodeFloat8FromBinary,
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeFloat8(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeFloat8,
EncodeFormat: 1}
EncodeFormat: BinaryFormatCode}
// int2[]
ValueTranscoders[Int2ArrayOid] = &ValueTranscoder{
DecodeText: decodeInt2ArrayFromText,
EncodeTo: encodeInt2Array}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} {
return decodeInt2Array(qr, fd, size)
},
DecodeFormat: TextFormatCode,
EncodeTo: encodeInt2Array,
EncodeFormat: TextFormatCode}
// int4[]
ValueTranscoders[Int4ArrayOid] = &ValueTranscoder{
DecodeText: decodeInt4ArrayFromText,
EncodeTo: encodeInt4Array}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} {
return decodeInt4Array(qr, fd, size)
},
DecodeFormat: TextFormatCode,
EncodeTo: encodeInt4Array,
EncodeFormat: TextFormatCode}
// int8[]
ValueTranscoders[Int8ArrayOid] = &ValueTranscoder{
DecodeText: decodeInt8ArrayFromText,
EncodeTo: encodeInt8Array}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} {
return decodeInt8Array(qr, fd, size)
},
DecodeFormat: TextFormatCode,
EncodeTo: encodeInt8Array,
EncodeFormat: TextFormatCode}
// varchar -- same as text
ValueTranscoders[VarcharOid] = ValueTranscoders[Oid(25)]
// date
ValueTranscoders[DateOid] = &ValueTranscoder{
DecodeText: decodeDateFromText,
DecodeBinary: decodeDateFromBinary,
EncodeTo: encodeDate}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} { return decodeDate(qr, fd, size) },
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeDate,
EncodeFormat: TextFormatCode}
// timestamptz
ValueTranscoders[TimestampTzOid] = &ValueTranscoder{
DecodeText: decodeTimestampTzFromText,
DecodeBinary: decodeTimestampTzFromBinary,
EncodeTo: encodeTimestampTz}
Decode: func(qr *QueryResult, fd *FieldDescription, size int32) interface{} {
return decodeTimestampTz(qr, fd, size)
},
DecodeFormat: BinaryFormatCode,
EncodeTo: encodeTimestampTz,
EncodeFormat: TextFormatCode}
// use text transcoder for anything we don't understand
defaultTranscoder = ValueTranscoders[TextOid]
@@ -158,26 +181,32 @@ func SplitArrayText(text string) (elements []string) {
return
}
func decodeBoolFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
switch s {
case "t":
return true
case "f":
return false
func decodeBool(qr *QueryResult, fd *FieldDescription, size int32) bool {
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
switch s {
case "t":
return true
case "f":
return false
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid bool: %v", s)))
return false
}
case BinaryFormatCode:
if size != 1 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an bool: %d", size)))
return false
}
b := qr.mr.ReadByte()
return b != 0
default:
return ProtocolError(fmt.Sprintf("Received invalid bool: %v", s))
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return false
}
}
func decodeBoolFromBinary(mr *MessageReader, size int32) interface{} {
if size != 1 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an bool: %d", size))
}
b := mr.ReadByte()
return b != 0
}
func encodeBool(w *WriteBuf, value interface{}) error {
v, ok := value.(bool)
if !ok {
@@ -196,20 +225,31 @@ func encodeBool(w *WriteBuf, value interface{}) error {
return nil
}
func decodeInt8FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int8: %v", s))
func decodeInt8(qr *QueryResult, fd *FieldDescription, size int32) int64 {
if fd.DataType != Int8Oid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read %v but received: %v", Int8Oid, fd.DataType)))
return 0
}
return n
}
func decodeInt8FromBinary(mr *MessageReader, size int32) interface{} {
if size != 8 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an int8: %d", size))
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int8: %v", s)))
return 0
}
return n
case BinaryFormatCode:
if size != 8 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an int8: %d", size)))
return 0
}
return qr.mr.ReadInt64()
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return 0
}
return mr.ReadInt64()
}
func encodeInt8(w *WriteBuf, value interface{}) error {
@@ -246,20 +286,31 @@ func encodeInt8(w *WriteBuf, value interface{}) error {
return nil
}
func decodeInt2FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 16)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int2: %v", s))
func decodeInt2(qr *QueryResult, fd *FieldDescription, size int32) int16 {
if fd.DataType != Int2Oid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read %v but received: %v", Int2Oid, fd.DataType)))
return 0
}
return int16(n)
}
func decodeInt2FromBinary(mr *MessageReader, size int32) interface{} {
if size != 2 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an int2: %d", size))
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 16)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int2: %v", s)))
return 0
}
return int16(n)
case BinaryFormatCode:
if size != 2 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an int2: %d", size)))
return 0
}
return qr.mr.ReadInt16()
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return 0
}
return mr.ReadInt16()
}
func encodeInt2(w *WriteBuf, value interface{}) error {
@@ -311,20 +362,30 @@ func encodeInt2(w *WriteBuf, value interface{}) error {
return nil
}
func decodeInt4FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int4: %v", s))
func decodeInt4(qr *QueryResult, fd *FieldDescription, size int32) int32 {
if fd.DataType != Int4Oid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read %v but received: %v", Int4Oid, fd.DataType)))
return 0
}
return int32(n)
}
func decodeInt4FromBinary(mr *MessageReader, size int32) interface{} {
if size != 4 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an int4: %d", size))
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
n, err := strconv.ParseInt(s, 10, 32)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int4: %v", s)))
}
return int32(n)
case BinaryFormatCode:
if size != 4 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an int4: %d", size)))
return 0
}
return qr.mr.ReadInt32()
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return 0
}
return mr.ReadInt32()
}
func encodeInt4(w *WriteBuf, value interface{}) error {
@@ -370,23 +431,29 @@ func encodeInt4(w *WriteBuf, value interface{}) error {
return nil
}
func decodeFloat4FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
n, err := strconv.ParseFloat(s, 32)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid float4: %v", s))
}
return float32(n)
}
func decodeFloat4(qr *QueryResult, fd *FieldDescription, size int32) float32 {
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
n, err := strconv.ParseFloat(s, 32)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid float4: %v", s)))
return 0
}
return float32(n)
case BinaryFormatCode:
if size != 4 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an float4: %d", size)))
return 0
}
func decodeFloat4FromBinary(mr *MessageReader, size int32) interface{} {
if size != 4 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an float4: %d", size))
i := qr.mr.ReadInt32()
p := unsafe.Pointer(&i)
return *(*float32)(p)
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return 0
}
i := mr.ReadInt32()
p := unsafe.Pointer(&i)
return *(*float32)(p)
}
func encodeFloat4(w *WriteBuf, value interface{}) error {
@@ -411,23 +478,29 @@ func encodeFloat4(w *WriteBuf, value interface{}) error {
return nil
}
func decodeFloat8FromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
v, err := strconv.ParseFloat(s, 64)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid float8: %v", s))
}
return v
}
func decodeFloat8(qr *QueryResult, fd *FieldDescription, size int32) float64 {
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
v, err := strconv.ParseFloat(s, 64)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid float8: %v", s)))
return 0
}
return v
case BinaryFormatCode:
if size != 8 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an float8: %d", size)))
return 0
}
func decodeFloat8FromBinary(mr *MessageReader, size int32) interface{} {
if size != 8 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an float8: %d", size))
i := qr.mr.ReadInt64()
p := unsafe.Pointer(&i)
return *(*float64)(p)
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return 0
}
i := mr.ReadInt64()
p := unsafe.Pointer(&i)
return *(*float64)(p)
}
func encodeFloat8(w *WriteBuf, value interface{}) error {
@@ -449,8 +522,8 @@ func encodeFloat8(w *WriteBuf, value interface{}) error {
return nil
}
func decodeTextFromText(mr *MessageReader, size int32) interface{} {
return mr.ReadString(size)
func decodeText(qr *QueryResult, fd *FieldDescription, size int32) string {
return qr.mr.ReadString(size)
}
func encodeText(w *WriteBuf, value interface{}) error {
@@ -465,13 +538,20 @@ func encodeText(w *WriteBuf, value interface{}) error {
return nil
}
func decodeByteaFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
b, err := hex.DecodeString(s[2:])
if err != nil {
return ProtocolError(fmt.Sprintf("Can't decode byte array: %v - %v", err, s))
func decodeBytea(qr *QueryResult, fd *FieldDescription, size int32) []byte {
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
b, err := hex.DecodeString(s[2:])
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Can't decode byte array: %v - %v", err, s)))
return nil
}
return b
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return nil
}
return b
}
func encodeBytea(w *WriteBuf, value interface{}) error {
@@ -486,18 +566,33 @@ func encodeBytea(w *WriteBuf, value interface{}) error {
return nil
}
func decodeDateFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
t, err := time.ParseInLocation("2006-01-02", s, time.Local)
if err != nil {
return ProtocolError(fmt.Sprintf("Can't decode date: %v", s))
}
return t
}
func decodeDate(qr *QueryResult, fd *FieldDescription, size int32) time.Time {
var zeroTime time.Time
func decodeDateFromBinary(mr *MessageReader, size int32) interface{} {
dayOffset := mr.ReadInt32()
return time.Date(2000, 1, int(1+dayOffset), 0, 0, 0, 0, time.Local)
if fd.DataType != DateOid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read date but received: %v", fd.DataType)))
return zeroTime
}
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
t, err := time.ParseInLocation("2006-01-02", s, time.Local)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Can't decode date: %v", s)))
return zeroTime
}
return t
case BinaryFormatCode:
if size != 4 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an date: %d", size)))
}
dayOffset := qr.mr.ReadInt32()
return time.Date(2000, 1, int(1+dayOffset), 0, 0, 0, 0, time.Local)
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return zeroTime
}
}
func encodeDate(w *WriteBuf, value interface{}) error {
@@ -510,27 +605,35 @@ func encodeDate(w *WriteBuf, value interface{}) error {
return encodeText(w, s)
}
func decodeTimestampTzFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
t, err := time.Parse("2006-01-02 15:04:05.999999-07", s)
if err != nil {
return ProtocolError(fmt.Sprintf("Can't decode timestamptz: %v - %v", err, s))
func decodeTimestampTz(qr *QueryResult, fd *FieldDescription, size int32) time.Time {
var zeroTime time.Time
if fd.DataType != TimestampTzOid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read timestamptz but received: %v", fd.DataType)))
return zeroTime
}
return t
}
func decodeTimestampTzFromBinary(mr *MessageReader, size int32) interface{} {
if size != 8 {
return ProtocolError(fmt.Sprintf("Received an invalid size for an int8: %d", size))
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
t, err := time.Parse("2006-01-02 15:04:05.999999-07", s)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Can't decode timestamptz: %v - %v", err, s)))
return zeroTime
}
return t
case BinaryFormatCode:
if size != 8 {
qr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an timestamptz: %d", size)))
}
microsecFromUnixEpochToY2K := int64(946684800 * 1000000)
microsecSinceY2K := qr.mr.ReadInt64()
microsecSinceUnixEpoch := microsecFromUnixEpochToY2K + microsecSinceY2K
return time.Unix(microsecSinceUnixEpoch/1000000, (microsecSinceUnixEpoch%1000000)*1000)
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return zeroTime
}
microsecFromUnixEpochToY2K := int64(946684800 * 1000000)
microsecSinceY2K := mr.ReadInt64()
microsecSinceUnixEpoch := microsecFromUnixEpochToY2K + microsecSinceY2K
return time.Unix(microsecSinceUnixEpoch/1000000, (microsecSinceUnixEpoch%1000000)*1000)
// 2000-01-01 00:00:00 in 946684800
// 946684800 * 1000000
}
func encodeTimestampTz(w *WriteBuf, value interface{}) error {
@@ -543,22 +646,34 @@ func encodeTimestampTz(w *WriteBuf, value interface{}) error {
return encodeText(w, s)
}
func decodeInt2ArrayFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int16, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 16)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int2[]: %v", s))
}
numbers = append(numbers, int16(n))
func decodeInt2Array(qr *QueryResult, fd *FieldDescription, size int32) []int16 {
if fd.DataType != Int2ArrayOid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read int2[] but received: %v", fd.DataType)))
return nil
}
return numbers
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int16, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 16)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int2[]: %v", s)))
return nil
}
numbers = append(numbers, int16(n))
}
return numbers
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return nil
}
}
func int16SliceToArrayString(nums []int16) (string, error) {
@@ -604,22 +719,34 @@ func encodeInt2Array(w *WriteBuf, value interface{}) error {
return encodeText(w, s)
}
func decodeInt4ArrayFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int32, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 16)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int4[]: %v", s))
}
numbers = append(numbers, int32(n))
func decodeInt4Array(qr *QueryResult, fd *FieldDescription, size int32) []int32 {
if fd.DataType != Int4ArrayOid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read int4[] but received: %v", fd.DataType)))
return nil
}
return numbers
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int32, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 32)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int4[]: %v", s)))
return nil
}
numbers = append(numbers, int32(n))
}
return numbers
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return nil
}
}
func int32SliceToArrayString(nums []int32) (string, error) {
@@ -666,22 +793,34 @@ func encodeInt4Array(w *WriteBuf, value interface{}) error {
return encodeText(w, s)
}
func decodeInt8ArrayFromText(mr *MessageReader, size int32) interface{} {
s := mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int64, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 16)
if err != nil {
return ProtocolError(fmt.Sprintf("Received invalid int8[]: %v", s))
}
numbers = append(numbers, int64(n))
func decodeInt8Array(qr *QueryResult, fd *FieldDescription, size int32) []int64 {
if fd.DataType != Int8ArrayOid {
qr.Fatal(ProtocolError(fmt.Sprintf("Tried to read int8[] but received: %v", fd.DataType)))
return nil
}
return numbers
switch fd.FormatCode {
case TextFormatCode:
s := qr.mr.ReadString(size)
elements := SplitArrayText(s)
numbers := make([]int64, 0, len(elements))
for _, e := range elements {
n, err := strconv.ParseInt(e, 10, 64)
if err != nil {
qr.Fatal(ProtocolError(fmt.Sprintf("Received invalid int8[]: %v", s)))
return nil
}
numbers = append(numbers, int64(n))
}
return numbers
default:
qr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", fd.FormatCode)))
return nil
}
}
func int64SliceToArrayString(nums []int64) (string, error) {