github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/zone_test.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 sql_test 12 13 import ( 14 "context" 15 "fmt" 16 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/server" 21 "github.com/cockroachdb/cockroach/pkg/sql/lex" 22 "github.com/cockroachdb/cockroach/pkg/sql/tests" 23 "github.com/cockroachdb/cockroach/pkg/testutils" 24 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 25 "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" 26 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 27 "github.com/gogo/protobuf/proto" 28 ) 29 30 func TestValidSetShowZones(t *testing.T) { 31 defer leaktest.AfterTest(t)() 32 33 params, _ := tests.CreateTestServerParams() 34 s, db, _ := serverutils.StartServer(t, params) 35 defer s.Stopper().Stop(context.Background()) 36 37 sqlDB := sqlutils.MakeSQLRunner(db) 38 sqlDB.Exec(t, `CREATE DATABASE d; USE d; CREATE TABLE t ();`) 39 40 yamlDefault := fmt.Sprintf("gc: {ttlseconds: %d}", s.(*server.TestServer).Cfg.DefaultZoneConfig.GC.TTLSeconds) 41 yamlOverride := "gc: {ttlseconds: 42}" 42 zoneOverride := s.(*server.TestServer).Cfg.DefaultZoneConfig 43 zoneOverride.GC = &zonepb.GCPolicy{TTLSeconds: 42} 44 partialZoneOverride := *zonepb.NewZoneConfig() 45 partialZoneOverride.GC = &zonepb.GCPolicy{TTLSeconds: 42} 46 47 defaultRow := sqlutils.ZoneRow{ 48 ID: keys.RootNamespaceID, 49 Config: s.(*server.TestServer).Cfg.DefaultZoneConfig, 50 } 51 defaultOverrideRow := sqlutils.ZoneRow{ 52 ID: keys.RootNamespaceID, 53 Config: zoneOverride, 54 } 55 metaRow := sqlutils.ZoneRow{ 56 ID: keys.MetaRangesID, 57 Config: zoneOverride, 58 } 59 systemRow := sqlutils.ZoneRow{ 60 ID: keys.SystemDatabaseID, 61 Config: zoneOverride, 62 } 63 jobsRow := sqlutils.ZoneRow{ 64 ID: keys.JobsTableID, 65 Config: zoneOverride, 66 } 67 68 dbID := sqlutils.QueryDatabaseID(t, db, "d") 69 tableID := sqlutils.QueryTableID(t, db, "d", "public", "t") 70 71 dbRow := sqlutils.ZoneRow{ 72 ID: dbID, 73 Config: zoneOverride, 74 } 75 tableRow := sqlutils.ZoneRow{ 76 ID: tableID, 77 Config: zoneOverride, 78 } 79 80 // Partially filled config rows 81 partialMetaRow := sqlutils.ZoneRow{ 82 ID: keys.MetaRangesID, 83 Config: partialZoneOverride, 84 } 85 partialSystemRow := sqlutils.ZoneRow{ 86 ID: keys.SystemDatabaseID, 87 Config: partialZoneOverride, 88 } 89 partialJobsRow := sqlutils.ZoneRow{ 90 ID: keys.JobsTableID, 91 Config: partialZoneOverride, 92 } 93 partialDbRow := sqlutils.ZoneRow{ 94 ID: dbID, 95 Config: partialZoneOverride, 96 } 97 partialTableRow := sqlutils.ZoneRow{ 98 ID: tableID, 99 Config: partialZoneOverride, 100 } 101 102 // Remove stock zone configs installed at cluster bootstrap. Otherwise this 103 // test breaks whenever these stock zone configs are adjusted. 104 sqlutils.RemoveAllZoneConfigs(t, sqlDB) 105 106 // Ensure the default is reported for all zones at first. 107 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow) 108 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE default", defaultRow) 109 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", defaultRow) 110 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultRow) 111 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultRow) 112 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", defaultRow) 113 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", defaultRow) 114 115 // Ensure a database zone config applies to that database and its tables, and 116 // no other zones. 117 sqlutils.SetZoneConfig(t, sqlDB, "DATABASE d", yamlOverride) 118 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow, partialDbRow) 119 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", defaultRow) 120 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultRow) 121 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultRow) 122 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", dbRow) 123 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", dbRow) 124 125 // Ensure a table zone config applies to that table and no others. 126 sqlutils.SetZoneConfig(t, sqlDB, "TABLE d.t", yamlOverride) 127 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow, partialDbRow, partialTableRow) 128 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", defaultRow) 129 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultRow) 130 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultRow) 131 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", dbRow) 132 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", tableRow) 133 134 // Ensure a named zone config applies to that named zone and no others. 135 sqlutils.SetZoneConfig(t, sqlDB, "RANGE meta", yamlOverride) 136 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow, partialMetaRow, partialDbRow, partialTableRow) 137 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", metaRow) 138 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultRow) 139 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultRow) 140 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", dbRow) 141 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", tableRow) 142 143 // Ensure updating the default zone propagates to zones without an override, 144 // but not to those with overrides. 145 sqlutils.SetZoneConfig(t, sqlDB, "RANGE default", yamlOverride) 146 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultOverrideRow, partialMetaRow, partialDbRow, partialTableRow) 147 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", metaRow) 148 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultOverrideRow) 149 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultOverrideRow) 150 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", dbRow) 151 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", tableRow) 152 153 // Ensure deleting a database deletes only the database zone, and not the 154 // table zone. 155 sqlutils.DeleteZoneConfig(t, sqlDB, "DATABASE d") 156 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultOverrideRow, partialMetaRow, partialTableRow) 157 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", defaultOverrideRow) 158 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", tableRow) 159 160 // Ensure deleting a table zone works. 161 sqlutils.DeleteZoneConfig(t, sqlDB, "TABLE d.t") 162 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultOverrideRow, partialMetaRow) 163 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", defaultOverrideRow) 164 165 // Ensure deleting a named zone works. 166 sqlutils.DeleteZoneConfig(t, sqlDB, "RANGE meta") 167 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultOverrideRow) 168 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", defaultOverrideRow) 169 170 // Ensure deleting non-overridden zones is not an error. 171 sqlutils.DeleteZoneConfig(t, sqlDB, "RANGE meta") 172 sqlutils.DeleteZoneConfig(t, sqlDB, "DATABASE d") 173 sqlutils.DeleteZoneConfig(t, sqlDB, "TABLE d.t") 174 175 // Ensure updating the default zone config applies to zones that have had 176 // overrides added and removed. 177 sqlutils.SetZoneConfig(t, sqlDB, "RANGE default", yamlDefault) 178 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow) 179 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE default", defaultRow) 180 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "RANGE meta", defaultRow) 181 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", defaultRow) 182 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.lease", defaultRow) 183 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", defaultRow) 184 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", defaultRow) 185 186 // Ensure the system database zone can be configured, even though zones on 187 // config tables are disallowed. 188 sqlutils.SetZoneConfig(t, sqlDB, "DATABASE system", yamlOverride) 189 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow, partialSystemRow) 190 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE system", systemRow) 191 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.namespace", systemRow) 192 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.jobs", systemRow) 193 194 // Ensure zones for non-config tables in the system database can be 195 // configured. 196 sqlutils.SetZoneConfig(t, sqlDB, "TABLE system.jobs", yamlOverride) 197 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultRow, partialSystemRow, partialJobsRow) 198 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE system.jobs", jobsRow) 199 200 // Verify that the session database is respected. 201 sqlutils.SetZoneConfig(t, sqlDB, "TABLE t", yamlOverride) 202 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE t", tableRow) 203 sqlutils.DeleteZoneConfig(t, sqlDB, "TABLE t") 204 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE t", defaultRow) 205 206 // Verify we can use composite values. 207 sqlDB.Exec(t, fmt.Sprintf("ALTER TABLE t CONFIGURE ZONE = '' || %s || ''", 208 lex.EscapeSQLString(yamlOverride))) 209 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE t", tableRow) 210 211 // Ensure zone configs are read transactionally instead of from the cached 212 // system config. 213 txn, err := db.Begin() 214 if err != nil { 215 t.Fatal(err) 216 } 217 sqlutils.TxnSetZoneConfig(t, sqlDB, txn, "RANGE default", yamlOverride) 218 sqlutils.TxnSetZoneConfig(t, sqlDB, txn, "TABLE d.t", "") // this should pick up the overridden default config 219 if err := txn.Commit(); err != nil { 220 t.Fatal(err) 221 } 222 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE d.t", tableRow) 223 224 sqlDB.Exec(t, "DROP TABLE d.t") 225 _, err = db.Exec("SHOW ZONE CONFIGURATION FOR TABLE d.t") 226 if !testutils.IsError(err, `relation "d.t" does not exist`) { 227 t.Errorf("expected SHOW ZONE CONFIGURATION to fail on dropped table, but got %q", err) 228 } 229 sqlutils.VerifyAllZoneConfigs(t, sqlDB, defaultOverrideRow, partialSystemRow, partialJobsRow) 230 } 231 232 func TestZoneInheritField(t *testing.T) { 233 defer leaktest.AfterTest(t)() 234 235 params, _ := tests.CreateTestServerParams() 236 s, db, _ := serverutils.StartServer(t, params) 237 defer s.Stopper().Stop(context.Background()) 238 239 sqlDB := sqlutils.MakeSQLRunner(db) 240 sqlutils.RemoveAllZoneConfigs(t, sqlDB) 241 sqlDB.Exec(t, `CREATE DATABASE d; USE d; CREATE TABLE t ();`) 242 243 defaultRow := sqlutils.ZoneRow{ 244 ID: keys.RootNamespaceID, 245 Config: s.(*server.TestServer).Cfg.DefaultZoneConfig, 246 } 247 248 newReplicationFactor := 10 249 tableID := sqlutils.QueryTableID(t, db, "d", "public", "t") 250 newDefCfg := s.(*server.TestServer).Cfg.DefaultZoneConfig 251 newDefCfg.NumReplicas = proto.Int32(int32(newReplicationFactor)) 252 253 newDefaultRow := sqlutils.ZoneRow{ 254 ID: keys.RootNamespaceID, 255 Config: newDefCfg, 256 } 257 258 newTableRow := sqlutils.ZoneRow{ 259 ID: tableID, 260 Config: s.(*server.TestServer).Cfg.DefaultZoneConfig, 261 } 262 263 // Doesn't have any values of its own. 264 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE t", defaultRow) 265 266 // Solidify the num replicas value. 267 sqlDB.Exec(t, `ALTER TABLE t CONFIGURE ZONE USING num_replicas = COPY FROM PARENT`) 268 269 // Change the default replication factor. 270 sqlDB.Exec(t, fmt.Sprintf("ALTER RANGE default CONFIGURE ZONE USING num_replicas = %d", 271 newReplicationFactor)) 272 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "DATABASE d", newDefaultRow) 273 274 // Verify the table didn't take on the new value for the replication factor. 275 sqlutils.VerifyZoneConfigForTarget(t, sqlDB, "TABLE t", newTableRow) 276 } 277 278 func TestInvalidSetShowZones(t *testing.T) { 279 defer leaktest.AfterTest(t)() 280 281 params, _ := tests.CreateTestServerParams() 282 s, db, _ := serverutils.StartServer(t, params) 283 defer s.Stopper().Stop(context.Background()) 284 285 for i, tc := range []struct { 286 query string 287 err string 288 }{ 289 { 290 "ALTER RANGE default CONFIGURE ZONE DISCARD", 291 "cannot remove default zone", 292 }, 293 { 294 "ALTER RANGE default CONFIGURE ZONE = '&!@*@&'", 295 "could not parse zone config", 296 }, 297 { 298 "ALTER TABLE system.namespace CONFIGURE ZONE USING DEFAULT", 299 "cannot set zone configs for system config tables", 300 }, 301 { 302 "ALTER RANGE foo CONFIGURE ZONE USING DEFAULT", 303 `"foo" is not a built-in zone`, 304 }, 305 { 306 "ALTER DATABASE foo CONFIGURE ZONE USING DEFAULT", 307 `database "foo" does not exist`, 308 }, 309 { 310 "ALTER TABLE system.foo CONFIGURE ZONE USING DEFAULT", 311 `relation "system.foo" does not exist`, 312 }, 313 { 314 "ALTER TABLE foo CONFIGURE ZONE USING DEFAULT", 315 `relation "foo" does not exist`, 316 }, 317 { 318 "SHOW ZONE CONFIGURATION FOR RANGE foo", 319 `"foo" is not a built-in zone`, 320 }, 321 { 322 "SHOW ZONE CONFIGURATION FOR DATABASE foo", 323 `database "foo" does not exist`, 324 }, 325 { 326 "SHOW ZONE CONFIGURATION FOR TABLE foo", 327 `relation "foo" does not exist`, 328 }, 329 { 330 "SHOW ZONE CONFIGURATION FOR TABLE system.foo", 331 `relation "system.foo" does not exist`, 332 }, 333 } { 334 if _, err := db.Exec(tc.query); !testutils.IsError(err, tc.err) { 335 t.Errorf("#%d: expected error matching %q, but got %v", i, tc.err, err) 336 } 337 } 338 }