Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
* Added support for nullable `Date32`, `Datetime64`, `Timestamp64`, and `Interval64` types in the `optional` parameter builder
* Added corresponding functions for nullable types in value layer

## v3.115.6
* Fixed context cancellation issues in the `QueryService` stream results

Expand Down
24 changes: 24 additions & 0 deletions internal/params/optional.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,24 +119,48 @@ func (p *optional) Timestamp(v *time.Time) *optionalBuilder {
return &optionalBuilder{opt: p}
}

func (p *optional) Timestamp64(v *time.Time) *optionalBuilder {
p.value = value.NullableTimestamp64ValueFromTime(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Date(v *time.Time) *optionalBuilder {
p.value = value.NullableDateValueFromTime(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Date32(v *time.Time) *optionalBuilder {
p.value = value.NullableDate32ValueFromTime(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Datetime(v *time.Time) *optionalBuilder {
p.value = value.NullableDatetimeValueFromTime(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Datetime64(v *time.Time) *optionalBuilder {
p.value = value.NullableDatetime64ValueFromTime(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Interval(v *time.Duration) *optionalBuilder {
p.value = value.NullableIntervalValueFromDuration(v)

return &optionalBuilder{opt: p}
}

func (p *optional) Interval64(v *time.Duration) *optionalBuilder {
p.value = value.NullableInterval64ValueFromDuration(v)

return &optionalBuilder{opt: p}
}

func (p *optional) JSON(v *string) *optionalBuilder {
p.value = value.NullableJSONValue(v)

Expand Down
80 changes: 80 additions & 0 deletions internal/params/optional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,26 @@ func TestOptional(t *testing.T) {
},
},
},
{
method: "Interval64",
args: []any{p(time.Duration(123456789))},
expected: expected{
Type: &Ydb.Type{
Type: &Ydb.Type_OptionalType{
OptionalType: &Ydb.OptionalType{
Item: &Ydb.Type{
Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_INTERVAL64},
},
},
},
},
Value: &Ydb.Value{
Value: &Ydb.Value_Int64Value{
Int64Value: 123456789, // nanoseconds
},
},
},
},
{
method: "Datetime",
args: []any{p(time.Unix(123456789, 456))},
Expand All @@ -338,6 +358,26 @@ func TestOptional(t *testing.T) {
},
},
},
{
method: "Datetime64",
args: []any{p(time.Unix(123456789, 456))},
expected: expected{
Type: &Ydb.Type{
Type: &Ydb.Type_OptionalType{
OptionalType: &Ydb.OptionalType{
Item: &Ydb.Type{
Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_DATETIME64},
},
},
},
},
Value: &Ydb.Value{
Value: &Ydb.Value_Int64Value{
Int64Value: 123456789,
},
},
},
},
{
method: "Date",
args: []any{p(time.Unix(123456789, 456))},
Expand All @@ -359,6 +399,26 @@ func TestOptional(t *testing.T) {
},
},
},
{
method: "Date32",
args: []any{p(time.Unix(123456789, 456))},
expected: expected{
Type: &Ydb.Type{
Type: &Ydb.Type_OptionalType{
OptionalType: &Ydb.OptionalType{
Item: &Ydb.Type{
Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_DATE32},
},
},
},
},
Value: &Ydb.Value{
Value: &Ydb.Value_Int32Value{
Int32Value: 1428,
},
},
},
},
{
method: "Timestamp",
args: []any{p(time.Unix(123456789, 456))},
Expand All @@ -380,6 +440,26 @@ func TestOptional(t *testing.T) {
},
},
},
{
method: "Timestamp64",
args: []any{p(time.Unix(123456789, 123456000))},
expected: expected{
Type: &Ydb.Type{
Type: &Ydb.Type_OptionalType{
OptionalType: &Ydb.OptionalType{
Item: &Ydb.Type{
Type: &Ydb.Type_TypeId{TypeId: Ydb.Type_TIMESTAMP64},
},
},
},
},
Value: &Ydb.Value{
Value: &Ydb.Value_Int64Value{
Int64Value: 123456789123456, // microseconds
},
},
},
},
{
method: "Decimal",
args: []any{p([...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}), uint32(22), uint32(9)},
Expand Down
100 changes: 100 additions & 0 deletions internal/value/nullable.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ func NullableDateValueFromTime(v *time.Time) Value {
return OptionalValue(DateValueFromTime(*v))
}

func NullableDate32Value(v *int32) Value {
if v == nil {
return NullValue(types.Date32)
}

return OptionalValue(Date32Value(*v))
}

func NullableDate32ValueFromTime(v *time.Time) Value {
if v == nil {
return NullValue(types.Date32)
}

return OptionalValue(Date32ValueFromTime(*v))
}

func NullableDatetimeValue(v *uint32) Value {
if v == nil {
return NullValue(types.Datetime)
Expand All @@ -151,6 +167,22 @@ func NullableDatetimeValue(v *uint32) Value {
return OptionalValue(DatetimeValue(*v))
}

func NullableDatetime64Value(v *int64) Value {
if v == nil {
return NullValue(types.Datetime64)
}

return OptionalValue(Datetime64Value(*v))
}

func NullableDatetime64ValueFromTime(v *time.Time) Value {
if v == nil {
return NullValue(types.Datetime64)
}

return OptionalValue(Datetime64ValueFromTime(*v))
}

func NullableDatetimeValueFromTime(v *time.Time) Value {
if v == nil {
return NullValue(types.Datetime)
Expand Down Expand Up @@ -223,6 +255,22 @@ func NullableTimestampValueFromTime(v *time.Time) Value {
return OptionalValue(TimestampValueFromTime(*v))
}

func NullableTimestamp64Value(v *int64) Value {
if v == nil {
return NullValue(types.Timestamp64)
}

return OptionalValue(Timestamp64Value(*v))
}

func NullableTimestamp64ValueFromTime(v *time.Time) Value {
if v == nil {
return NullValue(types.Timestamp64)
}

return OptionalValue(Timestamp64ValueFromTime(*v))
}

func NullableTzTimestampValue(v *string) Value {
if v == nil {
return NullValue(types.TzTimestamp)
Expand Down Expand Up @@ -255,6 +303,22 @@ func NullableIntervalValueFromDuration(v *time.Duration) Value {
return OptionalValue(IntervalValueFromDuration(*v))
}

func NullableInterval64ValueFromNanoseconds(v *int64) Value {
if v == nil {
return NullValue(types.Interval64)
}

return OptionalValue(Interval64Value(*v))
}

func NullableInterval64ValueFromDuration(v *time.Duration) Value {
if v == nil {
return NullValue(types.Interval64)
}

return OptionalValue(Interval64ValueFromDuration(*v))
}

func NullableBytesValue(v *[]byte) Value {
if v == nil {
return NullValue(types.Bytes)
Expand Down Expand Up @@ -451,6 +515,15 @@ func Nullable(t types.Type, v interface{}) Value {
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeDate", tt))
}
case types.Date32:
switch tt := v.(type) {
case *int32:
return NullableDate32Value(tt)
case *time.Time:
return NullableDate32ValueFromTime(tt)
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeDate32", tt))
}
case types.Datetime:
switch tt := v.(type) {
case *uint32:
Expand All @@ -460,6 +533,15 @@ func Nullable(t types.Type, v interface{}) Value {
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeDatetime", tt))
}
case types.Datetime64:
switch tt := v.(type) {
case *int64:
return NullableDatetime64Value(tt)
case *time.Time:
return NullableDatetime64ValueFromTime(tt)
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeDatetime64", tt))
}
case types.Timestamp:
switch tt := v.(type) {
case *uint64:
Expand All @@ -469,6 +551,15 @@ func Nullable(t types.Type, v interface{}) Value {
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeTimestamp", tt))
}
case types.Timestamp64:
switch tt := v.(type) {
case *int64:
return NullableTimestamp64Value(tt)
case *time.Time:
return NullableTimestamp64ValueFromTime(tt)
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeTimestamp64", tt))
}
case types.Interval:
switch tt := v.(type) {
case *int64:
Expand All @@ -478,6 +569,15 @@ func Nullable(t types.Type, v interface{}) Value {
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeInterval", tt))
}
case types.Interval64:
switch tt := v.(type) {
case *int64:
return NullableInterval64ValueFromNanoseconds(tt)
case *time.Duration:
return NullableInterval64ValueFromDuration(tt)
default:
panic(fmt.Sprintf("unsupported type conversion from %T to TypeInterval64", tt))
}
case types.TzDate:
switch tt := v.(type) {
case *string:
Expand Down
Loading
Loading