1 package pgtype_test
2
3 import (
4 "math"
5 "math/big"
6 "reflect"
7 "testing"
8
9 "github.com/jackc/pgtype"
10 "github.com/jackc/pgtype/testutil"
11 )
12
13 func TestNumericArrayTranscode(t *testing.T) {
14 testutil.TestSuccessfulTranscode(t, "numeric[]", []interface{}{
15 &pgtype.NumericArray{
16 Elements: nil,
17 Dimensions: nil,
18 Status: pgtype.Present,
19 },
20 &pgtype.NumericArray{
21 Elements: []pgtype.Numeric{
22 {Int: big.NewInt(1), Status: pgtype.Present},
23 {Status: pgtype.Null},
24 },
25 Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}},
26 Status: pgtype.Present,
27 },
28 &pgtype.NumericArray{Status: pgtype.Null},
29 &pgtype.NumericArray{
30 Elements: []pgtype.Numeric{
31 {Int: big.NewInt(1), Status: pgtype.Present},
32 {Int: big.NewInt(2), Status: pgtype.Present},
33 {Int: big.NewInt(3), Status: pgtype.Present},
34 {Int: big.NewInt(4), Status: pgtype.Present},
35 {Status: pgtype.Null},
36 {Int: big.NewInt(6), Status: pgtype.Present},
37 },
38 Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}},
39 Status: pgtype.Present,
40 },
41 &pgtype.NumericArray{
42 Elements: []pgtype.Numeric{
43 {Int: big.NewInt(1), Status: pgtype.Present},
44 {Int: big.NewInt(2), Status: pgtype.Present},
45 {Int: big.NewInt(3), Status: pgtype.Present},
46 {Int: big.NewInt(4), Status: pgtype.Present},
47 },
48 Dimensions: []pgtype.ArrayDimension{
49 {Length: 2, LowerBound: 4},
50 {Length: 2, LowerBound: 2},
51 },
52 Status: pgtype.Present,
53 },
54 })
55 }
56
57 func TestNumericArraySet(t *testing.T) {
58 successfulTests := []struct {
59 source interface{}
60 result pgtype.NumericArray
61 }{
62 {
63 source: []float32{1},
64 result: pgtype.NumericArray{
65 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}},
66 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
67 Status: pgtype.Present},
68 },
69 {
70 source: []float32{float32(math.Copysign(0, -1))},
71 result: pgtype.NumericArray{
72 Elements: []pgtype.Numeric{{Int: big.NewInt(0), Status: pgtype.Present}},
73 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
74 Status: pgtype.Present},
75 },
76 {
77 source: []float64{1},
78 result: pgtype.NumericArray{
79 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}},
80 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
81 Status: pgtype.Present},
82 },
83 {
84 source: []float64{math.Copysign(0, -1)},
85 result: pgtype.NumericArray{
86 Elements: []pgtype.Numeric{{Int: big.NewInt(0), Status: pgtype.Present}},
87 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
88 Status: pgtype.Present},
89 },
90 {
91 source: (([]float32)(nil)),
92 result: pgtype.NumericArray{Status: pgtype.Null},
93 },
94 {
95 source: [][]float32{{1}, {2}},
96 result: pgtype.NumericArray{
97 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
98 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
99 Status: pgtype.Present},
100 },
101 {
102 source: [][][][]float32{{{{1, 2, 3}}}, {{{4, 5, 6}}}},
103 result: pgtype.NumericArray{
104 Elements: []pgtype.Numeric{
105 {Int: big.NewInt(1), Status: pgtype.Present},
106 {Int: big.NewInt(2), Status: pgtype.Present},
107 {Int: big.NewInt(3), Status: pgtype.Present},
108 {Int: big.NewInt(4), Status: pgtype.Present},
109 {Int: big.NewInt(5), Status: pgtype.Present},
110 {Int: big.NewInt(6), Status: pgtype.Present}},
111 Dimensions: []pgtype.ArrayDimension{
112 {LowerBound: 1, Length: 2},
113 {LowerBound: 1, Length: 1},
114 {LowerBound: 1, Length: 1},
115 {LowerBound: 1, Length: 3}},
116 Status: pgtype.Present},
117 },
118 {
119 source: [2][1]float32{{1}, {2}},
120 result: pgtype.NumericArray{
121 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
122 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
123 Status: pgtype.Present},
124 },
125 {
126 source: [2][1][1][3]float32{{{{1, 2, 3}}}, {{{4, 5, 6}}}},
127 result: pgtype.NumericArray{
128 Elements: []pgtype.Numeric{
129 {Int: big.NewInt(1), Status: pgtype.Present},
130 {Int: big.NewInt(2), Status: pgtype.Present},
131 {Int: big.NewInt(3), Status: pgtype.Present},
132 {Int: big.NewInt(4), Status: pgtype.Present},
133 {Int: big.NewInt(5), Status: pgtype.Present},
134 {Int: big.NewInt(6), Status: pgtype.Present}},
135 Dimensions: []pgtype.ArrayDimension{
136 {LowerBound: 1, Length: 2},
137 {LowerBound: 1, Length: 1},
138 {LowerBound: 1, Length: 1},
139 {LowerBound: 1, Length: 3}},
140 Status: pgtype.Present},
141 },
142 }
143
144 for i, tt := range successfulTests {
145 var r pgtype.NumericArray
146 err := r.Set(tt.source)
147 if err != nil {
148 t.Errorf("%d: %v", i, err)
149 }
150
151 if !reflect.DeepEqual(r, tt.result) {
152 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
153 }
154 }
155 }
156
157 func TestNumericArrayAssignTo(t *testing.T) {
158 var float32Slice []float32
159 var float64Slice []float64
160 var float32SliceDim2 [][]float32
161 var float32SliceDim4 [][][][]float32
162 var float32ArrayDim2 [2][1]float32
163 var float32ArrayDim4 [2][1][1][3]float32
164
165 simpleTests := []struct {
166 src pgtype.NumericArray
167 dst interface{}
168 expected interface{}
169 }{
170 {
171 src: pgtype.NumericArray{
172 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}},
173 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
174 Status: pgtype.Present,
175 },
176 dst: &float32Slice,
177 expected: []float32{1},
178 },
179 {
180 src: pgtype.NumericArray{
181 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}},
182 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
183 Status: pgtype.Present,
184 },
185 dst: &float64Slice,
186 expected: []float64{1},
187 },
188 {
189 src: pgtype.NumericArray{Status: pgtype.Null},
190 dst: &float32Slice,
191 expected: (([]float32)(nil)),
192 },
193 {
194 src: pgtype.NumericArray{Status: pgtype.Present},
195 dst: &float32Slice,
196 expected: []float32{},
197 },
198 {
199 src: pgtype.NumericArray{
200 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
201 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
202 Status: pgtype.Present},
203 dst: &float32SliceDim2,
204 expected: [][]float32{{1}, {2}},
205 },
206 {
207 src: pgtype.NumericArray{
208 Elements: []pgtype.Numeric{
209 {Int: big.NewInt(1), Status: pgtype.Present},
210 {Int: big.NewInt(2), Status: pgtype.Present},
211 {Int: big.NewInt(3), Status: pgtype.Present},
212 {Int: big.NewInt(4), Status: pgtype.Present},
213 {Int: big.NewInt(5), Status: pgtype.Present},
214 {Int: big.NewInt(6), Status: pgtype.Present}},
215 Dimensions: []pgtype.ArrayDimension{
216 {LowerBound: 1, Length: 2},
217 {LowerBound: 1, Length: 1},
218 {LowerBound: 1, Length: 1},
219 {LowerBound: 1, Length: 3}},
220 Status: pgtype.Present},
221 dst: &float32SliceDim4,
222 expected: [][][][]float32{{{{1, 2, 3}}}, {{{4, 5, 6}}}},
223 },
224 {
225 src: pgtype.NumericArray{
226 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
227 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
228 Status: pgtype.Present},
229 dst: &float32ArrayDim2,
230 expected: [2][1]float32{{1}, {2}},
231 },
232 {
233 src: pgtype.NumericArray{
234 Elements: []pgtype.Numeric{
235 {Int: big.NewInt(1), Status: pgtype.Present},
236 {Int: big.NewInt(2), Status: pgtype.Present},
237 {Int: big.NewInt(3), Status: pgtype.Present},
238 {Int: big.NewInt(4), Status: pgtype.Present},
239 {Int: big.NewInt(5), Status: pgtype.Present},
240 {Int: big.NewInt(6), Status: pgtype.Present}},
241 Dimensions: []pgtype.ArrayDimension{
242 {LowerBound: 1, Length: 2},
243 {LowerBound: 1, Length: 1},
244 {LowerBound: 1, Length: 1},
245 {LowerBound: 1, Length: 3}},
246 Status: pgtype.Present},
247 dst: &float32ArrayDim4,
248 expected: [2][1][1][3]float32{{{{1, 2, 3}}}, {{{4, 5, 6}}}},
249 },
250 }
251
252 for i, tt := range simpleTests {
253 err := tt.src.AssignTo(tt.dst)
254 if err != nil {
255 t.Errorf("%d: %v", i, err)
256 }
257
258 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
259 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
260 }
261 }
262
263 errorTests := []struct {
264 src pgtype.NumericArray
265 dst interface{}
266 }{
267 {
268 src: pgtype.NumericArray{
269 Elements: []pgtype.Numeric{{Status: pgtype.Null}},
270 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
271 Status: pgtype.Present,
272 },
273 dst: &float32Slice,
274 },
275 {
276 src: pgtype.NumericArray{
277 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
278 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
279 Status: pgtype.Present},
280 dst: &float32ArrayDim2,
281 },
282 {
283 src: pgtype.NumericArray{
284 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
285 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}, {LowerBound: 1, Length: 2}},
286 Status: pgtype.Present},
287 dst: &float32Slice,
288 },
289 {
290 src: pgtype.NumericArray{
291 Elements: []pgtype.Numeric{{Int: big.NewInt(1), Status: pgtype.Present}, {Int: big.NewInt(2), Status: pgtype.Present}},
292 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
293 Status: pgtype.Present},
294 dst: &float32ArrayDim4,
295 },
296 }
297
298 for i, tt := range errorTests {
299 err := tt.src.AssignTo(tt.dst)
300 if err == nil {
301 t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
302 }
303 }
304
305 }
306
View as plain text