Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty datetime will fail when returning results #3169

Merged
merged 9 commits into from
Apr 11, 2019
7 changes: 6 additions & 1 deletion query/outputnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,12 @@ func valToBytes(v types.Val) ([]byte, error) {
}
return []byte("false"), nil
case types.DateTimeID:
return v.Value.(time.Time).MarshalJSON()
// Return empty string instead of zero-time value string - issue#3166
t := v.Value.(time.Time)
if t.IsZero() {
return []byte(`""`), nil
}
return t.MarshalJSON()
case types.GeoID:
return geojson.Marshal(v.Value.(geom.T))
case types.UidID:
Expand Down
7 changes: 5 additions & 2 deletions types/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,11 @@ func Convert(from Val, toID TypeID) (Val, error) {
case DateTimeID:
{
var t time.Time
if err := t.UnmarshalBinary(data); err != nil {
return to, err
// We must inverse the binary->datetime for zero-time values.
if !bytes.Equal(data, []byte("")) {
if err := t.UnmarshalBinary(data); err != nil {
return to, err
}
}
// NOTE: when converting datetime values to anything else, we must
// check for zero-time value and return the zero value of the new type.
Expand Down
30 changes: 30 additions & 0 deletions types/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,36 @@ func TestSameConversionDateTime(t *testing.T) {
}
}

func TestConversionEmpty(t *testing.T) {
tests := []struct {
in, out Val
}{
{in: Val{Tid: BinaryID, Value: []byte{}},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
{in: Val{Tid: BinaryID, Value: bs("")},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
{in: Val{Tid: DateTimeID, Value: bs(time.Time{})},
out: Val{Tid: BinaryID, Value: []byte{}}},
{in: Val{Tid: StringID, Value: bs("")},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
{in: Val{Tid: DateTimeID, Value: bs(time.Time{})},
out: Val{Tid: StringID, Value: ""}},
{in: Val{Tid: DefaultID, Value: bs("")},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
{in: Val{Tid: DateTimeID, Value: bs(time.Time{})},
out: Val{Tid: DefaultID, Value: ""}},
{in: Val{Tid: DateTimeID, Value: bs("")},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
{in: Val{Tid: DateTimeID, Value: []byte{}},
out: Val{Tid: DateTimeID, Value: time.Time{}}},
}
for _, tc := range tests {
out, err := Convert(tc.in, tc.out.Tid)
require.NoError(t, err)
require.EqualValues(t, tc.out, out)
}
}

func TestConvertToDefault(t *testing.T) {
tests := []struct {
in Val
Expand Down