diff --git a/pkg/sql/catalog/internal/validate/validate.go b/pkg/sql/catalog/internal/validate/validate.go index 616dd23ed605..3d1d834bccbe 100644 --- a/pkg/sql/catalog/internal/validate/validate.go +++ b/pkg/sql/catalog/internal/validate/validate.go @@ -58,6 +58,15 @@ func Validate( targetLevel catalog.ValidationLevel, descriptors ...catalog.Descriptor, ) catalog.ValidationErrors { + for i, d := range descriptors { + // Replace mutable descriptors with immutable copies. Validation is + // read-only in any case, and using immutables can have a significant + // impact on performance when validating tables due to columns, indexes, + // and so forth being cached. + if mut, ok := d.(catalog.MutableDescriptor); ok { + descriptors[i] = mut.ImmutableCopy() + } + } vea := validationErrorAccumulator{ ValidationTelemetry: telemetry, targetLevel: targetLevel, @@ -409,9 +418,17 @@ func (cs *collectorState) getMissingDescs( return nil, err } for _, desc := range resps { - if desc != nil { - cs.vdg.descriptors[desc.GetID()] = desc + if desc == nil { + continue + } + if mut, ok := desc.(catalog.MutableDescriptor); ok { + // Replace mutable descriptors with immutable copies. Validation is + // read-only in any case, and using immutables can have a significant + // impact on performance when validating tables due to columns, indexes, + // and so forth being cached. + desc = mut.ImmutableCopy() } + cs.vdg.descriptors[desc.GetID()] = desc } return resps, nil }