github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/storage/mvcc_test.go (about)

     1  // Copyright 2014 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package storage
    12  
    13  import (
    14  	"bytes"
    15  	"context"
    16  	"fmt"
    17  	"math"
    18  	"math/rand"
    19  	"reflect"
    20  	"sort"
    21  	"strconv"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/cockroachdb/cockroach/pkg/keys"
    27  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    28  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    29  	"github.com/cockroachdb/cockroach/pkg/testutils"
    30  	"github.com/cockroachdb/cockroach/pkg/testutils/zerofields"
    31  	"github.com/cockroachdb/cockroach/pkg/util/caller"
    32  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    33  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    34  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    35  	"github.com/cockroachdb/cockroach/pkg/util/log"
    36  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    37  	"github.com/cockroachdb/cockroach/pkg/util/randutil"
    38  	"github.com/cockroachdb/cockroach/pkg/util/shuffle"
    39  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    40  	"github.com/cockroachdb/errors"
    41  	"github.com/gogo/protobuf/proto"
    42  	"github.com/kr/pretty"
    43  	"github.com/stretchr/testify/require"
    44  )
    45  
    46  // Constants for system-reserved keys in the KV map.
    47  var (
    48  	keyMin       = roachpb.KeyMin
    49  	keyMax       = roachpb.KeyMax
    50  	testKey1     = roachpb.Key("/db1")
    51  	testKey2     = roachpb.Key("/db2")
    52  	testKey3     = roachpb.Key("/db3")
    53  	testKey4     = roachpb.Key("/db4")
    54  	testKey5     = roachpb.Key("/db5")
    55  	testKey6     = roachpb.Key("/db6")
    56  	txn1ID       = uuid.MakeV4()
    57  	txn2ID       = uuid.MakeV4()
    58  	txn1TS       = hlc.Timestamp{Logical: 1}
    59  	txn2TS       = hlc.Timestamp{Logical: 2}
    60  	txn1         = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn1ID, Epoch: 1, WriteTimestamp: txn1TS, MinTimestamp: txn1TS}, ReadTimestamp: txn1TS}
    61  	txn1Commit   = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn1ID, Epoch: 1, WriteTimestamp: txn1TS, MinTimestamp: txn1TS}, ReadTimestamp: txn1TS, Status: roachpb.COMMITTED}
    62  	txn1Abort    = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn1ID, Epoch: 1, WriteTimestamp: txn1TS, MinTimestamp: txn1TS}, Status: roachpb.ABORTED}
    63  	txn1e2       = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn1ID, Epoch: 2, WriteTimestamp: txn1TS, MinTimestamp: txn1TS}, ReadTimestamp: txn1TS}
    64  	txn1e2Commit = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn1ID, Epoch: 2, WriteTimestamp: txn1TS, MinTimestamp: txn1TS}, ReadTimestamp: txn1TS, Status: roachpb.COMMITTED}
    65  	txn2         = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn2ID, WriteTimestamp: txn2TS, MinTimestamp: txn2TS}, ReadTimestamp: txn2TS}
    66  	txn2Commit   = &roachpb.Transaction{TxnMeta: enginepb.TxnMeta{Key: roachpb.Key("a"), ID: txn2ID, WriteTimestamp: txn2TS, MinTimestamp: txn2TS}, ReadTimestamp: txn2TS, Status: roachpb.COMMITTED}
    67  	value1       = roachpb.MakeValueFromString("testValue1")
    68  	value2       = roachpb.MakeValueFromString("testValue2")
    69  	value3       = roachpb.MakeValueFromString("testValue3")
    70  	value4       = roachpb.MakeValueFromString("testValue4")
    71  	value5       = roachpb.MakeValueFromString("testValue5")
    72  	value6       = roachpb.MakeValueFromString("testValue6")
    73  	tsvalue1     = timeSeriesRowAsValue(testtime, 1000, []tsSample{
    74  		{1, 1, 5, 5, 5},
    75  	}...)
    76  	tsvalue2 = timeSeriesRowAsValue(testtime, 1000, []tsSample{
    77  		{1, 1, 15, 15, 15},
    78  	}...)
    79  )
    80  
    81  // createTestRocksDBEngine returns a new in-memory RocksDB engine with 1MB of
    82  // storage capacity.
    83  func createTestRocksDBEngine() Engine {
    84  	return newRocksDBInMem(roachpb.Attributes{}, 1<<20)
    85  }
    86  
    87  // createTestPebbleEngine returns a new in-memory Pebble storage engine.
    88  func createTestPebbleEngine() Engine {
    89  	return newPebbleInMem(context.Background(), roachpb.Attributes{}, 1<<20)
    90  }
    91  
    92  var mvccEngineImpls = []struct {
    93  	name   string
    94  	create func() Engine
    95  }{
    96  	{"rocksdb", createTestRocksDBEngine},
    97  	{"pebble", createTestPebbleEngine},
    98  }
    99  
   100  // makeTxn creates a new transaction using the specified base
   101  // txn and timestamp.
   102  func makeTxn(baseTxn roachpb.Transaction, ts hlc.Timestamp) *roachpb.Transaction {
   103  	txn := baseTxn.Clone()
   104  	txn.ReadTimestamp = ts
   105  	txn.DeprecatedOrigTimestamp = ts
   106  	txn.WriteTimestamp = ts
   107  	return txn
   108  }
   109  
   110  func mvccVersionKey(key roachpb.Key, ts hlc.Timestamp) MVCCKey {
   111  	return MVCCKey{Key: key, Timestamp: ts}
   112  }
   113  
   114  type mvccKeys []MVCCKey
   115  
   116  func (n mvccKeys) Len() int           { return len(n) }
   117  func (n mvccKeys) Swap(i, j int)      { n[i], n[j] = n[j], n[i] }
   118  func (n mvccKeys) Less(i, j int) bool { return n[i].Less(n[j]) }
   119  
   120  // mvccGetGo is identical to MVCCGet except that it uses mvccGetInternal
   121  // instead of the C++ Iterator.MVCCGet. It is used to test mvccGetInternal
   122  // which is used by mvccPutInternal to avoid Cgo crossings. Simply using the
   123  // C++ MVCCGet in mvccPutInternal causes a significant performance hit to
   124  // conditional put operations.
   125  func mvccGetGo(
   126  	ctx context.Context, reader Reader, key roachpb.Key, timestamp hlc.Timestamp, opts MVCCGetOptions,
   127  ) (*roachpb.Value, *roachpb.Intent, error) {
   128  	if len(key) == 0 {
   129  		return nil, nil, emptyKeyError()
   130  	}
   131  
   132  	iter := reader.NewIterator(IterOptions{Prefix: true})
   133  	defer iter.Close()
   134  
   135  	buf := newGetBuffer()
   136  	defer buf.release()
   137  
   138  	metaKey := MakeMVCCMetadataKey(key)
   139  	ok, _, _, err := mvccGetMetadata(iter, metaKey, &buf.meta)
   140  	if !ok || err != nil {
   141  		return nil, nil, err
   142  	}
   143  
   144  	value, intent, _, err := mvccGetInternal(ctx, iter, metaKey,
   145  		timestamp, !opts.Inconsistent, safeValue, opts.Txn, buf)
   146  	if !value.IsPresent() {
   147  		value = nil
   148  	}
   149  	if value == &buf.value {
   150  		value = &roachpb.Value{}
   151  		*value = buf.value
   152  		buf.value.Reset()
   153  	}
   154  	return value, intent, err
   155  }
   156  
   157  var mvccGetImpls = []struct {
   158  	name string
   159  	fn   func(
   160  		ctx context.Context,
   161  		reader Reader,
   162  		key roachpb.Key,
   163  		timestamp hlc.Timestamp,
   164  		opts MVCCGetOptions,
   165  	) (*roachpb.Value, *roachpb.Intent, error)
   166  }{
   167  	{"cpp", MVCCGet},
   168  	{"go", mvccGetGo},
   169  }
   170  
   171  func TestMVCCStatsAddSubForward(t *testing.T) {
   172  	defer leaktest.AfterTest(t)()
   173  	goldMS := enginepb.MVCCStats{
   174  		ContainsEstimates: 1,
   175  		KeyBytes:          1,
   176  		KeyCount:          1,
   177  		ValBytes:          1,
   178  		ValCount:          1,
   179  		IntentBytes:       1,
   180  		IntentCount:       1,
   181  		IntentAge:         1,
   182  		GCBytesAge:        1,
   183  		LiveBytes:         1,
   184  		LiveCount:         1,
   185  		SysBytes:          1,
   186  		SysCount:          1,
   187  		LastUpdateNanos:   1,
   188  	}
   189  	if err := zerofields.NoZeroField(&goldMS); err != nil {
   190  		t.Fatal(err) // prevent rot as fields are added
   191  	}
   192  
   193  	cmp := func(act, exp enginepb.MVCCStats) {
   194  		t.Helper()
   195  		f, l, _ := caller.Lookup(1)
   196  		if !reflect.DeepEqual(act, exp) {
   197  			t.Fatalf("%s:%d: wanted %+v back, got %+v", f, l, exp, act)
   198  		}
   199  	}
   200  
   201  	ms := goldMS
   202  	zeroWithLU := enginepb.MVCCStats{
   203  		ContainsEstimates: 0,
   204  		LastUpdateNanos:   ms.LastUpdateNanos,
   205  	}
   206  
   207  	ms.Subtract(goldMS)
   208  	cmp(ms, zeroWithLU)
   209  
   210  	ms.Add(goldMS)
   211  	cmp(ms, goldMS)
   212  
   213  	// Double-add double-sub guards against mistaking `+=` for `=`.
   214  	ms = zeroWithLU
   215  	ms.Add(goldMS)
   216  	ms.Add(goldMS)
   217  	ms.Subtract(goldMS)
   218  	ms.Subtract(goldMS)
   219  	cmp(ms, zeroWithLU)
   220  
   221  	// Run some checks for Forward.
   222  	goldDelta := enginepb.MVCCStats{
   223  		KeyBytes:        42,
   224  		IntentCount:     11,
   225  		LastUpdateNanos: 1e9 - 1000,
   226  	}
   227  	delta := goldDelta
   228  
   229  	for i, ns := range []int64{1, 1e9 - 1001, 1e9 - 1000, 1e9 - 1, 1e9, 1e9 + 1, 2e9 - 1} {
   230  		oldDelta := delta
   231  		delta.AgeTo(ns)
   232  		if delta.LastUpdateNanos < ns {
   233  			t.Fatalf("%d: expected LastUpdateNanos < %d, got %d", i, ns, delta.LastUpdateNanos)
   234  		}
   235  		shouldAge := ns/1e9-oldDelta.LastUpdateNanos/1e9 > 0
   236  		didAge := delta.IntentAge != oldDelta.IntentAge &&
   237  			delta.GCBytesAge != oldDelta.GCBytesAge
   238  		if shouldAge != didAge {
   239  			t.Fatalf("%d: should age: %t, but had\n%+v\nand now\n%+v", i, shouldAge, oldDelta, delta)
   240  		}
   241  	}
   242  
   243  	expDelta := goldDelta
   244  	expDelta.LastUpdateNanos = 2e9 - 1
   245  	expDelta.GCBytesAge = 42
   246  	expDelta.IntentAge = 11
   247  	cmp(delta, expDelta)
   248  
   249  	delta.AgeTo(2e9)
   250  	expDelta.LastUpdateNanos = 2e9
   251  	expDelta.GCBytesAge += 42
   252  	expDelta.IntentAge += 11
   253  	cmp(delta, expDelta)
   254  
   255  	{
   256  		// Verify that AgeTo can go backwards in time.
   257  		// Works on a copy.
   258  		tmpDelta := delta
   259  		expDelta := expDelta
   260  
   261  		tmpDelta.AgeTo(2e9 - 1)
   262  		expDelta.LastUpdateNanos = 2e9 - 1
   263  		expDelta.GCBytesAge -= 42
   264  		expDelta.IntentAge -= 11
   265  		cmp(tmpDelta, expDelta)
   266  	}
   267  
   268  	delta.AgeTo(3e9 - 1)
   269  	delta.Forward(5) // should be noop
   270  	expDelta.LastUpdateNanos = 3e9 - 1
   271  	cmp(delta, expDelta)
   272  
   273  	// Check that Add calls Forward appropriately.
   274  	mss := []enginepb.MVCCStats{goldMS, goldMS}
   275  
   276  	mss[0].LastUpdateNanos = 2e9 - 1
   277  	mss[1].LastUpdateNanos = 10e9 + 1
   278  
   279  	expMS := goldMS
   280  	expMS.Add(goldMS)
   281  	expMS.LastUpdateNanos = 10e9 + 1
   282  	expMS.IntentAge += 9  // from aging 9 ticks from 2E9-1 to 10E9+1
   283  	expMS.GCBytesAge += 9 // ditto
   284  
   285  	for i := range mss[:1] {
   286  		ms := mss[(1+i)%2]
   287  		ms.Add(mss[i])
   288  		cmp(ms, expMS)
   289  	}
   290  
   291  	// Finally, check Forward with negative counts (can happen).
   292  	neg := zeroWithLU
   293  	neg.Subtract(goldMS)
   294  	exp := neg
   295  
   296  	neg.AgeTo(2e9)
   297  
   298  	exp.LastUpdateNanos = 2e9
   299  	exp.GCBytesAge = -3
   300  	exp.IntentAge = -3
   301  	cmp(neg, exp)
   302  }
   303  
   304  // Verify the sort ordering of successive keys with metadata and
   305  // versioned values. In particular, the following sequence of keys /
   306  // versions:
   307  //
   308  // a
   309  // a<t=max>
   310  // a<t=1>
   311  // a<t=0>
   312  // a\x00
   313  // a\x00<t=max>
   314  // a\x00<t=1>
   315  // a\x00<t=0>
   316  func TestMVCCKeys(t *testing.T) {
   317  	defer leaktest.AfterTest(t)()
   318  	aKey := roachpb.Key("a")
   319  	a0Key := roachpb.Key("a\x00")
   320  	keys := mvccKeys{
   321  		mvccKey(aKey),
   322  		mvccVersionKey(aKey, hlc.Timestamp{WallTime: math.MaxInt64}),
   323  		mvccVersionKey(aKey, hlc.Timestamp{WallTime: 1}),
   324  		mvccVersionKey(aKey, hlc.Timestamp{Logical: 1}),
   325  		mvccKey(a0Key),
   326  		mvccVersionKey(a0Key, hlc.Timestamp{WallTime: math.MaxInt64}),
   327  		mvccVersionKey(a0Key, hlc.Timestamp{WallTime: 1}),
   328  		mvccVersionKey(a0Key, hlc.Timestamp{Logical: 1}),
   329  	}
   330  	sortKeys := make(mvccKeys, len(keys))
   331  	copy(sortKeys, keys)
   332  	shuffle.Shuffle(sortKeys)
   333  	sort.Sort(sortKeys)
   334  	if !reflect.DeepEqual(sortKeys, keys) {
   335  		t.Errorf("expected keys to sort in order %s, but got %s", keys, sortKeys)
   336  	}
   337  }
   338  
   339  func TestMVCCGetNotExist(t *testing.T) {
   340  	defer leaktest.AfterTest(t)()
   341  
   342  	for _, engineImpl := range mvccEngineImpls {
   343  		t.Run(engineImpl.name, func(t *testing.T) {
   344  			for _, impl := range mvccGetImpls {
   345  				t.Run(impl.name, func(t *testing.T) {
   346  					mvccGet := impl.fn
   347  
   348  					engine := engineImpl.create()
   349  					defer engine.Close()
   350  
   351  					value, _, err := mvccGet(context.Background(), engine, testKey1, hlc.Timestamp{Logical: 1},
   352  						MVCCGetOptions{})
   353  					if err != nil {
   354  						t.Fatal(err)
   355  					}
   356  					if value != nil {
   357  						t.Fatal("the value should be empty")
   358  					}
   359  				})
   360  			}
   361  		})
   362  	}
   363  }
   364  
   365  func TestMVCCGetNoMoreOldVersion(t *testing.T) {
   366  	defer leaktest.AfterTest(t)()
   367  
   368  	ctx := context.Background()
   369  
   370  	for _, engineImpl := range mvccEngineImpls {
   371  		t.Run(engineImpl.name, func(t *testing.T) {
   372  			for _, impl := range mvccGetImpls {
   373  				t.Run(impl.name, func(t *testing.T) {
   374  					mvccGet := impl.fn
   375  
   376  					// Need to handle the case here where the scan takes us to the
   377  					// next key, which may not match the key we're looking for. In
   378  					// other words, if we're looking for a<T=2>, and we have the
   379  					// following keys:
   380  					//
   381  					// a: MVCCMetadata(a)
   382  					// a<T=3>
   383  					// b: MVCCMetadata(b)
   384  					// b<T=1>
   385  					//
   386  					// If we search for a<T=2>, the scan should not return "b".
   387  
   388  					engine := engineImpl.create()
   389  					defer engine.Close()
   390  
   391  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, value1, nil); err != nil {
   392  						t.Fatal(err)
   393  					}
   394  					if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
   395  						t.Fatal(err)
   396  					}
   397  
   398  					value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{})
   399  					if err != nil {
   400  						t.Fatal(err)
   401  					}
   402  					if value != nil {
   403  						t.Fatal("the value should be empty")
   404  					}
   405  				})
   406  			}
   407  		})
   408  	}
   409  }
   410  
   411  // TestMVCCGetUncertainty verifies that the appropriate error results when
   412  // a transaction reads a key at a timestamp that has versions newer than that
   413  // timestamp, but older than the transaction's MaxTimestamp.
   414  func TestMVCCGetUncertainty(t *testing.T) {
   415  	defer leaktest.AfterTest(t)()
   416  
   417  	ctx := context.Background()
   418  
   419  	for _, engineImpl := range mvccEngineImpls {
   420  		t.Run(engineImpl.name, func(t *testing.T) {
   421  			for _, impl := range mvccGetImpls {
   422  				t.Run(impl.name, func(t *testing.T) {
   423  					mvccGet := impl.fn
   424  					engine := engineImpl.create()
   425  					defer engine.Close()
   426  
   427  					// Txn with read timestamp 7 and MaxTimestamp 10.
   428  					txn := &roachpb.Transaction{
   429  						TxnMeta: enginepb.TxnMeta{
   430  							ID:             uuid.MakeV4(),
   431  							WriteTimestamp: hlc.Timestamp{WallTime: 7},
   432  						},
   433  						MaxTimestamp: hlc.Timestamp{WallTime: 10},
   434  					}
   435  					getOptsTxn := MVCCGetOptions{Txn: txn}
   436  					scanOptsTxn := MVCCScanOptions{Txn: txn}
   437  
   438  					// Same txn but with a MaxTimestamp reduced to 9.
   439  					txnMaxTS9 := txn.Clone()
   440  					txnMaxTS9.MaxTimestamp = hlc.Timestamp{WallTime: 9}
   441  					getOptsTxnMaxTS9 := MVCCGetOptions{Txn: txnMaxTS9}
   442  					scanOptsTxnMaxTS9 := MVCCScanOptions{Txn: txnMaxTS9}
   443  
   444  					// Same txn but with a MaxTimestamp reduced to 7.
   445  					txnMaxTS7 := txn.Clone()
   446  					txnMaxTS7.MaxTimestamp = hlc.Timestamp{WallTime: 7}
   447  					getOptsTxnMaxTS7 := MVCCGetOptions{Txn: txnMaxTS7}
   448  					scanOptsTxnMaxTS7 := MVCCScanOptions{Txn: txnMaxTS7}
   449  
   450  					// Case 1: One value in the past, one value in the future of read
   451  					// and ahead of MaxTimestamp of read. Neither should interfere.
   452  					//
   453  					// -----------------
   454  					// - 12: val2
   455  					// |
   456  					// - 10: max timestamp
   457  					// |
   458  					// -  7: read timestamp
   459  					// |
   460  					// -  1: val1
   461  					// -----------------
   462  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
   463  						t.Fatal(err)
   464  					}
   465  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 12}, value2, nil); err != nil {
   466  						t.Fatal(err)
   467  					}
   468  					// Read with transaction, should get a value back.
   469  					if val, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 7}, getOptsTxn); err != nil {
   470  						t.Fatal(err)
   471  					} else if val == nil || !bytes.Equal(val.RawBytes, value1.RawBytes) {
   472  						t.Fatalf("wanted %q, got %v", value1.RawBytes, val)
   473  					}
   474  					if res, err := MVCCScan(
   475  						ctx, engine, testKey1, testKey1.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxn,
   476  					); err != nil {
   477  						t.Fatal(err)
   478  					} else if len(res.KVs) != 1 {
   479  						t.Fatalf("wanted 1 kv, got %d", len(res.KVs))
   480  					} else if val := res.KVs[0].Value; !bytes.Equal(val.RawBytes, value1.RawBytes) {
   481  						t.Fatalf("wanted %q, got %v", value1.RawBytes, val)
   482  					}
   483  
   484  					// Case 2a: One value in the future of read but below MaxTimestamp
   485  					// of read. Should result in a ReadWithinUncertaintyIntervalError
   486  					// when reading.
   487  					//
   488  					// -----------------
   489  					// - 10: max timestamp
   490  					// -  9: val2
   491  					// |
   492  					// -  7: read timestamp
   493  					// -----------------
   494  					if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 9}, value2, nil); err != nil {
   495  						t.Fatal(err)
   496  					}
   497  					// Read with transaction, should get error back.
   498  					if _, _, err := mvccGet(ctx, engine, testKey2, hlc.Timestamp{WallTime: 7}, getOptsTxn); err == nil {
   499  						t.Fatal("wanted an error")
   500  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   501  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   502  					}
   503  					if _, err := MVCCScan(
   504  						ctx, engine, testKey2, testKey2.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxn,
   505  					); err == nil {
   506  						t.Fatal("wanted an error")
   507  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   508  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   509  					}
   510  					// Case 2b: Reduce MaxTimestamp to exactly that of value in future.
   511  					// Should result in a ReadWithinUncertaintyIntervalError when
   512  					// reading.
   513  					//
   514  					// -----------------
   515  					// -  9: val2 & max timestamp
   516  					// |
   517  					// -  7: read timestamp
   518  					// -----------------
   519  					if _, _, err := mvccGet(ctx, engine, testKey2, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS9); err == nil {
   520  						t.Fatal("wanted an error")
   521  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   522  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   523  					}
   524  					if _, err := MVCCScan(
   525  						ctx, engine, testKey2, testKey2.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS9,
   526  					); err == nil {
   527  						t.Fatal("wanted an error")
   528  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   529  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   530  					}
   531  					// Case 2c: Reduce MaxTimestamp below value in future. Value should
   532  					// no longer interfere when reading.
   533  					//
   534  					// -----------------
   535  					// -  9: val2
   536  					// |
   537  					// -  7: read timestamp & max timestamp
   538  					// -----------------
   539  					if _, _, err := mvccGet(ctx, engine, testKey2, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS7); err != nil {
   540  						t.Fatal(err)
   541  					}
   542  					if _, err := MVCCScan(
   543  						ctx, engine, testKey2, testKey2.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS7,
   544  					); err != nil {
   545  						t.Fatal(err)
   546  					}
   547  
   548  					// Case 3a: One intent in the future of read but below MaxTimestamp
   549  					// of read. Should result in a WriteIntentError when reading.
   550  					//
   551  					// -----------------
   552  					// - 10: max timestamp
   553  					// -  9: val2 (intent)
   554  					// |
   555  					// -  7: read timestamp
   556  					// -----------------
   557  					intentTxn := &roachpb.Transaction{
   558  						TxnMeta: enginepb.TxnMeta{
   559  							ID:             uuid.MakeV4(),
   560  							WriteTimestamp: hlc.Timestamp{WallTime: 9},
   561  						},
   562  						ReadTimestamp: hlc.Timestamp{WallTime: 9},
   563  					}
   564  					if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 9}, value2, intentTxn); err != nil {
   565  						t.Fatal(err)
   566  					}
   567  					// Read with transaction, should get error back.
   568  					if _, _, err := mvccGet(ctx, engine, testKey3, hlc.Timestamp{WallTime: 7}, getOptsTxn); err == nil {
   569  						t.Fatal("wanted an error")
   570  					} else if !errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
   571  						t.Fatalf("wanted a WriteIntentError, got %+v", err)
   572  					}
   573  					if _, err := MVCCScan(
   574  						ctx, engine, testKey3, testKey3.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxn,
   575  					); err == nil {
   576  						t.Fatal("wanted an error")
   577  					} else if !errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
   578  						t.Fatalf("wanted a WriteIntentError, got %+v", err)
   579  					}
   580  					// Case 3b: Reduce MaxTimestamp to exactly that of intent in future.
   581  					// Should result in a WriteIntentError when reading.
   582  					//
   583  					// -----------------
   584  					// -  9: val2 (intent) & max timestamp
   585  					// |
   586  					// -  7: read timestamp
   587  					// -----------------
   588  					if _, _, err := mvccGet(ctx, engine, testKey3, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS9); err == nil {
   589  						t.Fatal("wanted an error")
   590  					} else if !errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
   591  						t.Fatalf("wanted a WriteIntentError, got %+v", err)
   592  					}
   593  					if _, err := MVCCScan(
   594  						ctx, engine, testKey3, testKey3.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS9,
   595  					); err == nil {
   596  						t.Fatal("wanted an error")
   597  					} else if !errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
   598  						t.Fatalf("wanted a WriteIntentError, got %+v", err)
   599  					}
   600  					// Case 3c: Reduce MaxTimestamp below intent in future. Intent should
   601  					// no longer interfere when reading.
   602  					//
   603  					// -----------------
   604  					// -  9: val2 (intent)
   605  					// |
   606  					// -  7: read timestamp & max timestamp
   607  					// -----------------
   608  					if _, _, err := mvccGet(ctx, engine, testKey3, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS7); err != nil {
   609  						t.Fatal(err)
   610  					}
   611  					if _, err := MVCCScan(
   612  						ctx, engine, testKey3, testKey3.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS7,
   613  					); err != nil {
   614  						t.Fatal(err)
   615  					}
   616  
   617  					// Case 4a: Two values in future of read. One is ahead of
   618  					// MaxTimestamp of read and one is below MaxTimestamp of read. The
   619  					// value within the read's uncertainty interval should result in a
   620  					// ReadWithinUncertaintyIntervalError when reading.
   621  					//
   622  					// -----------------
   623  					// - 99: val3
   624  					// |
   625  					// - 10: max timestamp
   626  					// -  9: val2
   627  					// |
   628  					// -  7: read timestamp
   629  					// -----------------
   630  					if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 9}, value2, nil); err != nil {
   631  						t.Fatal(err)
   632  					}
   633  					if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 99}, value3, nil); err != nil {
   634  						t.Fatal(err)
   635  					}
   636  					if _, _, err := mvccGet(ctx, engine, testKey4, hlc.Timestamp{WallTime: 7}, getOptsTxn); err == nil {
   637  						t.Fatalf("wanted an error")
   638  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   639  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   640  					}
   641  					if _, err := MVCCScan(
   642  						ctx, engine, testKey4, testKey4.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxn,
   643  					); err == nil {
   644  						t.Fatal("wanted an error")
   645  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   646  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   647  					}
   648  					// Case 4b: Reduce MaxTimestamp to exactly that of second value in
   649  					// future. The value within the read's uncertainty interval should
   650  					// result in a ReadWithinUncertaintyIntervalError when reading.
   651  					//
   652  					// -----------------
   653  					// - 99: val3
   654  					// |
   655  					// -  9: val2 & max timestamp
   656  					// |
   657  					// -  7: read timestamp
   658  					// -----------------
   659  					if _, _, err := mvccGet(ctx, engine, testKey4, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS9); err == nil {
   660  						t.Fatalf("wanted an error")
   661  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   662  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   663  					}
   664  					if _, err := MVCCScan(
   665  						ctx, engine, testKey4, testKey4.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS9,
   666  					); err == nil {
   667  						t.Fatal("wanted an error")
   668  					} else if !errors.HasType(err, (*roachpb.ReadWithinUncertaintyIntervalError)(nil)) {
   669  						t.Fatalf("wanted a ReadWithinUncertaintyIntervalError, got %+v", err)
   670  					}
   671  					// Case 4c: Reduce MaxTimestamp below second value in future. Value should
   672  					// no longer interfere when reading.
   673  					//
   674  					// -----------------
   675  					// - 99: val3
   676  					// |
   677  					// -  9: val2
   678  					// |
   679  					// -  7: read timestamp & max timestamp
   680  					// -----------------
   681  					if _, _, err := mvccGet(ctx, engine, testKey4, hlc.Timestamp{WallTime: 7}, getOptsTxnMaxTS7); err != nil {
   682  						t.Fatal(err)
   683  					}
   684  					if _, err := MVCCScan(
   685  						ctx, engine, testKey4, testKey4.PrefixEnd(), hlc.Timestamp{WallTime: 7}, scanOptsTxnMaxTS7,
   686  					); err != nil {
   687  						t.Fatal(err)
   688  					}
   689  				})
   690  			}
   691  		})
   692  	}
   693  }
   694  
   695  func TestMVCCGetAndDelete(t *testing.T) {
   696  	defer leaktest.AfterTest(t)()
   697  
   698  	ctx := context.Background()
   699  
   700  	for _, engineImpl := range mvccEngineImpls {
   701  		t.Run(engineImpl.name, func(t *testing.T) {
   702  			for _, impl := range mvccGetImpls {
   703  				t.Run(impl.name, func(t *testing.T) {
   704  					mvccGet := impl.fn
   705  
   706  					engine := engineImpl.create()
   707  					defer engine.Close()
   708  
   709  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
   710  						t.Fatal(err)
   711  					}
   712  					value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{})
   713  					if err != nil {
   714  						t.Fatal(err)
   715  					}
   716  					if value == nil {
   717  						t.Fatal("the value should not be empty")
   718  					}
   719  
   720  					err = MVCCDelete(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, nil)
   721  					if err != nil {
   722  						t.Fatal(err)
   723  					}
   724  
   725  					// Read the latest version which should be deleted.
   726  					value, _, err = mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 4}, MVCCGetOptions{})
   727  					if err != nil {
   728  						t.Fatal(err)
   729  					}
   730  					if value != nil {
   731  						t.Fatal("the value should be empty")
   732  					}
   733  					// Read the latest version with tombstone.
   734  					value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 4},
   735  						MVCCGetOptions{Tombstones: true})
   736  					if err != nil {
   737  						t.Fatal(err)
   738  					} else if value == nil || len(value.RawBytes) != 0 {
   739  						t.Fatalf("the value should be non-nil with empty RawBytes; got %+v", value)
   740  					}
   741  
   742  					// Read the old version which should still exist.
   743  					for _, logical := range []int32{0, math.MaxInt32} {
   744  						value, _, err = mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2, Logical: logical},
   745  							MVCCGetOptions{})
   746  						if err != nil {
   747  							t.Fatal(err)
   748  						}
   749  						if value == nil {
   750  							t.Fatal("the value should not be empty")
   751  						}
   752  					}
   753  				})
   754  			}
   755  		})
   756  	}
   757  }
   758  
   759  // TestMVCCWriteWithOlderTimestampAfterDeletionOfNonexistentKey tests a write
   760  // that comes after a delete on a nonexistent key, with the write holding a
   761  // timestamp earlier than the delete timestamp. The delete must write a
   762  // tombstone with its timestamp in order to push the write's timestamp.
   763  func TestMVCCWriteWithOlderTimestampAfterDeletionOfNonexistentKey(t *testing.T) {
   764  	defer leaktest.AfterTest(t)()
   765  	for _, engineImpl := range mvccEngineImpls {
   766  		t.Run(engineImpl.name, func(t *testing.T) {
   767  			engine := engineImpl.create()
   768  			defer engine.Close()
   769  
   770  			if err := MVCCDelete(
   771  				context.Background(), engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, nil,
   772  			); err != nil {
   773  				t.Fatal(err)
   774  			}
   775  
   776  			if err := MVCCPut(
   777  				context.Background(), engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil,
   778  			); !testutils.IsError(
   779  				err, "write at timestamp 0.000000001,0 too old; wrote at 0.000000003,1",
   780  			) {
   781  				t.Fatal(err)
   782  			}
   783  
   784  			value, _, err := MVCCGet(context.Background(), engine, testKey1, hlc.Timestamp{WallTime: 2},
   785  				MVCCGetOptions{})
   786  			if err != nil {
   787  				t.Fatal(err)
   788  			}
   789  			// The attempted write at ts(1,0) was performed at ts(3,1), so we should
   790  			// not see it at ts(2,0).
   791  			if value != nil {
   792  				t.Fatalf("value present at TS = %s", value.Timestamp)
   793  			}
   794  
   795  			// Read the latest version which will be the value written with the timestamp pushed.
   796  			value, _, err = MVCCGet(context.Background(), engine, testKey1, hlc.Timestamp{WallTime: 4},
   797  				MVCCGetOptions{})
   798  			if err != nil {
   799  				t.Fatal(err)
   800  			}
   801  			if value == nil {
   802  				t.Fatal("value doesn't exist")
   803  			}
   804  			if !bytes.Equal(value.RawBytes, value1.RawBytes) {
   805  				t.Errorf("expected %q; got %q", value1.RawBytes, value.RawBytes)
   806  			}
   807  			if expTS := (hlc.Timestamp{WallTime: 3, Logical: 1}); value.Timestamp != expTS {
   808  				t.Fatalf("timestamp was not pushed: %s, expected %s", value.Timestamp, expTS)
   809  			}
   810  		})
   811  	}
   812  }
   813  
   814  func TestMVCCInlineWithTxn(t *testing.T) {
   815  	defer leaktest.AfterTest(t)()
   816  
   817  	ctx := context.Background()
   818  	for _, engineImpl := range mvccEngineImpls {
   819  		t.Run(engineImpl.name, func(t *testing.T) {
   820  			engine := engineImpl.create()
   821  			defer engine.Close()
   822  
   823  			// Put an inline value.
   824  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{}, value1, nil); err != nil {
   825  				t.Fatal(err)
   826  			}
   827  
   828  			// Now verify inline get.
   829  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{}, MVCCGetOptions{})
   830  			if err != nil {
   831  				t.Fatal(err)
   832  			}
   833  			if !reflect.DeepEqual(value1, *value) {
   834  				t.Errorf("the inline value should be %v; got %v", value1, *value)
   835  			}
   836  
   837  			// Verify inline get with txn does still work (this will happen on a
   838  			// scan if the distributed sender is forced to wrap it in a txn).
   839  			if _, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{}, MVCCGetOptions{
   840  				Txn: txn1,
   841  			}); err != nil {
   842  				t.Error(err)
   843  			}
   844  
   845  			// Verify inline put with txn is an error.
   846  			err = MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{}, value2, txn2)
   847  			if !testutils.IsError(err, "writes not allowed within transactions") {
   848  				t.Errorf("unexpected error: %+v", err)
   849  			}
   850  		})
   851  	}
   852  }
   853  
   854  func TestMVCCDeleteMissingKey(t *testing.T) {
   855  	defer leaktest.AfterTest(t)()
   856  
   857  	ctx := context.Background()
   858  	for _, engineImpl := range mvccEngineImpls {
   859  		t.Run(engineImpl.name, func(t *testing.T) {
   860  			engine := engineImpl.create()
   861  			defer engine.Close()
   862  
   863  			if err := MVCCDelete(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, nil); err != nil {
   864  				t.Fatal(err)
   865  			}
   866  			// Verify nothing is written to the engine.
   867  			if val, err := engine.Get(mvccKey(testKey1)); err != nil || val != nil {
   868  				t.Fatalf("expected no mvcc metadata after delete of a missing key; got %q: %+v", val, err)
   869  			}
   870  		})
   871  	}
   872  }
   873  
   874  func TestMVCCGetAndDeleteInTxn(t *testing.T) {
   875  	defer leaktest.AfterTest(t)()
   876  
   877  	ctx := context.Background()
   878  
   879  	for _, engineImpl := range mvccEngineImpls {
   880  		t.Run(engineImpl.name, func(t *testing.T) {
   881  			for _, impl := range mvccGetImpls {
   882  				t.Run(impl.name, func(t *testing.T) {
   883  					mvccGet := impl.fn
   884  
   885  					engine := engineImpl.create()
   886  					defer engine.Close()
   887  
   888  					txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
   889  					txn.Sequence++
   890  					if err := MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value1, txn); err != nil {
   891  						t.Fatal(err)
   892  					}
   893  
   894  					if value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{
   895  						Txn: txn,
   896  					}); err != nil {
   897  						t.Fatal(err)
   898  					} else if value == nil {
   899  						t.Fatal("the value should not be empty")
   900  					}
   901  
   902  					txn.Sequence++
   903  					txn.WriteTimestamp = hlc.Timestamp{WallTime: 3}
   904  					if err := MVCCDelete(ctx, engine, nil, testKey1, txn.ReadTimestamp, txn); err != nil {
   905  						t.Fatal(err)
   906  					}
   907  
   908  					// Read the latest version which should be deleted.
   909  					if value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 4}, MVCCGetOptions{
   910  						Txn: txn,
   911  					}); err != nil {
   912  						t.Fatal(err)
   913  					} else if value != nil {
   914  						t.Fatal("the value should be empty")
   915  					}
   916  					// Read the latest version with tombstone.
   917  					if value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 4}, MVCCGetOptions{
   918  						Tombstones: true,
   919  						Txn:        txn,
   920  					}); err != nil {
   921  						t.Fatal(err)
   922  					} else if value == nil || len(value.RawBytes) != 0 {
   923  						t.Fatalf("the value should be non-nil with empty RawBytes; got %+v", value)
   924  					}
   925  
   926  					// Read the old version which shouldn't exist, as within a
   927  					// transaction, we delete previous values.
   928  					if value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{}); err != nil {
   929  						t.Fatal(err)
   930  					} else if value != nil {
   931  						t.Fatalf("expected value nil, got: %s", value)
   932  					}
   933  				})
   934  			}
   935  		})
   936  	}
   937  }
   938  
   939  func TestMVCCGetWriteIntentError(t *testing.T) {
   940  	defer leaktest.AfterTest(t)()
   941  
   942  	ctx := context.Background()
   943  
   944  	for _, engineImpl := range mvccEngineImpls {
   945  		t.Run(engineImpl.name, func(t *testing.T) {
   946  			for _, impl := range mvccGetImpls {
   947  				t.Run(impl.name, func(t *testing.T) {
   948  					mvccGet := impl.fn
   949  
   950  					engine := engineImpl.create()
   951  					defer engine.Close()
   952  
   953  					if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
   954  						t.Fatal(err)
   955  					}
   956  
   957  					if _, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{}); err == nil {
   958  						t.Fatal("cannot read the value of a write intent without TxnID")
   959  					}
   960  
   961  					if _, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
   962  						Txn: txn2,
   963  					}); err == nil {
   964  						t.Fatal("cannot read the value of a write intent from a different TxnID")
   965  					}
   966  				})
   967  			}
   968  		})
   969  	}
   970  }
   971  
   972  func mkVal(s string, ts hlc.Timestamp) roachpb.Value {
   973  	v := roachpb.MakeValueFromString(s)
   974  	v.Timestamp = ts
   975  	return v
   976  }
   977  
   978  func TestMVCCScanWriteIntentError(t *testing.T) {
   979  	defer leaktest.AfterTest(t)()
   980  
   981  	ctx := context.Background()
   982  	for _, engineImpl := range mvccEngineImpls {
   983  		t.Run(engineImpl.name, func(t *testing.T) {
   984  			engine := engineImpl.create()
   985  			defer engine.Close()
   986  
   987  			ts := []hlc.Timestamp{{Logical: 1}, {Logical: 2}, {Logical: 3}, {Logical: 4}, {Logical: 5}, {Logical: 6}}
   988  
   989  			txn1ts := makeTxn(*txn1, ts[2])
   990  			txn2ts := makeTxn(*txn2, ts[5])
   991  
   992  			fixtureKVs := []roachpb.KeyValue{
   993  				{Key: testKey1, Value: mkVal("testValue1 pre", ts[0])},
   994  				{Key: testKey4, Value: mkVal("testValue4 pre", ts[1])},
   995  				{Key: testKey1, Value: mkVal("testValue1", ts[2])},
   996  				{Key: testKey2, Value: mkVal("testValue2", ts[3])},
   997  				{Key: testKey3, Value: mkVal("testValue3", ts[4])},
   998  				{Key: testKey4, Value: mkVal("testValue4", ts[5])},
   999  			}
  1000  			for i, kv := range fixtureKVs {
  1001  				var txn *roachpb.Transaction
  1002  				if i == 2 {
  1003  					txn = txn1ts
  1004  				} else if i == 5 {
  1005  					txn = txn2ts
  1006  				}
  1007  				v := *protoutil.Clone(&kv.Value).(*roachpb.Value)
  1008  				v.Timestamp = hlc.Timestamp{}
  1009  				if err := MVCCPut(ctx, engine, nil, kv.Key, kv.Value.Timestamp, v, txn); err != nil {
  1010  					t.Fatal(err)
  1011  				}
  1012  			}
  1013  
  1014  			scanCases := []struct {
  1015  				consistent bool
  1016  				txn        *roachpb.Transaction
  1017  				expIntents []roachpb.Intent
  1018  				expValues  []roachpb.KeyValue
  1019  			}{
  1020  				{
  1021  					consistent: true,
  1022  					txn:        nil,
  1023  					expIntents: []roachpb.Intent{
  1024  						roachpb.MakeIntent(&txn1ts.TxnMeta, testKey1),
  1025  						roachpb.MakeIntent(&txn2ts.TxnMeta, testKey4),
  1026  					},
  1027  					// would be []roachpb.KeyValue{fixtureKVs[3], fixtureKVs[4]} without WriteIntentError
  1028  					expValues: nil,
  1029  				},
  1030  				{
  1031  					consistent: true,
  1032  					txn:        txn1ts,
  1033  					expIntents: []roachpb.Intent{
  1034  						roachpb.MakeIntent(&txn2ts.TxnMeta, testKey4),
  1035  					},
  1036  					expValues: nil, // []roachpb.KeyValue{fixtureKVs[2], fixtureKVs[3], fixtureKVs[4]},
  1037  				},
  1038  				{
  1039  					consistent: true,
  1040  					txn:        txn2ts,
  1041  					expIntents: []roachpb.Intent{
  1042  						roachpb.MakeIntent(&txn1ts.TxnMeta, testKey1),
  1043  					},
  1044  					expValues: nil, // []roachpb.KeyValue{fixtureKVs[3], fixtureKVs[4], fixtureKVs[5]},
  1045  				},
  1046  				{
  1047  					consistent: false,
  1048  					txn:        nil,
  1049  					expIntents: []roachpb.Intent{
  1050  						roachpb.MakeIntent(&txn1ts.TxnMeta, testKey1),
  1051  						roachpb.MakeIntent(&txn2ts.TxnMeta, testKey4),
  1052  					},
  1053  					expValues: []roachpb.KeyValue{fixtureKVs[0], fixtureKVs[3], fixtureKVs[4], fixtureKVs[1]},
  1054  				},
  1055  			}
  1056  
  1057  			for i, scan := range scanCases {
  1058  				cStr := "inconsistent"
  1059  				if scan.consistent {
  1060  					cStr = "consistent"
  1061  				}
  1062  				res, err := MVCCScan(ctx, engine, testKey1, testKey4.Next(),
  1063  					hlc.Timestamp{WallTime: 1}, MVCCScanOptions{Inconsistent: !scan.consistent, Txn: scan.txn})
  1064  				var wiErr *roachpb.WriteIntentError
  1065  				_ = errors.As(err, &wiErr)
  1066  				if (err == nil) != (wiErr == nil) {
  1067  					t.Errorf("%s(%d): unexpected error: %+v", cStr, i, err)
  1068  				}
  1069  
  1070  				if wiErr == nil != !scan.consistent {
  1071  					t.Errorf("%s(%d): expected write intent error; got %s", cStr, i, err)
  1072  					continue
  1073  				}
  1074  
  1075  				intents := res.Intents
  1076  				kvs := res.KVs
  1077  				if len(intents) > 0 != !scan.consistent {
  1078  					t.Errorf("%s(%d): expected different intents slice; got %+v", cStr, i, intents)
  1079  					continue
  1080  				}
  1081  
  1082  				if scan.consistent {
  1083  					intents = wiErr.Intents
  1084  				}
  1085  
  1086  				if !reflect.DeepEqual(intents, scan.expIntents) {
  1087  					t.Fatalf("%s(%d): expected intents:\n%+v;\n got\n%+v", cStr, i, scan.expIntents, intents)
  1088  				}
  1089  
  1090  				if !reflect.DeepEqual(kvs, scan.expValues) {
  1091  					t.Errorf("%s(%d): expected values %+v; got %+v", cStr, i, scan.expValues, kvs)
  1092  				}
  1093  			}
  1094  		})
  1095  	}
  1096  }
  1097  
  1098  // TestMVCCGetInconsistent verifies the behavior of get with
  1099  // consistent set to false.
  1100  func TestMVCCGetInconsistent(t *testing.T) {
  1101  	defer leaktest.AfterTest(t)()
  1102  
  1103  	ctx := context.Background()
  1104  
  1105  	for _, engineImpl := range mvccEngineImpls {
  1106  		t.Run(engineImpl.name, func(t *testing.T) {
  1107  			for _, impl := range mvccGetImpls {
  1108  				t.Run(impl.name, func(t *testing.T) {
  1109  					mvccGet := impl.fn
  1110  
  1111  					engine := engineImpl.create()
  1112  					defer engine.Close()
  1113  
  1114  					// Put two values to key 1, the latest with a txn.
  1115  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1116  						t.Fatal(err)
  1117  					}
  1118  					txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 2})
  1119  					if err := MVCCPut(ctx, engine, nil, testKey1, txn1ts.ReadTimestamp, value2, txn1ts); err != nil {
  1120  						t.Fatal(err)
  1121  					}
  1122  
  1123  					// A get with consistent=false should fail in a txn.
  1124  					if _, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
  1125  						Inconsistent: true,
  1126  						Txn:          txn1,
  1127  					}); err == nil {
  1128  						t.Error("expected an error getting with consistent=false in txn")
  1129  					}
  1130  
  1131  					// Inconsistent get will fetch value1 for any timestamp.
  1132  					for _, ts := range []hlc.Timestamp{{WallTime: 1}, {WallTime: 2}} {
  1133  						val, intent, err := mvccGet(ctx, engine, testKey1, ts, MVCCGetOptions{Inconsistent: true})
  1134  						if ts.Less(hlc.Timestamp{WallTime: 2}) {
  1135  							if err != nil {
  1136  								t.Fatal(err)
  1137  							}
  1138  						} else {
  1139  							if intent == nil || !intent.Key.Equal(testKey1) {
  1140  								t.Fatalf("expected %v, but got %v", testKey1, intent)
  1141  							}
  1142  						}
  1143  						if !bytes.Equal(val.RawBytes, value1.RawBytes) {
  1144  							t.Errorf("@%s expected %q; got %q", ts, value1.RawBytes, val.RawBytes)
  1145  						}
  1146  					}
  1147  
  1148  					// Write a single intent for key 2 and verify get returns empty.
  1149  					if err := MVCCPut(ctx, engine, nil, testKey2, txn2.ReadTimestamp, value1, txn2); err != nil {
  1150  						t.Fatal(err)
  1151  					}
  1152  					val, intent, err := mvccGet(ctx, engine, testKey2, hlc.Timestamp{WallTime: 2},
  1153  						MVCCGetOptions{Inconsistent: true})
  1154  					if intent == nil || !intent.Key.Equal(testKey2) {
  1155  						t.Fatal(err)
  1156  					}
  1157  					if val != nil {
  1158  						t.Errorf("expected empty val; got %+v", val)
  1159  					}
  1160  				})
  1161  			}
  1162  		})
  1163  	}
  1164  }
  1165  
  1166  // TestMVCCGetProtoInconsistent verifies the behavior of GetProto with
  1167  // consistent set to false.
  1168  func TestMVCCGetProtoInconsistent(t *testing.T) {
  1169  	defer leaktest.AfterTest(t)()
  1170  
  1171  	ctx := context.Background()
  1172  	for _, engineImpl := range mvccEngineImpls {
  1173  		t.Run(engineImpl.name, func(t *testing.T) {
  1174  			engine := engineImpl.create()
  1175  			defer engine.Close()
  1176  
  1177  			bytes1, err := protoutil.Marshal(&value1)
  1178  			if err != nil {
  1179  				t.Fatal(err)
  1180  			}
  1181  			bytes2, err := protoutil.Marshal(&value2)
  1182  			if err != nil {
  1183  				t.Fatal(err)
  1184  			}
  1185  
  1186  			v1 := roachpb.MakeValueFromBytes(bytes1)
  1187  			v2 := roachpb.MakeValueFromBytes(bytes2)
  1188  
  1189  			// Put two values to key 1, the latest with a txn.
  1190  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, v1, nil); err != nil {
  1191  				t.Fatal(err)
  1192  			}
  1193  			txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 2})
  1194  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1ts.ReadTimestamp, v2, txn1ts); err != nil {
  1195  				t.Fatal(err)
  1196  			}
  1197  
  1198  			// An inconsistent get should fail in a txn.
  1199  			if _, err := MVCCGetProto(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, nil, MVCCGetOptions{
  1200  				Inconsistent: true,
  1201  				Txn:          txn1,
  1202  			}); err == nil {
  1203  				t.Error("expected an error getting inconsistently in txn")
  1204  			} else if errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
  1205  				t.Error("expected non-WriteIntentError with inconsistent read in txn")
  1206  			}
  1207  
  1208  			// Inconsistent get will fetch value1 for any timestamp.
  1209  
  1210  			for _, ts := range []hlc.Timestamp{{WallTime: 1}, {WallTime: 2}} {
  1211  				val := roachpb.Value{}
  1212  				found, err := MVCCGetProto(ctx, engine, testKey1, ts, &val, MVCCGetOptions{
  1213  					Inconsistent: true,
  1214  				})
  1215  				if ts.Less(hlc.Timestamp{WallTime: 2}) {
  1216  					if err != nil {
  1217  						t.Fatal(err)
  1218  					}
  1219  				} else if err != nil {
  1220  					t.Fatal(err)
  1221  				}
  1222  				if !found {
  1223  					t.Errorf("expected to find result with inconsistent read")
  1224  				}
  1225  				valBytes, err := val.GetBytes()
  1226  				if err != nil {
  1227  					t.Fatal(err)
  1228  				}
  1229  				if !bytes.Equal(valBytes, []byte("testValue1")) {
  1230  					t.Errorf("@%s expected %q; got %q", ts, []byte("value1"), valBytes)
  1231  				}
  1232  			}
  1233  
  1234  			{
  1235  				// Write a single intent for key 2 and verify get returns empty.
  1236  				if err := MVCCPut(ctx, engine, nil, testKey2, txn2.ReadTimestamp, v1, txn2); err != nil {
  1237  					t.Fatal(err)
  1238  				}
  1239  				val := roachpb.Value{}
  1240  				found, err := MVCCGetProto(ctx, engine, testKey2, hlc.Timestamp{WallTime: 2}, &val, MVCCGetOptions{
  1241  					Inconsistent: true,
  1242  				})
  1243  				if err != nil {
  1244  					t.Fatal(err)
  1245  				}
  1246  				if found {
  1247  					t.Errorf("expected no result; got %+v", val)
  1248  				}
  1249  			}
  1250  
  1251  			{
  1252  				// Write a malformed value (not an encoded MVCCKeyValue) and a
  1253  				// write intent to key 3; the parse error is returned instead of the
  1254  				// write intent.
  1255  				if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1256  					t.Fatal(err)
  1257  				}
  1258  				if err := MVCCPut(ctx, engine, nil, testKey3, txn1ts.ReadTimestamp, v2, txn1ts); err != nil {
  1259  					t.Fatal(err)
  1260  				}
  1261  				val := roachpb.Value{}
  1262  				found, err := MVCCGetProto(ctx, engine, testKey3, hlc.Timestamp{WallTime: 1}, &val, MVCCGetOptions{
  1263  					Inconsistent: true,
  1264  				})
  1265  				if err == nil {
  1266  					t.Errorf("expected error reading malformed data")
  1267  				} else if !strings.HasPrefix(err.Error(), "proto: ") {
  1268  					t.Errorf("expected proto error, got %s", err)
  1269  				}
  1270  				if !found {
  1271  					t.Errorf("expected to find result with malformed data")
  1272  				}
  1273  			}
  1274  		})
  1275  	}
  1276  }
  1277  
  1278  // Regression test for #28205: MVCCGet and MVCCScan, FindSplitKey, and
  1279  // ComputeStats need to invalidate the cached iterator data.
  1280  func TestMVCCInvalidateIterator(t *testing.T) {
  1281  	defer leaktest.AfterTest(t)()
  1282  
  1283  	for _, which := range []string{"get", "scan", "findSplitKey", "computeStats"} {
  1284  		t.Run(which, func(t *testing.T) {
  1285  			for _, engineImpl := range mvccEngineImpls {
  1286  				t.Run(engineImpl.name, func(t *testing.T) {
  1287  					engine := engineImpl.create()
  1288  					defer engine.Close()
  1289  
  1290  					ctx := context.Background()
  1291  					ts1 := hlc.Timestamp{WallTime: 1}
  1292  					ts2 := hlc.Timestamp{WallTime: 2}
  1293  
  1294  					key := roachpb.Key("a")
  1295  					if err := MVCCPut(ctx, engine, nil, key, ts1, value1, nil); err != nil {
  1296  						t.Fatal(err)
  1297  					}
  1298  
  1299  					var iterOptions IterOptions
  1300  					switch which {
  1301  					case "get":
  1302  						iterOptions.Prefix = true
  1303  					case "scan", "findSplitKey", "computeStats":
  1304  						iterOptions.UpperBound = roachpb.KeyMax
  1305  					}
  1306  
  1307  					// Use a batch which internally caches the iterator.
  1308  					batch := engine.NewBatch()
  1309  					defer batch.Close()
  1310  
  1311  					{
  1312  						// Seek the iter to a valid position.
  1313  						iter := batch.NewIterator(iterOptions)
  1314  						iter.SeekGE(MakeMVCCMetadataKey(key))
  1315  						iter.Close()
  1316  					}
  1317  
  1318  					var err error
  1319  					switch which {
  1320  					case "get":
  1321  						_, _, err = MVCCGet(ctx, batch, key, ts2, MVCCGetOptions{})
  1322  					case "scan":
  1323  						_, err = MVCCScan(ctx, batch, key, roachpb.KeyMax, ts2, MVCCScanOptions{})
  1324  					case "findSplitKey":
  1325  						_, err = MVCCFindSplitKey(ctx, batch, roachpb.RKeyMin, roachpb.RKeyMax, 64<<20)
  1326  					case "computeStats":
  1327  						iter := batch.NewIterator(iterOptions)
  1328  						_, err = iter.ComputeStats(roachpb.KeyMin, roachpb.KeyMax, 0)
  1329  						iter.Close()
  1330  					}
  1331  					if err != nil {
  1332  						t.Fatal(err)
  1333  					}
  1334  
  1335  					// Verify that the iter is invalid.
  1336  					iter := batch.NewIterator(iterOptions)
  1337  					defer iter.Close()
  1338  					if ok, _ := iter.Valid(); ok {
  1339  						t.Fatalf("iterator should not be valid")
  1340  					}
  1341  				})
  1342  			}
  1343  		})
  1344  	}
  1345  }
  1346  
  1347  func TestMVCCPutAfterBatchIterCreate(t *testing.T) {
  1348  	defer leaktest.AfterTest(t)()
  1349  
  1350  	for _, engineImpl := range mvccEngineImpls {
  1351  		t.Run(engineImpl.name, func(t *testing.T) {
  1352  			engine := engineImpl.create()
  1353  			defer engine.Close()
  1354  
  1355  			err := engine.Put(MVCCKey{testKey1, hlc.Timestamp{WallTime: 5}}, []byte("foobar"))
  1356  			if err != nil {
  1357  				t.Fatal(err)
  1358  			}
  1359  			err = engine.Put(MVCCKey{testKey2, hlc.Timestamp{WallTime: 5}}, []byte("foobar"))
  1360  			if err != nil {
  1361  				t.Fatal(err)
  1362  			}
  1363  			err = engine.Put(MVCCKey{testKey2, hlc.Timestamp{WallTime: 3}}, []byte("foobar"))
  1364  			if err != nil {
  1365  				t.Fatal(err)
  1366  			}
  1367  			err = engine.Put(MVCCKey{testKey3, hlc.Timestamp{WallTime: 5}}, []byte("foobar"))
  1368  			if err != nil {
  1369  				t.Fatal(err)
  1370  			}
  1371  			err = engine.Put(MVCCKey{testKey4, hlc.Timestamp{WallTime: 5}}, []byte("foobar"))
  1372  			if err != nil {
  1373  				t.Fatal(err)
  1374  			}
  1375  
  1376  			batch := engine.NewBatch()
  1377  			defer batch.Close()
  1378  			txn := &roachpb.Transaction{
  1379  				TxnMeta: enginepb.TxnMeta{
  1380  					WriteTimestamp: hlc.Timestamp{WallTime: 10},
  1381  				},
  1382  				Name:                    "test",
  1383  				Status:                  roachpb.PENDING,
  1384  				DeprecatedOrigTimestamp: hlc.Timestamp{WallTime: 10},
  1385  				ReadTimestamp:           hlc.Timestamp{WallTime: 10},
  1386  				MaxTimestamp:            hlc.Timestamp{WallTime: 10},
  1387  			}
  1388  			iter := batch.NewIterator(IterOptions{
  1389  				LowerBound: testKey1,
  1390  				UpperBound: testKey5,
  1391  			})
  1392  			defer iter.Close()
  1393  			iter.SeekGE(MVCCKey{testKey1, hlc.Timestamp{WallTime: 5}})
  1394  			iter.Next() // key2/5
  1395  
  1396  			// Lay down an intent on key3, which will go at key3/0 and sort before key3/5.
  1397  			err = MVCCDelete(context.Background(), batch, nil, testKey3, txn.WriteTimestamp, txn)
  1398  			if err != nil {
  1399  				t.Fatal(err)
  1400  			}
  1401  			// Should Next() from key2/5 to key2/3 first, then Seek to key3, and see
  1402  			// the intent.
  1403  			iter.NextKey()
  1404  
  1405  			if iter.UnsafeKey().IsValue() {
  1406  				t.Fatalf("expected iterator to land on an intent, got a value: %v", iter.UnsafeKey())
  1407  			}
  1408  		})
  1409  	}
  1410  }
  1411  
  1412  func mvccScanTest(ctx context.Context, t *testing.T, engine Engine) {
  1413  	if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1414  		t.Fatal(err)
  1415  	}
  1416  	if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 2}, value4, nil); err != nil {
  1417  		t.Fatal(err)
  1418  	}
  1419  	if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  1420  		t.Fatal(err)
  1421  	}
  1422  	if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 3}, value3, nil); err != nil {
  1423  		t.Fatal(err)
  1424  	}
  1425  	if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1426  		t.Fatal(err)
  1427  	}
  1428  	if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 4}, value2, nil); err != nil {
  1429  		t.Fatal(err)
  1430  	}
  1431  	if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1432  		t.Fatal(err)
  1433  	}
  1434  	if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 5}, value1, nil); err != nil {
  1435  		t.Fatal(err)
  1436  	}
  1437  
  1438  	res, err := MVCCScan(ctx, engine, testKey2, testKey4,
  1439  		hlc.Timestamp{WallTime: 1}, MVCCScanOptions{})
  1440  	if err != nil {
  1441  		t.Fatal(err)
  1442  	}
  1443  	kvs := res.KVs
  1444  	resumeSpan := res.ResumeSpan
  1445  	if len(kvs) != 2 ||
  1446  		!bytes.Equal(kvs[0].Key, testKey2) ||
  1447  		!bytes.Equal(kvs[1].Key, testKey3) ||
  1448  		!bytes.Equal(kvs[0].Value.RawBytes, value2.RawBytes) ||
  1449  		!bytes.Equal(kvs[1].Value.RawBytes, value3.RawBytes) {
  1450  		t.Fatal("the value should not be empty")
  1451  	}
  1452  	if resumeSpan != nil {
  1453  		t.Fatalf("resumeSpan = %+v", resumeSpan)
  1454  	}
  1455  
  1456  	res, err = MVCCScan(ctx, engine, testKey2, testKey4,
  1457  		hlc.Timestamp{WallTime: 4}, MVCCScanOptions{})
  1458  	if err != nil {
  1459  		t.Fatal(err)
  1460  	}
  1461  	kvs = res.KVs
  1462  	resumeSpan = res.ResumeSpan
  1463  	if len(kvs) != 2 ||
  1464  		!bytes.Equal(kvs[0].Key, testKey2) ||
  1465  		!bytes.Equal(kvs[1].Key, testKey3) ||
  1466  		!bytes.Equal(kvs[0].Value.RawBytes, value3.RawBytes) ||
  1467  		!bytes.Equal(kvs[1].Value.RawBytes, value2.RawBytes) {
  1468  		t.Fatal("the value should not be empty")
  1469  	}
  1470  	if resumeSpan != nil {
  1471  		t.Fatalf("resumeSpan = %+v", resumeSpan)
  1472  	}
  1473  
  1474  	res, err = MVCCScan(
  1475  		ctx, engine, testKey4, keyMax, hlc.Timestamp{WallTime: 1}, MVCCScanOptions{},
  1476  	)
  1477  	if err != nil {
  1478  		t.Fatal(err)
  1479  	}
  1480  	kvs = res.KVs
  1481  	resumeSpan = res.ResumeSpan
  1482  	if len(kvs) != 1 ||
  1483  		!bytes.Equal(kvs[0].Key, testKey4) ||
  1484  		!bytes.Equal(kvs[0].Value.RawBytes, value4.RawBytes) {
  1485  		t.Fatal("the value should not be empty")
  1486  	}
  1487  	if resumeSpan != nil {
  1488  		t.Fatalf("resumeSpan = %+v", resumeSpan)
  1489  	}
  1490  
  1491  	if _, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
  1492  		Txn: txn2,
  1493  	}); err != nil {
  1494  		t.Fatal(err)
  1495  	}
  1496  	res, err = MVCCScan(ctx, engine, keyMin, testKey2,
  1497  		hlc.Timestamp{WallTime: 1}, MVCCScanOptions{})
  1498  	if err != nil {
  1499  		t.Fatal(err)
  1500  	}
  1501  	kvs = res.KVs
  1502  	if len(kvs) != 1 ||
  1503  		!bytes.Equal(kvs[0].Key, testKey1) ||
  1504  		!bytes.Equal(kvs[0].Value.RawBytes, value1.RawBytes) {
  1505  		t.Fatal("the value should not be empty")
  1506  	}
  1507  }
  1508  
  1509  func TestMVCCScan(t *testing.T) {
  1510  	defer leaktest.AfterTest(t)()
  1511  
  1512  	ctx := context.Background()
  1513  	for _, engineImpl := range mvccEngineImpls {
  1514  		t.Run(engineImpl.name, func(t *testing.T) {
  1515  			engine := engineImpl.create()
  1516  			defer engine.Close()
  1517  
  1518  			mvccScanTest(ctx, t, engine)
  1519  		})
  1520  	}
  1521  }
  1522  
  1523  func TestMVCCScanMaxNum(t *testing.T) {
  1524  	defer leaktest.AfterTest(t)()
  1525  
  1526  	ctx := context.Background()
  1527  	for _, engineImpl := range mvccEngineImpls {
  1528  		t.Run(engineImpl.name, func(t *testing.T) {
  1529  			engine := engineImpl.create()
  1530  			defer engine.Close()
  1531  
  1532  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1533  				t.Fatal(err)
  1534  			}
  1535  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  1536  				t.Fatal(err)
  1537  			}
  1538  			if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1539  				t.Fatal(err)
  1540  			}
  1541  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1542  				t.Fatal(err)
  1543  			}
  1544  			if err := MVCCPut(ctx, engine, nil, testKey6, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1545  				t.Fatal(err)
  1546  			}
  1547  
  1548  			res, err := MVCCScan(ctx, engine, testKey2, testKey4,
  1549  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{MaxKeys: 1})
  1550  			if err != nil {
  1551  				t.Fatal(err)
  1552  			}
  1553  			if len(res.KVs) != 1 ||
  1554  				!bytes.Equal(res.KVs[0].Key, testKey2) ||
  1555  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) {
  1556  				t.Fatal("the value should not be empty")
  1557  			}
  1558  			if expected := (roachpb.Span{Key: testKey3, EndKey: testKey4}); !res.ResumeSpan.EqualValue(expected) {
  1559  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, res.ResumeSpan)
  1560  			}
  1561  
  1562  			res, err = MVCCScan(ctx, engine, testKey2, testKey4,
  1563  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{MaxKeys: -1})
  1564  			if err != nil {
  1565  				t.Fatal(err)
  1566  			}
  1567  			if len(res.KVs) != 0 {
  1568  				t.Fatal("the value should be empty")
  1569  			}
  1570  			if expected := (roachpb.Span{Key: testKey2, EndKey: testKey4}); !res.ResumeSpan.EqualValue(expected) {
  1571  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, res.ResumeSpan)
  1572  			}
  1573  
  1574  			// Note: testKey6, though not scanned directly, is important in testing that
  1575  			// the computed resume span does not extend beyond the upper bound of a scan.
  1576  			res, err = MVCCScan(ctx, engine, testKey4, testKey5,
  1577  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{MaxKeys: 1})
  1578  			if err != nil {
  1579  				t.Fatal(err)
  1580  			}
  1581  			if len(res.KVs) != 1 {
  1582  				t.Fatalf("expected 1 key but got %d", len(res.KVs))
  1583  			}
  1584  			if res.ResumeSpan != nil {
  1585  				t.Fatalf("resumeSpan = %+v", res.ResumeSpan)
  1586  			}
  1587  
  1588  			res, err = MVCCScan(ctx, engine, testKey5, testKey6.Next(),
  1589  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{Reverse: true, MaxKeys: 1})
  1590  			if err != nil {
  1591  				t.Fatal(err)
  1592  			}
  1593  			if len(res.KVs) != 1 {
  1594  				t.Fatalf("expected 1 key but got %d", len(res.KVs))
  1595  			}
  1596  			if res.ResumeSpan != nil {
  1597  				t.Fatalf("resumeSpan = %+v", res.ResumeSpan)
  1598  			}
  1599  		})
  1600  	}
  1601  }
  1602  
  1603  func TestMVCCScanWithKeyPrefix(t *testing.T) {
  1604  	defer leaktest.AfterTest(t)()
  1605  
  1606  	ctx := context.Background()
  1607  	for _, engineImpl := range mvccEngineImpls {
  1608  		t.Run(engineImpl.name, func(t *testing.T) {
  1609  			engine := engineImpl.create()
  1610  			defer engine.Close()
  1611  
  1612  			// Let's say you have:
  1613  			// a
  1614  			// a<T=2>
  1615  			// a<T=1>
  1616  			// aa
  1617  			// aa<T=3>
  1618  			// aa<T=2>
  1619  			// b
  1620  			// b<T=5>
  1621  			// In this case, if we scan from "a"-"b", we wish to skip
  1622  			// a<T=2> and a<T=1> and find "aa'.
  1623  			if err := MVCCPut(ctx, engine, nil, roachpb.Key("/a"), hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1624  				t.Fatal(err)
  1625  			}
  1626  			if err := MVCCPut(ctx, engine, nil, roachpb.Key("/a"), hlc.Timestamp{WallTime: 2}, value2, nil); err != nil {
  1627  				t.Fatal(err)
  1628  			}
  1629  			if err := MVCCPut(ctx, engine, nil, roachpb.Key("/aa"), hlc.Timestamp{WallTime: 2}, value2, nil); err != nil {
  1630  				t.Fatal(err)
  1631  			}
  1632  			if err := MVCCPut(ctx, engine, nil, roachpb.Key("/aa"), hlc.Timestamp{WallTime: 3}, value3, nil); err != nil {
  1633  				t.Fatal(err)
  1634  			}
  1635  			if err := MVCCPut(ctx, engine, nil, roachpb.Key("/b"), hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1636  				t.Fatal(err)
  1637  			}
  1638  
  1639  			res, err := MVCCScan(ctx, engine, roachpb.Key("/a"), roachpb.Key("/b"),
  1640  				hlc.Timestamp{WallTime: 2}, MVCCScanOptions{})
  1641  			if err != nil {
  1642  				t.Fatal(err)
  1643  			}
  1644  			if len(res.KVs) != 2 ||
  1645  				!bytes.Equal(res.KVs[0].Key, roachpb.Key("/a")) ||
  1646  				!bytes.Equal(res.KVs[1].Key, roachpb.Key("/aa")) ||
  1647  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) ||
  1648  				!bytes.Equal(res.KVs[1].Value.RawBytes, value2.RawBytes) {
  1649  				t.Fatal("the value should not be empty")
  1650  			}
  1651  		})
  1652  	}
  1653  }
  1654  
  1655  func TestMVCCScanInTxn(t *testing.T) {
  1656  	defer leaktest.AfterTest(t)()
  1657  
  1658  	ctx := context.Background()
  1659  	for _, engineImpl := range mvccEngineImpls {
  1660  		t.Run(engineImpl.name, func(t *testing.T) {
  1661  			engine := engineImpl.create()
  1662  			defer engine.Close()
  1663  
  1664  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1665  				t.Fatal(err)
  1666  			}
  1667  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  1668  				t.Fatal(err)
  1669  			}
  1670  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  1671  			if err := MVCCPut(ctx, engine, nil, testKey3, txn.ReadTimestamp, value3, txn); err != nil {
  1672  				t.Fatal(err)
  1673  			}
  1674  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1675  				t.Fatal(err)
  1676  			}
  1677  
  1678  			res, err := MVCCScan(ctx, engine, testKey2, testKey4,
  1679  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{Txn: txn1})
  1680  			if err != nil {
  1681  				t.Fatal(err)
  1682  			}
  1683  			if len(res.KVs) != 2 ||
  1684  				!bytes.Equal(res.KVs[0].Key, testKey2) ||
  1685  				!bytes.Equal(res.KVs[1].Key, testKey3) ||
  1686  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) ||
  1687  				!bytes.Equal(res.KVs[1].Value.RawBytes, value3.RawBytes) {
  1688  				t.Fatal("the value should not be empty")
  1689  			}
  1690  
  1691  			if _, err := MVCCScan(
  1692  				ctx, engine, testKey2, testKey4, hlc.Timestamp{WallTime: 1}, MVCCScanOptions{},
  1693  			); err == nil {
  1694  				t.Fatal("expected error on uncommitted write intent")
  1695  			}
  1696  		})
  1697  	}
  1698  }
  1699  
  1700  // TestMVCCScanInconsistent writes several values, some as intents and
  1701  // verifies that the scan sees only the committed versions.
  1702  func TestMVCCScanInconsistent(t *testing.T) {
  1703  	defer leaktest.AfterTest(t)()
  1704  
  1705  	ctx := context.Background()
  1706  	for _, engineImpl := range mvccEngineImpls {
  1707  		t.Run(engineImpl.name, func(t *testing.T) {
  1708  			engine := engineImpl.create()
  1709  			defer engine.Close()
  1710  
  1711  			// A scan with consistent=false should fail in a txn.
  1712  			if _, err := MVCCScan(
  1713  				ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 1},
  1714  				MVCCScanOptions{Inconsistent: true, Txn: txn1},
  1715  			); err == nil {
  1716  				t.Error("expected an error scanning with consistent=false in txn")
  1717  			}
  1718  
  1719  			ts1 := hlc.Timestamp{WallTime: 1}
  1720  			ts2 := hlc.Timestamp{WallTime: 2}
  1721  			ts3 := hlc.Timestamp{WallTime: 3}
  1722  			ts4 := hlc.Timestamp{WallTime: 4}
  1723  			ts5 := hlc.Timestamp{WallTime: 5}
  1724  			ts6 := hlc.Timestamp{WallTime: 6}
  1725  			if err := MVCCPut(ctx, engine, nil, testKey1, ts1, value1, nil); err != nil {
  1726  				t.Fatal(err)
  1727  			}
  1728  			txn1ts2 := makeTxn(*txn1, ts2)
  1729  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1ts2.ReadTimestamp, value2, txn1ts2); err != nil {
  1730  				t.Fatal(err)
  1731  			}
  1732  			if err := MVCCPut(ctx, engine, nil, testKey2, ts3, value1, nil); err != nil {
  1733  				t.Fatal(err)
  1734  			}
  1735  			if err := MVCCPut(ctx, engine, nil, testKey2, ts4, value2, nil); err != nil {
  1736  				t.Fatal(err)
  1737  			}
  1738  			txn2ts5 := makeTxn(*txn2, ts5)
  1739  			if err := MVCCPut(ctx, engine, nil, testKey3, txn2ts5.ReadTimestamp, value3, txn2ts5); err != nil {
  1740  				t.Fatal(err)
  1741  			}
  1742  			if err := MVCCPut(ctx, engine, nil, testKey4, ts6, value4, nil); err != nil {
  1743  				t.Fatal(err)
  1744  			}
  1745  
  1746  			expIntents := []roachpb.Intent{
  1747  				roachpb.MakeIntent(&txn1ts2.TxnMeta, testKey1),
  1748  				roachpb.MakeIntent(&txn2ts5.TxnMeta, testKey3),
  1749  			}
  1750  			res, err := MVCCScan(
  1751  				ctx, engine, testKey1, testKey4.Next(), hlc.Timestamp{WallTime: 7},
  1752  				MVCCScanOptions{Inconsistent: true},
  1753  			)
  1754  			if err != nil {
  1755  				t.Fatal(err)
  1756  			}
  1757  			if !reflect.DeepEqual(res.Intents, expIntents) {
  1758  				t.Fatalf("expected %v, but found %v", expIntents, res.Intents)
  1759  			}
  1760  
  1761  			makeTimestampedValue := func(v roachpb.Value, ts hlc.Timestamp) roachpb.Value {
  1762  				v.Timestamp = ts
  1763  				return v
  1764  			}
  1765  
  1766  			expKVs := []roachpb.KeyValue{
  1767  				{Key: testKey1, Value: makeTimestampedValue(value1, ts1)},
  1768  				{Key: testKey2, Value: makeTimestampedValue(value2, ts4)},
  1769  				{Key: testKey4, Value: makeTimestampedValue(value4, ts6)},
  1770  			}
  1771  			if !reflect.DeepEqual(res.KVs, expKVs) {
  1772  				t.Errorf("expected key values equal %v != %v", res.KVs, expKVs)
  1773  			}
  1774  
  1775  			// Now try a scan at a historical timestamp.
  1776  			expIntents = expIntents[:1]
  1777  			res, err = MVCCScan(ctx, engine, testKey1, testKey4.Next(),
  1778  				hlc.Timestamp{WallTime: 3}, MVCCScanOptions{Inconsistent: true})
  1779  			if !reflect.DeepEqual(res.Intents, expIntents) {
  1780  				t.Fatal(err)
  1781  			}
  1782  			expKVs = []roachpb.KeyValue{
  1783  				{Key: testKey1, Value: makeTimestampedValue(value1, ts1)},
  1784  				{Key: testKey2, Value: makeTimestampedValue(value1, ts3)},
  1785  			}
  1786  			if !reflect.DeepEqual(res.KVs, expKVs) {
  1787  				t.Errorf("expected key values equal %v != %v", res.Intents, expKVs)
  1788  			}
  1789  		})
  1790  	}
  1791  }
  1792  
  1793  func TestMVCCDeleteRange(t *testing.T) {
  1794  	defer leaktest.AfterTest(t)()
  1795  
  1796  	ctx := context.Background()
  1797  	for _, engineImpl := range mvccEngineImpls {
  1798  		t.Run(engineImpl.name, func(t *testing.T) {
  1799  			engine := engineImpl.create()
  1800  			defer engine.Close()
  1801  
  1802  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1803  				t.Fatal(err)
  1804  			}
  1805  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  1806  				t.Fatal(err)
  1807  			}
  1808  			if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1809  				t.Fatal(err)
  1810  			}
  1811  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1812  				t.Fatal(err)
  1813  			}
  1814  			if err := MVCCPut(ctx, engine, nil, testKey5, hlc.Timestamp{WallTime: 1}, value5, nil); err != nil {
  1815  				t.Fatal(err)
  1816  			}
  1817  			if err := MVCCPut(ctx, engine, nil, testKey6, hlc.Timestamp{WallTime: 1}, value6, nil); err != nil {
  1818  				t.Fatal(err)
  1819  			}
  1820  
  1821  			// Attempt to delete two keys.
  1822  			deleted, resumeSpan, num, err := MVCCDeleteRange(
  1823  				ctx, engine, nil, testKey2, testKey6, 2, hlc.Timestamp{WallTime: 2}, nil, false,
  1824  			)
  1825  			if err != nil {
  1826  				t.Fatal(err)
  1827  			}
  1828  			if deleted != nil {
  1829  				t.Fatal("the value should be empty")
  1830  			}
  1831  			if num != 2 {
  1832  				t.Fatalf("incorrect number of keys deleted: %d", num)
  1833  			}
  1834  			if expected := (roachpb.Span{Key: testKey4, EndKey: testKey6}); !resumeSpan.EqualValue(expected) {
  1835  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, resumeSpan)
  1836  			}
  1837  			res, _ := MVCCScan(ctx, engine, keyMin, keyMax,
  1838  				hlc.Timestamp{WallTime: 2}, MVCCScanOptions{})
  1839  			if len(res.KVs) != 4 ||
  1840  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  1841  				!bytes.Equal(res.KVs[1].Key, testKey4) ||
  1842  				!bytes.Equal(res.KVs[2].Key, testKey5) ||
  1843  				!bytes.Equal(res.KVs[3].Key, testKey6) ||
  1844  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) ||
  1845  				!bytes.Equal(res.KVs[1].Value.RawBytes, value4.RawBytes) ||
  1846  				!bytes.Equal(res.KVs[2].Value.RawBytes, value5.RawBytes) ||
  1847  				!bytes.Equal(res.KVs[3].Value.RawBytes, value6.RawBytes) {
  1848  				t.Fatal("the value should not be empty")
  1849  			}
  1850  
  1851  			// Try again, but with tombstones set to true to fetch the deleted keys as well.
  1852  			kvs := []roachpb.KeyValue{}
  1853  			if _, err = MVCCIterate(
  1854  				ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2}, MVCCScanOptions{Tombstones: true},
  1855  				func(kv roachpb.KeyValue) (bool, error) {
  1856  					kvs = append(kvs, kv)
  1857  					return false, nil
  1858  				},
  1859  			); err != nil {
  1860  				t.Fatal(err)
  1861  			}
  1862  			if len(kvs) != 6 ||
  1863  				!bytes.Equal(kvs[0].Key, testKey1) ||
  1864  				!bytes.Equal(kvs[1].Key, testKey2) ||
  1865  				!bytes.Equal(kvs[2].Key, testKey3) ||
  1866  				!bytes.Equal(kvs[3].Key, testKey4) ||
  1867  				!bytes.Equal(kvs[4].Key, testKey5) ||
  1868  				!bytes.Equal(kvs[5].Key, testKey6) ||
  1869  				!bytes.Equal(kvs[0].Value.RawBytes, value1.RawBytes) ||
  1870  				!bytes.Equal(kvs[1].Value.RawBytes, nil) ||
  1871  				!bytes.Equal(kvs[2].Value.RawBytes, nil) ||
  1872  				!bytes.Equal(kvs[3].Value.RawBytes, value4.RawBytes) ||
  1873  				!bytes.Equal(kvs[4].Value.RawBytes, value5.RawBytes) ||
  1874  				!bytes.Equal(kvs[5].Value.RawBytes, value6.RawBytes) {
  1875  				t.Fatal("the value should not be empty")
  1876  			}
  1877  
  1878  			// Attempt to delete no keys.
  1879  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  1880  				ctx, engine, nil, testKey2, testKey6, -1, hlc.Timestamp{WallTime: 2}, nil, false)
  1881  			if err != nil {
  1882  				t.Fatal(err)
  1883  			}
  1884  			if deleted != nil {
  1885  				t.Fatal("the value should be empty")
  1886  			}
  1887  			if num != 0 {
  1888  				t.Fatalf("incorrect number of keys deleted: %d", num)
  1889  			}
  1890  			if expected := (roachpb.Span{Key: testKey2, EndKey: testKey6}); !resumeSpan.EqualValue(expected) {
  1891  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, resumeSpan)
  1892  			}
  1893  			res, _ = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  1894  				MVCCScanOptions{})
  1895  			if len(res.KVs) != 4 ||
  1896  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  1897  				!bytes.Equal(res.KVs[1].Key, testKey4) ||
  1898  				!bytes.Equal(res.KVs[2].Key, testKey5) ||
  1899  				!bytes.Equal(res.KVs[3].Key, testKey6) ||
  1900  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) ||
  1901  				!bytes.Equal(res.KVs[1].Value.RawBytes, value4.RawBytes) ||
  1902  				!bytes.Equal(res.KVs[2].Value.RawBytes, value5.RawBytes) ||
  1903  				!bytes.Equal(res.KVs[3].Value.RawBytes, value6.RawBytes) {
  1904  				t.Fatal("the value should not be empty")
  1905  			}
  1906  
  1907  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  1908  				ctx, engine, nil, testKey4, keyMax, 0, hlc.Timestamp{WallTime: 2}, nil, false)
  1909  			if err != nil {
  1910  				t.Fatal(err)
  1911  			}
  1912  			if deleted != nil {
  1913  				t.Fatal("the value should be empty")
  1914  			}
  1915  			if num != 3 {
  1916  				t.Fatalf("incorrect number of keys deleted: %d", num)
  1917  			}
  1918  			if resumeSpan != nil {
  1919  				t.Fatalf("wrong resume key: expected nil, found %v", resumeSpan)
  1920  			}
  1921  			res, err = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  1922  				MVCCScanOptions{})
  1923  			if err != nil {
  1924  				t.Fatal(err)
  1925  			}
  1926  			if len(res.KVs) != 1 ||
  1927  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  1928  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) {
  1929  				t.Fatalf("the value should not be empty: %+v", res.KVs)
  1930  			}
  1931  
  1932  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  1933  				ctx, engine, nil, keyMin, testKey2, 0, hlc.Timestamp{WallTime: 2}, nil, false)
  1934  			if err != nil {
  1935  				t.Fatal(err)
  1936  			}
  1937  			if deleted != nil {
  1938  				t.Fatal("the value should not be empty")
  1939  			}
  1940  			if num != 1 {
  1941  				t.Fatalf("incorrect number of keys deleted: %d", num)
  1942  			}
  1943  			if resumeSpan != nil {
  1944  				t.Fatalf("wrong resume key: expected nil, found %v", resumeSpan)
  1945  			}
  1946  			res, _ = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  1947  				MVCCScanOptions{})
  1948  			if err != nil {
  1949  				t.Fatal(err)
  1950  			}
  1951  			if len(res.KVs) != 0 {
  1952  				t.Fatal("the value should be empty")
  1953  			}
  1954  		})
  1955  	}
  1956  }
  1957  
  1958  func TestMVCCDeleteRangeReturnKeys(t *testing.T) {
  1959  	defer leaktest.AfterTest(t)()
  1960  
  1961  	ctx := context.Background()
  1962  	for _, engineImpl := range mvccEngineImpls {
  1963  		t.Run(engineImpl.name, func(t *testing.T) {
  1964  			engine := engineImpl.create()
  1965  			defer engine.Close()
  1966  
  1967  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  1968  				t.Fatal(err)
  1969  			}
  1970  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  1971  				t.Fatal(err)
  1972  			}
  1973  			if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  1974  				t.Fatal(err)
  1975  			}
  1976  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  1977  				t.Fatal(err)
  1978  			}
  1979  			if err := MVCCPut(ctx, engine, nil, testKey5, hlc.Timestamp{WallTime: 1}, value5, nil); err != nil {
  1980  				t.Fatal(err)
  1981  			}
  1982  			if err := MVCCPut(ctx, engine, nil, testKey6, hlc.Timestamp{WallTime: 1}, value6, nil); err != nil {
  1983  				t.Fatal(err)
  1984  			}
  1985  
  1986  			// Attempt to delete two keys.
  1987  			deleted, resumeSpan, num, err := MVCCDeleteRange(
  1988  				ctx, engine, nil, testKey2, testKey6, 2, hlc.Timestamp{WallTime: 2}, nil, true)
  1989  			if err != nil {
  1990  				t.Fatal(err)
  1991  			}
  1992  			if len(deleted) != 2 {
  1993  				t.Fatal("the value should not be empty")
  1994  			}
  1995  			if num != 2 {
  1996  				t.Fatalf("incorrect number of keys deleted: %d", num)
  1997  			}
  1998  			if expected, actual := testKey2, deleted[0]; !expected.Equal(actual) {
  1999  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2000  			}
  2001  			if expected, actual := testKey3, deleted[1]; !expected.Equal(actual) {
  2002  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2003  			}
  2004  			if expected := (roachpb.Span{Key: testKey4, EndKey: testKey6}); !resumeSpan.EqualValue(expected) {
  2005  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, resumeSpan)
  2006  			}
  2007  			res, _ := MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  2008  				MVCCScanOptions{})
  2009  			if len(res.KVs) != 4 ||
  2010  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  2011  				!bytes.Equal(res.KVs[1].Key, testKey4) ||
  2012  				!bytes.Equal(res.KVs[2].Key, testKey5) ||
  2013  				!bytes.Equal(res.KVs[3].Key, testKey6) ||
  2014  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) ||
  2015  				!bytes.Equal(res.KVs[1].Value.RawBytes, value4.RawBytes) ||
  2016  				!bytes.Equal(res.KVs[2].Value.RawBytes, value5.RawBytes) ||
  2017  				!bytes.Equal(res.KVs[3].Value.RawBytes, value6.RawBytes) {
  2018  				t.Fatal("the value should not be empty")
  2019  			}
  2020  
  2021  			// Attempt to delete no keys.
  2022  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  2023  				ctx, engine, nil, testKey2, testKey6, -1, hlc.Timestamp{WallTime: 2}, nil, true)
  2024  			if err != nil {
  2025  				t.Fatal(err)
  2026  			}
  2027  			if deleted != nil {
  2028  				t.Fatalf("the value should be empty: %s", deleted)
  2029  			}
  2030  			if num != 0 {
  2031  				t.Fatalf("incorrect number of keys deleted: %d", num)
  2032  			}
  2033  			if expected := (roachpb.Span{Key: testKey2, EndKey: testKey6}); !resumeSpan.EqualValue(expected) {
  2034  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, resumeSpan)
  2035  			}
  2036  			res, _ = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  2037  				MVCCScanOptions{})
  2038  			if len(res.KVs) != 4 ||
  2039  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  2040  				!bytes.Equal(res.KVs[1].Key, testKey4) ||
  2041  				!bytes.Equal(res.KVs[2].Key, testKey5) ||
  2042  				!bytes.Equal(res.KVs[3].Key, testKey6) ||
  2043  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) ||
  2044  				!bytes.Equal(res.KVs[1].Value.RawBytes, value4.RawBytes) ||
  2045  				!bytes.Equal(res.KVs[2].Value.RawBytes, value5.RawBytes) ||
  2046  				!bytes.Equal(res.KVs[3].Value.RawBytes, value6.RawBytes) {
  2047  				t.Fatal("the value should not be empty")
  2048  			}
  2049  
  2050  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  2051  				ctx, engine, nil, testKey4, keyMax, math.MaxInt64, hlc.Timestamp{WallTime: 2}, nil, true)
  2052  			if err != nil {
  2053  				t.Fatal(err)
  2054  			}
  2055  			if len(deleted) != 3 {
  2056  				t.Fatal("the value should not be empty")
  2057  			}
  2058  			if num != 3 {
  2059  				t.Fatalf("incorrect number of keys deleted: %d", num)
  2060  			}
  2061  			if expected, actual := testKey4, deleted[0]; !expected.Equal(actual) {
  2062  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2063  			}
  2064  			if expected, actual := testKey5, deleted[1]; !expected.Equal(actual) {
  2065  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2066  			}
  2067  			if expected, actual := testKey6, deleted[2]; !expected.Equal(actual) {
  2068  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2069  			}
  2070  			if resumeSpan != nil {
  2071  				t.Fatalf("wrong resume key: expected nil, found %v", resumeSpan)
  2072  			}
  2073  			res, _ = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  2074  				MVCCScanOptions{})
  2075  			if len(res.KVs) != 1 ||
  2076  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  2077  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) {
  2078  				t.Fatal("the value should not be empty")
  2079  			}
  2080  
  2081  			deleted, resumeSpan, num, err = MVCCDeleteRange(
  2082  				ctx, engine, nil, keyMin, testKey2, math.MaxInt64, hlc.Timestamp{WallTime: 2}, nil, true)
  2083  			if err != nil {
  2084  				t.Fatal(err)
  2085  			}
  2086  			if len(deleted) != 1 {
  2087  				t.Fatal("the value should not be empty")
  2088  			}
  2089  			if num != 1 {
  2090  				t.Fatalf("incorrect number of keys deleted: %d", num)
  2091  			}
  2092  			if expected, actual := testKey1, deleted[0]; !expected.Equal(actual) {
  2093  				t.Fatalf("wrong key deleted: expected %v found %v", expected, actual)
  2094  			}
  2095  			if resumeSpan != nil {
  2096  				t.Fatalf("wrong resume key: %v", resumeSpan)
  2097  			}
  2098  			res, _ = MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  2099  				MVCCScanOptions{})
  2100  			if len(res.KVs) != 0 {
  2101  				t.Fatal("the value should be empty")
  2102  			}
  2103  		})
  2104  	}
  2105  }
  2106  
  2107  func TestMVCCDeleteRangeFailed(t *testing.T) {
  2108  	defer leaktest.AfterTest(t)()
  2109  
  2110  	ctx := context.Background()
  2111  	for _, engineImpl := range mvccEngineImpls {
  2112  		t.Run(engineImpl.name, func(t *testing.T) {
  2113  			engine := engineImpl.create()
  2114  			defer engine.Close()
  2115  
  2116  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  2117  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  2118  				t.Fatal(err)
  2119  			}
  2120  			txn.Sequence++
  2121  			if err := MVCCPut(ctx, engine, nil, testKey2, txn.ReadTimestamp, value2, txn); err != nil {
  2122  				t.Fatal(err)
  2123  			}
  2124  			txn.Sequence++
  2125  			if err := MVCCPut(ctx, engine, nil, testKey3, txn.ReadTimestamp, value3, txn); err != nil {
  2126  				t.Fatal(err)
  2127  			}
  2128  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  2129  				t.Fatal(err)
  2130  			}
  2131  
  2132  			if _, _, _, err := MVCCDeleteRange(
  2133  				ctx, engine, nil, testKey2, testKey4, math.MaxInt64, hlc.Timestamp{WallTime: 1}, nil, false,
  2134  			); err == nil {
  2135  				t.Fatal("expected error on uncommitted write intent")
  2136  			}
  2137  
  2138  			txn.Sequence++
  2139  			if _, _, _, err := MVCCDeleteRange(
  2140  				ctx, engine, nil, testKey2, testKey4, math.MaxInt64, txn.ReadTimestamp, txn, false,
  2141  			); err != nil {
  2142  				t.Fatal(err)
  2143  			}
  2144  		})
  2145  	}
  2146  }
  2147  
  2148  func TestMVCCDeleteRangeConcurrentTxn(t *testing.T) {
  2149  	defer leaktest.AfterTest(t)()
  2150  
  2151  	ctx := context.Background()
  2152  	for _, engineImpl := range mvccEngineImpls {
  2153  		t.Run(engineImpl.name, func(t *testing.T) {
  2154  			engine := engineImpl.create()
  2155  			defer engine.Close()
  2156  
  2157  			txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  2158  			txn2ts := makeTxn(*txn2, hlc.Timestamp{WallTime: 2})
  2159  
  2160  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  2161  				t.Fatal(err)
  2162  			}
  2163  			if err := MVCCPut(ctx, engine, nil, testKey2, txn1ts.ReadTimestamp, value2, txn1ts); err != nil {
  2164  				t.Fatal(err)
  2165  			}
  2166  			if err := MVCCPut(ctx, engine, nil, testKey3, txn2ts.ReadTimestamp, value3, txn2ts); err != nil {
  2167  				t.Fatal(err)
  2168  			}
  2169  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value4, nil); err != nil {
  2170  				t.Fatal(err)
  2171  			}
  2172  
  2173  			if _, _, _, err := MVCCDeleteRange(
  2174  				ctx, engine, nil, testKey2, testKey4, math.MaxInt64, txn1ts.ReadTimestamp, txn1ts, false,
  2175  			); err == nil {
  2176  				t.Fatal("expected error on uncommitted write intent")
  2177  			}
  2178  		})
  2179  	}
  2180  }
  2181  
  2182  // TestMVCCUncommittedDeleteRangeVisible tests that the keys in an uncommitted
  2183  // DeleteRange are visible to the same transaction at a higher epoch.
  2184  func TestMVCCUncommittedDeleteRangeVisible(t *testing.T) {
  2185  	defer leaktest.AfterTest(t)()
  2186  
  2187  	ctx := context.Background()
  2188  	for _, engineImpl := range mvccEngineImpls {
  2189  		t.Run(engineImpl.name, func(t *testing.T) {
  2190  			engine := engineImpl.create()
  2191  			defer engine.Close()
  2192  
  2193  			if err := MVCCPut(
  2194  				ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil,
  2195  			); err != nil {
  2196  				t.Fatal(err)
  2197  			}
  2198  			if err := MVCCPut(
  2199  				ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil,
  2200  			); err != nil {
  2201  				t.Fatal(err)
  2202  			}
  2203  			if err := MVCCPut(
  2204  				ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value3, nil,
  2205  			); err != nil {
  2206  				t.Fatal(err)
  2207  			}
  2208  
  2209  			if err := MVCCDelete(
  2210  				ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 2, Logical: 1}, nil,
  2211  			); err != nil {
  2212  				t.Fatal(err)
  2213  			}
  2214  
  2215  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 2})
  2216  			if _, _, _, err := MVCCDeleteRange(
  2217  				ctx, engine, nil, testKey1, testKey4, math.MaxInt64, txn.ReadTimestamp, txn, false,
  2218  			); err != nil {
  2219  				t.Fatal(err)
  2220  			}
  2221  
  2222  			txn.Epoch++
  2223  			res, _ := MVCCScan(ctx, engine, testKey1, testKey4,
  2224  				hlc.Timestamp{WallTime: 3}, MVCCScanOptions{Txn: txn})
  2225  			if e := 2; len(res.KVs) != e {
  2226  				t.Fatalf("e = %d, got %d", e, len(res.KVs))
  2227  			}
  2228  		})
  2229  	}
  2230  }
  2231  
  2232  func TestMVCCDeleteRangeInline(t *testing.T) {
  2233  	defer leaktest.AfterTest(t)()
  2234  
  2235  	ctx := context.Background()
  2236  	for _, engineImpl := range mvccEngineImpls {
  2237  		t.Run(engineImpl.name, func(t *testing.T) {
  2238  			engine := engineImpl.create()
  2239  			defer engine.Close()
  2240  
  2241  			// Make five inline values (zero timestamp).
  2242  			for i, kv := range []struct {
  2243  				key   roachpb.Key
  2244  				value roachpb.Value
  2245  			}{
  2246  				{testKey1, value1},
  2247  				{testKey2, value2},
  2248  				{testKey3, value3},
  2249  				{testKey4, value4},
  2250  				{testKey5, value5},
  2251  			} {
  2252  				if err := MVCCPut(ctx, engine, nil, kv.key, hlc.Timestamp{Logical: 0}, kv.value, nil); err != nil {
  2253  					t.Fatalf("%d: %+v", i, err)
  2254  				}
  2255  			}
  2256  
  2257  			// Create one non-inline value (non-zero timestamp).
  2258  			if err := MVCCPut(ctx, engine, nil, testKey6, hlc.Timestamp{WallTime: 1}, value6, nil); err != nil {
  2259  				t.Fatal(err)
  2260  			}
  2261  
  2262  			// Attempt to delete two inline keys, should succeed.
  2263  			deleted, resumeSpan, num, err := MVCCDeleteRange(
  2264  				ctx, engine, nil, testKey2, testKey6, 2, hlc.Timestamp{Logical: 0}, nil, true,
  2265  			)
  2266  			if err != nil {
  2267  				t.Fatal(err)
  2268  			}
  2269  			if expected := int64(2); num != expected {
  2270  				t.Fatalf("got %d deleted keys, expected %d", num, expected)
  2271  			}
  2272  			if expected := []roachpb.Key{testKey2, testKey3}; !reflect.DeepEqual(deleted, expected) {
  2273  				t.Fatalf("got deleted values = %v, expected = %v", deleted, expected)
  2274  			}
  2275  			if expected := (roachpb.Span{Key: testKey4, EndKey: testKey6}); !resumeSpan.EqualValue(expected) {
  2276  				t.Fatalf("got resume span = %s, expected = %s", resumeSpan, expected)
  2277  			}
  2278  
  2279  			const inlineMismatchErrString = "put is inline"
  2280  
  2281  			// Attempt to delete inline keys at a timestamp; should fail.
  2282  			if _, _, _, err := MVCCDeleteRange(
  2283  				ctx, engine, nil, testKey1, testKey6, 1, hlc.Timestamp{WallTime: 2}, nil, true,
  2284  			); !testutils.IsError(err, inlineMismatchErrString) {
  2285  				t.Fatalf("got error %v, expected error with text '%s'", err, inlineMismatchErrString)
  2286  			}
  2287  
  2288  			// Attempt to delete non-inline key at zero timestamp; should fail.
  2289  			if _, _, _, err := MVCCDeleteRange(
  2290  				ctx, engine, nil, testKey6, keyMax, 1, hlc.Timestamp{Logical: 0}, nil, true,
  2291  			); !testutils.IsError(err, inlineMismatchErrString) {
  2292  				t.Fatalf("got error %v, expected error with text '%s'", err, inlineMismatchErrString)
  2293  			}
  2294  
  2295  			// Attempt to delete inline keys in a transaction; should fail.
  2296  			if _, _, _, err := MVCCDeleteRange(
  2297  				ctx, engine, nil, testKey2, testKey6, 2, hlc.Timestamp{Logical: 0}, txn1, true,
  2298  			); !testutils.IsError(err, "writes not allowed within transactions") {
  2299  				t.Errorf("unexpected error: %+v", err)
  2300  			}
  2301  
  2302  			// Verify final state of the engine.
  2303  			expectedKvs := []roachpb.KeyValue{
  2304  				{
  2305  					Key:   testKey1,
  2306  					Value: value1,
  2307  				},
  2308  				{
  2309  					Key:   testKey4,
  2310  					Value: value4,
  2311  				},
  2312  				{
  2313  					Key:   testKey5,
  2314  					Value: value5,
  2315  				},
  2316  				{
  2317  					Key:   testKey6,
  2318  					Value: value6,
  2319  				},
  2320  			}
  2321  			res, err := MVCCScan(ctx, engine, keyMin, keyMax, hlc.Timestamp{WallTime: 2},
  2322  				MVCCScanOptions{})
  2323  			if err != nil {
  2324  				t.Fatal(err)
  2325  			}
  2326  			if a, e := len(res.KVs), len(expectedKvs); a != e {
  2327  				t.Fatalf("engine scan found %d keys; expected %d", a, e)
  2328  			}
  2329  			res.KVs[3].Value.Timestamp = hlc.Timestamp{}
  2330  			if !reflect.DeepEqual(expectedKvs, res.KVs) {
  2331  				t.Fatalf(
  2332  					"engine scan found key/values: %v; expected %v. Diff: %s",
  2333  					res.KVs,
  2334  					expectedKvs,
  2335  					pretty.Diff(res.KVs, expectedKvs),
  2336  				)
  2337  			}
  2338  		})
  2339  	}
  2340  }
  2341  
  2342  func TestMVCCClearTimeRange(t *testing.T) {
  2343  	defer leaktest.AfterTest(t)()
  2344  
  2345  	ctx := context.Background()
  2346  	for _, engineImpl := range mvccEngineImpls {
  2347  		t.Run(engineImpl.name, func(t *testing.T) {
  2348  
  2349  			ts0 := hlc.Timestamp{WallTime: 0}
  2350  			ts0Content := []roachpb.KeyValue{}
  2351  			ts1 := hlc.Timestamp{WallTime: 10}
  2352  			v1 := value1
  2353  			v1.Timestamp = ts1
  2354  			ts1Content := []roachpb.KeyValue{{Key: testKey2, Value: v1}}
  2355  			ts2 := hlc.Timestamp{WallTime: 20}
  2356  			v2 := value2
  2357  			v2.Timestamp = ts2
  2358  			ts2Content := []roachpb.KeyValue{{Key: testKey2, Value: v2}, {Key: testKey5, Value: v2}}
  2359  			ts3 := hlc.Timestamp{WallTime: 30}
  2360  			v3 := value3
  2361  			v3.Timestamp = ts3
  2362  			ts3Content := []roachpb.KeyValue{
  2363  				{Key: testKey1, Value: v3}, {Key: testKey2, Value: v2}, {Key: testKey5, Value: v2},
  2364  			}
  2365  			ts4 := hlc.Timestamp{WallTime: 40}
  2366  			v4 := value4
  2367  			v4.Timestamp = ts4
  2368  			ts4Content := []roachpb.KeyValue{
  2369  				{Key: testKey1, Value: v3}, {Key: testKey2, Value: v4}, {Key: testKey5, Value: v4},
  2370  			}
  2371  			ts5 := hlc.Timestamp{WallTime: 50}
  2372  
  2373  			// setupKVs will generate an engine with the key-time space as follows:
  2374  			//    50 -
  2375  			//       |
  2376  			//    40 -      v4          v4
  2377  			//       |
  2378  			//    30 -  v3
  2379  			// time  |
  2380  			//    20 -      v2          v2
  2381  			//       |
  2382  			//    10 -      v1
  2383  			//       |
  2384  			//     0 -----------------------
  2385  			//          k1  k2  k3  k4  k5
  2386  			//                 keys
  2387  			// This returns a new, populated engine since we can't just setup one and use
  2388  			// a new batch in each subtest, since batches don't reflect ClearRange results
  2389  			// when read.
  2390  			setupKVs := func(t *testing.T) Engine {
  2391  				engine := engineImpl.create()
  2392  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey2, ts1, value1, nil))
  2393  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey2, ts2, value2, nil))
  2394  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey5, ts2, value2, nil))
  2395  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey1, ts3, value3, nil))
  2396  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey5, ts4, value4, nil))
  2397  				require.NoError(t, MVCCPut(ctx, engine, nil, testKey2, ts4, value4, nil))
  2398  				return engine
  2399  			}
  2400  
  2401  			assertKVs := func(t *testing.T, reader Reader, at hlc.Timestamp, expected []roachpb.KeyValue) {
  2402  				t.Helper()
  2403  				res, err := MVCCScan(ctx, reader, keyMin, keyMax, at, MVCCScanOptions{})
  2404  				require.NoError(t, err)
  2405  				require.Equal(t, expected, res.KVs)
  2406  			}
  2407  
  2408  			t.Run("clear > ts0", func(t *testing.T) {
  2409  				e := setupKVs(t)
  2410  				defer e.Close()
  2411  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts0, ts5, 10)
  2412  				require.NoError(t, err)
  2413  				assertKVs(t, e, ts0, ts0Content)
  2414  				assertKVs(t, e, ts1, ts0Content)
  2415  				assertKVs(t, e, ts5, ts0Content)
  2416  			})
  2417  
  2418  			t.Run("clear > ts1 ", func(t *testing.T) {
  2419  				e := setupKVs(t)
  2420  				defer e.Close()
  2421  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts1, ts5, 10)
  2422  				require.NoError(t, err)
  2423  				assertKVs(t, e, ts1, ts1Content)
  2424  				assertKVs(t, e, ts2, ts1Content)
  2425  				assertKVs(t, e, ts5, ts1Content)
  2426  			})
  2427  
  2428  			t.Run("clear > ts2", func(t *testing.T) {
  2429  				e := setupKVs(t)
  2430  				defer e.Close()
  2431  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts2, ts5, 10)
  2432  				require.NoError(t, err)
  2433  				assertKVs(t, e, ts2, ts2Content)
  2434  				assertKVs(t, e, ts5, ts2Content)
  2435  			})
  2436  
  2437  			t.Run("clear > ts3", func(t *testing.T) {
  2438  				e := setupKVs(t)
  2439  				defer e.Close()
  2440  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts3, ts5, 10)
  2441  				require.NoError(t, err)
  2442  				assertKVs(t, e, ts3, ts3Content)
  2443  				assertKVs(t, e, ts5, ts3Content)
  2444  			})
  2445  
  2446  			t.Run("clear > ts4 (nothing) ", func(t *testing.T) {
  2447  				e := setupKVs(t)
  2448  				defer e.Close()
  2449  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts4, ts5, 10)
  2450  				require.NoError(t, err)
  2451  				assertKVs(t, e, ts4, ts4Content)
  2452  				assertKVs(t, e, ts5, ts4Content)
  2453  			})
  2454  
  2455  			t.Run("clear > ts5 (nothing)", func(t *testing.T) {
  2456  				e := setupKVs(t)
  2457  				defer e.Close()
  2458  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts5, ts5, 10)
  2459  				require.NoError(t, err)
  2460  				assertKVs(t, e, ts4, ts4Content)
  2461  				assertKVs(t, e, ts5, ts4Content)
  2462  			})
  2463  
  2464  			t.Run("clear up to k5 to ts0", func(t *testing.T) {
  2465  				e := setupKVs(t)
  2466  				defer e.Close()
  2467  				_, err := MVCCClearTimeRange(ctx, e, nil, testKey1, testKey5, ts0, ts5, 10)
  2468  				require.NoError(t, err)
  2469  				assertKVs(t, e, ts2, []roachpb.KeyValue{{Key: testKey5, Value: v2}})
  2470  				assertKVs(t, e, ts5, []roachpb.KeyValue{{Key: testKey5, Value: v4}})
  2471  			})
  2472  
  2473  			t.Run("clear > ts0 in empty span (nothing)", func(t *testing.T) {
  2474  				e := setupKVs(t)
  2475  				defer e.Close()
  2476  				_, err := MVCCClearTimeRange(ctx, e, nil, testKey3, testKey5, ts0, ts5, 10)
  2477  				require.NoError(t, err)
  2478  				assertKVs(t, e, ts2, ts2Content)
  2479  				assertKVs(t, e, ts5, ts4Content)
  2480  			})
  2481  
  2482  			t.Run("clear > ts0 in empty span [k3,k5) (nothing)", func(t *testing.T) {
  2483  				e := setupKVs(t)
  2484  				defer e.Close()
  2485  				_, err := MVCCClearTimeRange(ctx, e, nil, testKey3, testKey5, ts0, ts5, 10)
  2486  				require.NoError(t, err)
  2487  				assertKVs(t, e, ts2, ts2Content)
  2488  				assertKVs(t, e, ts5, ts4Content)
  2489  			})
  2490  
  2491  			t.Run("clear k3 and up in ts0 > x >= ts1 (nothing)", func(t *testing.T) {
  2492  				e := setupKVs(t)
  2493  				defer e.Close()
  2494  				_, err := MVCCClearTimeRange(ctx, e, nil, testKey3, keyMax, ts0, ts1, 10)
  2495  				require.NoError(t, err)
  2496  				assertKVs(t, e, ts2, ts2Content)
  2497  				assertKVs(t, e, ts5, ts4Content)
  2498  			})
  2499  
  2500  			// Add an intent at k3@ts3.
  2501  			txn := roachpb.MakeTransaction("test", nil, roachpb.NormalUserPriority, ts3, 1)
  2502  			setupKVsWithIntent := func(t *testing.T) Engine {
  2503  				e := setupKVs(t)
  2504  				require.NoError(t, MVCCPut(ctx, e, nil, testKey3, ts3, value3, &txn))
  2505  				return e
  2506  			}
  2507  			t.Run("clear everything hitting intent fails", func(t *testing.T) {
  2508  				e := setupKVsWithIntent(t)
  2509  				defer e.Close()
  2510  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts0, ts5, 10)
  2511  				require.EqualError(t, err, "conflicting intents on \"/db3\"")
  2512  			})
  2513  
  2514  			t.Run("clear exactly hitting intent fails", func(t *testing.T) {
  2515  				e := setupKVsWithIntent(t)
  2516  				defer e.Close()
  2517  				_, err := MVCCClearTimeRange(ctx, e, nil, testKey3, testKey4, ts2, ts3, 10)
  2518  				require.EqualError(t, err, "conflicting intents on \"/db3\"")
  2519  			})
  2520  
  2521  			t.Run("clear everything above intent", func(t *testing.T) {
  2522  				e := setupKVsWithIntent(t)
  2523  				defer e.Close()
  2524  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts3, ts5, 10)
  2525  				require.NoError(t, err)
  2526  				assertKVs(t, e, ts2, ts2Content)
  2527  
  2528  				// Scan (< k3 to avoid intent) to confirm that k2 was indeed reverted to
  2529  				// value as of ts3 (i.e. v4 was cleared to expose v2).
  2530  				res, err := MVCCScan(ctx, e, keyMin, testKey3, ts5, MVCCScanOptions{})
  2531  				require.NoError(t, err)
  2532  				require.Equal(t, ts3Content[:2], res.KVs)
  2533  
  2534  				// Verify the intent was left alone.
  2535  				_, err = MVCCScan(ctx, e, testKey3, testKey4, ts5, MVCCScanOptions{})
  2536  				require.Error(t, err)
  2537  
  2538  				// Scan (> k3 to avoid intent) to confirm that k5 was indeed reverted to
  2539  				// value as of ts3 (i.e. v4 was cleared to expose v2).
  2540  				res, err = MVCCScan(ctx, e, testKey4, keyMax, ts5, MVCCScanOptions{})
  2541  				require.NoError(t, err)
  2542  				require.Equal(t, ts3Content[2:], res.KVs)
  2543  			})
  2544  
  2545  			t.Run("clear below intent", func(t *testing.T) {
  2546  				e := setupKVsWithIntent(t)
  2547  				defer e.Close()
  2548  				assertKVs(t, e, ts2, ts2Content)
  2549  				_, err := MVCCClearTimeRange(ctx, e, nil, keyMin, keyMax, ts1, ts2, 10)
  2550  				require.NoError(t, err)
  2551  				assertKVs(t, e, ts2, ts1Content)
  2552  			})
  2553  		})
  2554  	}
  2555  }
  2556  
  2557  func computeStats(
  2558  	t *testing.T, reader Reader, from, to roachpb.Key, nowNanos int64,
  2559  ) enginepb.MVCCStats {
  2560  	t.Helper()
  2561  	iter := reader.NewIterator(IterOptions{UpperBound: to})
  2562  	defer iter.Close()
  2563  	s, err := ComputeStatsGo(iter, from, to, nowNanos)
  2564  	if err != nil {
  2565  		t.Fatalf("%+v", err)
  2566  	}
  2567  	return s
  2568  }
  2569  
  2570  // TestMVCCClearTimeRangeOnRandomData sets up mostly random KVs and then picks
  2571  // some random times to which to revert, ensuring that a MVCC-Scan at each of
  2572  // those times before reverting matches the result of an MVCC-Scan done at a
  2573  // later time post-revert.
  2574  func TestMVCCClearTimeRangeOnRandomData(t *testing.T) {
  2575  	defer leaktest.AfterTest(t)()
  2576  
  2577  	rng, _ := randutil.NewPseudoRand()
  2578  
  2579  	ctx := context.Background()
  2580  
  2581  	for _, engineImpl := range mvccEngineImpls {
  2582  		t.Run(engineImpl.name, func(t *testing.T) {
  2583  			e := engineImpl.create()
  2584  			defer e.Close()
  2585  
  2586  			now := hlc.Timestamp{WallTime: 100000000}
  2587  
  2588  			var ms enginepb.MVCCStats
  2589  
  2590  			// Setup numKVs random kv by writing to random keys [0, keyRange) except for
  2591  			// the span [swathStart, swathEnd). Then fill in that swath with kvs all
  2592  			// having the same ts, to ensure they all revert at the same time, thus
  2593  			// triggering the ClearRange optimization path.
  2594  			const numKVs = 10000
  2595  			const keyRange, swathStart, swathEnd = 5000, 3500, 4000
  2596  			const swathSize = swathEnd - swathStart
  2597  			const randTimeRange = 1000
  2598  
  2599  			wrote := make(map[int]int64, keyRange)
  2600  			for i := 0; i < numKVs-swathSize; i++ {
  2601  				k := rng.Intn(keyRange - swathSize)
  2602  				if k >= swathStart {
  2603  					k += swathSize
  2604  				}
  2605  
  2606  				ts := int64(rng.Intn(randTimeRange))
  2607  				// Ensure writes to a given key are increasing in time.
  2608  				if ts <= wrote[k] {
  2609  					ts = wrote[k] + 1
  2610  				}
  2611  				wrote[k] = ts
  2612  
  2613  				key := roachpb.Key(fmt.Sprintf("%05d", k))
  2614  				if rand.Float64() > 0.8 {
  2615  					require.NoError(t, MVCCDelete(ctx, e, &ms, key, hlc.Timestamp{WallTime: ts}, nil))
  2616  				} else {
  2617  					v := roachpb.MakeValueFromString(fmt.Sprintf("v-%d", i))
  2618  					require.NoError(t, MVCCPut(ctx, e, &ms, key, hlc.Timestamp{WallTime: ts}, v, nil))
  2619  				}
  2620  			}
  2621  			swathTime := rand.Intn(randTimeRange-100) + 100
  2622  			for i := swathStart; i < swathEnd; i++ {
  2623  				key := roachpb.Key(fmt.Sprintf("%05d", i))
  2624  				v := roachpb.MakeValueFromString(fmt.Sprintf("v-%d", i))
  2625  				require.NoError(t, MVCCPut(ctx, e, &ms, key, hlc.Timestamp{WallTime: int64(swathTime)}, v, nil))
  2626  			}
  2627  
  2628  			// Add another swath of keys above to exercise an after-iteration range flush.
  2629  			for i := keyRange; i < keyRange+200; i++ {
  2630  				key := roachpb.Key(fmt.Sprintf("%05d", i))
  2631  				v := roachpb.MakeValueFromString(fmt.Sprintf("v-%d", i))
  2632  				require.NoError(t, MVCCPut(ctx, e, &ms, key, hlc.Timestamp{WallTime: int64(randTimeRange + 1)}, v, nil))
  2633  			}
  2634  
  2635  			ms.AgeTo(2000)
  2636  
  2637  			// Sanity check starting stats.
  2638  			require.Equal(t, computeStats(t, e, keyMin, keyMax, 2000), ms)
  2639  
  2640  			// Pick timestamps to which we'll revert, and sort them so we can go back
  2641  			// though them in order. The largest will still be less than randTimeRange so
  2642  			// the initial revert will be assured to use ClearRange.
  2643  			reverts := make([]int, 5)
  2644  			for i := range reverts {
  2645  				reverts[i] = rand.Intn(randTimeRange)
  2646  			}
  2647  			reverts[0] = swathTime - 1
  2648  			sort.Ints(reverts)
  2649  
  2650  			for i := len(reverts) - 1; i >= 0; i-- {
  2651  				t.Run(fmt.Sprintf("revert-%d", i), func(t *testing.T) {
  2652  					revertTo := hlc.Timestamp{WallTime: int64(reverts[i])}
  2653  					// MVCC-Scan at the revert time.
  2654  					resBefore, err := MVCCScan(ctx, e, keyMin, keyMax, revertTo, MVCCScanOptions{MaxKeys: numKVs})
  2655  					require.NoError(t, err)
  2656  
  2657  					// Revert to the revert time.
  2658  					startKey := keyMin
  2659  					for {
  2660  						resume, err := MVCCClearTimeRange(ctx, e, &ms, startKey, keyMax, revertTo, now, 100)
  2661  						require.NoError(t, err)
  2662  						if resume == nil {
  2663  							break
  2664  						}
  2665  						startKey = resume.Key
  2666  					}
  2667  
  2668  					require.Equal(t, computeStats(t, e, keyMin, keyMax, 2000), ms)
  2669  					// Scanning at "now" post-revert should yield the same result as scanning
  2670  					// at revert-time pre-revert.
  2671  					resAfter, err := MVCCScan(ctx, e, keyMin, keyMax, now, MVCCScanOptions{MaxKeys: numKVs})
  2672  					require.NoError(t, err)
  2673  					require.Equal(t, resBefore.KVs, resAfter.KVs)
  2674  				})
  2675  			}
  2676  		})
  2677  	}
  2678  }
  2679  
  2680  func TestMVCCInitPut(t *testing.T) {
  2681  	defer leaktest.AfterTest(t)()
  2682  
  2683  	ctx := context.Background()
  2684  	for _, engineImpl := range mvccEngineImpls {
  2685  		t.Run(engineImpl.name, func(t *testing.T) {
  2686  			engine := engineImpl.create()
  2687  			defer engine.Close()
  2688  
  2689  			err := MVCCInitPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 1}, value1, false, nil)
  2690  			if err != nil {
  2691  				t.Fatal(err)
  2692  			}
  2693  
  2694  			// A repeat of the command will still succeed
  2695  			err = MVCCInitPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 2}, value1, false, nil)
  2696  			if err != nil {
  2697  				t.Fatal(err)
  2698  			}
  2699  
  2700  			// Delete.
  2701  			err = MVCCDelete(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 3}, nil)
  2702  			if err != nil {
  2703  				t.Fatal(err)
  2704  			}
  2705  
  2706  			// Reinserting the value fails if we fail on tombstones.
  2707  			err = MVCCInitPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 4}, value1, true, nil)
  2708  			if e := (*roachpb.ConditionFailedError)(nil); errors.As(err, &e) {
  2709  				if !bytes.Equal(e.ActualValue.RawBytes, nil) {
  2710  					t.Fatalf("the value %s in get result is not a tombstone", e.ActualValue.RawBytes)
  2711  				}
  2712  			} else if err == nil {
  2713  				t.Fatal("MVCCInitPut with a different value did not fail")
  2714  			} else {
  2715  				t.Fatalf("unexpected error %T", e)
  2716  			}
  2717  
  2718  			// But doesn't if we *don't* fail on tombstones.
  2719  			err = MVCCInitPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 5}, value1, false, nil)
  2720  			if err != nil {
  2721  				t.Fatal(err)
  2722  			}
  2723  
  2724  			// A repeat of the command with a different value will fail.
  2725  			err = MVCCInitPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 6}, value2, false, nil)
  2726  			if e := (*roachpb.ConditionFailedError)(nil); errors.As(err, &e) {
  2727  				if !bytes.Equal(e.ActualValue.RawBytes, value1.RawBytes) {
  2728  					t.Fatalf("the value %s in get result does not match the value %s in request",
  2729  						e.ActualValue.RawBytes, value1.RawBytes)
  2730  				}
  2731  			} else if err == nil {
  2732  				t.Fatal("MVCCInitPut with a different value did not fail")
  2733  			} else {
  2734  				t.Fatalf("unexpected error %T", e)
  2735  			}
  2736  
  2737  			// Ensure that the timestamps were correctly updated.
  2738  			for _, check := range []struct {
  2739  				ts, expTS hlc.Timestamp
  2740  			}{
  2741  				{ts: hlc.Timestamp{Logical: 1}, expTS: hlc.Timestamp{Logical: 1}},
  2742  				{ts: hlc.Timestamp{Logical: 2}, expTS: hlc.Timestamp{Logical: 2}},
  2743  				// If we're checking the future wall time case, the rewrite after delete
  2744  				// will be present.
  2745  				{ts: hlc.Timestamp{WallTime: 1}, expTS: hlc.Timestamp{Logical: 5}},
  2746  			} {
  2747  				value, _, err := MVCCGet(ctx, engine, testKey1, check.ts, MVCCGetOptions{})
  2748  				if err != nil {
  2749  					t.Fatal(err)
  2750  				}
  2751  				if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  2752  					t.Fatalf("the value %s in get result does not match the value %s in request",
  2753  						value1.RawBytes, value.RawBytes)
  2754  				}
  2755  				if value.Timestamp != check.expTS {
  2756  					t.Errorf("value at timestamp %s seen, expected %s", value.Timestamp, check.expTS)
  2757  				}
  2758  			}
  2759  
  2760  			value, _, pErr := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 0}, MVCCGetOptions{})
  2761  			if pErr != nil {
  2762  				t.Fatal(pErr)
  2763  			}
  2764  			if value != nil {
  2765  				t.Fatalf("%v present at old timestamp", value)
  2766  			}
  2767  		})
  2768  	}
  2769  }
  2770  
  2771  func TestMVCCInitPutWithTxn(t *testing.T) {
  2772  	defer leaktest.AfterTest(t)()
  2773  
  2774  	ctx := context.Background()
  2775  	for _, engineImpl := range mvccEngineImpls {
  2776  		t.Run(engineImpl.name, func(t *testing.T) {
  2777  			engine := engineImpl.create()
  2778  			defer engine.Close()
  2779  
  2780  			clock := hlc.NewClock(hlc.NewManualClock(123).UnixNano, time.Nanosecond)
  2781  
  2782  			txn := *txn1
  2783  			txn.Sequence++
  2784  			err := MVCCInitPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value1, false, &txn)
  2785  			if err != nil {
  2786  				t.Fatal(err)
  2787  			}
  2788  
  2789  			// A repeat of the command will still succeed.
  2790  			txn.Sequence++
  2791  			err = MVCCInitPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value1, false, &txn)
  2792  			if err != nil {
  2793  				t.Fatal(err)
  2794  			}
  2795  
  2796  			// A repeat of the command with a different value at a different epoch
  2797  			// will still succeed.
  2798  			txn.Sequence++
  2799  			txn.Epoch = 2
  2800  			err = MVCCInitPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value2, false, &txn)
  2801  			if err != nil {
  2802  				t.Fatal(err)
  2803  			}
  2804  
  2805  			// Commit value3.
  2806  			txnCommit := txn
  2807  			txnCommit.Status = roachpb.COMMITTED
  2808  			txnCommit.WriteTimestamp = clock.Now().Add(1, 0)
  2809  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  2810  				roachpb.MakeLockUpdate(&txnCommit, roachpb.Span{Key: testKey1})); err != nil {
  2811  				t.Fatal(err)
  2812  			}
  2813  
  2814  			// Write value4 with an old timestamp without txn...should get an error.
  2815  			err = MVCCInitPut(ctx, engine, nil, testKey1, clock.Now(), value4, false, nil)
  2816  			if e := (*roachpb.ConditionFailedError)(nil); errors.As(err, &e) {
  2817  				if !bytes.Equal(e.ActualValue.RawBytes, value2.RawBytes) {
  2818  					t.Fatalf("the value %s in get result does not match the value %s in request",
  2819  						e.ActualValue.RawBytes, value2.RawBytes)
  2820  				}
  2821  			} else {
  2822  				t.Fatalf("unexpected error %T", e)
  2823  			}
  2824  		})
  2825  	}
  2826  }
  2827  
  2828  // TestMVCCReverseScan verifies that MVCCReverseScan scans [start,
  2829  // end) in descending order of keys.
  2830  func TestMVCCReverseScan(t *testing.T) {
  2831  	defer leaktest.AfterTest(t)()
  2832  
  2833  	ctx := context.Background()
  2834  	for _, engineImpl := range mvccEngineImpls {
  2835  		t.Run(engineImpl.name, func(t *testing.T) {
  2836  			engine := engineImpl.create()
  2837  			defer engine.Close()
  2838  
  2839  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  2840  				t.Fatal(err)
  2841  			}
  2842  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 2}, value2, nil); err != nil {
  2843  				t.Fatal(err)
  2844  			}
  2845  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value3, nil); err != nil {
  2846  				t.Fatal(err)
  2847  			}
  2848  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 3}, value4, nil); err != nil {
  2849  				t.Fatal(err)
  2850  			}
  2851  			if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  2852  				t.Fatal(err)
  2853  			}
  2854  			if err := MVCCPut(ctx, engine, nil, testKey4, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  2855  				t.Fatal(err)
  2856  			}
  2857  			if err := MVCCPut(ctx, engine, nil, testKey5, hlc.Timestamp{WallTime: 3}, value5, nil); err != nil {
  2858  				t.Fatal(err)
  2859  			}
  2860  			if err := MVCCPut(ctx, engine, nil, testKey6, hlc.Timestamp{WallTime: 3}, value6, nil); err != nil {
  2861  				t.Fatal(err)
  2862  			}
  2863  
  2864  			res, err := MVCCScan(ctx, engine, testKey2, testKey4,
  2865  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{Reverse: true})
  2866  
  2867  			if err != nil {
  2868  				t.Fatal(err)
  2869  			}
  2870  			if len(res.KVs) != 2 ||
  2871  				!bytes.Equal(res.KVs[0].Key, testKey3) ||
  2872  				!bytes.Equal(res.KVs[1].Key, testKey2) ||
  2873  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) ||
  2874  				!bytes.Equal(res.KVs[1].Value.RawBytes, value3.RawBytes) {
  2875  				t.Fatalf("unexpected value: %v", res.KVs)
  2876  			}
  2877  			if res.ResumeSpan != nil {
  2878  				t.Fatalf("resumeSpan = %+v", res.ResumeSpan)
  2879  			}
  2880  
  2881  			res, err = MVCCScan(ctx, engine, testKey2, testKey4, hlc.Timestamp{WallTime: 1},
  2882  				MVCCScanOptions{Reverse: true, MaxKeys: 1})
  2883  
  2884  			if err != nil {
  2885  				t.Fatal(err)
  2886  			}
  2887  			if len(res.KVs) != 1 ||
  2888  				!bytes.Equal(res.KVs[0].Key, testKey3) ||
  2889  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) {
  2890  				t.Fatalf("unexpected value: %v", res.KVs)
  2891  			}
  2892  			if expected := (roachpb.Span{Key: testKey2, EndKey: testKey2.Next()}); !res.ResumeSpan.EqualValue(expected) {
  2893  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, res.ResumeSpan)
  2894  			}
  2895  
  2896  			res, err = MVCCScan(ctx, engine, testKey2, testKey4, hlc.Timestamp{WallTime: 1},
  2897  				MVCCScanOptions{Reverse: true, MaxKeys: -1})
  2898  
  2899  			if err != nil {
  2900  				t.Fatal(err)
  2901  			}
  2902  			if len(res.KVs) != 0 {
  2903  				t.Fatalf("unexpected value: %v", res.KVs)
  2904  			}
  2905  			if expected := (roachpb.Span{Key: testKey2, EndKey: testKey4}); !res.ResumeSpan.EqualValue(expected) {
  2906  				t.Fatalf("expected = %+v, resumeSpan = %+v", expected, res.ResumeSpan)
  2907  			}
  2908  
  2909  			// The first key we encounter has multiple versions and we need to read the
  2910  			// latest.
  2911  			res, err = MVCCScan(ctx, engine, testKey2, testKey3, hlc.Timestamp{WallTime: 4},
  2912  				MVCCScanOptions{Reverse: true, MaxKeys: 1})
  2913  
  2914  			if err != nil {
  2915  				t.Fatal(err)
  2916  			}
  2917  			if len(res.KVs) != 1 ||
  2918  				!bytes.Equal(res.KVs[0].Key, testKey2) ||
  2919  				!bytes.Equal(res.KVs[0].Value.RawBytes, value4.RawBytes) {
  2920  				t.Errorf("unexpected value: %v", res.KVs)
  2921  			}
  2922  
  2923  			// The first key we encounter is newer than our read timestamp and we need to
  2924  			// back up to the previous key.
  2925  			res, err = MVCCScan(ctx, engine, testKey4, testKey6, hlc.Timestamp{WallTime: 1},
  2926  				MVCCScanOptions{Reverse: true, MaxKeys: 1})
  2927  
  2928  			if err != nil {
  2929  				t.Fatal(err)
  2930  			}
  2931  			if len(res.KVs) != 1 ||
  2932  				!bytes.Equal(res.KVs[0].Key, testKey4) ||
  2933  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) {
  2934  				t.Fatalf("unexpected value: %v", res.KVs)
  2935  			}
  2936  
  2937  			// Scan only the first key in the key space.
  2938  			res, err = MVCCScan(ctx, engine, testKey1, testKey1.Next(), hlc.Timestamp{WallTime: 1},
  2939  				MVCCScanOptions{Reverse: true, MaxKeys: 1})
  2940  
  2941  			if err != nil {
  2942  				t.Fatal(err)
  2943  			}
  2944  			if len(res.KVs) != 1 ||
  2945  				!bytes.Equal(res.KVs[0].Key, testKey1) ||
  2946  				!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) {
  2947  				t.Fatalf("unexpected value: %v", res.KVs)
  2948  			}
  2949  		})
  2950  	}
  2951  }
  2952  
  2953  // TestMVCCReverseScanFirstKeyInFuture verifies that when MVCCReverseScan scans
  2954  // encounter a key with only future timestamps first, that it skips the key and
  2955  // continues to scan in reverse. #17825 was caused by this not working correctly.
  2956  func TestMVCCReverseScanFirstKeyInFuture(t *testing.T) {
  2957  	defer leaktest.AfterTest(t)()
  2958  
  2959  	ctx := context.Background()
  2960  	for _, engineImpl := range mvccEngineImpls {
  2961  		t.Run(engineImpl.name, func(t *testing.T) {
  2962  			engine := engineImpl.create()
  2963  			defer engine.Close()
  2964  
  2965  			// The value at key2 will be at a lower timestamp than the ReverseScan, but
  2966  			// the value at key3 will be at a larger timetamp. The ReverseScan should
  2967  			// see key3 and ignore it because none of it versions are at a low enough
  2968  			// timestamp to read. It should then continue scanning backwards and find a
  2969  			// value at key2.
  2970  			//
  2971  			// Before fixing #17825, the MVCC version scan on key3 would fall out of the
  2972  			// scan bounds and if it never found another valid key before reaching
  2973  			// KeyMax, would stop the ReverseScan from continuing.
  2974  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  2975  				t.Fatal(err)
  2976  			}
  2977  			if err := MVCCPut(ctx, engine, nil, testKey3, hlc.Timestamp{WallTime: 3}, value3, nil); err != nil {
  2978  				t.Fatal(err)
  2979  			}
  2980  
  2981  			res, err := MVCCScan(ctx, engine, testKey1, testKey4,
  2982  				hlc.Timestamp{WallTime: 2}, MVCCScanOptions{Reverse: true})
  2983  			if err != nil {
  2984  				t.Fatal(err)
  2985  			}
  2986  			if len(res.KVs) != 1 ||
  2987  				!bytes.Equal(res.KVs[0].Key, testKey2) ||
  2988  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) {
  2989  				t.Errorf("unexpected value: %v", res.KVs)
  2990  			}
  2991  		})
  2992  	}
  2993  }
  2994  
  2995  // Exposes a bug where the reverse MVCC scan can get stuck in an infinite loop
  2996  // until we OOM. It happened in the code path optimized to use `SeekForPrev()`
  2997  // after N `Prev()`s do not reach another logical key. Further, a write intent
  2998  // needed to be present on the logical key to make it conflict with our chosen
  2999  // `SeekForPrev()` target (logical key + '\0').
  3000  func TestMVCCReverseScanSeeksOverRepeatedKeys(t *testing.T) {
  3001  	defer leaktest.AfterTest(t)()
  3002  
  3003  	ctx := context.Background()
  3004  	for _, engineImpl := range mvccEngineImpls {
  3005  		t.Run(engineImpl.name, func(t *testing.T) {
  3006  			engine := engineImpl.create()
  3007  			defer engine.Close()
  3008  
  3009  			// 10 is the value of `kMaxItersBeforeSeek` at the time this test case was
  3010  			// written. Repeat the key enough times to make sure the `SeekForPrev()`
  3011  			// optimization will be used.
  3012  			for i := 1; i <= 10; i++ {
  3013  				if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{WallTime: int64(i)}, value2, nil); err != nil {
  3014  					t.Fatal(err)
  3015  				}
  3016  			}
  3017  			txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 11})
  3018  			if err := MVCCPut(ctx, engine, nil, testKey2, txn1ts.ReadTimestamp, value2, txn1ts); err != nil {
  3019  				t.Fatal(err)
  3020  			}
  3021  
  3022  			res, err := MVCCScan(ctx, engine, testKey1, testKey3,
  3023  				hlc.Timestamp{WallTime: 1}, MVCCScanOptions{Reverse: true})
  3024  			if err != nil {
  3025  				t.Fatal(err)
  3026  			}
  3027  			if len(res.KVs) != 1 ||
  3028  				!bytes.Equal(res.KVs[0].Key, testKey2) ||
  3029  				!bytes.Equal(res.KVs[0].Value.RawBytes, value2.RawBytes) {
  3030  				t.Fatal("unexpected scan results")
  3031  			}
  3032  		})
  3033  	}
  3034  }
  3035  
  3036  // Exposes a bug where the reverse MVCC scan can get stuck in an infinite loop until we OOM.
  3037  //
  3038  // The bug happened in this scenario.
  3039  // (1) reverse scan is positioned at the range's smallest key and calls `prevKey()`
  3040  // (2) `prevKey()` peeks and sees newer versions of the same logical key
  3041  //     `iters_before_seek_-1` times, moving the iterator backwards each time
  3042  // (3) on the `iters_before_seek_`th peek, there are no previous keys found
  3043  //
  3044  // Then, the problem was `prevKey()` treated finding no previous key as if it had found a
  3045  // new logical key with the empty string. It would use `backwardLatestVersion()` to find
  3046  // the latest version of this empty string logical key. Due to condition (3),
  3047  // `backwardLatestVersion()` would go directly to its seeking optimization rather than
  3048  // trying to incrementally move backwards (if it had tried moving incrementally backwards,
  3049  // it would've noticed it's out of bounds). The seek optimization would then seek to "\0",
  3050  // which is the empty logical key with zero timestamp. Since we set RocksDB iterator lower
  3051  // bound to be the lower bound of the range scan, this seek actually lands back at the
  3052  // range's smallest key. It thinks it found a new key so it adds it to the result, and then
  3053  // this whole process repeats ad infinitum.
  3054  func TestMVCCReverseScanStopAtSmallestKey(t *testing.T) {
  3055  	defer leaktest.AfterTest(t)()
  3056  	for _, engineImpl := range mvccEngineImpls {
  3057  		t.Run(engineImpl.name, func(t *testing.T) {
  3058  			run := func(numPuts int, ts int64) {
  3059  				ctx := context.Background()
  3060  				engine := engineImpl.create()
  3061  				defer engine.Close()
  3062  
  3063  				for i := 1; i <= numPuts; i++ {
  3064  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: int64(i)}, value1, nil); err != nil {
  3065  						t.Fatal(err)
  3066  					}
  3067  				}
  3068  
  3069  				res, err := MVCCScan(ctx, engine, testKey1, testKey3,
  3070  					hlc.Timestamp{WallTime: ts}, MVCCScanOptions{Reverse: true})
  3071  				if err != nil {
  3072  					t.Fatal(err)
  3073  				}
  3074  				if len(res.KVs) != 1 ||
  3075  					!bytes.Equal(res.KVs[0].Key, testKey1) ||
  3076  					!bytes.Equal(res.KVs[0].Value.RawBytes, value1.RawBytes) {
  3077  					t.Fatal("unexpected scan results")
  3078  				}
  3079  			}
  3080  			// Satisfying (2) and (3) is incredibly intricate because of how `iters_before_seek_`
  3081  			// is incremented/decremented heuristically. For example, at the time of writing, the
  3082  			// infinitely looping cases are `numPuts == 6 && ts == 2`, `numPuts == 7 && ts == 3`,
  3083  			// `numPuts == 8 && ts == 4`, `numPuts == 9 && ts == 5`, and `numPuts == 10 && ts == 6`.
  3084  			// Tying our test case to the `iters_before_seek_` setting logic seems brittle so let's
  3085  			// just brute force test a wide range of cases.
  3086  			for numPuts := 1; numPuts <= 10; numPuts++ {
  3087  				for ts := 1; ts <= 10; ts++ {
  3088  					run(numPuts, int64(ts))
  3089  				}
  3090  			}
  3091  		})
  3092  	}
  3093  }
  3094  
  3095  func TestMVCCResolveTxn(t *testing.T) {
  3096  	defer leaktest.AfterTest(t)()
  3097  
  3098  	ctx := context.Background()
  3099  	for _, engineImpl := range mvccEngineImpls {
  3100  		t.Run(engineImpl.name, func(t *testing.T) {
  3101  			engine := engineImpl.create()
  3102  			defer engine.Close()
  3103  
  3104  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3105  				t.Fatal(err)
  3106  			}
  3107  
  3108  			{
  3109  				value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{
  3110  					Txn: txn1,
  3111  				})
  3112  				if err != nil {
  3113  					t.Fatal(err)
  3114  				}
  3115  				if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3116  					t.Fatalf("the value %s in get result does not match the value %s in request",
  3117  						value1.RawBytes, value.RawBytes)
  3118  				}
  3119  			}
  3120  
  3121  			// Resolve will write with txn1's timestamp which is 0,1.
  3122  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3123  				roachpb.MakeLockUpdate(txn1Commit, roachpb.Span{Key: testKey1})); err != nil {
  3124  				t.Fatal(err)
  3125  			}
  3126  
  3127  			{
  3128  				value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  3129  				if err != nil {
  3130  					t.Fatal(err)
  3131  				}
  3132  				if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3133  					t.Fatalf("the value %s in get result does not match the value %s in request",
  3134  						value1.RawBytes, value.RawBytes)
  3135  				}
  3136  			}
  3137  		})
  3138  	}
  3139  }
  3140  
  3141  // TestMVCCResolveNewerIntent verifies that resolving a newer intent
  3142  // than the committing transaction aborts the intent.
  3143  func TestMVCCResolveNewerIntent(t *testing.T) {
  3144  	defer leaktest.AfterTest(t)()
  3145  
  3146  	ctx := context.Background()
  3147  	for _, engineImpl := range mvccEngineImpls {
  3148  		t.Run(engineImpl.name, func(t *testing.T) {
  3149  			engine := engineImpl.create()
  3150  			defer engine.Close()
  3151  
  3152  			// Write first value.
  3153  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1Commit.WriteTimestamp, value1, nil); err != nil {
  3154  				t.Fatal(err)
  3155  			}
  3156  			// Now, put down an intent which should return a write too old error
  3157  			// (but will still write the intent at tx1Commit.Timestmap+1.
  3158  			err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value2, txn1)
  3159  			if !errors.HasType(err, (*roachpb.WriteTooOldError)(nil)) {
  3160  				t.Fatalf("expected write too old error; got %s", err)
  3161  			}
  3162  
  3163  			// Resolve will succeed but should remove the intent.
  3164  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3165  				roachpb.MakeLockUpdate(txn1Commit, roachpb.Span{Key: testKey1})); err != nil {
  3166  				t.Fatal(err)
  3167  			}
  3168  
  3169  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 2}, MVCCGetOptions{})
  3170  			if err != nil {
  3171  				t.Fatal(err)
  3172  			}
  3173  			if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3174  				t.Fatalf("expected value1 bytes; got %q", value.RawBytes)
  3175  			}
  3176  		})
  3177  	}
  3178  }
  3179  
  3180  func TestMVCCResolveIntentTxnTimestampMismatch(t *testing.T) {
  3181  	defer leaktest.AfterTest(t)()
  3182  
  3183  	ctx := context.Background()
  3184  	for _, engineImpl := range mvccEngineImpls {
  3185  		t.Run(engineImpl.name, func(t *testing.T) {
  3186  			engine := engineImpl.create()
  3187  			defer engine.Close()
  3188  
  3189  			txn := txn1.Clone()
  3190  			tsEarly := txn.WriteTimestamp
  3191  			txn.TxnMeta.WriteTimestamp.Forward(tsEarly.Add(10, 0))
  3192  
  3193  			// Write an intent which has txn.Timestamp > meta.timestamp.
  3194  			if err := MVCCPut(ctx, engine, nil, testKey1, tsEarly, value1, txn); err != nil {
  3195  				t.Fatal(err)
  3196  			}
  3197  
  3198  			// The Timestamp within is equal to that of txn.Meta even though
  3199  			// the intent sits at tsEarly. The bug was looking at the former
  3200  			// instead of the latter (and so we could also tickle it with
  3201  			// smaller timestamps in Txn).
  3202  			intent := roachpb.MakeLockUpdate(txn, roachpb.Span{Key: testKey1})
  3203  			intent.Status = roachpb.PENDING
  3204  
  3205  			// A bug (see #7654) caused intents to just stay where they were instead
  3206  			// of being moved forward in the situation set up above.
  3207  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil, intent); err != nil {
  3208  				t.Fatal(err)
  3209  			}
  3210  
  3211  			for i, test := range []struct {
  3212  				hlc.Timestamp
  3213  				found bool
  3214  			}{
  3215  				// Check that the intent has indeed moved to where we pushed it.
  3216  				{tsEarly, false},
  3217  				{intent.Txn.WriteTimestamp.Prev(), false},
  3218  				{intent.Txn.WriteTimestamp, true},
  3219  				{hlc.MaxTimestamp, true},
  3220  			} {
  3221  				_, _, err := MVCCGet(ctx, engine, testKey1, test.Timestamp, MVCCGetOptions{})
  3222  				if errors.HasType(err, (*roachpb.WriteIntentError)(nil)) != test.found {
  3223  					t.Fatalf("%d: expected write intent error: %t, got %v", i, test.found, err)
  3224  				}
  3225  			}
  3226  		})
  3227  	}
  3228  }
  3229  
  3230  // TestMVCCConditionalPutOldTimestamp tests a case where a conditional
  3231  // put with an older timestamp happens after a put with a newer timestamp.
  3232  //
  3233  // The conditional put uses the actual value at the timestamp as the
  3234  // basis for comparison first, and then may fail later with a
  3235  // WriteTooOldError if that timestamp isn't recent.
  3236  func TestMVCCConditionalPutOldTimestamp(t *testing.T) {
  3237  	defer leaktest.AfterTest(t)()
  3238  
  3239  	ctx := context.Background()
  3240  	for _, engineImpl := range mvccEngineImpls {
  3241  		t.Run(engineImpl.name, func(t *testing.T) {
  3242  			engine := engineImpl.create()
  3243  			defer engine.Close()
  3244  			err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil)
  3245  			if err != nil {
  3246  				t.Fatal(err)
  3247  			}
  3248  			err = MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, value2, nil)
  3249  			if err != nil {
  3250  				t.Fatal(err)
  3251  			}
  3252  
  3253  			// Check nothing is written if the value doesn't match.
  3254  			err = MVCCConditionalPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 2}, value3, &value1, CPutFailIfMissing, nil)
  3255  			if err == nil {
  3256  				t.Errorf("unexpected success on conditional put")
  3257  			}
  3258  			if !errors.HasType(err, (*roachpb.ConditionFailedError)(nil)) {
  3259  				t.Errorf("unexpected error on conditional put: %+v", err)
  3260  			}
  3261  
  3262  			// But if value does match the most recently written version, we'll get
  3263  			// a write too old error but still write updated value.
  3264  			err = MVCCConditionalPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 2}, value3, &value2, CPutFailIfMissing, nil)
  3265  			if err == nil {
  3266  				t.Errorf("unexpected success on conditional put")
  3267  			}
  3268  			if !errors.HasType(err, (*roachpb.WriteTooOldError)(nil)) {
  3269  				t.Errorf("unexpected error on conditional put: %+v", err)
  3270  			}
  3271  			// Verify new value was actually written at (3, 1).
  3272  			ts := hlc.Timestamp{WallTime: 3, Logical: 1}
  3273  			value, _, err := MVCCGet(ctx, engine, testKey1, ts, MVCCGetOptions{})
  3274  			if err != nil || value.Timestamp != ts || !bytes.Equal(value3.RawBytes, value.RawBytes) {
  3275  				t.Fatalf("expected err=nil (got %s), timestamp=%s (got %s), value=%q (got %q)",
  3276  					err, value.Timestamp, ts, value3.RawBytes, value.RawBytes)
  3277  			}
  3278  		})
  3279  	}
  3280  }
  3281  
  3282  // TestMVCCMultiplePutOldTimestamp tests a case where multiple
  3283  // transactional Puts occur to the same key, but with older timestamps
  3284  // than a pre-existing key. The first should generate a
  3285  // WriteTooOldError and write at a higher timestamp. The second should
  3286  // avoid the WriteTooOldError but also write at the higher timestamp.
  3287  func TestMVCCMultiplePutOldTimestamp(t *testing.T) {
  3288  	defer leaktest.AfterTest(t)()
  3289  
  3290  	ctx := context.Background()
  3291  	for _, engineImpl := range mvccEngineImpls {
  3292  		t.Run(engineImpl.name, func(t *testing.T) {
  3293  			engine := engineImpl.create()
  3294  			defer engine.Close()
  3295  
  3296  			err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, value1, nil)
  3297  			if err != nil {
  3298  				t.Fatal(err)
  3299  			}
  3300  
  3301  			// Verify the first txn Put returns a write too old error, but the
  3302  			// intent is written at the advanced timestamp.
  3303  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  3304  			txn.Sequence++
  3305  			err = MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value2, txn)
  3306  			if !errors.HasType(err, (*roachpb.WriteTooOldError)(nil)) {
  3307  				t.Errorf("expected WriteTooOldError on Put; got %v", err)
  3308  			}
  3309  			// Verify new value was actually written at (3, 1).
  3310  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.MaxTimestamp, MVCCGetOptions{Txn: txn})
  3311  			if err != nil {
  3312  				t.Fatal(err)
  3313  			}
  3314  			expTS := hlc.Timestamp{WallTime: 3, Logical: 1}
  3315  			if value.Timestamp != expTS || !bytes.Equal(value2.RawBytes, value.RawBytes) {
  3316  				t.Fatalf("expected timestamp=%s (got %s), value=%q (got %q)",
  3317  					value.Timestamp, expTS, value2.RawBytes, value.RawBytes)
  3318  			}
  3319  
  3320  			// Put again and verify no WriteTooOldError, but timestamp should continue
  3321  			// to be set to (3,1).
  3322  			txn.Sequence++
  3323  			err = MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value3, txn)
  3324  			if err != nil {
  3325  				t.Error(err)
  3326  			}
  3327  			// Verify new value was actually written at (3, 1).
  3328  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.MaxTimestamp, MVCCGetOptions{Txn: txn})
  3329  			if err != nil {
  3330  				t.Fatal(err)
  3331  			}
  3332  			if value.Timestamp != expTS || !bytes.Equal(value3.RawBytes, value.RawBytes) {
  3333  				t.Fatalf("expected timestamp=%s (got %s), value=%q (got %q)",
  3334  					value.Timestamp, expTS, value3.RawBytes, value.RawBytes)
  3335  			}
  3336  		})
  3337  	}
  3338  }
  3339  
  3340  func TestMVCCPutNegativeTimestampError(t *testing.T) {
  3341  	defer leaktest.AfterTest(t)()
  3342  
  3343  	ctx := context.Background()
  3344  	for _, engineImpl := range mvccEngineImpls {
  3345  		t.Run(engineImpl.name, func(t *testing.T) {
  3346  			engine := engineImpl.create()
  3347  			defer engine.Close()
  3348  
  3349  			timestamp := hlc.Timestamp{WallTime: -1}
  3350  			expectedErrorString := fmt.Sprintf("cannot write to %q at timestamp %s", testKey1, timestamp)
  3351  
  3352  			err := MVCCPut(ctx, engine, nil, testKey1, timestamp, value1, nil)
  3353  
  3354  			require.EqualError(t, err, expectedErrorString)
  3355  		})
  3356  	}
  3357  }
  3358  
  3359  // TestMVCCPutOldOrigTimestampNewCommitTimestamp tests a case where a
  3360  // transactional Put occurs to the same key, but with an older original
  3361  // timestamp than a pre-existing key. As always, this should result in a
  3362  // WriteTooOld error. However, in this case the transaction has a larger
  3363  // provisional commit timestamp than the pre-existing key. It should write
  3364  // its intent at this timestamp instead of directly above the existing key.
  3365  func TestMVCCPutOldOrigTimestampNewCommitTimestamp(t *testing.T) {
  3366  	defer leaktest.AfterTest(t)()
  3367  
  3368  	ctx := context.Background()
  3369  	for _, engineImpl := range mvccEngineImpls {
  3370  		t.Run(engineImpl.name, func(t *testing.T) {
  3371  			engine := engineImpl.create()
  3372  			defer engine.Close()
  3373  
  3374  			err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, value1, nil)
  3375  			if err != nil {
  3376  				t.Fatal(err)
  3377  			}
  3378  
  3379  			// Perform a transactional Put with a transaction whose original timestamp is
  3380  			// below the existing key's timestamp and whose provisional commit timestamp
  3381  			// is above the existing key's timestamp.
  3382  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  3383  			txn.WriteTimestamp = hlc.Timestamp{WallTime: 5}
  3384  			txn.Sequence++
  3385  			err = MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value2, txn)
  3386  
  3387  			// Verify that the Put returned a WriteTooOld with the ActualTime set to the
  3388  			// transactions provisional commit timestamp.
  3389  			expTS := txn.WriteTimestamp
  3390  			if wtoErr := (*roachpb.WriteTooOldError)(nil); !errors.As(err, &wtoErr) || wtoErr.ActualTimestamp != expTS {
  3391  				t.Fatalf("expected WriteTooOldError with actual time = %s; got %s", expTS, wtoErr)
  3392  			}
  3393  
  3394  			// Verify new value was actually written at the transaction's provisional
  3395  			// commit timestamp.
  3396  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.MaxTimestamp, MVCCGetOptions{Txn: txn})
  3397  			if err != nil {
  3398  				t.Fatal(err)
  3399  			}
  3400  			if value.Timestamp != expTS || !bytes.Equal(value2.RawBytes, value.RawBytes) {
  3401  				t.Fatalf("expected timestamp=%s (got %s), value=%q (got %q)",
  3402  					value.Timestamp, expTS, value2.RawBytes, value.RawBytes)
  3403  			}
  3404  		})
  3405  	}
  3406  }
  3407  
  3408  func TestMVCCAbortTxn(t *testing.T) {
  3409  	defer leaktest.AfterTest(t)()
  3410  
  3411  	ctx := context.Background()
  3412  	for _, engineImpl := range mvccEngineImpls {
  3413  		t.Run(engineImpl.name, func(t *testing.T) {
  3414  			engine := engineImpl.create()
  3415  			defer engine.Close()
  3416  
  3417  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3418  				t.Fatal(err)
  3419  			}
  3420  
  3421  			txn1AbortWithTS := txn1Abort.Clone()
  3422  			txn1AbortWithTS.WriteTimestamp = hlc.Timestamp{Logical: 1}
  3423  
  3424  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3425  				roachpb.MakeLockUpdate(txn1AbortWithTS, roachpb.Span{Key: testKey1}),
  3426  			); err != nil {
  3427  				t.Fatal(err)
  3428  			}
  3429  
  3430  			if value, _, err := MVCCGet(
  3431  				ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{},
  3432  			); err != nil {
  3433  				t.Fatal(err)
  3434  			} else if value != nil {
  3435  				t.Fatalf("expected the value to be empty: %s", value)
  3436  			}
  3437  			if meta, err := engine.Get(mvccKey(testKey1)); err != nil {
  3438  				t.Fatal(err)
  3439  			} else if len(meta) != 0 {
  3440  				t.Fatalf("expected no more MVCCMetadata, got: %s", meta)
  3441  			}
  3442  		})
  3443  	}
  3444  }
  3445  
  3446  func TestMVCCAbortTxnWithPreviousVersion(t *testing.T) {
  3447  	defer leaktest.AfterTest(t)()
  3448  
  3449  	ctx := context.Background()
  3450  	for _, engineImpl := range mvccEngineImpls {
  3451  		t.Run(engineImpl.name, func(t *testing.T) {
  3452  			engine := engineImpl.create()
  3453  			defer engine.Close()
  3454  
  3455  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 1}, value1, nil); err != nil {
  3456  				t.Fatal(err)
  3457  			}
  3458  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value2, nil); err != nil {
  3459  				t.Fatal(err)
  3460  			}
  3461  			txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 2})
  3462  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1ts.ReadTimestamp, value3, txn1ts); err != nil {
  3463  				t.Fatal(err)
  3464  			}
  3465  
  3466  			txn1AbortWithTS := txn1Abort.Clone()
  3467  			txn1AbortWithTS.WriteTimestamp = hlc.Timestamp{WallTime: 2}
  3468  
  3469  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3470  				roachpb.MakeLockUpdate(txn1AbortWithTS, roachpb.Span{Key: testKey1}),
  3471  			); err != nil {
  3472  				t.Fatal(err)
  3473  			}
  3474  
  3475  			if meta, err := engine.Get(mvccKey(testKey1)); err != nil {
  3476  				t.Fatal(err)
  3477  			} else if len(meta) != 0 {
  3478  				t.Fatalf("expected no more MVCCMetadata, got: %s", meta)
  3479  			}
  3480  
  3481  			if value, _, err := MVCCGet(
  3482  				ctx, engine, testKey1, hlc.Timestamp{WallTime: 3}, MVCCGetOptions{},
  3483  			); err != nil {
  3484  				t.Fatal(err)
  3485  			} else if expTS := (hlc.Timestamp{WallTime: 1}); value.Timestamp != expTS {
  3486  				t.Fatalf("expected timestamp %+v == %+v", value.Timestamp, expTS)
  3487  			} else if !bytes.Equal(value2.RawBytes, value.RawBytes) {
  3488  				t.Fatalf("the value %q in get result does not match the value %q in request",
  3489  					value.RawBytes, value2.RawBytes)
  3490  			}
  3491  		})
  3492  	}
  3493  }
  3494  
  3495  func TestMVCCWriteWithDiffTimestampsAndEpochs(t *testing.T) {
  3496  	defer leaktest.AfterTest(t)()
  3497  
  3498  	ctx := context.Background()
  3499  	for _, engineImpl := range mvccEngineImpls {
  3500  		t.Run(engineImpl.name, func(t *testing.T) {
  3501  			engine := engineImpl.create()
  3502  			defer engine.Close()
  3503  
  3504  			// Start with epoch 1.
  3505  			txn := *txn1
  3506  			txn.Sequence++
  3507  			if err := MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value1, &txn); err != nil {
  3508  				t.Fatal(err)
  3509  			}
  3510  			// Now write with greater timestamp and epoch 2.
  3511  			txne2 := txn
  3512  			txne2.Sequence++
  3513  			txne2.Epoch = 2
  3514  			txne2.WriteTimestamp = hlc.Timestamp{WallTime: 1}
  3515  			if err := MVCCPut(ctx, engine, nil, testKey1, txne2.ReadTimestamp, value2, &txne2); err != nil {
  3516  				t.Fatal(err)
  3517  			}
  3518  			// Try a write with an earlier timestamp; this is just ignored.
  3519  			txne2.Sequence++
  3520  			txne2.WriteTimestamp = hlc.Timestamp{WallTime: 1}
  3521  			if err := MVCCPut(ctx, engine, nil, testKey1, txne2.ReadTimestamp, value1, &txne2); err != nil {
  3522  				t.Fatal(err)
  3523  			}
  3524  			// Try a write with an earlier epoch; again ignored.
  3525  			if err := MVCCPut(ctx, engine, nil, testKey1, txn.ReadTimestamp, value1, &txn); err == nil {
  3526  				t.Fatal("unexpected success of a write with an earlier epoch")
  3527  			}
  3528  			// Try a write with different value using both later timestamp and epoch.
  3529  			txne2.Sequence++
  3530  			if err := MVCCPut(ctx, engine, nil, testKey1, txne2.ReadTimestamp, value3, &txne2); err != nil {
  3531  				t.Fatal(err)
  3532  			}
  3533  			// Resolve the intent.
  3534  			txne2Commit := txne2
  3535  			txne2Commit.Status = roachpb.COMMITTED
  3536  			txne2Commit.WriteTimestamp = hlc.Timestamp{WallTime: 1}
  3537  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3538  				roachpb.MakeLockUpdate(&txne2Commit, roachpb.Span{Key: testKey1})); err != nil {
  3539  				t.Fatal(err)
  3540  			}
  3541  
  3542  			expTS := txne2Commit.WriteTimestamp.Add(0, 1)
  3543  
  3544  			// Now try writing an earlier value without a txn--should get WriteTooOldError.
  3545  			err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 1}, value4, nil)
  3546  			if wtoErr := (*roachpb.WriteTooOldError)(nil); !errors.As(err, &wtoErr) {
  3547  				t.Fatal("unexpected success")
  3548  			} else if wtoErr.ActualTimestamp != expTS {
  3549  				t.Fatalf("expected write too old error with actual ts %s; got %s", expTS, wtoErr.ActualTimestamp)
  3550  			}
  3551  			// Verify value was actually written at (1, 1).
  3552  			value, _, err := MVCCGet(ctx, engine, testKey1, expTS, MVCCGetOptions{})
  3553  			if err != nil || value.Timestamp != expTS || !bytes.Equal(value4.RawBytes, value.RawBytes) {
  3554  				t.Fatalf("expected err=nil (got %s), timestamp=%s (got %s), value=%q (got %q)",
  3555  					err, value.Timestamp, expTS, value4.RawBytes, value.RawBytes)
  3556  			}
  3557  			// Now write an intent with exactly the same timestamp--ties also get WriteTooOldError.
  3558  			err = MVCCPut(ctx, engine, nil, testKey1, txn2.ReadTimestamp, value5, txn2)
  3559  			intentTS := expTS.Add(0, 1)
  3560  			if wtoErr := (*roachpb.WriteTooOldError)(nil); !errors.As(err, &wtoErr) {
  3561  				t.Fatal("unexpected success")
  3562  			} else if wtoErr.ActualTimestamp != intentTS {
  3563  				t.Fatalf("expected write too old error with actual ts %s; got %s", intentTS, wtoErr.ActualTimestamp)
  3564  			}
  3565  			// Verify intent value was actually written at (1, 2).
  3566  			value, _, err = MVCCGet(ctx, engine, testKey1, intentTS, MVCCGetOptions{Txn: txn2})
  3567  			if err != nil || value.Timestamp != intentTS || !bytes.Equal(value5.RawBytes, value.RawBytes) {
  3568  				t.Fatalf("expected err=nil (got %s), timestamp=%s (got %s), value=%q (got %q)",
  3569  					err, value.Timestamp, intentTS, value5.RawBytes, value.RawBytes)
  3570  			}
  3571  			// Attempt to read older timestamp; should fail.
  3572  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 0}, MVCCGetOptions{})
  3573  			if value != nil || err != nil {
  3574  				t.Fatalf("expected value nil, err nil; got %+v, %v", value, err)
  3575  			}
  3576  			// Read at correct timestamp.
  3577  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{})
  3578  			if err != nil {
  3579  				t.Fatal(err)
  3580  			}
  3581  			if expTS := (hlc.Timestamp{WallTime: 1}); value.Timestamp != expTS {
  3582  				t.Fatalf("expected timestamp %+v == %+v", value.Timestamp, expTS)
  3583  			}
  3584  			if !bytes.Equal(value3.RawBytes, value.RawBytes) {
  3585  				t.Fatalf("the value %s in get result does not match the value %s in request",
  3586  					value3.RawBytes, value.RawBytes)
  3587  			}
  3588  		})
  3589  	}
  3590  }
  3591  
  3592  // TestMVCCGetWithDiffEpochs writes a value first using epoch 1, then
  3593  // reads using epoch 2 to verify that values written during different
  3594  // transaction epochs are not visible.
  3595  func TestMVCCGetWithDiffEpochs(t *testing.T) {
  3596  	defer leaktest.AfterTest(t)()
  3597  
  3598  	for _, engineImpl := range mvccEngineImpls {
  3599  		t.Run(engineImpl.name, func(t *testing.T) {
  3600  
  3601  			for _, impl := range mvccGetImpls {
  3602  				t.Run(impl.name, func(t *testing.T) {
  3603  					mvccGet := impl.fn
  3604  
  3605  					ctx := context.Background()
  3606  					engine := engineImpl.create()
  3607  					defer engine.Close()
  3608  
  3609  					// Write initial value without a txn.
  3610  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 1}, value1, nil); err != nil {
  3611  						t.Fatal(err)
  3612  					}
  3613  					// Now write using txn1, epoch 1.
  3614  					txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  3615  					if err := MVCCPut(ctx, engine, nil, testKey1, txn1ts.ReadTimestamp, value2, txn1ts); err != nil {
  3616  						t.Fatal(err)
  3617  					}
  3618  					// Try reading using different txns & epochs.
  3619  					testCases := []struct {
  3620  						txn      *roachpb.Transaction
  3621  						expValue *roachpb.Value
  3622  						expErr   bool
  3623  					}{
  3624  						// No transaction; should see error.
  3625  						{nil, nil, true},
  3626  						// Txn1, epoch 1; should see new value2.
  3627  						{txn1, &value2, false},
  3628  						// Txn1, epoch 2; should see original value1.
  3629  						{txn1e2, &value1, false},
  3630  						// Txn2; should see error.
  3631  						{txn2, nil, true},
  3632  					}
  3633  					for i, test := range testCases {
  3634  						t.Run(strconv.Itoa(i), func(t *testing.T) {
  3635  							value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{
  3636  								Txn: test.txn,
  3637  							})
  3638  							if test.expErr {
  3639  								if err == nil {
  3640  									t.Errorf("test %d: unexpected success", i)
  3641  								} else if !errors.HasType(err, (*roachpb.WriteIntentError)(nil)) {
  3642  									t.Errorf("test %d: expected write intent error; got %v", i, err)
  3643  								}
  3644  							} else if err != nil || value == nil || !bytes.Equal(test.expValue.RawBytes, value.RawBytes) {
  3645  								t.Errorf("test %d: expected value %q, err nil; got %+v, %v", i, test.expValue.RawBytes, value, err)
  3646  							}
  3647  						})
  3648  					}
  3649  				})
  3650  			}
  3651  		})
  3652  	}
  3653  }
  3654  
  3655  // TestMVCCGetWithDiffEpochsAndTimestamps writes a value first using
  3656  // epoch 1, then reads using epoch 2 with different timestamps to verify
  3657  // that values written during different transaction epochs are not visible.
  3658  //
  3659  // The test includes the case where the read at epoch 2 is at a *lower*
  3660  // timestamp than the intent write at epoch 1. This is not expected to
  3661  // happen commonly, but caused issues in #36089.
  3662  func TestMVCCGetWithDiffEpochsAndTimestamps(t *testing.T) {
  3663  	defer leaktest.AfterTest(t)()
  3664  
  3665  	for _, engineImpl := range mvccEngineImpls {
  3666  		t.Run(engineImpl.name, func(t *testing.T) {
  3667  			for _, impl := range mvccGetImpls {
  3668  				t.Run(impl.name, func(t *testing.T) {
  3669  					mvccGet := impl.fn
  3670  
  3671  					ctx := context.Background()
  3672  					engine := engineImpl.create()
  3673  					defer engine.Close()
  3674  
  3675  					// Write initial value without a txn at timestamp 1.
  3676  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 1}, value1, nil); err != nil {
  3677  						t.Fatal(err)
  3678  					}
  3679  					// Write another value without a txn at timestamp 3.
  3680  					if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{WallTime: 3}, value2, nil); err != nil {
  3681  						t.Fatal(err)
  3682  					}
  3683  					// Now write using txn1, epoch 1.
  3684  					txn1ts := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  3685  					// Bump epoch 1's write timestamp to timestamp 4.
  3686  					txn1ts.WriteTimestamp = hlc.Timestamp{WallTime: 4}
  3687  					// Expected to hit WriteTooOld error but to still lay down intent.
  3688  					err := MVCCPut(ctx, engine, nil, testKey1, txn1ts.ReadTimestamp, value3, txn1ts)
  3689  					if wtoErr := (*roachpb.WriteTooOldError)(nil); !errors.As(err, &wtoErr) {
  3690  						t.Fatalf("unexpectedly not WriteTooOld: %+v", err)
  3691  					} else if expTS, actTS := txn1ts.WriteTimestamp, wtoErr.ActualTimestamp; expTS != actTS {
  3692  						t.Fatalf("expected write too old error with actual ts %s; got %s", expTS, actTS)
  3693  					}
  3694  					// Try reading using different epochs & timestamps.
  3695  					testCases := []struct {
  3696  						txn      *roachpb.Transaction
  3697  						readTS   hlc.Timestamp
  3698  						expValue *roachpb.Value
  3699  					}{
  3700  						// Epoch 1, read 1; should see new value3.
  3701  						{txn1, hlc.Timestamp{WallTime: 1}, &value3},
  3702  						// Epoch 1, read 2; should see new value3.
  3703  						{txn1, hlc.Timestamp{WallTime: 2}, &value3},
  3704  						// Epoch 1, read 3; should see new value3.
  3705  						{txn1, hlc.Timestamp{WallTime: 3}, &value3},
  3706  						// Epoch 1, read 4; should see new value3.
  3707  						{txn1, hlc.Timestamp{WallTime: 4}, &value3},
  3708  						// Epoch 1, read 5; should see new value3.
  3709  						{txn1, hlc.Timestamp{WallTime: 5}, &value3},
  3710  						// Epoch 2, read 1; should see committed value1.
  3711  						{txn1e2, hlc.Timestamp{WallTime: 1}, &value1},
  3712  						// Epoch 2, read 2; should see committed value1.
  3713  						{txn1e2, hlc.Timestamp{WallTime: 2}, &value1},
  3714  						// Epoch 2, read 3; should see committed value2.
  3715  						{txn1e2, hlc.Timestamp{WallTime: 3}, &value2},
  3716  						// Epoch 2, read 4; should see committed value2.
  3717  						{txn1e2, hlc.Timestamp{WallTime: 4}, &value2},
  3718  						// Epoch 2, read 5; should see committed value2.
  3719  						{txn1e2, hlc.Timestamp{WallTime: 5}, &value2},
  3720  					}
  3721  					for i, test := range testCases {
  3722  						t.Run(strconv.Itoa(i), func(t *testing.T) {
  3723  							value, _, err := mvccGet(ctx, engine, testKey1, test.readTS, MVCCGetOptions{Txn: test.txn})
  3724  							if err != nil || value == nil || !bytes.Equal(test.expValue.RawBytes, value.RawBytes) {
  3725  								t.Errorf("test %d: expected value %q, err nil; got %+v, %v", i, test.expValue.RawBytes, value, err)
  3726  							}
  3727  						})
  3728  					}
  3729  				})
  3730  			}
  3731  		})
  3732  	}
  3733  }
  3734  
  3735  // TestMVCCGetWithOldEpoch writes a value first using epoch 2, then
  3736  // reads using epoch 1 to verify that the read will fail.
  3737  func TestMVCCGetWithOldEpoch(t *testing.T) {
  3738  	defer leaktest.AfterTest(t)()
  3739  
  3740  	for _, engineImpl := range mvccEngineImpls {
  3741  		t.Run(engineImpl.name, func(t *testing.T) {
  3742  			for _, impl := range mvccGetImpls {
  3743  				t.Run(impl.name, func(t *testing.T) {
  3744  					mvccGet := impl.fn
  3745  
  3746  					ctx := context.Background()
  3747  					engine := engineImpl.create()
  3748  					defer engine.Close()
  3749  
  3750  					if err := MVCCPut(ctx, engine, nil, testKey1, txn1e2.ReadTimestamp, value2, txn1e2); err != nil {
  3751  						t.Fatal(err)
  3752  					}
  3753  					_, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 2}, MVCCGetOptions{
  3754  						Txn: txn1,
  3755  					})
  3756  					if err == nil {
  3757  						t.Fatalf("unexpected success of get")
  3758  					}
  3759  				})
  3760  			}
  3761  		})
  3762  	}
  3763  }
  3764  
  3765  // TestMVCCDeleteRangeWithSequence verifies that delete range operations at sequence
  3766  // numbers equal to or below the sequence of a previous delete range operation
  3767  // verify that they agree with the sequence history of each intent left by the
  3768  // delete range. If so, they become no-ops because writes are meant to be
  3769  // idempotent. If not, they throw errors.
  3770  func TestMVCCDeleteRangeWithSequence(t *testing.T) {
  3771  	defer leaktest.AfterTest(t)()
  3772  
  3773  	ctx := context.Background()
  3774  	for _, engineImpl := range mvccEngineImpls {
  3775  		t.Run(engineImpl.name, func(t *testing.T) {
  3776  			engine := engineImpl.create()
  3777  			defer engine.Close()
  3778  
  3779  			testCases := []struct {
  3780  				name     string
  3781  				sequence enginepb.TxnSeq
  3782  				expErr   string
  3783  			}{
  3784  				{"old seq", 5, "missing an intent"},
  3785  				{"same seq", 6, ""},
  3786  				{"new seq", 7, ""},
  3787  			}
  3788  
  3789  			for _, tc := range testCases {
  3790  				t.Run(tc.name, func(t *testing.T) {
  3791  					prefix := roachpb.Key(fmt.Sprintf("key-%d", tc.sequence))
  3792  					txn := *txn1
  3793  					for i := enginepb.TxnSeq(0); i < 3; i++ {
  3794  						key := append(prefix, []byte(strconv.Itoa(int(i)))...)
  3795  						txn.Sequence = 2 + i
  3796  						if err := MVCCPut(ctx, engine, nil, key, txn.WriteTimestamp, value1, &txn); err != nil {
  3797  							t.Fatal(err)
  3798  						}
  3799  					}
  3800  
  3801  					// Perform the initial DeleteRange.
  3802  					const origSeq = 6
  3803  					txn.Sequence = origSeq
  3804  					origDeleted, _, origNum, err := MVCCDeleteRange(
  3805  						ctx, engine, nil, prefix, prefix.PrefixEnd(), math.MaxInt64, txn.WriteTimestamp, &txn, true,
  3806  					)
  3807  					if err != nil {
  3808  						t.Fatal(err)
  3809  					}
  3810  
  3811  					txn.Sequence = tc.sequence
  3812  					deleted, _, num, err := MVCCDeleteRange(
  3813  						ctx, engine, nil, prefix, prefix.PrefixEnd(), math.MaxInt64, txn.WriteTimestamp, &txn, true,
  3814  					)
  3815  					if tc.expErr != "" && err != nil {
  3816  						if !testutils.IsError(err, tc.expErr) {
  3817  							t.Fatalf("unexpected error: %+v", err)
  3818  						}
  3819  					} else if err != nil {
  3820  						t.Fatalf("unexpected error: %+v", err)
  3821  					}
  3822  
  3823  					// If at the same sequence as the initial DeleteRange.
  3824  					if tc.sequence == origSeq {
  3825  						if !reflect.DeepEqual(origDeleted, deleted) {
  3826  							t.Fatalf("deleted keys did not match original execution: %+v vs. %+v",
  3827  								origDeleted, deleted)
  3828  						}
  3829  						if origNum != num {
  3830  							t.Fatalf("number of keys deleted did not match original execution: %d vs. %d",
  3831  								origNum, num)
  3832  						}
  3833  					}
  3834  				})
  3835  			}
  3836  		})
  3837  	}
  3838  }
  3839  
  3840  // TestMVCCGetWithPushedTimestamp verifies that a read for a value
  3841  // written by the transaction, but then subsequently pushed, can still
  3842  // be read by the txn at the later timestamp, even if an earlier
  3843  // timestamp is specified. This happens when a txn's intents are
  3844  // resolved by other actors; the intents shouldn't become invisible
  3845  // to pushed txn.
  3846  func TestMVCCGetWithPushedTimestamp(t *testing.T) {
  3847  	defer leaktest.AfterTest(t)()
  3848  
  3849  	for _, engineImpl := range mvccEngineImpls {
  3850  		t.Run(engineImpl.name, func(t *testing.T) {
  3851  			engine := engineImpl.create()
  3852  			defer engine.Close()
  3853  			for _, impl := range mvccGetImpls {
  3854  				t.Run(impl.name, func(t *testing.T) {
  3855  					mvccGet := impl.fn
  3856  
  3857  					ctx := context.Background()
  3858  					engine := engineImpl.create()
  3859  					defer engine.Close()
  3860  
  3861  					// Start with epoch 1.
  3862  					if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3863  						t.Fatal(err)
  3864  					}
  3865  					// Resolve the intent, pushing its timestamp forward.
  3866  					txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  3867  					if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  3868  						roachpb.MakeLockUpdate(txn, roachpb.Span{Key: testKey1})); err != nil {
  3869  						t.Fatal(err)
  3870  					}
  3871  					// Attempt to read using naive txn's previous timestamp.
  3872  					value, _, err := mvccGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{
  3873  						Txn: txn1,
  3874  					})
  3875  					if err != nil || value == nil || !bytes.Equal(value.RawBytes, value1.RawBytes) {
  3876  						t.Errorf("expected value %q, err nil; got %+v, %v", value1.RawBytes, value, err)
  3877  					}
  3878  				})
  3879  			}
  3880  		})
  3881  	}
  3882  }
  3883  
  3884  func TestMVCCResolveWithDiffEpochs(t *testing.T) {
  3885  	defer leaktest.AfterTest(t)()
  3886  
  3887  	ctx := context.Background()
  3888  	for _, engineImpl := range mvccEngineImpls {
  3889  		t.Run(engineImpl.name, func(t *testing.T) {
  3890  			engine := engineImpl.create()
  3891  			defer engine.Close()
  3892  
  3893  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3894  				t.Fatal(err)
  3895  			}
  3896  			if err := MVCCPut(ctx, engine, nil, testKey2, txn1e2.ReadTimestamp, value2, txn1e2); err != nil {
  3897  				t.Fatal(err)
  3898  			}
  3899  			num, _, err := MVCCResolveWriteIntentRange(ctx, engine, nil,
  3900  				roachpb.MakeLockUpdate(txn1e2Commit, roachpb.Span{Key: testKey1, EndKey: testKey2.Next()}), 2)
  3901  			if err != nil {
  3902  				t.Fatal(err)
  3903  			}
  3904  			if num != 2 {
  3905  				t.Errorf("expected 2 rows resolved; got %d", num)
  3906  			}
  3907  
  3908  			// Verify key1 is empty, as resolution with epoch 2 would have
  3909  			// aborted the epoch 1 intent.
  3910  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  3911  			if value != nil || err != nil {
  3912  				t.Errorf("expected value nil, err nil; got %+v, %v", value, err)
  3913  			}
  3914  
  3915  			// Key2 should be committed.
  3916  			value, _, err = MVCCGet(ctx, engine, testKey2, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  3917  			if err != nil {
  3918  				t.Fatal(err)
  3919  			}
  3920  			if !bytes.Equal(value2.RawBytes, value.RawBytes) {
  3921  				t.Fatalf("the value %s in get result does not match the value %s in request",
  3922  					value2.RawBytes, value.RawBytes)
  3923  			}
  3924  		})
  3925  	}
  3926  }
  3927  
  3928  func TestMVCCResolveWithUpdatedTimestamp(t *testing.T) {
  3929  	defer leaktest.AfterTest(t)()
  3930  
  3931  	ctx := context.Background()
  3932  	for _, engineImpl := range mvccEngineImpls {
  3933  		t.Run(engineImpl.name, func(t *testing.T) {
  3934  			engine := engineImpl.create()
  3935  			defer engine.Close()
  3936  
  3937  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3938  				t.Fatal(err)
  3939  			}
  3940  
  3941  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
  3942  				Txn: txn1,
  3943  			})
  3944  			if err != nil {
  3945  				t.Fatal(err)
  3946  			}
  3947  			if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3948  				t.Fatalf("the value %s in get result does not match the value %s in request",
  3949  					value1.RawBytes, value.RawBytes)
  3950  			}
  3951  
  3952  			// Resolve with a higher commit timestamp -- this should rewrite the
  3953  			// intent when making it permanent.
  3954  			txn := makeTxn(*txn1Commit, hlc.Timestamp{WallTime: 1})
  3955  			if _, err = MVCCResolveWriteIntent(ctx, engine, nil,
  3956  				roachpb.MakeLockUpdate(txn, roachpb.Span{Key: testKey1})); err != nil {
  3957  				t.Fatal(err)
  3958  			}
  3959  
  3960  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  3961  			if value != nil || err != nil {
  3962  				t.Fatalf("expected both value and err to be nil: %+v, %v", value, err)
  3963  			}
  3964  
  3965  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{})
  3966  			if err != nil {
  3967  				t.Error(err)
  3968  			}
  3969  			if expTS := (hlc.Timestamp{WallTime: 1}); value.Timestamp != expTS {
  3970  				t.Fatalf("expected timestamp %+v == %+v", value.Timestamp, expTS)
  3971  			}
  3972  			if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3973  				t.Fatalf("the value %s in get result does not match the value %s in request",
  3974  					value1.RawBytes, value.RawBytes)
  3975  			}
  3976  		})
  3977  	}
  3978  }
  3979  
  3980  func TestMVCCResolveWithPushedTimestamp(t *testing.T) {
  3981  	defer leaktest.AfterTest(t)()
  3982  
  3983  	ctx := context.Background()
  3984  	for _, engineImpl := range mvccEngineImpls {
  3985  		t.Run(engineImpl.name, func(t *testing.T) {
  3986  			engine := engineImpl.create()
  3987  			defer engine.Close()
  3988  
  3989  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  3990  				t.Fatal(err)
  3991  			}
  3992  			value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
  3993  				Txn: txn1,
  3994  			})
  3995  			if err != nil {
  3996  				t.Fatal(err)
  3997  			}
  3998  			if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  3999  				t.Fatalf("the value %s in get result does not match the value %s in request",
  4000  					value1.RawBytes, value.RawBytes)
  4001  			}
  4002  
  4003  			// Resolve with a higher commit timestamp, but with still-pending transaction.
  4004  			// This represents a straightforward push (i.e. from a read/write conflict).
  4005  			txn := makeTxn(*txn1, hlc.Timestamp{WallTime: 1})
  4006  			if _, err = MVCCResolveWriteIntent(ctx, engine, nil,
  4007  				roachpb.MakeLockUpdate(txn, roachpb.Span{Key: testKey1})); err != nil {
  4008  				t.Fatal(err)
  4009  			}
  4010  
  4011  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{})
  4012  			if value != nil || err == nil {
  4013  				t.Fatalf("expected both value nil and err to be a writeIntentError: %+v", value)
  4014  			}
  4015  
  4016  			// Can still fetch the value using txn1.
  4017  			value, _, err = MVCCGet(ctx, engine, testKey1, hlc.Timestamp{WallTime: 1}, MVCCGetOptions{
  4018  				Txn: txn1,
  4019  			})
  4020  			if err != nil {
  4021  				t.Error(err)
  4022  			}
  4023  			if expTS := (hlc.Timestamp{WallTime: 1}); value.Timestamp != expTS {
  4024  				t.Fatalf("expected timestamp %+v == %+v", value.Timestamp, expTS)
  4025  			}
  4026  			if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  4027  				t.Fatalf("the value %s in get result does not match the value %s in request",
  4028  					value1.RawBytes, value.RawBytes)
  4029  			}
  4030  		})
  4031  	}
  4032  }
  4033  
  4034  func TestMVCCResolveTxnNoOps(t *testing.T) {
  4035  	defer leaktest.AfterTest(t)()
  4036  
  4037  	ctx := context.Background()
  4038  	for _, engineImpl := range mvccEngineImpls {
  4039  		t.Run(engineImpl.name, func(t *testing.T) {
  4040  			engine := engineImpl.create()
  4041  			defer engine.Close()
  4042  
  4043  			// Resolve a non existent key; noop.
  4044  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  4045  				roachpb.MakeLockUpdate(txn1Commit, roachpb.Span{Key: testKey1})); err != nil {
  4046  				t.Fatal(err)
  4047  			}
  4048  
  4049  			// Add key and resolve despite there being no intent.
  4050  			if err := MVCCPut(ctx, engine, nil, testKey1, hlc.Timestamp{Logical: 1}, value1, nil); err != nil {
  4051  				t.Fatal(err)
  4052  			}
  4053  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  4054  				roachpb.MakeLockUpdate(txn2Commit, roachpb.Span{Key: testKey1})); err != nil {
  4055  				t.Fatal(err)
  4056  			}
  4057  
  4058  			// Write intent and resolve with different txn.
  4059  			if err := MVCCPut(ctx, engine, nil, testKey2, txn1.ReadTimestamp, value2, txn1); err != nil {
  4060  				t.Fatal(err)
  4061  			}
  4062  
  4063  			txn1CommitWithTS := txn2Commit.Clone()
  4064  			txn1CommitWithTS.WriteTimestamp = hlc.Timestamp{WallTime: 1}
  4065  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  4066  				roachpb.MakeLockUpdate(txn1CommitWithTS, roachpb.Span{Key: testKey2})); err != nil {
  4067  				t.Fatal(err)
  4068  			}
  4069  		})
  4070  	}
  4071  }
  4072  
  4073  func TestMVCCResolveTxnRange(t *testing.T) {
  4074  	defer leaktest.AfterTest(t)()
  4075  
  4076  	ctx := context.Background()
  4077  	for _, engineImpl := range mvccEngineImpls {
  4078  		t.Run(engineImpl.name, func(t *testing.T) {
  4079  			engine := engineImpl.create()
  4080  			defer engine.Close()
  4081  
  4082  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1.ReadTimestamp, value1, txn1); err != nil {
  4083  				t.Fatal(err)
  4084  			}
  4085  			if err := MVCCPut(ctx, engine, nil, testKey2, hlc.Timestamp{Logical: 1}, value2, nil); err != nil {
  4086  				t.Fatal(err)
  4087  			}
  4088  			if err := MVCCPut(ctx, engine, nil, testKey3, txn2.ReadTimestamp, value3, txn2); err != nil {
  4089  				t.Fatal(err)
  4090  			}
  4091  			if err := MVCCPut(ctx, engine, nil, testKey4, txn1.ReadTimestamp, value4, txn1); err != nil {
  4092  				t.Fatal(err)
  4093  			}
  4094  
  4095  			num, resumeSpan, err := MVCCResolveWriteIntentRange(ctx, engine, nil,
  4096  				roachpb.MakeLockUpdate(txn1Commit, roachpb.Span{Key: testKey1, EndKey: testKey4.Next()}),
  4097  				math.MaxInt64)
  4098  			if err != nil {
  4099  				t.Fatal(err)
  4100  			}
  4101  			if num != 2 || resumeSpan != nil {
  4102  				t.Fatalf("expected all keys to process for resolution, even though 2 are noops; got %d, resume=%s",
  4103  					num, resumeSpan)
  4104  			}
  4105  
  4106  			{
  4107  				value, _, err := MVCCGet(ctx, engine, testKey1, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  4108  				if err != nil {
  4109  					t.Fatal(err)
  4110  				}
  4111  				if !bytes.Equal(value1.RawBytes, value.RawBytes) {
  4112  					t.Fatalf("the value %s in get result does not match the value %s in request",
  4113  						value1.RawBytes, value.RawBytes)
  4114  				}
  4115  			}
  4116  			{
  4117  				value, _, err := MVCCGet(ctx, engine, testKey2, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  4118  				if err != nil {
  4119  					t.Fatal(err)
  4120  				}
  4121  				if !bytes.Equal(value2.RawBytes, value.RawBytes) {
  4122  					t.Fatalf("the value %s in get result does not match the value %s in request",
  4123  						value2.RawBytes, value.RawBytes)
  4124  				}
  4125  			}
  4126  			{
  4127  				value, _, err := MVCCGet(ctx, engine, testKey3, hlc.Timestamp{Logical: 1}, MVCCGetOptions{
  4128  					Txn: txn2,
  4129  				})
  4130  				if err != nil {
  4131  					t.Fatal(err)
  4132  				}
  4133  				if !bytes.Equal(value3.RawBytes, value.RawBytes) {
  4134  					t.Fatalf("the value %s in get result does not match the value %s in request",
  4135  						value3.RawBytes, value.RawBytes)
  4136  				}
  4137  			}
  4138  			{
  4139  				value, _, err := MVCCGet(ctx, engine, testKey4, hlc.Timestamp{Logical: 1}, MVCCGetOptions{})
  4140  				if err != nil {
  4141  					t.Fatal(err)
  4142  				}
  4143  				if !bytes.Equal(value4.RawBytes, value.RawBytes) {
  4144  					t.Fatalf("the value %s in get result does not match the value %s in request",
  4145  						value1.RawBytes, value.RawBytes)
  4146  				}
  4147  			}
  4148  		})
  4149  	}
  4150  }
  4151  
  4152  func TestMVCCResolveTxnRangeResume(t *testing.T) {
  4153  	defer leaktest.AfterTest(t)()
  4154  
  4155  	ctx := context.Background()
  4156  	for _, engineImpl := range mvccEngineImpls {
  4157  		t.Run(engineImpl.name, func(t *testing.T) {
  4158  			engine := engineImpl.create()
  4159  			defer engine.Close()
  4160  
  4161  			// Write 10 keys from txn1, 10 from txn2, and 10 with no txn, interleaved.
  4162  			for i := 0; i < 30; i += 3 {
  4163  				key0 := roachpb.Key(fmt.Sprintf("%02d", i+0))
  4164  				key1 := roachpb.Key(fmt.Sprintf("%02d", i+1))
  4165  				key2 := roachpb.Key(fmt.Sprintf("%02d", i+2))
  4166  				if err := MVCCPut(ctx, engine, nil, key0, txn1.ReadTimestamp, value1, txn1); err != nil {
  4167  					t.Fatal(err)
  4168  				}
  4169  				txn2ts := makeTxn(*txn2, hlc.Timestamp{Logical: 2})
  4170  				if err := MVCCPut(ctx, engine, nil, key1, txn2ts.ReadTimestamp, value2, txn2ts); err != nil {
  4171  					t.Fatal(err)
  4172  				}
  4173  				if err := MVCCPut(ctx, engine, nil, key2, hlc.Timestamp{Logical: 3}, value3, nil); err != nil {
  4174  					t.Fatal(err)
  4175  				}
  4176  			}
  4177  
  4178  			// Resolve up to 5 intents.
  4179  			num, resumeSpan, err := MVCCResolveWriteIntentRange(ctx, engine, nil,
  4180  				roachpb.MakeLockUpdate(txn1Commit, roachpb.Span{Key: roachpb.Key("00"), EndKey: roachpb.Key("30")}),
  4181  				5)
  4182  			if err != nil {
  4183  				t.Fatal(err)
  4184  			}
  4185  			if num != 5 || resumeSpan == nil {
  4186  				t.Errorf("expected resolution for only 5 keys; got %d, resume=%s", num, resumeSpan)
  4187  			}
  4188  			expResumeSpan := &roachpb.Span{Key: roachpb.Key("12").Next(), EndKey: roachpb.Key("30")}
  4189  			if !resumeSpan.Equal(expResumeSpan) {
  4190  				t.Errorf("expected resume span %s; got %s", expResumeSpan, resumeSpan)
  4191  			}
  4192  		})
  4193  	}
  4194  }
  4195  
  4196  func TestValidSplitKeys(t *testing.T) {
  4197  	defer leaktest.AfterTest(t)()
  4198  
  4199  	testCases := []struct {
  4200  		key   roachpb.Key
  4201  		valid bool
  4202  	}{
  4203  		{roachpb.Key("\x02"), false},
  4204  		{roachpb.Key("\x02\x00"), false},
  4205  		{roachpb.Key("\x02\xff"), false},
  4206  		{roachpb.Key("\x03"), true},
  4207  		{roachpb.Key("\x03\x00"), true},
  4208  		{roachpb.Key("\x03\xff"), true},
  4209  		{roachpb.Key("\x03\xff\xff"), false},
  4210  		{roachpb.Key("\x03\xff\xff\x88"), false},
  4211  		{roachpb.Key("\x04"), true},
  4212  		{roachpb.Key("\x05"), true},
  4213  		{roachpb.Key("a"), true},
  4214  		{roachpb.Key("\xff"), true},
  4215  		{roachpb.Key("\xff\x01"), true},
  4216  		{keys.SystemSQLCodec.TablePrefix(keys.MaxSystemConfigDescID), false},
  4217  		{keys.SystemSQLCodec.TablePrefix(keys.MaxSystemConfigDescID + 1), true},
  4218  	}
  4219  	for i, test := range testCases {
  4220  		valid := IsValidSplitKey(test.key)
  4221  		if valid != test.valid {
  4222  			t.Errorf("%d: expected %q [%x] valid %t; got %t",
  4223  				i, test.key, []byte(test.key), test.valid, valid)
  4224  		}
  4225  	}
  4226  }
  4227  
  4228  func TestFindSplitKey(t *testing.T) {
  4229  	defer leaktest.AfterTest(t)()
  4230  
  4231  	ctx := context.Background()
  4232  	for _, engineImpl := range mvccEngineImpls {
  4233  		t.Run(engineImpl.name, func(t *testing.T) {
  4234  			engine := engineImpl.create()
  4235  			defer engine.Close()
  4236  
  4237  			ms := &enginepb.MVCCStats{}
  4238  			// Generate a series of KeyValues, each containing targetLength
  4239  			// bytes, writing key #i to (encoded) key #i through the MVCC
  4240  			// facility. Assuming that this translates roughly into same-length
  4241  			// values after MVCC encoding, the split key should hence be chosen
  4242  			// as the middle key of the interval.
  4243  			splitReservoirSize := 100
  4244  			for i := 0; i < splitReservoirSize; i++ {
  4245  				k := fmt.Sprintf("%09d", i)
  4246  				v := strings.Repeat("X", 10-len(k))
  4247  				val := roachpb.MakeValueFromString(v)
  4248  				// Write the key and value through MVCC
  4249  				if err := MVCCPut(ctx, engine, ms, []byte(k), hlc.Timestamp{Logical: 1}, val, nil); err != nil {
  4250  					t.Fatal(err)
  4251  				}
  4252  			}
  4253  
  4254  			testData := []struct {
  4255  				targetSize int64
  4256  				splitInd   int
  4257  			}{
  4258  				{(ms.KeyBytes + ms.ValBytes) / 2, splitReservoirSize / 2},
  4259  				{0, 0},
  4260  				{math.MaxInt64, splitReservoirSize},
  4261  			}
  4262  
  4263  			for i, td := range testData {
  4264  				humanSplitKey, err := MVCCFindSplitKey(ctx, engine, roachpb.RKeyMin, roachpb.RKeyMax, td.targetSize)
  4265  				if err != nil {
  4266  					t.Fatal(err)
  4267  				}
  4268  				ind, err := strconv.Atoi(string(humanSplitKey))
  4269  				if err != nil {
  4270  					t.Fatalf("%d: could not parse key %s as int: %+v", i, humanSplitKey, err)
  4271  				}
  4272  				if ind == 0 {
  4273  					t.Fatalf("%d: should never select first key as split key", i)
  4274  				}
  4275  				if diff := td.splitInd - ind; diff > 1 || diff < -1 {
  4276  					t.Fatalf("%d: wanted key #%d+-1, but got %d (diff %d)", i, td.splitInd, ind, diff)
  4277  				}
  4278  			}
  4279  		})
  4280  	}
  4281  }
  4282  
  4283  // TestFindValidSplitKeys verifies split keys are located such that
  4284  // they avoid splits through invalid key ranges.
  4285  func TestFindValidSplitKeys(t *testing.T) {
  4286  	defer leaktest.AfterTest(t)()
  4287  
  4288  	const userID = keys.MinUserDescID
  4289  	const interleave1 = userID + 1
  4290  	const interleave2 = userID + 2
  4291  	const interleave3 = userID + 3
  4292  	// Manually creates rows corresponding to the schema:
  4293  	// CREATE TABLE t (id1 STRING, id2 STRING, ... PRIMARY KEY (id1, id2, ...))
  4294  	addTablePrefix := func(prefix roachpb.Key, id uint32, rowVals ...string) roachpb.Key {
  4295  		tableKey := append(prefix, keys.SystemSQLCodec.TablePrefix(id)...)
  4296  		rowKey := roachpb.Key(encoding.EncodeVarintAscending(tableKey, 1))
  4297  		for _, rowVal := range rowVals {
  4298  			rowKey = encoding.EncodeStringAscending(rowKey, rowVal)
  4299  		}
  4300  		return rowKey
  4301  	}
  4302  	tablePrefix := func(id uint32, rowVals ...string) roachpb.Key {
  4303  		return addTablePrefix(nil, id, rowVals...)
  4304  	}
  4305  	addColFam := func(rowKey roachpb.Key, colFam uint32) roachpb.Key {
  4306  		return keys.MakeFamilyKey(append([]byte(nil), rowKey...), colFam)
  4307  	}
  4308  	addInterleave := func(rowKey roachpb.Key) roachpb.Key {
  4309  		return encoding.EncodeInterleavedSentinel(rowKey)
  4310  	}
  4311  
  4312  	testCases := []struct {
  4313  		keys       []roachpb.Key
  4314  		rangeStart roachpb.Key // optional
  4315  		expSplit   roachpb.Key
  4316  		expError   bool
  4317  	}{
  4318  		// All m1 cannot be split.
  4319  		{
  4320  			keys: []roachpb.Key{
  4321  				roachpb.Key("\x02"),
  4322  				roachpb.Key("\x02\x00"),
  4323  				roachpb.Key("\x02\xff"),
  4324  			},
  4325  			expSplit: nil,
  4326  			expError: false,
  4327  		},
  4328  		// All system span cannot be split.
  4329  		{
  4330  			keys: []roachpb.Key{
  4331  				addColFam(tablePrefix(1, "some", "data"), 1),
  4332  				addColFam(tablePrefix(keys.MaxSystemConfigDescID, "blah"), 1),
  4333  			},
  4334  			rangeStart: keys.SystemSQLCodec.TablePrefix(1),
  4335  			expSplit:   nil,
  4336  			expError:   false,
  4337  		},
  4338  		// Between meta1 and meta2, splits at meta2.
  4339  		{
  4340  			keys: []roachpb.Key{
  4341  				roachpb.Key("\x02"),
  4342  				roachpb.Key("\x02\x00"),
  4343  				roachpb.Key("\x02\xff"),
  4344  				roachpb.Key("\x03"),
  4345  				roachpb.Key("\x03\x00"),
  4346  				roachpb.Key("\x03\xff"),
  4347  			},
  4348  			expSplit: roachpb.Key("\x03"),
  4349  			expError: false,
  4350  		},
  4351  		// Even lopsided, always split at meta2.
  4352  		{
  4353  			keys: []roachpb.Key{
  4354  				roachpb.Key("\x02"),
  4355  				roachpb.Key("\x02\x00"),
  4356  				roachpb.Key("\x02\xff"),
  4357  				roachpb.Key("\x03"),
  4358  			},
  4359  			expSplit: roachpb.Key("\x03"),
  4360  			expError: false,
  4361  		},
  4362  		// Between meta2Max and metaMax, splits at metaMax.
  4363  		{
  4364  			keys: []roachpb.Key{
  4365  				roachpb.Key("\x03\xff\xff"),
  4366  				roachpb.Key("\x03\xff\xff\x88"),
  4367  				roachpb.Key("\x04"),
  4368  				roachpb.Key("\x04\xff\xff\x88"),
  4369  			},
  4370  			expSplit: roachpb.Key("\x04"),
  4371  			expError: false,
  4372  		},
  4373  		// Even lopsided, always split at metaMax.
  4374  		{
  4375  			keys: []roachpb.Key{
  4376  				roachpb.Key("\x03\xff\xff"),
  4377  				roachpb.Key("\x03\xff\xff\x11"),
  4378  				roachpb.Key("\x03\xff\xff\x88"),
  4379  				roachpb.Key("\x03\xff\xff\xee"),
  4380  				roachpb.Key("\x04"),
  4381  			},
  4382  			expSplit: roachpb.Key("\x04"),
  4383  			expError: false,
  4384  		},
  4385  		// Lopsided, truncate non-zone prefix.
  4386  		{
  4387  			keys: []roachpb.Key{
  4388  				roachpb.Key("\x04zond"),
  4389  				roachpb.Key("\x04zone"),
  4390  				roachpb.Key("\x04zone\x00"),
  4391  				roachpb.Key("\x04zone\xff"),
  4392  			},
  4393  			expSplit: roachpb.Key("\x04zone\x00"),
  4394  			expError: false,
  4395  		},
  4396  		// Lopsided, truncate non-zone suffix.
  4397  		{
  4398  			keys: []roachpb.Key{
  4399  				roachpb.Key("\x04zone"),
  4400  				roachpb.Key("\x04zone\x00"),
  4401  				roachpb.Key("\x04zone\xff"),
  4402  				roachpb.Key("\x04zonf"),
  4403  			},
  4404  			expSplit: roachpb.Key("\x04zone\xff"),
  4405  			expError: false,
  4406  		},
  4407  		// A Range for which MVCCSplitKey would return the start key isn't fair
  4408  		// game, even if the StartKey actually exists. There was once a bug
  4409  		// here which compared timestamps as well as keys and thus didn't
  4410  		// realize it was splitting at the initial key (due to getting confused
  4411  		// by the actual value having a nonzero timestamp).
  4412  		{
  4413  			keys: []roachpb.Key{
  4414  				roachpb.Key("b"),
  4415  			},
  4416  			rangeStart: roachpb.Key("a"),
  4417  			expSplit:   nil,
  4418  			expError:   false,
  4419  		},
  4420  		// Similar test, but the range starts at first key.
  4421  		{
  4422  			keys: []roachpb.Key{
  4423  				roachpb.Key("b"),
  4424  			},
  4425  			rangeStart: roachpb.Key("b"),
  4426  			expSplit:   nil,
  4427  			expError:   false,
  4428  		},
  4429  		// Some example table data. Make sure we don't split in the middle of a row
  4430  		// or return the start key of the range.
  4431  		{
  4432  			keys: []roachpb.Key{
  4433  				addColFam(tablePrefix(userID, "a"), 1),
  4434  				addColFam(tablePrefix(userID, "a"), 2),
  4435  				addColFam(tablePrefix(userID, "a"), 3),
  4436  				addColFam(tablePrefix(userID, "a"), 4),
  4437  				addColFam(tablePrefix(userID, "a"), 5),
  4438  				addColFam(tablePrefix(userID, "b"), 1),
  4439  				addColFam(tablePrefix(userID, "c"), 1),
  4440  			},
  4441  			rangeStart: tablePrefix(userID, "a"),
  4442  			expSplit:   tablePrefix(userID, "b"),
  4443  			expError:   false,
  4444  		},
  4445  		// More example table data. Make sure ranges at the start of a table can
  4446  		// be split properly - this checks that the minSplitKey logic doesn't
  4447  		// break for such ranges.
  4448  		{
  4449  			keys: []roachpb.Key{
  4450  				addColFam(tablePrefix(userID, "a"), 1),
  4451  				addColFam(tablePrefix(userID, "b"), 1),
  4452  				addColFam(tablePrefix(userID, "c"), 1),
  4453  				addColFam(tablePrefix(userID, "d"), 1),
  4454  			},
  4455  			rangeStart: keys.SystemSQLCodec.TablePrefix(userID),
  4456  			expSplit:   tablePrefix(userID, "c"),
  4457  			expError:   false,
  4458  		},
  4459  		// More example table data. Make sure ranges at the start of a table can
  4460  		// be split properly even in the presence of a large first row.
  4461  		{
  4462  			keys: []roachpb.Key{
  4463  				addColFam(tablePrefix(userID, "a"), 1),
  4464  				addColFam(tablePrefix(userID, "a"), 2),
  4465  				addColFam(tablePrefix(userID, "a"), 3),
  4466  				addColFam(tablePrefix(userID, "a"), 4),
  4467  				addColFam(tablePrefix(userID, "a"), 5),
  4468  				addColFam(tablePrefix(userID, "b"), 1),
  4469  				addColFam(tablePrefix(userID, "c"), 1),
  4470  			},
  4471  			rangeStart: keys.SystemSQLCodec.TablePrefix(keys.MinUserDescID),
  4472  			expSplit:   tablePrefix(userID, "b"),
  4473  			expError:   false,
  4474  		},
  4475  		// One partition where partition key is the first column. Checks that
  4476  		// split logic is not confused by the special partition start key.
  4477  		{
  4478  			keys: []roachpb.Key{
  4479  				addColFam(tablePrefix(userID, "a", "a"), 1),
  4480  				addColFam(tablePrefix(userID, "a", "b"), 1),
  4481  				addColFam(tablePrefix(userID, "a", "c"), 1),
  4482  				addColFam(tablePrefix(userID, "a", "d"), 1),
  4483  			},
  4484  			rangeStart: tablePrefix(userID, "a"),
  4485  			expSplit:   tablePrefix(userID, "a", "c"),
  4486  			expError:   false,
  4487  		},
  4488  		// One partition with a large first row. Checks that our logic to avoid
  4489  		// splitting in the middle of a row still applies.
  4490  		{
  4491  			keys: []roachpb.Key{
  4492  				addColFam(tablePrefix(userID, "a", "a"), 1),
  4493  				addColFam(tablePrefix(userID, "a", "a"), 2),
  4494  				addColFam(tablePrefix(userID, "a", "a"), 3),
  4495  				addColFam(tablePrefix(userID, "a", "a"), 4),
  4496  				addColFam(tablePrefix(userID, "a", "a"), 5),
  4497  				addColFam(tablePrefix(userID, "a", "b"), 1),
  4498  				addColFam(tablePrefix(userID, "a", "c"), 1),
  4499  			},
  4500  			rangeStart: tablePrefix(userID, "a"),
  4501  			expSplit:   tablePrefix(userID, "a", "b"),
  4502  			expError:   false,
  4503  		},
  4504  		// One large first row with interleaved child rows. Check that we can
  4505  		// split before the first interleaved row.
  4506  		{
  4507  			keys: []roachpb.Key{
  4508  				addColFam(tablePrefix(userID, "a"), 0),
  4509  				addColFam(tablePrefix(userID, "a"), 1),
  4510  				addColFam(tablePrefix(userID, "a"), 2),
  4511  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"), 0),
  4512  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"), 1),
  4513  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave2, "c"), 1),
  4514  			},
  4515  			rangeStart: tablePrefix(userID, "a"),
  4516  			expSplit:   addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4517  			expError:   false,
  4518  		},
  4519  		// One large first row with a double interleaved child row. Check that
  4520  		// we can split before the double interleaved row.
  4521  		{
  4522  			keys: []roachpb.Key{
  4523  				addColFam(tablePrefix(userID, "a"), 0),
  4524  				addColFam(tablePrefix(userID, "a"), 1),
  4525  				addColFam(tablePrefix(userID, "a"), 2),
  4526  				addColFam(addTablePrefix(addInterleave(
  4527  					addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4528  				), interleave2, "d"), 3),
  4529  			},
  4530  			rangeStart: tablePrefix(userID, "a"),
  4531  			expSplit: addTablePrefix(addInterleave(
  4532  				addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4533  			), interleave2, "d"),
  4534  			expError: false,
  4535  		},
  4536  		// Two interleaved rows. Check that we can split between them.
  4537  		{
  4538  			keys: []roachpb.Key{
  4539  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"), 0),
  4540  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"), 1),
  4541  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave2, "c"), 3),
  4542  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave2, "c"), 4),
  4543  			},
  4544  			rangeStart: addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4545  			expSplit:   addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave2, "c"),
  4546  			expError:   false,
  4547  		},
  4548  		// Two small rows with interleaved child rows after the second. Check
  4549  		// that we can split before the first interleaved row.
  4550  		{
  4551  			keys: []roachpb.Key{
  4552  				addColFam(tablePrefix(userID, "a"), 0),
  4553  				addColFam(tablePrefix(userID, "b"), 0),
  4554  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "b")), interleave1, "b"), 0),
  4555  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "b")), interleave1, "b"), 1),
  4556  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "b")), interleave2, "c"), 1),
  4557  			},
  4558  			rangeStart: tablePrefix(userID, "a"),
  4559  			expSplit:   addTablePrefix(addInterleave(tablePrefix(userID, "b")), interleave1, "b"),
  4560  			expError:   false,
  4561  		},
  4562  		// A chain of interleaved rows. Check that we can split them.
  4563  		{
  4564  			keys: []roachpb.Key{
  4565  				addColFam(tablePrefix(userID, "a"), 0),
  4566  				addColFam(addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"), 0),
  4567  				addColFam(addTablePrefix(addInterleave(
  4568  					addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4569  				), interleave2, "c"), 0),
  4570  				addColFam(addTablePrefix(addInterleave(
  4571  					addTablePrefix(addInterleave(
  4572  						addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4573  					), interleave2, "c"),
  4574  				), interleave3, "d"), 0),
  4575  			},
  4576  			rangeStart: tablePrefix(userID, "a"),
  4577  			expSplit: addTablePrefix(addInterleave(
  4578  				addTablePrefix(addInterleave(tablePrefix(userID, "a")), interleave1, "b"),
  4579  			), interleave2, "c"),
  4580  			expError: false,
  4581  		},
  4582  	}
  4583  
  4584  	for _, engineImpl := range mvccEngineImpls {
  4585  		t.Run(engineImpl.name, func(t *testing.T) {
  4586  			for i, test := range testCases {
  4587  				t.Run("", func(t *testing.T) {
  4588  					ctx := context.Background()
  4589  					engine := engineImpl.create()
  4590  					defer engine.Close()
  4591  
  4592  					ms := &enginepb.MVCCStats{}
  4593  					val := roachpb.MakeValueFromString(strings.Repeat("X", 10))
  4594  					for _, k := range test.keys {
  4595  						// Add three MVCC versions of every key. Splits are not allowed
  4596  						// between MVCC versions, so this shouldn't have any effect.
  4597  						for j := 1; j <= 3; j++ {
  4598  							ts := hlc.Timestamp{Logical: int32(j)}
  4599  							if err := MVCCPut(ctx, engine, ms, []byte(k), ts, val, nil); err != nil {
  4600  								t.Fatal(err)
  4601  							}
  4602  						}
  4603  					}
  4604  					rangeStart := test.keys[0]
  4605  					if len(test.rangeStart) > 0 {
  4606  						rangeStart = test.rangeStart
  4607  					}
  4608  					rangeEnd := test.keys[len(test.keys)-1].Next()
  4609  					rangeStartAddr, err := keys.Addr(rangeStart)
  4610  					if err != nil {
  4611  						t.Fatal(err)
  4612  					}
  4613  					rangeEndAddr, err := keys.Addr(rangeEnd)
  4614  					if err != nil {
  4615  						t.Fatal(err)
  4616  					}
  4617  					targetSize := (ms.KeyBytes + ms.ValBytes) / 2
  4618  					splitKey, err := MVCCFindSplitKey(ctx, engine, rangeStartAddr, rangeEndAddr, targetSize)
  4619  					if test.expError {
  4620  						if !testutils.IsError(err, "has no valid splits") {
  4621  							t.Fatalf("%d: unexpected error: %+v", i, err)
  4622  						}
  4623  						return
  4624  					}
  4625  					if err != nil {
  4626  						t.Fatalf("%d; unexpected error: %+v", i, err)
  4627  					}
  4628  					if !splitKey.Equal(test.expSplit) {
  4629  						t.Errorf("%d: expected split key %q; got %q", i, test.expSplit, splitKey)
  4630  					}
  4631  				})
  4632  			}
  4633  		})
  4634  	}
  4635  }
  4636  
  4637  // TestFindBalancedSplitKeys verifies split keys are located such that
  4638  // the left and right halves are equally balanced.
  4639  func TestFindBalancedSplitKeys(t *testing.T) {
  4640  	defer leaktest.AfterTest(t)()
  4641  	testCases := []struct {
  4642  		keySizes []int
  4643  		valSizes []int
  4644  		expSplit int
  4645  	}{
  4646  		// Bigger keys on right side.
  4647  		{
  4648  			keySizes: []int{10, 100, 10, 10, 500},
  4649  			valSizes: []int{1, 1, 1, 1, 1},
  4650  			expSplit: 4,
  4651  		},
  4652  		// Bigger keys on left side.
  4653  		{
  4654  			keySizes: []int{1000, 500, 500, 10, 10},
  4655  			valSizes: []int{1, 1, 1, 1, 1},
  4656  			expSplit: 1,
  4657  		},
  4658  		// Bigger values on right side.
  4659  		{
  4660  			keySizes: []int{1, 1, 1, 1, 1},
  4661  			valSizes: []int{10, 100, 10, 10, 500},
  4662  			expSplit: 4,
  4663  		},
  4664  		// Bigger values on left side.
  4665  		{
  4666  			keySizes: []int{1, 1, 1, 1, 1},
  4667  			valSizes: []int{1000, 100, 500, 10, 10},
  4668  			expSplit: 1,
  4669  		},
  4670  		// Bigger key/values on right side.
  4671  		{
  4672  			keySizes: []int{10, 100, 10, 10, 250},
  4673  			valSizes: []int{10, 100, 10, 10, 250},
  4674  			expSplit: 4,
  4675  		},
  4676  		// Bigger key/values on left side.
  4677  		{
  4678  			keySizes: []int{500, 50, 250, 10, 10},
  4679  			valSizes: []int{500, 50, 250, 10, 10},
  4680  			expSplit: 1,
  4681  		},
  4682  	}
  4683  
  4684  	for _, engineImpl := range mvccEngineImpls {
  4685  		t.Run(engineImpl.name, func(t *testing.T) {
  4686  			for i, test := range testCases {
  4687  				t.Run("", func(t *testing.T) {
  4688  					ctx := context.Background()
  4689  					engine := engineImpl.create()
  4690  					defer engine.Close()
  4691  
  4692  					ms := &enginepb.MVCCStats{}
  4693  					var expKey roachpb.Key
  4694  					for j, keySize := range test.keySizes {
  4695  						key := roachpb.Key(fmt.Sprintf("%d%s", j, strings.Repeat("X", keySize)))
  4696  						if test.expSplit == j {
  4697  							expKey = key
  4698  						}
  4699  						val := roachpb.MakeValueFromString(strings.Repeat("X", test.valSizes[j]))
  4700  						if err := MVCCPut(ctx, engine, ms, key, hlc.Timestamp{Logical: 1}, val, nil); err != nil {
  4701  							t.Fatal(err)
  4702  						}
  4703  					}
  4704  					targetSize := (ms.KeyBytes + ms.ValBytes) / 2
  4705  					splitKey, err := MVCCFindSplitKey(ctx, engine, roachpb.RKey("\x02"), roachpb.RKeyMax, targetSize)
  4706  					if err != nil {
  4707  						t.Fatalf("unexpected error: %+v", err)
  4708  					}
  4709  					if !splitKey.Equal(expKey) {
  4710  						t.Errorf("%d: expected split key %q; got %q", i, expKey, splitKey)
  4711  					}
  4712  				})
  4713  			}
  4714  		})
  4715  	}
  4716  }
  4717  
  4718  // TestMVCCGarbageCollect writes a series of gc'able bytes and then
  4719  // sends an MVCC GC request and verifies cleared values and updated
  4720  // stats.
  4721  func TestMVCCGarbageCollect(t *testing.T) {
  4722  	defer leaktest.AfterTest(t)()
  4723  
  4724  	ctx := context.Background()
  4725  	for _, engineImpl := range mvccEngineImpls {
  4726  		t.Run(engineImpl.name, func(t *testing.T) {
  4727  			engine := engineImpl.create()
  4728  			defer engine.Close()
  4729  
  4730  			ms := &enginepb.MVCCStats{}
  4731  
  4732  			bytes := []byte("value")
  4733  			ts1 := hlc.Timestamp{WallTime: 1e9}
  4734  			ts2 := hlc.Timestamp{WallTime: 2e9}
  4735  			ts3 := hlc.Timestamp{WallTime: 3e9}
  4736  			val1 := roachpb.MakeValueFromBytesAndTimestamp(bytes, ts1)
  4737  			val2 := roachpb.MakeValueFromBytesAndTimestamp(bytes, ts2)
  4738  			val3 := roachpb.MakeValueFromBytesAndTimestamp(bytes, ts3)
  4739  			valInline := roachpb.MakeValueFromBytesAndTimestamp(bytes, hlc.Timestamp{})
  4740  
  4741  			testData := []struct {
  4742  				key       roachpb.Key
  4743  				vals      []roachpb.Value
  4744  				isDeleted bool // is the most recent value a deletion tombstone?
  4745  			}{
  4746  				{roachpb.Key("a"), []roachpb.Value{val1, val2}, false},
  4747  				{roachpb.Key("a-del"), []roachpb.Value{val1, val2}, true},
  4748  				{roachpb.Key("b"), []roachpb.Value{val1, val2, val3}, false},
  4749  				{roachpb.Key("b-del"), []roachpb.Value{val1, val2, val3}, true},
  4750  				{roachpb.Key("inline"), []roachpb.Value{valInline}, false},
  4751  			}
  4752  
  4753  			for i := 0; i < 3; i++ {
  4754  				for _, test := range testData {
  4755  					if i >= len(test.vals) {
  4756  						continue
  4757  					}
  4758  					for _, val := range test.vals[i : i+1] {
  4759  						if i == len(test.vals)-1 && test.isDeleted {
  4760  							if err := MVCCDelete(ctx, engine, ms, test.key, val.Timestamp, nil); err != nil {
  4761  								t.Fatal(err)
  4762  							}
  4763  							continue
  4764  						}
  4765  						valCpy := *protoutil.Clone(&val).(*roachpb.Value)
  4766  						valCpy.Timestamp = hlc.Timestamp{}
  4767  						if err := MVCCPut(ctx, engine, ms, test.key, val.Timestamp, valCpy, nil); err != nil {
  4768  							t.Fatal(err)
  4769  						}
  4770  					}
  4771  				}
  4772  			}
  4773  			if log.V(1) {
  4774  				kvsn, err := Scan(engine, keyMin, keyMax, 0)
  4775  				if err != nil {
  4776  					t.Fatal(err)
  4777  				}
  4778  				for i, kv := range kvsn {
  4779  					log.Infof(context.Background(), "%d: %s", i, kv.Key)
  4780  				}
  4781  			}
  4782  
  4783  			keys := []roachpb.GCRequest_GCKey{
  4784  				{Key: roachpb.Key("a"), Timestamp: ts1},
  4785  				{Key: roachpb.Key("a-del"), Timestamp: ts2},
  4786  				{Key: roachpb.Key("b"), Timestamp: ts1},
  4787  				{Key: roachpb.Key("b-del"), Timestamp: ts2},
  4788  				{Key: roachpb.Key("inline"), Timestamp: hlc.Timestamp{}},
  4789  				// Keys that don't exist, which should result in a no-op.
  4790  				{Key: roachpb.Key("a-bad"), Timestamp: ts2},
  4791  				{Key: roachpb.Key("inline-bad"), Timestamp: hlc.Timestamp{}},
  4792  			}
  4793  			if err := MVCCGarbageCollect(
  4794  				context.Background(), engine, ms, keys, ts3,
  4795  			); err != nil {
  4796  				t.Fatal(err)
  4797  			}
  4798  
  4799  			expEncKeys := []MVCCKey{
  4800  				mvccVersionKey(roachpb.Key("a"), ts2),
  4801  				mvccVersionKey(roachpb.Key("b"), ts3),
  4802  				mvccVersionKey(roachpb.Key("b"), ts2),
  4803  				mvccVersionKey(roachpb.Key("b-del"), ts3),
  4804  			}
  4805  			kvs, err := Scan(engine, keyMin, keyMax, 0)
  4806  			if err != nil {
  4807  				t.Fatal(err)
  4808  			}
  4809  			if len(kvs) != len(expEncKeys) {
  4810  				t.Fatalf("number of kvs %d != expected %d", len(kvs), len(expEncKeys))
  4811  			}
  4812  			for i, kv := range kvs {
  4813  				if !kv.Key.Equal(expEncKeys[i]) {
  4814  					t.Errorf("%d: expected key %q; got %q", i, expEncKeys[i], kv.Key)
  4815  				}
  4816  			}
  4817  
  4818  			// Verify aggregated stats match computed stats after GC.
  4819  			iter := engine.NewIterator(IterOptions{UpperBound: roachpb.KeyMax})
  4820  			defer iter.Close()
  4821  			for _, mvccStatsTest := range mvccStatsTests {
  4822  				t.Run(mvccStatsTest.name, func(t *testing.T) {
  4823  					expMS, err := mvccStatsTest.fn(iter, roachpb.KeyMin, roachpb.KeyMax, ts3.WallTime)
  4824  					if err != nil {
  4825  						t.Fatal(err)
  4826  					}
  4827  					assertEq(t, engine, "verification", ms, &expMS)
  4828  				})
  4829  			}
  4830  		})
  4831  	}
  4832  }
  4833  
  4834  // TestMVCCGarbageCollectNonDeleted verifies that the first value for
  4835  // a key cannot be GC'd if it's not deleted.
  4836  func TestMVCCGarbageCollectNonDeleted(t *testing.T) {
  4837  	defer leaktest.AfterTest(t)()
  4838  
  4839  	ctx := context.Background()
  4840  	for _, engineImpl := range mvccEngineImpls {
  4841  		t.Run(engineImpl.name, func(t *testing.T) {
  4842  			engine := engineImpl.create()
  4843  			defer engine.Close()
  4844  
  4845  			s := "string"
  4846  			ts1 := hlc.Timestamp{WallTime: 1e9}
  4847  			ts2 := hlc.Timestamp{WallTime: 2e9}
  4848  			val1 := mkVal(s, ts1)
  4849  			val2 := mkVal(s, ts2)
  4850  			valInline := mkVal(s, hlc.Timestamp{})
  4851  
  4852  			testData := []struct {
  4853  				key      roachpb.Key
  4854  				vals     []roachpb.Value
  4855  				expError string
  4856  			}{
  4857  				{roachpb.Key("a"), []roachpb.Value{val1, val2}, `request to GC non-deleted, latest value of "a"`},
  4858  				{roachpb.Key("inline"), []roachpb.Value{valInline}, ""},
  4859  			}
  4860  
  4861  			for _, test := range testData {
  4862  				for _, val := range test.vals {
  4863  					valCpy := *protoutil.Clone(&val).(*roachpb.Value)
  4864  					valCpy.Timestamp = hlc.Timestamp{}
  4865  					if err := MVCCPut(ctx, engine, nil, test.key, val.Timestamp, valCpy, nil); err != nil {
  4866  						t.Fatal(err)
  4867  					}
  4868  				}
  4869  				keys := []roachpb.GCRequest_GCKey{
  4870  					{Key: test.key, Timestamp: ts2},
  4871  				}
  4872  				err := MVCCGarbageCollect(ctx, engine, nil, keys, ts2)
  4873  				if !testutils.IsError(err, test.expError) {
  4874  					t.Fatalf("expected error %q when garbage collecting a non-deleted live value, found %v",
  4875  						test.expError, err)
  4876  				}
  4877  			}
  4878  		})
  4879  	}
  4880  }
  4881  
  4882  // TestMVCCGarbageCollectIntent verifies that an intent cannot be GC'd.
  4883  func TestMVCCGarbageCollectIntent(t *testing.T) {
  4884  	defer leaktest.AfterTest(t)()
  4885  
  4886  	ctx := context.Background()
  4887  	for _, engineImpl := range mvccEngineImpls {
  4888  		t.Run(engineImpl.name, func(t *testing.T) {
  4889  			engine := engineImpl.create()
  4890  			defer engine.Close()
  4891  
  4892  			bytes := []byte("value")
  4893  			ts1 := hlc.Timestamp{WallTime: 1e9}
  4894  			ts2 := hlc.Timestamp{WallTime: 2e9}
  4895  			key := roachpb.Key("a")
  4896  			{
  4897  				val1 := roachpb.MakeValueFromBytes(bytes)
  4898  				if err := MVCCPut(ctx, engine, nil, key, ts1, val1, nil); err != nil {
  4899  					t.Fatal(err)
  4900  				}
  4901  			}
  4902  			txn := &roachpb.Transaction{
  4903  				TxnMeta:       enginepb.TxnMeta{ID: uuid.MakeV4(), WriteTimestamp: ts2},
  4904  				ReadTimestamp: ts2,
  4905  			}
  4906  			if err := MVCCDelete(ctx, engine, nil, key, txn.ReadTimestamp, txn); err != nil {
  4907  				t.Fatal(err)
  4908  			}
  4909  			keys := []roachpb.GCRequest_GCKey{
  4910  				{Key: key, Timestamp: ts2},
  4911  			}
  4912  			if err := MVCCGarbageCollect(ctx, engine, nil, keys, ts2); err == nil {
  4913  				t.Fatal("expected error garbage collecting an intent")
  4914  			}
  4915  		})
  4916  	}
  4917  }
  4918  
  4919  // TestResolveIntentWithLowerEpoch verifies that trying to resolve
  4920  // an intent at an epoch that is lower than the epoch of the intent
  4921  // leaves the intent untouched.
  4922  func TestResolveIntentWithLowerEpoch(t *testing.T) {
  4923  	defer leaktest.AfterTest(t)()
  4924  
  4925  	ctx := context.Background()
  4926  	for _, engineImpl := range mvccEngineImpls {
  4927  		t.Run(engineImpl.name, func(t *testing.T) {
  4928  			engine := engineImpl.create()
  4929  			defer engine.Close()
  4930  
  4931  			// Lay down an intent with a high epoch.
  4932  			if err := MVCCPut(ctx, engine, nil, testKey1, txn1e2.ReadTimestamp, value1, txn1e2); err != nil {
  4933  				t.Fatal(err)
  4934  			}
  4935  			// Resolve the intent with a low epoch.
  4936  			if _, err := MVCCResolveWriteIntent(ctx, engine, nil,
  4937  				roachpb.MakeLockUpdate(txn1, roachpb.Span{Key: testKey1})); err != nil {
  4938  				t.Fatal(err)
  4939  			}
  4940  
  4941  			// Check that the intent was not cleared.
  4942  			metaKey := mvccKey(testKey1)
  4943  			meta := &enginepb.MVCCMetadata{}
  4944  			ok, _, _, err := engine.GetProto(metaKey, meta)
  4945  			if err != nil {
  4946  				t.Fatal(err)
  4947  			}
  4948  			if !ok {
  4949  				t.Fatal("intent should not be cleared by resolve intent request with lower epoch")
  4950  			}
  4951  		})
  4952  	}
  4953  }
  4954  
  4955  // TestMVCCTimeSeriesPartialMerge ensures that "partial merges" of merged time
  4956  // series data does not result in a different final result than a "full merge".
  4957  func TestMVCCTimeSeriesPartialMerge(t *testing.T) {
  4958  	defer leaktest.AfterTest(t)()
  4959  
  4960  	ctx := context.Background()
  4961  	for _, engineImpl := range mvccEngineImpls {
  4962  		t.Run(engineImpl.name, func(t *testing.T) {
  4963  			engine := engineImpl.create()
  4964  			defer engine.Close()
  4965  
  4966  			// Perform the same sequence of merges on two different keys. For
  4967  			// one of them, insert some compactions which cause partial merges
  4968  			// to be run and affect the results.
  4969  			vals := make([]*roachpb.Value, 2)
  4970  
  4971  			for i, k := range []roachpb.Key{testKey1, testKey2} {
  4972  				if err := MVCCMerge(ctx, engine, nil, k, hlc.Timestamp{Logical: 1}, tsvalue1); err != nil {
  4973  					t.Fatal(err)
  4974  				}
  4975  				if err := MVCCMerge(ctx, engine, nil, k, hlc.Timestamp{Logical: 2}, tsvalue2); err != nil {
  4976  					t.Fatal(err)
  4977  				}
  4978  
  4979  				if i == 1 {
  4980  					if err := engine.Compact(); err != nil {
  4981  						t.Fatal(err)
  4982  					}
  4983  				}
  4984  
  4985  				if err := MVCCMerge(ctx, engine, nil, k, hlc.Timestamp{Logical: 2}, tsvalue2); err != nil {
  4986  					t.Fatal(err)
  4987  				}
  4988  				if err := MVCCMerge(ctx, engine, nil, k, hlc.Timestamp{Logical: 1}, tsvalue1); err != nil {
  4989  					t.Fatal(err)
  4990  				}
  4991  
  4992  				if i == 1 {
  4993  					if err := engine.Compact(); err != nil {
  4994  						t.Fatal(err)
  4995  					}
  4996  				}
  4997  
  4998  				if v, _, err := MVCCGet(ctx, engine, k, hlc.Timestamp{}, MVCCGetOptions{}); err != nil {
  4999  					t.Fatal(err)
  5000  				} else {
  5001  					vals[i] = v
  5002  				}
  5003  			}
  5004  
  5005  			if first, second := vals[0], vals[1]; !proto.Equal(first, second) {
  5006  				var firstTS, secondTS roachpb.InternalTimeSeriesData
  5007  				if err := first.GetProto(&firstTS); err != nil {
  5008  					t.Fatal(err)
  5009  				}
  5010  				if err := second.GetProto(&secondTS); err != nil {
  5011  					t.Fatal(err)
  5012  				}
  5013  				t.Fatalf("partially merged value %v differed from expected merged value %v", secondTS, firstTS)
  5014  			}
  5015  		})
  5016  	}
  5017  }
  5018  
  5019  func TestWillOverflow(t *testing.T) {
  5020  	defer leaktest.AfterTest(t)()
  5021  
  5022  	testCases := []struct {
  5023  		a, b     int64
  5024  		overflow bool // will a+b over- or underflow?
  5025  	}{
  5026  		{0, 0, false},
  5027  		{math.MaxInt64, 0, false},
  5028  		{math.MaxInt64, 1, true},
  5029  		{math.MaxInt64, math.MinInt64, false},
  5030  		{math.MinInt64, 0, false},
  5031  		{math.MinInt64, -1, true},
  5032  		{math.MinInt64, math.MinInt64, true},
  5033  	}
  5034  
  5035  	for i, c := range testCases {
  5036  		if willOverflow(c.a, c.b) != c.overflow ||
  5037  			willOverflow(c.b, c.a) != c.overflow {
  5038  			t.Errorf("%d: overflow recognition error", i)
  5039  		}
  5040  	}
  5041  }