@@ -3,6 +3,7 @@ package internal
3
3
import (
4
4
"database/sql"
5
5
"database/sql/driver"
6
+ "fmt"
6
7
"io"
7
8
"reflect"
8
9
"time"
@@ -67,163 +68,205 @@ func (r *Rows) Next(dest []driver.Value) error {
67
68
values = append (values , & v )
68
69
}
69
70
retErr := r .rows .Scan (values ... )
71
+ destV := reflect .ValueOf (dest )
70
72
for idx , colType := range colTypes {
71
- v := reflect .ValueOf (values [idx ]).Elem ().Interface ()
72
- value , err := r . convertValue ( v , colType )
73
- if err != nil {
73
+ src := reflect .ValueOf (values [idx ]).Elem ().Interface ()
74
+ dst := destV . Index ( idx )
75
+ if err := r . assignValue ( src , dst , colType ); err != nil {
74
76
return err
75
77
}
76
- dest [idx ] = value
77
78
}
78
79
return retErr
79
80
}
80
81
81
- func (r * Rows ) convertValue (value interface {}, typ * Type ) (driver.Value , error ) {
82
- if value == nil {
83
- return nil , nil
82
+ func (r * Rows ) assignValue (src interface {}, dst reflect.Value , typ * Type ) error {
83
+ if src == nil {
84
+ dst .Set (reflect .New (dst .Type ()).Elem ())
85
+ return nil
84
86
}
85
- switch types .TypeKind (typ .Kind ) {
86
- case types .BOOL :
87
- val , err := ValueOf (value )
87
+ value , err := ValueOf (src )
88
+ if err != nil {
89
+ return err
90
+ }
91
+ kind := dst .Type ().Kind ()
92
+ switch kind {
93
+ case reflect .Int :
94
+ i64 , err := value .ToInt64 ()
88
95
if err != nil {
89
- return nil , err
96
+ return err
90
97
}
91
- return val . ToBool ( )
92
- case types . ARRAY :
93
- val , err := ValueOf ( value )
98
+ dst . Set ( reflect . ValueOf ( int ( i64 )) )
99
+ case reflect . Int8 :
100
+ i64 , err := value . ToInt64 ( )
94
101
if err != nil {
95
- return nil , err
102
+ return err
96
103
}
97
- array , err := val .ToArray ()
104
+ dst .Set (reflect .ValueOf (int8 (i64 )))
105
+ case reflect .Int16 :
106
+ i64 , err := value .ToInt64 ()
98
107
if err != nil {
99
- return nil , err
108
+ return err
100
109
}
101
- elementType , err := typ .ElementType .ToZetaSQLType ()
110
+ dst .Set (reflect .ValueOf (int16 (i64 )))
111
+ case reflect .Int32 :
112
+ i64 , err := value .ToInt64 ()
102
113
if err != nil {
103
- return nil , err
114
+ return err
104
115
}
105
- switch elementType .Kind () {
106
- case types .INT64 :
107
- v := []int64 {}
108
- for _ , value := range array .values {
109
- if value == nil {
110
- // TODO: must be add nil to result values
111
- continue
112
- }
113
- iv , err := value .ToInt64 ()
114
- if err != nil {
115
- return nil , err
116
- }
117
- v = append (v , iv )
118
- }
119
- return v , nil
120
- case types .DOUBLE :
121
- v := []float64 {}
122
- for _ , value := range array .values {
123
- fv , err := value .ToFloat64 ()
124
- if err != nil {
125
- return nil , err
126
- }
127
- v = append (v , fv )
128
- }
129
- return v , nil
130
- case types .BOOL :
131
- v := []bool {}
132
- for _ , value := range array .values {
133
- bv , err := value .ToBool ()
134
- if err != nil {
135
- return nil , err
136
- }
137
- v = append (v , bv )
138
- }
139
- return v , nil
140
- case types .STRING :
141
- v := []string {}
142
- for _ , value := range array .values {
143
- sv , err := value .ToString ()
144
- if err != nil {
145
- return nil , err
146
- }
147
- v = append (v , sv )
148
- }
149
- return v , nil
150
- case types .DATE :
151
- v := []string {}
152
- for _ , value := range array .values {
153
- date , err := value .ToJSON ()
154
- if err != nil {
155
- return nil , err
156
- }
157
- v = append (v , date )
158
- }
159
- return v , nil
160
- case types .TIMESTAMP :
161
- v := []time.Time {}
162
- for _ , value := range array .values {
163
- t , err := value .ToTime ()
164
- if err != nil {
165
- return nil , err
166
- }
167
- v = append (v , t .UTC ())
168
- }
169
- return v , nil
170
- case types .STRUCT :
171
- return array .Interface (), nil
172
- case types .JSON :
173
- v := []string {}
174
- for _ , value := range array .values {
175
- jv , err := value .ToJSON ()
176
- if err != nil {
177
- return nil , err
178
- }
179
- v = append (v , jv )
180
- }
181
- return v , nil
116
+ dst .Set (reflect .ValueOf (int32 (i64 )))
117
+ case reflect .Int64 :
118
+ i64 , err := value .ToInt64 ()
119
+ if err != nil {
120
+ return err
182
121
}
183
- case types .STRUCT :
184
- val , err := ValueOf (value )
122
+ dst .Set (reflect .ValueOf (i64 ))
123
+ case reflect .Uint :
124
+ i64 , err := value .ToInt64 ()
125
+ if err != nil {
126
+ return err
127
+ }
128
+ dst .Set (reflect .ValueOf (uint (i64 )))
129
+ case reflect .Uint8 :
130
+ i64 , err := value .ToInt64 ()
131
+ if err != nil {
132
+ return err
133
+ }
134
+ dst .Set (reflect .ValueOf (uint8 (i64 )))
135
+ case reflect .Uint16 :
136
+ i64 , err := value .ToInt64 ()
137
+ if err != nil {
138
+ return err
139
+ }
140
+ dst .Set (reflect .ValueOf (uint16 (i64 )))
141
+ case reflect .Uint32 :
142
+ i64 , err := value .ToInt64 ()
143
+ if err != nil {
144
+ return err
145
+ }
146
+ dst .Set (reflect .ValueOf (uint32 (i64 )))
147
+ case reflect .Uint64 :
148
+ i64 , err := value .ToInt64 ()
149
+ if err != nil {
150
+ return err
151
+ }
152
+ dst .Set (reflect .ValueOf (uint64 (i64 )))
153
+ case reflect .Float32 :
154
+ f64 , err := value .ToFloat64 ()
155
+ if err != nil {
156
+ return err
157
+ }
158
+ dst .Set (reflect .ValueOf (float32 (f64 )))
159
+ case reflect .Float64 :
160
+ f64 , err := value .ToFloat64 ()
161
+ if err != nil {
162
+ return err
163
+ }
164
+ dst .Set (reflect .ValueOf (f64 ))
165
+ case reflect .String :
166
+ s , err := value .ToString ()
167
+ if err != nil {
168
+ return err
169
+ }
170
+ dst .Set (reflect .ValueOf (s ))
171
+ case reflect .Bool :
172
+ b , err := value .ToBool ()
173
+ if err != nil {
174
+ return err
175
+ }
176
+ dst .Set (reflect .ValueOf (b ))
177
+ case reflect .Interface :
178
+ return r .assignInterfaceValue (value , dst , typ )
179
+ default :
180
+ return fmt .Errorf ("unexpected destination type %s for %T" , kind , value )
181
+ }
182
+ return nil
183
+ }
184
+
185
+ func (r * Rows ) assignInterfaceValue (src Value , dst reflect.Value , typ * Type ) error {
186
+ switch types .TypeKind (typ .Kind ) {
187
+ case types .INT32 , types .INT64 , types .UINT32 , types .UINT64 :
188
+ i64 , err := src .ToInt64 ()
189
+ if err != nil {
190
+ return err
191
+ }
192
+ dst .Set (reflect .ValueOf (i64 ))
193
+ case types .BOOL :
194
+ b , err := src .ToBool ()
185
195
if err != nil {
186
- return nil , err
196
+ return err
187
197
}
188
- s , err := val .ToStruct ()
198
+ dst .Set (reflect .ValueOf (b ))
199
+ case types .FLOAT , types .DOUBLE :
200
+ f64 , err := src .ToFloat64 ()
189
201
if err != nil {
190
- return nil , err
202
+ return err
191
203
}
192
- return s .Interface (), nil
204
+ dst .Set (reflect .ValueOf (f64 ))
205
+ case types .BYTES , types .STRING :
206
+ s , err := src .ToString ()
207
+ if err != nil {
208
+ return err
209
+ }
210
+ dst .Set (reflect .ValueOf (s ))
193
211
case types .DATE :
194
- val , err := ValueOf ( value )
212
+ date , err := src . ToJSON ( )
195
213
if err != nil {
196
- return nil , err
214
+ return err
197
215
}
198
- return val . ToJSON ( )
216
+ dst . Set ( reflect . ValueOf ( date ) )
199
217
case types .DATETIME :
200
- val , err := ValueOf ( value )
218
+ datetime , err := src . ToJSON ( )
201
219
if err != nil {
202
- return nil , err
220
+ return err
203
221
}
204
- return val . ToJSON ( )
222
+ dst . Set ( reflect . ValueOf ( datetime ) )
205
223
case types .TIME :
206
- val , err := ValueOf ( value )
224
+ time , err := src . ToJSON ( )
207
225
if err != nil {
208
- return nil , err
226
+ return err
209
227
}
210
- return val . ToJSON ( )
228
+ dst . Set ( reflect . ValueOf ( time ) )
211
229
case types .TIMESTAMP :
212
- val , err := ValueOf ( value )
230
+ t , err := src . ToTime ( )
213
231
if err != nil {
214
- return nil , err
232
+ return err
215
233
}
216
- t , err := val .ToTime ()
234
+ unixmicro := t .UnixMicro ()
235
+ sec := unixmicro / int64 (time .Millisecond )
236
+ nsec := unixmicro - sec * int64 (time .Millisecond )
237
+ dst .Set (reflect .ValueOf (fmt .Sprintf ("%d.%d" , sec , nsec )))
238
+ case types .JSON :
239
+ json , err := src .ToJSON ()
217
240
if err != nil {
218
- return nil , err
241
+ return err
219
242
}
220
- return t .UTC (), nil
221
- case types .JSON :
222
- val , err := ValueOf (value )
243
+ dst .Set (reflect .ValueOf (json ))
244
+ case types .STRUCT :
245
+ s , err := src .ToStruct ()
246
+ if err != nil {
247
+ return err
248
+ }
249
+ dst .Set (reflect .ValueOf (s .Interface ()))
250
+ case types .ARRAY :
251
+ array , err := src .ToArray ()
223
252
if err != nil {
224
- return nil , err
253
+ return err
254
+ }
255
+ sliceType := reflect .SliceOf (reflect .TypeOf ((* interface {})(nil )).Elem ())
256
+ sliceRef := reflect .New (sliceType )
257
+ sliceRef .Elem ().Set (reflect .MakeSlice (sliceType , 0 , len (array .values )))
258
+ for _ , v := range array .values {
259
+ refV := reflect .New (sliceType .Elem ())
260
+ if v == nil {
261
+ sliceRef .Elem ().Set (reflect .Append (sliceRef .Elem (), refV .Elem ()))
262
+ continue
263
+ }
264
+ if err := r .assignInterfaceValue (v , refV .Elem (), typ .ElementType ); err != nil {
265
+ return err
266
+ }
267
+ sliceRef .Elem ().Set (reflect .Append (sliceRef .Elem (), refV .Elem ()))
225
268
}
226
- return val . ToJSON ( )
269
+ dst . Set ( sliceRef . Elem () )
227
270
}
228
- return value , nil
271
+ return nil
229
272
}
0 commit comments