@@ -27,6 +27,7 @@ const (
|
||||
CidrArrayOid = 651
|
||||
Float4Oid = 700
|
||||
Float8Oid = 701
|
||||
UnknownOid = 705
|
||||
InetOid = 869
|
||||
BoolArrayOid = 1000
|
||||
Int2ArrayOid = 1005
|
||||
@@ -44,6 +45,7 @@ const (
|
||||
TimestampArrayOid = 1115
|
||||
TimestampTzOid = 1184
|
||||
TimestampTzArrayOid = 1185
|
||||
RecordOid = 2249
|
||||
UuidOid = 2950
|
||||
JsonbOid = 3802
|
||||
)
|
||||
@@ -91,8 +93,11 @@ func init() {
|
||||
"int4": BinaryFormatCode,
|
||||
"int8": BinaryFormatCode,
|
||||
"oid": BinaryFormatCode,
|
||||
"record": BinaryFormatCode,
|
||||
"text": BinaryFormatCode,
|
||||
"timestamp": BinaryFormatCode,
|
||||
"timestamptz": BinaryFormatCode,
|
||||
"varchar": BinaryFormatCode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,6 +812,8 @@ func Decode(vr *ValueReader, d interface{}) error {
|
||||
*v = decodeTimestampArray(vr)
|
||||
case *[][]byte:
|
||||
*v = decodeByteaArray(vr)
|
||||
case *[]interface{}:
|
||||
*v = decodeRecord(vr)
|
||||
case *time.Time:
|
||||
switch vr.Type().DataType {
|
||||
case DateOid:
|
||||
@@ -1613,6 +1620,77 @@ func encodeIP(w *WriteBuf, oid Oid, value net.IP) error {
|
||||
return encodeIPNet(w, oid, ipnet)
|
||||
}
|
||||
|
||||
func decodeRecord(vr *ValueReader) []interface{} {
|
||||
if vr.Len() == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if vr.Type().FormatCode != BinaryFormatCode {
|
||||
vr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", vr.Type().FormatCode)))
|
||||
return nil
|
||||
}
|
||||
|
||||
if vr.Type().DataType != RecordOid {
|
||||
vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into []interface{}", vr.Type().DataType)))
|
||||
return nil
|
||||
}
|
||||
|
||||
valueCount := vr.ReadInt32()
|
||||
record := make([]interface{}, 0, int(valueCount))
|
||||
|
||||
for i := int32(0); i < valueCount; i++ {
|
||||
fd := FieldDescription{FormatCode: BinaryFormatCode}
|
||||
fieldVR := ValueReader{mr: vr.mr, fd: &fd}
|
||||
fd.DataType = vr.ReadOid()
|
||||
fieldVR.valueBytesRemaining = vr.ReadInt32()
|
||||
vr.valueBytesRemaining -= fieldVR.valueBytesRemaining
|
||||
|
||||
switch fd.DataType {
|
||||
case BoolOid:
|
||||
record = append(record, decodeBool(&fieldVR))
|
||||
case ByteaOid:
|
||||
record = append(record, decodeBytea(&fieldVR))
|
||||
case Int8Oid:
|
||||
record = append(record, decodeInt8(&fieldVR))
|
||||
case Int2Oid:
|
||||
record = append(record, decodeInt2(&fieldVR))
|
||||
case Int4Oid:
|
||||
record = append(record, decodeInt4(&fieldVR))
|
||||
case OidOid:
|
||||
record = append(record, decodeOid(&fieldVR))
|
||||
case Float4Oid:
|
||||
record = append(record, decodeFloat4(&fieldVR))
|
||||
case Float8Oid:
|
||||
record = append(record, decodeFloat8(&fieldVR))
|
||||
case DateOid:
|
||||
record = append(record, decodeDate(&fieldVR))
|
||||
case TimestampTzOid:
|
||||
record = append(record, decodeTimestampTz(&fieldVR))
|
||||
case TimestampOid:
|
||||
record = append(record, decodeTimestamp(&fieldVR))
|
||||
case InetOid, CidrOid:
|
||||
record = append(record, decodeInet(&fieldVR))
|
||||
case TextOid, VarcharOid, UnknownOid:
|
||||
record = append(record, decodeText(&fieldVR))
|
||||
default:
|
||||
vr.Fatal(fmt.Errorf("decodeRecord cannot decode oid %d", fd.DataType))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Consume any remaining data
|
||||
if fieldVR.Len() > 0 {
|
||||
fieldVR.ReadBytes(fieldVR.Len())
|
||||
}
|
||||
|
||||
if fieldVR.Err() != nil {
|
||||
vr.Fatal(fieldVR.Err())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
func decode1dArrayHeader(vr *ValueReader) (length int32, err error) {
|
||||
numDims := vr.ReadInt32()
|
||||
if numDims > 1 {
|
||||
|
||||
Reference in New Issue
Block a user