Skip to content
Closed
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
42 changes: 7 additions & 35 deletions base/bucket_gocb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,27 +573,13 @@ func TestMultiXattrRoundtrip(t *testing.T) {
xattrKeys[2]: []byte(`{"key3": "value3"}`),
}
_, err := dataStore.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"key": "value"}`), inputXattrs, nil, nil)
if dataStore.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
require.NoError(t, err)
} else {
require.ErrorContains(t, err, "invalid xattr key combination")
inputXattrs = map[string][]byte{
xattrKeys[0]: inputXattrs[xattrKeys[0]],
}
// write a document an xattrs, because subsequent GetXattrs needs a document to produce an error without multi-xattr support
_, err := dataStore.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"key": "value"}`), inputXattrs, nil, nil)
require.NoError(t, err)
}
require.NoError(t, err)

xattrs, _, err := dataStore.GetXattrs(ctx, docID, xattrKeys)
if dataStore.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
require.NoError(t, err)
for _, key := range xattrKeys {
require.Contains(t, xattrs, key)
require.JSONEq(t, string(inputXattrs[key]), string(xattrs[key]))
}
} else {
require.ErrorContains(t, err, "not supported")
require.NoError(t, err)
for _, key := range xattrKeys {
require.Contains(t, xattrs, key)
require.JSONEq(t, string(inputXattrs[key]), string(xattrs[key]))
}
}

Expand Down Expand Up @@ -2168,15 +2154,8 @@ func TestUserXattrGetWithXattr(t *testing.T) {
"_sync": MustJSONMarshal(t, syncXattrVal),
"test": MustJSONMarshal(t, userXattrVal),
}
if bucket.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
_, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, xattrs, nil)
require.NoError(t, err)
} else {
for k, v := range xattrs {
cas, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, map[string][]byte{k: v}, nil)
require.NoError(t, err)
}
}
_, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, xattrs, nil)
require.NoError(t, err)
var docValRet map[string]any
docRaw, xattrsResult, _, err := dataStore.GetWithXattrs(ctx, docKey, []string{SyncXattrName, "test"})
require.NoError(t, JSONUnmarshal(docRaw, &docValRet))
Expand Down Expand Up @@ -2549,10 +2528,6 @@ func TestWriteWithXattrsXattrWriteXattrDelete(t *testing.T) {
xattrBody := []byte(`{"some": "val"}`)

cas, err := collection.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"foo": "bar"}`), map[string][]byte{xattr1Name: xattrBody, xattr2Name: xattrBody}, nil, nil)
if !collection.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
require.ErrorContains(t, err, "SUBDOC_XATTR_INVALID_KEY_COMBO")
return
}
require.NoError(t, err)

newXattrBody := []byte(`{"another" : "val"}`)
Expand Down Expand Up @@ -2589,9 +2564,6 @@ func TestWriteUpdateWithXattrsDocumentTombstone(t *testing.T) {
ctx := TestCtx(t)
bucket := GetTestBucket(t)
defer bucket.Close(ctx)
if !bucket.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
t.Skip("this test writes multiple xattrs")
}
dataStore := bucket.GetSingleDataStore()
key := t.Name()

Expand Down
38 changes: 1 addition & 37 deletions base/collection_xattr.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,6 @@ func (c *Collection) SubdocWrite(ctx context.Context, k string, subdocKey string

// subdocGetBodyAndXattrs retrieves the document body and xattrs in a single LookupIn subdoc operation. Does not require both to exist.
func (c *Collection) subdocGetBodyAndXattrs(ctx context.Context, k string, xattrKeys []string, fetchBody bool) (isTombstone bool, rawBody []byte, xattrs map[string][]byte, cas uint64, err error) {
xattrKey2 := ""
// Backward compatibility for one system xattr and one user xattr support.
if !c.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
if len(xattrKeys) > 2 {
return false, nil, nil, 0, fmt.Errorf("subdocGetBodyAndXattrs: more than 2 xattrKeys %+v not supported in this version of Couchbase Server", xattrKeys)
}
if len(xattrKeys) == 2 {
xattrKey2 = xattrKeys[1]
xattrKeys = []string{xattrKeys[0]}
}
}
xattrs = make(map[string][]byte, len(xattrKeys))
worker := func() (shouldRetry bool, err error, value uint64) {

Expand Down Expand Up @@ -283,29 +272,7 @@ func (c *Collection) subdocGetBodyAndXattrs(ctx context.Context, k string, xattr
shouldRetry = c.isRecoverableReadError(lookupErr)
return shouldRetry, lookupErr, uint64(0)
}
// If BucketStoreFeatureMultiXattrSubdocOperations is not supported, do a second get for the second xattr.
if xattrKey2 != "" {
xattrs2, xattr2Cas, xattr2Err := c.GetXattrs(ctx, k, []string{xattrKey2})
switch pkgerrors.Cause(xattr2Err) {
case gocb.ErrDocumentNotFound:
// If key not found it has been deleted in between the first op and this op.
return false, err, xattr2Cas
case ErrXattrNotFound:
// Xattr doesn't exist, can skip
case nil:
if cas != xattr2Cas {
return true, errors.New("cas mismatch between user xattr and document body"), uint64(0)
}
default:
// Unknown error occurred
// Shouldn't retry as any recoverable error will have been retried already in GetXattrs
return false, xattr2Err, uint64(0)
}
xattr2, ok := xattrs2[xattrKey2]
if ok {
xattrs[xattrKey2] = xattr2
}
}

return false, nil, cas
}

Expand Down Expand Up @@ -427,9 +394,6 @@ func (c *Collection) UpdateXattrs(ctx context.Context, k string, exp uint32, cas
}

func (c *Collection) updateXattrs(ctx context.Context, k string, exp uint32, cas uint64, xattrs map[string][]byte, xattrsToDelete []string, opts *sgbucket.MutateInOptions) (casOut uint64, err error) {
if !c.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) && len(xattrs) >= 2 {
return 0, fmt.Errorf("UpdateXattrs: more than 1 xattr %v not supported in UpdateXattrs in this version of Couchbase Server", xattrs)
}
if cas == 0 && len(xattrsToDelete) > 0 {
return 0, sgbucket.ErrDeleteXattrOnDocumentInsert
}
Expand Down
Loading