Skip to content

Commit

Permalink
Add LogicalColumnID field to ColumnDescriptor.
Browse files Browse the repository at this point in the history
The LogicalColumnID field mimics the ColumnID field however LogicalColumnID may be swapped
between two columns whereas ColumnID cannot. LogicalColumnID is referenced for virtual tables
(pg_catalog, information_schema) and most notably affects column ordering for SHOW COLUMNS.

This LogicalColumnID field support swapping the order of two columns - currently only used for
ALTER COLUMN TYPE when a shadow column is created and swapped with it's original column.

Does not affect existing behaviour.

Release note: None
  • Loading branch information
RichardJCai committed Apr 7, 2020
1 parent 1c27a9f commit 07ed952
Show file tree
Hide file tree
Showing 11 changed files with 527 additions and 446 deletions.
3 changes: 3 additions & 0 deletions pkg/ccl/backupccl/restore_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ func allocateTableRewrites(
// backup descriptors provided. if skipFKsWithNoMatchingTable is set, FKs whose
// "other" table is missing from the set provided are omitted during the
// upgrade, instead of causing an error to be returned.
// Also assigns LogicalColumnIDs for TableDescriptors that do not have it,
// namely TableDescriptors created before 20.2.
func maybeUpgradeTableDescsInBackupManifests(
ctx context.Context, backupManifests []BackupManifest, skipFKsWithNoMatchingTable bool,
) error {
Expand All @@ -413,6 +415,7 @@ func maybeUpgradeTableDescsInBackupManifests(
if _, err := table.MaybeUpgradeForeignKeyRepresentation(ctx, protoGetter, skipFKsWithNoMatchingTable); err != nil {
return err
}
table.MaybeFillInLogicalColumnID()
// TODO(lucy): Is this necessary?
backupManifest.Descriptors[j] = *sqlbase.WrapDescriptor(table)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func getDescriptorByID(
return pgerror.Newf(pgcode.WrongObjectType,
"%q is not a table", desc.String())
}
if err := table.MaybeFillInDescriptor(ctx, txn); err != nil {
if _, err := table.MaybeFillInDescriptor(ctx, txn); err != nil {
return err
}

Expand Down Expand Up @@ -320,7 +320,7 @@ func GetAllDescriptors(ctx context.Context, txn *kv.Txn) ([]sqlbase.DescriptorPr
switch t := desc.Union.(type) {
case *sqlbase.Descriptor_Table:
table := desc.Table(kv.Value.Timestamp)
if err := table.MaybeFillInDescriptor(ctx, txn); err != nil {
if _, err := table.MaybeFillInDescriptor(ctx, txn); err != nil {
return nil, err
}
descs = append(descs, table)
Expand Down
10 changes: 5 additions & 5 deletions pkg/sql/information_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,11 @@ https://www.postgresql.org/docs/9.5/infoschema-columns.html`,
collationName = tree.NewDString(locale)
}
return addRow(
dbNameStr, // table_catalog
scNameStr, // table_schema
tree.NewDString(table.Name), // table_name
tree.NewDString(column.Name), // column_name
tree.NewDInt(tree.DInt(column.ID)), // ordinal_position
dbNameStr, // table_catalog
scNameStr, // table_schema
tree.NewDString(table.Name), // table_name
tree.NewDString(column.Name), // column_name
tree.NewDInt(tree.DInt(column.LogicalColumnID)), // ordinal_position
dStringPtrOrNull(column.DefaultExpr), // column_default
yesOrNoDatum(column.Nullable), // is_nullable
tree.NewDString(column.Type.InformationSchemaName()), // data_type
Expand Down
6 changes: 3 additions & 3 deletions pkg/sql/lease.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func (s LeaseStore) acquire(
if err := FilterTableState(tableDesc); err != nil {
return err
}
if err := tableDesc.MaybeFillInDescriptor(ctx, txn); err != nil {
if _, err := tableDesc.MaybeFillInDescriptor(ctx, txn); err != nil {
return err
}
// Once the descriptor is set it is immutable and care must be taken
Expand Down Expand Up @@ -583,7 +583,7 @@ func (s LeaseStore) getForExpiration(
if prevTimestamp.LessEq(tableDesc.ModificationTime) {
return errors.AssertionFailedf("unable to read table= (%d, %s)", id, expiration)
}
if err := tableDesc.MaybeFillInDescriptor(ctx, txn); err != nil {
if _, err := tableDesc.MaybeFillInDescriptor(ctx, txn); err != nil {
return err
}
// Create a tableVersionState with the table and without a lease.
Expand Down Expand Up @@ -1799,7 +1799,7 @@ func (m *LeaseManager) RefreshLeases(s *stop.Stopper, db *kv.DB, g *gossip.Gossi
// Note that we don't need to "fill in" the descriptor here. Nobody
// actually reads the table, but it's necessary for the call to
// ValidateTable().
if err := table.MaybeFillInDescriptor(ctx, nil); err != nil {
if _, err := table.MaybeFillInDescriptor(ctx, nil); err != nil {
log.Warningf(ctx, "%s: unable to fill in table descriptor %v", kv.Key, table)
return
}
Expand Down
42 changes: 20 additions & 22 deletions pkg/sql/pg_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,7 @@ CREATE TABLE pg_catalog.pg_attrdef (
h := makeOidHasher()
return forEachTableDesc(ctx, p, dbContext, virtualMany,
func(db *sqlbase.DatabaseDescriptor, scName string, table *sqlbase.TableDescriptor) error {
colNum := 0
return forEachColumnInTable(table, func(column *sqlbase.ColumnDescriptor) error {
colNum++
if column.DefaultExpr == nil {
// pg_attrdef only expects rows for columns with default values.
return nil
Expand All @@ -408,11 +406,11 @@ CREATE TABLE pg_catalog.pg_attrdef (
defSrc = tree.NewDString(ctx.String())
}
return addRow(
h.ColumnOid(table.ID, column.ID), // oid
defaultOid(table.ID), // adrelid
tree.NewDInt(tree.DInt(colNum)), // adnum
defSrc, // adbin
defSrc, // adsrc
h.ColumnOid(table.ID, column.ID), // oid
defaultOid(table.ID), // adrelid
tree.NewDInt(tree.DInt(column.LogicalColumnID)), // adnum
defSrc, // adbin
defSrc, // adsrc
)
})
})
Expand Down Expand Up @@ -450,7 +448,7 @@ CREATE TABLE pg_catalog.pg_attribute (
h := makeOidHasher()
return forEachTableDesc(ctx, p, dbContext, virtualMany, func(db *sqlbase.DatabaseDescriptor, scName string, table *sqlbase.TableDescriptor) error {
// addColumn adds adds either a table or a index column to the pg_attribute table.
addColumn := func(column *sqlbase.ColumnDescriptor, attRelID tree.Datum, colID sqlbase.ColumnID) error {
addColumn := func(column *sqlbase.ColumnDescriptor, attRelID tree.Datum, logicalColID sqlbase.ColumnID) error {
colTyp := &column.Type
attTypMod := int32(-1)
if width := colTyp.Width(); width != 0 {
Expand All @@ -470,18 +468,18 @@ CREATE TABLE pg_catalog.pg_attribute (
}
}
return addRow(
attRelID, // attrelid
tree.NewDName(column.Name), // attname
typOid(colTyp), // atttypid
zeroVal, // attstattarget
typLen(colTyp), // attlen
tree.NewDInt(tree.DInt(colID)), // attnum
zeroVal, // attndims
negOneVal, // attcacheoff
tree.NewDInt(tree.DInt(attTypMod)), // atttypmod
tree.DNull, // attbyval (see pg_type.typbyval)
tree.DNull, // attstorage
tree.DNull, // attalign
attRelID, // attrelid
tree.NewDName(column.Name), // attname
typOid(colTyp), // atttypid
zeroVal, // attstattarget
typLen(colTyp), // attlen
tree.NewDInt(tree.DInt(logicalColID)), // attnum
zeroVal, // attndims
negOneVal, // attcacheoff
tree.NewDInt(tree.DInt(attTypMod)), // atttypmod
tree.DNull, // attbyval (see pg_type.typbyval)
tree.DNull, // attstorage
tree.DNull, // attalign
tree.MakeDBool(tree.DBool(!column.Nullable)), // attnotnull
tree.MakeDBool(tree.DBool(column.DefaultExpr != nil)), // atthasdef
tree.DBoolFalse, // attisdropped
Expand All @@ -497,7 +495,7 @@ CREATE TABLE pg_catalog.pg_attribute (
// Columns for table.
if err := forEachColumnInTable(table, func(column *sqlbase.ColumnDescriptor) error {
tableID := defaultOid(table.ID)
return addColumn(column, tableID, column.ID)
return addColumn(column, tableID, column.LogicalColumnID)
}); err != nil {
return err
}
Expand All @@ -507,7 +505,7 @@ CREATE TABLE pg_catalog.pg_attribute (
return forEachColumnInIndex(table, index,
func(column *sqlbase.ColumnDescriptor) error {
idxID := h.IndexOid(table.ID, index.ID)
return addColumn(column, idxID, column.ID)
return addColumn(column, idxID, column.LogicalColumnID)
},
)
})
Expand Down
42 changes: 34 additions & 8 deletions pkg/sql/sqlbase/structured.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ func GetTableDescFromID(
return nil, err
}

if err := table.MaybeFillInDescriptor(ctx, protoGetter); err != nil {
if _, err := table.MaybeFillInDescriptor(ctx, protoGetter); err != nil {
return nil, err
}

Expand All @@ -381,12 +381,11 @@ func GetTableDescFromIDWithFKsChanged(
if err != nil {
return nil, false, err
}
table.maybeUpgradeFormatVersion()
table.Privileges.MaybeFixPrivileges(table.ID)
changed, err := table.MaybeUpgradeForeignKeyRepresentation(ctx, protoGetter, false /* skipFKsWithNoMatchingTable */)
changed, err := table.MaybeFillInDescriptor(ctx, protoGetter)
if err != nil {
return nil, false, err
}

return table, changed, err
}

Expand Down Expand Up @@ -886,15 +885,21 @@ func generatedFamilyName(familyID FamilyID, columnNames []string) string {
// in a similar way.
func (desc *TableDescriptor) MaybeFillInDescriptor(
ctx context.Context, protoGetter protoGetter,
) error {
) (bool, error) {
desc.maybeUpgradeFormatVersion()
desc.Privileges.MaybeFixPrivileges(desc.ID)

var changed bool
var err error
if protoGetter != nil {
if _, err := desc.MaybeUpgradeForeignKeyRepresentation(ctx, protoGetter, false /* skipFKsWithNoMatchingTable*/); err != nil {
return err
if changed, err = desc.MaybeUpgradeForeignKeyRepresentation(ctx, protoGetter, false /* skipFKsWithNoMatchingTable*/); err != nil {
return false, err
}
}
return nil

desc.MaybeFillInLogicalColumnID()

return changed, nil
}

// MapProtoGetter is a protoGetter that has a hard-coded map of keys to proto
Expand Down Expand Up @@ -1198,6 +1203,27 @@ func (desc *MutableTableDescriptor) MaybeFillColumnID(
}
columnNames[c.Name] = columnID
c.ID = columnID
c.LogicalColumnID = columnID
}

// MaybeFillInLogicalColumnID assigns a LogicalColumnID to a column
// if the ColumnID is set and the LogicalColumnID is not
// it assigns the ColumnID as the LogicalColumnID.
func (desc *TableDescriptor) MaybeFillInLogicalColumnID() {
for i := range desc.Columns {
col := &desc.Columns[i]
if col.ID != 0 && col.LogicalColumnID == 0 {
col.LogicalColumnID = col.ID
}
}

for _, m := range desc.Mutations {
if col := m.GetColumn(); col != nil {
if col.ID != 0 && col.LogicalColumnID == 0 {
col.LogicalColumnID = col.ID
}
}
}
}

// AllocateIDs allocates column, family, and index ids for any column, family,
Expand Down
Loading

0 comments on commit 07ed952

Please sign in to comment.