Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: allow for pre-19.2 foreign keys in table validation #57066

Merged
merged 2 commits into from
Nov 24, 2020

Conversation

thoszhang
Copy link
Contributor

@thoszhang thoszhang commented Nov 24, 2020

sql: allow for pre-19.2 foreign keys in table validation

We introduced a bug in v20.2 where we failed to upgrade referenced
descriptors' FK representations from pre-19.2 descriptors when
validating cross-references for tables, leading to validation failures
that would make the table unusable. This PR gets rid of the validation
errors by having Validate() account for pre-19.2-style foreign keys on
referenced table descriptors.

Fixes #57032.

Release note (bug fix): Fixes a bug where tables and metadata were
unavailable due to spurious missing fk back reference validation
errors.


catalogkv: add testing of descriptor unwrapping and validation

This commit adds a framework to test that descriptors validate properly.
It also adds testdata and a bash script to generate that test data.

This test is to exercise a problematic path whereby tables constructed
in v19.1 would fail to validate in v20.2.

Release note: None

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@thoszhang thoszhang force-pushed the validate-old-fks branch 3 times, most recently from 58b9261 to 7e05797 Compare November 24, 2020 18:50
@thoszhang thoszhang changed the title [wip] sql: allow for pre-19.2 foreign keys in table validation sql: allow for pre-19.2 foreign keys in table validation Nov 24, 2020
@thoszhang thoszhang marked this pull request as ready for review November 24, 2020 18:51
@thoszhang thoszhang force-pushed the validate-old-fks branch 2 times, most recently from fdd2573 to a2b9edf Compare November 24, 2020 19:51
Copy link
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

I might extract some helpers and do some more line wrapping but that' extremely nitpicky.

Reviewed 1 of 1 files at r1, 4 of 4 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @ajwerner, @jordanlewis, and @lucy-zhang)


pkg/sql/catalog/catalogkv/unwrap_validation_test.go, line 16 at r2 (raw file):

	"context"
	"encoding/hex"
	"errors"

Is the linter going to complain about this?


pkg/sql/catalog/tabledesc/structured.go, line 1648 at r1 (raw file):


					"missing index %d on %q from pre-19.2 foreign key forward reference %q on %q",
					fk.Index, desc.Name, backref.Name, originTable.GetName(),

Would we be happier if these errors had the entire descriptor? The names are going to disappear in redaction. Same for all the other errors around here.

Copy link
Member

@jordanlewis jordanlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. If it's not too much trouble, I would like to see a unit test in the first commit that validates a hand-constructed descriptor pair of this type as well, so it's as easy as possible to see the behavior of this commit, and so we don't accidentally "lose" this test if the datadriven approach changes over time.

If this is silly, feel free to push back.

Overall, I'm confident in the small footprint of this change.

Reviewed 1 of 1 files at r1.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @ajwerner and @lucy-zhang)


pkg/sql/catalog/tabledesc/structured.go, line 1544 at r1 (raw file):

		// somewhat parallels the logic in maybeUpgradeForeignKeyRepOnIndex.
		unupgradedFKsPresent := false
		if err := referencedTable.ForeachIndex(catalog.IndexOpts{}, func(referencedIdx *descpb.IndexDescriptor, isPrimary bool) error {

Should we add a if found == true breakout from this section to, to parallel the one in the second section?

@thoszhang
Copy link
Contributor Author

I added some testing for (1) auto-created referencing-side indexes in 19.2, (2) extra indexes on the referencing side that overlap with the one that's designated for the FK, and (3) the case where we switch out the referencing-side index from the original pre-19.2 one (just sort of a special case in the upgrade path which I don't expect to cause problems).

@thoszhang thoszhang force-pushed the validate-old-fks branch 2 times, most recently from 2da2cb5 to 9dbfb1d Compare November 24, 2020 20:08
Copy link
Contributor Author

@thoszhang thoszhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner and @jordanlewis)


pkg/sql/catalog/catalogkv/unwrap_validation_test.go, line 16 at r2 (raw file):

Previously, ajwerner wrote…

Is the linter going to complain about this?

Good point, fixed.


pkg/sql/catalog/tabledesc/structured.go, line 1544 at r1 (raw file):

Previously, jordanlewis (Jordan Lewis) wrote…

Should we add a if found == true breakout from this section to, to parallel the one in the second section?

Oh yeah, done.


pkg/sql/catalog/tabledesc/structured.go, line 1648 at r1 (raw file):

Previously, ajwerner wrote…

					"missing index %d on %q from pre-19.2 foreign key forward reference %q on %q",
					fk.Index, desc.Name, backref.Name, originTable.GetName(),

Would we be happier if these errors had the entire descriptor? The names are going to disappear in redaction. Same for all the other errors around here.

Yeah, I think so. How do you think we should format this log line (given that the table descriptor is some large thing with newlines)?

@thoszhang
Copy link
Contributor Author

If it's not too much trouble, I would like to see a unit test in the first commit that validates a hand-constructed descriptor pair of this type as well, so it's as easy as possible to see the behavior of this commit, and so we don't accidentally "lose" this test if the datadriven approach changes over time.

I think that's reasonable. We can add it to TestValidateCrossTableReferences.

Copy link
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r3.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner, @jordanlewis, and @lucy-zhang)


pkg/sql/catalog/tabledesc/structured.go, line 1648 at r1 (raw file):

Previously, lucy-zhang (Lucy Zhang) wrote…

Yeah, I think so. How do you think we should format this log line (given that the table descriptor is some large thing with newlines)?

for better or for worse, it doesn't have newlines.

Copy link
Contributor Author

@thoszhang thoszhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner and @jordanlewis)


pkg/sql/catalog/tabledesc/structured.go, line 1648 at r1 (raw file):

Previously, ajwerner wrote…

for better or for worse, it doesn't have newlines.

Feel free to just do something reasonable here and push it.

Copy link
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner, @jordanlewis, and @lucy-zhang)


pkg/sql/catalog/tabledesc/structured.go, line 1648 at r1 (raw file):

Previously, lucy-zhang (Lucy Zhang) wrote…

Feel free to just do something reasonable here and push it.

I'm skipping for now because it breaks a bunch of tests because we don't actually have valid descriptors and the formatting assumes we do (maybe that's a mistake). Will deal with it later in a more generic way.

thoszhang and others added 2 commits November 24, 2020 17:13
We introduced a bug in v20.2 where we failed to upgrade referenced
descriptors' FK representations from pre-19.2 descriptors when
validating cross-references for tables, leading to validation failures
that would make the table unusable. This PR gets rid of the validation
errors by having `Validate()` account for pre-19.2-style foreign keys on
referenced table descriptors.

Release note (bug fix): Fixes a bug where tables and metadata were
unavailable due to spurious `missing fk back reference` validation
errors.
This commit adds a framework to test that descriptors validate properly.
It also adds testdata and a bash script to generate that test data.

This test is to exercise a problematic path whereby tables constructed
in v19.1 would fail to validate in v20.2.

Release note: None
@thoszhang
Copy link
Contributor Author

@jordanlewis do you want to take another look at the tests?

Copy link
Member

@jordanlewis jordanlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that checks what happens if neither descriptor had been upgraded? I see 2, which I think are both the 1-side case: one of the descriptors was upgraded, but not the other.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner, @jordanlewis, and @lucy-zhang)

@thoszhang
Copy link
Contributor Author

We're assuming (both in code and in the tests) that once the descriptors make their way into validateCrossReferences, the descriptor whose descriptor is being validated is always upgraded. The problem is just with the referenced descriptors.

@ajwerner
Copy link
Contributor

Do we have a test that checks what happens if neither descriptor had been upgraded? I see 2, which I think are both the 1-side case: one of the descriptors was upgraded, but not the other.

We always upgrade the current descriptor before attempting to read the other side. This test just tests validating the other side. We do exercise the specific scenario you're bringing up in the datadriven test. I can try to finagle one that runs the whole validation logic on both but it's going to be annoying.

@jordanlewis
Copy link
Member

No problem, I'm satisfied if you are.

@thoszhang
Copy link
Contributor Author

bors r+

@craig
Copy link
Contributor

craig bot commented Nov 24, 2020

Build succeeded:

@craig craig bot merged commit c9fb63a into cockroachdb:master Nov 24, 2020
@thoszhang thoszhang deleted the validate-old-fks branch November 25, 2020 06:21
ajwerner added a commit to ajwerner/cockroach that referenced this pull request Nov 25, 2020
In the haste of cockroachdb#57066 we erroneously checked the origin rather than reference
column ID when validating an inbound fk reference. The tests did not catch this
error because the column IDs were the same on both sides.

Release note (bug fix): Fix a bug related validation of unupgraded pre-19.2
inbound foreign keys.
ajwerner added a commit to ajwerner/cockroach that referenced this pull request Nov 25, 2020
In the haste of cockroachdb#57066 we erroneously checked the origin rather than reference
column ID when validating an inbound fk reference. The tests did not catch this
error because the column IDs were the same on both sides.

Release note (bug fix): Fix a bug related validation of unupgraded pre-19.2
inbound foreign keys.
ajwerner added a commit to ajwerner/cockroach that referenced this pull request Nov 25, 2020
In the haste of cockroachdb#57066 we erroneously checked the origin rather than reference
column ID when validating an inbound fk reference. The tests did not catch this
error because the column IDs were the same on both sides.

Release note (bug fix): Fix a bug related validation of unupgraded pre-19.2
inbound foreign keys.
craig bot pushed a commit that referenced this pull request Nov 25, 2020
57132: tabledesc: fix bug in unupgraded descriptor validation r=lucy-zhang,jordanlewis a=ajwerner

In the haste of #57066 we erroneously checked the origin rather than reference
column ID when validating an inbound fk reference. The tests did not catch this
error because the column IDs were the same on both sides.

Release note (bug fix): Fix a bug related validation of unupgraded pre-19.2
inbound foreign keys.

Co-authored-by: Andrew Werner <ajwerner@cockroachlabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants