github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/system.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 sqlbase
    12  
    13  import (
    14  	"fmt"
    15  	"math"
    16  	"time"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/config/zonepb"
    19  	"github.com/cockroachdb/cockroach/pkg/keys"
    20  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    21  	"github.com/cockroachdb/cockroach/pkg/security"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    24  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    25  )
    26  
    27  // ShouldSplitAtDesc determines whether a specific descriptor should be
    28  // considered for a split. Only plain tables are considered for split.
    29  func ShouldSplitAtDesc(rawDesc *roachpb.Value) bool {
    30  	var desc Descriptor
    31  	if err := rawDesc.GetProto(&desc); err != nil {
    32  		return false
    33  	}
    34  	switch t := desc.GetUnion().(type) {
    35  	case *Descriptor_Table:
    36  		if t.Table.IsView() {
    37  			return false
    38  		}
    39  		return true
    40  	case *Descriptor_Database:
    41  		return false
    42  	case *Descriptor_Type:
    43  		return false
    44  	case *Descriptor_Schema:
    45  		return false
    46  	default:
    47  		panic(fmt.Sprintf("unexpected descriptor type %#v", &desc))
    48  	}
    49  }
    50  
    51  // sql CREATE commands and full schema for each system table.
    52  // These strings are *not* used at runtime, but are checked by the
    53  // `TestSystemTableLiterals` test that compares the table generated by
    54  // evaluating the `CREATE TABLE` statement to the descriptor literal that is
    55  // actually used at runtime.
    56  
    57  // These system tables are part of the system config.
    58  const (
    59  	NamespaceTableSchema = `
    60  CREATE TABLE system.namespace2 (
    61    "parentID" INT8,
    62    "parentSchemaID" INT8,
    63    name       STRING,
    64    id         INT8,
    65    PRIMARY KEY ("parentID", "parentSchemaID", name)
    66  );`
    67  
    68  	DescriptorTableSchema = `
    69  CREATE TABLE system.descriptor (
    70    id         INT8 PRIMARY KEY,
    71    descriptor BYTES
    72  );`
    73  
    74  	UsersTableSchema = `
    75  CREATE TABLE system.users (
    76    username         STRING PRIMARY KEY,
    77    "hashedPassword" BYTES,
    78    "isRole"         BOOL NOT NULL DEFAULT false
    79  );`
    80  
    81  	RoleOptionsTableSchema = `
    82  CREATE TABLE system.role_options (
    83  	username STRING NOT NULL,
    84  	option STRING NOT NULL,
    85  	value STRING,
    86  	PRIMARY KEY (username, option),
    87  	FAMILY "primary" (username, option, value)
    88  )`
    89  
    90  	// Zone settings per DB/Table.
    91  	ZonesTableSchema = `
    92  CREATE TABLE system.zones (
    93    id     INT8 PRIMARY KEY,
    94    config BYTES
    95  );`
    96  
    97  	SettingsTableSchema = `
    98  CREATE TABLE system.settings (
    99  	name              STRING    NOT NULL PRIMARY KEY,
   100  	value             STRING    NOT NULL,
   101  	"lastUpdated"     TIMESTAMP NOT NULL DEFAULT now(),
   102  	"valueType"       STRING,
   103  	FAMILY (name, value, "lastUpdated", "valueType")
   104  );`
   105  
   106  	DescIDSequenceSchema = `
   107  CREATE SEQUENCE system.descriptor_id_seq;`
   108  
   109  	TenantsTableSchema = `
   110  CREATE TABLE system.tenants (
   111  	id     INT8 NOT NULL PRIMARY KEY,
   112  	active BOOL NOT NULL DEFAULT true,
   113  	info   BYTES,
   114  	FAMILY "primary" (id, active, info)
   115  );`
   116  )
   117  
   118  // These system tables are not part of the system config.
   119  const (
   120  	LeaseTableSchema = `
   121  CREATE TABLE system.lease (
   122    "descID"   INT8,
   123    version    INT8,
   124    "nodeID"   INT8,
   125    expiration TIMESTAMP,
   126    PRIMARY KEY ("descID", version, expiration, "nodeID")
   127  );`
   128  
   129  	EventLogTableSchema = `
   130  CREATE TABLE system.eventlog (
   131    timestamp     TIMESTAMP  NOT NULL,
   132    "eventType"   STRING     NOT NULL,
   133    "targetID"    INT8       NOT NULL,
   134    "reportingID" INT8       NOT NULL,
   135    info          STRING,
   136    "uniqueID"    BYTES      DEFAULT uuid_v4(),
   137    PRIMARY KEY (timestamp, "uniqueID")
   138  );`
   139  
   140  	// rangelog is currently envisioned as a wide table; many different event
   141  	// types can be recorded to the table.
   142  	RangeEventTableSchema = `
   143  CREATE TABLE system.rangelog (
   144    timestamp      TIMESTAMP  NOT NULL,
   145    "rangeID"      INT8       NOT NULL,
   146    "storeID"      INT8       NOT NULL,
   147    "eventType"    STRING     NOT NULL,
   148    "otherRangeID" INT8,
   149    info           STRING,
   150    "uniqueID"     INT8       DEFAULT unique_rowid(),
   151    PRIMARY KEY (timestamp, "uniqueID")
   152  );`
   153  
   154  	UITableSchema = `
   155  CREATE TABLE system.ui (
   156  	key           STRING PRIMARY KEY,
   157  	value         BYTES,
   158  	"lastUpdated" TIMESTAMP NOT NULL
   159  );`
   160  
   161  	// Note: this schema is changed in a migration (a progress column is added in
   162  	// a separate family).
   163  	// NB: main column family uses old, pre created_by_type/created_by_id columns, named.
   164  	// This is done to minimize migration work required.
   165  	JobsTableSchema = `
   166  CREATE TABLE system.jobs (
   167  	id                INT8      DEFAULT unique_rowid() PRIMARY KEY,
   168  	status            STRING    NOT NULL,
   169  	created           TIMESTAMP NOT NULL DEFAULT now(),
   170  	payload           BYTES     NOT NULL,
   171  	progress          BYTES,
   172  	created_by_type   STRING,
   173  	created_by_id     INT,
   174  	INDEX (status, created),
   175  	INDEX (created_by_type, created_by_id) STORING (status),
   176  
   177  	FAMILY fam_0_id_status_created_payload (id, status, created, payload, created_by_type, created_by_id),
   178  	FAMILY progress (progress)
   179  );`
   180  
   181  	// web_sessions are used to track authenticated user actions over stateless
   182  	// connections, such as the cookie-based authentication used by the Admin
   183  	// UI.
   184  	// Design outlined in /docs/RFCS/web_session_login.rfc
   185  	WebSessionsTableSchema = `
   186  CREATE TABLE system.web_sessions (
   187  	id             INT8       NOT NULL DEFAULT unique_rowid() PRIMARY KEY,
   188  	"hashedSecret" BYTES      NOT NULL,
   189  	username       STRING     NOT NULL,
   190  	"createdAt"    TIMESTAMP  NOT NULL DEFAULT now(),
   191  	"expiresAt"    TIMESTAMP  NOT NULL,
   192  	"revokedAt"    TIMESTAMP,
   193  	"lastUsedAt"   TIMESTAMP  NOT NULL DEFAULT now(),
   194  	"auditInfo"    STRING,
   195  	INDEX ("expiresAt"),
   196  	INDEX ("createdAt"),
   197  	FAMILY (id, "hashedSecret", username, "createdAt", "expiresAt", "revokedAt", "lastUsedAt", "auditInfo")
   198  );`
   199  
   200  	// table_statistics is used to track statistics collected about individual columns
   201  	// or groups of columns from every table in the database. Each row contains the
   202  	// number of distinct values of the column group and (optionally) a histogram if there
   203  	// is only one column in columnIDs.
   204  	//
   205  	// Design outlined in /docs/RFCS/20170908_sql_optimizer_statistics.md
   206  	TableStatisticsTableSchema = `
   207  CREATE TABLE system.table_statistics (
   208  	"tableID"       INT8       NOT NULL,
   209  	"statisticID"   INT8       NOT NULL DEFAULT unique_rowid(),
   210  	name            STRING,
   211  	"columnIDs"     INT8[]     NOT NULL,
   212  	"createdAt"     TIMESTAMP  NOT NULL DEFAULT now(),
   213  	"rowCount"      INT8       NOT NULL,
   214  	"distinctCount" INT8       NOT NULL,
   215  	"nullCount"     INT8       NOT NULL,
   216  	histogram       BYTES,
   217  	PRIMARY KEY ("tableID", "statisticID"),
   218  	FAMILY ("tableID", "statisticID", name, "columnIDs", "createdAt", "rowCount", "distinctCount", "nullCount", histogram)
   219  );`
   220  
   221  	// locations are used to map a locality specified by a node to geographic
   222  	// latitude, longitude coordinates, specified as degrees.
   223  	LocationsTableSchema = `
   224  CREATE TABLE system.locations (
   225    "localityKey"   STRING,
   226    "localityValue" STRING,
   227    latitude        DECIMAL(18,15) NOT NULL,
   228    longitude       DECIMAL(18,15) NOT NULL,
   229    PRIMARY KEY ("localityKey", "localityValue"),
   230    FAMILY ("localityKey", "localityValue", latitude, longitude)
   231  );`
   232  
   233  	// role_members stores relationships between roles (role->role and role->user).
   234  	RoleMembersTableSchema = `
   235  CREATE TABLE system.role_members (
   236    "role"   STRING NOT NULL,
   237    "member" STRING NOT NULL,
   238    "isAdmin"  BOOL NOT NULL,
   239    PRIMARY KEY  ("role", "member"),
   240    INDEX ("role"),
   241    INDEX ("member")
   242  );`
   243  
   244  	// comments stores comments(database, table, column...).
   245  	CommentsTableSchema = `
   246  CREATE TABLE system.comments (
   247     type      INT NOT NULL,    -- type of object, to distinguish between db, table, column and others
   248     object_id INT NOT NULL,    -- object ID, this will be usually db/table desc ID
   249     sub_id    INT NOT NULL,    -- sub ID for column or indexes inside table, 0 for pure table
   250     comment   STRING NOT NULL, -- the comment
   251     PRIMARY KEY (type, object_id, sub_id)
   252  );`
   253  
   254  	// protected_ts_meta stores a single row of metadata for the protectedts
   255  	// subsystem.
   256  	ProtectedTimestampsMetaTableSchema = `
   257  CREATE TABLE system.protected_ts_meta (
   258     singleton   BOOL NOT NULL PRIMARY KEY DEFAULT (true),
   259     version     INT8 NOT NULL,
   260     num_records INT8 NOT NULL,
   261     num_spans   INT8 NOT NULL,
   262     total_bytes INT8 NOT NULL,
   263     CONSTRAINT check_singleton  CHECK (singleton),
   264     FAMILY "primary" (singleton, version, num_records, num_spans, total_bytes)
   265  );`
   266  
   267  	ProtectedTimestampsRecordsTableSchema = `
   268  CREATE TABLE system.protected_ts_records (
   269     id        UUID NOT NULL PRIMARY KEY,
   270     ts        DECIMAL NOT NULL,
   271     meta_type STRING NOT NULL,
   272     meta      BYTES,
   273     num_spans INT8 NOT NULL, -- num spans is important to know how to decode spans
   274     spans     BYTES NOT NULL,
   275     verified  BOOL NOT NULL DEFAULT (false),
   276     FAMILY "primary" (id, ts, meta_type, meta, num_spans, spans, verified)
   277  );`
   278  
   279  	StatementBundleChunksTableSchema = `
   280  CREATE TABLE system.statement_bundle_chunks (
   281     id          INT8 PRIMARY KEY DEFAULT unique_rowid(),
   282  	 description STRING,
   283  	 data        BYTES NOT NULL,
   284  
   285     FAMILY "primary" (id, description, data)
   286  );`
   287  
   288  	StatementDiagnosticsRequestsTableSchema = `
   289  CREATE TABLE system.statement_diagnostics_requests(
   290  	id INT8 DEFAULT unique_rowid() PRIMARY KEY NOT NULL,
   291  	completed BOOL NOT NULL DEFAULT FALSE,
   292  	statement_fingerprint STRING NOT NULL,
   293  	statement_diagnostics_id INT8,
   294  	requested_at TIMESTAMPTZ NOT NULL,
   295  	INDEX completed_idx (completed, id) STORING (statement_fingerprint),
   296  
   297  	FAMILY "primary" (id, completed, statement_fingerprint, statement_diagnostics_id, requested_at)
   298  );`
   299  
   300  	StatementDiagnosticsTableSchema = `
   301  create table system.statement_diagnostics(
   302    id INT8 DEFAULT unique_rowid() PRIMARY KEY NOT NULL,
   303    statement_fingerprint STRING NOT NULL,
   304    statement STRING NOT NULL,
   305    collected_at TIMESTAMPTZ NOT NULL,
   306    trace JSONB,
   307    bundle_chunks INT ARRAY,
   308  	error STRING,
   309  
   310  	FAMILY "primary" (id, statement_fingerprint, statement, collected_at, trace, bundle_chunks, error)
   311  );`
   312  )
   313  
   314  func pk(name string) IndexDescriptor {
   315  	return IndexDescriptor{
   316  		Name:             PrimaryKeyIndexName,
   317  		ID:               1,
   318  		Unique:           true,
   319  		ColumnNames:      []string{name},
   320  		ColumnDirections: singleASC,
   321  		ColumnIDs:        singleID1,
   322  		Version:          SecondaryIndexFamilyFormatVersion,
   323  	}
   324  }
   325  
   326  // SystemAllowedPrivileges describes the allowable privilege list for each
   327  // system object. Super users (root and admin) must have exactly the specified privileges,
   328  // other users must not exceed the specified privileges.
   329  var SystemAllowedPrivileges = map[ID]privilege.List{
   330  	keys.SystemDatabaseID:           privilege.ReadData,
   331  	keys.NamespaceTableID:           privilege.ReadData,
   332  	keys.DeprecatedNamespaceTableID: privilege.ReadData,
   333  	keys.DescriptorTableID:          privilege.ReadData,
   334  	keys.UsersTableID:               privilege.ReadWriteData,
   335  	keys.RoleOptionsTableID:         privilege.ReadWriteData,
   336  	keys.ZonesTableID:               privilege.ReadWriteData,
   337  	// We eventually want to migrate the table to appear read-only to force the
   338  	// the use of a validating, logging accessor, so we'll go ahead and tolerate
   339  	// read-only privs to make that migration possible later.
   340  	keys.SettingsTableID:   privilege.ReadWriteData,
   341  	keys.DescIDSequenceID:  privilege.ReadData,
   342  	keys.TenantsTableID:    privilege.ReadData,
   343  	keys.LeaseTableID:      privilege.ReadWriteData,
   344  	keys.EventLogTableID:   privilege.ReadWriteData,
   345  	keys.RangeEventTableID: privilege.ReadWriteData,
   346  	keys.UITableID:         privilege.ReadWriteData,
   347  	// IMPORTANT: CREATE|DROP|ALL privileges should always be denied or database
   348  	// users will be able to modify system tables' schemas at will. CREATE and
   349  	// DROP privileges are allowed on the above system tables for backwards
   350  	// compatibility reasons only!
   351  	keys.JobsTableID:                          privilege.ReadWriteData,
   352  	keys.WebSessionsTableID:                   privilege.ReadWriteData,
   353  	keys.TableStatisticsTableID:               privilege.ReadWriteData,
   354  	keys.LocationsTableID:                     privilege.ReadWriteData,
   355  	keys.RoleMembersTableID:                   privilege.ReadWriteData,
   356  	keys.CommentsTableID:                      privilege.ReadWriteData,
   357  	keys.ReplicationConstraintStatsTableID:    privilege.ReadWriteData,
   358  	keys.ReplicationCriticalLocalitiesTableID: privilege.ReadWriteData,
   359  	keys.ReplicationStatsTableID:              privilege.ReadWriteData,
   360  	keys.ReportsMetaTableID:                   privilege.ReadWriteData,
   361  	keys.ProtectedTimestampsMetaTableID:       privilege.ReadData,
   362  	keys.ProtectedTimestampsRecordsTableID:    privilege.ReadData,
   363  	keys.StatementBundleChunksTableID:         privilege.ReadWriteData,
   364  	keys.StatementDiagnosticsRequestsTableID:  privilege.ReadWriteData,
   365  	keys.StatementDiagnosticsTableID:          privilege.ReadWriteData,
   366  }
   367  
   368  // Helpers used to make some of the TableDescriptor literals below more concise.
   369  var (
   370  	singleASC = []IndexDescriptor_Direction{IndexDescriptor_ASC}
   371  	singleID1 = []ColumnID{1}
   372  )
   373  
   374  // MakeSystemDatabaseDesc constructs a copy of the system database
   375  // descriptor.
   376  func MakeSystemDatabaseDesc() DatabaseDescriptor {
   377  	return DatabaseDescriptor{
   378  		Name: "system",
   379  		ID:   keys.SystemDatabaseID,
   380  		// Assign max privileges to root user.
   381  		Privileges: NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.SystemDatabaseID]),
   382  	}
   383  }
   384  
   385  // These system config TableDescriptor literals should match the descriptor
   386  // that would be produced by evaluating one of the above `CREATE TABLE`
   387  // statements. See the `TestSystemTableLiterals` which checks that they do
   388  // indeed match, and has suggestions on writing and maintaining them.
   389  var (
   390  	// SystemDB is the descriptor for the system database.
   391  	SystemDB = MakeSystemDatabaseDesc()
   392  
   393  	// NamespaceTableName is "namespace", which is always and forever the
   394  	// user-visible name of the system.namespace table. Tautological, but
   395  	// important.
   396  	NamespaceTableName = "namespace"
   397  
   398  	// DeprecatedNamespaceTable is the descriptor for the deprecated namespace table.
   399  	DeprecatedNamespaceTable = TableDescriptor{
   400  		Name:                    NamespaceTableName,
   401  		ID:                      keys.DeprecatedNamespaceTableID,
   402  		ParentID:                keys.SystemDatabaseID,
   403  		UnexposedParentSchemaID: keys.PublicSchemaID,
   404  		Version:                 1,
   405  		Columns: []ColumnDescriptor{
   406  			{Name: "parentID", ID: 1, Type: types.Int},
   407  			{Name: "name", ID: 2, Type: types.String},
   408  			{Name: "id", ID: 3, Type: types.Int, Nullable: true},
   409  		},
   410  		NextColumnID: 4,
   411  		Families: []ColumnFamilyDescriptor{
   412  			{Name: "primary", ID: 0, ColumnNames: []string{"parentID", "name"}, ColumnIDs: []ColumnID{1, 2}},
   413  			{Name: "fam_3_id", ID: 3, ColumnNames: []string{"id"}, ColumnIDs: []ColumnID{3}, DefaultColumnID: 3},
   414  		},
   415  		NextFamilyID: 4,
   416  		PrimaryIndex: IndexDescriptor{
   417  			Name:             "primary",
   418  			ID:               1,
   419  			Unique:           true,
   420  			ColumnNames:      []string{"parentID", "name"},
   421  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   422  			ColumnIDs:        []ColumnID{1, 2},
   423  			Version:          SecondaryIndexFamilyFormatVersion,
   424  		},
   425  		NextIndexID:    2,
   426  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.DeprecatedNamespaceTableID]),
   427  		FormatVersion:  InterleavedFormatVersion,
   428  		NextMutationID: 1,
   429  	}
   430  
   431  	// NamespaceTable is the descriptor for the namespace table. Note that this
   432  	// table should only be written to via KV puts, not via the SQL layer. Some
   433  	// code assumes that it only has KV entries for column family 4, not the
   434  	// "sentinel" column family 0 which would be written by SQL.
   435  	//
   436  	// Note that the Descriptor.Name of this table is not "namespace", but
   437  	// something else. This is because, in 20.1, we moved the representation of
   438  	// namespaces to a new place, and for various reasons, we can't have two
   439  	// descriptors with the same Name at once.
   440  	//
   441  	// TODO(solon): in 20.2, we should change the Name of this descriptor
   442  	// back to "namespace".
   443  	NamespaceTable = TableDescriptor{
   444  		Name:                    "namespace2",
   445  		ID:                      keys.NamespaceTableID,
   446  		ParentID:                keys.SystemDatabaseID,
   447  		UnexposedParentSchemaID: keys.PublicSchemaID,
   448  		Version:                 1,
   449  		Columns: []ColumnDescriptor{
   450  			{Name: "parentID", ID: 1, Type: types.Int},
   451  			{Name: "parentSchemaID", ID: 2, Type: types.Int},
   452  			{Name: "name", ID: 3, Type: types.String},
   453  			{Name: "id", ID: 4, Type: types.Int, Nullable: true},
   454  		},
   455  		NextColumnID: 5,
   456  		Families: []ColumnFamilyDescriptor{
   457  			{Name: "primary", ID: 0, ColumnNames: []string{"parentID", "parentSchemaID", "name"}, ColumnIDs: []ColumnID{1, 2, 3}},
   458  			{Name: "fam_4_id", ID: 4, ColumnNames: []string{"id"}, ColumnIDs: []ColumnID{4}, DefaultColumnID: 4},
   459  		},
   460  		NextFamilyID: 5,
   461  		PrimaryIndex: IndexDescriptor{
   462  			Name:             "primary",
   463  			ID:               1,
   464  			Unique:           true,
   465  			ColumnNames:      []string{"parentID", "parentSchemaID", "name"},
   466  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC},
   467  			ColumnIDs:        []ColumnID{1, 2, 3},
   468  			Version:          SecondaryIndexFamilyFormatVersion,
   469  		},
   470  		NextIndexID:    2,
   471  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.DeprecatedNamespaceTableID]),
   472  		FormatVersion:  InterleavedFormatVersion,
   473  		NextMutationID: 1,
   474  	}
   475  
   476  	// DescriptorTable is the descriptor for the descriptor table.
   477  	DescriptorTable = TableDescriptor{
   478  		Name:                    "descriptor",
   479  		ID:                      keys.DescriptorTableID,
   480  		Privileges:              NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.DescriptorTableID]),
   481  		ParentID:                keys.SystemDatabaseID,
   482  		UnexposedParentSchemaID: keys.PublicSchemaID,
   483  		Version:                 1,
   484  		Columns: []ColumnDescriptor{
   485  			{Name: "id", ID: 1, Type: types.Int},
   486  			{Name: "descriptor", ID: keys.DescriptorTableDescriptorColID, Type: types.Bytes, Nullable: true},
   487  		},
   488  		NextColumnID: 3,
   489  		Families: []ColumnFamilyDescriptor{
   490  			// The id of the first col fam is hardcoded in keys.MakeDescMetadataKey().
   491  			{Name: "primary", ID: 0, ColumnNames: []string{"id"}, ColumnIDs: singleID1},
   492  			{Name: "fam_2_descriptor", ID: keys.DescriptorTableDescriptorColFamID,
   493  				ColumnNames: []string{"descriptor"},
   494  				ColumnIDs:   []ColumnID{keys.DescriptorTableDescriptorColID}, DefaultColumnID: keys.DescriptorTableDescriptorColID},
   495  		},
   496  		PrimaryIndex:   pk("id"),
   497  		NextFamilyID:   3,
   498  		NextIndexID:    2,
   499  		FormatVersion:  InterleavedFormatVersion,
   500  		NextMutationID: 1,
   501  	}
   502  
   503  	falseBoolString = "false"
   504  	trueBoolString  = "true"
   505  
   506  	// UsersTable is the descriptor for the users table.
   507  	UsersTable = TableDescriptor{
   508  		Name:                    "users",
   509  		ID:                      keys.UsersTableID,
   510  		ParentID:                keys.SystemDatabaseID,
   511  		UnexposedParentSchemaID: keys.PublicSchemaID,
   512  		Version:                 1,
   513  		Columns: []ColumnDescriptor{
   514  			{Name: "username", ID: 1, Type: types.String},
   515  			{Name: "hashedPassword", ID: 2, Type: types.Bytes, Nullable: true},
   516  			{Name: "isRole", ID: 3, Type: types.Bool, DefaultExpr: &falseBoolString},
   517  		},
   518  		NextColumnID: 4,
   519  		Families: []ColumnFamilyDescriptor{
   520  			{Name: "primary", ID: 0, ColumnNames: []string{"username"}, ColumnIDs: singleID1},
   521  			{Name: "fam_2_hashedPassword", ID: 2, ColumnNames: []string{"hashedPassword"}, ColumnIDs: []ColumnID{2}, DefaultColumnID: 2},
   522  			{Name: "fam_3_isRole", ID: 3, ColumnNames: []string{"isRole"}, ColumnIDs: []ColumnID{3}, DefaultColumnID: 3},
   523  		},
   524  		PrimaryIndex:   pk("username"),
   525  		NextFamilyID:   4,
   526  		NextIndexID:    2,
   527  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.UsersTableID]),
   528  		FormatVersion:  InterleavedFormatVersion,
   529  		NextMutationID: 1,
   530  	}
   531  
   532  	// ZonesTable is the descriptor for the zones table.
   533  	ZonesTable = TableDescriptor{
   534  		Name:                    "zones",
   535  		ID:                      keys.ZonesTableID,
   536  		ParentID:                keys.SystemDatabaseID,
   537  		UnexposedParentSchemaID: keys.PublicSchemaID,
   538  		Version:                 1,
   539  		Columns: []ColumnDescriptor{
   540  			{Name: "id", ID: 1, Type: types.Int},
   541  			{Name: "config", ID: keys.ZonesTableConfigColumnID, Type: types.Bytes, Nullable: true},
   542  		},
   543  		NextColumnID: 3,
   544  		Families: []ColumnFamilyDescriptor{
   545  			{Name: "primary", ID: 0, ColumnNames: []string{"id"}, ColumnIDs: singleID1},
   546  			{Name: "fam_2_config", ID: keys.ZonesTableConfigColFamID, ColumnNames: []string{"config"},
   547  				ColumnIDs: []ColumnID{keys.ZonesTableConfigColumnID}, DefaultColumnID: keys.ZonesTableConfigColumnID},
   548  		},
   549  		PrimaryIndex: IndexDescriptor{
   550  			Name:             "primary",
   551  			ID:               keys.ZonesTablePrimaryIndexID,
   552  			Unique:           true,
   553  			ColumnNames:      []string{"id"},
   554  			ColumnDirections: singleASC,
   555  			ColumnIDs:        []ColumnID{keys.ZonesTablePrimaryIndexID},
   556  			Version:          SecondaryIndexFamilyFormatVersion,
   557  		},
   558  		NextFamilyID:   3,
   559  		NextIndexID:    2,
   560  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ZonesTableID]),
   561  		FormatVersion:  InterleavedFormatVersion,
   562  		NextMutationID: 1,
   563  	}
   564  
   565  	// SettingsTable is the descriptor for the settings table.
   566  	// It contains all cluster settings for which a value has been set.
   567  	SettingsTable = TableDescriptor{
   568  		Name:                    "settings",
   569  		ID:                      keys.SettingsTableID,
   570  		ParentID:                keys.SystemDatabaseID,
   571  		UnexposedParentSchemaID: keys.PublicSchemaID,
   572  		Version:                 1,
   573  		Columns: []ColumnDescriptor{
   574  			{Name: "name", ID: 1, Type: types.String},
   575  			{Name: "value", ID: 2, Type: types.String},
   576  			{Name: "lastUpdated", ID: 3, Type: types.Timestamp, DefaultExpr: &nowString},
   577  			{Name: "valueType", ID: 4, Type: types.String, Nullable: true},
   578  		},
   579  		NextColumnID: 5,
   580  		Families: []ColumnFamilyDescriptor{
   581  			{
   582  				Name:        "fam_0_name_value_lastUpdated_valueType",
   583  				ID:          0,
   584  				ColumnNames: []string{"name", "value", "lastUpdated", "valueType"},
   585  				ColumnIDs:   []ColumnID{1, 2, 3, 4},
   586  			},
   587  		},
   588  		NextFamilyID:   1,
   589  		PrimaryIndex:   pk("name"),
   590  		NextIndexID:    2,
   591  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.SettingsTableID]),
   592  		FormatVersion:  InterleavedFormatVersion,
   593  		NextMutationID: 1,
   594  	}
   595  
   596  	// DescIDSequence is the descriptor for the descriptor ID sequence.
   597  	DescIDSequence = TableDescriptor{
   598  		Name:                    "descriptor_id_seq",
   599  		ID:                      keys.DescIDSequenceID,
   600  		ParentID:                keys.SystemDatabaseID,
   601  		UnexposedParentSchemaID: keys.PublicSchemaID,
   602  		Version:                 1,
   603  		Columns: []ColumnDescriptor{
   604  			{Name: SequenceColumnName, ID: SequenceColumnID, Type: types.Int},
   605  		},
   606  		Families: []ColumnFamilyDescriptor{{
   607  			Name:            "primary",
   608  			ID:              keys.SequenceColumnFamilyID,
   609  			ColumnNames:     []string{SequenceColumnName},
   610  			ColumnIDs:       []ColumnID{SequenceColumnID},
   611  			DefaultColumnID: SequenceColumnID,
   612  		}},
   613  		PrimaryIndex: IndexDescriptor{
   614  			ID:               keys.SequenceIndexID,
   615  			Name:             PrimaryKeyIndexName,
   616  			ColumnIDs:        []ColumnID{SequenceColumnID},
   617  			ColumnNames:      []string{SequenceColumnName},
   618  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   619  		},
   620  		SequenceOpts: &TableDescriptor_SequenceOpts{
   621  			Increment: 1,
   622  			MinValue:  1,
   623  			MaxValue:  math.MaxInt64,
   624  			Start:     1,
   625  		},
   626  		Privileges:    NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.DescIDSequenceID]),
   627  		FormatVersion: InterleavedFormatVersion,
   628  	}
   629  
   630  	TenantsTable = TableDescriptor{
   631  		Name:                    "tenants",
   632  		ID:                      keys.TenantsTableID,
   633  		ParentID:                keys.SystemDatabaseID,
   634  		UnexposedParentSchemaID: keys.PublicSchemaID,
   635  		Version:                 1,
   636  		Columns: []ColumnDescriptor{
   637  			{Name: "id", ID: 1, Type: types.Int},
   638  			{Name: "active", ID: 2, Type: types.Bool, DefaultExpr: &trueBoolString},
   639  			// NOTE: info is currently a placeholder and may be kept, replaced,
   640  			// or even just removed. The idea is to provide users of
   641  			// multi-tenancy with some ability to store associated metadata with
   642  			// each tenant. For instance, it might prove to be useful to map a
   643  			// tenant in a cluster back to the corresponding user ID in CC.
   644  			{Name: "info", ID: 3, Type: types.Bytes, Nullable: true},
   645  		},
   646  		NextColumnID: 4,
   647  		Families: []ColumnFamilyDescriptor{{
   648  			Name:        "primary",
   649  			ID:          0,
   650  			ColumnNames: []string{"id", "active", "info"},
   651  			ColumnIDs:   []ColumnID{1, 2, 3},
   652  		}},
   653  		NextFamilyID:   1,
   654  		PrimaryIndex:   pk("id"),
   655  		NextIndexID:    2,
   656  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.TenantsTableID]),
   657  		FormatVersion:  InterleavedFormatVersion,
   658  		NextMutationID: 1,
   659  	}
   660  )
   661  
   662  // These system TableDescriptor literals should match the descriptor that
   663  // would be produced by evaluating one of the above `CREATE TABLE` statements
   664  // for system tables that are not system config tables. See the
   665  // `TestSystemTableLiterals` which checks that they do indeed match, and has
   666  // suggestions on writing and maintaining them.
   667  var (
   668  	// LeaseTable is the descriptor for the leases table.
   669  	LeaseTable = TableDescriptor{
   670  		Name:                    "lease",
   671  		ID:                      keys.LeaseTableID,
   672  		ParentID:                keys.SystemDatabaseID,
   673  		UnexposedParentSchemaID: keys.PublicSchemaID,
   674  		Version:                 1,
   675  		Columns: []ColumnDescriptor{
   676  			{Name: "descID", ID: 1, Type: types.Int},
   677  			{Name: "version", ID: 2, Type: types.Int},
   678  			{Name: "nodeID", ID: 3, Type: types.Int},
   679  			{Name: "expiration", ID: 4, Type: types.Timestamp},
   680  		},
   681  		NextColumnID: 5,
   682  		Families: []ColumnFamilyDescriptor{
   683  			{Name: "primary", ID: 0, ColumnNames: []string{"descID", "version", "nodeID", "expiration"}, ColumnIDs: []ColumnID{1, 2, 3, 4}},
   684  		},
   685  		PrimaryIndex: IndexDescriptor{
   686  			Name:             "primary",
   687  			ID:               1,
   688  			Unique:           true,
   689  			ColumnNames:      []string{"descID", "version", "expiration", "nodeID"},
   690  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC},
   691  			ColumnIDs:        []ColumnID{1, 2, 4, 3},
   692  			Version:          SecondaryIndexFamilyFormatVersion,
   693  		},
   694  		NextFamilyID:   1,
   695  		NextIndexID:    2,
   696  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.LeaseTableID]),
   697  		FormatVersion:  InterleavedFormatVersion,
   698  		NextMutationID: 1,
   699  	}
   700  
   701  	uuidV4String = "uuid_v4()"
   702  
   703  	// EventLogTable is the descriptor for the event log table.
   704  	EventLogTable = TableDescriptor{
   705  		Name:                    "eventlog",
   706  		ID:                      keys.EventLogTableID,
   707  		ParentID:                keys.SystemDatabaseID,
   708  		UnexposedParentSchemaID: keys.PublicSchemaID,
   709  		Version:                 1,
   710  		Columns: []ColumnDescriptor{
   711  			{Name: "timestamp", ID: 1, Type: types.Timestamp},
   712  			{Name: "eventType", ID: 2, Type: types.String},
   713  			{Name: "targetID", ID: 3, Type: types.Int},
   714  			{Name: "reportingID", ID: 4, Type: types.Int},
   715  			{Name: "info", ID: 5, Type: types.String, Nullable: true},
   716  			{Name: "uniqueID", ID: 6, Type: types.Bytes, DefaultExpr: &uuidV4String},
   717  		},
   718  		NextColumnID: 7,
   719  		Families: []ColumnFamilyDescriptor{
   720  			{Name: "primary", ID: 0, ColumnNames: []string{"timestamp", "uniqueID"}, ColumnIDs: []ColumnID{1, 6}},
   721  			{Name: "fam_2_eventType", ID: 2, ColumnNames: []string{"eventType"}, ColumnIDs: []ColumnID{2}, DefaultColumnID: 2},
   722  			{Name: "fam_3_targetID", ID: 3, ColumnNames: []string{"targetID"}, ColumnIDs: []ColumnID{3}, DefaultColumnID: 3},
   723  			{Name: "fam_4_reportingID", ID: 4, ColumnNames: []string{"reportingID"}, ColumnIDs: []ColumnID{4}, DefaultColumnID: 4},
   724  			{Name: "fam_5_info", ID: 5, ColumnNames: []string{"info"}, ColumnIDs: []ColumnID{5}, DefaultColumnID: 5},
   725  		},
   726  		PrimaryIndex: IndexDescriptor{
   727  			Name:             "primary",
   728  			ID:               1,
   729  			Unique:           true,
   730  			ColumnNames:      []string{"timestamp", "uniqueID"},
   731  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   732  			ColumnIDs:        []ColumnID{1, 6},
   733  			Version:          SecondaryIndexFamilyFormatVersion,
   734  		},
   735  		NextFamilyID:   6,
   736  		NextIndexID:    2,
   737  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.EventLogTableID]),
   738  		FormatVersion:  InterleavedFormatVersion,
   739  		NextMutationID: 1,
   740  	}
   741  
   742  	uniqueRowIDString = "unique_rowid()"
   743  
   744  	// RangeEventTable is the descriptor for the range log table.
   745  	RangeEventTable = TableDescriptor{
   746  		Name:                    "rangelog",
   747  		ID:                      keys.RangeEventTableID,
   748  		ParentID:                keys.SystemDatabaseID,
   749  		UnexposedParentSchemaID: keys.PublicSchemaID,
   750  		Version:                 1,
   751  		Columns: []ColumnDescriptor{
   752  			{Name: "timestamp", ID: 1, Type: types.Timestamp},
   753  			{Name: "rangeID", ID: 2, Type: types.Int},
   754  			{Name: "storeID", ID: 3, Type: types.Int},
   755  			{Name: "eventType", ID: 4, Type: types.String},
   756  			{Name: "otherRangeID", ID: 5, Type: types.Int, Nullable: true},
   757  			{Name: "info", ID: 6, Type: types.String, Nullable: true},
   758  			{Name: "uniqueID", ID: 7, Type: types.Int, DefaultExpr: &uniqueRowIDString},
   759  		},
   760  		NextColumnID: 8,
   761  		Families: []ColumnFamilyDescriptor{
   762  			{Name: "primary", ID: 0, ColumnNames: []string{"timestamp", "uniqueID"}, ColumnIDs: []ColumnID{1, 7}},
   763  			{Name: "fam_2_rangeID", ID: 2, ColumnNames: []string{"rangeID"}, ColumnIDs: []ColumnID{2}, DefaultColumnID: 2},
   764  			{Name: "fam_3_storeID", ID: 3, ColumnNames: []string{"storeID"}, ColumnIDs: []ColumnID{3}, DefaultColumnID: 3},
   765  			{Name: "fam_4_eventType", ID: 4, ColumnNames: []string{"eventType"}, ColumnIDs: []ColumnID{4}, DefaultColumnID: 4},
   766  			{Name: "fam_5_otherRangeID", ID: 5, ColumnNames: []string{"otherRangeID"}, ColumnIDs: []ColumnID{5}, DefaultColumnID: 5},
   767  			{Name: "fam_6_info", ID: 6, ColumnNames: []string{"info"}, ColumnIDs: []ColumnID{6}, DefaultColumnID: 6},
   768  		},
   769  		PrimaryIndex: IndexDescriptor{
   770  			Name:             "primary",
   771  			ID:               1,
   772  			Unique:           true,
   773  			ColumnNames:      []string{"timestamp", "uniqueID"},
   774  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   775  			ColumnIDs:        []ColumnID{1, 7},
   776  			Version:          SecondaryIndexFamilyFormatVersion,
   777  		},
   778  		NextFamilyID:   7,
   779  		NextIndexID:    2,
   780  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.RangeEventTableID]),
   781  		FormatVersion:  InterleavedFormatVersion,
   782  		NextMutationID: 1,
   783  	}
   784  
   785  	// UITable is the descriptor for the ui table.
   786  	UITable = TableDescriptor{
   787  		Name:                    "ui",
   788  		ID:                      keys.UITableID,
   789  		ParentID:                keys.SystemDatabaseID,
   790  		UnexposedParentSchemaID: keys.PublicSchemaID,
   791  		Version:                 1,
   792  		Columns: []ColumnDescriptor{
   793  			{Name: "key", ID: 1, Type: types.String},
   794  			{Name: "value", ID: 2, Type: types.Bytes, Nullable: true},
   795  			{Name: "lastUpdated", ID: 3, Type: types.Timestamp},
   796  		},
   797  		NextColumnID: 4,
   798  		Families: []ColumnFamilyDescriptor{
   799  			{Name: "primary", ID: 0, ColumnNames: []string{"key"}, ColumnIDs: singleID1},
   800  			{Name: "fam_2_value", ID: 2, ColumnNames: []string{"value"}, ColumnIDs: []ColumnID{2}, DefaultColumnID: 2},
   801  			{Name: "fam_3_lastUpdated", ID: 3, ColumnNames: []string{"lastUpdated"}, ColumnIDs: []ColumnID{3}, DefaultColumnID: 3},
   802  		},
   803  		NextFamilyID:   4,
   804  		PrimaryIndex:   pk("key"),
   805  		NextIndexID:    2,
   806  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.UITableID]),
   807  		FormatVersion:  InterleavedFormatVersion,
   808  		NextMutationID: 1,
   809  	}
   810  
   811  	nowString = "now():::TIMESTAMP"
   812  
   813  	// JobsTable is the descriptor for the jobs table.
   814  	JobsTable = TableDescriptor{
   815  		Name:                    "jobs",
   816  		ID:                      keys.JobsTableID,
   817  		ParentID:                keys.SystemDatabaseID,
   818  		UnexposedParentSchemaID: keys.PublicSchemaID,
   819  		Version:                 1,
   820  		Columns: []ColumnDescriptor{
   821  			{Name: "id", ID: 1, Type: types.Int, DefaultExpr: &uniqueRowIDString},
   822  			{Name: "status", ID: 2, Type: types.String},
   823  			{Name: "created", ID: 3, Type: types.Timestamp, DefaultExpr: &nowString},
   824  			{Name: "payload", ID: 4, Type: types.Bytes},
   825  			{Name: "progress", ID: 5, Type: types.Bytes, Nullable: true},
   826  			{Name: "created_by_type", ID: 6, Type: types.String, Nullable: true},
   827  			{Name: "created_by_id", ID: 7, Type: types.Int, Nullable: true},
   828  		},
   829  		NextColumnID: 8,
   830  		Families: []ColumnFamilyDescriptor{
   831  			{
   832  				// NB: We are using family name that existed prior to adding created_by_type and
   833  				// created_by_id columns.  This is done to minimize and simplify migration work
   834  				// that needed to be done.
   835  				Name:        "fam_0_id_status_created_payload",
   836  				ID:          0,
   837  				ColumnNames: []string{"id", "status", "created", "payload", "created_by_type", "created_by_id"},
   838  				ColumnIDs:   []ColumnID{1, 2, 3, 4, 6, 7},
   839  			},
   840  			{
   841  				Name:            "progress",
   842  				ID:              1,
   843  				ColumnNames:     []string{"progress"},
   844  				ColumnIDs:       []ColumnID{5},
   845  				DefaultColumnID: 5,
   846  			},
   847  		},
   848  		NextFamilyID: 2,
   849  		PrimaryIndex: pk("id"),
   850  		Indexes: []IndexDescriptor{
   851  			{
   852  				Name:             "jobs_status_created_idx",
   853  				ID:               2,
   854  				Unique:           false,
   855  				ColumnNames:      []string{"status", "created"},
   856  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   857  				ColumnIDs:        []ColumnID{2, 3},
   858  				ExtraColumnIDs:   []ColumnID{1},
   859  				Version:          SecondaryIndexFamilyFormatVersion,
   860  			},
   861  			{
   862  				Name:             "jobs_created_by_type_created_by_id_idx",
   863  				ID:               3,
   864  				Unique:           false,
   865  				ColumnNames:      []string{"created_by_type", "created_by_id"},
   866  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   867  				ColumnIDs:        []ColumnID{6, 7},
   868  				StoreColumnIDs:   []ColumnID{2},
   869  				StoreColumnNames: []string{"status"},
   870  				ExtraColumnIDs:   []ColumnID{1},
   871  				Version:          SecondaryIndexFamilyFormatVersion,
   872  			},
   873  		},
   874  		NextIndexID:    4,
   875  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.JobsTableID]),
   876  		FormatVersion:  InterleavedFormatVersion,
   877  		NextMutationID: 1,
   878  	}
   879  
   880  	// WebSessions table to authenticate sessions over stateless connections.
   881  	WebSessionsTable = TableDescriptor{
   882  		Name:                    "web_sessions",
   883  		ID:                      keys.WebSessionsTableID,
   884  		ParentID:                keys.SystemDatabaseID,
   885  		UnexposedParentSchemaID: keys.PublicSchemaID,
   886  		Version:                 1,
   887  		Columns: []ColumnDescriptor{
   888  			{Name: "id", ID: 1, Type: types.Int, DefaultExpr: &uniqueRowIDString},
   889  			{Name: "hashedSecret", ID: 2, Type: types.Bytes},
   890  			{Name: "username", ID: 3, Type: types.String},
   891  			{Name: "createdAt", ID: 4, Type: types.Timestamp, DefaultExpr: &nowString},
   892  			{Name: "expiresAt", ID: 5, Type: types.Timestamp},
   893  			{Name: "revokedAt", ID: 6, Type: types.Timestamp, Nullable: true},
   894  			{Name: "lastUsedAt", ID: 7, Type: types.Timestamp, DefaultExpr: &nowString},
   895  			{Name: "auditInfo", ID: 8, Type: types.String, Nullable: true},
   896  		},
   897  		NextColumnID: 9,
   898  		Families: []ColumnFamilyDescriptor{
   899  			{
   900  				Name: "fam_0_id_hashedSecret_username_createdAt_expiresAt_revokedAt_lastUsedAt_auditInfo",
   901  				ID:   0,
   902  				ColumnNames: []string{
   903  					"id",
   904  					"hashedSecret",
   905  					"username",
   906  					"createdAt",
   907  					"expiresAt",
   908  					"revokedAt",
   909  					"lastUsedAt",
   910  					"auditInfo",
   911  				},
   912  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5, 6, 7, 8},
   913  			},
   914  		},
   915  		NextFamilyID: 1,
   916  		PrimaryIndex: pk("id"),
   917  		Indexes: []IndexDescriptor{
   918  			{
   919  				Name:             "web_sessions_expiresAt_idx",
   920  				ID:               2,
   921  				Unique:           false,
   922  				ColumnNames:      []string{"expiresAt"},
   923  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   924  				ColumnIDs:        []ColumnID{5},
   925  				ExtraColumnIDs:   []ColumnID{1},
   926  				Version:          SecondaryIndexFamilyFormatVersion,
   927  			},
   928  			{
   929  				Name:             "web_sessions_createdAt_idx",
   930  				ID:               3,
   931  				Unique:           false,
   932  				ColumnNames:      []string{"createdAt"},
   933  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
   934  				ColumnIDs:        []ColumnID{4},
   935  				ExtraColumnIDs:   []ColumnID{1},
   936  				Version:          SecondaryIndexFamilyFormatVersion,
   937  			},
   938  		},
   939  		NextIndexID:    4,
   940  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.WebSessionsTableID]),
   941  		NextMutationID: 1,
   942  		FormatVersion:  3,
   943  	}
   944  
   945  	// TableStatistics table to hold statistics about columns and column groups.
   946  	TableStatisticsTable = TableDescriptor{
   947  		Name:                    "table_statistics",
   948  		ID:                      keys.TableStatisticsTableID,
   949  		ParentID:                keys.SystemDatabaseID,
   950  		UnexposedParentSchemaID: keys.PublicSchemaID,
   951  		Version:                 1,
   952  		Columns: []ColumnDescriptor{
   953  			{Name: "tableID", ID: 1, Type: types.Int},
   954  			{Name: "statisticID", ID: 2, Type: types.Int, DefaultExpr: &uniqueRowIDString},
   955  			{Name: "name", ID: 3, Type: types.String, Nullable: true},
   956  			{Name: "columnIDs", ID: 4, Type: types.IntArray},
   957  			{Name: "createdAt", ID: 5, Type: types.Timestamp, DefaultExpr: &nowString},
   958  			{Name: "rowCount", ID: 6, Type: types.Int},
   959  			{Name: "distinctCount", ID: 7, Type: types.Int},
   960  			{Name: "nullCount", ID: 8, Type: types.Int},
   961  			{Name: "histogram", ID: 9, Type: types.Bytes, Nullable: true},
   962  		},
   963  		NextColumnID: 10,
   964  		Families: []ColumnFamilyDescriptor{
   965  			{
   966  				Name: "fam_0_tableID_statisticID_name_columnIDs_createdAt_rowCount_distinctCount_nullCount_histogram",
   967  				ID:   0,
   968  				ColumnNames: []string{
   969  					"tableID",
   970  					"statisticID",
   971  					"name",
   972  					"columnIDs",
   973  					"createdAt",
   974  					"rowCount",
   975  					"distinctCount",
   976  					"nullCount",
   977  					"histogram",
   978  				},
   979  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5, 6, 7, 8, 9},
   980  			},
   981  		},
   982  		NextFamilyID: 1,
   983  		PrimaryIndex: IndexDescriptor{
   984  			Name:             "primary",
   985  			ID:               1,
   986  			Unique:           true,
   987  			ColumnNames:      []string{"tableID", "statisticID"},
   988  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
   989  			ColumnIDs:        []ColumnID{1, 2},
   990  			Version:          SecondaryIndexFamilyFormatVersion,
   991  		},
   992  		NextIndexID:    2,
   993  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.TableStatisticsTableID]),
   994  		FormatVersion:  InterleavedFormatVersion,
   995  		NextMutationID: 1,
   996  	}
   997  
   998  	latLonDecimal = types.MakeDecimal(18, 15)
   999  
  1000  	// LocationsTable is the descriptor for the locations table.
  1001  	LocationsTable = TableDescriptor{
  1002  		Name:                    "locations",
  1003  		ID:                      keys.LocationsTableID,
  1004  		ParentID:                keys.SystemDatabaseID,
  1005  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1006  		Version:                 1,
  1007  		Columns: []ColumnDescriptor{
  1008  			{Name: "localityKey", ID: 1, Type: types.String},
  1009  			{Name: "localityValue", ID: 2, Type: types.String},
  1010  			{Name: "latitude", ID: 3, Type: latLonDecimal},
  1011  			{Name: "longitude", ID: 4, Type: latLonDecimal},
  1012  		},
  1013  		NextColumnID: 5,
  1014  		Families: []ColumnFamilyDescriptor{
  1015  			{
  1016  				Name:        "fam_0_localityKey_localityValue_latitude_longitude",
  1017  				ID:          0,
  1018  				ColumnNames: []string{"localityKey", "localityValue", "latitude", "longitude"},
  1019  				ColumnIDs:   []ColumnID{1, 2, 3, 4},
  1020  			},
  1021  		},
  1022  		NextFamilyID: 1,
  1023  		PrimaryIndex: IndexDescriptor{
  1024  			Name:             "primary",
  1025  			ID:               1,
  1026  			Unique:           true,
  1027  			ColumnNames:      []string{"localityKey", "localityValue"},
  1028  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1029  			ColumnIDs:        []ColumnID{1, 2},
  1030  			Version:          SecondaryIndexFamilyFormatVersion,
  1031  		},
  1032  		NextIndexID:    2,
  1033  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.LocationsTableID]),
  1034  		FormatVersion:  InterleavedFormatVersion,
  1035  		NextMutationID: 1,
  1036  	}
  1037  
  1038  	// RoleMembersTable is the descriptor for the role_members table.
  1039  	RoleMembersTable = TableDescriptor{
  1040  		Name:                    "role_members",
  1041  		ID:                      keys.RoleMembersTableID,
  1042  		ParentID:                keys.SystemDatabaseID,
  1043  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1044  		Version:                 1,
  1045  		Columns: []ColumnDescriptor{
  1046  			{Name: "role", ID: 1, Type: types.String},
  1047  			{Name: "member", ID: 2, Type: types.String},
  1048  			{Name: "isAdmin", ID: 3, Type: types.Bool},
  1049  		},
  1050  		NextColumnID: 4,
  1051  		Families: []ColumnFamilyDescriptor{
  1052  			{
  1053  				Name:        "primary",
  1054  				ID:          0,
  1055  				ColumnNames: []string{"role", "member"},
  1056  				ColumnIDs:   []ColumnID{1, 2},
  1057  			},
  1058  			{
  1059  				Name:            "fam_3_isAdmin",
  1060  				ID:              3,
  1061  				ColumnNames:     []string{"isAdmin"},
  1062  				ColumnIDs:       []ColumnID{3},
  1063  				DefaultColumnID: 3,
  1064  			},
  1065  		},
  1066  		NextFamilyID: 4,
  1067  		PrimaryIndex: IndexDescriptor{
  1068  			Name:             "primary",
  1069  			ID:               1,
  1070  			Unique:           true,
  1071  			ColumnNames:      []string{"role", "member"},
  1072  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1073  			ColumnIDs:        []ColumnID{1, 2},
  1074  			Version:          SecondaryIndexFamilyFormatVersion,
  1075  		},
  1076  		Indexes: []IndexDescriptor{
  1077  			{
  1078  				Name:             "role_members_role_idx",
  1079  				ID:               2,
  1080  				Unique:           false,
  1081  				ColumnNames:      []string{"role"},
  1082  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
  1083  				ColumnIDs:        []ColumnID{1},
  1084  				ExtraColumnIDs:   []ColumnID{2},
  1085  				Version:          SecondaryIndexFamilyFormatVersion,
  1086  			},
  1087  			{
  1088  				Name:             "role_members_member_idx",
  1089  				ID:               3,
  1090  				Unique:           false,
  1091  				ColumnNames:      []string{"member"},
  1092  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC},
  1093  				ColumnIDs:        []ColumnID{2},
  1094  				ExtraColumnIDs:   []ColumnID{1},
  1095  				Version:          SecondaryIndexFamilyFormatVersion,
  1096  			},
  1097  		},
  1098  		NextIndexID:    4,
  1099  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.RoleMembersTableID]),
  1100  		FormatVersion:  InterleavedFormatVersion,
  1101  		NextMutationID: 1,
  1102  	}
  1103  
  1104  	// CommentsTable is the descriptor for the comments table.
  1105  	CommentsTable = TableDescriptor{
  1106  		Name:                    "comments",
  1107  		ID:                      keys.CommentsTableID,
  1108  		ParentID:                keys.SystemDatabaseID,
  1109  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1110  		Version:                 1,
  1111  		Columns: []ColumnDescriptor{
  1112  			{Name: "type", ID: 1, Type: types.Int},
  1113  			{Name: "object_id", ID: 2, Type: types.Int},
  1114  			{Name: "sub_id", ID: 3, Type: types.Int},
  1115  			{Name: "comment", ID: 4, Type: types.String},
  1116  		},
  1117  		NextColumnID: 5,
  1118  		Families: []ColumnFamilyDescriptor{
  1119  			{Name: "primary", ID: 0, ColumnNames: []string{"type", "object_id", "sub_id"}, ColumnIDs: []ColumnID{1, 2, 3}},
  1120  			{Name: "fam_4_comment", ID: 4, ColumnNames: []string{"comment"}, ColumnIDs: []ColumnID{4}, DefaultColumnID: 4},
  1121  		},
  1122  		NextFamilyID: 5,
  1123  		PrimaryIndex: IndexDescriptor{
  1124  			Name:             "primary",
  1125  			ID:               1,
  1126  			Unique:           true,
  1127  			ColumnNames:      []string{"type", "object_id", "sub_id"},
  1128  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC},
  1129  			ColumnIDs:        []ColumnID{1, 2, 3},
  1130  			Version:          SecondaryIndexFamilyFormatVersion,
  1131  		},
  1132  		NextIndexID:    2,
  1133  		Privileges:     newCommentPrivilegeDescriptor(SystemAllowedPrivileges[keys.CommentsTableID]),
  1134  		FormatVersion:  InterleavedFormatVersion,
  1135  		NextMutationID: 1,
  1136  	}
  1137  
  1138  	ReportsMetaTable = TableDescriptor{
  1139  		Name:                    "reports_meta",
  1140  		ID:                      keys.ReportsMetaTableID,
  1141  		ParentID:                keys.SystemDatabaseID,
  1142  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1143  		Version:                 1,
  1144  		Columns: []ColumnDescriptor{
  1145  			{Name: "id", ID: 1, Type: types.Int},
  1146  			{Name: "generated", ID: 2, Type: types.TimestampTZ},
  1147  		},
  1148  		NextColumnID: 3,
  1149  		Families: []ColumnFamilyDescriptor{
  1150  			{
  1151  				Name:        "primary",
  1152  				ID:          0,
  1153  				ColumnNames: []string{"id", "generated"},
  1154  				ColumnIDs:   []ColumnID{1, 2},
  1155  			},
  1156  		},
  1157  		NextFamilyID: 1,
  1158  		PrimaryIndex: IndexDescriptor{
  1159  			Name:        "primary",
  1160  			ID:          1,
  1161  			Unique:      true,
  1162  			ColumnNames: []string{"id"},
  1163  			ColumnDirections: []IndexDescriptor_Direction{
  1164  				IndexDescriptor_ASC,
  1165  			},
  1166  			ColumnIDs: []ColumnID{1},
  1167  			Version:   SecondaryIndexFamilyFormatVersion,
  1168  		},
  1169  		NextIndexID:    2,
  1170  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ReportsMetaTableID]),
  1171  		FormatVersion:  InterleavedFormatVersion,
  1172  		NextMutationID: 1,
  1173  	}
  1174  
  1175  	ReplicationConstraintStatsTableTTL = time.Minute * 10
  1176  	// TODO(andrei): In 20.1 we should add a foreign key reference to the
  1177  	// reports_meta table. Until then, it would cost us having to create an index
  1178  	// on report_id.
  1179  	ReplicationConstraintStatsTable = TableDescriptor{
  1180  		Name:                    "replication_constraint_stats",
  1181  		ID:                      keys.ReplicationConstraintStatsTableID,
  1182  		ParentID:                keys.SystemDatabaseID,
  1183  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1184  		Version:                 1,
  1185  		Columns: []ColumnDescriptor{
  1186  			{Name: "zone_id", ID: 1, Type: types.Int},
  1187  			{Name: "subzone_id", ID: 2, Type: types.Int},
  1188  			{Name: "type", ID: 3, Type: types.String},
  1189  			{Name: "config", ID: 4, Type: types.String},
  1190  			{Name: "report_id", ID: 5, Type: types.Int},
  1191  			{Name: "violation_start", ID: 6, Type: types.TimestampTZ, Nullable: true},
  1192  			{Name: "violating_ranges", ID: 7, Type: types.Int},
  1193  		},
  1194  		NextColumnID: 8,
  1195  		Families: []ColumnFamilyDescriptor{
  1196  			{
  1197  				Name: "primary",
  1198  				ID:   0,
  1199  				ColumnNames: []string{
  1200  					"zone_id",
  1201  					"subzone_id",
  1202  					"type",
  1203  					"config",
  1204  					"report_id",
  1205  					"violation_start",
  1206  					"violating_ranges",
  1207  				},
  1208  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5, 6, 7},
  1209  			},
  1210  		},
  1211  		NextFamilyID: 1,
  1212  		PrimaryIndex: IndexDescriptor{
  1213  			Name:        "primary",
  1214  			ID:          1,
  1215  			Unique:      true,
  1216  			ColumnNames: []string{"zone_id", "subzone_id", "type", "config"},
  1217  			ColumnDirections: []IndexDescriptor_Direction{
  1218  				IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC,
  1219  			},
  1220  			ColumnIDs: []ColumnID{1, 2, 3, 4},
  1221  			Version:   SecondaryIndexFamilyFormatVersion,
  1222  		},
  1223  		NextIndexID:    2,
  1224  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ReplicationConstraintStatsTableID]),
  1225  		FormatVersion:  InterleavedFormatVersion,
  1226  		NextMutationID: 1,
  1227  	}
  1228  
  1229  	// TODO(andrei): In 20.1 we should add a foreign key reference to the
  1230  	// reports_meta table. Until then, it would cost us having to create an index
  1231  	// on report_id.
  1232  	ReplicationCriticalLocalitiesTable = TableDescriptor{
  1233  		Name:                    "replication_critical_localities",
  1234  		ID:                      keys.ReplicationCriticalLocalitiesTableID,
  1235  		ParentID:                keys.SystemDatabaseID,
  1236  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1237  		Version:                 1,
  1238  		Columns: []ColumnDescriptor{
  1239  			{Name: "zone_id", ID: 1, Type: types.Int},
  1240  			{Name: "subzone_id", ID: 2, Type: types.Int},
  1241  			{Name: "locality", ID: 3, Type: types.String},
  1242  			{Name: "report_id", ID: 4, Type: types.Int},
  1243  			{Name: "at_risk_ranges", ID: 5, Type: types.Int},
  1244  		},
  1245  		NextColumnID: 6,
  1246  		Families: []ColumnFamilyDescriptor{
  1247  			{
  1248  				Name: "primary",
  1249  				ID:   0,
  1250  				ColumnNames: []string{
  1251  					"zone_id",
  1252  					"subzone_id",
  1253  					"locality",
  1254  					"report_id",
  1255  					"at_risk_ranges",
  1256  				},
  1257  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5},
  1258  			},
  1259  		},
  1260  		NextFamilyID: 1,
  1261  		PrimaryIndex: IndexDescriptor{
  1262  			Name:        "primary",
  1263  			ID:          1,
  1264  			Unique:      true,
  1265  			ColumnNames: []string{"zone_id", "subzone_id", "locality"},
  1266  			ColumnDirections: []IndexDescriptor_Direction{
  1267  				IndexDescriptor_ASC, IndexDescriptor_ASC, IndexDescriptor_ASC,
  1268  			},
  1269  			ColumnIDs: []ColumnID{1, 2, 3},
  1270  			Version:   SecondaryIndexFamilyFormatVersion,
  1271  		},
  1272  		NextIndexID:    2,
  1273  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ReplicationCriticalLocalitiesTableID]),
  1274  		FormatVersion:  InterleavedFormatVersion,
  1275  		NextMutationID: 1,
  1276  	}
  1277  
  1278  	ReplicationStatsTableTTL = time.Minute * 10
  1279  	// TODO(andrei): In 20.1 we should add a foreign key reference to the
  1280  	// reports_meta table. Until then, it would cost us having to create an index
  1281  	// on report_id.
  1282  	ReplicationStatsTable = TableDescriptor{
  1283  		Name:                    "replication_stats",
  1284  		ID:                      keys.ReplicationStatsTableID,
  1285  		ParentID:                keys.SystemDatabaseID,
  1286  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1287  		Version:                 1,
  1288  		Columns: []ColumnDescriptor{
  1289  			{Name: "zone_id", ID: 1, Type: types.Int},
  1290  			{Name: "subzone_id", ID: 2, Type: types.Int},
  1291  			{Name: "report_id", ID: 3, Type: types.Int},
  1292  			{Name: "total_ranges", ID: 4, Type: types.Int},
  1293  			{Name: "unavailable_ranges", ID: 5, Type: types.Int},
  1294  			{Name: "under_replicated_ranges", ID: 6, Type: types.Int},
  1295  			{Name: "over_replicated_ranges", ID: 7, Type: types.Int},
  1296  		},
  1297  		NextColumnID: 8,
  1298  		Families: []ColumnFamilyDescriptor{
  1299  			{
  1300  				Name: "primary",
  1301  				ID:   0,
  1302  				ColumnNames: []string{
  1303  					"zone_id",
  1304  					"subzone_id",
  1305  					"report_id",
  1306  					"total_ranges",
  1307  					"unavailable_ranges",
  1308  					"under_replicated_ranges",
  1309  					"over_replicated_ranges",
  1310  				},
  1311  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5, 6, 7},
  1312  			},
  1313  		},
  1314  		NextFamilyID: 2,
  1315  		PrimaryIndex: IndexDescriptor{
  1316  			Name:             "primary",
  1317  			ID:               1,
  1318  			Unique:           true,
  1319  			ColumnNames:      []string{"zone_id", "subzone_id"},
  1320  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1321  			ColumnIDs:        []ColumnID{1, 2},
  1322  			Version:          SecondaryIndexFamilyFormatVersion,
  1323  		},
  1324  		NextIndexID:    2,
  1325  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ReplicationStatsTableID]),
  1326  		FormatVersion:  InterleavedFormatVersion,
  1327  		NextMutationID: 1,
  1328  	}
  1329  
  1330  	ProtectedTimestampsMetaTable = TableDescriptor{
  1331  		Name:                    "protected_ts_meta",
  1332  		ID:                      keys.ProtectedTimestampsMetaTableID,
  1333  		ParentID:                keys.SystemDatabaseID,
  1334  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1335  		Version:                 1,
  1336  		Columns: []ColumnDescriptor{
  1337  			{
  1338  				Name:        "singleton",
  1339  				ID:          1,
  1340  				Type:        types.Bool,
  1341  				DefaultExpr: &trueBoolString,
  1342  			},
  1343  			{Name: "version", ID: 2, Type: types.Int},
  1344  			{Name: "num_records", ID: 3, Type: types.Int},
  1345  			{Name: "num_spans", ID: 4, Type: types.Int},
  1346  			{Name: "total_bytes", ID: 5, Type: types.Int},
  1347  		},
  1348  		Checks: []*TableDescriptor_CheckConstraint{
  1349  			{
  1350  				Name:      "check_singleton",
  1351  				Expr:      "singleton",
  1352  				ColumnIDs: []ColumnID{1},
  1353  			},
  1354  		},
  1355  		NextColumnID: 6,
  1356  		Families: []ColumnFamilyDescriptor{
  1357  			{
  1358  				Name:        "primary",
  1359  				ColumnNames: []string{"singleton", "version", "num_records", "num_spans", "total_bytes"},
  1360  				ColumnIDs:   []ColumnID{1, 2, 3, 4, 5},
  1361  			},
  1362  		},
  1363  		NextFamilyID: 1,
  1364  		PrimaryIndex: IndexDescriptor{
  1365  			Name:        "primary",
  1366  			ID:          1,
  1367  			Version:     1,
  1368  			Unique:      true,
  1369  			ColumnNames: []string{"singleton"},
  1370  			ColumnIDs:   []ColumnID{1},
  1371  			ColumnDirections: []IndexDescriptor_Direction{
  1372  				IndexDescriptor_ASC,
  1373  			},
  1374  		},
  1375  		NextIndexID:    2,
  1376  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ReplicationStatsTableID]),
  1377  		FormatVersion:  InterleavedFormatVersion,
  1378  		NextMutationID: 1,
  1379  	}
  1380  
  1381  	ProtectedTimestampsRecordsTable = TableDescriptor{
  1382  		Name:                    "protected_ts_records",
  1383  		ID:                      keys.ProtectedTimestampsRecordsTableID,
  1384  		ParentID:                keys.SystemDatabaseID,
  1385  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1386  		Version:                 1,
  1387  		Columns: []ColumnDescriptor{
  1388  			{Name: "id", ID: 1, Type: types.Uuid},
  1389  			{Name: "ts", ID: 2, Type: types.Decimal},
  1390  			{Name: "meta_type", ID: 3, Type: types.String},
  1391  			{Name: "meta", ID: 4, Type: types.Bytes, Nullable: true},
  1392  			{Name: "num_spans", ID: 5, Type: types.Int},
  1393  			{Name: "spans", ID: 6, Type: types.Bytes},
  1394  			{Name: "verified", ID: 7, Type: types.Bool, DefaultExpr: &falseBoolString},
  1395  		},
  1396  		NextColumnID: 8,
  1397  		Families: []ColumnFamilyDescriptor{
  1398  			{
  1399  				Name:        "primary",
  1400  				ColumnNames: []string{"id", "ts", "meta_type", "meta", "num_spans", "spans", "verified"},
  1401  				ColumnIDs:   []ColumnID{1, 2, 3, 4, 5, 6, 7},
  1402  			},
  1403  		},
  1404  		NextFamilyID: 1,
  1405  		PrimaryIndex: IndexDescriptor{
  1406  			Name:        "primary",
  1407  			ID:          1,
  1408  			Version:     1,
  1409  			Unique:      true,
  1410  			ColumnNames: []string{"id"},
  1411  			ColumnIDs:   []ColumnID{1},
  1412  			ColumnDirections: []IndexDescriptor_Direction{
  1413  				IndexDescriptor_ASC,
  1414  			},
  1415  		},
  1416  		NextIndexID:    2,
  1417  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.ProtectedTimestampsRecordsTableID]),
  1418  		FormatVersion:  InterleavedFormatVersion,
  1419  		NextMutationID: 1,
  1420  	}
  1421  
  1422  	// RoleOptionsTable is the descriptor for the role_options table.
  1423  	RoleOptionsTable = TableDescriptor{
  1424  		Name:                    "role_options",
  1425  		ID:                      keys.RoleOptionsTableID,
  1426  		ParentID:                keys.SystemDatabaseID,
  1427  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1428  		Version:                 1,
  1429  		Columns: []ColumnDescriptor{
  1430  			{Name: "username", ID: 1, Type: types.String},
  1431  			{Name: "option", ID: 2, Type: types.String},
  1432  			{Name: "value", ID: 3, Type: types.String, Nullable: true},
  1433  		},
  1434  		NextColumnID: 4,
  1435  		Families: []ColumnFamilyDescriptor{
  1436  			{
  1437  				Name:            "primary",
  1438  				ColumnNames:     []string{"username", "option", "value"},
  1439  				ColumnIDs:       []ColumnID{1, 2, 3},
  1440  				DefaultColumnID: 3,
  1441  			},
  1442  		},
  1443  		NextFamilyID: 1,
  1444  		PrimaryIndex: IndexDescriptor{
  1445  			Name:             "primary",
  1446  			ID:               1,
  1447  			Unique:           true,
  1448  			ColumnNames:      []string{"username", "option"},
  1449  			ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1450  			ColumnIDs:        []ColumnID{1, 2},
  1451  			Version:          SecondaryIndexFamilyFormatVersion,
  1452  		},
  1453  		NextIndexID:    2,
  1454  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.RoleOptionsTableID]),
  1455  		FormatVersion:  InterleavedFormatVersion,
  1456  		NextMutationID: 1,
  1457  	}
  1458  
  1459  	StatementBundleChunksTable = TableDescriptor{
  1460  		Name:                    "statement_bundle_chunks",
  1461  		ID:                      keys.StatementBundleChunksTableID,
  1462  		ParentID:                keys.SystemDatabaseID,
  1463  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1464  		Version:                 1,
  1465  		Columns: []ColumnDescriptor{
  1466  			{Name: "id", ID: 1, Type: types.Int, DefaultExpr: &uniqueRowIDString},
  1467  			{Name: "description", ID: 2, Type: types.String, Nullable: true},
  1468  			{Name: "data", ID: 3, Type: types.Bytes},
  1469  		},
  1470  		NextColumnID: 4,
  1471  		Families: []ColumnFamilyDescriptor{
  1472  			{
  1473  				Name:        "primary",
  1474  				ColumnNames: []string{"id", "description", "data"},
  1475  				ColumnIDs:   []ColumnID{1, 2, 3},
  1476  			},
  1477  		},
  1478  		NextFamilyID:   1,
  1479  		PrimaryIndex:   pk("id"),
  1480  		NextIndexID:    2,
  1481  		Privileges:     NewCustomSuperuserPrivilegeDescriptor(SystemAllowedPrivileges[keys.StatementBundleChunksTableID]),
  1482  		FormatVersion:  InterleavedFormatVersion,
  1483  		NextMutationID: 1,
  1484  	}
  1485  
  1486  	// TODO(andrei): Add a foreign key reference to the statement_diagnostics table when
  1487  	// it no longer requires us to create an index on statement_diagnostics_id.
  1488  	StatementDiagnosticsRequestsTable = TableDescriptor{
  1489  		Name:                    "statement_diagnostics_requests",
  1490  		ID:                      keys.StatementDiagnosticsRequestsTableID,
  1491  		ParentID:                keys.SystemDatabaseID,
  1492  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1493  		Version:                 1,
  1494  		Columns: []ColumnDescriptor{
  1495  			{Name: "id", ID: 1, Type: types.Int, DefaultExpr: &uniqueRowIDString, Nullable: false},
  1496  			{Name: "completed", ID: 2, Type: types.Bool, Nullable: false, DefaultExpr: &falseBoolString},
  1497  			{Name: "statement_fingerprint", ID: 3, Type: types.String, Nullable: false},
  1498  			{Name: "statement_diagnostics_id", ID: 4, Type: types.Int, Nullable: true},
  1499  			{Name: "requested_at", ID: 5, Type: types.TimestampTZ, Nullable: false},
  1500  		},
  1501  		NextColumnID: 6,
  1502  		Families: []ColumnFamilyDescriptor{
  1503  			{
  1504  				Name:        "primary",
  1505  				ColumnNames: []string{"id", "completed", "statement_fingerprint", "statement_diagnostics_id", "requested_at"},
  1506  				ColumnIDs:   []ColumnID{1, 2, 3, 4, 5},
  1507  			},
  1508  		},
  1509  		NextFamilyID: 1,
  1510  		PrimaryIndex: pk("id"),
  1511  		// Index for the polling query.
  1512  		Indexes: []IndexDescriptor{
  1513  			{
  1514  				Name:             "completed_idx",
  1515  				ID:               2,
  1516  				Unique:           false,
  1517  				ColumnNames:      []string{"completed", "id"},
  1518  				StoreColumnNames: []string{"statement_fingerprint"},
  1519  				ColumnIDs:        []ColumnID{2, 1},
  1520  				ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC, IndexDescriptor_ASC},
  1521  				StoreColumnIDs:   []ColumnID{3},
  1522  				Version:          SecondaryIndexFamilyFormatVersion,
  1523  			},
  1524  		},
  1525  		NextIndexID: 3,
  1526  		Privileges: NewCustomSuperuserPrivilegeDescriptor(
  1527  			SystemAllowedPrivileges[keys.StatementDiagnosticsRequestsTableID]),
  1528  		FormatVersion:  InterleavedFormatVersion,
  1529  		NextMutationID: 1,
  1530  	}
  1531  
  1532  	StatementDiagnosticsTable = TableDescriptor{
  1533  		Name:                    "statement_diagnostics",
  1534  		ID:                      keys.StatementDiagnosticsTableID,
  1535  		ParentID:                keys.SystemDatabaseID,
  1536  		UnexposedParentSchemaID: keys.PublicSchemaID,
  1537  		Version:                 1,
  1538  		Columns: []ColumnDescriptor{
  1539  			{Name: "id", ID: 1, Type: types.Int, DefaultExpr: &uniqueRowIDString, Nullable: false},
  1540  			{Name: "statement_fingerprint", ID: 2, Type: types.String, Nullable: false},
  1541  			{Name: "statement", ID: 3, Type: types.String, Nullable: false},
  1542  			{Name: "collected_at", ID: 4, Type: types.TimestampTZ, Nullable: false},
  1543  			{Name: "trace", ID: 5, Type: types.Jsonb, Nullable: true},
  1544  			{Name: "bundle_chunks", ID: 6, Type: types.IntArray, Nullable: true},
  1545  			{Name: "error", ID: 7, Type: types.String, Nullable: true},
  1546  		},
  1547  		NextColumnID: 8,
  1548  		Families: []ColumnFamilyDescriptor{
  1549  			{
  1550  				Name: "primary",
  1551  				ColumnNames: []string{"id", "statement_fingerprint", "statement",
  1552  					"collected_at", "trace", "bundle_chunks", "error"},
  1553  				ColumnIDs: []ColumnID{1, 2, 3, 4, 5, 6, 7},
  1554  			},
  1555  		},
  1556  		NextFamilyID: 1,
  1557  		PrimaryIndex: pk("id"),
  1558  		NextIndexID:  2,
  1559  		Privileges: NewCustomSuperuserPrivilegeDescriptor(
  1560  			SystemAllowedPrivileges[keys.StatementDiagnosticsTableID]),
  1561  		FormatVersion:  InterleavedFormatVersion,
  1562  		NextMutationID: 1,
  1563  	}
  1564  )
  1565  
  1566  // addSystemDescriptorsToSchema populates the supplied MetadataSchema
  1567  // with the system database and table descriptors. The descriptors for
  1568  // these objects exist statically in this file, but a MetadataSchema
  1569  // can be used to persist these descriptors to the cockroach store.
  1570  func addSystemDescriptorsToSchema(target *MetadataSchema) {
  1571  	// Add system database.
  1572  	target.AddDescriptor(keys.RootNamespaceID, &SystemDB)
  1573  
  1574  	// Add system config tables.
  1575  	target.AddDescriptor(keys.SystemDatabaseID, &DeprecatedNamespaceTable)
  1576  	target.AddDescriptor(keys.SystemDatabaseID, &NamespaceTable)
  1577  	target.AddDescriptor(keys.SystemDatabaseID, &DescriptorTable)
  1578  	target.AddDescriptor(keys.SystemDatabaseID, &UsersTable)
  1579  	if target.codec.ForSystemTenant() {
  1580  		target.AddDescriptor(keys.SystemDatabaseID, &ZonesTable)
  1581  	}
  1582  	target.AddDescriptor(keys.SystemDatabaseID, &SettingsTable)
  1583  	if !target.codec.ForSystemTenant() {
  1584  		// Only add the descriptor ID sequence if this is a non-system tenant.
  1585  		// System tenants use the global descIDGenerator key. See #48513.
  1586  		target.AddDescriptor(keys.SystemDatabaseID, &DescIDSequence)
  1587  	}
  1588  	if target.codec.ForSystemTenant() {
  1589  		// Only add the tenant table if this is the system tenant.
  1590  		target.AddDescriptor(keys.SystemDatabaseID, &TenantsTable)
  1591  	}
  1592  
  1593  	// Add all the other system tables.
  1594  	target.AddDescriptor(keys.SystemDatabaseID, &LeaseTable)
  1595  	target.AddDescriptor(keys.SystemDatabaseID, &EventLogTable)
  1596  	target.AddDescriptor(keys.SystemDatabaseID, &RangeEventTable)
  1597  	target.AddDescriptor(keys.SystemDatabaseID, &UITable)
  1598  	target.AddDescriptor(keys.SystemDatabaseID, &JobsTable)
  1599  	target.AddDescriptor(keys.SystemDatabaseID, &WebSessionsTable)
  1600  	target.AddDescriptor(keys.SystemDatabaseID, &RoleOptionsTable)
  1601  
  1602  	// Tables introduced in 2.0, added here for 2.1.
  1603  	target.AddDescriptor(keys.SystemDatabaseID, &TableStatisticsTable)
  1604  	target.AddDescriptor(keys.SystemDatabaseID, &LocationsTable)
  1605  	target.AddDescriptor(keys.SystemDatabaseID, &RoleMembersTable)
  1606  
  1607  	// The CommentsTable has been introduced in 2.2. It was added here since it
  1608  	// was introduced, but it's also created as a migration for older clusters.
  1609  	target.AddDescriptor(keys.SystemDatabaseID, &CommentsTable)
  1610  	target.AddDescriptor(keys.SystemDatabaseID, &ReportsMetaTable)
  1611  	target.AddDescriptor(keys.SystemDatabaseID, &ReplicationConstraintStatsTable)
  1612  	target.AddDescriptor(keys.SystemDatabaseID, &ReplicationStatsTable)
  1613  	target.AddDescriptor(keys.SystemDatabaseID, &ReplicationCriticalLocalitiesTable)
  1614  	target.AddDescriptor(keys.SystemDatabaseID, &ProtectedTimestampsMetaTable)
  1615  	target.AddDescriptor(keys.SystemDatabaseID, &ProtectedTimestampsRecordsTable)
  1616  
  1617  	// Tables introduced in 20.1.
  1618  	target.AddDescriptor(keys.SystemDatabaseID, &StatementBundleChunksTable)
  1619  	target.AddDescriptor(keys.SystemDatabaseID, &StatementDiagnosticsRequestsTable)
  1620  	target.AddDescriptor(keys.SystemDatabaseID, &StatementDiagnosticsTable)
  1621  }
  1622  
  1623  // addSplitIDs adds a split point for each of the PseudoTableIDs to the supplied
  1624  // MetadataSchema.
  1625  func addSplitIDs(target *MetadataSchema) {
  1626  	target.AddSplitIDs(keys.PseudoTableIDs...)
  1627  }
  1628  
  1629  // Create a kv pair for the zone config for the given key and config value.
  1630  func createZoneConfigKV(
  1631  	keyID int, codec keys.SQLCodec, zoneConfig *zonepb.ZoneConfig,
  1632  ) roachpb.KeyValue {
  1633  	value := roachpb.Value{}
  1634  	if err := value.SetProto(zoneConfig); err != nil {
  1635  		panic(fmt.Sprintf("could not marshal ZoneConfig for ID: %d: %s", keyID, err))
  1636  	}
  1637  	return roachpb.KeyValue{
  1638  		Key:   codec.ZoneKey(uint32(keyID)),
  1639  		Value: value,
  1640  	}
  1641  }
  1642  
  1643  // addZoneConfigKVsToSchema adds a kv pair for each of the statically defined
  1644  // zone configurations that should be populated in a newly bootstrapped cluster.
  1645  func addZoneConfigKVsToSchema(
  1646  	target *MetadataSchema,
  1647  	defaultZoneConfig *zonepb.ZoneConfig,
  1648  	defaultSystemZoneConfig *zonepb.ZoneConfig,
  1649  ) {
  1650  	// If this isn't the system tenant, don't add any zone configuration keys.
  1651  	// Only the system tenant has a zone table.
  1652  	if !target.codec.ForSystemTenant() {
  1653  		return
  1654  	}
  1655  
  1656  	// Adding a new system table? It should be added here to the metadata schema,
  1657  	// and also created as a migration for older cluster. The includedInBootstrap
  1658  	// field should be set on the migration.
  1659  
  1660  	target.otherKV = append(target.otherKV,
  1661  		createZoneConfigKV(keys.RootNamespaceID, target.codec, defaultZoneConfig))
  1662  
  1663  	systemZoneConf := defaultSystemZoneConfig
  1664  	metaRangeZoneConf := protoutil.Clone(defaultSystemZoneConfig).(*zonepb.ZoneConfig)
  1665  	livenessZoneConf := protoutil.Clone(defaultSystemZoneConfig).(*zonepb.ZoneConfig)
  1666  
  1667  	// .meta zone config entry with a shorter GC time.
  1668  	metaRangeZoneConf.GC.TTLSeconds = 60 * 60 // 1h
  1669  	target.otherKV = append(target.otherKV,
  1670  		createZoneConfigKV(keys.MetaRangesID, target.codec, metaRangeZoneConf))
  1671  
  1672  	// Some reporting tables have shorter GC times.
  1673  	replicationConstraintStatsZoneConf := &zonepb.ZoneConfig{
  1674  		GC: &zonepb.GCPolicy{TTLSeconds: int32(ReplicationConstraintStatsTableTTL.Seconds())},
  1675  	}
  1676  	replicationStatsZoneConf := &zonepb.ZoneConfig{
  1677  		GC: &zonepb.GCPolicy{TTLSeconds: int32(ReplicationStatsTableTTL.Seconds())},
  1678  	}
  1679  
  1680  	// Liveness zone config entry with a shorter GC time.
  1681  	livenessZoneConf.GC.TTLSeconds = 10 * 60 // 10m
  1682  	target.otherKV = append(target.otherKV,
  1683  		createZoneConfigKV(keys.LivenessRangesID, target.codec, livenessZoneConf))
  1684  	target.otherKV = append(target.otherKV,
  1685  		createZoneConfigKV(keys.SystemRangesID, target.codec, systemZoneConf))
  1686  	target.otherKV = append(target.otherKV,
  1687  		createZoneConfigKV(keys.SystemDatabaseID, target.codec, systemZoneConf))
  1688  	target.otherKV = append(target.otherKV,
  1689  		createZoneConfigKV(keys.ReplicationConstraintStatsTableID, target.codec, replicationConstraintStatsZoneConf))
  1690  	target.otherKV = append(target.otherKV,
  1691  		createZoneConfigKV(keys.ReplicationStatsTableID, target.codec, replicationStatsZoneConf))
  1692  }
  1693  
  1694  // addSystemDatabaseToSchema populates the supplied MetadataSchema with the
  1695  // System database, its tables and zone configurations.
  1696  func addSystemDatabaseToSchema(
  1697  	target *MetadataSchema,
  1698  	defaultZoneConfig *zonepb.ZoneConfig,
  1699  	defaultSystemZoneConfig *zonepb.ZoneConfig,
  1700  ) {
  1701  	addSystemDescriptorsToSchema(target)
  1702  	addSplitIDs(target)
  1703  	addZoneConfigKVsToSchema(target, defaultZoneConfig, defaultSystemZoneConfig)
  1704  }
  1705  
  1706  // IsSystemConfigID returns whether this ID is for a system config object.
  1707  func IsSystemConfigID(id ID) bool {
  1708  	return id > 0 && id <= keys.MaxSystemConfigDescID
  1709  }
  1710  
  1711  // IsReservedID returns whether this ID is for any system object.
  1712  func IsReservedID(id ID) bool {
  1713  	return id > 0 && id <= keys.MaxReservedDescID
  1714  }
  1715  
  1716  // newCommentPrivilegeDescriptor returns a privilege descriptor for comment table
  1717  func newCommentPrivilegeDescriptor(priv privilege.List) *PrivilegeDescriptor {
  1718  	selectPriv := privilege.List{privilege.SELECT}
  1719  	return &PrivilegeDescriptor{
  1720  		Users: []UserPrivileges{
  1721  			{
  1722  				User:       AdminRole,
  1723  				Privileges: priv.ToBitField(),
  1724  			},
  1725  			{
  1726  				User:       PublicRole,
  1727  				Privileges: selectPriv.ToBitField(),
  1728  			},
  1729  			{
  1730  				User:       security.RootUser,
  1731  				Privileges: priv.ToBitField(),
  1732  			},
  1733  		},
  1734  	}
  1735  }