github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/cmd_get.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 batcheval
    12  
    13  import (
    14  	"context"
    15  
    16  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result"
    17  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    18  	"github.com/cockroachdb/cockroach/pkg/storage"
    19  	"github.com/cockroachdb/cockroach/pkg/util/log"
    20  )
    21  
    22  func init() {
    23  	RegisterReadOnlyCommand(roachpb.Get, DefaultDeclareIsolatedKeys, Get)
    24  }
    25  
    26  // Get returns the value for a specified key.
    27  func Get(
    28  	ctx context.Context, reader storage.Reader, cArgs CommandArgs, resp roachpb.Response,
    29  ) (result.Result, error) {
    30  	args := cArgs.Args.(*roachpb.GetRequest)
    31  	h := cArgs.Header
    32  	reply := resp.(*roachpb.GetResponse)
    33  
    34  	val, intent, err := storage.MVCCGet(ctx, reader, args.Key, h.Timestamp, storage.MVCCGetOptions{
    35  		Inconsistent: h.ReadConsistency != roachpb.CONSISTENT,
    36  		Txn:          h.Txn,
    37  	})
    38  	if err != nil {
    39  		return result.Result{}, err
    40  	}
    41  	var intents []roachpb.Intent
    42  	if intent != nil {
    43  		intents = append(intents, *intent)
    44  	}
    45  
    46  	reply.Value = val
    47  	if h.ReadConsistency == roachpb.READ_UNCOMMITTED {
    48  		var intentVals []roachpb.KeyValue
    49  		// NOTE: MVCCGet uses a Prefix iterator, so we want to use one in
    50  		// CollectIntentRows as well so that we're guaranteed to use the same
    51  		// cached iterator and observe a consistent snapshot of the engine.
    52  		const usePrefixIter = true
    53  		intentVals, err = CollectIntentRows(ctx, reader, usePrefixIter, intents)
    54  		if err == nil {
    55  			switch len(intentVals) {
    56  			case 0:
    57  			case 1:
    58  				reply.IntentValue = &intentVals[0].Value
    59  			default:
    60  				log.Fatalf(ctx, "more than 1 intent on single key: %v", intentVals)
    61  			}
    62  		}
    63  	}
    64  	return result.FromEncounteredIntents(intents), err
    65  }