forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
60775: sql: descriptor validation overhaul r=postamar a=postamar sql: descriptor validation overhaul Previously, descriptor validation suffered from a few shortcomings: 1. The methods to call were inconsistent across descriptor types, and the error messages they return are inconsistent as well. 2. Those methods made ad-hoc use of catalog.DescGetter to walk through the descriptor reference graph, and could sometimes walk surprisingly far. This is particularly true for type descriptors, which hold references to other types. 3. To complicate things further, DescGetter implementations which read descriptors from storage themselves perform validation as well. Although it is perfectly sensible to systematically validate descriptors when read, there is a circularity problem at hand which would benefit from being solved without melting the maintainer's brain in the process. 4. The validation methods return an error type, making it awkward to return multiple errors. Tools like doctor would be made more useful if they could report more than only the first encountered error. Recently we introduced a change that added descriptor validation on write. This change involves validating all uncommitted descriptors in bulk and this in turn favours a bulk approach to reading all their referenced descriptors from storage. With this in mind, this commit adds a GetReferencedDescIDs method to catalog.Descriptor which returns the IDs of all descriptors referenced by the receiver. By calling this method on all descriptors we intend to validate and by reading all referenced descriptors in one kv.Batch and stuffing them in a catalog.MapDescGetter, we can now validate using this in-memory DescGetter instead. Turning validation into this multi-step process means it can no longer be invoked as a method call on the target descriptor. This commit moves the entry point to descriptor validation to the catalog.Validate function. The descriptor objects themselves still define the validation checks themselves but these are effectively made inaccessible from outside the catalog package. The rationale behind this is to enforce order in the sequence of checks performed and to enforce some uniformity in the formatting of the error messages. The checks are grouped into three tiers: internal consistency checks, cross-reference consistency checks, and transactional consistency checks. All this also helps reduce the number of call sites of descriptor validations as well as increase the scope of the validations. This has uncovered a few bugs related to schemas and temporary tables. This effort has also helped identify validation checks which have since been made redundant, either by other existing rules or by the new validation-on-write behaviour. Finally, this has allowed us to strip doctor of its own duplicated (and dodgy) validation logic and simply report all validation errors instead. Release justification: bug fixes and low-risk updates to new functionality (descriptor validation on write). Release note (cli change): The doctor tool can now report multiple descriptor validation failures per descriptor. ---- *Follow-up work* - `WriteDescriptors` in `pkg/ccl/backupccl/restore_job.go`: should it validate schemas and types also? It seems like it should. When I add those, tests fail. I didn't look into it further. Probably out of scope for this change. - ~Add linter check to enforce the use of `catalog.Validate` and `catalog.ValidateSelf`? It seems all too easy to call the `ValidateSelf` method on a `catalog.Descriptor` without being aware that it returns an `[]error` instead of an `error`.~ (edit: I since changed the way validation errors were collected, making a linter check unnecessary) - Remove privileges surgery in `ValidateSelf` methods in favour of `NewFilledInImmutable`-like constructors. I don't like that validation functionality changes the underlying objects. (edit: this is actually really hard, and dangerous! giving up on this for now) - ~I feel like my validation error wrapping is an improvement to the incoherent messaging that prevailed before but I'm not sure what's best to put in the prefix message. I settled on `errors.Wrapf(err, "%s %q", desc.TypeName(), desc.GetName())` but it could be anything else really. Do we prefer reporting names or IDs? I also don't know whether error message changes are considered to be contract-breaking, worthy of release note mentions, interfering with stability period, etc.~(edit: done like Andrew suggested below) *Review guide* The meat and potatoes of the change is in `pkg/sql/catalog/*.go`, best start reviewing from there, moving on to the `pkg/sql/catalog/*desc` packages. Notice that I moved the validation logic in `tabledesc` out of `structured.go` into a new file, `validate.go`. The diff in `structured.go` was going to be messy anyways despite there not being too many significant underlying changes: it's just calling `Report` with the errors, moving stuff around, removing redundancies, breaking down massive functions into smaller chunks, etc. The code still basically does the same thing. I moved tests cases around also. Co-authored-by: Marius Posta <[email protected]>
- Loading branch information
Showing
74 changed files
with
4,373 additions
and
3,632 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.