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

     1  // Copyright 2020 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 keys
    12  
    13  import (
    14  	"bytes"
    15  
    16  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    17  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    18  	"github.com/cockroachdb/errors"
    19  )
    20  
    21  // MakeTenantPrefix creates the key prefix associated with the specified tenant.
    22  func MakeTenantPrefix(tenID roachpb.TenantID) roachpb.Key {
    23  	if tenID == roachpb.SystemTenantID {
    24  		return nil
    25  	}
    26  	return encoding.EncodeUvarintAscending(TenantPrefix, tenID.ToUint64())
    27  }
    28  
    29  // DecodeTenantPrefix determines the tenant ID from the key prefix, returning
    30  // the remainder of the key (with the prefix removed) and the decoded tenant ID.
    31  func DecodeTenantPrefix(key roachpb.Key) ([]byte, roachpb.TenantID, error) {
    32  	if len(key) == 0 { // key.Equal(roachpb.RKeyMin)
    33  		return nil, roachpb.SystemTenantID, nil
    34  	}
    35  	if key[0] != tenantPrefixByte {
    36  		return key, roachpb.SystemTenantID, nil
    37  	}
    38  	rem, tenID, err := encoding.DecodeUvarintAscending(key[1:])
    39  	if err != nil {
    40  		return nil, roachpb.TenantID{}, err
    41  	}
    42  	return rem, roachpb.MakeTenantID(tenID), nil
    43  }
    44  
    45  // SQLCodec provides methods for encoding SQL table keys bound to a given
    46  // tenant. The generator also provides methods for efficiently decoding keys
    47  // previously generated by it. The generated keys are safe to use indefinitely
    48  // and the generator is safe to use concurrently.
    49  type SQLCodec struct {
    50  	sqlEncoder
    51  	sqlDecoder
    52  	_ func() // incomparable
    53  }
    54  
    55  // sqlEncoder implements the encoding logic for SQL keys.
    56  //
    57  // The type is expressed as a pointer to a slice instead of a slice directly so
    58  // that its zero value is not usable. Any attempt to use the methods on the zero
    59  // value of a sqlEncoder will panic.
    60  type sqlEncoder struct {
    61  	buf *roachpb.Key
    62  }
    63  
    64  // sqlEncoder implements the decoding logic for SQL keys.
    65  //
    66  // The type is expressed as a pointer to a slice instead of a slice directly so
    67  // that its zero value is not usable. Any attempt to use the methods on the zero
    68  // value of a sqlDecoder will panic.
    69  type sqlDecoder struct {
    70  	buf *roachpb.Key
    71  }
    72  
    73  // MakeSQLCodec creates a new  SQLCodec suitable for manipulating SQL keys.
    74  func MakeSQLCodec(tenID roachpb.TenantID) SQLCodec {
    75  	k := MakeTenantPrefix(tenID)
    76  	k = k[:len(k):len(k)] // bound capacity, avoid aliasing
    77  	return SQLCodec{
    78  		sqlEncoder: sqlEncoder{&k},
    79  		sqlDecoder: sqlDecoder{&k},
    80  	}
    81  }
    82  
    83  // SystemSQLCodec is a SQL key codec for the system tenant.
    84  var SystemSQLCodec = MakeSQLCodec(roachpb.SystemTenantID)
    85  
    86  // TODOSQLCodec is a SQL key codec. It is equivalent to SystemSQLCodec, but
    87  // should be used when it is unclear which tenant should be referenced by the
    88  // surrounding context.
    89  var TODOSQLCodec = MakeSQLCodec(roachpb.SystemTenantID)
    90  
    91  // ForSystemTenant returns whether the encoder is bound to the system tenant.
    92  func (e sqlEncoder) ForSystemTenant() bool {
    93  	return len(e.TenantPrefix()) == 0
    94  }
    95  
    96  // TenantPrefix returns the key prefix used for the tenants's data.
    97  func (e sqlEncoder) TenantPrefix() roachpb.Key {
    98  	return *e.buf
    99  }
   100  
   101  // TablePrefix returns the key prefix used for the table's data.
   102  func (e sqlEncoder) TablePrefix(tableID uint32) roachpb.Key {
   103  	k := e.TenantPrefix()
   104  	return encoding.EncodeUvarintAscending(k, uint64(tableID))
   105  }
   106  
   107  // IndexPrefix returns the key prefix used for the index's data.
   108  func (e sqlEncoder) IndexPrefix(tableID, indexID uint32) roachpb.Key {
   109  	k := e.TablePrefix(tableID)
   110  	return encoding.EncodeUvarintAscending(k, uint64(indexID))
   111  }
   112  
   113  // DescMetadataPrefix returns the key prefix for all descriptors.
   114  func (e sqlEncoder) DescMetadataPrefix() roachpb.Key {
   115  	return e.IndexPrefix(DescriptorTableID, DescriptorTablePrimaryKeyIndexID)
   116  }
   117  
   118  // DescMetadataKey returns the key for the descriptor.
   119  func (e sqlEncoder) DescMetadataKey(descID uint32) roachpb.Key {
   120  	k := e.DescMetadataPrefix()
   121  	k = encoding.EncodeUvarintAscending(k, uint64(descID))
   122  	return MakeFamilyKey(k, DescriptorTableDescriptorColFamID)
   123  }
   124  
   125  // SequenceKey returns the key used to store the value of a sequence.
   126  func (e sqlEncoder) SequenceKey(tableID uint32) roachpb.Key {
   127  	k := e.IndexPrefix(tableID, SequenceIndexID)
   128  	k = encoding.EncodeUvarintAscending(k, 0)    // Primary key value
   129  	k = MakeFamilyKey(k, SequenceColumnFamilyID) // Column family
   130  	return k
   131  }
   132  
   133  // DescIDSequenceKey returns the key used for the descriptor ID sequence.
   134  func (e sqlEncoder) DescIDSequenceKey() roachpb.Key {
   135  	if e.ForSystemTenant() {
   136  		// To maintain backwards compatibility, the system tenant uses a
   137  		// separate, non-SQL, key to store its descriptor ID sequence.
   138  		return descIDGenerator
   139  	}
   140  	return e.SequenceKey(DescIDSequenceID)
   141  }
   142  
   143  // ZoneKeyPrefix returns the key prefix for id's row in the system.zones table.
   144  func (e sqlEncoder) ZoneKeyPrefix(id uint32) roachpb.Key {
   145  	if !e.ForSystemTenant() {
   146  		panic("zone keys only exist in the system tenant's keyspace")
   147  	}
   148  	k := e.IndexPrefix(ZonesTableID, ZonesTablePrimaryIndexID)
   149  	return encoding.EncodeUvarintAscending(k, uint64(id))
   150  }
   151  
   152  // ZoneKey returns the key for id's entry in the system.zones table.
   153  func (e sqlEncoder) ZoneKey(id uint32) roachpb.Key {
   154  	if !e.ForSystemTenant() {
   155  		panic("zone keys only exist in the system tenant's keyspace")
   156  	}
   157  	k := e.ZoneKeyPrefix(id)
   158  	return MakeFamilyKey(k, uint32(ZonesTableConfigColumnID))
   159  }
   160  
   161  // MigrationKeyPrefix returns the key prefix to store all migration details.
   162  func (e sqlEncoder) MigrationKeyPrefix() roachpb.Key {
   163  	return append(e.TenantPrefix(), MigrationPrefix...)
   164  }
   165  
   166  // MigrationLeaseKey returns the key that nodes must take a lease on in order to
   167  // run system migrations on the cluster.
   168  func (e sqlEncoder) MigrationLeaseKey() roachpb.Key {
   169  	return append(e.TenantPrefix(), MigrationLease...)
   170  }
   171  
   172  // unexpected to avoid colliding with sqlEncoder.tenantPrefix.
   173  func (d sqlDecoder) tenantPrefix() roachpb.Key {
   174  	return *d.buf
   175  }
   176  
   177  // StripTenantPrefix validates that the given key has the proper tenant ID
   178  // prefix, returning the remainder of the key with the prefix removed. The
   179  // method returns an error if the key has a different tenant ID prefix than
   180  // would be generated by the generator.
   181  func (d sqlDecoder) StripTenantPrefix(key roachpb.Key) ([]byte, error) {
   182  	tenPrefix := d.tenantPrefix()
   183  	if !bytes.HasPrefix(key, tenPrefix) {
   184  		return nil, errors.Errorf("invalid tenant id prefix: %q", key)
   185  	}
   186  	return key[len(tenPrefix):], nil
   187  }
   188  
   189  // DecodeTablePrefix validates that the given key has a table prefix, returning
   190  // the remainder of the key (with the prefix removed) and the decoded descriptor
   191  // ID of the table.
   192  func (d sqlDecoder) DecodeTablePrefix(key roachpb.Key) ([]byte, uint32, error) {
   193  	key, err := d.StripTenantPrefix(key)
   194  	if err != nil {
   195  		return nil, 0, err
   196  	}
   197  	if encoding.PeekType(key) != encoding.Int {
   198  		return nil, 0, errors.Errorf("invalid key prefix: %q", key)
   199  	}
   200  	key, tableID, err := encoding.DecodeUvarintAscending(key)
   201  	return key, uint32(tableID), err
   202  }
   203  
   204  // DecodeIndexPrefix validates that the given key has a table ID followed by an
   205  // index ID, returning the remainder of the key (with the table and index prefix
   206  // removed) and the decoded IDs of the table and index, respectively.
   207  func (d sqlDecoder) DecodeIndexPrefix(key roachpb.Key) ([]byte, uint32, uint32, error) {
   208  	key, tableID, err := d.DecodeTablePrefix(key)
   209  	if err != nil {
   210  		return nil, 0, 0, err
   211  	}
   212  	if encoding.PeekType(key) != encoding.Int {
   213  		return nil, 0, 0, errors.Errorf("invalid key prefix: %q", key)
   214  	}
   215  	key, indexID, err := encoding.DecodeUvarintAscending(key)
   216  	return key, tableID, uint32(indexID), err
   217  }
   218  
   219  // DecodeDescMetadataID decodes a descriptor ID from a descriptor metadata key.
   220  func (d sqlDecoder) DecodeDescMetadataID(key roachpb.Key) (uint64, error) {
   221  	// Extract table and index ID from key.
   222  	remaining, tableID, _, err := d.DecodeIndexPrefix(key)
   223  	if err != nil {
   224  		return 0, err
   225  	}
   226  	if tableID != DescriptorTableID {
   227  		return 0, errors.Errorf("key is not a descriptor table entry: %v", key)
   228  	}
   229  	// Extract the descriptor ID.
   230  	_, id, err := encoding.DecodeUvarintAscending(remaining)
   231  	if err != nil {
   232  		return 0, err
   233  	}
   234  	return id, nil
   235  }