MCPcopy Create free account
hub / github.com/dolthub/doltgresql / serializeArray

Function serializeArray

server/types/array.go:97–137  ·  view source on GitHub ↗

deserializeArray serializes an array of given base type.

(ctx *sql.Context, vals []any, baseType *DoltgresType)

Source from the content-addressed store, hash-verified

95
96// deserializeArray serializes an array of given base type.
97func serializeArray(ctx *sql.Context, vals []any, baseType *DoltgresType) ([]byte, error) {
98 bb := bytes.Buffer{}
99 // Write the element count to a buffer. We're using an array since it's stack-allocated, so no need for pooling.
100 var elementCount [4]byte
101 binary.LittleEndian.PutUint32(elementCount[:], uint32(len(vals)))
102 bb.Write(elementCount[:])
103 // Create an array that contains the offsets for each value. Since we can't update the offset portion of the buffer
104 // as we determine the offsets, we have to track them outside the buffer. We'll overwrite the buffer later with the
105 // correct offsets. The last offset represents the end of the slice, which simplifies the logic for reading elements
106 // using the "current offset to next offset" strategy. We use a byte slice since the buffer only works with byte
107 // slices.
108 offsets := make([]byte, (len(vals)+1)*4)
109 bb.Write(offsets)
110 // The starting offset for the first element is Count(uint32) + (NumberOfElementOffsets * sizeof(uint32))
111 currentOffset := uint32(4 + (len(vals)+1)*4)
112 for i := range vals {
113 // Write the current offset
114 binary.LittleEndian.PutUint32(offsets[i*4:], currentOffset)
115 // Handle serialization of the value
116 // TODO: ARRAYs may be multidimensional, such as ARRAY[[4,2],[6,3]], which isn't accounted for here
117 serializedVal, err := baseType.SerializeValue(ctx, vals[i])
118 if err != nil {
119 return nil, err
120 }
121 // Handle the nil case and non-nil case
122 if serializedVal == nil {
123 bb.WriteByte(1)
124 currentOffset += 1
125 } else {
126 bb.WriteByte(0)
127 bb.Write(serializedVal)
128 currentOffset += 1 + uint32(len(serializedVal))
129 }
130 }
131 // Write the final offset, which will equal the length of the serialized slice
132 binary.LittleEndian.PutUint32(offsets[len(offsets)-4:], currentOffset)
133 // Get the final output, and write the updated offsets to it
134 outputBytes := bb.Bytes()
135 copy(outputBytes[4:], offsets)
136 return outputBytes, nil
137}
138
139// deserializeArray deserializes an array of given base type.
140func deserializeArray(ctx *sql.Context, data []byte, baseType *DoltgresType) ([]any, error) {

Callers 3

serializeTypeArrayFunction · 0.85
serializeTypeInt16VectorFunction · 0.85
serializeTypeOidvectorFunction · 0.85

Calls 3

SerializeValueMethod · 0.80
BytesMethod · 0.80
WriteMethod · 0.45

Tested by

no test coverage detected