From a372c8c037671cb6e52ce4afb95db71f61c181f3 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Mon, 11 Dec 2023 16:29:22 -0700 Subject: [PATCH] GODRIVER-2698 Make Comment fields any-type on all options structs and setters (#1454) --- .../unified/client_operation_execution.go | 6 +- .../unified/collection_operation_execution.go | 24 +---- internal/integration/unified/crud_helpers.go | 11 --- internal/integration/unified/matches.go | 43 -------- mongo/change_stream.go | 10 +- mongo/collection.go | 67 +++++++------ mongo/collection_test.go | 97 +++++++++++++++++++ mongo/options/aggregateoptions.go | 11 ++- mongo/options/changestreamoptions.go | 11 ++- mongo/options/countoptions.go | 9 +- mongo/options/findoptions.go | 20 ++-- testdata/change-streams/change-streams.json | 1 - testdata/change-streams/change-streams.yml | 1 - testdata/crud/unified/aggregate.json | 1 - testdata/crud/unified/aggregate.yml | 1 - .../crud/unified/countDocuments-comment.json | 1 - testdata/crud/unified/find-comment.json | 1 - x/mongo/driver/operation/aggregate.go | 13 ++- x/mongo/driver/operation/find.go | 12 +-- 19 files changed, 183 insertions(+), 157 deletions(-) diff --git a/internal/integration/unified/client_operation_execution.go b/internal/integration/unified/client_operation_execution.go index 506ca4f351..99f5884d2f 100644 --- a/internal/integration/unified/client_operation_execution.go +++ b/internal/integration/unified/client_operation_execution.go @@ -55,11 +55,7 @@ func executeCreateChangeStream(ctx context.Context, operation *operation) (*oper } opts.SetCollation(*collation) case "comment": - commentString, err := createCommentString(val) - if err != nil { - return nil, fmt.Errorf("error creating comment: %v", err) - } - opts.SetComment(commentString) + opts.SetComment(val) case "fullDocument": switch fd := val.StringValue(); fd { case "default": diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index fc5c884791..8cfb2ef3af 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -60,13 +60,7 @@ func executeAggregate(ctx context.Context, operation *operation) (*operationResu } opts.SetCollation(collation) case "comment": - // TODO(GODRIVER-2386): when document support for comments is added, we can replace this switch condition - // TODO with `opts.SetComment(val)` - commentString, err := createCommentString(val) - if err != nil { - return nil, fmt.Errorf("error creating comment: %v", err) - } - opts.SetComment(commentString) + opts.SetComment(val) case "hint": hint, err := createHint(val) if err != nil { @@ -188,13 +182,7 @@ func executeCountDocuments(ctx context.Context, operation *operation) (*operatio } opts.SetCollation(collation) case "comment": - // TODO(GODRIVER-2386): when document support for comments is added, we can replace this switch condition - // TODO with `opts.SetComment(val)` - commentString, err := createCommentString(val) - if err != nil { - return nil, fmt.Errorf("error creating comment: %v", err) - } - opts.SetComment(commentString) + opts.SetComment(val) case "filter": filter = val.Document() case "hint": @@ -1393,13 +1381,7 @@ func createFindCursor(ctx context.Context, operation *operation) (*cursorResult, } opts.SetCollation(collation) case "comment": - // TODO(GODRIVER-2386): when document support for comments is added, we can replace this switch condition - // TODO with `opts.SetComment(val)` - commentString, err := createCommentString(val) - if err != nil { - return nil, fmt.Errorf("error creating comment: %v", err) - } - opts.SetComment(commentString) + opts.SetComment(val) case "filter": filter = val.Document() case "hint": diff --git a/internal/integration/unified/crud_helpers.go b/internal/integration/unified/crud_helpers.go index 245d0e02a9..5a9adb8005 100644 --- a/internal/integration/unified/crud_helpers.go +++ b/internal/integration/unified/crud_helpers.go @@ -159,14 +159,3 @@ func createHint(val bson.RawValue) (interface{}, error) { } return hint, nil } - -func createCommentString(val bson.RawValue) (string, error) { - switch val.Type { - case bsontype.String: - return val.StringValue(), nil - case bsontype.EmbeddedDocument: - return val.String(), nil - default: - return "", fmt.Errorf("unrecognized 'comment' value type: %T", val) - } -} diff --git a/internal/integration/unified/matches.go b/internal/integration/unified/matches.go index 51df30a7dd..6968c00126 100644 --- a/internal/integration/unified/matches.go +++ b/internal/integration/unified/matches.go @@ -97,18 +97,6 @@ func verifyValuesMatchInner(ctx context.Context, expected, actual bson.RawValue) return newMatchingError(fullKeyPath, "key not found in actual document") } - // Check to see if the keypath requires us to convert actual/expected to make a true comparison. If the - // comparison is not supported for the keypath, continue with the recursive strategy. - // - // TODO(GODRIVER-2386): this branch of logic will be removed once we add document support for comments - mixedTypeEvaluated, err := evaluateMixedTypeComparison(expectedKey, expectedValue, actualValue) - if err != nil { - return newMatchingError(fullKeyPath, "error doing mixed-type matching assertion: %v", err) - } - if mixedTypeEvaluated { - continue - } - // Nested documents cannot have extra keys, so we unconditionally pass false for extraKeysAllowed. comparisonCtx := makeMatchContext(ctx, fullKeyPath, false) if err := verifyValuesMatchInner(comparisonCtx, expectedValue, actualValue); err != nil { @@ -185,37 +173,6 @@ func verifyValuesMatchInner(ctx context.Context, expected, actual bson.RawValue) return nil } -// compareDocumentToString will compare an expected document to an actual string by converting the document into a -// string. -func compareDocumentToString(expected, actual bson.RawValue) error { - expectedDocument, ok := expected.DocumentOK() - if !ok { - return fmt.Errorf("expected value to be a document but got a %s", expected.Type) - } - - actualString, ok := actual.StringValueOK() - if !ok { - return fmt.Errorf("expected value to be a string but got a %s", actual.Type) - } - - if actualString != expectedDocument.String() { - return fmt.Errorf("expected value %s, got %s", expectedDocument.String(), actualString) - } - return nil -} - -// evaluateMixedTypeComparison compares an expected document with an actual string. If this comparison occurs, then -// the function will return `true` along with any resulting error. -func evaluateMixedTypeComparison(expectedKey string, expected, actual bson.RawValue) (bool, error) { - switch expectedKey { - case "comment": - if expected.Type == bsontype.EmbeddedDocument && actual.Type == bsontype.String { - return true, compareDocumentToString(expected, actual) - } - } - return false, nil -} - func evaluateSpecialComparison(ctx context.Context, assertionDoc bson.Raw, actual bson.RawValue) error { assertionElem := assertionDoc.Index(0) assertion := assertionElem.Key() diff --git a/mongo/change_stream.go b/mongo/change_stream.go index ca0b5fa3b8..1012aac9f0 100644 --- a/mongo/change_stream.go +++ b/mongo/change_stream.go @@ -191,14 +191,14 @@ func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline in if cs.options.Collation != nil { cs.aggregate.Collation(bsoncore.Document(cs.options.Collation.ToDocument())) } - if comment := cs.options.Comment; comment != nil { - cs.aggregate.Comment(*comment) - - commentVal, err := marshalValue(comment, cs.bsonOpts, cs.registry) + if cs.options.Comment != nil { + comment, err := marshalValue(cs.options.Comment, cs.bsonOpts, cs.registry) if err != nil { return nil, err } - cs.cursorOptions.Comment = commentVal + + cs.aggregate.Comment(comment) + cs.cursorOptions.Comment = comment } if cs.options.BatchSize != nil { cs.aggregate.BatchSize(*cs.options.BatchSize) diff --git a/mongo/collection.go b/mongo/collection.go index 8d7fd288cc..37214b9153 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1046,13 +1046,13 @@ func aggregate(a aggregateParams) (cur *Cursor, err error) { cursorOpts.MaxTimeMS = int64(*ao.MaxAwaitTime / time.Millisecond) } if ao.Comment != nil { - op.Comment(*ao.Comment) - - commentVal, err := marshalValue(ao.Comment, a.bsonOpts, a.registry) + comment, err := marshalValue(ao.Comment, a.bsonOpts, a.registry) if err != nil { return nil, err } - cursorOpts.Comment = commentVal + + op.Comment(comment) + cursorOpts.Comment = comment } if ao.Hint != nil { if isUnorderedMap(ao.Hint) { @@ -1176,7 +1176,12 @@ func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, op.Collation(bsoncore.Document(countOpts.Collation.ToDocument())) } if countOpts.Comment != nil { - op.Comment(*countOpts.Comment) + comment, err := marshalValue(countOpts.Comment, coll.bsonOpts, coll.registry) + if err != nil { + return 0, err + } + + op.Comment(comment) } if countOpts.Hint != nil { if isUnorderedMap(countOpts.Hint) { @@ -1531,13 +1536,13 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, op.Collation(bsoncore.Document(fo.Collation.ToDocument())) } if fo.Comment != nil { - op.Comment(*fo.Comment) - - commentVal, err := marshalValue(fo.Comment, coll.bsonOpts, coll.registry) + comment, err := marshalValue(fo.Comment, coll.bsonOpts, coll.registry) if err != nil { return nil, err } - cursorOpts.Comment = commentVal + + op.Comment(comment) + cursorOpts.Comment = comment } if fo.CursorType != nil { switch *fo.CursorType { @@ -1637,27 +1642,13 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, return newCursorWithSession(bc, coll.bsonOpts, coll.registry, sess) } -// FindOne executes a find command and returns a SingleResult for one document in the collection. -// -// The filter parameter must be a document containing query operators and can be used to select the document to be -// returned. It cannot be nil. If the filter does not match any documents, a SingleResult with an error set to -// ErrNoDocuments will be returned. If the filter matches multiple documents, one will be selected from the matched set. -// -// The opts parameter can be used to specify options for this operation (see the options.FindOneOptions documentation). -// -// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/find/. -func (coll *Collection) FindOne(ctx context.Context, filter interface{}, - opts ...*options.FindOneOptions) *SingleResult { - - if ctx == nil { - ctx = context.Background() - } - +func newFindOptionsFromFindOneOptions(opts ...*options.FindOneOptions) []*options.FindOptions { findOpts := make([]*options.FindOptions, 0, len(opts)) for _, opt := range opts { if opt == nil { continue } + findOpts = append(findOpts, &options.FindOptions{ AllowPartialResults: opt.AllowPartialResults, Collation: opt.Collation, @@ -1673,11 +1664,31 @@ func (coll *Collection) FindOne(ctx context.Context, filter interface{}, Sort: opt.Sort, }) } - // Unconditionally send a limit to make sure only one document is returned and the cursor is not kept open - // by the server. + + // Unconditionally send a limit to make sure only one document is returned and + // the cursor is not kept open by the server. findOpts = append(findOpts, options.Find().SetLimit(-1)) - cursor, err := coll.Find(ctx, filter, findOpts...) + return findOpts +} + +// FindOne executes a find command and returns a SingleResult for one document in the collection. +// +// The filter parameter must be a document containing query operators and can be used to select the document to be +// returned. It cannot be nil. If the filter does not match any documents, a SingleResult with an error set to +// ErrNoDocuments will be returned. If the filter matches multiple documents, one will be selected from the matched set. +// +// The opts parameter can be used to specify options for this operation (see the options.FindOneOptions documentation). +// +// For more information about the command, see https://www.mongodb.com/docs/manual/reference/command/find/. +func (coll *Collection) FindOne(ctx context.Context, filter interface{}, + opts ...*options.FindOneOptions) *SingleResult { + + if ctx == nil { + ctx = context.Background() + } + + cursor, err := coll.Find(ctx, filter, newFindOptionsFromFindOneOptions(opts...)...) return &SingleResult{ ctx: ctx, cur: cursor, diff --git a/mongo/collection_test.go b/mongo/collection_test.go index 86dc85848a..355cae09cd 100644 --- a/mongo/collection_test.go +++ b/mongo/collection_test.go @@ -217,3 +217,100 @@ func TestCollection(t *testing.T) { assert.Equal(t, aggErr, err, "expected error %v, got %v", aggErr, err) }) } + +func TestNewFindOptionsFromFindOneOptions(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + opts []*options.FindOneOptions + want []*options.FindOptions + }{ + { + name: "nil", + opts: nil, + want: []*options.FindOptions{ + options.Find().SetLimit(-1), + }, + }, + { + name: "empty", + opts: []*options.FindOneOptions{}, + want: []*options.FindOptions{ + options.Find().SetLimit(-1), + }, + }, + { + name: "singleton", + opts: []*options.FindOneOptions{ + options.FindOne().SetSkip(1), + }, + want: []*options.FindOptions{ + options.Find().SetSkip(1), + options.Find().SetLimit(-1), + }, + }, + { + name: "multiplicity", + opts: []*options.FindOneOptions{ + options.FindOne().SetSkip(1), + options.FindOne().SetSkip(2), + }, + want: []*options.FindOptions{ + options.Find().SetSkip(1), + options.Find().SetSkip(2), + options.Find().SetLimit(-1), + }, + }, + { + name: "interior null", + opts: []*options.FindOneOptions{ + options.FindOne().SetSkip(1), + nil, + options.FindOne().SetSkip(2), + }, + want: []*options.FindOptions{ + options.Find().SetSkip(1), + options.Find().SetSkip(2), + options.Find().SetLimit(-1), + }, + }, + { + name: "start null", + opts: []*options.FindOneOptions{ + nil, + options.FindOne().SetSkip(1), + options.FindOne().SetSkip(2), + }, + want: []*options.FindOptions{ + options.Find().SetSkip(1), + options.Find().SetSkip(2), + options.Find().SetLimit(-1), + }, + }, + { + name: "end null", + opts: []*options.FindOneOptions{ + options.FindOne().SetSkip(1), + options.FindOne().SetSkip(2), + nil, + }, + want: []*options.FindOptions{ + options.Find().SetSkip(1), + options.Find().SetSkip(2), + options.Find().SetLimit(-1), + }, + }, + } + + for _, test := range tests { + test := test // Capture the range variable + + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + got := newFindOptionsFromFindOneOptions(test.opts...) + assert.Equal(t, test.want, got) + }) + } +} diff --git a/mongo/options/aggregateoptions.go b/mongo/options/aggregateoptions.go index 9fcafcaf73..6a8c26faab 100644 --- a/mongo/options/aggregateoptions.go +++ b/mongo/options/aggregateoptions.go @@ -44,9 +44,10 @@ type AggregateOptions struct { // This option is only valid for MongoDB versions >= 3.2 and is ignored for previous server versions. MaxAwaitTime *time.Duration - // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. - // The default is nil, which means that no comment will be included in the logs. - Comment *string + // A string or document that will be included in server logs, profiling logs, + // and currentOp queries to help trace the operation. The default is nil, + // which means that no comment will be included in the logs. + Comment interface{} // The index to use for the aggregation. This should either be the index name as a string or the index specification // as a document. The hint does not apply to $lookup and $graphLookup aggregation stages. The driver will return an @@ -111,8 +112,8 @@ func (ao *AggregateOptions) SetMaxAwaitTime(d time.Duration) *AggregateOptions { } // SetComment sets the value for the Comment field. -func (ao *AggregateOptions) SetComment(s string) *AggregateOptions { - ao.Comment = &s +func (ao *AggregateOptions) SetComment(comment interface{}) *AggregateOptions { + ao.Comment = comment return ao } diff --git a/mongo/options/changestreamoptions.go b/mongo/options/changestreamoptions.go index 3c84b83458..060226f955 100644 --- a/mongo/options/changestreamoptions.go +++ b/mongo/options/changestreamoptions.go @@ -23,9 +23,10 @@ type ChangeStreamOptions struct { // default value is nil, which means the default collation of the collection will be used. Collation *Collation - // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. - // The default is nil, which means that no comment will be included in the logs. - Comment *string + // A string or document that will be included in server logs, profiling logs, + // and currentOp queries to help trace the operation. The default is nil, + // which means that no comment will be included in the logs. + Comment interface{} // Specifies how the updated document should be returned in change notifications for update operations. The default // is options.Default, which means that only partial update deltas will be included in the change notification. @@ -90,8 +91,8 @@ func (cso *ChangeStreamOptions) SetCollation(c Collation) *ChangeStreamOptions { } // SetComment sets the value for the Comment field. -func (cso *ChangeStreamOptions) SetComment(comment string) *ChangeStreamOptions { - cso.Comment = &comment +func (cso *ChangeStreamOptions) SetComment(comment interface{}) *ChangeStreamOptions { + cso.Comment = comment return cso } diff --git a/mongo/options/countoptions.go b/mongo/options/countoptions.go index 677d3e4e2a..a47550f6d2 100644 --- a/mongo/options/countoptions.go +++ b/mongo/options/countoptions.go @@ -15,12 +15,9 @@ type CountOptions struct { // default value is nil, which means the default collation of the collection will be used. Collation *Collation - // TODO(GODRIVER-2386): CountOptions executor uses aggregation under the hood, which means this type has to be - // TODO a string for now. This can be replaced with `Comment interface{}` once 2386 is implemented. - // A string or document that will be included in server logs, profiling logs, and currentOp queries to help trace // the operation. The default is nil, which means that no comment will be included in the logs. - Comment *string + Comment interface{} // The index to use for the aggregation. This should either be the index name as a string or the index specification // as a document. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, @@ -55,8 +52,8 @@ func (co *CountOptions) SetCollation(c *Collation) *CountOptions { } // SetComment sets the value for the Comment field. -func (co *CountOptions) SetComment(c string) *CountOptions { - co.Comment = &c +func (co *CountOptions) SetComment(comment interface{}) *CountOptions { + co.Comment = comment return co } diff --git a/mongo/options/findoptions.go b/mongo/options/findoptions.go index 93c4787e98..705fefc3f3 100644 --- a/mongo/options/findoptions.go +++ b/mongo/options/findoptions.go @@ -30,9 +30,10 @@ type FindOptions struct { // default value is nil, which means the default collation of the collection will be used. Collation *Collation - // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. - // The default is nil, which means that no comment will be included in the logs. - Comment *string + // A string or document that will be included in server logs, profiling logs, + // and currentOp queries to help trace the operation. The default is nil, + // which means that no comment will be included in the logs. + Comment interface{} // CursorType specifies the type of cursor that should be created for the operation. The default is NonTailable, which // means that the cursor will be closed by the server when the last batch of documents is retrieved. @@ -129,8 +130,8 @@ func (f *FindOptions) SetCollation(collation *Collation) *FindOptions { } // SetComment sets the value for the Comment field. -func (f *FindOptions) SetComment(comment string) *FindOptions { - f.Comment = &comment +func (f *FindOptions) SetComment(comment interface{}) *FindOptions { + f.Comment = comment return f } @@ -233,9 +234,10 @@ type FindOneOptions struct { // default value is nil, which means the default collation of the collection will be used. Collation *Collation - // A string that will be included in server logs, profiling logs, and currentOp queries to help trace the operation. - // The default is nil, which means that no comment will be included in the logs. - Comment *string + // A string or document that will be included in server logs, profiling logs, + // and currentOp queries to help trace the operation. The default is nil, + // which means that no comment will be included in the logs. + Comment interface{} // The index to use for the aggregation. This should either be the index name as a string or the index specification // as a document. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, @@ -296,7 +298,7 @@ func (f *FindOneOptions) SetCollation(collation *Collation) *FindOneOptions { } // SetComment sets the value for the Comment field. -func (f *FindOneOptions) SetComment(comment string) *FindOneOptions { +func (f *FindOneOptions) SetComment(comment interface{}) *FindOneOptions { f.Comment = &comment return f } diff --git a/testdata/change-streams/change-streams.json b/testdata/change-streams/change-streams.json index d03fde97e5..c8b60ed4e2 100644 --- a/testdata/change-streams/change-streams.json +++ b/testdata/change-streams/change-streams.json @@ -232,7 +232,6 @@ }, { "description": "Test with document comment - pre 4.4", - "skipReason": "TODO(GODRIVER-2386): aggregate only supports string comments", "runOnRequirements": [ { "maxServerVersion": "4.2.99" diff --git a/testdata/change-streams/change-streams.yml b/testdata/change-streams/change-streams.yml index 113c80f50d..3235533b5d 100644 --- a/testdata/change-streams/change-streams.yml +++ b/testdata/change-streams/change-streams.yml @@ -140,7 +140,6 @@ tests: comment: *comment0 - description: "Test with document comment - pre 4.4" - skipReason: "TODO(GODRIVER-2386): aggregate only supports string comments" runOnRequirements: - maxServerVersion: "4.2.99" operations: diff --git a/testdata/crud/unified/aggregate.json b/testdata/crud/unified/aggregate.json index b5a70e6299..2e46e74ef7 100644 --- a/testdata/crud/unified/aggregate.json +++ b/testdata/crud/unified/aggregate.json @@ -268,7 +268,6 @@ }, { "description": "aggregate with a document comment - pre 4.4", - "skipReason": "TODO(GODRIVER-2386): aggregate only supports string comments", "runOnRequirements": [ { "minServerVersion": "3.6.0", diff --git a/testdata/crud/unified/aggregate.yml b/testdata/crud/unified/aggregate.yml index 02f07770f4..e0f47f5a43 100644 --- a/testdata/crud/unified/aggregate.yml +++ b/testdata/crud/unified/aggregate.yml @@ -103,7 +103,6 @@ tests: comment: *comment0 - description: "aggregate with a document comment - pre 4.4" - skipReason: "TODO(GODRIVER-2386): aggregate only supports string comments" runOnRequirements: - minServerVersion: "3.6.0" maxServerVersion: "4.2.99" diff --git a/testdata/crud/unified/countDocuments-comment.json b/testdata/crud/unified/countDocuments-comment.json index 547274c9d0..e6c7ae8170 100644 --- a/testdata/crud/unified/countDocuments-comment.json +++ b/testdata/crud/unified/countDocuments-comment.json @@ -150,7 +150,6 @@ }, { "description": "countDocuments with document comment on less than 4.4.0 - server error", - "skipReason": "TODO(GODRIVER-2386): aggregate only supports string comments", "runOnRequirements": [ { "minServerVersion": "3.6.0", diff --git a/testdata/crud/unified/find-comment.json b/testdata/crud/unified/find-comment.json index 44312aed94..600a3723f1 100644 --- a/testdata/crud/unified/find-comment.json +++ b/testdata/crud/unified/find-comment.json @@ -150,7 +150,6 @@ }, { "description": "find with document comment - pre 4.4", - "skipReason": "TODO(GODRIVER-2386): aggregate only supports string comments", "runOnRequirements": [ { "maxServerVersion": "4.2.99", diff --git a/x/mongo/driver/operation/aggregate.go b/x/mongo/driver/operation/aggregate.go index ca0e796523..d7f29be676 100644 --- a/x/mongo/driver/operation/aggregate.go +++ b/x/mongo/driver/operation/aggregate.go @@ -29,7 +29,7 @@ type Aggregate struct { batchSize *int32 bypassDocumentValidation *bool collation bsoncore.Document - comment *string + comment bsoncore.Value hint bsoncore.Value maxTime *time.Duration pipeline bsoncore.Document @@ -143,9 +143,8 @@ func (a *Aggregate) command(dst []byte, desc description.SelectedServer) ([]byte } dst = bsoncore.AppendDocumentElement(dst, "collation", a.collation) } - if a.comment != nil { - - dst = bsoncore.AppendStringElement(dst, "comment", *a.comment) + if a.comment.Type != bsontype.Type(0) { + dst = bsoncore.AppendValueElement(dst, "comment", a.comment) } if a.hint.Type != bsontype.Type(0) { @@ -207,13 +206,13 @@ func (a *Aggregate) Collation(collation bsoncore.Document) *Aggregate { return a } -// Comment specifies an arbitrary string to help trace the operation through the database profiler, currentOp, and logs. -func (a *Aggregate) Comment(comment string) *Aggregate { +// Comment sets a value to help trace an operation. +func (a *Aggregate) Comment(comment bsoncore.Value) *Aggregate { if a == nil { a = new(Aggregate) } - a.comment = &comment + a.comment = comment return a } diff --git a/x/mongo/driver/operation/find.go b/x/mongo/driver/operation/find.go index 27bb5b4f99..656ef409e3 100644 --- a/x/mongo/driver/operation/find.go +++ b/x/mongo/driver/operation/find.go @@ -30,7 +30,7 @@ type Find struct { awaitData *bool batchSize *int32 collation bsoncore.Document - comment *string + comment bsoncore.Value filter bsoncore.Document hint bsoncore.Value let bsoncore.Document @@ -137,8 +137,8 @@ func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, err } dst = bsoncore.AppendDocumentElement(dst, "collation", f.collation) } - if f.comment != nil { - dst = bsoncore.AppendStringElement(dst, "comment", *f.comment) + if f.comment.Type != bsontype.Type(0) { + dst = bsoncore.AppendValueElement(dst, "comment", f.comment) } if f.filter != nil { dst = bsoncore.AppendDocumentElement(dst, "filter", f.filter) @@ -241,13 +241,13 @@ func (f *Find) Collation(collation bsoncore.Document) *Find { return f } -// Comment sets a string to help trace an operation. -func (f *Find) Comment(comment string) *Find { +// Comment sets a value to help trace an operation. +func (f *Find) Comment(comment bsoncore.Value) *Find { if f == nil { f = new(Find) } - f.comment = &comment + f.comment = comment return f }