Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
if err != nil {
t.Fatal(err)
}
defer db.Close()

Check failure on line 23 in exec_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `db.Close` is not checked (errcheck)
for _, test := range []struct {
name string
query string
Expand Down Expand Up @@ -152,7 +152,7 @@
if err != nil {
t.Fatal(err)
}
defer db.Close()

Check failure on line 155 in exec_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `db.Close` is not checked (errcheck)
if _, err := db.ExecContext(ctx, `
CREATE TABLE table (
id INT64,
Expand All @@ -176,17 +176,17 @@
if err != nil {
t.Fatal(err)
}
defer rows.Close()

Check failure on line 179 in exec_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `rows.Close` is not checked (errcheck)
type queryRow struct {
Value interface{}
FieldB []map[string]interface{}
FieldB map[string]interface{}
FieldY string
}
var results []*queryRow
for rows.Next() {
var (
value interface{}
fieldB []map[string]interface{}
fieldB map[string]interface{}
fieldY string
)
if err := rows.Scan(&value, &fieldB, &fieldY); err != nil {
Expand Down Expand Up @@ -217,7 +217,7 @@
if err != nil {
t.Fatal(err)
}
defer db.Close()

Check failure on line 220 in exec_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `db.Close` is not checked (errcheck)
if _, err := db.ExecContext(ctx, "CREATE TEMP TABLE tmp_table (id INT64)"); err != nil {
t.Fatal(err)
}
Expand Down
12 changes: 3 additions & 9 deletions internal/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,18 +472,12 @@
return nil, err
}
typ := t.AsStruct()
anonymousStruct := true
for _, key := range s.keys {
if key != "" {
anonymousStruct = false
}
}
if anonymousStruct {
return s, nil
}
ret := &StructValue{m: s.m}
for i := 0; i < typ.NumFields(); i++ {
key := typ.Field(i).Name()
if key == "" {
key = fmt.Sprintf("_field_%d", i+1)
}
value, exists := s.m[key]
if !exists {
ret.keys = append(ret.keys, key)
Expand Down Expand Up @@ -639,7 +633,7 @@
Body: base64.StdEncoding.EncodeToString([]byte(vv)),
}, nil
case *NumericValue:
b, err := vv.Rat.MarshalText()

Check failure on line 636 in internal/encoder.go

View workflow job for this annotation

GitHub Actions / lint

QF1008: could remove embedded field "Rat" from selector (staticcheck)
if err != nil {
return nil, err
}
Expand Down
9 changes: 9 additions & 0 deletions internal/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ func STRUCT_FIELD(v Value, idx int) (Value, error) {
if err != nil {
return nil, err
}
if sv == nil {
return nil, nil
}
if idx < 0 || idx >= len(sv.values) {
return nil, fmt.Errorf("struct field index %d out of range (struct has %d fields)", idx, len(sv.values))
}
return sv.values[idx], nil
}

Expand Down Expand Up @@ -403,6 +409,9 @@ func MAKE_STRUCT(args ...Value) (Value, error) {
if err != nil {
return nil, err
}
if k == "" {
k = fmt.Sprintf("_field_%d", i+1)
}
keys[i] = k
values[i] = value
fieldMap[k] = value
Expand Down
45 changes: 28 additions & 17 deletions internal/rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"io"
"reflect"
"time"

"github.com/goccy/go-json"
"github.com/goccy/go-zetasql/types"
Expand Down Expand Up @@ -232,74 +231,86 @@ func (r *Rows) assignInterfaceValue(src Value, dst reflect.Value, typ *Type) err
}
dst.Set(reflect.ValueOf(f64))
case types.BYTES:
s, err := src.ToString()
s, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s))
case types.STRING:
s, err := src.ToString()
s, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s))
case types.NUMERIC:
s, err := src.ToString()
s, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s))
case types.BIG_NUMERIC:
s, err := src.ToString()
s, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s))
case types.DATE:
date, err := src.ToJSON()
date, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(date))
case types.DATETIME:
datetime, err := src.ToJSON()
datetime, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(datetime))
case types.TIME:
time, err := src.ToJSON()
time, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(time))
case types.TIMESTAMP:
t, err := src.ToTime()
t, err := src.ToApiString()
if err != nil {
return err
}
unixmicro := t.UnixMicro()
sec := unixmicro / int64(time.Millisecond)
nsec := unixmicro - sec*int64(time.Millisecond)
dst.Set(reflect.ValueOf(fmt.Sprintf("%d.%d", sec, nsec)))
dst.Set(reflect.ValueOf(t))
case types.INTERVAL:
s, err := src.ToString()
s, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s))
case types.JSON:
json, err := src.ToJSON()
j, err := src.ToApiString()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(json))
dst.Set(reflect.ValueOf(j))
case types.STRUCT:
s, err := src.ToStruct()
if err != nil {
return err
}
dst.Set(reflect.ValueOf(s.Interface()))
m := make(map[string]interface{}, len(s.keys))
for i, key := range s.keys {
var child interface{}
if s.values[i] != nil {
fieldType := typ.FieldTypes[i].Type
if err := r.assignInterfaceValue(
s.values[i],
reflect.ValueOf(&child).Elem(),
fieldType,
); err != nil {
return err
}
}
m[key] = child
}
dst.Set(reflect.ValueOf(m))
case types.ARRAY:
array, err := src.ToArray()
if err != nil {
Expand Down
Loading
Loading