From ec9307ebb92b3932b264993b9e0930646cc8e370 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Wed, 25 Oct 2023 23:01:02 +0200 Subject: [PATCH 01/15] Add multi range support Update descriptors. Add multirange codec. Add simple multi range test. --- internal/client/options.go | 2 +- internal/client/types_test.go | 45 +++++++ internal/codecs/codecs.go | 2 + internal/codecs/multirange.go | 185 +++++++++++++++++++++++++++ internal/descriptor/descriptor.go | 12 ++ internal/descriptor/descriptor_v2.go | 12 ++ internal/edgedbtypes/datetime.go | 4 +- 7 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 internal/codecs/multirange.go diff --git a/internal/client/options.go b/internal/client/options.go index 24131f5..be0d7da 100644 --- a/internal/client/options.go +++ b/internal/client/options.go @@ -147,7 +147,7 @@ func defaultBackoff(attempt int) time.Duration { return time.Duration(backoff+jitter) * time.Millisecond } -// RetryCondition represents scenarios that can caused a transaction +// RetryCondition represents scenarios that can cause a transaction // run in Tx() methods to be retried. type RetryCondition int diff --git a/internal/client/types_test.go b/internal/client/types_test.go index 03f651c..3603ec6 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -7806,3 +7806,48 @@ func TestSendAndReceiveRangeLocalDate(t *testing.T) { }) } } + +func serverHasMultiRange(t *testing.T) bool { + var hasMultiRange bool + err := client.QuerySingle( + context.Background(), + `SELECT count(( + SELECT names := schema::ObjectType.name + FILTER names = 'schema::MultiRange' + )) = 1`, + &hasMultiRange, + ) + require.NoError(t, err) + return hasMultiRange +} + +func TestSendAndReceiveInt32MultiRange(t *testing.T) { + if !serverHasMultiRange(t) { + t.Skip("server lacks std::MultiRange support") + } + + ctx := context.Background() + + var result []types.RangeInt32 + + multiRange := make([]types.RangeInt32, 2) + + multiRange[0] = types.NewRangeInt32( + types.NewOptionalInt32(1), + types.NewOptionalInt32(1), + true, + false, + ) + + multiRange[1] = types.NewRangeInt32( + types.NewOptionalInt32(1), + types.NewOptionalInt32(10), + true, + false, + ) + + query := "SELECT >>$0" + err := client.QuerySingle(ctx, query, &result, multiRange) + require.NoError(t, err) + assert.Equal(t, multiRange, result) +} diff --git a/internal/codecs/codecs.go b/internal/codecs/codecs.go index 7b372a4..2213972 100644 --- a/internal/codecs/codecs.go +++ b/internal/codecs/codecs.go @@ -102,6 +102,8 @@ func BuildEncoder( return buildArrayEncoder(desc, version) case descriptor.Range: return buildRangeEncoder(desc, version) + case descriptor.MultiRange: + return buildMultiRangeEncoder(desc, version) default: return nil, fmt.Errorf( "building encoder: unknown descriptor type 0x%x", diff --git a/internal/codecs/multirange.go b/internal/codecs/multirange.go new file mode 100644 index 0000000..e60a981 --- /dev/null +++ b/internal/codecs/multirange.go @@ -0,0 +1,185 @@ +// This source file is part of the EdgeDB open source project. +// +// Copyright EdgeDB Inc. and the EdgeDB authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package codecs + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/edgedb/edgedb-go/internal" + "github.com/edgedb/edgedb-go/internal/buff" + "github.com/edgedb/edgedb-go/internal/descriptor" + types "github.com/edgedb/edgedb-go/internal/edgedbtypes" +) + +func buildMultiRangeEncoder( + desc descriptor.Descriptor, + version internal.ProtocolVersion, +) (Encoder, error) { + child, err := BuildEncoder(desc.Fields[0].Desc, version) + + if err != nil { + return nil, err + } + + return &multiRangeEncoder{desc.ID, child}, nil +} + +func buildMultiRangeEncoderV2( + desc *descriptor.V2, + version internal.ProtocolVersion, +) (Encoder, error) { + child, err := BuildEncoderV2(&desc.Fields[0].Desc, version) + + if err != nil { + return nil, err + } + + return &multiRangeEncoder{desc.ID, child}, nil +} + +type multiRangeEncoder struct { + id types.UUID + child Encoder +} + +func (c *multiRangeEncoder) DescriptorID() types.UUID { return c.id } + +func (c *multiRangeEncoder) Encode( + w *buff.Writer, + val interface{}, + path Path, + required bool, // todo do we need this? +) error { + in := reflect.ValueOf(val) + if in.Kind() != reflect.Slice { + return fmt.Errorf( + "expected %v to be a slice got: %T", path, val, + ) + } + + if in.IsNil() && required { // todo do we need this? + return missingValueError(val, path) + } + + if in.IsNil() { + w.PushUint32(0xffffffff) + return nil + } + + elmCount := in.Len() + + w.BeginBytes() + w.PushUint32(uint32(elmCount)) + + var err error + for i := 0; i < elmCount; i++ { + err = c.child.Encode( + w, + in.Index(i).Interface(), + path.AddIndex(i), + true, + ) + if err != nil { + return err + } + } + + w.EndBytes() + return nil +} + +func buildMultiRangeDecoder( + desc descriptor.Descriptor, + typ reflect.Type, + path Path, +) (Decoder, error) { + if typ.Kind() != reflect.Slice { + return nil, fmt.Errorf( + "expected %v to be a Slice, got %v", path, typ.Kind(), + ) + } + + child, err := BuildDecoder(desc.Fields[0].Desc, typ.Elem(), path) + if err != nil { + return nil, err + } + + return &multiRangeDecoder{desc.ID, child, typ, calcStep(typ.Elem())}, nil +} + +func buildMultiRangeDecoderV2( + desc *descriptor.V2, + typ reflect.Type, + path Path, +) (Decoder, error) { + if typ.Kind() != reflect.Slice { + return nil, fmt.Errorf( + "expected %v to be a Slice, got %v", path, typ.Kind(), + ) + } + + child, err := BuildDecoderV2(&desc.Fields[0].Desc, typ.Elem(), path) + if err != nil { + return nil, err + } + + return &multiRangeDecoder{desc.ID, child, typ, calcStep(typ.Elem())}, nil +} + +type multiRangeDecoder struct { + id types.UUID + child Decoder + typ reflect.Type + + // step is the element width in bytes for a go array of type `MultiRange.typ`. + step int +} + +func (c *multiRangeDecoder) DescriptorID() types.UUID { return c.id } + +func (c *multiRangeDecoder) Decode(r *buff.Reader, out unsafe.Pointer) error { + upper := int32(r.PopUint32()) + n := int(upper) + + slice := (*sliceHeader)(out) + setSliceLen(slice, c.typ, n) + + for i := 0; i < n; i++ { + elmLen := r.PopUint32() + if elmLen == 0xffffffff { + continue + } + + err := c.child.Decode( + r.PopSlice(elmLen), + pAdd(slice.Data, uintptr(i*c.step)), + ) + if err != nil { + return err + } + } + return nil +} + +func (c *multiRangeDecoder) DecodeMissing(out unsafe.Pointer) { + slice := (*sliceHeader)(out) + slice.Data = nilPointer + slice.Len = 0 + slice.Cap = 0 +} diff --git a/internal/descriptor/descriptor.go b/internal/descriptor/descriptor.go index 76883c7..6f1b206 100644 --- a/internal/descriptor/descriptor.go +++ b/internal/descriptor/descriptor.go @@ -71,6 +71,9 @@ const ( // Compound represents the compound descriptor type. Compound + + // MultiRange represents the multi range descriptor type. + MultiRange ) // Descriptor is a type descriptor @@ -143,6 +146,15 @@ func Pop( desc = Descriptor{typ, id, []*Field{{ Desc: descriptors[r.PopUint16()], }}} + case MultiRange: + fields := []*Field{{ + Desc: descriptors[r.PopUint16()], + }} + err := assertArrayDimensions(r) + if err != nil { + return Descriptor{}, err + } + desc = Descriptor{typ, id, fields} default: if 0x80 <= typ && typ <= 0xff { // ignore unknown type annotations diff --git a/internal/descriptor/descriptor_v2.go b/internal/descriptor/descriptor_v2.go index 681488f..043cf49 100644 --- a/internal/descriptor/descriptor_v2.go +++ b/internal/descriptor/descriptor_v2.go @@ -140,6 +140,18 @@ func PopV2( } fields := scalarFields2pX(r, descriptorsV2, unionOperation) desc = V2{Compound, id, name, true, nil, fields} + case MultiRange: + name := r.PopString() + r.PopUint8() // schema_defined + ancestors := scalarFields2pX(r, descriptorsV2, false) + fields := []*FieldV2{{ + Desc: descriptorsV2[r.PopUint16()], + }} + err := assertArrayDimensions(r) + if err != nil { + return V2{}, err + } + desc = V2{MultiRange, id, name, true, ancestors, fields} default: if 0x80 <= typ && typ <= 0xff { // ignore unknown type annotations diff --git a/internal/edgedbtypes/datetime.go b/internal/edgedbtypes/datetime.go index 210053b..b291fb4 100644 --- a/internal/edgedbtypes/datetime.go +++ b/internal/edgedbtypes/datetime.go @@ -1156,12 +1156,12 @@ func (dd DateDuration) String() string { return strings.Join(buf, "") } -// MarshalText returns rd marshaled as text. +// MarshalText returns dd marshaled as text. func (dd DateDuration) MarshalText() ([]byte, error) { return []byte(dd.String()), nil } -// UnmarshalText unmarshals bytes into *rd. +// UnmarshalText unmarshals bytes into *dd. func (dd *DateDuration) UnmarshalText(b []byte) error { str := string(b) if !strings.HasPrefix(str, "P") { From b4f756b43d84fdab09d13be8e229f5066fb11baa Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Tue, 31 Oct 2023 21:34:18 +0100 Subject: [PATCH 02/15] Add multirange to encoder/decoder & update test --- internal/client/types_test.go | 2 +- internal/codecs/codecs.go | 6 ++++++ internal/descriptor/descriptor.go | 4 ---- internal/descriptor/descriptor_v2.go | 4 ---- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/internal/client/types_test.go b/internal/client/types_test.go index 3603ec6..d9aa776 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -7846,7 +7846,7 @@ func TestSendAndReceiveInt32MultiRange(t *testing.T) { false, ) - query := "SELECT >>$0" + query := "SELECT $0" err := client.QuerySingle(ctx, query, &result, multiRange) require.NoError(t, err) assert.Equal(t, multiRange, result) diff --git a/internal/codecs/codecs.go b/internal/codecs/codecs.go index 2213972..6752418 100644 --- a/internal/codecs/codecs.go +++ b/internal/codecs/codecs.go @@ -135,6 +135,8 @@ func BuildEncoderV2( return buildArrayEncoderV2(desc, version) case descriptor.Range: return buildRangeEncoderV2(desc, version) + case descriptor.MultiRange: + return buildMultiRangeEncoderV2(desc, version) default: return nil, fmt.Errorf( "building encoder: unknown descriptor type 0x%x", @@ -315,6 +317,8 @@ func BuildDecoder( return buildArrayDecoder(desc, typ, path) case descriptor.Range: return buildRangeDecoder(desc, typ, path) + case descriptor.MultiRange: + return buildMultiRangeDecoder(desc, typ, path) default: return nil, fmt.Errorf( "building decoder: unknown descriptor type 0x%x", @@ -347,6 +351,8 @@ func BuildDecoderV2( return buildArrayDecoderV2(desc, typ, path) case descriptor.Range: return buildRangeDecoderV2(desc, typ, path) + case descriptor.MultiRange: + return buildMultiRangeDecoderV2(desc, typ, path) default: return nil, fmt.Errorf( "building decoder: unknown descriptor type 0x%x", diff --git a/internal/descriptor/descriptor.go b/internal/descriptor/descriptor.go index 6f1b206..a2c557a 100644 --- a/internal/descriptor/descriptor.go +++ b/internal/descriptor/descriptor.go @@ -150,10 +150,6 @@ func Pop( fields := []*Field{{ Desc: descriptors[r.PopUint16()], }} - err := assertArrayDimensions(r) - if err != nil { - return Descriptor{}, err - } desc = Descriptor{typ, id, fields} default: if 0x80 <= typ && typ <= 0xff { diff --git a/internal/descriptor/descriptor_v2.go b/internal/descriptor/descriptor_v2.go index 043cf49..b5c31f8 100644 --- a/internal/descriptor/descriptor_v2.go +++ b/internal/descriptor/descriptor_v2.go @@ -147,10 +147,6 @@ func PopV2( fields := []*FieldV2{{ Desc: descriptorsV2[r.PopUint16()], }} - err := assertArrayDimensions(r) - if err != nil { - return V2{}, err - } desc = V2{MultiRange, id, name, true, ancestors, fields} default: if 0x80 <= typ && typ <= 0xff { From 3707c515981e2808da75c341e0986bcd6bfd4fbe Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 14:56:38 +0100 Subject: [PATCH 03/15] Fix multiRange encode/decode to use range encoder/decoder --- .vscode/settings.json | 4 ++++ internal/client/types_test.go | 21 +++++++++++++++--- internal/codecs/multirange.go | 33 +++++++++++++--------------- internal/descriptor/descriptor_v2.go | 7 +++++- 4 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b196e53 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.defaultFormatter": "golang.go", + "editor.formatOnSave": true +} diff --git a/internal/client/types_test.go b/internal/client/types_test.go index d9aa776..ea5f85a 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -7834,20 +7834,35 @@ func TestSendAndReceiveInt32MultiRange(t *testing.T) { multiRange[0] = types.NewRangeInt32( types.NewOptionalInt32(1), - types.NewOptionalInt32(1), + types.NewOptionalInt32(5), true, false, ) multiRange[1] = types.NewRangeInt32( - types.NewOptionalInt32(1), + types.NewOptionalInt32(8), types.NewOptionalInt32(10), true, false, ) - query := "SELECT $0" + query := "SELECT >$0" err := client.QuerySingle(ctx, query, &result, multiRange) require.NoError(t, err) assert.Equal(t, multiRange, result) } + +func TestMultiRangeContains(t *testing.T) { + if !serverHasMultiRange(t) { + t.Skip("server lacks std::MultiRange support") + } + + ctx := context.Background() + + var result bool + + query := "select contains(multirange([range(1, 5), range(8,10)]), 9)" + err := client.QuerySingle(ctx, query, &result) + require.NoError(t, err) + assert.Equal(t, true, result) +} diff --git a/internal/codecs/multirange.go b/internal/codecs/multirange.go index e60a981..fb621f4 100644 --- a/internal/codecs/multirange.go +++ b/internal/codecs/multirange.go @@ -31,7 +31,7 @@ func buildMultiRangeEncoder( desc descriptor.Descriptor, version internal.ProtocolVersion, ) (Encoder, error) { - child, err := BuildEncoder(desc.Fields[0].Desc, version) + child, err := buildRangeEncoder(desc.Fields[0].Desc, version) if err != nil { return nil, err @@ -44,7 +44,7 @@ func buildMultiRangeEncoderV2( desc *descriptor.V2, version internal.ProtocolVersion, ) (Encoder, error) { - child, err := BuildEncoderV2(&desc.Fields[0].Desc, version) + child, err := buildRangeEncoderV2(&desc.Fields[0].Desc, version) if err != nil { return nil, err @@ -64,16 +64,17 @@ func (c *multiRangeEncoder) Encode( w *buff.Writer, val interface{}, path Path, - required bool, // todo do we need this? + required bool, ) error { in := reflect.ValueOf(val) + if in.Kind() != reflect.Slice { return fmt.Errorf( "expected %v to be a slice got: %T", path, val, ) } - if in.IsNil() && required { // todo do we need this? + if in.IsNil() && required { return missingValueError(val, path) } @@ -115,7 +116,7 @@ func buildMultiRangeDecoder( ) } - child, err := BuildDecoder(desc.Fields[0].Desc, typ.Elem(), path) + child, err := buildRangeDecoder(desc.Fields[0].Desc, typ.Elem(), path) if err != nil { return nil, err } @@ -134,7 +135,8 @@ func buildMultiRangeDecoderV2( ) } - child, err := BuildDecoderV2(&desc.Fields[0].Desc, typ.Elem(), path) + child, err := buildRangeDecoderV2(&desc.Fields[0].Desc, typ.Elem(), path) + if err != nil { return nil, err } @@ -147,21 +149,21 @@ type multiRangeDecoder struct { child Decoder typ reflect.Type - // step is the element width in bytes for a go array of type `MultiRange.typ`. + // step is the element width in bytes for a go array of type `Array.typ`. step int } func (c *multiRangeDecoder) DescriptorID() types.UUID { return c.id } func (c *multiRangeDecoder) Decode(r *buff.Reader, out unsafe.Pointer) error { - upper := int32(r.PopUint32()) - n := int(upper) + elmCount := int(int32(r.PopUint32())) slice := (*sliceHeader)(out) - setSliceLen(slice, c.typ, n) + setSliceLen(slice, c.typ, elmCount) - for i := 0; i < n; i++ { + for i := 0; i < elmCount; i++ { elmLen := r.PopUint32() + if elmLen == 0xffffffff { continue } @@ -170,16 +172,11 @@ func (c *multiRangeDecoder) Decode(r *buff.Reader, out unsafe.Pointer) error { r.PopSlice(elmLen), pAdd(slice.Data, uintptr(i*c.step)), ) + if err != nil { return err } } - return nil -} -func (c *multiRangeDecoder) DecodeMissing(out unsafe.Pointer) { - slice := (*sliceHeader)(out) - slice.Data = nilPointer - slice.Len = 0 - slice.Cap = 0 + return nil } diff --git a/internal/descriptor/descriptor_v2.go b/internal/descriptor/descriptor_v2.go index b5c31f8..4157568 100644 --- a/internal/descriptor/descriptor_v2.go +++ b/internal/descriptor/descriptor_v2.go @@ -145,7 +145,12 @@ func PopV2( r.PopUint8() // schema_defined ancestors := scalarFields2pX(r, descriptorsV2, false) fields := []*FieldV2{{ - Desc: descriptorsV2[r.PopUint16()], + Desc: V2{ + Type: Range, + Fields: []*FieldV2{{ + Desc: descriptorsV2[r.PopUint16()], + }}, + }, }} desc = V2{MultiRange, id, name, true, ancestors, fields} default: From f90f21751519b74787b1701139a4b566bfcf8c51 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 16:17:45 +0100 Subject: [PATCH 04/15] Remove multirange from protocol V1 --- .gitignore | 1 + .vscode/settings.json | 4 ---- internal/codecs/codecs.go | 4 ---- internal/codecs/multirange.go | 32 ------------------------------- internal/descriptor/descriptor.go | 8 -------- 5 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index abc3b12..7678796 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ edgedb *.test +/.vscode diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index b196e53..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "editor.defaultFormatter": "golang.go", - "editor.formatOnSave": true -} diff --git a/internal/codecs/codecs.go b/internal/codecs/codecs.go index 6752418..befcd59 100644 --- a/internal/codecs/codecs.go +++ b/internal/codecs/codecs.go @@ -102,8 +102,6 @@ func BuildEncoder( return buildArrayEncoder(desc, version) case descriptor.Range: return buildRangeEncoder(desc, version) - case descriptor.MultiRange: - return buildMultiRangeEncoder(desc, version) default: return nil, fmt.Errorf( "building encoder: unknown descriptor type 0x%x", @@ -317,8 +315,6 @@ func BuildDecoder( return buildArrayDecoder(desc, typ, path) case descriptor.Range: return buildRangeDecoder(desc, typ, path) - case descriptor.MultiRange: - return buildMultiRangeDecoder(desc, typ, path) default: return nil, fmt.Errorf( "building decoder: unknown descriptor type 0x%x", diff --git a/internal/codecs/multirange.go b/internal/codecs/multirange.go index fb621f4..572fc7f 100644 --- a/internal/codecs/multirange.go +++ b/internal/codecs/multirange.go @@ -27,19 +27,6 @@ import ( types "github.com/edgedb/edgedb-go/internal/edgedbtypes" ) -func buildMultiRangeEncoder( - desc descriptor.Descriptor, - version internal.ProtocolVersion, -) (Encoder, error) { - child, err := buildRangeEncoder(desc.Fields[0].Desc, version) - - if err != nil { - return nil, err - } - - return &multiRangeEncoder{desc.ID, child}, nil -} - func buildMultiRangeEncoderV2( desc *descriptor.V2, version internal.ProtocolVersion, @@ -105,25 +92,6 @@ func (c *multiRangeEncoder) Encode( return nil } -func buildMultiRangeDecoder( - desc descriptor.Descriptor, - typ reflect.Type, - path Path, -) (Decoder, error) { - if typ.Kind() != reflect.Slice { - return nil, fmt.Errorf( - "expected %v to be a Slice, got %v", path, typ.Kind(), - ) - } - - child, err := buildRangeDecoder(desc.Fields[0].Desc, typ.Elem(), path) - if err != nil { - return nil, err - } - - return &multiRangeDecoder{desc.ID, child, typ, calcStep(typ.Elem())}, nil -} - func buildMultiRangeDecoderV2( desc *descriptor.V2, typ reflect.Type, diff --git a/internal/descriptor/descriptor.go b/internal/descriptor/descriptor.go index a2c557a..76883c7 100644 --- a/internal/descriptor/descriptor.go +++ b/internal/descriptor/descriptor.go @@ -71,9 +71,6 @@ const ( // Compound represents the compound descriptor type. Compound - - // MultiRange represents the multi range descriptor type. - MultiRange ) // Descriptor is a type descriptor @@ -146,11 +143,6 @@ func Pop( desc = Descriptor{typ, id, []*Field{{ Desc: descriptors[r.PopUint16()], }}} - case MultiRange: - fields := []*Field{{ - Desc: descriptors[r.PopUint16()], - }} - desc = Descriptor{typ, id, fields} default: if 0x80 <= typ && typ <= 0xff { // ignore unknown type annotations From dfe760e6adc46840569f1ad2024cca43dae6475c Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 20:17:28 +0100 Subject: [PATCH 05/15] Add multirange const to descriptor file --- internal/descriptor/descriptor.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/descriptor/descriptor.go b/internal/descriptor/descriptor.go index 76883c7..6e506d2 100644 --- a/internal/descriptor/descriptor.go +++ b/internal/descriptor/descriptor.go @@ -71,6 +71,9 @@ const ( // Compound represents the compound descriptor type. Compound + + // MultiRange represents the multi range descriptor type. + MultiRange ) // Descriptor is a type descriptor From 45a68c90c7cb4ff94bcf2f92a43702b978be6f99 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 20:41:15 +0100 Subject: [PATCH 06/15] Fix docs --- rstdocs/types.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rstdocs/types.rst b/rstdocs/types.rst index fa041c2..04b00d8 100644 --- a/rstdocs/types.rst +++ b/rstdocs/types.rst @@ -36,7 +36,7 @@ NewDateDuration returns a new DateDuration func (dd DateDuration) MarshalText() ([]byte, error) -MarshalText returns rd marshaled as text. +MarshalText returns dd marshaled as text. @@ -58,7 +58,7 @@ MarshalText returns rd marshaled as text. func (dd *DateDuration) UnmarshalText(b []byte) error -UnmarshalText unmarshals bytes into \*rd. +UnmarshalText unmarshals bytes into \*dd. From 08b4af86817fb41cc6d94f727c7945930b254002 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:23:32 +0100 Subject: [PATCH 07/15] Add multi range type aliases --- internal/client/types_test.go | 22 +++++++++++++++++++-- internal/edgedbtypes/multirange.go | 31 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 internal/edgedbtypes/multirange.go diff --git a/internal/client/types_test.go b/internal/client/types_test.go index 97bc2f1..2790fdc 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -6701,7 +6701,7 @@ func TestReceiveOptionalArray(t *testing.T) { }) } -func TestSendOptioanlArray(t *testing.T) { +func TestSendOptionalArray(t *testing.T) { ctx := context.Background() var result struct { Val []int64 `edgedb:"val"` @@ -7828,7 +7828,7 @@ func TestSendAndReceiveInt32MultiRange(t *testing.T) { ctx := context.Background() - var result []types.RangeInt32 + var result types.MultiRangeInt32 multiRange := make([]types.RangeInt32, 2) @@ -7852,6 +7852,24 @@ func TestSendAndReceiveInt32MultiRange(t *testing.T) { assert.Equal(t, multiRange, result) } + +func TestEmptyMultiRange(t *testing.T) { + if !serverHasMultiRange(t) { + t.Skip("server lacks std::MultiRange support") + } + + ctx := context.Background() + + var result types.MultiRangeFloat32 + + emptyMultiRange := []types.RangeFloat32{} + + query := "SELECT >$0" + err := client.QuerySingle(ctx, query, &result, emptyMultiRange) + require.NoError(t, err) + assert.Equal(t, emptyMultiRange, result) +} + func TestMultiRangeContains(t *testing.T) { if !serverHasMultiRange(t) { t.Skip("server lacks std::MultiRange support") diff --git a/internal/edgedbtypes/multirange.go b/internal/edgedbtypes/multirange.go new file mode 100644 index 0000000..314fd3a --- /dev/null +++ b/internal/edgedbtypes/multirange.go @@ -0,0 +1,31 @@ +// This source file is part of the EdgeDB open source project. +// +// Copyright EdgeDB Inc. and the EdgeDB authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package edgedbtypes + +type MultiRangeInt32 = []RangeInt32 + +type MultiRangeInt64 = []RangeInt64 + +type MultiRangeFloat32 = []RangeFloat32 + +type MultiRangeFloat64 = []RangeFloat64 + +type MultiRangeDateTime = []RangeDateTime + +type MultiRangeLocalDateTime = []RangeLocalDateTime + +type MultiRangeLocalDate = []RangeLocalDate From decef3cceeba7baa9e64f9e8fd23c29f4e7ac274 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:29:10 +0100 Subject: [PATCH 08/15] Add gendocs for multi range type aliases --- rstdocs/types.rst | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/rstdocs/types.rst b/rstdocs/types.rst index 04b00d8..979ac31 100644 --- a/rstdocs/types.rst +++ b/rstdocs/types.rst @@ -324,6 +324,69 @@ UnmarshalText unmarshals bytes into \*m. +*type* MultiRangeDateTime +------------------------- + + +.. code-block:: go + + type MultiRangeDateTime = []RangeDateTime + + +*type* MultiRangeFloat32 +------------------------ + + +.. code-block:: go + + type MultiRangeFloat32 = []RangeFloat32 + + +*type* MultiRangeFloat64 +------------------------ + + +.. code-block:: go + + type MultiRangeFloat64 = []RangeFloat64 + + +*type* MultiRangeInt32 +---------------------- + + +.. code-block:: go + + type MultiRangeInt32 = []RangeInt32 + + +*type* MultiRangeInt64 +---------------------- + + +.. code-block:: go + + type MultiRangeInt64 = []RangeInt64 + + +*type* MultiRangeLocalDate +-------------------------- + + +.. code-block:: go + + type MultiRangeLocalDate = []RangeLocalDate + + +*type* MultiRangeLocalDateTime +------------------------------ + + +.. code-block:: go + + type MultiRangeLocalDateTime = []RangeLocalDateTime + + *type* Optional --------------- From 22fe0d175dcfc8d6f9824c0812c974009109839d Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:35:21 +0100 Subject: [PATCH 09/15] Add comments for public multi range aliases --- internal/edgedbtypes/multirange.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/edgedbtypes/multirange.go b/internal/edgedbtypes/multirange.go index 314fd3a..b67485b 100644 --- a/internal/edgedbtypes/multirange.go +++ b/internal/edgedbtypes/multirange.go @@ -16,16 +16,23 @@ package edgedbtypes +// MultiRangeInt32 is a type alias for multi range of RangeInt32 values. type MultiRangeInt32 = []RangeInt32 +// MultiRangeInt64 is a type alias for multi range of RangeInt64 values. type MultiRangeInt64 = []RangeInt64 +// MultiRangeFloat32 is a type alias for multi range of RangeFloat32 values. type MultiRangeFloat32 = []RangeFloat32 +// MultiRangeFloat64 is a type alias for multi range of RangeFloat64 values. type MultiRangeFloat64 = []RangeFloat64 +// MultiRangeDateTime is a type alias for multi range of RangeDateTime values. type MultiRangeDateTime = []RangeDateTime +// MultiRangeLocalDateTime is a type alias for multi range of RangeLocalDateTime values. type MultiRangeLocalDateTime = []RangeLocalDateTime +// MultiRangeLocalDate is a type alias for multi range of RangeLocalDate values. type MultiRangeLocalDate = []RangeLocalDate From 7b19e237c256443c4602bb443f87dde59e9da454 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:40:10 +0100 Subject: [PATCH 10/15] Put long comments in 2 lines --- internal/edgedbtypes/multirange.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/edgedbtypes/multirange.go b/internal/edgedbtypes/multirange.go index b67485b..2ce6d87 100644 --- a/internal/edgedbtypes/multirange.go +++ b/internal/edgedbtypes/multirange.go @@ -31,8 +31,10 @@ type MultiRangeFloat64 = []RangeFloat64 // MultiRangeDateTime is a type alias for multi range of RangeDateTime values. type MultiRangeDateTime = []RangeDateTime -// MultiRangeLocalDateTime is a type alias for multi range of RangeLocalDateTime values. +// MultiRangeLocalDateTime is a type alias for multi range of +// RangeLocalDateTime values. type MultiRangeLocalDateTime = []RangeLocalDateTime -// MultiRangeLocalDate is a type alias for multi range of RangeLocalDate values. +// MultiRangeLocalDate is a type alias for multi range of +// RangeLocalDate values. type MultiRangeLocalDate = []RangeLocalDate From 7ab60c8c5b4565ff950bf9a8b66f62b1e7a3b979 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:44:47 +0100 Subject: [PATCH 11/15] Fix lint error --- internal/client/types_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/client/types_test.go b/internal/client/types_test.go index 2790fdc..abb6ebc 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -7852,7 +7852,6 @@ func TestSendAndReceiveInt32MultiRange(t *testing.T) { assert.Equal(t, multiRange, result) } - func TestEmptyMultiRange(t *testing.T) { if !serverHasMultiRange(t) { t.Skip("server lacks std::MultiRange support") From 587ce0ab4f49a61214a90f5dc9d301445a45d906 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Fri, 10 Nov 2023 23:47:36 +0100 Subject: [PATCH 12/15] Make gendocs for multi range type aliases --- rstdocs/types.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rstdocs/types.rst b/rstdocs/types.rst index 979ac31..9322ea2 100644 --- a/rstdocs/types.rst +++ b/rstdocs/types.rst @@ -327,6 +327,8 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeDateTime ------------------------- +MultiRangeDateTime is a type alias for multi range of RangeDateTime values. + .. code-block:: go @@ -336,6 +338,8 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeFloat32 ------------------------ +MultiRangeFloat32 is a type alias for multi range of RangeFloat32 values. + .. code-block:: go @@ -345,6 +349,8 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeFloat64 ------------------------ +MultiRangeFloat64 is a type alias for multi range of RangeFloat64 values. + .. code-block:: go @@ -354,6 +360,8 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeInt32 ---------------------- +MultiRangeInt32 is a type alias for multi range of RangeInt32 values. + .. code-block:: go @@ -363,6 +371,8 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeInt64 ---------------------- +MultiRangeInt64 is a type alias for multi range of RangeInt64 values. + .. code-block:: go @@ -372,6 +382,9 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeLocalDate -------------------------- +MultiRangeLocalDate is a type alias for multi range of +RangeLocalDate values. + .. code-block:: go @@ -381,6 +394,9 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeLocalDateTime ------------------------------ +MultiRangeLocalDateTime is a type alias for multi range of +RangeLocalDateTime values. + .. code-block:: go From 57f568a53860668032d4096a720c4007db56002b Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Tue, 9 Apr 2024 18:59:12 +0200 Subject: [PATCH 13/15] Update multirange comments --- internal/edgedbtypes/multirange.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/edgedbtypes/multirange.go b/internal/edgedbtypes/multirange.go index 2ce6d87..b1ddaa3 100644 --- a/internal/edgedbtypes/multirange.go +++ b/internal/edgedbtypes/multirange.go @@ -16,25 +16,25 @@ package edgedbtypes -// MultiRangeInt32 is a type alias for multi range of RangeInt32 values. +// MultiRangeInt32 is a type alias for a slice of RangeInt32 values. type MultiRangeInt32 = []RangeInt32 -// MultiRangeInt64 is a type alias for multi range of RangeInt64 values. +// MultiRangeInt64 is a type alias for a slice of RangeInt64 values. type MultiRangeInt64 = []RangeInt64 -// MultiRangeFloat32 is a type alias for multi range of RangeFloat32 values. +// MultiRangeFloat32 is a type alias for a slice of RangeFloat32 values. type MultiRangeFloat32 = []RangeFloat32 -// MultiRangeFloat64 is a type alias for multi range of RangeFloat64 values. +// MultiRangeFloat64 is a type alias for a slice of RangeFloat64 values. type MultiRangeFloat64 = []RangeFloat64 -// MultiRangeDateTime is a type alias for multi range of RangeDateTime values. +// MultiRangeDateTime is a type alias for a slice of RangeDateTime values. type MultiRangeDateTime = []RangeDateTime -// MultiRangeLocalDateTime is a type alias for multi range of +// MultiRangeLocalDateTime is a type alias for a slice of // RangeLocalDateTime values. type MultiRangeLocalDateTime = []RangeLocalDateTime -// MultiRangeLocalDate is a type alias for multi range of +// MultiRangeLocalDate is a type alias for a slice of // RangeLocalDate values. type MultiRangeLocalDate = []RangeLocalDate From 45694513b4e2ad056a0c1569a5ebc10f099d2174 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Tue, 9 Apr 2024 19:16:49 +0200 Subject: [PATCH 14/15] Delete contains multirange test --- internal/client/types_test.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/internal/client/types_test.go b/internal/client/types_test.go index abb6ebc..e8f0dd1 100644 --- a/internal/client/types_test.go +++ b/internal/client/types_test.go @@ -7869,21 +7869,6 @@ func TestEmptyMultiRange(t *testing.T) { assert.Equal(t, emptyMultiRange, result) } -func TestMultiRangeContains(t *testing.T) { - if !serverHasMultiRange(t) { - t.Skip("server lacks std::MultiRange support") - } - - ctx := context.Background() - - var result bool - - query := "select contains(multirange([range(1, 5), range(8,10)]), 9)" - err := client.QuerySingle(ctx, query, &result) - require.NoError(t, err) - assert.Equal(t, true, result) -} - func TestCustomSequenceTypeHandling(t *testing.T) { ddl := ` CREATE SCALAR TYPE SampleSequence extending std::sequence; From 69653c762021c192bc738e6b9ed8b2b7cdbfb803 Mon Sep 17 00:00:00 2001 From: Dijana Pavlovic Date: Wed, 10 Apr 2024 09:23:17 +0200 Subject: [PATCH 15/15] Update rstdocs/types.rst file --- rstdocs/types.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rstdocs/types.rst b/rstdocs/types.rst index 9322ea2..b57054d 100644 --- a/rstdocs/types.rst +++ b/rstdocs/types.rst @@ -327,7 +327,7 @@ UnmarshalText unmarshals bytes into \*m. *type* MultiRangeDateTime ------------------------- -MultiRangeDateTime is a type alias for multi range of RangeDateTime values. +MultiRangeDateTime is a type alias for a slice of RangeDateTime values. .. code-block:: go @@ -338,7 +338,7 @@ MultiRangeDateTime is a type alias for multi range of RangeDateTime values. *type* MultiRangeFloat32 ------------------------ -MultiRangeFloat32 is a type alias for multi range of RangeFloat32 values. +MultiRangeFloat32 is a type alias for a slice of RangeFloat32 values. .. code-block:: go @@ -349,7 +349,7 @@ MultiRangeFloat32 is a type alias for multi range of RangeFloat32 values. *type* MultiRangeFloat64 ------------------------ -MultiRangeFloat64 is a type alias for multi range of RangeFloat64 values. +MultiRangeFloat64 is a type alias for a slice of RangeFloat64 values. .. code-block:: go @@ -360,7 +360,7 @@ MultiRangeFloat64 is a type alias for multi range of RangeFloat64 values. *type* MultiRangeInt32 ---------------------- -MultiRangeInt32 is a type alias for multi range of RangeInt32 values. +MultiRangeInt32 is a type alias for a slice of RangeInt32 values. .. code-block:: go @@ -371,7 +371,7 @@ MultiRangeInt32 is a type alias for multi range of RangeInt32 values. *type* MultiRangeInt64 ---------------------- -MultiRangeInt64 is a type alias for multi range of RangeInt64 values. +MultiRangeInt64 is a type alias for a slice of RangeInt64 values. .. code-block:: go @@ -382,7 +382,7 @@ MultiRangeInt64 is a type alias for multi range of RangeInt64 values. *type* MultiRangeLocalDate -------------------------- -MultiRangeLocalDate is a type alias for multi range of +MultiRangeLocalDate is a type alias for a slice of RangeLocalDate values. @@ -394,7 +394,7 @@ RangeLocalDate values. *type* MultiRangeLocalDateTime ------------------------------ -MultiRangeLocalDateTime is a type alias for multi range of +MultiRangeLocalDateTime is a type alias for a slice of RangeLocalDateTime values.