Skip to content

Commit 343643a

Browse files
authored
Merge pull request #26 from goccy/fix-timestamp-return-value
Fix timestamp return value format
2 parents d252389 + 10b7c72 commit 343643a

File tree

4 files changed

+338
-247
lines changed

4 files changed

+338
-247
lines changed

internal/rows.go

+164-121
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"database/sql"
55
"database/sql/driver"
6+
"fmt"
67
"io"
78
"reflect"
89
"time"
@@ -67,163 +68,205 @@ func (r *Rows) Next(dest []driver.Value) error {
6768
values = append(values, &v)
6869
}
6970
retErr := r.rows.Scan(values...)
71+
destV := reflect.ValueOf(dest)
7072
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 {
7476
return err
7577
}
76-
dest[idx] = value
7778
}
7879
return retErr
7980
}
8081

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
8486
}
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()
8895
if err != nil {
89-
return nil, err
96+
return err
9097
}
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()
94101
if err != nil {
95-
return nil, err
102+
return err
96103
}
97-
array, err := val.ToArray()
104+
dst.Set(reflect.ValueOf(int8(i64)))
105+
case reflect.Int16:
106+
i64, err := value.ToInt64()
98107
if err != nil {
99-
return nil, err
108+
return err
100109
}
101-
elementType, err := typ.ElementType.ToZetaSQLType()
110+
dst.Set(reflect.ValueOf(int16(i64)))
111+
case reflect.Int32:
112+
i64, err := value.ToInt64()
102113
if err != nil {
103-
return nil, err
114+
return err
104115
}
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
182121
}
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()
185195
if err != nil {
186-
return nil, err
196+
return err
187197
}
188-
s, err := val.ToStruct()
198+
dst.Set(reflect.ValueOf(b))
199+
case types.FLOAT, types.DOUBLE:
200+
f64, err := src.ToFloat64()
189201
if err != nil {
190-
return nil, err
202+
return err
191203
}
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))
193211
case types.DATE:
194-
val, err := ValueOf(value)
212+
date, err := src.ToJSON()
195213
if err != nil {
196-
return nil, err
214+
return err
197215
}
198-
return val.ToJSON()
216+
dst.Set(reflect.ValueOf(date))
199217
case types.DATETIME:
200-
val, err := ValueOf(value)
218+
datetime, err := src.ToJSON()
201219
if err != nil {
202-
return nil, err
220+
return err
203221
}
204-
return val.ToJSON()
222+
dst.Set(reflect.ValueOf(datetime))
205223
case types.TIME:
206-
val, err := ValueOf(value)
224+
time, err := src.ToJSON()
207225
if err != nil {
208-
return nil, err
226+
return err
209227
}
210-
return val.ToJSON()
228+
dst.Set(reflect.ValueOf(time))
211229
case types.TIMESTAMP:
212-
val, err := ValueOf(value)
230+
t, err := src.ToTime()
213231
if err != nil {
214-
return nil, err
232+
return err
215233
}
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()
217240
if err != nil {
218-
return nil, err
241+
return err
219242
}
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()
223252
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()))
225268
}
226-
return val.ToJSON()
269+
dst.Set(sliceRef.Elem())
227270
}
228-
return value, nil
271+
return nil
229272
}

internal/spec.go

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"context"
55
"fmt"
6+
"reflect"
67
"strings"
78

89
ast "github.com/goccy/go-zetasql/resolved_ast"
@@ -106,6 +107,28 @@ func (t *Type) IsStruct() bool {
106107
return t.Kind == types.STRUCT
107108
}
108109

110+
func (t *Type) GoReflectType() (reflect.Type, error) {
111+
switch t.Kind {
112+
case types.INT32, types.INT64, types.UINT32, types.UINT64:
113+
return reflect.TypeOf(int64(0)), nil
114+
case types.BOOL:
115+
return reflect.TypeOf(false), nil
116+
case types.FLOAT, types.DOUBLE:
117+
return reflect.TypeOf(float64(0)), nil
118+
case types.BYTES, types.STRING, types.DATE, types.DATETIME, types.TIME, types.TIMESTAMP, types.JSON:
119+
return reflect.TypeOf(""), nil
120+
case types.ARRAY:
121+
elem, err := t.ElementType.GoReflectType()
122+
if err != nil {
123+
return nil, err
124+
}
125+
return reflect.SliceOf(elem), nil
126+
case types.STRUCT:
127+
return reflect.TypeOf(map[string]interface{}{}), nil
128+
}
129+
return nil, fmt.Errorf("cannot convert %s to reflect.Type", t.Name)
130+
}
131+
109132
func (t *Type) ToZetaSQLType() (types.Type, error) {
110133
switch types.TypeKind(t.Kind) {
111134
case types.ARRAY:

0 commit comments

Comments
 (0)