diff --git a/quesma/quesma/functionality/resolve/resolve.go b/quesma/quesma/functionality/resolve/resolve.go new file mode 100644 index 000000000..1a7fe395b --- /dev/null +++ b/quesma/quesma/functionality/resolve/resolve.go @@ -0,0 +1,76 @@ +// Copyright Quesma, licensed under the Elastic License 2.0. +// SPDX-License-Identifier: Elastic-2.0 +package resolve + +import ( + "quesma/elasticsearch" + "quesma/quesma/config" + "quesma/schema" + "slices" +) + +func HandleResolve(pattern string, sr schema.Registry, cfg config.QuesmaConfiguration) (elasticsearch.Sources, error) { + // In the _resolve endpoint we want to combine the results from both schema.Registry and Elasticsearch + + normalizedPattern := elasticsearch.NormalizePattern(pattern) + + // Optimization: if it's not a pattern, let's try avoiding querying Elasticsearch - let's first try + // finding that index in schema.Registry: + if !elasticsearch.IsIndexPattern(normalizedPattern) { + if foundSchema, found := sr.FindSchema(schema.TableName(normalizedPattern)); found { + if !foundSchema.ExistsInDataSource { + // index configured by the user, but not present in the data source + return elasticsearch.Sources{}, nil + } + + return elasticsearch.Sources{ + Indices: []elasticsearch.Index{}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{ + { + Name: normalizedPattern, + BackingIndices: []string{normalizedPattern}, + TimestampField: `@timestamp`, + }, + }, + }, nil + } + + // ...index not found in schema.Registry (meaning the user did not configure it), but it could exist in Elastic + } + + // Combine results from both schema.Registry and Elasticsearch: + + // todo avoid creating new instances all the time + sourcesFromElastic, _, err := elasticsearch.NewIndexResolver(cfg.Elasticsearch.Url.String()).Resolve(normalizedPattern) + if err != nil { + return elasticsearch.Sources{}, err + } + + combineSourcesFromElasticWithRegistry(&sourcesFromElastic, sr.AllSchemas(), normalizedPattern) + return sourcesFromElastic, nil +} + +func combineSourcesFromElasticWithRegistry(sourcesFromElastic *elasticsearch.Sources, schemas map[schema.TableName]schema.Schema, normalizedPattern string) { + sourcesFromElastic.Indices = + slices.DeleteFunc(sourcesFromElastic.Indices, func(i elasticsearch.Index) bool { + _, exists := schemas[schema.TableName(i.Name)] + return exists + }) + sourcesFromElastic.DataStreams = slices.DeleteFunc(sourcesFromElastic.DataStreams, func(i elasticsearch.DataStream) bool { + _, exists := schemas[schema.TableName(i.Name)] + return exists + }) + + for name, currentSchema := range schemas { + indexName := name.AsString() + + if config.MatchName(normalizedPattern, indexName) && currentSchema.ExistsInDataSource { + sourcesFromElastic.DataStreams = append(sourcesFromElastic.DataStreams, elasticsearch.DataStream{ + Name: indexName, + BackingIndices: []string{indexName}, + TimestampField: `@timestamp`, + }) + } + } +} diff --git a/quesma/quesma/functionality/resolve/resolve_test.go b/quesma/quesma/functionality/resolve/resolve_test.go new file mode 100644 index 000000000..d5fa21fdf --- /dev/null +++ b/quesma/quesma/functionality/resolve/resolve_test.go @@ -0,0 +1,104 @@ +// Copyright Quesma, licensed under the Elastic License 2.0. +// SPDX-License-Identifier: Elastic-2.0 +package resolve + +import ( + "github.com/stretchr/testify/assert" + "quesma/elasticsearch" + "quesma/schema" + "testing" +) + +func Test_combineSourcesFromElasticWithRegistry(t *testing.T) { + // Expected behavior: + // + // # | In Elastic? | Exists in data source? | Enabled in the config (= present in schema.Registry)? | Quesma response + // 1 | NO | NO | NO | Not exists + // 2 | NO | NO | YES | Not exists + // 3 | YES | NO | NO | Exists + // 4 | YES | NO | YES | Not exist + // 5 | NO | YES | NO | Not exist + // 6 | NO | YES | YES | Exists + // 7 | YES | YES | NO | Exists + // 8 | YES | YES | YES | Exists + + tests := []struct { + name string + sourcesFromElastic elasticsearch.Sources + schemas map[schema.TableName]schema.Schema + normalizedPattern string + expectedResult elasticsearch.Sources + }{ + // Cases 1, 3 (index1), 5, 7 (index1): + { + name: "index not enabled in config, some unrelated index in Elastic", + sourcesFromElastic: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index1"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{}, + }, + schemas: map[schema.TableName]schema.Schema{}, // schema.Registry won't contain disabled indexes, even if they exist in the data source (manually created by the user) + normalizedPattern: "index*", + expectedResult: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index1"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{}, + }, + }, + // Cases 2 (index2), 4 (index1): + { + name: "index enabled in config, not present in the data source; decoy index in Elastic", + sourcesFromElastic: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index1"} /* decoy */, {Name: "index3"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{}, + }, + schemas: map[schema.TableName]schema.Schema{ + "index1": schema.Schema{ExistsInDataSource: false}, + "index2": schema.Schema{ExistsInDataSource: false}, + "quesma": schema.Schema{ExistsInDataSource: true}, + }, + normalizedPattern: "index*", + expectedResult: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index3"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{}, + }, + }, + // Cases 6 (index2), 8 (index1, index3): + { + name: "index enabled in config, present in the data source", + sourcesFromElastic: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index1"}, {Name: "index4"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{{Name: "index3"}, {Name: "index5"}}, + }, + schemas: map[schema.TableName]schema.Schema{ + "index1": schema.Schema{ExistsInDataSource: true}, + "index2": schema.Schema{ExistsInDataSource: true}, + "index3": schema.Schema{ExistsInDataSource: true}, + "quesma": schema.Schema{ExistsInDataSource: true}, + }, + normalizedPattern: "index*", + expectedResult: elasticsearch.Sources{ + Indices: []elasticsearch.Index{{Name: "index4"}}, + Aliases: []elasticsearch.Alias{}, + DataStreams: []elasticsearch.DataStream{ + {Name: "index5"}, + {Name: "index1", BackingIndices: []string{"index1"}, TimestampField: `@timestamp`}, + {Name: "index2", BackingIndices: []string{"index2"}, TimestampField: `@timestamp`}, + {Name: "index3", BackingIndices: []string{"index3"}, TimestampField: `@timestamp`}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + combineSourcesFromElasticWithRegistry(&tt.sourcesFromElastic, tt.schemas, tt.normalizedPattern) + assert.ElementsMatchf(t, tt.sourcesFromElastic.Aliases, tt.expectedResult.Aliases, "Aliases don't match") + assert.ElementsMatchf(t, tt.sourcesFromElastic.Indices, tt.expectedResult.Indices, "Indices don't match") + assert.ElementsMatchf(t, tt.sourcesFromElastic.DataStreams, tt.expectedResult.DataStreams, "DataStreams don't match") + }) + } +} diff --git a/quesma/quesma/router.go b/quesma/quesma/router.go index 5441eab21..44cd6914e 100644 --- a/quesma/quesma/router.go +++ b/quesma/quesma/router.go @@ -15,6 +15,7 @@ import ( "quesma/quesma/functionality/bulk" "quesma/quesma/functionality/doc" "quesma/quesma/functionality/field_capabilities" + "quesma/quesma/functionality/resolve" "quesma/quesma/functionality/terms_enum" "quesma/quesma/mux" "quesma/quesma/routes" @@ -24,7 +25,6 @@ import ( "quesma/telemetry" "quesma/tracing" "regexp" - "slices" "strings" "time" ) @@ -83,75 +83,11 @@ func configureRouter(cfg config.QuesmaConfiguration, sr schema.Registry, lm *cli }) router.Register(routes.ResolveIndexPath, method("GET"), func(ctx context.Context, req *mux.Request) (*mux.Result, error) { - pattern := elasticsearch.NormalizePattern(req.Params["index"]) - if elasticsearch.IsIndexPattern(pattern) { - // todo avoid creating new instances all the time - sources, found, err := elasticsearch.NewIndexResolver(cfg.Elasticsearch.Url.String()).Resolve(pattern) - if err != nil { - return nil, err - } - if !found { - return &mux.Result{StatusCode: 404}, nil - } - - definitions, err := lm.GetTableDefinitions() - if err != nil { - return nil, err - } - sources.Indices = slices.DeleteFunc(sources.Indices, func(i elasticsearch.Index) bool { - return definitions.Has(i.Name) - }) - sources.DataStreams = slices.DeleteFunc(sources.DataStreams, func(i elasticsearch.DataStream) bool { - return definitions.Has(i.Name) - }) - definitions.Range( - func(name string, table *clickhouse.Table) bool { - if config.MatchName(elasticsearch.NormalizePattern(pattern), name) { - sources.DataStreams = append(sources.DataStreams, elasticsearch.DataStream{ - Name: name, - BackingIndices: []string{name}, - TimestampField: `@timestamp`, - }) - } - - return true - }) - - return resolveIndexResult(sources), nil - } else { - if config.MatchName(elasticsearch.NormalizePattern(pattern), pattern) { - definitions, err := lm.GetTableDefinitions() - if err != nil { - return nil, err - } - - if definitions.Has(pattern) { - return resolveIndexResult(elasticsearch.Sources{ - Indices: []elasticsearch.Index{}, - Aliases: []elasticsearch.Alias{}, - DataStreams: []elasticsearch.DataStream{ - { - Name: pattern, - BackingIndices: []string{pattern}, - TimestampField: `@timestamp`, - }, - }, - }), nil - } else { - return &mux.Result{StatusCode: 404}, nil - } - } else { - sources, found, err := elasticsearch.NewIndexResolver(cfg.Elasticsearch.Url.String()).Resolve(pattern) - if err != nil { - return nil, err - } - if !found { - return &mux.Result{StatusCode: 404}, nil - } - - return resolveIndexResult(sources), nil - } + sources, err := resolve.HandleResolve(req.Params["index"], sr, cfg) + if err != nil { + return nil, err } + return resolveIndexResult(sources), nil }) router.Register(routes.IndexCountPath, and(method("GET"), matchedAgainstPattern(cfg)), func(ctx context.Context, req *mux.Request) (*mux.Result, error) { @@ -401,6 +337,10 @@ func elasticsearchInsertResult(body string, statusCode int) *mux.Result { } func resolveIndexResult(sources elasticsearch.Sources) *mux.Result { + if len(sources.Aliases) == 0 && len(sources.DataStreams) == 0 && len(sources.Indices) == 0 { + return &mux.Result{StatusCode: 404} + } + body, err := json.Marshal(sources) if err != nil { panic(err) diff --git a/quesma/schema/registry.go b/quesma/schema/registry.go index 08dcb3653..73eccb982 100644 --- a/quesma/schema/registry.go +++ b/quesma/schema/registry.go @@ -42,9 +42,9 @@ func (s *schemaRegistry) loadSchemas() (map[TableName]Schema, error) { aliases := make(map[FieldName]FieldName) s.populateSchemaFromStaticConfiguration(indexConfiguration, fields) - s.populateSchemaFromTableDefinition(definitions, indexName, fields) + existsInDataSource := s.populateSchemaFromTableDefinition(definitions, indexName, fields) s.populateAliases(indexConfiguration, fields, aliases) - schemas[TableName(indexName)] = NewSchemaWithAliases(fields, aliases) + schemas[TableName(indexName)] = NewSchemaWithAliases(fields, aliases, existsInDataSource) } return schemas, nil @@ -136,8 +136,9 @@ func (s *schemaRegistry) populateAliases(indexConfiguration config.IndexConfigur } } -func (s *schemaRegistry) populateSchemaFromTableDefinition(definitions map[string]Table, indexName string, fields map[FieldName]Field) { - if tableDefinition, found := definitions[indexName]; found { +func (s *schemaRegistry) populateSchemaFromTableDefinition(definitions map[string]Table, indexName string, fields map[FieldName]Field) (existsInDataSource bool) { + tableDefinition, found := definitions[indexName] + if found { logger.Debug().Msgf("loading schema for table %s", indexName) for _, column := range tableDefinition.Columns { @@ -154,4 +155,5 @@ func (s *schemaRegistry) populateSchemaFromTableDefinition(definitions map[strin } } } + return found } diff --git a/quesma/schema/registry_test.go b/quesma/schema/registry_test.go index 0b5536134..798151bbd 100644 --- a/quesma/schema/registry_test.go +++ b/quesma/schema/registry_test.go @@ -17,7 +17,7 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { tableDiscovery schema.TableProvider tableName schema.TableName want schema.Schema - exists bool + found bool }{ { name: "schema not found", @@ -25,7 +25,7 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { tableDiscovery: fixedTableProvider{tables: map[string]schema.Table{}}, tableName: "nonexistent", want: schema.Schema{}, - exists: false, + found: false, }, { name: "schema inferred, no mappings", @@ -45,8 +45,9 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { want: schema.NewSchema(map[schema.FieldName]schema.Field{ "message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}, "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, - "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}), - exists: true, + "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, + true), + found: true, }, { name: "schema inferred, with type mappings (deprecated)", @@ -66,8 +67,9 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { want: schema.NewSchema(map[schema.FieldName]schema.Field{ "message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}, "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, - "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}), - exists: true, + "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, + true), + found: true, }, { name: "schema inferred, with type mappings not backed by db (deprecated)", @@ -86,8 +88,9 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { want: schema.NewSchema(map[schema.FieldName]schema.Field{ "message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}, "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, - "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}), - exists: true, + "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, + true), + found: true, }, { name: "schema inferred, with type mappings not backed by db", @@ -110,8 +113,9 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { want: schema.NewSchema(map[schema.FieldName]schema.Field{ "message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}, "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, - "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}), - exists: true, + "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, + true), + found: true, }, { name: "schema explicitly configured, nothing in db", @@ -126,8 +130,8 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { }, tableDiscovery: fixedTableProvider{tables: map[string]schema.Table{}}, tableName: "some_table", - want: schema.NewSchema(map[schema.FieldName]schema.Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}}), - exists: true, + want: schema.NewSchema(map[schema.FieldName]schema.Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}}, false), + found: true, }, { name: "schema inferred, with mapping overrides", @@ -151,8 +155,9 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { want: schema.NewSchema(map[schema.FieldName]schema.Field{ "message": {PropertyName: "message", InternalPropertyName: "message", Type: schema.TypeKeyword}, "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, - "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}), - exists: true, + "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, + true), + found: true, }, { name: "schema inferred, with aliases", @@ -179,8 +184,8 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, map[schema.FieldName]schema.FieldName{ "message_alias": "message", - }), - exists: true, + }, true), + found: true, }, { name: "schema inferred, with aliases [deprecated config]", @@ -205,8 +210,8 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { "event_date": {PropertyName: "event_date", InternalPropertyName: "event_date", Type: schema.TypeTimestamp}, "count": {PropertyName: "count", InternalPropertyName: "count", Type: schema.TypeLong}}, map[schema.FieldName]schema.FieldName{ "message_alias": "message", - }), - exists: true, + }, true), + found: true, }, { name: "schema inferred, requesting nonexistent schema", @@ -224,15 +229,15 @@ func Test_schemaRegistry_FindSchema(t *testing.T) { }}, tableName: "foo", want: schema.Schema{}, - exists: false, + found: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := schema.NewSchemaRegistry(tt.tableDiscovery, tt.cfg, clickhouse.SchemaTypeAdapter{}) resultSchema, resultFound := s.FindSchema(tt.tableName) - if resultFound != tt.exists { - t.Errorf("FindSchema() got1 = %v, want %v", resultFound, tt.exists) + if resultFound != tt.found { + t.Errorf("FindSchema() got1 = %v, want %v", resultFound, tt.found) } if !reflect.DeepEqual(resultSchema, tt.want) { t.Errorf("FindSchema() got = %v, want %v", resultSchema, tt.want) diff --git a/quesma/schema/schema.go b/quesma/schema/schema.go index d6d1d0422..05c460ddf 100644 --- a/quesma/schema/schema.go +++ b/quesma/schema/schema.go @@ -6,6 +6,7 @@ type ( Schema struct { Fields map[FieldName]Field Aliases map[FieldName]FieldName + ExistsInDataSource bool internalNameToField map[FieldName]Field } Field struct { @@ -19,7 +20,7 @@ type ( FieldName string ) -func NewSchemaWithAliases(fields map[FieldName]Field, aliases map[FieldName]FieldName) Schema { +func NewSchemaWithAliases(fields map[FieldName]Field, aliases map[FieldName]FieldName, existsInDataSource bool) Schema { internalNameToField := make(map[FieldName]Field) for _, field := range fields { internalNameToField[field.InternalPropertyName] = field @@ -27,12 +28,13 @@ func NewSchemaWithAliases(fields map[FieldName]Field, aliases map[FieldName]Fiel return Schema{ Fields: fields, Aliases: aliases, + ExistsInDataSource: existsInDataSource, internalNameToField: internalNameToField, } } -func NewSchema(fields map[FieldName]Field) Schema { - return NewSchemaWithAliases(fields, map[FieldName]FieldName{}) +func NewSchema(fields map[FieldName]Field, existsInDataSource bool) Schema { + return NewSchemaWithAliases(fields, map[FieldName]FieldName{}, existsInDataSource) } func (t FieldName) AsString() string { diff --git a/quesma/schema/schema_test.go b/quesma/schema/schema_test.go index 0f5797c22..22d8b2467 100644 --- a/quesma/schema/schema_test.go +++ b/quesma/schema/schema_test.go @@ -24,28 +24,28 @@ func TestSchema_ResolveField(t *testing.T) { { name: "should resolve field", fieldName: "message", - schema: NewSchema(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}), + schema: NewSchema(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, false), resolvedField: Field{PropertyName: "message", InternalPropertyName: "message", Type: TypeText}, exists: true, }, { name: "should not resolve field", fieldName: "foo", - schema: NewSchema(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}), + schema: NewSchema(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, false), resolvedField: Field{}, exists: false, }, { name: "should resolve aliased field", fieldName: "message_alias", - schema: NewSchemaWithAliases(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, map[FieldName]FieldName{"message_alias": "message"}), + schema: NewSchemaWithAliases(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, map[FieldName]FieldName{"message_alias": "message"}, false), resolvedField: Field{PropertyName: "message", InternalPropertyName: "message", Type: TypeText}, exists: true, }, { name: "should not resolve aliased field", fieldName: "message_alias", - schema: NewSchemaWithAliases(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, map[FieldName]FieldName{"message_alias": "foo"}), + schema: NewSchemaWithAliases(map[FieldName]Field{"message": {PropertyName: "message", InternalPropertyName: "message", Type: TypeText}}, map[FieldName]FieldName{"message_alias": "foo"}, false), resolvedField: Field{}, exists: false, }, @@ -73,21 +73,21 @@ func TestSchema_ResolveFieldByInternalName(t *testing.T) { }{ { testName: "empty schema", - schema: NewSchemaWithAliases(map[FieldName]Field{}, map[FieldName]FieldName{}), + schema: NewSchemaWithAliases(map[FieldName]Field{}, map[FieldName]FieldName{}, false), fieldName: "message", want: Field{}, found: false, }, { testName: "schema with fields with internal separators, lookup by property name", - schema: NewSchema(map[FieldName]Field{"foo.bar": {PropertyName: "foo.bar", InternalPropertyName: "foo::bar", Type: TypeText}}), + schema: NewSchema(map[FieldName]Field{"foo.bar": {PropertyName: "foo.bar", InternalPropertyName: "foo::bar", Type: TypeText}}, false), fieldName: "foo.bar", want: Field{}, found: false, }, { testName: "schema with fields with internal separators, lookup by internal name", - schema: NewSchema(map[FieldName]Field{"foo.bar": {PropertyName: "foo.bar", InternalPropertyName: "foo::bar", Type: TypeText}}), + schema: NewSchema(map[FieldName]Field{"foo.bar": {PropertyName: "foo.bar", InternalPropertyName: "foo::bar", Type: TypeText}}, false), fieldName: "foo::bar", want: Field{PropertyName: "foo.bar", InternalPropertyName: "foo::bar", Type: TypeText}, found: true, @@ -95,7 +95,7 @@ func TestSchema_ResolveFieldByInternalName(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - s := NewSchemaWithAliases(tt.schema.Fields, tt.schema.Aliases) + s := NewSchemaWithAliases(tt.schema.Fields, tt.schema.Aliases, false) got, found := s.ResolveFieldByInternalName(tt.fieldName) if !reflect.DeepEqual(got, tt.want) { t.Errorf("ResolveFieldByInternalName() got = %v, want %v", got, tt.want)