Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return correct response if unique index violation happened on SQLite backend #3353

Merged
merged 4 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 9 additions & 16 deletions integration/update_compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ type updateCompatTestCase struct {
resultType compatTestCaseResultType // defaults to nonEmptyResult
providers []shareddata.Provider // defaults to shareddata.AllProviders()

skip string // skips test if non-empty
skipForSQLite string // optional, if set, the case is skipped for SQLite due to given issue
skip string // skips test if non-empty
}

// testUpdateCompat tests update compatibility test cases.
Expand All @@ -59,10 +58,6 @@ func testUpdateCompat(t *testing.T, testCases map[string]updateCompatTestCase) {
t.Skip(tc.skip)
}

if tc.skipForSQLite != "" {
t.Skip(tc.skipForSQLite)
}

t.Parallel()

providers := shareddata.AllProviders()
Expand Down Expand Up @@ -554,18 +549,16 @@ func TestUpdateCompat(t *testing.T) {
replace: bson.D{},
},
"ReplaceNonExistentUpsert": {
filter: bson.D{{"non-existent", "no-match"}},
replace: bson.D{{"_id", "new"}},
replaceOpts: options.Replace().SetUpsert(true),
resultType: emptyResult,
skipForSQLite: "https://github.com/FerretDB/FerretDB/issues/3183",
filter: bson.D{{"non-existent", "no-match"}},
replace: bson.D{{"_id", "new"}},
replaceOpts: options.Replace().SetUpsert(true),
resultType: emptyResult,
},
"UpdateNonExistentUpsert": {
filter: bson.D{{"_id", "non-existent"}},
update: bson.D{{"$set", bson.D{{"v", int32(42)}}}},
updateOpts: options.Update().SetUpsert(true),
resultType: emptyResult,
skipForSQLite: "https://github.com/FerretDB/FerretDB/issues/3183",
filter: bson.D{{"_id", "non-existent"}},
update: bson.D{{"$set", bson.D{{"v", int32(42)}}}},
updateOpts: options.Update().SetUpsert(true),
resultType: emptyResult,
},
}

Expand Down
19 changes: 18 additions & 1 deletion internal/handlers/sqlite/msg_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,32 @@
// TODO https://github.com/FerretDB/FerretDB/issues/2612
_ = params.Ordered

var we *writeError

matched, modified, upserted, err := h.updateDocument(ctx, params)
if err != nil {
return nil, lazyerrors.Error(err)
switch {
case backends.ErrorCodeIs(err, backends.ErrorCodeInsertDuplicateID):
// TODO https://github.com/FerretDB/FerretDB/issues/3263
we = &writeError{
index: int32(0),
code: commonerrors.ErrDuplicateKeyInsert,
errmsg: fmt.Sprintf(`E11000 duplicate key error collection: %s.%s`, params.DB, params.Collection),
}

Check warning on line 58 in internal/handlers/sqlite/msg_update.go

View check run for this annotation

Codecov / codecov/patch

internal/handlers/sqlite/msg_update.go#L52-L58

Added lines #L52 - L58 were not covered by tests

default:
return nil, lazyerrors.Error(err)
}
}

res := must.NotFail(types.NewDocument(
"n", matched,
))

if we != nil {
res.Set("writeErrors", must.NotFail(types.NewArray(we.Document())))
}

Check warning on line 71 in internal/handlers/sqlite/msg_update.go

View check run for this annotation

Codecov / codecov/patch

internal/handlers/sqlite/msg_update.go#L70-L71

Added lines #L70 - L71 were not covered by tests

if upserted.Len() != 0 {
res.Set("upserted", upserted)
}
Expand Down
Loading