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

     1  // Copyright 2018 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
    12  
    13  import (
    14  	"context"
    15  	"math"
    16  	"time"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/config"
    19  	"github.com/cockroachdb/cockroach/pkg/config/zonepb"
    20  	"github.com/cockroachdb/cockroach/pkg/keys"
    21  	"github.com/cockroachdb/cockroach/pkg/kv"
    22  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/opt/cat"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    28  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    29  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    30  	"github.com/cockroachdb/cockroach/pkg/sql/stats"
    31  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    32  	"github.com/cockroachdb/cockroach/pkg/util"
    33  	"github.com/cockroachdb/errors"
    34  )
    35  
    36  // optCatalog implements the cat.Catalog interface over the SchemaResolver
    37  // interface for the use of the new optimizer. The interfaces are simplified to
    38  // only include what the optimizer needs, and certain common lookups are cached
    39  // for faster performance.
    40  type optCatalog struct {
    41  	// planner needs to be set via a call to init before calling other methods.
    42  	planner *planner
    43  
    44  	// cfg is the gossiped and cached system config. It may be nil if the node
    45  	// does not yet have it available.
    46  	cfg *config.SystemConfig
    47  
    48  	// dataSources is a cache of table and view objects that's used to satisfy
    49  	// repeated calls for the same data source.
    50  	// Note that the data source object might still need to be recreated if
    51  	// something outside of the descriptor has changed (e.g. table stats).
    52  	dataSources map[*sqlbase.ImmutableTableDescriptor]cat.DataSource
    53  
    54  	// tn is a temporary name used during resolution to avoid heap allocation.
    55  	tn tree.TableName
    56  }
    57  
    58  var _ cat.Catalog = &optCatalog{}
    59  
    60  // init initializes an optCatalog instance (which the caller can pre-allocate).
    61  // The instance can be used across multiple queries, but reset() should be
    62  // called for each query.
    63  func (oc *optCatalog) init(planner *planner) {
    64  	oc.planner = planner
    65  	oc.dataSources = make(map[*sqlbase.ImmutableTableDescriptor]cat.DataSource)
    66  }
    67  
    68  // reset prepares the optCatalog to be used for a new query.
    69  func (oc *optCatalog) reset() {
    70  	// If we have accumulated too many tables in our map, throw everything away.
    71  	// This deals with possible edge cases where we do a lot of DDL in a
    72  	// long-lived session.
    73  	if len(oc.dataSources) > 100 {
    74  		oc.dataSources = make(map[*sqlbase.ImmutableTableDescriptor]cat.DataSource)
    75  	}
    76  
    77  	oc.cfg = oc.planner.execCfg.Gossip.DeprecatedSystemConfig(47150)
    78  }
    79  
    80  // optSchema is a wrapper around sqlbase.DatabaseDescriptor that implements the
    81  // cat.Object and cat.Schema interfaces.
    82  type optSchema struct {
    83  	planner *planner
    84  	desc    *sqlbase.DatabaseDescriptor
    85  
    86  	name cat.SchemaName
    87  }
    88  
    89  // ID is part of the cat.Object interface.
    90  func (os *optSchema) ID() cat.StableID {
    91  	return cat.StableID(os.desc.ID)
    92  }
    93  
    94  // PostgresDescriptorID is part of the cat.Object interface.
    95  func (os *optSchema) PostgresDescriptorID() cat.StableID {
    96  	return cat.StableID(os.desc.ID)
    97  }
    98  
    99  // Equals is part of the cat.Object interface.
   100  func (os *optSchema) Equals(other cat.Object) bool {
   101  	otherSchema, ok := other.(*optSchema)
   102  	return ok && os.desc.ID == otherSchema.desc.ID
   103  }
   104  
   105  // Name is part of the cat.Schema interface.
   106  func (os *optSchema) Name() *cat.SchemaName {
   107  	return &os.name
   108  }
   109  
   110  // GetDataSourceNames is part of the cat.Schema interface.
   111  func (os *optSchema) GetDataSourceNames(ctx context.Context) ([]cat.DataSourceName, error) {
   112  	return resolver.GetObjectNames(
   113  		ctx,
   114  		os.planner.Txn(),
   115  		os.planner,
   116  		os.planner.ExecCfg().Codec,
   117  		os.desc,
   118  		os.name.Schema(),
   119  		true, /* explicitPrefix */
   120  	)
   121  }
   122  
   123  // ResolveSchema is part of the cat.Catalog interface.
   124  func (oc *optCatalog) ResolveSchema(
   125  	ctx context.Context, flags cat.Flags, name *cat.SchemaName,
   126  ) (cat.Schema, cat.SchemaName, error) {
   127  	if flags.AvoidDescriptorCaches {
   128  		defer func(prev bool) {
   129  			oc.planner.avoidCachedDescriptors = prev
   130  		}(oc.planner.avoidCachedDescriptors)
   131  		oc.planner.avoidCachedDescriptors = true
   132  	}
   133  
   134  	oc.tn.ObjectNamePrefix = *name
   135  	found, desc, err := oc.tn.ObjectNamePrefix.Resolve(
   136  		ctx,
   137  		oc.planner,
   138  		oc.planner.CurrentDatabase(),
   139  		oc.planner.CurrentSearchPath(),
   140  	)
   141  	if err != nil {
   142  		return nil, cat.SchemaName{}, err
   143  	}
   144  	if !found {
   145  		if !name.ExplicitSchema && !name.ExplicitCatalog {
   146  			return nil, cat.SchemaName{}, pgerror.New(
   147  				pgcode.InvalidName, "no database specified",
   148  			)
   149  		}
   150  		return nil, cat.SchemaName{}, pgerror.Newf(
   151  			pgcode.InvalidSchemaName, "target database or schema does not exist",
   152  		)
   153  	}
   154  	return &optSchema{
   155  		planner: oc.planner,
   156  		desc:    desc.(*DatabaseDescriptor),
   157  		name:    oc.tn.ObjectNamePrefix,
   158  	}, oc.tn.ObjectNamePrefix, nil
   159  }
   160  
   161  // ResolveDataSource is part of the cat.Catalog interface.
   162  func (oc *optCatalog) ResolveDataSource(
   163  	ctx context.Context, flags cat.Flags, name *cat.DataSourceName,
   164  ) (cat.DataSource, cat.DataSourceName, error) {
   165  	if flags.AvoidDescriptorCaches {
   166  		defer func(prev bool) {
   167  			oc.planner.avoidCachedDescriptors = prev
   168  		}(oc.planner.avoidCachedDescriptors)
   169  		oc.planner.avoidCachedDescriptors = true
   170  	}
   171  
   172  	oc.tn = *name
   173  	desc, err := resolver.ResolveExistingTableObject(ctx, oc.planner, &oc.tn, tree.ObjectLookupFlagsWithRequired(), resolver.ResolveAnyDescType)
   174  	if err != nil {
   175  		return nil, cat.DataSourceName{}, err
   176  	}
   177  	ds, err := oc.dataSourceForDesc(ctx, flags, desc, &oc.tn)
   178  	if err != nil {
   179  		return nil, cat.DataSourceName{}, err
   180  	}
   181  	return ds, oc.tn, nil
   182  }
   183  
   184  // ResolveDataSourceByID is part of the cat.Catalog interface.
   185  func (oc *optCatalog) ResolveDataSourceByID(
   186  	ctx context.Context, flags cat.Flags, dataSourceID cat.StableID,
   187  ) (_ cat.DataSource, isAdding bool, _ error) {
   188  	if flags.AvoidDescriptorCaches {
   189  		defer func(prev bool) {
   190  			oc.planner.avoidCachedDescriptors = prev
   191  		}(oc.planner.avoidCachedDescriptors)
   192  		oc.planner.avoidCachedDescriptors = true
   193  	}
   194  
   195  	tableLookup, err := oc.planner.LookupTableByID(ctx, sqlbase.ID(dataSourceID))
   196  
   197  	if err != nil || tableLookup.IsAdding {
   198  		if errors.Is(err, sqlbase.ErrDescriptorNotFound) || tableLookup.IsAdding {
   199  			return nil, tableLookup.IsAdding, sqlbase.NewUndefinedRelationError(&tree.TableRef{TableID: int64(dataSourceID)})
   200  		}
   201  		return nil, false, err
   202  	}
   203  
   204  	// The name is only used for virtual tables, which can't be looked up by ID.
   205  	ds, err := oc.dataSourceForDesc(ctx, cat.Flags{}, tableLookup.Desc, &tree.TableName{})
   206  	return ds, false, err
   207  }
   208  
   209  func getDescForCatalogObject(o cat.Object) (sqlbase.DescriptorProto, error) {
   210  	switch t := o.(type) {
   211  	case *optSchema:
   212  		return t.desc, nil
   213  	case *optTable:
   214  		return t.desc, nil
   215  	case *optVirtualTable:
   216  		return t.desc, nil
   217  	case *optView:
   218  		return t.desc, nil
   219  	case *optSequence:
   220  		return t.desc, nil
   221  	default:
   222  		return nil, errors.AssertionFailedf("invalid object type: %T", o)
   223  	}
   224  }
   225  
   226  func getDescForDataSource(o cat.DataSource) (*sqlbase.ImmutableTableDescriptor, error) {
   227  	switch t := o.(type) {
   228  	case *optTable:
   229  		return t.desc, nil
   230  	case *optVirtualTable:
   231  		return t.desc, nil
   232  	case *optView:
   233  		return t.desc, nil
   234  	case *optSequence:
   235  		return t.desc, nil
   236  	default:
   237  		return nil, errors.AssertionFailedf("invalid object type: %T", o)
   238  	}
   239  }
   240  
   241  // CheckPrivilege is part of the cat.Catalog interface.
   242  func (oc *optCatalog) CheckPrivilege(ctx context.Context, o cat.Object, priv privilege.Kind) error {
   243  	desc, err := getDescForCatalogObject(o)
   244  	if err != nil {
   245  		return err
   246  	}
   247  	return oc.planner.CheckPrivilege(ctx, desc, priv)
   248  }
   249  
   250  // CheckAnyPrivilege is part of the cat.Catalog interface.
   251  func (oc *optCatalog) CheckAnyPrivilege(ctx context.Context, o cat.Object) error {
   252  	desc, err := getDescForCatalogObject(o)
   253  	if err != nil {
   254  		return err
   255  	}
   256  	return oc.planner.CheckAnyPrivilege(ctx, desc)
   257  }
   258  
   259  // HasAdminRole is part of the cat.Catalog interface.
   260  func (oc *optCatalog) HasAdminRole(ctx context.Context) (bool, error) {
   261  	return oc.planner.HasAdminRole(ctx)
   262  }
   263  
   264  // RequireAdminRole is part of the cat.Catalog interface.
   265  func (oc *optCatalog) RequireAdminRole(ctx context.Context, action string) error {
   266  	return oc.planner.RequireAdminRole(ctx, action)
   267  }
   268  
   269  // FullyQualifiedName is part of the cat.Catalog interface.
   270  func (oc *optCatalog) FullyQualifiedName(
   271  	ctx context.Context, ds cat.DataSource,
   272  ) (cat.DataSourceName, error) {
   273  	return oc.fullyQualifiedNameWithTxn(ctx, ds, oc.planner.Txn())
   274  }
   275  
   276  func (oc *optCatalog) fullyQualifiedNameWithTxn(
   277  	ctx context.Context, ds cat.DataSource, txn *kv.Txn,
   278  ) (cat.DataSourceName, error) {
   279  	if vt, ok := ds.(*optVirtualTable); ok {
   280  		// Virtual tables require special handling, because they can have multiple
   281  		// effective instances that utilize the same descriptor.
   282  		return vt.name, nil
   283  	}
   284  
   285  	desc, err := getDescForDataSource(ds)
   286  	if err != nil {
   287  		return cat.DataSourceName{}, err
   288  	}
   289  
   290  	dbID := desc.ParentID
   291  	dbDesc, err := sqlbase.GetDatabaseDescFromID(ctx, txn, oc.codec(), dbID)
   292  	if err != nil {
   293  		return cat.DataSourceName{}, err
   294  	}
   295  	return tree.MakeTableName(tree.Name(dbDesc.Name), tree.Name(desc.Name)), nil
   296  }
   297  
   298  // dataSourceForDesc returns a data source wrapper for the given descriptor.
   299  // The wrapper might come from the cache, or it may be created now.
   300  func (oc *optCatalog) dataSourceForDesc(
   301  	ctx context.Context,
   302  	flags cat.Flags,
   303  	desc *sqlbase.ImmutableTableDescriptor,
   304  	name *cat.DataSourceName,
   305  ) (cat.DataSource, error) {
   306  	if desc.IsTable() {
   307  		// Tables require invalidation logic for cached wrappers.
   308  		return oc.dataSourceForTable(ctx, flags, desc, name)
   309  	}
   310  
   311  	ds, ok := oc.dataSources[desc]
   312  	if ok {
   313  		return ds, nil
   314  	}
   315  
   316  	switch {
   317  	case desc.IsView():
   318  		ds = newOptView(desc)
   319  
   320  	case desc.IsSequence():
   321  		ds = newOptSequence(desc)
   322  
   323  	default:
   324  		return nil, errors.AssertionFailedf("unexpected table descriptor: %+v", desc)
   325  	}
   326  
   327  	oc.dataSources[desc] = ds
   328  	return ds, nil
   329  }
   330  
   331  // dataSourceForTable returns a table data source wrapper for the given descriptor.
   332  // The wrapper might come from the cache, or it may be created now.
   333  func (oc *optCatalog) dataSourceForTable(
   334  	ctx context.Context,
   335  	flags cat.Flags,
   336  	desc *sqlbase.ImmutableTableDescriptor,
   337  	name *cat.DataSourceName,
   338  ) (cat.DataSource, error) {
   339  	if desc.IsVirtualTable() {
   340  		// Virtual tables can have multiple effective instances that utilize the
   341  		// same descriptor, so we can't cache them (see the comment for
   342  		// optVirtualTable.id for more information).
   343  		return newOptVirtualTable(ctx, oc, desc, name)
   344  	}
   345  
   346  	// Even if we have a cached data source, we still have to cross-check that
   347  	// statistics and the zone config haven't changed.
   348  	var tableStats []*stats.TableStatistic
   349  	if !flags.NoTableStats {
   350  		var err error
   351  		tableStats, err = oc.planner.execCfg.TableStatsCache.GetTableStats(context.TODO(), desc.ID)
   352  		if err != nil {
   353  			// Ignore any error. We still want to be able to run queries even if we lose
   354  			// access to the statistics table.
   355  			// TODO(radu): at least log the error.
   356  			tableStats = nil
   357  		}
   358  	}
   359  
   360  	zoneConfig, err := oc.getZoneConfig(desc)
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  
   365  	// Check to see if there's already a data source wrapper for this descriptor,
   366  	// and it was created with the same stats and zone config.
   367  	if ds, ok := oc.dataSources[desc]; ok && !ds.(*optTable).isStale(tableStats, zoneConfig) {
   368  		return ds, nil
   369  	}
   370  
   371  	ds, err := newOptTable(desc, oc.codec(), tableStats, zoneConfig)
   372  	if err != nil {
   373  		return nil, err
   374  	}
   375  	oc.dataSources[desc] = ds
   376  	return ds, nil
   377  }
   378  
   379  var emptyZoneConfig = &zonepb.ZoneConfig{}
   380  
   381  // getZoneConfig returns the ZoneConfig data structure for the given table.
   382  // ZoneConfigs are stored in protobuf binary format in the SystemConfig, which
   383  // is gossiped around the cluster. Note that the returned ZoneConfig might be
   384  // somewhat stale, since it's taken from the gossiped SystemConfig.
   385  func (oc *optCatalog) getZoneConfig(
   386  	desc *sqlbase.ImmutableTableDescriptor,
   387  ) (*zonepb.ZoneConfig, error) {
   388  	// Lookup table's zone if system config is available (it may not be as node
   389  	// is starting up and before it's received the gossiped config). If it is
   390  	// not available, use an empty config that has no zone constraints.
   391  	if oc.cfg == nil || desc.IsVirtualTable() {
   392  		return emptyZoneConfig, nil
   393  	}
   394  	zone, err := oc.cfg.GetZoneConfigForObject(uint32(desc.ID))
   395  	if err != nil {
   396  		return nil, err
   397  	}
   398  	if zone == nil {
   399  		// This can happen with tests that override the hook.
   400  		zone = emptyZoneConfig
   401  	}
   402  	return zone, err
   403  }
   404  
   405  func (oc *optCatalog) codec() keys.SQLCodec {
   406  	return oc.planner.ExecCfg().Codec
   407  }
   408  
   409  // optView is a wrapper around sqlbase.ImmutableTableDescriptor that implements
   410  // the cat.Object, cat.DataSource, and cat.View interfaces.
   411  type optView struct {
   412  	desc *sqlbase.ImmutableTableDescriptor
   413  }
   414  
   415  var _ cat.View = &optView{}
   416  
   417  func newOptView(desc *sqlbase.ImmutableTableDescriptor) *optView {
   418  	return &optView{desc: desc}
   419  }
   420  
   421  // ID is part of the cat.Object interface.
   422  func (ov *optView) ID() cat.StableID {
   423  	return cat.StableID(ov.desc.ID)
   424  }
   425  
   426  // PostgresDescriptorID is part of the cat.Object interface.
   427  func (ov *optView) PostgresDescriptorID() cat.StableID {
   428  	return cat.StableID(ov.desc.ID)
   429  }
   430  
   431  // Equals is part of the cat.Object interface.
   432  func (ov *optView) Equals(other cat.Object) bool {
   433  	otherView, ok := other.(*optView)
   434  	if !ok {
   435  		return false
   436  	}
   437  	return ov.desc.ID == otherView.desc.ID && ov.desc.Version == otherView.desc.Version
   438  }
   439  
   440  // Name is part of the cat.View interface.
   441  func (ov *optView) Name() tree.Name {
   442  	return tree.Name(ov.desc.Name)
   443  }
   444  
   445  // IsSystemView is part of the cat.View interface.
   446  func (ov *optView) IsSystemView() bool {
   447  	return ov.desc.IsVirtualTable()
   448  }
   449  
   450  // Query is part of the cat.View interface.
   451  func (ov *optView) Query() string {
   452  	return ov.desc.ViewQuery
   453  }
   454  
   455  // ColumnNameCount is part of the cat.View interface.
   456  func (ov *optView) ColumnNameCount() int {
   457  	return len(ov.desc.Columns)
   458  }
   459  
   460  // ColumnName is part of the cat.View interface.
   461  func (ov *optView) ColumnName(i int) tree.Name {
   462  	return tree.Name(ov.desc.Columns[i].Name)
   463  }
   464  
   465  // optSequence is a wrapper around sqlbase.ImmutableTableDescriptor that
   466  // implements the cat.Object and cat.DataSource interfaces.
   467  type optSequence struct {
   468  	desc *sqlbase.ImmutableTableDescriptor
   469  }
   470  
   471  var _ cat.DataSource = &optSequence{}
   472  var _ cat.Sequence = &optSequence{}
   473  
   474  func newOptSequence(desc *sqlbase.ImmutableTableDescriptor) *optSequence {
   475  	return &optSequence{desc: desc}
   476  }
   477  
   478  // ID is part of the cat.Object interface.
   479  func (os *optSequence) ID() cat.StableID {
   480  	return cat.StableID(os.desc.ID)
   481  }
   482  
   483  // PostgresDescriptorID is part of the cat.Object interface.
   484  func (os *optSequence) PostgresDescriptorID() cat.StableID {
   485  	return cat.StableID(os.desc.ID)
   486  }
   487  
   488  // Equals is part of the cat.Object interface.
   489  func (os *optSequence) Equals(other cat.Object) bool {
   490  	otherSeq, ok := other.(*optSequence)
   491  	if !ok {
   492  		return false
   493  	}
   494  	return os.desc.ID == otherSeq.desc.ID && os.desc.Version == otherSeq.desc.Version
   495  }
   496  
   497  // Name is part of the cat.Sequence interface.
   498  func (os *optSequence) Name() tree.Name {
   499  	return tree.Name(os.desc.Name)
   500  }
   501  
   502  // SequenceMarker is part of the cat.Sequence interface.
   503  func (os *optSequence) SequenceMarker() {}
   504  
   505  // optTable is a wrapper around sqlbase.ImmutableTableDescriptor that caches
   506  // index wrappers and maintains a ColumnID => Column mapping for fast lookup.
   507  type optTable struct {
   508  	desc *sqlbase.ImmutableTableDescriptor
   509  
   510  	// indexes are the inlined wrappers for the table's primary and secondary
   511  	// indexes.
   512  	indexes []optIndex
   513  
   514  	// codec is capable of encoding sql table keys.
   515  	codec keys.SQLCodec
   516  
   517  	// rawStats stores the original table statistics slice. Used for a fast-path
   518  	// check that the statistics haven't changed.
   519  	rawStats []*stats.TableStatistic
   520  
   521  	// stats are the inlined wrappers for table statistics.
   522  	stats []optTableStat
   523  
   524  	zone *zonepb.ZoneConfig
   525  
   526  	// family is the inlined wrapper for the table's primary family. The primary
   527  	// family is the first family explicitly specified by the user. If no families
   528  	// were explicitly specified, then the primary family is synthesized.
   529  	primaryFamily optFamily
   530  
   531  	// families are the inlined wrappers for the table's non-primary families,
   532  	// which are all the families specified by the user after the first. The
   533  	// primary family is kept separate since the common case is that there's just
   534  	// one family.
   535  	families []optFamily
   536  
   537  	outboundFKs []optForeignKeyConstraint
   538  	inboundFKs  []optForeignKeyConstraint
   539  
   540  	// colMap is a mapping from unique ColumnID to column ordinal within the
   541  	// table. This is a common lookup that needs to be fast.
   542  	colMap map[sqlbase.ColumnID]int
   543  }
   544  
   545  var _ cat.Table = &optTable{}
   546  
   547  func newOptTable(
   548  	desc *sqlbase.ImmutableTableDescriptor,
   549  	codec keys.SQLCodec,
   550  	stats []*stats.TableStatistic,
   551  	tblZone *zonepb.ZoneConfig,
   552  ) (*optTable, error) {
   553  	ot := &optTable{
   554  		desc:     desc,
   555  		codec:    codec,
   556  		rawStats: stats,
   557  		zone:     tblZone,
   558  	}
   559  
   560  	// Create the table's column mapping from sqlbase.ColumnID to column ordinal.
   561  	ot.colMap = make(map[sqlbase.ColumnID]int, ot.DeletableColumnCount())
   562  	for i, n := 0, ot.DeletableColumnCount(); i < n; i++ {
   563  		ot.colMap[sqlbase.ColumnID(ot.Column(i).ColID())] = i
   564  	}
   565  
   566  	// Build the indexes (add 1 to account for lack of primary index in
   567  	// DeletableIndexes slice).
   568  	ot.indexes = make([]optIndex, 1+len(ot.desc.DeletableIndexes()))
   569  
   570  	for i := range ot.indexes {
   571  		var idxDesc *sqlbase.IndexDescriptor
   572  		if i == 0 {
   573  			idxDesc = &desc.PrimaryIndex
   574  		} else {
   575  			idxDesc = &ot.desc.DeletableIndexes()[i-1]
   576  		}
   577  
   578  		// If there is a subzone that applies to the entire index, use that,
   579  		// else use the table zone. Skip subzones that apply to partitions,
   580  		// since they apply only to a subset of the index.
   581  		idxZone := tblZone
   582  		for j := range tblZone.Subzones {
   583  			subzone := &tblZone.Subzones[j]
   584  			if subzone.IndexID == uint32(idxDesc.ID) && subzone.PartitionName == "" {
   585  				copyZone := subzone.Config
   586  				copyZone.InheritFromParent(tblZone)
   587  				idxZone = &copyZone
   588  			}
   589  		}
   590  		ot.indexes[i].init(ot, i, idxDesc, idxZone)
   591  	}
   592  
   593  	for i := range ot.desc.OutboundFKs {
   594  		fk := &ot.desc.OutboundFKs[i]
   595  		ot.outboundFKs = append(ot.outboundFKs, optForeignKeyConstraint{
   596  			name:              fk.Name,
   597  			originTable:       ot.ID(),
   598  			originColumns:     fk.OriginColumnIDs,
   599  			referencedTable:   cat.StableID(fk.ReferencedTableID),
   600  			referencedColumns: fk.ReferencedColumnIDs,
   601  			validity:          fk.Validity,
   602  			match:             fk.Match,
   603  			deleteAction:      fk.OnDelete,
   604  			updateAction:      fk.OnUpdate,
   605  		})
   606  	}
   607  	for i := range ot.desc.InboundFKs {
   608  		fk := &ot.desc.InboundFKs[i]
   609  		ot.inboundFKs = append(ot.inboundFKs, optForeignKeyConstraint{
   610  			name:              fk.Name,
   611  			originTable:       cat.StableID(fk.OriginTableID),
   612  			originColumns:     fk.OriginColumnIDs,
   613  			referencedTable:   ot.ID(),
   614  			referencedColumns: fk.ReferencedColumnIDs,
   615  			validity:          fk.Validity,
   616  			match:             fk.Match,
   617  			deleteAction:      fk.OnDelete,
   618  			updateAction:      fk.OnUpdate,
   619  		})
   620  	}
   621  
   622  	ot.primaryFamily.init(ot, &desc.Families[0])
   623  	ot.families = make([]optFamily, len(desc.Families)-1)
   624  	for i := range ot.families {
   625  		ot.families[i].init(ot, &desc.Families[i+1])
   626  	}
   627  
   628  	// Add stats last, now that other metadata is initialized.
   629  	if stats != nil {
   630  		ot.stats = make([]optTableStat, len(stats))
   631  		n := 0
   632  		for i := range stats {
   633  			// We skip any stats that have columns that don't exist in the table anymore.
   634  			if ok, err := ot.stats[n].init(ot, stats[i]); err != nil {
   635  				return nil, err
   636  			} else if ok {
   637  				n++
   638  			}
   639  		}
   640  		ot.stats = ot.stats[:n]
   641  	}
   642  
   643  	return ot, nil
   644  }
   645  
   646  // ID is part of the cat.Object interface.
   647  func (ot *optTable) ID() cat.StableID {
   648  	return cat.StableID(ot.desc.ID)
   649  }
   650  
   651  // PostgresDescriptorID is part of the cat.Object interface.
   652  func (ot *optTable) PostgresDescriptorID() cat.StableID {
   653  	return cat.StableID(ot.desc.ID)
   654  }
   655  
   656  // isStale checks if the optTable object needs to be refreshed because the stats
   657  // or zone config have changed. False positives are ok.
   658  func (ot *optTable) isStale(tableStats []*stats.TableStatistic, zone *zonepb.ZoneConfig) bool {
   659  	// Fast check to verify that the statistics haven't changed: we check the
   660  	// length and the address of the underlying array. This is not a perfect
   661  	// check (in principle, the stats could have left the cache and then gotten
   662  	// regenerated), but it works in the common case.
   663  	if len(tableStats) != len(ot.rawStats) {
   664  		return true
   665  	}
   666  	if len(tableStats) > 0 && &tableStats[0] != &ot.rawStats[0] {
   667  		return true
   668  	}
   669  	if !zone.Equal(ot.zone) {
   670  		return true
   671  	}
   672  	return false
   673  }
   674  
   675  // Equals is part of the cat.Object interface.
   676  func (ot *optTable) Equals(other cat.Object) bool {
   677  	otherTable, ok := other.(*optTable)
   678  	if !ok {
   679  		return false
   680  	}
   681  	if ot == otherTable {
   682  		// Fast path when it is the same object.
   683  		return true
   684  	}
   685  	if ot.desc.ID != otherTable.desc.ID || ot.desc.Version != otherTable.desc.Version {
   686  		return false
   687  	}
   688  
   689  	// Verify the stats are identical.
   690  	if len(ot.stats) != len(otherTable.stats) {
   691  		return false
   692  	}
   693  	for i := range ot.stats {
   694  		if !ot.stats[i].equals(&otherTable.stats[i]) {
   695  			return false
   696  		}
   697  	}
   698  
   699  	// Verify that indexes are in same zones. For performance, skip deep equality
   700  	// check if it's the same as the previous index (common case).
   701  	var prevLeftZone, prevRightZone *zonepb.ZoneConfig
   702  	for i := range ot.indexes {
   703  		leftZone := ot.indexes[i].zone
   704  		rightZone := otherTable.indexes[i].zone
   705  		if leftZone == prevLeftZone && rightZone == prevRightZone {
   706  			continue
   707  		}
   708  		if !leftZone.Equal(rightZone) {
   709  			return false
   710  		}
   711  		prevLeftZone = leftZone
   712  		prevRightZone = rightZone
   713  	}
   714  
   715  	return true
   716  }
   717  
   718  // Name is part of the cat.Table interface.
   719  func (ot *optTable) Name() tree.Name {
   720  	return tree.Name(ot.desc.Name)
   721  }
   722  
   723  // IsVirtualTable is part of the cat.Table interface.
   724  func (ot *optTable) IsVirtualTable() bool {
   725  	return false
   726  }
   727  
   728  // ColumnCount is part of the cat.Table interface.
   729  func (ot *optTable) ColumnCount() int {
   730  	return len(ot.desc.Columns)
   731  }
   732  
   733  // WritableColumnCount is part of the cat.Table interface.
   734  func (ot *optTable) WritableColumnCount() int {
   735  	return len(ot.desc.WritableColumns())
   736  }
   737  
   738  // DeletableColumnCount is part of the cat.Table interface.
   739  func (ot *optTable) DeletableColumnCount() int {
   740  	return len(ot.desc.DeletableColumns())
   741  }
   742  
   743  // Column is part of the cat.Table interface.
   744  func (ot *optTable) Column(i int) cat.Column {
   745  	return &ot.desc.DeletableColumns()[i]
   746  }
   747  
   748  // IndexCount is part of the cat.Table interface.
   749  func (ot *optTable) IndexCount() int {
   750  	// Primary index is always present, so count is always >= 1.
   751  	return 1 + len(ot.desc.Indexes)
   752  }
   753  
   754  // WritableIndexCount is part of the cat.Table interface.
   755  func (ot *optTable) WritableIndexCount() int {
   756  	// Primary index is always present, so count is always >= 1.
   757  	return 1 + len(ot.desc.WritableIndexes())
   758  }
   759  
   760  // DeletableIndexCount is part of the cat.Table interface.
   761  func (ot *optTable) DeletableIndexCount() int {
   762  	// Primary index is always present, so count is always >= 1.
   763  	return 1 + len(ot.desc.DeletableIndexes())
   764  }
   765  
   766  // Index is part of the cat.Table interface.
   767  func (ot *optTable) Index(i cat.IndexOrdinal) cat.Index {
   768  	return &ot.indexes[i]
   769  }
   770  
   771  // StatisticCount is part of the cat.Table interface.
   772  func (ot *optTable) StatisticCount() int {
   773  	return len(ot.stats)
   774  }
   775  
   776  // Statistic is part of the cat.Table interface.
   777  func (ot *optTable) Statistic(i int) cat.TableStatistic {
   778  	return &ot.stats[i]
   779  }
   780  
   781  // CheckCount is part of the cat.Table interface.
   782  func (ot *optTable) CheckCount() int {
   783  	return len(ot.desc.ActiveChecks())
   784  }
   785  
   786  // Check is part of the cat.Table interface.
   787  func (ot *optTable) Check(i int) cat.CheckConstraint {
   788  	check := ot.desc.ActiveChecks()[i]
   789  	return cat.CheckConstraint{
   790  		Constraint: check.Expr,
   791  		Validated:  check.Validity == sqlbase.ConstraintValidity_Validated,
   792  	}
   793  }
   794  
   795  // FamilyCount is part of the cat.Table interface.
   796  func (ot *optTable) FamilyCount() int {
   797  	return 1 + len(ot.families)
   798  }
   799  
   800  // Family is part of the cat.Table interface.
   801  func (ot *optTable) Family(i int) cat.Family {
   802  	if i == 0 {
   803  		return &ot.primaryFamily
   804  	}
   805  	return &ot.families[i-1]
   806  }
   807  
   808  // OutboundForeignKeyCount is part of the cat.Table interface.
   809  func (ot *optTable) OutboundForeignKeyCount() int {
   810  	return len(ot.outboundFKs)
   811  }
   812  
   813  // OutboundForeignKeyCount is part of the cat.Table interface.
   814  func (ot *optTable) OutboundForeignKey(i int) cat.ForeignKeyConstraint {
   815  	return &ot.outboundFKs[i]
   816  }
   817  
   818  // InboundForeignKeyCount is part of the cat.Table interface.
   819  func (ot *optTable) InboundForeignKeyCount() int {
   820  	return len(ot.inboundFKs)
   821  }
   822  
   823  // InboundForeignKey is part of the cat.Table interface.
   824  func (ot *optTable) InboundForeignKey(i int) cat.ForeignKeyConstraint {
   825  	return &ot.inboundFKs[i]
   826  }
   827  
   828  // lookupColumnOrdinal returns the ordinal of the column with the given ID. A
   829  // cache makes the lookup O(1).
   830  func (ot *optTable) lookupColumnOrdinal(colID sqlbase.ColumnID) (int, error) {
   831  	col, ok := ot.colMap[colID]
   832  	if ok {
   833  		return col, nil
   834  	}
   835  	return col, pgerror.Newf(pgcode.UndefinedColumn,
   836  		"column [%d] does not exist", colID)
   837  }
   838  
   839  // optIndex is a wrapper around sqlbase.IndexDescriptor that caches some
   840  // commonly accessed information and keeps a reference to the table wrapper.
   841  type optIndex struct {
   842  	tab  *optTable
   843  	desc *sqlbase.IndexDescriptor
   844  	zone *zonepb.ZoneConfig
   845  
   846  	// storedCols is the set of non-PK columns if this is the primary index,
   847  	// otherwise it is desc.StoreColumnIDs.
   848  	storedCols []sqlbase.ColumnID
   849  
   850  	indexOrdinal  int
   851  	numCols       int
   852  	numKeyCols    int
   853  	numLaxKeyCols int
   854  }
   855  
   856  var _ cat.Index = &optIndex{}
   857  
   858  // init can be used instead of newOptIndex when we have a pre-allocated instance
   859  // (e.g. as part of a bigger struct).
   860  func (oi *optIndex) init(
   861  	tab *optTable, indexOrdinal int, desc *sqlbase.IndexDescriptor, zone *zonepb.ZoneConfig,
   862  ) {
   863  	oi.tab = tab
   864  	oi.desc = desc
   865  	oi.zone = zone
   866  	oi.indexOrdinal = indexOrdinal
   867  	if desc == &tab.desc.PrimaryIndex {
   868  		// Although the primary index contains all columns in the table, the index
   869  		// descriptor does not contain columns that are not explicitly part of the
   870  		// primary key. Retrieve those columns from the table descriptor.
   871  		oi.storedCols = make([]sqlbase.ColumnID, 0, tab.DeletableColumnCount()-len(desc.ColumnIDs))
   872  		var pkCols util.FastIntSet
   873  		for i := range desc.ColumnIDs {
   874  			pkCols.Add(int(desc.ColumnIDs[i]))
   875  		}
   876  		for i, n := 0, tab.DeletableColumnCount(); i < n; i++ {
   877  			id := tab.Column(i).ColID()
   878  			if !pkCols.Contains(int(id)) {
   879  				oi.storedCols = append(oi.storedCols, sqlbase.ColumnID(id))
   880  			}
   881  		}
   882  		oi.numCols = tab.DeletableColumnCount()
   883  	} else {
   884  		oi.storedCols = desc.StoreColumnIDs
   885  		oi.numCols = len(desc.ColumnIDs) + len(desc.ExtraColumnIDs) + len(desc.StoreColumnIDs)
   886  	}
   887  
   888  	if desc.Unique {
   889  		notNull := true
   890  		for _, id := range desc.ColumnIDs {
   891  			ord, _ := tab.lookupColumnOrdinal(id)
   892  			if tab.desc.DeletableColumns()[ord].Nullable {
   893  				notNull = false
   894  				break
   895  			}
   896  		}
   897  
   898  		if notNull {
   899  			// Unique index with no null columns: columns from index are sufficient
   900  			// to form a key without needing extra primary key columns. There is no
   901  			// separate lax key.
   902  			oi.numLaxKeyCols = len(desc.ColumnIDs)
   903  			oi.numKeyCols = oi.numLaxKeyCols
   904  		} else {
   905  			// Unique index with at least one nullable column: extra primary key
   906  			// columns will be added to the row key when one of the unique index
   907  			// columns has a NULL value.
   908  			oi.numLaxKeyCols = len(desc.ColumnIDs)
   909  			oi.numKeyCols = oi.numLaxKeyCols + len(desc.ExtraColumnIDs)
   910  		}
   911  	} else {
   912  		// Non-unique index: extra primary key columns are always added to the row
   913  		// key. There is no separate lax key.
   914  		oi.numLaxKeyCols = len(desc.ColumnIDs) + len(desc.ExtraColumnIDs)
   915  		oi.numKeyCols = oi.numLaxKeyCols
   916  	}
   917  }
   918  
   919  // ID is part of the cat.Index interface.
   920  func (oi *optIndex) ID() cat.StableID {
   921  	return cat.StableID(oi.desc.ID)
   922  }
   923  
   924  // Name is part of the cat.Index interface.
   925  func (oi *optIndex) Name() tree.Name {
   926  	return tree.Name(oi.desc.Name)
   927  }
   928  
   929  // IsUnique is part of the cat.Index interface.
   930  func (oi *optIndex) IsUnique() bool {
   931  	return oi.desc.Unique
   932  }
   933  
   934  // IsInverted is part of the cat.Index interface.
   935  func (oi *optIndex) IsInverted() bool {
   936  	return oi.desc.Type == sqlbase.IndexDescriptor_INVERTED
   937  }
   938  
   939  // ColumnCount is part of the cat.Index interface.
   940  func (oi *optIndex) ColumnCount() int {
   941  	return oi.numCols
   942  }
   943  
   944  // Predicate is part of the cat.Index interface. It returns the predicate
   945  // expression and true if the index is a partial index. If the index is not
   946  // partial, the empty string and false is returned.
   947  func (oi *optIndex) Predicate() (string, bool) {
   948  	return oi.desc.Predicate, oi.desc.Predicate != ""
   949  }
   950  
   951  // KeyColumnCount is part of the cat.Index interface.
   952  func (oi *optIndex) KeyColumnCount() int {
   953  	return oi.numKeyCols
   954  }
   955  
   956  // LaxKeyColumnCount is part of the cat.Index interface.
   957  func (oi *optIndex) LaxKeyColumnCount() int {
   958  	return oi.numLaxKeyCols
   959  }
   960  
   961  // Column is part of the cat.Index interface.
   962  func (oi *optIndex) Column(i int) cat.IndexColumn {
   963  	length := len(oi.desc.ColumnIDs)
   964  	if i < length {
   965  		ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i])
   966  		return cat.IndexColumn{
   967  			Column:     oi.tab.Column(ord),
   968  			Ordinal:    ord,
   969  			Descending: oi.desc.ColumnDirections[i] == sqlbase.IndexDescriptor_DESC,
   970  		}
   971  	}
   972  
   973  	i -= length
   974  	length = len(oi.desc.ExtraColumnIDs)
   975  	if i < length {
   976  		ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ExtraColumnIDs[i])
   977  		return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord}
   978  	}
   979  
   980  	i -= length
   981  	ord, _ := oi.tab.lookupColumnOrdinal(oi.storedCols[i])
   982  	return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord}
   983  }
   984  
   985  // Zone is part of the cat.Index interface.
   986  func (oi *optIndex) Zone() cat.Zone {
   987  	return oi.zone
   988  }
   989  
   990  // Span is part of the cat.Index interface.
   991  func (oi *optIndex) Span() roachpb.Span {
   992  	desc := oi.tab.desc
   993  	// Tables up to MaxSystemConfigDescID are grouped in a single system config
   994  	// span.
   995  	if desc.ID <= keys.MaxSystemConfigDescID {
   996  		return keys.SystemConfigSpan
   997  	}
   998  	return desc.IndexSpan(oi.tab.codec, oi.desc.ID)
   999  }
  1000  
  1001  // Table is part of the cat.Index interface.
  1002  func (oi *optIndex) Table() cat.Table {
  1003  	return oi.tab
  1004  }
  1005  
  1006  // Ordinal is part of the cat.Index interface.
  1007  func (oi *optIndex) Ordinal() int {
  1008  	return oi.indexOrdinal
  1009  }
  1010  
  1011  // PartitionByListPrefixes is part of the cat.Index interface.
  1012  func (oi *optIndex) PartitionByListPrefixes() []tree.Datums {
  1013  	list := oi.desc.Partitioning.List
  1014  	if len(list) == 0 {
  1015  		return nil
  1016  	}
  1017  	res := make([]tree.Datums, 0, len(list))
  1018  	var a sqlbase.DatumAlloc
  1019  	for i := range list {
  1020  		for _, valueEncBuf := range list[i].Values {
  1021  			t, _, err := sqlbase.DecodePartitionTuple(
  1022  				&a, oi.tab.codec, &oi.tab.desc.TableDescriptor, oi.desc, &oi.desc.Partitioning,
  1023  				valueEncBuf, nil, /* prefixDatums */
  1024  			)
  1025  			if err != nil {
  1026  				panic(errors.NewAssertionErrorWithWrappedErrf(err, "while decoding partition tuple"))
  1027  			}
  1028  			// Ignore the DEFAULT case, where there is nothing to return.
  1029  			if len(t.Datums) > 0 {
  1030  				res = append(res, t.Datums)
  1031  			}
  1032  			// TODO(radu): split into multiple prefixes if Subpartition is also by list.
  1033  			// Note that this functionality should be kept in sync with the test catalog
  1034  			// implementation (test_catalog.go).
  1035  		}
  1036  	}
  1037  	return res
  1038  }
  1039  
  1040  // InterleaveAncestorCount is part of the cat.Index interface.
  1041  func (oi *optIndex) InterleaveAncestorCount() int {
  1042  	return len(oi.desc.Interleave.Ancestors)
  1043  }
  1044  
  1045  // InterleaveAncestor is part of the cat.Index interface.
  1046  func (oi *optIndex) InterleaveAncestor(i int) (table, index cat.StableID, numKeyCols int) {
  1047  	a := &oi.desc.Interleave.Ancestors[i]
  1048  	return cat.StableID(a.TableID), cat.StableID(a.IndexID), int(a.SharedPrefixLen)
  1049  }
  1050  
  1051  // InterleavedByCount is part of the cat.Index interface.
  1052  func (oi *optIndex) InterleavedByCount() int {
  1053  	return len(oi.desc.InterleavedBy)
  1054  }
  1055  
  1056  // InterleavedBy is part of the cat.Index interface.
  1057  func (oi *optIndex) InterleavedBy(i int) (table, index cat.StableID) {
  1058  	ref := &oi.desc.InterleavedBy[i]
  1059  	return cat.StableID(ref.Table), cat.StableID(ref.Index)
  1060  }
  1061  
  1062  type optTableStat struct {
  1063  	stat           *stats.TableStatistic
  1064  	columnOrdinals []int
  1065  }
  1066  
  1067  var _ cat.TableStatistic = &optTableStat{}
  1068  
  1069  func (os *optTableStat) init(tab *optTable, stat *stats.TableStatistic) (ok bool, _ error) {
  1070  	os.stat = stat
  1071  	os.columnOrdinals = make([]int, len(stat.ColumnIDs))
  1072  	for i, c := range stat.ColumnIDs {
  1073  		var ok bool
  1074  		os.columnOrdinals[i], ok = tab.colMap[c]
  1075  		if !ok {
  1076  			// Column not in table (this is possible if the column was removed since
  1077  			// the statistic was calculated).
  1078  			return false, nil
  1079  		}
  1080  	}
  1081  
  1082  	return true, nil
  1083  }
  1084  
  1085  func (os *optTableStat) equals(other *optTableStat) bool {
  1086  	// Two table statistics are considered equal if they have been created at the
  1087  	// same time, on the same set of columns.
  1088  	if os.CreatedAt() != other.CreatedAt() || len(os.columnOrdinals) != len(other.columnOrdinals) {
  1089  		return false
  1090  	}
  1091  	for i, c := range os.columnOrdinals {
  1092  		if c != other.columnOrdinals[i] {
  1093  			return false
  1094  		}
  1095  	}
  1096  	return true
  1097  }
  1098  
  1099  // CreatedAt is part of the cat.TableStatistic interface.
  1100  func (os *optTableStat) CreatedAt() time.Time {
  1101  	return os.stat.CreatedAt
  1102  }
  1103  
  1104  // ColumnCount is part of the cat.TableStatistic interface.
  1105  func (os *optTableStat) ColumnCount() int {
  1106  	return len(os.columnOrdinals)
  1107  }
  1108  
  1109  // ColumnOrdinal is part of the cat.TableStatistic interface.
  1110  func (os *optTableStat) ColumnOrdinal(i int) int {
  1111  	return os.columnOrdinals[i]
  1112  }
  1113  
  1114  // RowCount is part of the cat.TableStatistic interface.
  1115  func (os *optTableStat) RowCount() uint64 {
  1116  	return os.stat.RowCount
  1117  }
  1118  
  1119  // DistinctCount is part of the cat.TableStatistic interface.
  1120  func (os *optTableStat) DistinctCount() uint64 {
  1121  	return os.stat.DistinctCount
  1122  }
  1123  
  1124  // NullCount is part of the cat.TableStatistic interface.
  1125  func (os *optTableStat) NullCount() uint64 {
  1126  	return os.stat.NullCount
  1127  }
  1128  
  1129  // Histogram is part of the cat.TableStatistic interface.
  1130  func (os *optTableStat) Histogram() []cat.HistogramBucket {
  1131  	return os.stat.Histogram
  1132  }
  1133  
  1134  // optFamily is a wrapper around sqlbase.ColumnFamilyDescriptor that keeps a
  1135  // reference to the table wrapper.
  1136  type optFamily struct {
  1137  	tab  *optTable
  1138  	desc *sqlbase.ColumnFamilyDescriptor
  1139  }
  1140  
  1141  var _ cat.Family = &optFamily{}
  1142  
  1143  // init can be used instead of newOptFamily when we have a pre-allocated
  1144  // instance (e.g. as part of a bigger struct).
  1145  func (oi *optFamily) init(tab *optTable, desc *sqlbase.ColumnFamilyDescriptor) {
  1146  	oi.tab = tab
  1147  	oi.desc = desc
  1148  }
  1149  
  1150  // ID is part of the cat.Family interface.
  1151  func (oi *optFamily) ID() cat.StableID {
  1152  	return cat.StableID(oi.desc.ID)
  1153  }
  1154  
  1155  // Name is part of the cat.Family interface.
  1156  func (oi *optFamily) Name() tree.Name {
  1157  	return tree.Name(oi.desc.Name)
  1158  }
  1159  
  1160  // ColumnCount is part of the cat.Family interface.
  1161  func (oi *optFamily) ColumnCount() int {
  1162  	return len(oi.desc.ColumnIDs)
  1163  }
  1164  
  1165  // Column is part of the cat.Family interface.
  1166  func (oi *optFamily) Column(i int) cat.FamilyColumn {
  1167  	ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i])
  1168  	return cat.FamilyColumn{Column: oi.tab.Column(ord), Ordinal: ord}
  1169  }
  1170  
  1171  // Table is part of the cat.Family interface.
  1172  func (oi *optFamily) Table() cat.Table {
  1173  	return oi.tab
  1174  }
  1175  
  1176  // optForeignKeyConstraint implements cat.ForeignKeyConstraint and represents a
  1177  // foreign key relationship. Both the origin and the referenced table store the
  1178  // same optForeignKeyConstraint (as an outbound and inbound reference,
  1179  // respectively).
  1180  type optForeignKeyConstraint struct {
  1181  	name string
  1182  
  1183  	originTable   cat.StableID
  1184  	originColumns []sqlbase.ColumnID
  1185  
  1186  	referencedTable   cat.StableID
  1187  	referencedColumns []sqlbase.ColumnID
  1188  
  1189  	validity     sqlbase.ConstraintValidity
  1190  	match        sqlbase.ForeignKeyReference_Match
  1191  	deleteAction sqlbase.ForeignKeyReference_Action
  1192  	updateAction sqlbase.ForeignKeyReference_Action
  1193  }
  1194  
  1195  var _ cat.ForeignKeyConstraint = &optForeignKeyConstraint{}
  1196  
  1197  // Name is part of the cat.ForeignKeyConstraint interface.
  1198  func (fk *optForeignKeyConstraint) Name() string {
  1199  	return fk.name
  1200  }
  1201  
  1202  // OriginTableID is part of the cat.ForeignKeyConstraint interface.
  1203  func (fk *optForeignKeyConstraint) OriginTableID() cat.StableID {
  1204  	return fk.originTable
  1205  }
  1206  
  1207  // ReferencedTableID is part of the cat.ForeignKeyConstraint interface.
  1208  func (fk *optForeignKeyConstraint) ReferencedTableID() cat.StableID {
  1209  	return fk.referencedTable
  1210  }
  1211  
  1212  // ColumnCount is part of the cat.ForeignKeyConstraint interface.
  1213  func (fk *optForeignKeyConstraint) ColumnCount() int {
  1214  	return len(fk.originColumns)
  1215  }
  1216  
  1217  // OriginColumnOrdinal is part of the cat.ForeignKeyConstraint interface.
  1218  func (fk *optForeignKeyConstraint) OriginColumnOrdinal(originTable cat.Table, i int) int {
  1219  	if originTable.ID() != fk.originTable {
  1220  		panic(errors.AssertionFailedf(
  1221  			"invalid table %d passed to OriginColumnOrdinal (expected %d)",
  1222  			originTable.ID(), fk.originTable,
  1223  		))
  1224  	}
  1225  
  1226  	tab := originTable.(*optTable)
  1227  	ord, _ := tab.lookupColumnOrdinal(fk.originColumns[i])
  1228  	return ord
  1229  }
  1230  
  1231  // ReferencedColumnOrdinal is part of the cat.ForeignKeyConstraint interface.
  1232  func (fk *optForeignKeyConstraint) ReferencedColumnOrdinal(referencedTable cat.Table, i int) int {
  1233  	if referencedTable.ID() != fk.referencedTable {
  1234  		panic(errors.AssertionFailedf(
  1235  			"invalid table %d passed to ReferencedColumnOrdinal (expected %d)",
  1236  			referencedTable.ID(), fk.referencedTable,
  1237  		))
  1238  	}
  1239  	tab := referencedTable.(*optTable)
  1240  	ord, _ := tab.lookupColumnOrdinal(fk.referencedColumns[i])
  1241  	return ord
  1242  }
  1243  
  1244  // Validated is part of the cat.ForeignKeyConstraint interface.
  1245  func (fk *optForeignKeyConstraint) Validated() bool {
  1246  	return fk.validity == sqlbase.ConstraintValidity_Validated
  1247  }
  1248  
  1249  // MatchMethod is part of the cat.ForeignKeyConstraint interface.
  1250  func (fk *optForeignKeyConstraint) MatchMethod() tree.CompositeKeyMatchMethod {
  1251  	return sqlbase.ForeignKeyReferenceMatchValue[fk.match]
  1252  }
  1253  
  1254  // DeleteReferenceAction is part of the cat.ForeignKeyConstraint interface.
  1255  func (fk *optForeignKeyConstraint) DeleteReferenceAction() tree.ReferenceAction {
  1256  	return sqlbase.ForeignKeyReferenceActionType[fk.deleteAction]
  1257  }
  1258  
  1259  // UpdateReferenceAction is part of the cat.ForeignKeyConstraint interface.
  1260  func (fk *optForeignKeyConstraint) UpdateReferenceAction() tree.ReferenceAction {
  1261  	return sqlbase.ForeignKeyReferenceActionType[fk.updateAction]
  1262  }
  1263  
  1264  // optVirtualTable is similar to optTable but is used with virtual tables.
  1265  type optVirtualTable struct {
  1266  	desc *sqlbase.ImmutableTableDescriptor
  1267  
  1268  	// A virtual table can effectively have multiple instances, with different
  1269  	// contents. For example `db1.pg_catalog.pg_sequence` contains info about
  1270  	// sequences in db1, whereas `db2.pg_catalog.pg_sequence` contains info about
  1271  	// sequences in db2.
  1272  	//
  1273  	// These instances should have different stable IDs. To achieve this, the
  1274  	// stable ID is the database ID concatenated with the descriptor ID.
  1275  	//
  1276  	// Note that some virtual tables have a special instance with empty catalog,
  1277  	// for example "".information_schema.tables contains info about tables in
  1278  	// all databases. We treat the empty catalog as having database ID 0.
  1279  	id cat.StableID
  1280  
  1281  	// name is the fully qualified, fully resolved, fully normalized name of the
  1282  	// virtual table.
  1283  	name cat.DataSourceName
  1284  
  1285  	// indexes contains "virtual indexes", which are used to produce virtual table
  1286  	// data given constraints using generator functions. The 0th index is a
  1287  	// synthesized primary index.
  1288  	indexes []optVirtualIndex
  1289  
  1290  	// family is a synthesized primary family.
  1291  	family optVirtualFamily
  1292  
  1293  	// colMap is a mapping from unique ColumnID to column ordinal within the
  1294  	// table. This is a common lookup that needs to be fast.
  1295  	colMap map[sqlbase.ColumnID]int
  1296  }
  1297  
  1298  var _ cat.Table = &optVirtualTable{}
  1299  
  1300  func newOptVirtualTable(
  1301  	ctx context.Context,
  1302  	oc *optCatalog,
  1303  	desc *sqlbase.ImmutableTableDescriptor,
  1304  	name *cat.DataSourceName,
  1305  ) (*optVirtualTable, error) {
  1306  	// Calculate the stable ID (see the comment for optVirtualTable.id).
  1307  	id := cat.StableID(desc.ID)
  1308  	if name.Catalog() != "" {
  1309  		// TODO(radu): it's unfortunate that we have to lookup the schema again.
  1310  		_, dbDesc, err := oc.planner.LookupSchema(ctx, name.Catalog(), name.Schema())
  1311  		if err != nil {
  1312  			return nil, err
  1313  		}
  1314  		if dbDesc == nil {
  1315  			// The database was not found. This can happen e.g. when
  1316  			// accessing a virtual schema over a non-existent
  1317  			// database. This is a common scenario when the current db
  1318  			// in the session points to a database that was not created
  1319  			// yet.
  1320  			//
  1321  			// In that case we use an invalid database ID. We
  1322  			// distinguish this from the empty database case because the
  1323  			// virtual tables do not "contain" the same information in
  1324  			// both cases.
  1325  			id |= cat.StableID(math.MaxUint32) << 32
  1326  		} else {
  1327  			id |= cat.StableID(dbDesc.(*DatabaseDescriptor).ID) << 32
  1328  		}
  1329  	}
  1330  
  1331  	ot := &optVirtualTable{
  1332  		desc: desc,
  1333  		id:   id,
  1334  		name: *name,
  1335  	}
  1336  
  1337  	// Create the table's column mapping from sqlbase.ColumnID to column ordinal.
  1338  	ot.colMap = make(map[sqlbase.ColumnID]int, ot.DeletableColumnCount())
  1339  	for i, n := 0, ot.DeletableColumnCount(); i < n; i++ {
  1340  		ot.colMap[sqlbase.ColumnID(ot.Column(i).ColID())] = i
  1341  	}
  1342  
  1343  	ot.name.ExplicitSchema = true
  1344  	ot.name.ExplicitCatalog = true
  1345  
  1346  	ot.family.init(ot)
  1347  
  1348  	// Build the indexes (add 1 to account for lack of primary index in
  1349  	// indexes slice).
  1350  	ot.indexes = make([]optVirtualIndex, 1+len(ot.desc.Indexes))
  1351  	// Set up the primary index.
  1352  	ot.indexes[0] = optVirtualIndex{
  1353  		tab:          ot,
  1354  		indexOrdinal: 0,
  1355  		numCols:      ot.ColumnCount(),
  1356  		isPrimary:    true,
  1357  		desc: &sqlbase.IndexDescriptor{
  1358  			ID:   0,
  1359  			Name: "primary",
  1360  		},
  1361  	}
  1362  
  1363  	for i := range ot.desc.Indexes {
  1364  		idxDesc := &ot.desc.Indexes[i]
  1365  		if len(idxDesc.ColumnIDs) > 1 {
  1366  			panic("virtual indexes with more than 1 col not supported")
  1367  		}
  1368  
  1369  		// Add 1, since the 0th index will the the primary that we added above.
  1370  		ot.indexes[i+1] = optVirtualIndex{
  1371  			tab:          ot,
  1372  			desc:         idxDesc,
  1373  			indexOrdinal: i + 1,
  1374  			// The virtual indexes don't return the bogus PK key?
  1375  			numCols: ot.ColumnCount(),
  1376  		}
  1377  	}
  1378  
  1379  	return ot, nil
  1380  }
  1381  
  1382  // ID is part of the cat.Object interface.
  1383  func (ot *optVirtualTable) ID() cat.StableID {
  1384  	return ot.id
  1385  }
  1386  
  1387  // PostgresDescriptorID is part of the cat.Object interface.
  1388  func (ot *optVirtualTable) PostgresDescriptorID() cat.StableID {
  1389  	return cat.StableID(ot.desc.ID)
  1390  }
  1391  
  1392  // Equals is part of the cat.Object interface.
  1393  func (ot *optVirtualTable) Equals(other cat.Object) bool {
  1394  	otherTable, ok := other.(*optVirtualTable)
  1395  	if !ok {
  1396  		return false
  1397  	}
  1398  	if ot == otherTable {
  1399  		// Fast path when it is the same object.
  1400  		return true
  1401  	}
  1402  	if ot.id != otherTable.id || ot.desc.Version != otherTable.desc.Version {
  1403  		return false
  1404  	}
  1405  
  1406  	return true
  1407  }
  1408  
  1409  // Name is part of the cat.Table interface.
  1410  func (ot *optVirtualTable) Name() tree.Name {
  1411  	return ot.name.ObjectName
  1412  }
  1413  
  1414  // IsVirtualTable is part of the cat.Table interface.
  1415  func (ot *optVirtualTable) IsVirtualTable() bool {
  1416  	return true
  1417  }
  1418  
  1419  // ColumnCount is part of the cat.Table interface.
  1420  func (ot *optVirtualTable) ColumnCount() int {
  1421  	// Virtual tables expose an extra (bogus) PK column.
  1422  	return len(ot.desc.Columns) + 1
  1423  }
  1424  
  1425  // WritableColumnCount is part of the cat.Table interface.
  1426  func (ot *optVirtualTable) WritableColumnCount() int {
  1427  	return len(ot.desc.WritableColumns()) + 1
  1428  }
  1429  
  1430  // DeletableColumnCount is part of the cat.Table interface.
  1431  func (ot *optVirtualTable) DeletableColumnCount() int {
  1432  	return len(ot.desc.DeletableColumns()) + 1
  1433  }
  1434  
  1435  // Column is part of the cat.Table interface.
  1436  func (ot *optVirtualTable) Column(i int) cat.Column {
  1437  	if i == 0 {
  1438  		// Column 0 is a dummy PK column.
  1439  		return optDummyVirtualPKColumn{}
  1440  	}
  1441  	return &ot.desc.DeletableColumns()[i-1]
  1442  }
  1443  
  1444  // IndexCount is part of the cat.Table interface.
  1445  func (ot *optVirtualTable) IndexCount() int {
  1446  	// Primary index is always present, so count is always >= 1.
  1447  	return 1 + len(ot.desc.Indexes)
  1448  }
  1449  
  1450  // WritableIndexCount is part of the cat.Table interface.
  1451  func (ot *optVirtualTable) WritableIndexCount() int {
  1452  	// Primary index is always present, so count is always >= 1.
  1453  	return 1 + len(ot.desc.WritableIndexes())
  1454  }
  1455  
  1456  // DeletableIndexCount is part of the cat.Table interface.
  1457  func (ot *optVirtualTable) DeletableIndexCount() int {
  1458  	// Primary index is always present, so count is always >= 1.
  1459  	return 1 + len(ot.desc.DeletableIndexes())
  1460  }
  1461  
  1462  // Index is part of the cat.Table interface.
  1463  func (ot *optVirtualTable) Index(i cat.IndexOrdinal) cat.Index {
  1464  	return &ot.indexes[i]
  1465  }
  1466  
  1467  // StatisticCount is part of the cat.Table interface.
  1468  func (ot *optVirtualTable) StatisticCount() int {
  1469  	return 0
  1470  }
  1471  
  1472  // Statistic is part of the cat.Table interface.
  1473  func (ot *optVirtualTable) Statistic(i int) cat.TableStatistic {
  1474  	panic("no stats")
  1475  }
  1476  
  1477  // CheckCount is part of the cat.Table interface.
  1478  func (ot *optVirtualTable) CheckCount() int {
  1479  	return len(ot.desc.ActiveChecks())
  1480  }
  1481  
  1482  // Check is part of the cat.Table interface.
  1483  func (ot *optVirtualTable) Check(i int) cat.CheckConstraint {
  1484  	check := ot.desc.ActiveChecks()[i]
  1485  	return cat.CheckConstraint{
  1486  		Constraint: check.Expr,
  1487  		Validated:  check.Validity == sqlbase.ConstraintValidity_Validated,
  1488  	}
  1489  }
  1490  
  1491  // FamilyCount is part of the cat.Table interface.
  1492  func (ot *optVirtualTable) FamilyCount() int {
  1493  	return 1
  1494  }
  1495  
  1496  // Family is part of the cat.Table interface.
  1497  func (ot *optVirtualTable) Family(i int) cat.Family {
  1498  	return &ot.family
  1499  }
  1500  
  1501  // OutboundForeignKeyCount is part of the cat.Table interface.
  1502  func (ot *optVirtualTable) OutboundForeignKeyCount() int {
  1503  	return 0
  1504  }
  1505  
  1506  // OutboundForeignKeyCount is part of the cat.Table interface.
  1507  func (ot *optVirtualTable) OutboundForeignKey(i int) cat.ForeignKeyConstraint {
  1508  	panic("no FKs")
  1509  }
  1510  
  1511  // InboundForeignKeyCount is part of the cat.Table interface.
  1512  func (ot *optVirtualTable) InboundForeignKeyCount() int {
  1513  	return 0
  1514  }
  1515  
  1516  // InboundForeignKey is part of the cat.Table interface.
  1517  func (ot *optVirtualTable) InboundForeignKey(i int) cat.ForeignKeyConstraint {
  1518  	panic("no FKs")
  1519  }
  1520  
  1521  type optDummyVirtualPKColumn struct{}
  1522  
  1523  var _ cat.Column = optDummyVirtualPKColumn{}
  1524  
  1525  // ColID is part of the cat.Column interface.
  1526  func (optDummyVirtualPKColumn) ColID() cat.StableID {
  1527  	return math.MaxInt64
  1528  }
  1529  
  1530  // ColName is part of the cat.Column interface.
  1531  func (optDummyVirtualPKColumn) ColName() tree.Name {
  1532  	return "crdb_internal_vtable_pk"
  1533  }
  1534  
  1535  // DatumType is part of the cat.Column interface.
  1536  func (optDummyVirtualPKColumn) DatumType() *types.T {
  1537  	return types.Int
  1538  }
  1539  
  1540  // ColTypePrecision is part of the cat.Column interface.
  1541  func (optDummyVirtualPKColumn) ColTypePrecision() int {
  1542  	return int(types.Int.Precision())
  1543  }
  1544  
  1545  // ColTypeWidth is part of the cat.Column interface.
  1546  func (optDummyVirtualPKColumn) ColTypeWidth() int {
  1547  	return int(types.Int.Width())
  1548  }
  1549  
  1550  // ColTypeStr is part of the cat.Column interface.
  1551  func (optDummyVirtualPKColumn) ColTypeStr() string {
  1552  	return types.Int.SQLString()
  1553  }
  1554  
  1555  // IsNullable is part of the cat.Column interface.
  1556  func (optDummyVirtualPKColumn) IsNullable() bool {
  1557  	return false
  1558  }
  1559  
  1560  // IsHidden is part of the cat.Column interface.
  1561  func (optDummyVirtualPKColumn) IsHidden() bool {
  1562  	return true
  1563  }
  1564  
  1565  // HasDefault is part of the cat.Column interface.
  1566  func (optDummyVirtualPKColumn) HasDefault() bool {
  1567  	return false
  1568  }
  1569  
  1570  // DefaultExprStr is part of the cat.Column interface.
  1571  func (optDummyVirtualPKColumn) DefaultExprStr() string {
  1572  	return ""
  1573  }
  1574  
  1575  // IsComputed is part of the cat.Column interface.
  1576  func (optDummyVirtualPKColumn) IsComputed() bool {
  1577  	return false
  1578  }
  1579  
  1580  // ComputedExprStr is part of the cat.Column interface.
  1581  func (optDummyVirtualPKColumn) ComputedExprStr() string {
  1582  	return ""
  1583  }
  1584  
  1585  // optVirtualIndex is a dummy implementation of cat.Index for the indexes
  1586  // reported by a virtual table. The index assumes that table column 0 is a dummy
  1587  // PK column.
  1588  type optVirtualIndex struct {
  1589  	tab *optVirtualTable
  1590  
  1591  	// isPrimary is set to true if this is the dummy PK index for virtual tables.
  1592  	isPrimary bool
  1593  
  1594  	desc *sqlbase.IndexDescriptor
  1595  
  1596  	numCols int
  1597  
  1598  	indexOrdinal int
  1599  }
  1600  
  1601  // ID is part of the cat.Index interface.
  1602  func (oi *optVirtualIndex) ID() cat.StableID {
  1603  	return cat.StableID(oi.desc.ID)
  1604  }
  1605  
  1606  // Name is part of the cat.Index interface.
  1607  func (oi *optVirtualIndex) Name() tree.Name {
  1608  	return tree.Name(oi.desc.Name)
  1609  }
  1610  
  1611  // IsUnique is part of the cat.Index interface.
  1612  func (oi *optVirtualIndex) IsUnique() bool {
  1613  	return oi.desc.Unique
  1614  }
  1615  
  1616  // IsInverted is part of the cat.Index interface.
  1617  func (oi *optVirtualIndex) IsInverted() bool {
  1618  	return false
  1619  }
  1620  
  1621  // ColumnCount is part of the cat.Index interface.
  1622  func (oi *optVirtualIndex) ColumnCount() int {
  1623  	return oi.numCols
  1624  }
  1625  
  1626  // Predicate is part of the cat.Index interface.
  1627  func (oi *optVirtualIndex) Predicate() (string, bool) {
  1628  	return "", false
  1629  }
  1630  
  1631  // KeyColumnCount is part of the cat.Index interface.
  1632  func (oi *optVirtualIndex) KeyColumnCount() int {
  1633  	return 1
  1634  }
  1635  
  1636  // LaxKeyColumnCount is part of the cat.Index interface.
  1637  func (oi *optVirtualIndex) LaxKeyColumnCount() int {
  1638  	return 1
  1639  }
  1640  
  1641  // lookupColumnOrdinal returns the ordinal of the column with the given ID. A
  1642  // cache makes the lookup O(1).
  1643  func (ot *optVirtualTable) lookupColumnOrdinal(colID sqlbase.ColumnID) (int, error) {
  1644  	col, ok := ot.colMap[colID]
  1645  	if ok {
  1646  		return col, nil
  1647  	}
  1648  	return col, pgerror.Newf(pgcode.UndefinedColumn,
  1649  		"column [%d] does not exist", colID)
  1650  }
  1651  
  1652  // Column is part of the cat.Index interface.
  1653  func (oi *optVirtualIndex) Column(i int) cat.IndexColumn {
  1654  	if oi.isPrimary {
  1655  		return cat.IndexColumn{Column: oi.tab.Column(i), Ordinal: i}
  1656  	}
  1657  	if i == oi.ColumnCount()-1 {
  1658  		// The special bogus PK column goes at the end. It has ID 0.
  1659  		return cat.IndexColumn{Column: oi.tab.Column(0), Ordinal: 0}
  1660  	}
  1661  	length := len(oi.desc.ColumnIDs)
  1662  	if i < length {
  1663  		ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i])
  1664  		return cat.IndexColumn{
  1665  			Column:  oi.tab.Column(ord),
  1666  			Ordinal: ord,
  1667  		}
  1668  	}
  1669  
  1670  	i -= length
  1671  	ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.StoreColumnIDs[i])
  1672  	return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord}
  1673  }
  1674  
  1675  // Zone is part of the cat.Index interface.
  1676  func (oi *optVirtualIndex) Zone() cat.Zone {
  1677  	panic("no zone")
  1678  }
  1679  
  1680  // Span is part of the cat.Index interface.
  1681  func (oi *optVirtualIndex) Span() roachpb.Span {
  1682  	panic("no span")
  1683  }
  1684  
  1685  // Table is part of the cat.Index interface.
  1686  func (oi *optVirtualIndex) Table() cat.Table {
  1687  	return oi.tab
  1688  }
  1689  
  1690  // Ordinal is part of the cat.Index interface.
  1691  func (oi *optVirtualIndex) Ordinal() int {
  1692  	return oi.indexOrdinal
  1693  }
  1694  
  1695  // PartitionByListPrefixes is part of the cat.Index interface.
  1696  func (oi *optVirtualIndex) PartitionByListPrefixes() []tree.Datums {
  1697  	panic("no partition")
  1698  }
  1699  
  1700  // InterleaveAncestorCount is part of the cat.Index interface.
  1701  func (oi *optVirtualIndex) InterleaveAncestorCount() int {
  1702  	return 0
  1703  }
  1704  
  1705  // InterleaveAncestor is part of the cat.Index interface.
  1706  func (oi *optVirtualIndex) InterleaveAncestor(i int) (table, index cat.StableID, numKeyCols int) {
  1707  	panic("no interleavings")
  1708  }
  1709  
  1710  // InterleavedByCount is part of the cat.Index interface.
  1711  func (oi *optVirtualIndex) InterleavedByCount() int {
  1712  	return 0
  1713  }
  1714  
  1715  // InterleavedBy is part of the cat.Index interface.
  1716  func (oi *optVirtualIndex) InterleavedBy(i int) (table, index cat.StableID) {
  1717  	panic("no interleavings")
  1718  }
  1719  
  1720  // optVirtualFamily is a dummy implementation of cat.Family for the only family
  1721  // reported by a virtual table.
  1722  type optVirtualFamily struct {
  1723  	tab *optVirtualTable
  1724  }
  1725  
  1726  var _ cat.Family = &optVirtualFamily{}
  1727  
  1728  func (oi *optVirtualFamily) init(tab *optVirtualTable) {
  1729  	oi.tab = tab
  1730  }
  1731  
  1732  // ID is part of the cat.Family interface.
  1733  func (oi *optVirtualFamily) ID() cat.StableID {
  1734  	return 0
  1735  }
  1736  
  1737  // Name is part of the cat.Family interface.
  1738  func (oi *optVirtualFamily) Name() tree.Name {
  1739  	return "primary"
  1740  }
  1741  
  1742  // ColumnCount is part of the cat.Family interface.
  1743  func (oi *optVirtualFamily) ColumnCount() int {
  1744  	return oi.tab.ColumnCount()
  1745  }
  1746  
  1747  // Column is part of the cat.Family interface.
  1748  func (oi *optVirtualFamily) Column(i int) cat.FamilyColumn {
  1749  	return cat.FamilyColumn{Column: oi.tab.Column(i), Ordinal: i}
  1750  }
  1751  
  1752  // Table is part of the cat.Family interface.
  1753  func (oi *optVirtualFamily) Table() cat.Table {
  1754  	return oi.tab
  1755  }