1 package pq
2
3 import (
4 "math"
5 "reflect"
6 "testing"
7
8 "github.com/lib/pq/oid"
9 )
10
11 func TestDataTypeName(t *testing.T) {
12 tts := []struct {
13 typ oid.Oid
14 name string
15 }{
16 {oid.T_int8, "INT8"},
17 {oid.T_int4, "INT4"},
18 {oid.T_int2, "INT2"},
19 {oid.T_varchar, "VARCHAR"},
20 {oid.T_text, "TEXT"},
21 {oid.T_bool, "BOOL"},
22 {oid.T_numeric, "NUMERIC"},
23 {oid.T_date, "DATE"},
24 {oid.T_time, "TIME"},
25 {oid.T_timetz, "TIMETZ"},
26 {oid.T_timestamp, "TIMESTAMP"},
27 {oid.T_timestamptz, "TIMESTAMPTZ"},
28 {oid.T_bytea, "BYTEA"},
29 }
30
31 for i, tt := range tts {
32 dt := fieldDesc{OID: tt.typ}
33 if name := dt.Name(); name != tt.name {
34 t.Errorf("(%d) got: %s want: %s", i, name, tt.name)
35 }
36 }
37 }
38
39 func TestDataType(t *testing.T) {
40 tts := []struct {
41 typ oid.Oid
42 kind reflect.Kind
43 }{
44 {oid.T_int8, reflect.Int64},
45 {oid.T_int4, reflect.Int32},
46 {oid.T_int2, reflect.Int16},
47 {oid.T_varchar, reflect.String},
48 {oid.T_text, reflect.String},
49 {oid.T_bool, reflect.Bool},
50 {oid.T_date, reflect.Struct},
51 {oid.T_time, reflect.Struct},
52 {oid.T_timetz, reflect.Struct},
53 {oid.T_timestamp, reflect.Struct},
54 {oid.T_timestamptz, reflect.Struct},
55 {oid.T_bytea, reflect.Slice},
56 }
57
58 for i, tt := range tts {
59 dt := fieldDesc{OID: tt.typ}
60 if kind := dt.Type().Kind(); kind != tt.kind {
61 t.Errorf("(%d) got: %s want: %s", i, kind, tt.kind)
62 }
63 }
64 }
65
66 func TestDataTypeLength(t *testing.T) {
67 tts := []struct {
68 typ oid.Oid
69 len int
70 mod int
71 length int64
72 ok bool
73 }{
74 {oid.T_int4, 0, -1, 0, false},
75 {oid.T_varchar, 65535, 9, 5, true},
76 {oid.T_text, 65535, -1, math.MaxInt64, true},
77 {oid.T_bytea, 65535, -1, math.MaxInt64, true},
78 }
79
80 for i, tt := range tts {
81 dt := fieldDesc{OID: tt.typ, Len: tt.len, Mod: tt.mod}
82 if l, k := dt.Length(); k != tt.ok || l != tt.length {
83 t.Errorf("(%d) got: %d, %t want: %d, %t", i, l, k, tt.length, tt.ok)
84 }
85 }
86 }
87
88 func TestDataTypePrecisionScale(t *testing.T) {
89 tts := []struct {
90 typ oid.Oid
91 mod int
92 precision, scale int64
93 ok bool
94 }{
95 {oid.T_int4, -1, 0, 0, false},
96 {oid.T_numeric, 589830, 9, 2, true},
97 {oid.T_text, -1, 0, 0, false},
98 }
99
100 for i, tt := range tts {
101 dt := fieldDesc{OID: tt.typ, Mod: tt.mod}
102 p, s, k := dt.PrecisionScale()
103 if k != tt.ok {
104 t.Errorf("(%d) got: %t want: %t", i, k, tt.ok)
105 }
106 if p != tt.precision {
107 t.Errorf("(%d) wrong precision got: %d want: %d", i, p, tt.precision)
108 }
109 if s != tt.scale {
110 t.Errorf("(%d) wrong scale got: %d want: %d", i, s, tt.scale)
111 }
112 }
113 }
114
115 func TestRowsColumnTypes(t *testing.T) {
116 columnTypesTests := []struct {
117 Name string
118 TypeName string
119 Length struct {
120 Len int64
121 OK bool
122 }
123 DecimalSize struct {
124 Precision int64
125 Scale int64
126 OK bool
127 }
128 ScanType reflect.Type
129 }{
130 {
131 Name: "a",
132 TypeName: "INT4",
133 Length: struct {
134 Len int64
135 OK bool
136 }{
137 Len: 0,
138 OK: false,
139 },
140 DecimalSize: struct {
141 Precision int64
142 Scale int64
143 OK bool
144 }{
145 Precision: 0,
146 Scale: 0,
147 OK: false,
148 },
149 ScanType: reflect.TypeOf(int32(0)),
150 }, {
151 Name: "bar",
152 TypeName: "TEXT",
153 Length: struct {
154 Len int64
155 OK bool
156 }{
157 Len: math.MaxInt64,
158 OK: true,
159 },
160 DecimalSize: struct {
161 Precision int64
162 Scale int64
163 OK bool
164 }{
165 Precision: 0,
166 Scale: 0,
167 OK: false,
168 },
169 ScanType: reflect.TypeOf(""),
170 },
171 }
172
173 db := openTestConn(t)
174 defer db.Close()
175
176 rows, err := db.Query("SELECT 1 AS a, text 'bar' AS bar, 1.28::numeric(9, 2) AS dec")
177 if err != nil {
178 t.Fatal(err)
179 }
180
181 columns, err := rows.ColumnTypes()
182 if err != nil {
183 t.Fatal(err)
184 }
185 if len(columns) != 3 {
186 t.Errorf("expected 3 columns found %d", len(columns))
187 }
188
189 for i, tt := range columnTypesTests {
190 c := columns[i]
191 if c.Name() != tt.Name {
192 t.Errorf("(%d) got: %s, want: %s", i, c.Name(), tt.Name)
193 }
194 if c.DatabaseTypeName() != tt.TypeName {
195 t.Errorf("(%d) got: %s, want: %s", i, c.DatabaseTypeName(), tt.TypeName)
196 }
197 l, ok := c.Length()
198 if l != tt.Length.Len {
199 t.Errorf("(%d) got: %d, want: %d", i, l, tt.Length.Len)
200 }
201 if ok != tt.Length.OK {
202 t.Errorf("(%d) got: %t, want: %t", i, ok, tt.Length.OK)
203 }
204 p, s, ok := c.DecimalSize()
205 if p != tt.DecimalSize.Precision {
206 t.Errorf("(%d) got: %d, want: %d", i, p, tt.DecimalSize.Precision)
207 }
208 if s != tt.DecimalSize.Scale {
209 t.Errorf("(%d) got: %d, want: %d", i, s, tt.DecimalSize.Scale)
210 }
211 if ok != tt.DecimalSize.OK {
212 t.Errorf("(%d) got: %t, want: %t", i, ok, tt.DecimalSize.OK)
213 }
214 if c.ScanType() != tt.ScanType {
215 t.Errorf("(%d) got: %v, want: %v", i, c.ScanType(), tt.ScanType)
216 }
217 }
218 }
219
View as plain text