Skip to content

Commit

Permalink
implementing feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroshade committed May 24, 2024
1 parent 28449df commit 29be466
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
23 changes: 13 additions & 10 deletions literals.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,7 @@ func (t TimestampLiteral) To(typ Type) (Literal, error) {
case TimestampTzType:
return t, nil
case DateType:
tm := time.UnixMicro(int64(t)).UTC()
return DateLiteral(tm.Truncate(24*time.Hour).Unix() / int64((time.Hour * 24).Seconds())), nil
return DateLiteral(Timestamp(t).ToDate()), nil
}
return nil, fmt.Errorf("%w: TimestampLiteral to %s", ErrBadCast, typ)
}
Expand Down Expand Up @@ -538,19 +537,23 @@ func (s StringLiteral) To(typ Type) (Literal, error) {

return TimeLiteral(val), nil
case TimestampType:
val, err := arrow.TimestampFromString(string(s), arrow.Microsecond)
// requires RFC3339 with no time zone
tm, err := time.Parse("2006-01-02T15:04:05", string(s))
if err != nil {
return nil, fmt.Errorf("%w: casting '%s' to %s - %s",
ErrBadCast, s, typ, err.Error())
return nil, fmt.Errorf("%w: invalid Timestamp format for casting from string '%s': %s",
ErrBadCast, s, err.Error())
}
return TimestampLiteral(val), nil

return TimestampLiteral(Timestamp(tm.UTC().UnixMicro())), nil
case TimestampTzType:
val, err := arrow.TimestampFromString(string(s), arrow.Microsecond)
// requires RFC3339 format WITH time zone
tm, err := time.Parse(time.RFC3339, string(s))
if err != nil {
return nil, fmt.Errorf("%w: casting '%s' to %s - %s",
ErrBadCast, s, typ, err.Error())
return nil, fmt.Errorf("%w: invalid TimestampTz format for casting from string '%s': %s",
ErrBadCast, s, err.Error())
}
return TimestampLiteral(val), nil

return TimestampLiteral(Timestamp(tm.UTC().UnixMicro())), nil
case UUIDType:
val, err := uuid.Parse(string(s))
if err != nil {
Expand Down
22 changes: 18 additions & 4 deletions literals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,12 +358,8 @@ func TestStringLiteralConversion(t *testing.T) {
iceberg.NewLiteral(iceberg.Date(arrow.Date32FromTime(tm)))},
{iceberg.StringLiteral("14:21:01.919"),
iceberg.NewLiteral(iceberg.Time(51661919000))},
{iceberg.StringLiteral("2017-08-18T14:21:01.919234+00:00"),
iceberg.NewLiteral(iceberg.Timestamp(1503066061919234))},
{iceberg.StringLiteral("2017-08-18T14:21:01.919234"),
iceberg.NewLiteral(iceberg.Timestamp(1503066061919234))},
{iceberg.StringLiteral("2017-08-18T14:21:01.919234-07:00"),
iceberg.NewLiteral(iceberg.Timestamp(1503091261919234))},
{iceberg.StringLiteral(expected.String()), iceberg.NewLiteral(expected)},
{iceberg.StringLiteral("34.560"),
iceberg.NewLiteral(iceberg.Decimal{Val: decimal128.FromI64(34560), Scale: 3})},
Expand All @@ -383,6 +379,24 @@ func TestStringLiteralConversion(t *testing.T) {
assert.Truef(t, tt.to.Equals(got), "expected: %s, got: %s", tt.to, got)
})
}

lit := iceberg.StringLiteral("2017-08-18T14:21:01.919234-07:00")
casted, err := lit.To(iceberg.PrimitiveTypes.TimestampTz)
require.NoError(t, err)
expectedTimestamp := iceberg.NewLiteral(iceberg.Timestamp(1503091261919234))
assert.Truef(t, casted.Equals(expectedTimestamp), "expected: %s, got: %s",
expectedTimestamp, casted)

_, err = lit.To(iceberg.PrimitiveTypes.Timestamp)
require.Error(t, err)
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, `parsing time "2017-08-18T14:21:01.919234-07:00": extra text: "-07:00"`)
assert.ErrorContains(t, err, "invalid Timestamp format for casting from string")

_, err = iceberg.StringLiteral("2017-08-18T14:21:01.919234").To(iceberg.PrimitiveTypes.TimestampTz)
require.Error(t, err)
assert.ErrorIs(t, err, iceberg.ErrBadCast)
assert.ErrorContains(t, err, `cannot parse "" as "Z07:00"`)
}

func TestLiteralIdentityConversions(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"regexp"
"strconv"
"strings"
"time"

"github.com/apache/arrow/go/v16/arrow/decimal128"
"golang.org/x/exp/slices"
Expand Down Expand Up @@ -535,6 +536,11 @@ func (TimeType) String() string { return "time" }

type Timestamp int64

func (t Timestamp) ToDate() Date {
tm := time.UnixMicro(int64(t)).UTC()
return Date(tm.Truncate(24*time.Hour).Unix() / int64((time.Hour * 24).Seconds()))
}

// TimestampType represents a number of microseconds since the unix epoch
// without regard for timezone.
type TimestampType struct{}
Expand Down

0 comments on commit 29be466

Please sign in to comment.