From f7375c165d7b90ca902bc4cbf795995169c27fd9 Mon Sep 17 00:00:00 2001 From: Rohan Yadav Date: Wed, 27 May 2020 21:16:59 -0400 Subject: [PATCH] sql: introduce `{Imm,M}utableTypeDescriptor` and plumbing This PR introduces the `ImmutableTypeDescriptor` and `MutableTypeDescriptor` types, and plumbs them through to existing usages. Once more descriptor refactoring completes, only operations on `TypeDescriptor`s through these wrapper structs will be allowed. Release note: None --- .../catalog/catalogkv/physical_accessor.go | 5 ++- pkg/sql/catalog/resolver/resolver.go | 5 ++- pkg/sql/resolver.go | 3 +- pkg/sql/sqlbase/structured.go | 39 +++++++++++++++++++ pkg/sql/virtual_schema.go | 13 +++++-- 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/pkg/sql/catalog/catalogkv/physical_accessor.go b/pkg/sql/catalog/catalogkv/physical_accessor.go index 291592a4c89b..9e39588f54a5 100644 --- a/pkg/sql/catalog/catalogkv/physical_accessor.go +++ b/pkg/sql/catalog/catalogkv/physical_accessor.go @@ -235,7 +235,10 @@ func (a UncachedPhysicalAccessor) GetObjectDesc( } return nil, nil case *sqlbase.TypeDescriptor: - return desc, nil + if flags.RequireMutable { + return sqlbase.NewMutableExistingTypeDescriptor(*desc), nil + } + return sqlbase.NewImmutableTypeDescriptor(*desc), nil default: return nil, nil } diff --git a/pkg/sql/catalog/resolver/resolver.go b/pkg/sql/catalog/resolver/resolver.go index cb77587206b3..a9ff7fae1fb0 100644 --- a/pkg/sql/catalog/resolver/resolver.go +++ b/pkg/sql/catalog/resolver/resolver.go @@ -151,7 +151,10 @@ func ResolveExistingObject( if obj.TypeDesc() == nil { return nil, prefix, sqlbase.NewUndefinedTypeError(&resolvedTn) } - return obj.TypeDesc(), prefix, nil + if lookupFlags.RequireMutable { + return obj.(*sqlbase.MutableTypeDescriptor), prefix, nil + } + return obj.(*sqlbase.ImmutableTypeDescriptor), prefix, nil case tree.TableObject: if obj.TableDesc() == nil { return nil, prefix, sqlbase.NewUndefinedRelationError(&resolvedTn) diff --git a/pkg/sql/resolver.go b/pkg/sql/resolver.go index e4a110bf2a3b..4b20a04c82ed 100644 --- a/pkg/sql/resolver.go +++ b/pkg/sql/resolver.go @@ -138,6 +138,7 @@ func (p *planner) ResolveType(name *tree.UnresolvedObjectName) (*types.T, error) lookupFlags := tree.ObjectLookupFlags{ CommonLookupFlags: tree.CommonLookupFlags{Required: true}, DesiredObjectKind: tree.TypeObject, + RequireMutable: false, } // TODO (rohany): The ResolveAnyDescType argument doesn't do anything here // if we are looking for a type. This should be cleaned up. @@ -146,7 +147,7 @@ func (p *planner) ResolveType(name *tree.UnresolvedObjectName) (*types.T, error) return nil, err } tn := tree.MakeTypeNameFromPrefix(prefix, tree.Name(name.Object())) - tdesc := desc.(*sqlbase.TypeDescriptor) + tdesc := desc.(*sqlbase.ImmutableTypeDescriptor) // Hydrate the types.T from the resolved descriptor. Once we cache // descriptors, this hydration should install pointers to cached data. switch t := tdesc.Kind; t { diff --git a/pkg/sql/sqlbase/structured.go b/pkg/sql/sqlbase/structured.go index cf69489f1cdb..374d1b17643f 100644 --- a/pkg/sql/sqlbase/structured.go +++ b/pkg/sql/sqlbase/structured.go @@ -4309,6 +4309,45 @@ func (desc *ImmutableTableDescriptor) TypeDesc() *TypeDescriptor { return nil } +// MutableTypeDescriptor is a custom type for TypeDescriptors undergoing +// any types of modifications. +type MutableTypeDescriptor struct { + TypeDescriptor + + // ClusterVersion represents the version of the type descriptor read + // from the store. + ClusterVersion TypeDescriptor +} + +// ImmutableTypeDescriptor is a custom type for wrapping TypeDescriptors +// when used in a read only way. +type ImmutableTypeDescriptor struct { + TypeDescriptor +} + +// Avoid linter unused warnings. +var _ = NewMutableCreatedTypeDescriptor + +// NewMutableCreatedTypeDescriptor returns a MutableTypeDescriptor from the +// given type descriptor with the cluster version being the zero type. This +// is for a type that is created in the same transaction. +func NewMutableCreatedTypeDescriptor(desc TypeDescriptor) *MutableTypeDescriptor { + return &MutableTypeDescriptor{TypeDescriptor: desc} +} + +// NewMutableExistingTypeDescriptor returns a MutableTypeDescriptor from the +// given type descriptor with the cluster version also set to the descriptor. +// This is for types that already exist. +func NewMutableExistingTypeDescriptor(desc TypeDescriptor) *MutableTypeDescriptor { + return &MutableTypeDescriptor{TypeDescriptor: desc, ClusterVersion: desc} +} + +// NewImmutableTypeDescriptor returns an ImmutableTypeDescriptor from the +// given TypeDescriptor. +func NewImmutableTypeDescriptor(desc TypeDescriptor) *ImmutableTypeDescriptor { + return &ImmutableTypeDescriptor{TypeDescriptor: desc} +} + // DatabaseDesc implements the ObjectDescriptor interface. func (desc *TypeDescriptor) DatabaseDesc() *DatabaseDescriptor { return nil diff --git a/pkg/sql/virtual_schema.go b/pkg/sql/virtual_schema.go index 2143c1621ab6..8ab75dab98c5 100644 --- a/pkg/sql/virtual_schema.go +++ b/pkg/sql/virtual_schema.go @@ -345,7 +345,10 @@ func (v virtualSchemaEntry) GetObjectByName( if !ok { return nil, nil } - return virtualTypeEntry{desc: sqlbase.MakeSimpleAliasTypeDescriptor(typ)}, nil + return virtualTypeEntry{ + desc: sqlbase.MakeSimpleAliasTypeDescriptor(typ), + mutable: flags.RequireMutable, + }, nil default: return nil, errors.AssertionFailedf("unknown desired object kind %d", flags.DesiredObjectKind) } @@ -371,11 +374,15 @@ func (e mutableVirtualDefEntry) Desc() catalog.Descriptor { } type virtualTypeEntry struct { - desc *sqlbase.TypeDescriptor + desc *sqlbase.TypeDescriptor + mutable bool } func (e virtualTypeEntry) Desc() catalog.Descriptor { - return e.desc + if e.mutable { + return sqlbase.NewMutableExistingTypeDescriptor(*e.desc) + } + return sqlbase.NewImmutableTypeDescriptor(*e.desc) } type virtualTableConstructor func(context.Context, *planner, string) (planNode, error)