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: fix create table failure with regional by row #80590

Merged
merged 1 commit into from
Apr 27, 2022

Conversation

fqazi
Copy link
Collaborator

@fqazi fqazi commented Apr 26, 2022

Fixes: #71600

Previously, if a transaction retry error happened
during a CREATE TABLE, we could had AST changes
persist which could lead to incorrect behaviour.
For example tables with a locality of regional
by row would have an implicit column added with an
OID from the database descriptor. Unfortunately, after
a transaction retry it is possible that the OID
ID could have changed. To address this, and prevent
future issues in CREATE TABLE, we are going to clone
the AST before any modification.

Release note (bug fix): Creating a table with a locality
of regional by row could intermittently fail with a missing
type error.

@fqazi fqazi requested a review from a team April 26, 2022 21:31
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@fqazi fqazi force-pushed the missingTypeIssue branch 2 times, most recently from 2e250d0 to df2db04 Compare April 27, 2022 04:58
Fixes: cockroachdb#71600

Previously, if a transaction retry error happened
during a CREATE TABLE, we could had AST changes
persist which could lead to incorrect behaviour.
For example tables with a locality of regional
by row would have an implicit column added with an
OID from the database descriptor. Unfortunately, after
a transaction retry it is possible that the OID
ID could have changed. To address this, and prevent
future issues in CREATE TABLE, we are going to copy
the column definition slice.

Release note (bug fix): Creating a table with a locality
of regional by row could intermittently fail with a missing
type error.
Copy link
Contributor

@Xiang-Gu Xiang-Gu 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 (waiting on @fqazi and @Xiang-Gu)


pkg/sql/create_table.go line 263 at r1 (raw file):

	defer func(originalDefs tree.TableDefs) { n.n.Defs = originalDefs }(n.n.Defs)
	n.n.Defs = defsCopy

If I understand correctly, we want to save a copy defsCopy to be the initial n.n.Defs. We then go ahead and modify n.n.Defs but we can rest assured that we have deferred a function that reset n.n.Defs back to the initial defsCopy that we saved and is intact.

I didn't understand the defer function where we essentially did n.n.Defs = n.n.Defs

Copy link
Collaborator Author

@fqazi fqazi 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 (waiting on @Xiang-Gu)


pkg/sql/create_table.go line 263 at r1 (raw file):

Previously, Xiang-Gu (Xiang Gu) wrote…

If I understand correctly, we want to save a copy defsCopy to be the initial n.n.Defs. We then go ahead and modify n.n.Defs but we can rest assured that we have deferred a function that reset n.n.Defs back to the initial defsCopy that we saved and is intact.

I didn't understand the defer function where we essentially did n.n.Defs = n.n.Defs

The key here is that this function will be invoked when the function scope ends. With the original slice that we specified as a parameter to the call (think of that being closure capturing it in a slice). The slice afterwards could have had any value, but will be reverted back to the originally observed value

Copy link
Contributor

@chengxiong-ruan chengxiong-ruan left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @chengxiong-ruan and @Xiang-Gu)


pkg/sql/create_table.go line 263 at r1 (raw file):

Previously, fqazi (Faizan Qazi) wrote…

The key here is that this function will be invoked when the function scope ends. With the original slice that we specified as a parameter to the call (think of that being closure capturing it in a slice). The slice afterwards could have had any value, but will be reverted back to the originally observed value

yeah, the key point about defer is that, the function input value is evaluated at definition time. so the defer function takes the original defs value as input. this is true even we over write it with the defsCopy. this should work.

@fqazi
Copy link
Collaborator Author

fqazi commented Apr 27, 2022

@Xiang-Gu @chengxiong-ruan TFTR!

@fqazi
Copy link
Collaborator Author

fqazi commented Apr 27, 2022

bors r+

@craig
Copy link
Contributor

craig bot commented Apr 27, 2022

Build succeeded:

@craig craig bot merged commit f4123d3 into cockroachdb:master Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ccl/multiregionccl: TestRegionAddDropEnclosingRegionalByRowOps failed
4 participants