github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/tests/end_txn_trigger.go (about) 1 // Copyright 2017 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 tests 12 13 import ( 14 "bytes" 15 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase" 18 "github.com/cockroachdb/cockroach/pkg/roachpb" 19 "github.com/cockroachdb/errors" 20 ) 21 22 // CheckEndTxnTrigger verifies that an EndTxnRequest that includes intents for 23 // the SystemDB keys sets the proper trigger. 24 func CheckEndTxnTrigger(args kvserverbase.FilterArgs) *roachpb.Error { 25 req, ok := args.Req.(*roachpb.EndTxnRequest) 26 if !ok { 27 return nil 28 } 29 30 if !req.Commit { 31 // This is a rollback: skip trigger verification. 32 return nil 33 } 34 35 modifiedSpanTrigger := req.InternalCommitTrigger.GetModifiedSpanTrigger() 36 modifiedSystemConfigSpan := modifiedSpanTrigger != nil && modifiedSpanTrigger.SystemConfigSpan 37 38 var hasSystemKey bool 39 for _, span := range req.LockSpans { 40 if bytes.Compare(span.Key, keys.SystemConfigSpan.Key) >= 0 && 41 bytes.Compare(span.Key, keys.SystemConfigSpan.EndKey) < 0 { 42 hasSystemKey = true 43 break 44 } 45 } 46 // If the transaction in question has intents in the system span, then 47 // modifiedSystemConfigSpan should always be true. However, it is possible 48 // for modifiedSystemConfigSpan to be set, even though no system keys are 49 // present. This can occur with certain conditional DDL statements (e.g. 50 // "CREATE TABLE IF NOT EXISTS"), which set the SystemConfigTrigger 51 // aggressively but may not actually end up changing the system DB depending 52 // on the current state. 53 // For more information, see the related comment at the beginning of 54 // planner.makePlan(). 55 if hasSystemKey && !modifiedSystemConfigSpan { 56 return roachpb.NewError(errors.Errorf("EndTxn hasSystemKey=%t, but hasSystemConfigTrigger=%t", 57 hasSystemKey, modifiedSystemConfigSpan)) 58 } 59 60 return nil 61 }