diff --git a/internal/request/graphql/schema/collection.go b/internal/request/graphql/schema/collection.go index 5f8d121b62..76835fd7c2 100644 --- a/internal/request/graphql/schema/collection.go +++ b/internal/request/graphql/schema/collection.go @@ -133,7 +133,7 @@ func collectionFromAstDefinition( for _, directive := range field.Directives { if directive.Name.Value == types.IndexDirectiveLabel { - index, err := fieldIndexFromAST(field, directive) + index, err := indexFromAST(directive, field) if err != nil { return client.CollectionDefinition{}, err } @@ -164,7 +164,7 @@ func collectionFromAstDefinition( for _, directive := range def.Directives { if directive.Name.Value == types.IndexDirectiveLabel { - index, err := indexFromAST(directive) + index, err := indexFromAST(directive, nil) if err != nil { return client.CollectionDefinition{}, err } @@ -239,14 +239,13 @@ func IsValidIndexName(name string) bool { return true } -func fieldIndexFromAST(field *ast.FieldDefinition, directive *ast.Directive) (client.IndexDescription, error) { - desc := client.IndexDescription{ - Fields: []client.IndexedFieldDescription{ - { - Name: field.Name.Value, - }, - }, - } +func indexFromAST(directive *ast.Directive, fieldDef *ast.FieldDefinition) (client.IndexDescription, error) { + var name string + var unique bool + + var direction *ast.EnumValue + var includes *ast.ListValue + for _, arg := range directive.Arguments { switch arg.Name.Value { case types.IndexDirectivePropName: @@ -254,95 +253,120 @@ func fieldIndexFromAST(field *ast.FieldDefinition, directive *ast.Directive) (cl if !ok { return client.IndexDescription{}, ErrIndexWithInvalidArg } - desc.Name = nameVal.Value - if !IsValidIndexName(desc.Name) { - return client.IndexDescription{}, NewErrIndexWithInvalidName(desc.Name) + name = nameVal.Value + if !IsValidIndexName(name) { + return client.IndexDescription{}, NewErrIndexWithInvalidName(name) } - case types.IndexDirectivePropUnique: - boolVal, ok := arg.Value.(*ast.BooleanValue) + + case types.IndexDirectivePropIncludes: + includesVal, ok := arg.Value.(*ast.ListValue) if !ok { return client.IndexDescription{}, ErrIndexWithInvalidArg } - desc.Unique = boolVal.Value + includes = includesVal + case types.IndexDirectivePropDirection: - dirVal, ok := arg.Value.(*ast.EnumValue) + directionVal, ok := arg.Value.(*ast.EnumValue) if !ok { return client.IndexDescription{}, ErrIndexWithInvalidArg } - if dirVal.Value == types.FieldOrderDESC { - desc.Fields[0].Descending = true + direction = directionVal + + case types.IndexDirectivePropUnique: + uniqueVal, ok := arg.Value.(*ast.BooleanValue) + if !ok { + return client.IndexDescription{}, ErrIndexWithInvalidArg } + unique = uniqueVal.Value + default: return client.IndexDescription{}, ErrIndexWithUnknownArg } } - return desc, nil -} -func indexFromAST(directive *ast.Directive) (client.IndexDescription, error) { - desc := client.IndexDescription{} - var directions *ast.ListValue - for _, arg := range directive.Arguments { - switch arg.Name.Value { - case types.IndexDirectivePropName: - nameVal, ok := arg.Value.(*ast.StringValue) - if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg - } - desc.Name = nameVal.Value - if !IsValidIndexName(desc.Name) { - return client.IndexDescription{}, ErrIndexWithInvalidArg - } - case types.IndexDirectivePropFields: - fieldsVal, ok := arg.Value.(*ast.ListValue) - if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg - } - for _, field := range fieldsVal.Values { - fieldVal, ok := field.(*ast.StringValue) - if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg - } - desc.Fields = append(desc.Fields, client.IndexedFieldDescription{ - Name: fieldVal.Value, - }) - } - case types.IndexDirectivePropDirections: - var ok bool - directions, ok = arg.Value.(*ast.ListValue) - if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg + var containsField bool + var fields []client.IndexedFieldDescription + + if includes != nil { + for _, include := range includes.Values { + field, err := indexFieldFromAST(include, direction) + if err != nil { + return client.IndexDescription{}, err } - case types.IndexDirectivePropUnique: - boolVal, ok := arg.Value.(*ast.BooleanValue) - if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg + if fieldDef != nil && fieldDef.Name.Value == field.Name { + containsField = true } - desc.Unique = boolVal.Value - default: - return client.IndexDescription{}, ErrIndexWithUnknownArg + fields = append(fields, field) } } - if len(desc.Fields) == 0 { + + // if the directive is applied to a field and + // the field is not in the includes list + // implicitly add it as the first entry + if !containsField && fieldDef != nil { + field := client.IndexedFieldDescription{ + Name: fieldDef.Name.Value, + } + if direction != nil { + field.Descending = direction.Value == types.FieldOrderDESC + } + fields = append([]client.IndexedFieldDescription{field}, fields...) + } + + if len(fields) == 0 { return client.IndexDescription{}, ErrIndexMissingFields } - if directions != nil { - if len(directions.Values) != len(desc.Fields) { - return client.IndexDescription{}, ErrIndexWithInvalidArg - } - for i := range desc.Fields { - dirVal, ok := directions.Values[i].(*ast.EnumValue) + + return client.IndexDescription{ + Name: name, + Fields: fields, + Unique: unique, + }, nil +} + +func indexFieldFromAST(value ast.Value, defaultDirection *ast.EnumValue) (client.IndexedFieldDescription, error) { + argTypeObject, ok := value.(*ast.ObjectValue) + if !ok { + return client.IndexedFieldDescription{}, ErrIndexWithInvalidArg + } + + var name string + var direction *ast.EnumValue + + for _, field := range argTypeObject.Fields { + switch field.Name.Value { + case types.IndexFieldInputName: + nameVal, ok := field.Value.(*ast.StringValue) if !ok { - return client.IndexDescription{}, ErrIndexWithInvalidArg + return client.IndexedFieldDescription{}, ErrIndexWithInvalidArg } - if dirVal.Value == types.FieldOrderASC { - desc.Fields[i].Descending = false - } else if dirVal.Value == types.FieldOrderDESC { - desc.Fields[i].Descending = true + name = nameVal.Value + + case types.IndexFieldInputDirection: + directionVal, ok := field.Value.(*ast.EnumValue) + if !ok { + return client.IndexedFieldDescription{}, ErrIndexWithInvalidArg } + direction = directionVal + + default: + return client.IndexedFieldDescription{}, ErrIndexWithUnknownArg } } - return desc, nil + + var descending bool + // if the direction is explicitly set use that value, otherwise + // if the default direction was set on the index use that value + if direction != nil { + descending = direction.Value == types.FieldOrderDESC + } else if defaultDirection != nil { + descending = defaultDirection.Value == types.FieldOrderDESC + } + + return client.IndexedFieldDescription{ + Name: name, + Descending: descending, + }, nil } func fieldsFromAST( diff --git a/internal/request/graphql/schema/index_parse_test.go b/internal/request/graphql/schema/index_parse_test.go index 8204c2d0ec..0c8413ec85 100644 --- a/internal/request/graphql/schema/index_parse_test.go +++ b/internal/request/graphql/schema/index_parse_test.go @@ -15,6 +15,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/sourcenetwork/defradb/client" ) @@ -23,7 +24,7 @@ func TestParseIndexOnStruct(t *testing.T) { cases := []indexTestCase{ { description: "Index with a single field", - sdl: `type user @index(fields: ["name"]) {}`, + sdl: `type user @index(includes: [{name: "name"}]) {}`, targetDescriptions: []client.IndexDescription{ { Name: "", @@ -36,7 +37,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index with a name", - sdl: `type user @index(name: "userIndex", fields: ["name"]) {}`, + sdl: `type user @index(name: "userIndex", includes: [{name: "name"}]) {}`, targetDescriptions: []client.IndexDescription{ { Name: "userIndex", @@ -48,7 +49,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Unique index", - sdl: `type user @index(fields: ["name"], unique: true) {}`, + sdl: `type user @index(includes: [{name: "name"}], unique: true) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -60,7 +61,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index explicitly not unique", - sdl: `type user @index(fields: ["name"], unique: false) {}`, + sdl: `type user @index(includes: [{name: "name"}], unique: false) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -72,7 +73,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index with explicit ascending field", - sdl: `type user @index(fields: ["name"], directions: [ASC]) {}`, + sdl: `type user @index(includes: [{name: "name", direction: ASC}]) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -82,7 +83,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index with descending field", - sdl: `type user @index(fields: ["name"], directions: [DESC]) {}`, + sdl: `type user @index(includes: [{name: "name", direction: DESC}]) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -92,7 +93,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index with 2 fields", - sdl: `type user @index(fields: ["name", "age"]) {}`, + sdl: `type user @index(includes: [{name: "name"}, {name: "age"}]) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -104,7 +105,7 @@ func TestParseIndexOnStruct(t *testing.T) { }, { description: "Index with 2 fields and 2 directions", - sdl: `type user @index(fields: ["name", "age"], directions: [ASC, DESC]) {}`, + sdl: `type user @index(includes: [{name: "name", direction: ASC}, {name: "age", direction: DESC}]) {}`, targetDescriptions: []client.IndexDescription{ { Fields: []client.IndexedFieldDescription{ @@ -124,78 +125,53 @@ func TestParseIndexOnStruct(t *testing.T) { func TestParseInvalidIndexOnStruct(t *testing.T) { cases := []invalidIndexTestCase{ { - description: "missing 'fields' argument", + description: "missing 'includes' argument", sdl: `type user @index(name: "userIndex", unique: true) {}`, expectedErr: errIndexMissingFields, }, { description: "unknown argument", - sdl: `type user @index(unknown: "something", fields: ["name"]) {}`, + sdl: `type user @index(unknown: "something", includes: [{name: "name"}]) {}`, expectedErr: errIndexUnknownArgument, }, { description: "invalid index name type", - sdl: `type user @index(name: 1, fields: ["name"]) {}`, + sdl: `type user @index(name: 1, includes: [{name: "name"}]) {}`, expectedErr: errIndexInvalidArgument, }, { description: "index name starts with a number", - sdl: `type user @index(name: "1_user_name", fields: ["name"]) {}`, - expectedErr: errIndexInvalidArgument, + sdl: `type user @index(name: "1_user_name", includes: [{name: "name"}]) {}`, + expectedErr: errIndexInvalidName, }, { description: "index with empty name", - sdl: `type user @index(name: "", fields: ["name"]) {}`, - expectedErr: errIndexInvalidArgument, + sdl: `type user @index(name: "", includes: [{name: "name"}]) {}`, + expectedErr: errIndexInvalidName, }, { description: "index name with spaces", - sdl: `type user @index(name: "user name", fields: ["name"]) {}`, - expectedErr: errIndexInvalidArgument, + sdl: `type user @index(name: "user name", includes: [{name: "name"}]) {}`, + expectedErr: errIndexInvalidName, }, { description: "index name with special symbols", - sdl: `type user @index(name: "user!name", fields: ["name"]) {}`, - expectedErr: errIndexInvalidArgument, + sdl: `type user @index(name: "user!name", includes: [{name: "name"}]) {}`, + expectedErr: errIndexInvalidName, }, { description: "invalid 'unique' value type", - sdl: `type user @index(fields: ["name"], unique: "true") {}`, - expectedErr: errIndexInvalidArgument, - }, - { - description: "invalid 'fields' value type (not a list)", - sdl: `type user @index(fields: "name") {}`, - expectedErr: errIndexInvalidArgument, - }, - { - description: "invalid 'fields' value type (not a string list)", - sdl: `type user @index(fields: [1]) {}`, - expectedErr: errIndexInvalidArgument, - }, - { - description: "invalid 'directions' value type (not a list)", - sdl: `type user @index(fields: ["name"], directions: "ASC") {}`, - expectedErr: errIndexInvalidArgument, - }, - { - description: "invalid 'directions' value type (not a string list)", - sdl: `type user @index(fields: ["name"], directions: [1]) {}`, + sdl: `type user @index(includes: [{name: "name"}], unique: "true") {}`, expectedErr: errIndexInvalidArgument, }, { - description: "invalid 'directions' value type (invalid element value)", - sdl: `type user @index(fields: ["name"], directions: ["direction"]) {}`, + description: "invalid 'includes' value type (not a list)", + sdl: `type user @index(includes: "name") {}`, expectedErr: errIndexInvalidArgument, }, { - description: "fewer directions than fields", - sdl: `type user @index(fields: ["name", "age"], directions: [ASC]) {}`, - expectedErr: errIndexInvalidArgument, - }, - { - description: "more directions than fields", - sdl: `type user @index(fields: ["name"], directions: [ASC, DESC]) {}`, + description: "invalid 'includes' value type (not an object list)", + sdl: `type user @index(includes: [1]) {}`, expectedErr: errIndexInvalidArgument, }, } @@ -293,6 +269,57 @@ func TestParseIndexOnField(t *testing.T) { }, }, }, + { + description: "composite field index with implicit include and implicit ordering", + sdl: `type user { + name: String @index(direction: DESC, includes: [{name: "age"}]) + age: Int + }`, + targetDescriptions: []client.IndexDescription{ + { + Name: "", + Fields: []client.IndexedFieldDescription{ + {Name: "name", Descending: true}, + {Name: "age", Descending: true}, + }, + Unique: false, + }, + }, + }, + { + description: "composite field index with implicit include and explicit ordering", + sdl: `type user { + name: String @index(direction: DESC, includes: [{name: "age", direction: ASC}]) + age: Int + }`, + targetDescriptions: []client.IndexDescription{ + { + Name: "", + Fields: []client.IndexedFieldDescription{ + {Name: "name", Descending: true}, + {Name: "age", Descending: false}, + }, + Unique: false, + }, + }, + }, + { + description: "composite field index with explicit includes", + sdl: `type user { + name: String @index(includes: [{name: "age"}, {name: "name"}]) + age: Int + }`, + targetDescriptions: []client.IndexDescription{ + { + Name: "", + Fields: []client.IndexedFieldDescription{ + {Name: "age", Descending: false}, + {Name: "name", Descending: false}, + }, + Unique: false, + }, + }, + }, } for _, test := range cases { @@ -362,9 +389,10 @@ func parseIndexAndTest(t *testing.T, testCase indexTestCase) { ctx := context.Background() cols, err := FromString(ctx, testCase.sdl) - assert.NoError(t, err, testCase.description) - assert.Equal(t, len(cols), 1, testCase.description) - assert.Equal(t, len(cols[0].Description.Indexes), len(testCase.targetDescriptions), testCase.description) + require.NoError(t, err, testCase.description) + + require.Equal(t, len(cols), 1, testCase.description) + require.Equal(t, len(cols[0].Description.Indexes), len(testCase.targetDescriptions), testCase.description) for i, d := range cols[0].Description.Indexes { assert.Equal(t, testCase.targetDescriptions[i], d, testCase.description) diff --git a/internal/request/graphql/schema/manager.go b/internal/request/graphql/schema/manager.go index 5c9a6c73c8..de2aa52ca3 100644 --- a/internal/request/graphql/schema/manager.go +++ b/internal/request/graphql/schema/manager.go @@ -36,6 +36,8 @@ func NewSchemaManager() (*SchemaManager, error) { commitObject := schemaTypes.CommitObject(commitLinkObject) commitsOrderArg := schemaTypes.CommitsOrderArg(orderEnum) + indexFieldInput := schemaTypes.IndexFieldInputObject(orderEnum) + schema, err := gql.NewSchema(gql.SchemaConfig{ Types: defaultTypes( commitObject, @@ -44,11 +46,12 @@ func NewSchemaManager() (*SchemaManager, error) { orderEnum, crdtEnum, explainEnum, + indexFieldInput, ), Query: defaultQueryType(commitObject, commitsOrderArg), Mutation: defaultMutationType(), + Directives: defaultDirectivesType(crdtEnum, explainEnum, orderEnum, indexFieldInput), Subscription: defaultSubscriptionType(), - Directives: defaultDirectivesType(crdtEnum, explainEnum, orderEnum), }) if err != nil { return sm, err @@ -145,13 +148,13 @@ func defaultDirectivesType( crdtEnum *gql.Enum, explainEnum *gql.Enum, orderEnum *gql.Enum, + indexFieldInput *gql.InputObject, ) []*gql.Directive { return []*gql.Directive{ schemaTypes.CRDTFieldDirective(crdtEnum), schemaTypes.ExplainDirective(explainEnum), schemaTypes.PolicyDirective(), - schemaTypes.IndexDirective(orderEnum), - schemaTypes.IndexFieldDirective(orderEnum), + schemaTypes.IndexDirective(orderEnum, indexFieldInput), schemaTypes.PrimaryDirective(), schemaTypes.RelationDirective(), } @@ -178,6 +181,7 @@ func defaultTypes( orderEnum *gql.Enum, crdtEnum *gql.Enum, explainEnum *gql.Enum, + indexFieldInput *gql.InputObject, ) []gql.Type { blobScalarType := schemaTypes.BlobScalarType() jsonScalarType := schemaTypes.JSONScalarType() @@ -222,5 +226,7 @@ func defaultTypes( crdtEnum, explainEnum, + + indexFieldInput, } } diff --git a/internal/request/graphql/schema/types/types.go b/internal/request/graphql/schema/types/types.go index ae027312ba..121bd4a3a4 100644 --- a/internal/request/graphql/schema/types/types.go +++ b/internal/request/graphql/schema/types/types.go @@ -33,12 +33,14 @@ const ( PolicySchemaDirectivePropID = "id" PolicySchemaDirectivePropResource = "resource" - IndexDirectiveLabel = "index" - IndexDirectivePropName = "name" - IndexDirectivePropUnique = "unique" - IndexDirectivePropFields = "fields" - IndexDirectivePropDirection = "direction" - IndexDirectivePropDirections = "directions" + IndexDirectiveLabel = "index" + IndexDirectivePropName = "name" + IndexDirectivePropUnique = "unique" + IndexDirectivePropDirection = "direction" + IndexDirectivePropIncludes = "includes" + + IndexFieldInputName = "name" + IndexFieldInputDirection = "direction" FieldOrderASC = "ASC" FieldOrderDESC = "DESC" @@ -121,44 +123,52 @@ func PolicyDirective() *gql.Directive { }) } -func IndexDirective(orderingEnum *gql.Enum) *gql.Directive { - return gql.NewDirective(gql.DirectiveConfig{ - Name: IndexDirectiveLabel, - Description: "@index is a directive that can be used to create an index on a type.", - Args: gql.FieldConfigArgument{ - IndexDirectivePropName: &gql.ArgumentConfig{ +func IndexFieldInputObject(orderingEnum *gql.Enum) *gql.InputObject { + return gql.NewInputObject(gql.InputObjectConfig{ + Name: "IndexField", + Description: "Used to create an index from a field.", + Fields: gql.InputObjectConfigFieldMap{ + IndexFieldInputName: &gql.InputObjectFieldConfig{ Type: gql.String, }, - IndexDirectivePropFields: &gql.ArgumentConfig{ - Type: gql.NewList(gql.String), - }, - IndexDirectivePropDirections: &gql.ArgumentConfig{ - Type: gql.NewList(orderingEnum), + IndexFieldInputDirection: &gql.InputObjectFieldConfig{ + Type: orderingEnum, }, }, - Locations: []string{ - gql.DirectiveLocationObject, - }, }) } -func IndexFieldDirective(orderingEnum *gql.Enum) *gql.Directive { +func IndexDirective(orderingEnum *gql.Enum, indexFieldInputObject *gql.InputObject) *gql.Directive { return gql.NewDirective(gql.DirectiveConfig{ Name: IndexDirectiveLabel, - Description: "@index is a directive that can be used to create an index on a field.", + Description: "@index is a directive that can be used to create an index on a type or a field.", Args: gql.FieldConfigArgument{ IndexDirectivePropName: &gql.ArgumentConfig{ - Type: gql.String, + Description: "Sets the index name.", + Type: gql.String, }, IndexDirectivePropUnique: &gql.ArgumentConfig{ - Type: gql.Boolean, + Description: "Makes the index unique.", + Type: gql.Boolean, }, IndexDirectivePropDirection: &gql.ArgumentConfig{ + Description: `Sets the default index ordering for all fields. + + If a field in the includes list does not specify a direction + the default ordering from this value will be used instead.`, Type: orderingEnum, }, + IndexDirectivePropIncludes: &gql.ArgumentConfig{ + Description: `Sets the fields the index is created on. + + When used on a field definition and the field is not in the includes list + it will be implicitly added as the first entry.`, + Type: gql.NewList(indexFieldInputObject), + }, }, Locations: []string{ - gql.DirectiveLocationField, + gql.DirectiveLocationObject, + gql.DirectiveLocationFieldDefinition, }, }) } diff --git a/tests/integration/index/create_composite_test.go b/tests/integration/index/create_composite_test.go index e9a83f1d15..6c1fe6c058 100644 --- a/tests/integration/index/create_composite_test.go +++ b/tests/integration/index/create_composite_test.go @@ -72,3 +72,225 @@ func TestCompositeIndexCreate_WhenCreated_CanRetrieve(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestCompositeIndexCreate_UsingObjectDirective_SetsDefaultDirection(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite index using object directive sets default direction", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User @index(direction: DESC, includes: [{name: "name"}, {name: "age"}]) { + name: String + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + // this should be User_name_DESC + Name: "User_name_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "name", + Descending: true, + }, + { + Name: "age", + Descending: true, + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestCompositeIndexCreate_UsingObjectDirective_OverridesDefaultDirection(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite object using field directive overrides default direction", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User @index(direction: DESC, includes: [{name: "name"}, {name: "age", direction: ASC}]) { + name: String + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + // this should be User_name_DESC + Name: "User_name_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "name", + Descending: true, + }, + { + Name: "age", + Descending: false, + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestCompositeIndexCreate_UsingFieldDirective_ImplicitlyAddsField(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite index using field directive implicitly adds field", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String @index(includes: [{name: "age"}]) + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + Name: "User_name_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "name", + }, + { + Name: "age", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestCompositeIndexCreate_UsingFieldDirective_SetsDefaultDirection(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite index using field directive sets default direction", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String @index(direction: DESC, includes: [{name: "age"}]) + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + // this should be User_name_DESC + Name: "User_name_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "name", + Descending: true, + }, + { + Name: "age", + Descending: true, + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestCompositeIndexCreate_UsingFieldDirective_OverridesDefaultDirection(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite index using field directive overrides default direction", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String @index(direction: DESC, includes: [{name: "age", direction: ASC}]) + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + // this should be User_name_DESC + Name: "User_name_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "name", + Descending: true, + }, + { + Name: "age", + Descending: false, + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestCompositeIndexCreate_UsingFieldDirective_WithExplicitIncludes_RespectsOrder(t *testing.T) { + test := testUtils.TestCase{ + Description: "create composite index using field directive with explicit includes respects order", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String @index(includes: [{name: "age"}, {name: "name"}]) + age: Int + } + `, + }, + testUtils.GetIndexes{ + CollectionID: 0, + ExpectedIndexes: []client.IndexDescription{ + { + Name: "User_age_ASC", + ID: 1, + Fields: []client.IndexedFieldDescription{ + { + Name: "age", + }, + { + Name: "name", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/index/create_get_test.go b/tests/integration/index/create_get_test.go index 3ba27cfa9e..76b63980c4 100644 --- a/tests/integration/index/create_get_test.go +++ b/tests/integration/index/create_get_test.go @@ -23,7 +23,7 @@ func TestIndexGet_ShouldReturnListOfExistingIndexes(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(name: "age_index", fields: ["age"]) { + type User @index(name: "age_index", includes: [{name: "age"}]) { name: String @index(name: "name_index") age: Int } diff --git a/tests/integration/index/create_unique_composite_test.go b/tests/integration/index/create_unique_composite_test.go index 9adb6d2e67..44123eaefe 100644 --- a/tests/integration/index/create_unique_composite_test.go +++ b/tests/integration/index/create_unique_composite_test.go @@ -75,7 +75,7 @@ func TestUniqueCompositeIndexCreate_UponAddingDocWithExistingFieldValue_ReturnEr Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String diff --git a/tests/integration/index/query_with_composite_index_field_order_test.go b/tests/integration/index/query_with_composite_index_field_order_test.go index 7b38163c1c..f53fbc3312 100644 --- a/tests/integration/index/query_with_composite_index_field_order_test.go +++ b/tests/integration/index/query_with_composite_index_field_order_test.go @@ -22,7 +22,7 @@ func TestQueryWithCompositeIndex_WithDefaultOrder_ShouldFetchInDefaultOrder(t *t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int }`, @@ -100,7 +100,7 @@ func TestQueryWithCompositeIndex_WithDefaultOrderCaseInsensitive_ShouldFetchInDe Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int }`, @@ -178,7 +178,7 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnFirstField_ShouldFetchInReve Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [DESC, ASC]) { + type User @index(includes: [{name: "name", direction: DESC}, {name: "age", direction: ASC}]) { name: String age: Int }`, @@ -268,7 +268,7 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnFirstFieldCaseInsensitive_Sh Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [DESC, ASC]) { + type User @index(includes: [{name: "name", direction: DESC}, {name: "age", direction: ASC}]) { name: String age: Int }`, @@ -358,7 +358,7 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnSecondField_ShouldFetchInRev Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [ASC, DESC]) { + type User @index(includes: [{name: "name", direction: ASC}, {name: "age", direction: DESC}]) { name: String age: Int }`, @@ -438,7 +438,7 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnSecondFieldCaseInsensitive_S Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [ASC, DESC]) { + type User @index(includes: [{name: "name", direction: ASC}, {name: "age", direction: DESC}]) { name: String age: Int }`, @@ -516,7 +516,7 @@ func TestQueryWithCompositeIndex_IfExactMatchWithRevertedOrderOnFirstField_Shoul Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [DESC, ASC]) { + type User @index(includes: [{name: "name", direction: DESC}, {name: "age", direction: ASC}]) { name: String age: Int }`, @@ -574,7 +574,7 @@ func TestQueryWithCompositeIndex_IfExactMatchWithRevertedOrderOnSecondField_Shou Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [ASC, DESC]) { + type User @index(includes: [{name: "name", direction: ASC}, {name: "age", direction: DESC}]) { name: String age: Int }`, @@ -632,7 +632,7 @@ func TestQueryWithCompositeIndex_WithInFilterOnFirstFieldWithRevertedOrder_Shoul Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [DESC, ASC]) { + type User @index(includes: [{name: "name", direction: DESC}, {name: "age", direction: ASC}]) { name: String age: Int email: String @@ -667,7 +667,7 @@ func TestQueryWithCompositeIndex_WithInFilterOnSecondFieldWithRevertedOrder_Shou Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"], directions: [ASC, DESC]) { + type User @index(includes: [{name: "name", direction: ASC}, {name: "age", direction: DESC}]) { name: String age: Int email: String diff --git a/tests/integration/index/query_with_composite_index_only_filter_test.go b/tests/integration/index/query_with_composite_index_only_filter_test.go index 94e6a54727..adaef0d481 100644 --- a/tests/integration/index/query_with_composite_index_only_filter_test.go +++ b/tests/integration/index/query_with_composite_index_only_filter_test.go @@ -40,7 +40,7 @@ func TestQueryWithCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -96,7 +96,7 @@ func TestQueryWithCompositeIndex_WithGreaterThanFilterOnFirstField_ShouldFetch(t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["age", "name"]) { + type User @index(includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -134,7 +134,7 @@ func TestQueryWithCompositeIndex_WithGreaterThanFilterOnSecondField_ShouldFetch( Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -172,7 +172,7 @@ func TestQueryWithCompositeIndex_WithGreaterOrEqualFilterOnFirstField_ShouldFetc Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["age", "name"]) { + type User @index(includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -211,7 +211,7 @@ func TestQueryWithCompositeIndex_WithGreaterOrEqualFilterOnSecondField_ShouldFet Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -250,7 +250,7 @@ func TestQueryWithCompositeIndex_WithLessThanFilterOnFirstField_ShouldFetch(t *t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["age", "name"]) { + type User @index(includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -288,7 +288,7 @@ func TestQueryWithCompositeIndex_WithLessThanFilterOnSecondField_ShouldFetch(t * Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -326,7 +326,7 @@ func TestQueryWithCompositeIndex_WithLessOrEqualFilterOnFirstField_ShouldFetch(t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["age", "name"]) { + type User @index(includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -365,7 +365,7 @@ func TestQueryWithCompositeIndex_WithLessOrEqualFilterOnSecondField_ShouldFetch( Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -404,7 +404,7 @@ func TestQueryWithCompositeIndex_WithNotEqualFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -449,7 +449,7 @@ func TestQueryWithCompositeIndex_WithInFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -488,7 +488,7 @@ func TestQueryWithCompositeIndex_WithNotInFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -558,7 +558,7 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "email"]) { + type User @index(includes: [{name: "name"}, {name: "email"}]) { name: String email: String }`, @@ -655,7 +655,7 @@ func TestQueryWithCompositeIndex_WithNotLikeFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "email"]) { + type User @index(includes: [{name: "name"}, {name: "email"}]) { name: String email: String }`, @@ -690,7 +690,7 @@ func TestQueryWithCompositeIndex_IfFirstFieldIsNotInFilter_ShouldNotUseIndex(t * Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -719,7 +719,7 @@ func TestQueryWithCompositeIndex_WithEqualFilterOnNilValueOnFirst_ShouldFetch(t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -766,7 +766,7 @@ func TestQueryWithCompositeIndex_WithEqualFilterOnNilValueOnSecond_ShouldFetch(t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age"]) { + type User @index(includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -823,7 +823,7 @@ func TestQueryWithCompositeIndex_IfMiddleFieldIsNotInFilter_ShouldIgnoreValue(t Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "email", "age"]) { + type User @index(includes: [{name: "name"}, {name: "email"}, {name: "age"}]) { name: String email: String age: Int @@ -898,7 +898,7 @@ func TestQueryWithCompositeIndex_IfConsecutiveEqOps_ShouldUseAllToOptimizeQuery( Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(fields: ["name", "age", "numChildren"]) { + type User @index(includes: [{name: "name"}, {name: "age"}, {name: "numChildren"}]) { name: String age: Int numChildren: Int diff --git a/tests/integration/index/query_with_composite_inxed_on_relation_test.go b/tests/integration/index/query_with_composite_inxed_on_relation_test.go index 40d736ba3c..aab19f2d07 100644 --- a/tests/integration/index/query_with_composite_inxed_on_relation_test.go +++ b/tests/integration/index/query_with_composite_inxed_on_relation_test.go @@ -31,7 +31,7 @@ func TestQueryWithCompositeIndexOnManyToOne_WithMultipleIndexedChildNodes_Should devices: [Device] } - type Device @index(fields: ["owner_id", "manufacturer_id"]) { + type Device @index(includes: [{name: "owner_id"}, {name: "manufacturer_id"}]) { model: String owner: User manufacturer: Manufacturer diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index 9428626810..e31685a0cf 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -182,7 +182,7 @@ func TestQueryWithIndexOnOneToOnesSecondaryRelation_IfFilterOnIndexedRelation_Sh type Address { user: User @primary - city: String @index + city: String @index }`, }, testUtils.CreatePredefinedDocs{ diff --git a/tests/integration/index/query_with_unique_composite_index_filter_test.go b/tests/integration/index/query_with_unique_composite_index_filter_test.go index 0df9b349ca..190bfca53a 100644 --- a/tests/integration/index/query_with_unique_composite_index_filter_test.go +++ b/tests/integration/index/query_with_unique_composite_index_filter_test.go @@ -40,7 +40,7 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -114,7 +114,7 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterThanFilterOnFirstField_ShouldF Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["age", "name"]) { + type User @index(unique: true, includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -152,7 +152,7 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterThanFilterOnSecondField_Should Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -190,7 +190,7 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterOrEqualFilterOnFirstField_Shou Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["age", "name"]) { + type User @index(unique: true, includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -229,7 +229,7 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterOrEqualFilterOnSecondField_Sho Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -268,7 +268,7 @@ func TestQueryWithUniqueCompositeIndex_WithLessThanFilterOnFirstField_ShouldFetc Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["age", "name"]) { + type User @index(unique: true, includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -306,7 +306,7 @@ func TestQueryWithUniqueCompositeIndex_WithLessThanFilterOnSecondField_ShouldFet Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -344,7 +344,7 @@ func TestQueryWithUniqueCompositeIndex_WithLessOrEqualFilterOnFirstField_ShouldF Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["age", "name"]) { + type User @index(unique: true, includes: [{name: "age"}, {name: "name"}]) { name: String age: Int email: String @@ -383,7 +383,7 @@ func TestQueryWithUniqueCompositeIndex_WithLessOrEqualFilterOnSecondField_Should Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -422,7 +422,7 @@ func TestQueryWithUniqueCompositeIndex_WithNotEqualFilter_ShouldFetch(t *testing Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -468,7 +468,7 @@ func TestQueryWithUniqueCompositeIndex_WithInForFirstAndEqForRest_ShouldFetchEff Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -544,7 +544,7 @@ func TestQueryWithUniqueCompositeIndex_WithInFilter_ShouldFetch(t *testing.T) { Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -599,7 +599,7 @@ func TestQueryWithUniqueCompositeIndex_WithNotInFilter_ShouldFetch(t *testing.T) Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -669,7 +669,7 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "email"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "email"}]) { name: String email: String }`, @@ -766,7 +766,7 @@ func TestQueryWithUniqueCompositeIndex_WithNotLikeFilter_ShouldFetch(t *testing. Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "email"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "email"}]) { name: String email: String }`, @@ -806,7 +806,7 @@ func TestQueryWithUniqueCompositeIndex_WithNotCaseInsensitiveLikeFilter_ShouldFe Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "email"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "email"}]) { name: String email: String }`, @@ -842,7 +842,7 @@ func TestQueryWithUniqueCompositeIndex_IfFirstFieldIsNotInFilter_ShouldNotUseInd Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -871,7 +871,7 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilterOnNilValueOnFirst_ShouldFe Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -925,7 +925,7 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnFirstFieldAndNilFilter_S Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -981,7 +981,7 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilterOnNilValueOnSecond_ShouldF Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int about: String @@ -1048,7 +1048,7 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnSecondFieldsAndNilFilter Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String @@ -1113,7 +1113,7 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnBothFieldsAndNilFilter_S Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int about: String @@ -1214,7 +1214,7 @@ func TestQueryWithUniqueCompositeIndex_AfterUpdateOnNilFields_ShouldFetch(t *tes Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int about: String @@ -1355,7 +1355,7 @@ func TestQueryWithUniqueCompositeIndex_IfMiddleFieldIsNotInFilter_ShouldIgnoreVa Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "email", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "email"}, {name: "age"}]) { name: String email: String age: Int diff --git a/tests/integration/index/update_unique_composite_test.go b/tests/integration/index/update_unique_composite_test.go index 4621e79283..17a831369c 100644 --- a/tests/integration/index/update_unique_composite_test.go +++ b/tests/integration/index/update_unique_composite_test.go @@ -22,7 +22,7 @@ func TestUniqueCompositeIndexUpdate_UponUpdatingDocWithExistingFieldValue_Should Actions: []any{ testUtils.SchemaUpdate{ Schema: ` - type User @index(unique: true, fields: ["name", "age"]) { + type User @index(unique: true, includes: [{name: "name"}, {name: "age"}]) { name: String age: Int email: String