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

     1  // Copyright 2015 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 sql_test
    12  
    13  import (
    14  	"context"
    15  	"testing"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/config"
    18  	"github.com/cockroachdb/cockroach/pkg/config/zonepb"
    19  	"github.com/cockroachdb/cockroach/pkg/keys"
    20  	"github.com/cockroachdb/cockroach/pkg/kv"
    21  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    22  	"github.com/cockroachdb/cockroach/pkg/server"
    23  	"github.com/cockroachdb/cockroach/pkg/sql"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/tests"
    26  	"github.com/cockroachdb/cockroach/pkg/testutils"
    27  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    28  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    29  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    30  	"github.com/cockroachdb/errors"
    31  	"github.com/gogo/protobuf/proto"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  var configID = sqlbase.ID(1)
    36  var configDescKey = sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, keys.MaxReservedDescID)
    37  
    38  // forceNewConfig forces a system config update by writing a bogus descriptor with an
    39  // incremented value inside. It then repeatedly fetches the gossip config until the
    40  // just-written descriptor is found.
    41  func forceNewConfig(t testing.TB, s *server.TestServer) *config.SystemConfig {
    42  	configID++
    43  	configDesc := &sqlbase.Descriptor{
    44  		Union: &sqlbase.Descriptor_Database{
    45  			Database: &sqlbase.DatabaseDescriptor{
    46  				Name:       "sentinel",
    47  				ID:         configID,
    48  				Privileges: &sqlbase.PrivilegeDescriptor{},
    49  			},
    50  		},
    51  	}
    52  
    53  	// This needs to be done in a transaction with the system trigger set.
    54  	if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error {
    55  		if err := txn.SetSystemConfigTrigger(); err != nil {
    56  			return err
    57  		}
    58  		return txn.Put(ctx, configDescKey, configDesc)
    59  	}); err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	return waitForConfigChange(t, s)
    63  }
    64  
    65  func waitForConfigChange(t testing.TB, s *server.TestServer) *config.SystemConfig {
    66  	var foundDesc sqlbase.Descriptor
    67  	var cfg *config.SystemConfig
    68  	testutils.SucceedsSoon(t, func() error {
    69  		if cfg = s.Gossip().GetSystemConfig(); cfg != nil {
    70  			if val := cfg.GetValue(configDescKey); val != nil {
    71  				if err := val.GetProto(&foundDesc); err != nil {
    72  					t.Fatal(err)
    73  				}
    74  				if id := foundDesc.GetDatabase().GetID(); id != configID {
    75  					return errors.Errorf("expected database id %d; got %d", configID, id)
    76  				}
    77  				return nil
    78  			}
    79  		}
    80  		return errors.Errorf("got nil system config")
    81  	})
    82  	return cfg
    83  }
    84  
    85  // TODO(benesch,ridwansharif): modernize these tests to avoid hardcoding
    86  // expectations about descriptor IDs and zone config encoding.
    87  // TestGetZoneConfig exercises config.getZoneConfig and the sql hook for it.
    88  func TestGetZoneConfig(t *testing.T) {
    89  	defer leaktest.AfterTest(t)()
    90  	params, _ := tests.CreateTestServerParams()
    91  	defaultZoneConfig := zonepb.DefaultSystemZoneConfig()
    92  	defaultZoneConfig.NumReplicas = proto.Int32(1)
    93  	defaultZoneConfig.RangeMinBytes = proto.Int64(1 << 20)
    94  	defaultZoneConfig.RangeMaxBytes = proto.Int64(1 << 21)
    95  	defaultZoneConfig.GC = &zonepb.GCPolicy{TTLSeconds: 60}
    96  	require.NoError(t, defaultZoneConfig.Validate())
    97  	params.Knobs.Server = &server.TestingKnobs{
    98  		DefaultZoneConfigOverride:       &defaultZoneConfig,
    99  		DefaultSystemZoneConfigOverride: &defaultZoneConfig,
   100  	}
   101  
   102  	srv, sqlDB, _ := serverutils.StartServer(t, params)
   103  	defer srv.Stopper().Stop(context.Background())
   104  	s := srv.(*server.TestServer)
   105  
   106  	expectedCounter := uint32(keys.MinNonPredefinedUserDescID)
   107  
   108  	type testCase struct {
   109  		objectID uint32
   110  
   111  		// keySuffix and partitionName must specify the same subzone.
   112  		keySuffix     []byte
   113  		partitionName string
   114  
   115  		zoneCfg zonepb.ZoneConfig
   116  	}
   117  	verifyZoneConfigs := func(testCases []testCase) {
   118  		cfg := forceNewConfig(t, s)
   119  
   120  		for tcNum, tc := range testCases {
   121  			// Verify SystemConfig.GetZoneConfigForKey.
   122  			{
   123  				key := append(roachpb.RKey(keys.SystemSQLCodec.TablePrefix(tc.objectID)), tc.keySuffix...)
   124  				zoneCfg, err := cfg.GetZoneConfigForKey(key) // Complete ZoneConfig
   125  				if err != nil {
   126  					t.Fatalf("#%d: err=%s", tcNum, err)
   127  				}
   128  
   129  				if !tc.zoneCfg.Equal(zoneCfg) {
   130  					t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, tc.zoneCfg, zoneCfg)
   131  				}
   132  			}
   133  
   134  			// Verify sql.GetZoneConfigInTxn.
   135  			if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error {
   136  				_, zoneCfg, subzone, err := sql.GetZoneConfigInTxn(ctx, txn,
   137  					tc.objectID, &sqlbase.IndexDescriptor{}, tc.partitionName, false)
   138  				if err != nil {
   139  					return err
   140  				} else if subzone != nil {
   141  					zoneCfg = &subzone.Config
   142  				}
   143  				if !tc.zoneCfg.Equal(zoneCfg) {
   144  					t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, tc.zoneCfg, zoneCfg)
   145  				}
   146  				return nil
   147  			}); err != nil {
   148  				t.Fatalf("#%d: err=%s", tcNum, err)
   149  			}
   150  		}
   151  	}
   152  
   153  	{
   154  		buf, err := protoutil.Marshal(&defaultZoneConfig)
   155  		if err != nil {
   156  			t.Fatal(err)
   157  		}
   158  		objID := keys.RootNamespaceID
   159  		if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil {
   160  			t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err)
   161  		}
   162  	}
   163  
   164  	// Naming scheme for database and tables:
   165  	// db1 has tables tb11 and tb12
   166  	// db2 has tables tb21 and tb22
   167  
   168  	db1 := expectedCounter
   169  	if _, err := sqlDB.Exec(`CREATE DATABASE db1`); err != nil {
   170  		t.Fatal(err)
   171  	}
   172  
   173  	expectedCounter++
   174  	db2 := expectedCounter
   175  	if _, err := sqlDB.Exec(`CREATE DATABASE db2`); err != nil {
   176  		t.Fatal(err)
   177  	}
   178  
   179  	expectedCounter++
   180  	tb11 := expectedCounter
   181  	if _, err := sqlDB.Exec(`CREATE TABLE db1.tb1 (k INT PRIMARY KEY, v INT)`); err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	expectedCounter++
   186  	tb12 := expectedCounter
   187  	if _, err := sqlDB.Exec(`CREATE TABLE db1.tb2 (k INT PRIMARY KEY, v INT)`); err != nil {
   188  		t.Fatal(err)
   189  	}
   190  
   191  	expectedCounter++
   192  	tb21 := expectedCounter
   193  	if _, err := sqlDB.Exec(`CREATE TABLE db2.tb1 (k INT PRIMARY KEY, v INT)`); err != nil {
   194  		t.Fatal(err)
   195  	}
   196  
   197  	expectedCounter++
   198  	if _, err := sqlDB.Exec(`CREATE TABLE db2.tb2 (k INT PRIMARY KEY, v INT)`); err != nil {
   199  		t.Fatal(err)
   200  	}
   201  
   202  	expectedCounter++
   203  	tb22 := expectedCounter
   204  	if _, err := sqlDB.Exec(`TRUNCATE TABLE db2.tb2`); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	// We have no custom zone configs.
   209  	verifyZoneConfigs([]testCase{
   210  		{0, nil, "", defaultZoneConfig},
   211  		{1, nil, "", defaultZoneConfig},
   212  		{keys.MaxReservedDescID, nil, "", defaultZoneConfig},
   213  		{db1, nil, "", defaultZoneConfig},
   214  		{db2, nil, "", defaultZoneConfig},
   215  		{tb11, nil, "", defaultZoneConfig},
   216  		{tb11, []byte{42}, "p0", defaultZoneConfig},
   217  		{tb12, nil, "", defaultZoneConfig},
   218  		{tb12, []byte{42}, "p0", defaultZoneConfig},
   219  		{tb21, nil, "", defaultZoneConfig},
   220  		{tb22, nil, "", defaultZoneConfig},
   221  	})
   222  
   223  	// Now set some zone configs. We don't have a nice way of using table
   224  	// names for this, so we do raw puts.
   225  	// Here is the list of dbs/tables/partitions and whether they have a custom
   226  	// zone config:
   227  	// db1: true
   228  	//   tb1: true
   229  	//   tb2: false
   230  	// db2: false
   231  	//   tb1: true
   232  	//     p1: true [1, 2), [6, 7)
   233  	//     p2: true [3, 5)
   234  	//   tb2: false
   235  	//     p1: true  [1, 255)
   236  
   237  	db1Cfg := defaultZoneConfig
   238  	db1Cfg.NumReplicas = proto.Int32(1)
   239  	db1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}}
   240  
   241  	tb11Cfg := defaultZoneConfig
   242  	tb11Cfg.NumReplicas = proto.Int32(1)
   243  	tb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}}
   244  
   245  	p211Cfg := defaultZoneConfig
   246  	p211Cfg.NumReplicas = proto.Int32(1)
   247  	p211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}}
   248  
   249  	p212Cfg := defaultZoneConfig
   250  	p212Cfg.NumReplicas = proto.Int32(1)
   251  	p212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}}
   252  
   253  	tb21Cfg := defaultZoneConfig
   254  	tb21Cfg.NumReplicas = proto.Int32(1)
   255  	tb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}}
   256  	tb21Cfg.Subzones = []zonepb.Subzone{
   257  		{PartitionName: "p0", Config: p211Cfg},
   258  		{PartitionName: "p1", Config: p212Cfg},
   259  	}
   260  	tb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{
   261  		{SubzoneIndex: 0, Key: []byte{1}},
   262  		{SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}},
   263  		{SubzoneIndex: 0, Key: []byte{6}},
   264  	}
   265  
   266  	p221Cfg := defaultZoneConfig
   267  	p221Cfg.NumReplicas = proto.Int32(1)
   268  	p221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}}
   269  
   270  	// Subzone Placeholder
   271  	tb22Cfg := *zonepb.NewZoneConfig()
   272  	tb22Cfg.NumReplicas = proto.Int32(0)
   273  	tb22Cfg.Subzones = []zonepb.Subzone{{PartitionName: "p0", Config: p221Cfg}}
   274  	tb22Cfg.SubzoneSpans = []zonepb.SubzoneSpan{
   275  		{SubzoneIndex: 0, Key: []byte{1}, EndKey: []byte{255}},
   276  	}
   277  
   278  	for objID, objZone := range map[uint32]zonepb.ZoneConfig{
   279  		db1:  db1Cfg,
   280  		tb11: tb11Cfg,
   281  		tb21: tb21Cfg,
   282  		tb22: tb22Cfg,
   283  	} {
   284  		buf, err := protoutil.Marshal(&objZone)
   285  		if err != nil {
   286  			t.Fatal(err)
   287  		}
   288  		if _, err = sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, objID, buf); err != nil {
   289  			t.Fatalf("problem writing zone %+v: %s", objZone, err)
   290  		}
   291  	}
   292  
   293  	verifyZoneConfigs([]testCase{
   294  		{0, nil, "", defaultZoneConfig},
   295  		{1, nil, "", defaultZoneConfig},
   296  		{keys.MaxReservedDescID, nil, "", defaultZoneConfig},
   297  		{db1, nil, "", db1Cfg},
   298  		{db2, nil, "", defaultZoneConfig},
   299  		{tb11, nil, "", tb11Cfg},
   300  		{tb11, []byte{42}, "p0", tb11Cfg},
   301  		{tb12, nil, "", db1Cfg},
   302  		{tb12, []byte{42}, "p0", db1Cfg},
   303  		{tb21, nil, "", tb21Cfg},
   304  		{tb21, []byte{}, "", tb21Cfg},
   305  		{tb21, []byte{0}, "", tb21Cfg},
   306  		{tb21, []byte{1}, "p0", p211Cfg},
   307  		{tb21, []byte{1, 255}, "p0", p211Cfg},
   308  		{tb21, []byte{2}, "", tb21Cfg},
   309  		{tb21, []byte{3}, "p1", p212Cfg},
   310  		{tb21, []byte{4}, "p1", p212Cfg},
   311  		{tb21, []byte{5}, "", tb21Cfg},
   312  		{tb21, []byte{6}, "p0", p211Cfg},
   313  		{tb22, nil, "", defaultZoneConfig},
   314  		{tb22, []byte{0}, "", defaultZoneConfig},
   315  		{tb22, []byte{1}, "p0", p221Cfg},
   316  		{tb22, []byte{255}, "", defaultZoneConfig},
   317  	})
   318  }
   319  
   320  // TestCascadingZoneConfig tests whether the cascading nature of
   321  // the zone configurations works well with the different inheritance
   322  // hierarchies.
   323  func TestCascadingZoneConfig(t *testing.T) {
   324  	defer leaktest.AfterTest(t)()
   325  	params, _ := tests.CreateTestServerParams()
   326  
   327  	defaultZoneConfig := zonepb.DefaultZoneConfig()
   328  	defaultZoneConfig.NumReplicas = proto.Int32(1)
   329  	defaultZoneConfig.RangeMinBytes = proto.Int64(1 << 20)
   330  	defaultZoneConfig.RangeMaxBytes = proto.Int64(1 << 21)
   331  	defaultZoneConfig.GC = &zonepb.GCPolicy{TTLSeconds: 60}
   332  	require.NoError(t, defaultZoneConfig.Validate())
   333  	params.Knobs.Server = &server.TestingKnobs{
   334  		DefaultZoneConfigOverride:       &defaultZoneConfig,
   335  		DefaultSystemZoneConfigOverride: &defaultZoneConfig,
   336  	}
   337  
   338  	srv, sqlDB, _ := serverutils.StartServer(t, params)
   339  	defer srv.Stopper().Stop(context.Background())
   340  	s := srv.(*server.TestServer)
   341  
   342  	expectedCounter := uint32(keys.MinNonPredefinedUserDescID)
   343  
   344  	type testCase struct {
   345  		objectID uint32
   346  
   347  		// keySuffix and partitionName must specify the same subzone.
   348  		keySuffix     []byte
   349  		partitionName string
   350  
   351  		zoneCfg zonepb.ZoneConfig
   352  	}
   353  	verifyZoneConfigs := func(testCases []testCase) {
   354  		cfg := forceNewConfig(t, s)
   355  
   356  		for tcNum, tc := range testCases {
   357  			// Verify SystemConfig.GetZoneConfigForKey.
   358  			{
   359  				key := append(roachpb.RKey(keys.SystemSQLCodec.TablePrefix(tc.objectID)), tc.keySuffix...)
   360  				zoneCfg, err := cfg.GetZoneConfigForKey(key) // Complete ZoneConfig
   361  				if err != nil {
   362  					t.Fatalf("#%d: err=%s", tcNum, err)
   363  				}
   364  
   365  				if !tc.zoneCfg.Equal(zoneCfg) {
   366  					t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, &tc.zoneCfg, zoneCfg)
   367  				}
   368  			}
   369  
   370  			// Verify sql.GetZoneConfigInTxn.
   371  			if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error {
   372  				_, zoneCfg, subzone, err := sql.GetZoneConfigInTxn(ctx, txn,
   373  					tc.objectID, &sqlbase.IndexDescriptor{}, tc.partitionName, false)
   374  				if err != nil {
   375  					return err
   376  				} else if subzone != nil {
   377  					zoneCfg = &subzone.Config
   378  				}
   379  				if !tc.zoneCfg.Equal(zoneCfg) {
   380  					t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, &tc.zoneCfg, zoneCfg)
   381  				}
   382  				return nil
   383  			}); err != nil {
   384  				t.Fatalf("#%d: err=%s", tcNum, err)
   385  			}
   386  		}
   387  	}
   388  
   389  	{
   390  		buf, err := protoutil.Marshal(&defaultZoneConfig)
   391  		if err != nil {
   392  			t.Fatal(err)
   393  		}
   394  		objID := keys.RootNamespaceID
   395  		if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil {
   396  			t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err)
   397  		}
   398  	}
   399  
   400  	// Naming scheme for database and tables:
   401  	// db1 has tables tb11 and tb12
   402  	// db2 has tables tb21 and tb22
   403  
   404  	db1 := expectedCounter
   405  	if _, err := sqlDB.Exec(`CREATE DATABASE db1`); err != nil {
   406  		t.Fatal(err)
   407  	}
   408  
   409  	expectedCounter++
   410  	db2 := expectedCounter
   411  	if _, err := sqlDB.Exec(`CREATE DATABASE db2`); err != nil {
   412  		t.Fatal(err)
   413  	}
   414  
   415  	expectedCounter++
   416  	tb11 := expectedCounter
   417  	if _, err := sqlDB.Exec(`CREATE TABLE db1.tb1 (k INT PRIMARY KEY, v INT)`); err != nil {
   418  		t.Fatal(err)
   419  	}
   420  
   421  	expectedCounter++
   422  	tb12 := expectedCounter
   423  	if _, err := sqlDB.Exec(`CREATE TABLE db1.tb2 (k INT PRIMARY KEY, v INT)`); err != nil {
   424  		t.Fatal(err)
   425  	}
   426  
   427  	expectedCounter++
   428  	tb21 := expectedCounter
   429  	if _, err := sqlDB.Exec(`CREATE TABLE db2.tb1 (k INT PRIMARY KEY, v INT)`); err != nil {
   430  		t.Fatal(err)
   431  	}
   432  
   433  	expectedCounter++
   434  	if _, err := sqlDB.Exec(`CREATE TABLE db2.tb2 (k INT PRIMARY KEY, v INT)`); err != nil {
   435  		t.Fatal(err)
   436  	}
   437  
   438  	expectedCounter++
   439  	tb22 := expectedCounter
   440  	if _, err := sqlDB.Exec(`TRUNCATE TABLE db2.tb2`); err != nil {
   441  		t.Fatal(err)
   442  	}
   443  
   444  	// We have no custom zone configs.
   445  	verifyZoneConfigs([]testCase{
   446  		{0, nil, "", defaultZoneConfig},
   447  		{1, nil, "", defaultZoneConfig},
   448  		{keys.MaxReservedDescID, nil, "", defaultZoneConfig},
   449  		{db1, nil, "", defaultZoneConfig},
   450  		{db2, nil, "", defaultZoneConfig},
   451  		{tb11, nil, "", defaultZoneConfig},
   452  		{tb11, []byte{42}, "p0", defaultZoneConfig},
   453  		{tb12, nil, "", defaultZoneConfig},
   454  		{tb12, []byte{42}, "p0", defaultZoneConfig},
   455  		{tb21, nil, "", defaultZoneConfig},
   456  		{tb22, nil, "", defaultZoneConfig},
   457  	})
   458  
   459  	// Now set some zone configs. We don't have a nice way of using table
   460  	// names for this, so we do raw puts.
   461  	// .default: has replciation factor of 1
   462  	// db1: has replication factor of 5
   463  	//   tb1: inherits replication factor from db1
   464  	//   tb2: no zone config
   465  	// db2: no zone config
   466  	//   tb1: inherits replication factor from default
   467  	//     p1: true [1, 2), [6, 7) - Explicitly set replciation factor
   468  	//     p2: true [3, 5) - inherits repliaction factor from default
   469  	//   tb2: no zone config
   470  	//     p1: true  [1, 255) - inherits replciation factor from default
   471  
   472  	db1Cfg := *zonepb.NewZoneConfig()
   473  	db1Cfg.NumReplicas = proto.Int32(5)
   474  	db1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}}
   475  	db1Cfg.InheritedConstraints = false
   476  
   477  	// Expected complete config
   478  	expectedDb1Cfg := defaultZoneConfig
   479  	expectedDb1Cfg.NumReplicas = proto.Int32(5)
   480  	expectedDb1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}}
   481  
   482  	tb11Cfg := *zonepb.NewZoneConfig()
   483  	tb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}}
   484  	tb11Cfg.InheritedConstraints = false
   485  
   486  	// Expected complete config
   487  	expectedTb11Cfg := expectedDb1Cfg
   488  	expectedTb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}}
   489  
   490  	p211Cfg := *zonepb.NewZoneConfig()
   491  	p211Cfg.NumReplicas = proto.Int32(1)
   492  	p211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}}
   493  	p211Cfg.InheritedConstraints = false
   494  
   495  	// Expected complete config
   496  	expectedP211Cfg := defaultZoneConfig
   497  	expectedP211Cfg.NumReplicas = proto.Int32(1)
   498  	expectedP211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}}
   499  
   500  	p212Cfg := *zonepb.NewZoneConfig()
   501  	p212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}}
   502  	p212Cfg.InheritedConstraints = false
   503  
   504  	// Expected complete config
   505  	expectedP212Cfg := defaultZoneConfig
   506  	expectedP212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}}
   507  
   508  	tb21Cfg := *zonepb.NewZoneConfig()
   509  	tb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}}
   510  	tb21Cfg.InheritedConstraints = false
   511  	tb21Cfg.Subzones = []zonepb.Subzone{
   512  		{PartitionName: "p0", Config: p211Cfg},
   513  		{PartitionName: "p1", Config: p212Cfg},
   514  	}
   515  	tb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{
   516  		{SubzoneIndex: 0, Key: []byte{1}},
   517  		{SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}},
   518  		{SubzoneIndex: 0, Key: []byte{6}},
   519  	}
   520  
   521  	// Expected complete config
   522  	expectedTb21Cfg := defaultZoneConfig
   523  	expectedTb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}}
   524  	expectedTb21Cfg.Subzones = []zonepb.Subzone{
   525  		{PartitionName: "p0", Config: p211Cfg},
   526  		{PartitionName: "p1", Config: p212Cfg},
   527  	}
   528  	expectedTb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{
   529  		{SubzoneIndex: 0, Key: []byte{1}},
   530  		{SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}},
   531  		{SubzoneIndex: 0, Key: []byte{6}},
   532  	}
   533  
   534  	p221Cfg := *zonepb.NewZoneConfig()
   535  	p221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}}
   536  	p221Cfg.InheritedConstraints = false
   537  
   538  	// Expected complete config
   539  	expectedP221Cfg := defaultZoneConfig
   540  	expectedP221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}}
   541  
   542  	// Subzone Placeholder
   543  	tb22Cfg := *zonepb.NewZoneConfig()
   544  	tb22Cfg.NumReplicas = proto.Int32(0)
   545  	tb22Cfg.Subzones = []zonepb.Subzone{{PartitionName: "p0", Config: p221Cfg}}
   546  	tb22Cfg.SubzoneSpans = []zonepb.SubzoneSpan{
   547  		{SubzoneIndex: 0, Key: []byte{1}, EndKey: []byte{255}},
   548  	}
   549  
   550  	for objID, objZone := range map[uint32]zonepb.ZoneConfig{
   551  		db1:  db1Cfg,
   552  		tb11: tb11Cfg,
   553  		tb21: tb21Cfg,
   554  		tb22: tb22Cfg,
   555  	} {
   556  		buf, err := protoutil.Marshal(&objZone)
   557  		if err != nil {
   558  			t.Fatal(err)
   559  		}
   560  		if _, err = sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, objID, buf); err != nil {
   561  			t.Fatalf("problem writing zone %+v: %s", objZone, err)
   562  		}
   563  	}
   564  
   565  	verifyZoneConfigs([]testCase{
   566  		{0, nil, "", defaultZoneConfig},
   567  		{1, nil, "", defaultZoneConfig},
   568  		{keys.MaxReservedDescID, nil, "", defaultZoneConfig},
   569  		{db1, nil, "", expectedDb1Cfg},
   570  		{db2, nil, "", defaultZoneConfig},
   571  		{tb11, nil, "", expectedTb11Cfg},
   572  		{tb11, []byte{42}, "p0", expectedTb11Cfg},
   573  		{tb12, nil, "", expectedDb1Cfg},
   574  		{tb12, []byte{42}, "p0", expectedDb1Cfg},
   575  		{tb21, nil, "", expectedTb21Cfg},
   576  		{tb21, []byte{}, "", expectedTb21Cfg},
   577  		{tb21, []byte{0}, "", expectedTb21Cfg},
   578  		{tb21, []byte{1}, "p0", expectedP211Cfg},
   579  		{tb21, []byte{1, 255}, "p0", expectedP211Cfg},
   580  		{tb21, []byte{2}, "", expectedTb21Cfg},
   581  		{tb21, []byte{3}, "p1", expectedP212Cfg},
   582  		{tb21, []byte{4}, "p1", expectedP212Cfg},
   583  		{tb21, []byte{5}, "", expectedTb21Cfg},
   584  		{tb21, []byte{6}, "p0", expectedP211Cfg},
   585  		{tb22, nil, "", defaultZoneConfig},
   586  		{tb22, []byte{0}, "", defaultZoneConfig},
   587  		{tb22, []byte{1}, "p0", expectedP221Cfg},
   588  		{tb22, []byte{255}, "", defaultZoneConfig},
   589  	})
   590  
   591  	// Change the default.
   592  	defaultZoneConfig.NumReplicas = proto.Int32(5)
   593  
   594  	buf, err := protoutil.Marshal(&defaultZoneConfig)
   595  	if err != nil {
   596  		t.Fatal(err)
   597  	}
   598  	objID := keys.RootNamespaceID
   599  	if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil {
   600  		t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err)
   601  	}
   602  
   603  	// Ensure the changes cascade down.
   604  	expectedTb21Cfg.NumReplicas = proto.Int32(5)
   605  	expectedP212Cfg.NumReplicas = proto.Int32(5)
   606  	expectedP221Cfg.NumReplicas = proto.Int32(5)
   607  
   608  	verifyZoneConfigs([]testCase{
   609  		// TODO(ridwanmsharif): Figure out what these 3 are supposed to do.
   610  		// {0, nil, "", defaultZoneConfig},
   611  		// {1, nil, "", cfg},
   612  		// {keys.MaxReservedDescID, nil, "", defaultZoneConfig},
   613  		{db1, nil, "", expectedDb1Cfg},
   614  		{db2, nil, "", defaultZoneConfig},
   615  		{tb11, nil, "", expectedTb11Cfg},
   616  		{tb11, []byte{42}, "p0", expectedTb11Cfg},
   617  		{tb12, nil, "", expectedDb1Cfg},
   618  		{tb12, []byte{42}, "p0", expectedDb1Cfg},
   619  		{tb21, nil, "", expectedTb21Cfg},
   620  		{tb21, []byte{}, "", expectedTb21Cfg},
   621  		{tb21, []byte{0}, "", expectedTb21Cfg},
   622  		{tb21, []byte{1}, "p0", expectedP211Cfg},
   623  		{tb21, []byte{1, 255}, "p0", expectedP211Cfg},
   624  		{tb21, []byte{2}, "", expectedTb21Cfg},
   625  		{tb21, []byte{3}, "p1", expectedP212Cfg},
   626  		{tb21, []byte{4}, "p1", expectedP212Cfg},
   627  		{tb21, []byte{5}, "", expectedTb21Cfg},
   628  		{tb21, []byte{6}, "p0", expectedP211Cfg},
   629  		{tb22, nil, "", defaultZoneConfig},
   630  		{tb22, []byte{0}, "", defaultZoneConfig},
   631  		{tb22, []byte{1}, "p0", expectedP221Cfg},
   632  		{tb22, []byte{255}, "", defaultZoneConfig},
   633  	})
   634  }
   635  
   636  func BenchmarkGetZoneConfig(b *testing.B) {
   637  	defer leaktest.AfterTest(b)()
   638  
   639  	params, _ := tests.CreateTestServerParams()
   640  	srv, _, _ := serverutils.StartServer(b, params)
   641  	defer srv.Stopper().Stop(context.Background())
   642  	s := srv.(*server.TestServer)
   643  	cfg := forceNewConfig(b, s)
   644  
   645  	b.ResetTimer()
   646  	for i := 0; i < b.N; i++ {
   647  		key := roachpb.RKey(keys.SystemSQLCodec.TablePrefix(keys.MinUserDescID))
   648  		_, err := cfg.GetZoneConfigForKey(key)
   649  		if err != nil {
   650  			b.Fatal(err)
   651  		}
   652  	}
   653  	b.StopTimer()
   654  }