Skip to content

Commit

Permalink
Merge pull request #19 from gcpug/fix-int64
Browse files Browse the repository at this point in the history
Fix int64 handling
  • Loading branch information
vvakame authored Jul 19, 2019
2 parents 4f65476 + 1a3fb97 commit fbb3ad1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 14 deletions.
23 changes: 16 additions & 7 deletions json_column.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"path"
"strconv"
"time"

"cloud.google.com/go/civil"
Expand Down Expand Up @@ -36,13 +35,20 @@ func (c *JSONColumn) marshal(t *gspanner.Type, v *structpb.Value) (interface{},
// See: https://godoc.org/google.golang.org/genproto/googleapis/spanner/v1#TypeCode
switch t.Code {
case gspanner.TypeCode_INT64:
// JavaScript's integral part is 53bit. see Number.MAX_SAFE_INTEGER.
return v.GetStringValue(), nil
case gspanner.TypeCode_FLOAT64:
s := v.GetStringValue()
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return nil, err
switch s {
case "NaN", "Infinity", "-Infinity":
// NaN, Infinity, -Infinity will be null on JSON with JavaScript.
// http://www.ecma-international.org/ecma-262/10.0/index.html#sec-serializejsonproperty
return nil, nil
}
return n, nil
case gspanner.TypeCode_FLOAT64:
// golang: https://golang.org/ref/spec#Numeric_types
// float64 the set of all IEEE-754 64-bit floating-point numbers
// ECMAScript: http://www.ecma-international.org/ecma-262/10.0/index.html#sec-ecmascript-language-types-number-type
// representing the double-precision 64-bit format IEEE 754-2008 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic
return v.GetNumberValue(), nil
case gspanner.TypeCode_STRING:
return v.GetStringValue(), nil
Expand Down Expand Up @@ -99,7 +105,10 @@ func (c *JSONColumn) schema(o JSONObject, t *gspanner.Type, options ...jsonschem
switch t.Code {
default:
return fmt.Errorf("unsupport type: type:%v", t)
case gspanner.TypeCode_INT64, gspanner.TypeCode_FLOAT64:
case gspanner.TypeCode_INT64:
o.Set("type", "string")
o.Set("format", "int64")
case gspanner.TypeCode_FLOAT64:
o.Set("type", "number")
case gspanner.TypeCode_STRING:
o.Set("type", "string")
Expand Down
18 changes: 14 additions & 4 deletions json_column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,41 @@ import (

"cloud.google.com/go/spanner"
. "github.com/gcpug/hake"
structpb "github.com/golang/protobuf/ptypes/struct"
gspanner "google.golang.org/genproto/googleapis/spanner/v1"
)

func TestColumn_MarshalJSON(t *testing.T) {

type T struct {
N int
N interface{}
S string
}

type NT struct {
T T
}

floatWithString := func(s string) *spanner.GenericColumnValue {
return &spanner.GenericColumnValue{Type: &gspanner.Type{Code: gspanner.TypeCode_FLOAT64}, Value: &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: s}}}
}

cases := []struct {
name string
col *spanner.GenericColumnValue
want string
}{
{"null", column(t, nil), toJSON(t, nil)},
{"int", column(t, 100), toJSON(t, 100)},
{"int", column(t, 100), toJSON(t, "100")},
{"big int", column(t, 72057596404714278), toJSON(t, "72057596404714278")},
{"float", column(t, 10.5), toJSON(t, 10.5)},
{"float with NaN", floatWithString("NaN"), toJSON(t, nil)},
{"float with Infinity", floatWithString("Infinity"), toJSON(t, nil)},
{"float with -Infinity", floatWithString("-Infinity"), toJSON(t, nil)},
{"string", column(t, "test"), toJSON(t, "test")},
{"bool", column(t, true), toJSON(t, true)},
{"struct", column(t, T{N: 100, S: "test"}), toJSON(t, T{N: 100, S: "test"})},
{"nested struct", column(t, NT{T{N: 100, S: "test"}}), toJSON(t, NT{T{N: 100, S: "test"}})},
{"struct", column(t, T{N: 100, S: "test"}), toJSON(t, T{N: "100", S: "test"})},
{"nested struct", column(t, NT{T{N: 100, S: "test"}}), toJSON(t, NT{T{N: "100", S: "test"}})},
{"timestamp", column(t, timestamp(t, "2002-10-02T10:00:00Z")), toJSON(t, "2002-10-02T10:00:00Z")},
{"bytes", column(t, []byte("test")), toJSON(t, []byte("test"))},
}
Expand Down
6 changes: 3 additions & 3 deletions json_row_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func TestJSONRow_MarshalJSON(t *testing.T) {
}{
{"null", row(t, nil), toJSON(t, nil)},
{"empty", row(t, R{}), toJSON(t, R{})},
{"single", row(t, R{"col1", 100}), toJSON(t, R{"col1", 100})},
{"multiple", row(t, R{"col1", 100, "col2", 10.5}), toJSON(t, R{"col1", 100, "col2", 10.5})},
{"single", row(t, R{"col1", 100}), toJSON(t, R{"col1", "100"})},
{"multiple", row(t, R{"col1", 100, "col2", 10.5}), toJSON(t, R{"col1", "100", "col2", 10.5})},
}

for _, tt := range cases {
Expand All @@ -42,7 +42,7 @@ func TestRows(t *testing.T) {
}{
{"null", rows(t, nil), toJSON(t, nil)},
{"empties", rows(t, []R{{}, {}}), toJSON(t, []R{{}, {}})},
{"singles", rows(t, []R{{"col1", 100}, {"col1", 200}}), toJSON(t, []R{{"col1", 100}, {"col1", 200}})},
{"singles", rows(t, []R{{"col1", 100}, {"col1", 200}}), toJSON(t, []R{{"col1", "100"}, {"col1", "200"}})},
}

for _, tt := range cases {
Expand Down

0 comments on commit fbb3ad1

Please sign in to comment.