Skip to content

Commit

Permalink
Merge pull request #71421 from dt/backport21.2-71161
Browse files Browse the repository at this point in the history
release-21.2: backupccl: fix bug when restoring a table with existing UDT
  • Loading branch information
dt authored Oct 11, 2021
2 parents 26f11c0 + 78b2673 commit 2ef2409
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
23 changes: 23 additions & 0 deletions pkg/ccl/backupccl/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8759,3 +8759,26 @@ DROP TABLE foo;
defer cleanupEmptyCluster()
sqlDBRestore.Exec(t, "RESTORE FROM $1 AS OF SYSTEM TIME "+aost, LocalFoo)
}

// TestRestoreRemappingOfExistingUDTInColExpr is a regression test for a nil
// pointer exception when restoring tables that point to existing types. When
// updating the back references of the existing types we would index into a map
// keyed on pre-rewrite IDs using a post rewrite ID.
func TestRestoreRemappingOfExistingUDTInColExpr(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

const numAccounts = 1
_, _, sqlDB, _, cleanupFn := BackupRestoreTestSetup(t, singleNode, numAccounts, InitManualReplication)
defer cleanupFn()

sqlDB.Exec(t, `
CREATE TYPE status AS ENUM ('open', 'closed', 'inactive');
CREATE TABLE foo (id INT PRIMARY KEY, what status default 'open');
BACKUP DATABASE data to 'nodelocal://0/foo';
DROP TABLE foo CASCADE;
DROP TYPE status;
CREATE TYPE status AS ENUM ('open', 'closed', 'inactive');
RESTORE TABLE foo FROM 'nodelocal://0/foo';
`)
}
23 changes: 20 additions & 3 deletions pkg/ccl/backupccl/restore_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -1142,8 +1142,21 @@ func createImportingDescriptors(
}
}

// Assign new IDs to all of the type descriptors that need to be written.
if err := rewriteTypeDescs(typesToWrite, details.DescriptorRewrites); err != nil {
// Perform rewrites on ALL type descriptors that are present in the rewrite
// mapping.
//
// `types` contains a mix of existing type descriptors in the restoring
// cluster, and new type descriptors we will write from the backup.
//
// New type descriptors need to be rewritten with their generated IDs before
// they are written out to disk.
//
// Existing type descriptors need to be rewritten to the type ID of the type
// they are referring to in the restoring cluster. This ID is different from
// the ID the descriptor had when it was backed up. Changes to existing type
// descriptors will not be written to disk, and is only for accurate,
// in-memory resolution hereon out.
if err := rewriteTypeDescs(types, details.DescriptorRewrites); err != nil {
return nil, nil, err
}

Expand Down Expand Up @@ -1316,7 +1329,11 @@ func createImportingDescriptors(
return err
}
typeIDs, _, err := table.GetAllReferencedTypeIDs(dbDesc, func(id descpb.ID) (catalog.TypeDescriptor, error) {
return typesByID[id], nil
t, ok := typesByID[id]
if !ok {
return nil, errors.AssertionFailedf("type with id %d was not found in rewritten type mapping", id)
}
return t, nil
})
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/ccl/backupccl/restore_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,8 @@ func allocateDescriptorRewrites(

if parentDB.IsMultiRegion() && table.GetLocalityConfig() != nil {
// We're restoring a table and not its parent database. We may block
// restoring multi-region tables to multi-region databases since regions
// may mismatch.
// restoring multi-region tables to multi-region databases since
// regions may mismatch.
if err := checkMultiRegionCompatible(ctx, txn, p.ExecCfg().Codec, table, parentDB); err != nil {
return pgerror.WithCandidateCode(err, pgcode.FeatureNotSupported)
}
Expand Down

0 comments on commit 2ef2409

Please sign in to comment.