github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/resolver.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  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/keys"
    18  	"github.com/cockroachdb/cockroach/pkg/kv"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/opt/cat"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    27  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    28  	"github.com/cockroachdb/errors"
    29  )
    30  
    31  var _ resolver.SchemaResolver = &planner{}
    32  
    33  // ResolveUncachedDatabaseByName looks up a database name from the store.
    34  func (p *planner) ResolveUncachedDatabaseByName(
    35  	ctx context.Context, dbName string, required bool,
    36  ) (res *UncachedDatabaseDescriptor, err error) {
    37  	p.runWithOptions(resolveFlags{skipCache: true}, func() {
    38  		res, err = p.LogicalSchemaAccessor().GetDatabaseDesc(
    39  			ctx, p.txn, p.ExecCfg().Codec, dbName, p.CommonLookupFlags(required),
    40  		)
    41  	})
    42  	return res, err
    43  }
    44  
    45  // runWithOptions sets the provided resolution flags for the
    46  // duration of the call of the passed argument fn.
    47  //
    48  // This is meant to be used like this (for example):
    49  //
    50  // var someVar T
    51  // var err error
    52  // p.runWithOptions(resolveFlags{skipCache: true}, func() {
    53  //    someVar, err = ResolveExistingTableObject(ctx, p, ...)
    54  // })
    55  // if err != nil { ... }
    56  // use(someVar)
    57  func (p *planner) runWithOptions(flags resolveFlags, fn func()) {
    58  	if flags.skipCache {
    59  		defer func(prev bool) { p.avoidCachedDescriptors = prev }(p.avoidCachedDescriptors)
    60  		p.avoidCachedDescriptors = true
    61  	}
    62  	fn()
    63  }
    64  
    65  type resolveFlags struct {
    66  	skipCache bool
    67  }
    68  
    69  func (p *planner) ResolveMutableTableDescriptor(
    70  	ctx context.Context, tn *TableName, required bool, requiredType resolver.ResolveRequiredType,
    71  ) (table *MutableTableDescriptor, err error) {
    72  	return resolver.ResolveMutableExistingTableObject(ctx, p, tn, required, requiredType)
    73  }
    74  
    75  func (p *planner) ResolveUncachedTableDescriptor(
    76  	ctx context.Context, tn *TableName, required bool, requiredType resolver.ResolveRequiredType,
    77  ) (table *ImmutableTableDescriptor, err error) {
    78  	p.runWithOptions(resolveFlags{skipCache: true}, func() {
    79  		lookupFlags := tree.ObjectLookupFlags{CommonLookupFlags: tree.CommonLookupFlags{Required: required}}
    80  		table, err = resolver.ResolveExistingTableObject(ctx, p, tn, lookupFlags, requiredType)
    81  	})
    82  	return table, err
    83  }
    84  
    85  func (p *planner) ResolveUncachedDatabase(
    86  	ctx context.Context, un *tree.UnresolvedObjectName,
    87  ) (res *UncachedDatabaseDescriptor, namePrefix tree.ObjectNamePrefix, err error) {
    88  	p.runWithOptions(resolveFlags{skipCache: true}, func() {
    89  		res, namePrefix, err = resolver.ResolveTargetObject(ctx, p, un)
    90  	})
    91  	return res, namePrefix, err
    92  }
    93  
    94  // LookupSchema implements the tree.ObjectNameTargetResolver interface.
    95  func (p *planner) LookupSchema(
    96  	ctx context.Context, dbName, scName string,
    97  ) (found bool, scMeta tree.SchemaMeta, err error) {
    98  	sc := p.LogicalSchemaAccessor()
    99  	dbDesc, err := sc.GetDatabaseDesc(ctx, p.txn, p.ExecCfg().Codec, dbName, p.CommonLookupFlags(false /*required*/))
   100  	if err != nil || dbDesc == nil {
   101  		return false, nil, err
   102  	}
   103  	found, _, err = sc.IsValidSchema(ctx, p.txn, p.ExecCfg().Codec, dbDesc.ID, scName)
   104  	if err != nil {
   105  		return false, nil, err
   106  	}
   107  	return found, dbDesc, nil
   108  }
   109  
   110  // LookupObject implements the tree.ObjectNameExistingResolver interface.
   111  func (p *planner) LookupObject(
   112  	ctx context.Context, lookupFlags tree.ObjectLookupFlags, dbName, scName, tbName string,
   113  ) (found bool, objMeta tree.NameResolutionResult, err error) {
   114  	sc := p.LogicalSchemaAccessor()
   115  	lookupFlags.CommonLookupFlags = p.CommonLookupFlags(false /* required */)
   116  	objDesc, err := sc.GetObjectDesc(ctx, p.txn, p.ExecCfg().Settings, p.ExecCfg().Codec, dbName, scName, tbName, lookupFlags)
   117  
   118  	// The returned object may contain types.T that need hydrating.
   119  	if objDesc != nil {
   120  		if err := p.maybeHydrateTypesInDescriptor(ctx, objDesc); err != nil {
   121  			return false, nil, err
   122  		}
   123  	}
   124  
   125  	return objDesc != nil, objDesc, err
   126  }
   127  
   128  // CommonLookupFlags is part of the resolver.SchemaResolver interface.
   129  func (p *planner) CommonLookupFlags(required bool) tree.CommonLookupFlags {
   130  	return tree.CommonLookupFlags{
   131  		Required:    required,
   132  		AvoidCached: p.avoidCachedDescriptors,
   133  	}
   134  }
   135  
   136  func (p *planner) makeTypeLookupFn(ctx context.Context) sqlbase.TypeLookupFunc {
   137  	return func(id sqlbase.ID) (*tree.TypeName, *TypeDescriptor, error) {
   138  		return resolver.ResolveTypeDescByID(ctx, p.txn, p.ExecCfg().Codec, id)
   139  	}
   140  }
   141  
   142  // ResolveType implements the TypeReferenceResolver interface.
   143  func (p *planner) ResolveType(
   144  	ctx context.Context, name *tree.UnresolvedObjectName,
   145  ) (*types.T, error) {
   146  	lookupFlags := tree.ObjectLookupFlags{
   147  		CommonLookupFlags: tree.CommonLookupFlags{Required: true},
   148  		DesiredObjectKind: tree.TypeObject,
   149  		RequireMutable:    false,
   150  	}
   151  	// TODO (rohany): The ResolveAnyDescType argument doesn't do anything here
   152  	//  if we are looking for a type. This should be cleaned up.
   153  	desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, resolver.ResolveAnyDescType)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	tn := tree.MakeTypeNameFromPrefix(prefix, tree.Name(name.Object()))
   158  	tdesc := desc.(*sqlbase.ImmutableTypeDescriptor)
   159  	return tdesc.MakeTypesT(&tn, p.makeTypeLookupFn(ctx))
   160  }
   161  
   162  // ResolveTypeByID implements the tree.TypeResolver interface.
   163  func (p *planner) ResolveTypeByID(ctx context.Context, id uint32) (*types.T, error) {
   164  	name, desc, err := resolver.ResolveTypeDescByID(ctx, p.txn, p.ExecCfg().Codec, sqlbase.ID(id))
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	return desc.MakeTypesT(name, p.makeTypeLookupFn(ctx))
   169  }
   170  
   171  // maybeHydrateTypesInDescriptor hydrates any types.T's in the input descriptor.
   172  // TODO (rohany): Once we lease types, this should be pushed down into the
   173  //  leased object collection.
   174  func (p *planner) maybeHydrateTypesInDescriptor(
   175  	ctx context.Context, objDesc tree.NameResolutionResult,
   176  ) error {
   177  	// As of now, only {Mutable,Immutable}TableDescriptor have types.T that
   178  	// need to be hydrated.
   179  	switch desc := objDesc.(type) {
   180  	case *sqlbase.MutableTableDescriptor:
   181  		if err := sqlbase.HydrateTypesInTableDescriptor(desc.TableDesc(), p.makeTypeLookupFn(ctx)); err != nil {
   182  			return err
   183  		}
   184  	case *sqlbase.ImmutableTableDescriptor:
   185  		if err := sqlbase.HydrateTypesInTableDescriptor(desc.TableDesc(), p.makeTypeLookupFn(ctx)); err != nil {
   186  			return err
   187  		}
   188  	}
   189  	return nil
   190  }
   191  
   192  // ObjectLookupFlags is part of the resolver.SchemaResolver interface.
   193  func (p *planner) ObjectLookupFlags(required, requireMutable bool) tree.ObjectLookupFlags {
   194  	return tree.ObjectLookupFlags{
   195  		CommonLookupFlags: p.CommonLookupFlags(required),
   196  		RequireMutable:    requireMutable,
   197  	}
   198  }
   199  
   200  // getDescriptorsFromTargetList fetches the descriptors for the targets.
   201  func getDescriptorsFromTargetList(
   202  	ctx context.Context, p *planner, targets tree.TargetList,
   203  ) ([]sqlbase.DescriptorProto, error) {
   204  	if targets.Databases != nil {
   205  		if len(targets.Databases) == 0 {
   206  			return nil, errNoDatabase
   207  		}
   208  		descs := make([]sqlbase.DescriptorProto, 0, len(targets.Databases))
   209  		for _, database := range targets.Databases {
   210  			descriptor, err := p.ResolveUncachedDatabaseByName(ctx, string(database), true /*required*/)
   211  			if err != nil {
   212  				return nil, err
   213  			}
   214  			descs = append(descs, descriptor)
   215  		}
   216  		if len(descs) == 0 {
   217  			return nil, errNoMatch
   218  		}
   219  		return descs, nil
   220  	}
   221  
   222  	if len(targets.Tables) == 0 {
   223  		return nil, errNoTable
   224  	}
   225  	descs := make([]sqlbase.DescriptorProto, 0, len(targets.Tables))
   226  	for _, tableTarget := range targets.Tables {
   227  		tableGlob, err := tableTarget.NormalizeTablePattern()
   228  		if err != nil {
   229  			return nil, err
   230  		}
   231  		objectNames, err := expandTableGlob(ctx, p, tableGlob)
   232  		if err != nil {
   233  			return nil, err
   234  		}
   235  
   236  		for i := range objectNames {
   237  			// We set required to false here, because there could be type names in
   238  			// the returned set of names, so we don't want to error out if we
   239  			// couldn't resolve a name into a table.
   240  			descriptor, err := resolver.ResolveMutableExistingTableObject(ctx, p,
   241  				&objectNames[i], false /* required */, resolver.ResolveAnyDescType)
   242  			if err != nil {
   243  				return nil, err
   244  			}
   245  			if descriptor != nil {
   246  				descs = append(descs, descriptor)
   247  			}
   248  		}
   249  	}
   250  	if len(descs) == 0 {
   251  		return nil, errNoMatch
   252  	}
   253  	return descs, nil
   254  }
   255  
   256  // getQualifiedTableName returns the database-qualified name of the table
   257  // or view represented by the provided descriptor. It is a sort of
   258  // reverse of the Resolve() functions.
   259  func (p *planner) getQualifiedTableName(
   260  	ctx context.Context, desc *sqlbase.TableDescriptor,
   261  ) (string, error) {
   262  	dbDesc, err := sqlbase.GetDatabaseDescFromID(ctx, p.txn, p.ExecCfg().Codec, desc.ParentID)
   263  	if err != nil {
   264  		return "", err
   265  	}
   266  	schemaID := desc.GetParentSchemaID()
   267  	schemaName, err := resolver.ResolveSchemaNameByID(ctx, p.txn, p.ExecCfg().Codec, desc.ParentID, schemaID)
   268  	if err != nil {
   269  		return "", err
   270  	}
   271  	tbName := tree.MakeTableNameWithSchema(
   272  		tree.Name(dbDesc.Name),
   273  		tree.Name(schemaName),
   274  		tree.Name(desc.Name),
   275  	)
   276  	return tbName.String(), nil
   277  }
   278  
   279  // findTableContainingIndex returns the descriptor of a table
   280  // containing the index of the given name.
   281  // This is used by expandMutableIndexName().
   282  //
   283  // An error is returned if the index name is ambiguous (i.e. exists in
   284  // multiple tables). If no table is found and requireTable is true, an
   285  // error will be returned, otherwise the TableName and descriptor
   286  // returned will be nil.
   287  func findTableContainingIndex(
   288  	ctx context.Context,
   289  	txn *kv.Txn,
   290  	sc resolver.SchemaResolver,
   291  	codec keys.SQLCodec,
   292  	dbName, scName string,
   293  	idxName tree.UnrestrictedName,
   294  	lookupFlags tree.CommonLookupFlags,
   295  ) (result *tree.TableName, desc *MutableTableDescriptor, err error) {
   296  	sa := sc.LogicalSchemaAccessor()
   297  	dbDesc, err := sa.GetDatabaseDesc(ctx, txn, codec, dbName, lookupFlags)
   298  	if dbDesc == nil || err != nil {
   299  		return nil, nil, err
   300  	}
   301  
   302  	tns, err := sa.GetObjectNames(ctx, txn, codec, dbDesc, scName,
   303  		tree.DatabaseListFlags{CommonLookupFlags: lookupFlags, ExplicitPrefix: true})
   304  	if err != nil {
   305  		return nil, nil, err
   306  	}
   307  
   308  	result = nil
   309  	for i := range tns {
   310  		tn := &tns[i]
   311  		tableDesc, err := resolver.ResolveMutableExistingTableObject(ctx, sc, tn, false /*required*/, resolver.ResolveAnyDescType)
   312  		if err != nil {
   313  			return nil, nil, err
   314  		}
   315  		if tableDesc == nil || !tableDesc.IsTable() {
   316  			continue
   317  		}
   318  
   319  		_, dropped, err := tableDesc.FindIndexByName(string(idxName))
   320  		if err != nil || dropped {
   321  			// err is nil if the index does not exist on the table.
   322  			continue
   323  		}
   324  		if result != nil {
   325  			return nil, nil, pgerror.Newf(pgcode.AmbiguousParameter,
   326  				"index name %q is ambiguous (found in %s and %s)",
   327  				idxName, tn.String(), result.String())
   328  		}
   329  		result = tn
   330  		desc = tableDesc
   331  	}
   332  	if result == nil && lookupFlags.Required {
   333  		return nil, nil, pgerror.Newf(pgcode.UndefinedObject,
   334  			"index %q does not exist", idxName)
   335  	}
   336  	return result, desc, nil
   337  }
   338  
   339  // expandMutableIndexName ensures that the index name is qualified with a table
   340  // name, and searches the table name if not yet specified.
   341  //
   342  // It returns the TableName of the underlying table for convenience.
   343  // If no table is found and requireTable is true an error will be
   344  // returned, otherwise the TableName returned will be nil.
   345  //
   346  // It *may* return the descriptor of the underlying table, depending
   347  // on the lookup path. This can be used in the caller to avoid a 2nd
   348  // lookup.
   349  func expandMutableIndexName(
   350  	ctx context.Context, p *planner, index *tree.TableIndexName, requireTable bool,
   351  ) (tn *tree.TableName, desc *MutableTableDescriptor, err error) {
   352  	p.runWithOptions(resolveFlags{skipCache: true}, func() {
   353  		tn, desc, err = expandIndexName(ctx, p.txn, p, p.ExecCfg().Codec, index, requireTable)
   354  	})
   355  	return tn, desc, err
   356  }
   357  
   358  func expandIndexName(
   359  	ctx context.Context,
   360  	txn *kv.Txn,
   361  	sc resolver.SchemaResolver,
   362  	codec keys.SQLCodec,
   363  	index *tree.TableIndexName,
   364  	requireTable bool,
   365  ) (tn *tree.TableName, desc *MutableTableDescriptor, err error) {
   366  	tn = &index.Table
   367  	if tn.Table() != "" {
   368  		// The index and its table prefix must exist already. Resolve the table.
   369  		desc, err = resolver.ResolveMutableExistingTableObject(ctx, sc, tn, requireTable, resolver.ResolveRequireTableDesc)
   370  		if err != nil {
   371  			return nil, nil, err
   372  		}
   373  		return tn, desc, nil
   374  	}
   375  
   376  	// On the first call to expandMutableIndexName(), index.Table.Table() is empty.
   377  	// Once the table name is resolved for the index below, index.Table
   378  	// references the table name.
   379  
   380  	// Look up the table prefix.
   381  	found, _, err := tn.ObjectNamePrefix.Resolve(ctx, sc, sc.CurrentDatabase(), sc.CurrentSearchPath())
   382  	if err != nil {
   383  		return nil, nil, err
   384  	}
   385  	if !found {
   386  		if requireTable {
   387  			err = pgerror.Newf(pgcode.UndefinedObject,
   388  				"schema or database was not found while searching index: %q",
   389  				tree.ErrString(&index.Index))
   390  			err = errors.WithHint(err, "check the current database and search_path are valid")
   391  			return nil, nil, err
   392  		}
   393  		return nil, nil, nil
   394  	}
   395  
   396  	lookupFlags := sc.CommonLookupFlags(requireTable)
   397  	var foundTn *tree.TableName
   398  	foundTn, desc, err = findTableContainingIndex(ctx, txn, sc, codec, tn.Catalog(), tn.Schema(), index.Index, lookupFlags)
   399  	if err != nil {
   400  		return nil, nil, err
   401  	}
   402  
   403  	if foundTn != nil {
   404  		// Memoize the table name that was found. tn is a reference to the table name
   405  		// stored in index.Table.
   406  		*tn = *foundTn
   407  	}
   408  	return tn, desc, nil
   409  }
   410  
   411  // getTableAndIndex returns the table and index descriptors for a
   412  // TableIndexName.
   413  //
   414  // It can return indexes that are being rolled out.
   415  func (p *planner) getTableAndIndex(
   416  	ctx context.Context, tableWithIndex *tree.TableIndexName, privilege privilege.Kind,
   417  ) (*MutableTableDescriptor, *sqlbase.IndexDescriptor, error) {
   418  	var catalog optCatalog
   419  	catalog.init(p)
   420  	catalog.reset()
   421  
   422  	idx, _, err := cat.ResolveTableIndex(
   423  		ctx, &catalog, cat.Flags{AvoidDescriptorCaches: true}, tableWithIndex,
   424  	)
   425  	if err != nil {
   426  		return nil, nil, err
   427  	}
   428  	if err := catalog.CheckPrivilege(ctx, idx.Table(), privilege); err != nil {
   429  		return nil, nil, err
   430  	}
   431  	optIdx := idx.(*optIndex)
   432  	return sqlbase.NewMutableExistingTableDescriptor(optIdx.tab.desc.TableDescriptor), optIdx.desc, nil
   433  }
   434  
   435  // expandTableGlob expands pattern into a list of objects represented
   436  // as a tree.TableNames.
   437  func expandTableGlob(
   438  	ctx context.Context, p *planner, pattern tree.TablePattern,
   439  ) (tree.TableNames, error) {
   440  	var catalog optCatalog
   441  	catalog.init(p)
   442  	catalog.reset()
   443  
   444  	return cat.ExpandDataSourceGlob(ctx, &catalog, cat.Flags{}, pattern)
   445  }
   446  
   447  // fkSelfResolver is a SchemaResolver that inserts itself between a
   448  // user of name resolution and another SchemaResolver, and will answer
   449  // lookups of the new table being created. This is needed in the case
   450  // of CREATE TABLE with a foreign key self-reference: the target of
   451  // the FK definition is a table that does not exist yet.
   452  type fkSelfResolver struct {
   453  	resolver.SchemaResolver
   454  	newTableName *tree.TableName
   455  	newTableDesc *sqlbase.TableDescriptor
   456  }
   457  
   458  var _ resolver.SchemaResolver = &fkSelfResolver{}
   459  
   460  // LookupObject implements the tree.ObjectNameExistingResolver interface.
   461  func (r *fkSelfResolver) LookupObject(
   462  	ctx context.Context, lookupFlags tree.ObjectLookupFlags, dbName, scName, tbName string,
   463  ) (found bool, objMeta tree.NameResolutionResult, err error) {
   464  	if dbName == r.newTableName.Catalog() &&
   465  		scName == r.newTableName.Schema() &&
   466  		tbName == r.newTableName.Table() {
   467  		table := r.newTableDesc
   468  		if lookupFlags.RequireMutable {
   469  			return true, sqlbase.NewMutableExistingTableDescriptor(*table), nil
   470  		}
   471  		return true, sqlbase.NewImmutableTableDescriptor(*table), nil
   472  	}
   473  	lookupFlags.IncludeOffline = false
   474  	return r.SchemaResolver.LookupObject(ctx, lookupFlags, dbName, scName, tbName)
   475  }
   476  
   477  // internalLookupCtx can be used in contexts where all descriptors
   478  // have been recently read, to accelerate the lookup of
   479  // inter-descriptor relationships.
   480  //
   481  // This is used mainly in the generators for virtual tables,
   482  // aliased as tableLookupFn below.
   483  //
   484  // It only reveals physical descriptors (not virtual descriptors).
   485  type internalLookupCtx struct {
   486  	dbNames  map[sqlbase.ID]string
   487  	dbIDs    []sqlbase.ID
   488  	dbDescs  map[sqlbase.ID]*DatabaseDescriptor
   489  	tbDescs  map[sqlbase.ID]*TableDescriptor
   490  	tbIDs    []sqlbase.ID
   491  	typDescs map[sqlbase.ID]*TypeDescriptor
   492  	typIDs   []sqlbase.ID
   493  }
   494  
   495  // tableLookupFn can be used to retrieve a table descriptor and its corresponding
   496  // database descriptor using the table's ID.
   497  type tableLookupFn = *internalLookupCtx
   498  
   499  func newInternalLookupCtx(
   500  	descs []sqlbase.DescriptorProto, prefix *DatabaseDescriptor,
   501  ) *internalLookupCtx {
   502  	wrappedDescs := make([]sqlbase.Descriptor, len(descs))
   503  	for i, desc := range descs {
   504  		wrappedDescs[i] = *sqlbase.WrapDescriptor(desc)
   505  	}
   506  	return newInternalLookupCtxFromDescriptors(wrappedDescs, prefix)
   507  }
   508  
   509  func newInternalLookupCtxFromDescriptors(
   510  	descs []sqlbase.Descriptor, prefix *DatabaseDescriptor,
   511  ) *internalLookupCtx {
   512  	dbNames := make(map[sqlbase.ID]string)
   513  	dbDescs := make(map[sqlbase.ID]*DatabaseDescriptor)
   514  	tbDescs := make(map[sqlbase.ID]*TableDescriptor)
   515  	typDescs := make(map[sqlbase.ID]*TypeDescriptor)
   516  	var tbIDs, typIDs, dbIDs []sqlbase.ID
   517  	// Record database descriptors for name lookups.
   518  	for _, desc := range descs {
   519  		if database := desc.GetDatabase(); database != nil {
   520  			dbNames[database.ID] = database.Name
   521  			dbDescs[database.ID] = database
   522  			if prefix == nil || prefix.ID == database.ID {
   523  				dbIDs = append(dbIDs, database.ID)
   524  			}
   525  		} else if table := desc.Table(hlc.Timestamp{}); table != nil {
   526  			tbDescs[table.ID] = table
   527  			if prefix == nil || prefix.ID == table.ParentID {
   528  				// Only make the table visible for iteration if the prefix was included.
   529  				tbIDs = append(tbIDs, table.ID)
   530  			}
   531  		} else if typ := desc.GetType(); typ != nil {
   532  			typDescs[typ.ID] = typ
   533  			if prefix == nil || prefix.ID == typ.ParentID {
   534  				// Only make the type visible for iteration if the prefix was included.
   535  				typIDs = append(typIDs, typ.ID)
   536  			}
   537  		}
   538  	}
   539  	return &internalLookupCtx{
   540  		dbNames:  dbNames,
   541  		dbDescs:  dbDescs,
   542  		tbDescs:  tbDescs,
   543  		typDescs: typDescs,
   544  		tbIDs:    tbIDs,
   545  		dbIDs:    dbIDs,
   546  		typIDs:   typIDs,
   547  	}
   548  }
   549  
   550  func (l *internalLookupCtx) getDatabaseByID(id sqlbase.ID) (*DatabaseDescriptor, error) {
   551  	db, ok := l.dbDescs[id]
   552  	if !ok {
   553  		return nil, sqlbase.NewUndefinedDatabaseError(fmt.Sprintf("[%d]", id))
   554  	}
   555  	return db, nil
   556  }
   557  
   558  func (l *internalLookupCtx) getTableByID(id sqlbase.ID) (*TableDescriptor, error) {
   559  	tb, ok := l.tbDescs[id]
   560  	if !ok {
   561  		return nil, sqlbase.NewUndefinedRelationError(
   562  			tree.NewUnqualifiedTableName(tree.Name(fmt.Sprintf("[%d]", id))))
   563  	}
   564  	return tb, nil
   565  }
   566  
   567  func (l *internalLookupCtx) getParentName(table *TableDescriptor) string {
   568  	parentName := l.dbNames[table.GetParentID()]
   569  	if parentName == "" {
   570  		// The parent database was deleted. This is possible e.g. when
   571  		// a database is dropped with CASCADE, and someone queries
   572  		// this virtual table before the dropped table descriptors are
   573  		// effectively deleted.
   574  		parentName = fmt.Sprintf("[%d]", table.GetParentID())
   575  	}
   576  	return parentName
   577  }
   578  
   579  // getParentAsTableName returns a TreeTable object of the parent table for a
   580  // given table ID. Used to get the parent table of a table with interleaved
   581  // indexes.
   582  func getParentAsTableName(
   583  	l simpleSchemaResolver, parentTableID sqlbase.ID, dbPrefix string,
   584  ) (tree.TableName, error) {
   585  	var parentName tree.TableName
   586  	parentTable, err := l.getTableByID(parentTableID)
   587  	if err != nil {
   588  		return tree.TableName{}, err
   589  	}
   590  	parentDbDesc, err := l.getDatabaseByID(parentTable.ParentID)
   591  	if err != nil {
   592  		return tree.TableName{}, err
   593  	}
   594  	parentName = tree.MakeTableName(tree.Name(parentDbDesc.Name), tree.Name(parentTable.Name))
   595  	parentName.ExplicitSchema = parentDbDesc.Name != dbPrefix
   596  	return parentName, nil
   597  }
   598  
   599  // getTableAsTableName returns a TableName object for a given TableDescriptor.
   600  func getTableAsTableName(
   601  	l simpleSchemaResolver, table *sqlbase.TableDescriptor, dbPrefix string,
   602  ) (tree.TableName, error) {
   603  	var tableName tree.TableName
   604  	tableDbDesc, err := l.getDatabaseByID(table.ParentID)
   605  	if err != nil {
   606  		return tree.TableName{}, err
   607  	}
   608  	tableName = tree.MakeTableName(tree.Name(tableDbDesc.Name), tree.Name(table.Name))
   609  	tableName.ExplicitSchema = tableDbDesc.Name != dbPrefix
   610  	return tableName, nil
   611  }
   612  
   613  // The versions below are part of the work for #34240.
   614  // TODO(radu): clean these up when everything is switched over.
   615  
   616  // See ResolveMutableTableDescriptor.
   617  func (p *planner) ResolveMutableTableDescriptorEx(
   618  	ctx context.Context,
   619  	name *tree.UnresolvedObjectName,
   620  	required bool,
   621  	requiredType resolver.ResolveRequiredType,
   622  ) (*MutableTableDescriptor, error) {
   623  	tn := name.ToTableName()
   624  	table, err := resolver.ResolveMutableExistingTableObject(ctx, p, &tn, required, requiredType)
   625  	if err != nil {
   626  		return nil, err
   627  	}
   628  	name.SetAnnotation(&p.semaCtx.Annotations, &tn)
   629  	return table, nil
   630  }
   631  
   632  // ResolveMutableTableDescriptorExAllowNoPrimaryKey performs the
   633  // same logic as ResolveMutableTableDescriptorEx but allows for
   634  // the resolved table to not have a primary key.
   635  func (p *planner) ResolveMutableTableDescriptorExAllowNoPrimaryKey(
   636  	ctx context.Context,
   637  	name *tree.UnresolvedObjectName,
   638  	required bool,
   639  	requiredType resolver.ResolveRequiredType,
   640  ) (*MutableTableDescriptor, error) {
   641  	lookupFlags := tree.ObjectLookupFlags{
   642  		CommonLookupFlags:      tree.CommonLookupFlags{Required: required},
   643  		RequireMutable:         true,
   644  		AllowWithoutPrimaryKey: true,
   645  	}
   646  	desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, requiredType)
   647  	if err != nil || desc == nil {
   648  		return nil, err
   649  	}
   650  	tn := tree.MakeTableNameFromPrefix(prefix, tree.Name(name.Object()))
   651  	name.SetAnnotation(&p.semaCtx.Annotations, &tn)
   652  	return desc.(*MutableTableDescriptor), nil
   653  }
   654  
   655  // See ResolveUncachedTableDescriptor.
   656  func (p *planner) ResolveUncachedTableDescriptorEx(
   657  	ctx context.Context,
   658  	name *tree.UnresolvedObjectName,
   659  	required bool,
   660  	requiredType resolver.ResolveRequiredType,
   661  ) (table *ImmutableTableDescriptor, err error) {
   662  	p.runWithOptions(resolveFlags{skipCache: true}, func() {
   663  		table, err = p.ResolveExistingObjectEx(ctx, name, required, requiredType)
   664  	})
   665  	return table, err
   666  }
   667  
   668  // See ResolveExistingTableObject.
   669  func (p *planner) ResolveExistingObjectEx(
   670  	ctx context.Context,
   671  	name *tree.UnresolvedObjectName,
   672  	required bool,
   673  	requiredType resolver.ResolveRequiredType,
   674  ) (res *ImmutableTableDescriptor, err error) {
   675  	lookupFlags := tree.ObjectLookupFlags{CommonLookupFlags: tree.CommonLookupFlags{Required: required}}
   676  	desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, requiredType)
   677  	if err != nil || desc == nil {
   678  		return nil, err
   679  	}
   680  	tn := tree.MakeTableNameFromPrefix(prefix, tree.Name(name.Object()))
   681  	name.SetAnnotation(&p.semaCtx.Annotations, &tn)
   682  	return desc.(*ImmutableTableDescriptor), nil
   683  }
   684  
   685  // ResolvedName is a convenience wrapper for UnresolvedObjectName.Resolved.
   686  func (p *planner) ResolvedName(u *tree.UnresolvedObjectName) tree.ObjectName {
   687  	return u.Resolved(&p.semaCtx.Annotations)
   688  }
   689  
   690  type simpleSchemaResolver interface {
   691  	getDatabaseByID(id sqlbase.ID) (*DatabaseDescriptor, error)
   692  	getTableByID(id sqlbase.ID) (*TableDescriptor, error)
   693  }