Skip to content

Commit

Permalink
sql/catalog: add Column interface and TableDescriptor methods
Browse files Browse the repository at this point in the history
Previously, the catalog.TableDescriptor interface and its implementing
types would liberally return descpb.ColumnDescriptor values, pointers and
slices. In an effort to stop manipulating such protos directly, this
patch introduces a catalog.Column interface to encapsulate it. In order
to enventually propagate this change throughout the code base, this
patch marks some existing catalog.TableDescriptor methods as deprecated
and introduces new ones to eventually replace them.

This work is very similar to that which I already performed for #57465.

Fixes #59805.

Release note: None
  • Loading branch information
Marius Posta committed Feb 5, 2021
1 parent c584f62 commit a4ac4d1
Show file tree
Hide file tree
Showing 10 changed files with 601 additions and 246 deletions.
2 changes: 1 addition & 1 deletion pkg/ccl/changefeedccl/rowfetcher_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (c *rowFetcherCache) RowFetcherForTableDesc(
// guaranteed that the tables have the same version. Additionally, these
// fetchers are always initialized with a single tabledesc.Immutable.
if rf, ok := c.fetchers[idVer]; ok &&
tableDesc.UserDefinedTypeColsHaveSameVersion(rf.GetTables()[0].(catalog.TableDescriptor)) {
catalog.UserDefinedTypeColsHaveSameVersion(tableDesc, rf.GetTables()[0].(catalog.TableDescriptor)) {
return rf, nil
}
// TODO(dan): Allow for decoding a subset of the columns.
Expand Down
16 changes: 4 additions & 12 deletions pkg/ccl/changefeedccl/schemafeed/schema_feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,22 +167,14 @@ func (t *typeDependencyTracker) removeDependency(typeID, tableID descpb.ID) {
}

func (t *typeDependencyTracker) purgeTable(tbl catalog.TableDescriptor) {
if !tbl.ContainsUserDefinedTypes() {
return
}
for _, colOrd := range tbl.GetColumnOrdinalsWithUserDefinedTypes() {
colTyp := tbl.DeletableColumns()[colOrd].Type
t.removeDependency(typedesc.UserDefinedTypeOIDToID(colTyp.Oid()), tbl.GetID())
for _, col := range tbl.ColumnsWithUserDefinedTypesNew() {
t.removeDependency(typedesc.UserDefinedTypeOIDToID(col.GetType().Oid()), tbl.GetID())
}
}

func (t *typeDependencyTracker) ingestTable(tbl catalog.TableDescriptor) {
if !tbl.ContainsUserDefinedTypes() {
return
}
for _, colOrd := range tbl.GetColumnOrdinalsWithUserDefinedTypes() {
colTyp := tbl.DeletableColumns()[colOrd].Type
t.addDependency(typedesc.UserDefinedTypeOIDToID(colTyp.Oid()), tbl.GetID())
for _, col := range tbl.ColumnsWithUserDefinedTypesNew() {
t.addDependency(typedesc.UserDefinedTypeOIDToID(col.GetType().Oid()), tbl.GetID())
}
}

Expand Down
167 changes: 148 additions & 19 deletions pkg/sql/catalog/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,39 @@ type TableDescriptor interface {
HasPrimaryKey() bool
PrimaryKeyString() string

GetPublicColumns() []descpb.ColumnDescriptor
ForeachPublicColumn(f func(col *descpb.ColumnDescriptor) error) error
ForeachNonDropColumn(f func(col *descpb.ColumnDescriptor) error) error
AllColumnsNew() []Column
PublicColumnsNew() []Column
WritableColumnsNew() []Column
NonDropColumnsNew() []Column
VisibleColumnsNew() []Column
ReadableColumnsNew() []Column
ColumnsWithUserDefinedTypesNew() []Column

FindColumnWithID(id descpb.ColumnID) (Column, error)
FindColumnWithName(name tree.Name) (Column, error)

GetPublicColumns() []descpb.ColumnDescriptor // deprecated
ForeachPublicColumn(f func(col *descpb.ColumnDescriptor) error) error // deprecated
ForeachNonDropColumn(f func(col *descpb.ColumnDescriptor) error) error // deprecated
NamesForColumnIDs(ids descpb.ColumnIDs) ([]string, error)
FindColumnByName(name tree.Name) (*descpb.ColumnDescriptor, bool, error)
FindActiveColumnByID(id descpb.ColumnID) (*descpb.ColumnDescriptor, error)
FindColumnByID(id descpb.ColumnID) (*descpb.ColumnDescriptor, error)
FindColumnByName(name tree.Name) (*descpb.ColumnDescriptor, bool, error) // deprecated
FindActiveColumnByID(id descpb.ColumnID) (*descpb.ColumnDescriptor, error) // deprecated
FindColumnByID(id descpb.ColumnID) (*descpb.ColumnDescriptor, error) // deprecated
ColumnIdxMap() TableColMap
GetColumnAtIdx(idx int) *descpb.ColumnDescriptor
AllNonDropColumns() []descpb.ColumnDescriptor
VisibleColumns() []descpb.ColumnDescriptor
ColumnsWithMutations(includeMutations bool) []descpb.ColumnDescriptor
GetColumnAtIdx(idx int) *descpb.ColumnDescriptor // deprecated
AllNonDropColumns() []descpb.ColumnDescriptor // deprecated
VisibleColumns() []descpb.ColumnDescriptor // deprecated
ColumnsWithMutations(includeMutations bool) []descpb.ColumnDescriptor // deprecated
ColumnIdxMapWithMutations(includeMutations bool) TableColMap
DeletableColumns() []descpb.ColumnDescriptor
MutationColumns() []descpb.ColumnDescriptor
DeletableColumns() []descpb.ColumnDescriptor // deprecated
MutationColumns() []descpb.ColumnDescriptor // deprecated
ContainsUserDefinedTypes() bool
GetColumnOrdinalsWithUserDefinedTypes() []int
UserDefinedTypeColsHaveSameVersion(otherDesc TableDescriptor) bool
FindActiveColumnByName(s string) (*descpb.ColumnDescriptor, error)
WritableColumns() []descpb.ColumnDescriptor
ReadableColumns() []descpb.ColumnDescriptor
FindActiveColumnByName(s string) (*descpb.ColumnDescriptor, error) // deprecated
WritableColumns() []descpb.ColumnDescriptor // deprecated
ReadableColumns() []descpb.ColumnDescriptor // deprecated
GetNextColumnID() descpb.ColumnID
HasColumnWithName(name tree.Name) (*descpb.ColumnDescriptor, bool)
FindActiveColumnsByNames(names tree.NameList) ([]descpb.ColumnDescriptor, error)
HasColumnWithName(name tree.Name) (*descpb.ColumnDescriptor, bool) // deprecated
FindActiveColumnsByNames(names tree.NameList) ([]descpb.ColumnDescriptor, error) // deprecated
ColumnTypes() []*types.T
ColumnTypesWithMutations(mutations bool) []*types.T
ColumnTypesWithMutationsAndVirtualCol(mutations bool, virtualCol *descpb.ColumnDescriptor) []*types.T
Expand Down Expand Up @@ -379,6 +388,111 @@ type Index interface {
GetCompositeColumnID(compositeColumnOrdinal int) descpb.ColumnID
}

// Column is an interface around the index descriptor types.
type Column interface {

// ColumnDesc returns the underlying protobuf descriptor.
// Ideally, this method should be called as rarely as possible.
ColumnDesc() *descpb.ColumnDescriptor

// ColumnDescDeepCopy returns a deep copy of the underlying proto.
ColumnDescDeepCopy() descpb.ColumnDescriptor

// Ordinal returns the ordinal of the column in its parent table descriptor.
//
// The ordinal of a column in a `tableDesc descpb.TableDescriptor` is
// defined as follows:
// - [0:len(tableDesc.Columns)] is the range of public columns,
// - [len(tableDesc.Columns):] is the range of non-public columns.
//
// In terms of a `table catalog.TableDescriptor` interface, it is defined
// as the catalog.Column object's position in the table.AllColumns() slice.
Ordinal() int

// Public returns true iff the column is active, i.e. readable, in the table
// descriptor.
Public() bool

// WriteAndDeleteOnly returns true iff the column is a mutation in the
// delete-and-write-only state in the table descriptor.
WriteAndDeleteOnly() bool

// DeleteOnly returns true iff the column is a mutation in the delete-only
// state in the table descriptor.
DeleteOnly() bool

// Adding returns true iff the column is an add mutation in the table
// descriptor.
Adding() bool

// Dropped returns true iff the column is a drop mutation in the table
// descriptor.
Dropped() bool

// GetID returns the column ID.
GetID() descpb.ColumnID

// GetName returns the column name as a string.
GetName() string

// ColName returns the column name as a tree.Name.
ColName() tree.Name

// HasType returns true iff the column type is set.
HasType() bool

// GetType returns the column type.
GetType() *types.T

// IsNullable returns true iff the column allows NULL values.
IsNullable() bool

// HasDefault returns true iff the column has a default expression set.
HasDefault() bool

// GetDefaultExpr returns the column default expression if it exists,
// empty string otherwise.
GetDefaultExpr() string

// IsComputed returns true iff the column is a computed column.
IsComputed() bool

// GetComputeExpr returns the column computed expression if it exists,
// empty string otherwise.
GetComputeExpr() string

// IsHidden returns true iff the column is not visible.
IsHidden() bool

// NumUsesSequences returns the number of sequences used by this column.
NumUsesSequences() int

// GetUsesSequenceID returns the ID of a sequence used by this column.
GetUsesSequenceID(usesSequenceOrdinal int) descpb.ID

// NumOwnsSequences returns the number of sequences owned by this column.
NumOwnsSequences() int

// GetOwnsSequenceID returns the ID of a sequence owned by this column.
GetOwnsSequenceID(ownsSequenceOrdinal int) descpb.ID

// IsVirtual returns true iff the column is a virtual column.
IsVirtual() bool

// CheckCanBeInboundFKRef returns whether the given column can be on the
// referenced (target) side of a foreign key relation.
CheckCanBeInboundFKRef() error

// CheckCanBeOutboundFKRef returns whether the given column can be on the
// referencing (origin) side of a foreign key relation.
CheckCanBeOutboundFKRef() error

// GetPGAttributeNum returns the PGAttributeNum of the column descriptor
// if the PGAttributeNum is set (non-zero). Returns the ID of the
// column descriptor if the PGAttributeNum is not set.
GetPGAttributeNum() uint32
}

// TypeDescriptor will eventually be called typedesc.Descriptor.
// It is implemented by (Imm|M)utableTypeDescriptor.
type TypeDescriptor interface {
Expand Down Expand Up @@ -623,3 +737,18 @@ func FindDeletableNonPrimaryIndex(desc TableDescriptor, test func(idx Index) boo
func FindDeleteOnlyNonPrimaryIndex(desc TableDescriptor, test func(idx Index) bool) Index {
return findIndex(desc.DeleteOnlyNonPrimaryIndexes(), test)
}

// UserDefinedTypeColsHaveSameVersion returns whether one table descriptor's
// columns with user defined type metadata have the same versions of metadata
// as in the other descriptor. Note that this function is only valid on two
// descriptors representing the same table at the same version.
func UserDefinedTypeColsHaveSameVersion(desc TableDescriptor, otherDesc TableDescriptor) bool {
otherCols := otherDesc.ColumnsWithUserDefinedTypesNew()
for i, thisCol := range desc.ColumnsWithUserDefinedTypesNew() {
this, other := thisCol.GetType(), otherCols[i].GetType()
if this.TypeMeta.Version != other.TypeMeta.Version {
return false
}
}
return true
}
1 change: 1 addition & 0 deletions pkg/sql/catalog/tabledesc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "tabledesc",
srcs = [
"column.go",
"index.go",
"safe_format.go",
"structured.go",
Expand Down
Loading

0 comments on commit a4ac4d1

Please sign in to comment.