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

schemachanger: Implement ADD UNIQUE WITHOUT INDEX #93824

Conversation

Xiang-Gu
Copy link
Contributor

@Xiang-Gu Xiang-Gu commented Dec 16, 2022

This PR implements ADD UNIQUE WITHOUT INDEX in the declarative schema changer.
In general, it follows the same recipe for ADD CHECK.

Epic: None

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch 4 times, most recently from be03a59 to 41327b8 Compare December 19, 2022 19:56
@Xiang-Gu
Copy link
Contributor Author

This is ready for a round of looks!

@Xiang-Gu Xiang-Gu marked this pull request as ready for review December 19, 2022 20:56
@Xiang-Gu Xiang-Gu requested a review from a team December 19, 2022 20:56
@Xiang-Gu Xiang-Gu requested review from a team as code owners December 19, 2022 20:56
@Xiang-Gu Xiang-Gu changed the title WIP: schemachanger: Implement ADD UNIQUE WITHOUT INDEX schemachanger: Implement ADD UNIQUE WITHOUT INDEX Dec 19, 2022
@postamar
Copy link
Contributor

This looks good, I did a first pass and have no comments besides what I already shared in the PR this is based on, which might apply here also.

@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch from 41327b8 to 2ff8573 Compare December 20, 2022 23:16
@Xiang-Gu Xiang-Gu requested a review from a team as a code owner December 20, 2022 23:16
@Xiang-Gu Xiang-Gu requested a review from rytaft December 20, 2022 23:16
@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch from 2ff8573 to 03d3059 Compare December 20, 2022 23:53
Copy link
Collaborator

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

Nice! Most of this code is out of my area of expertise, but from what I can tell it looks good!

With this PR have you added support for all aspects of UNIQUE WITHOUT INDEX or just some? e.g., does this cover adding NOT VALID constraints and/or running VALIDATE on an existing constraint? How about adding them as part of a CREATE TABLE statement or dropping them?

Also seems like the change to include indexIDForValidation is mixed in with this change but should probably be its own separate change. It doesn't seem related to this.

I left a bunch of nits about long comment lines. Comments should be <= 80 characters wide.

Reviewed 5 of 5 files at r18, 9 of 9 files at r19, 3 of 3 files at r20, 3 of 3 files at r21, 17 of 17 files at r22, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @Xiang-Gu)


pkg/sql/catalog/rewrite/rewrite.go line 176 at r21 (raw file):

		}

		// Rewrite unique_without_index in both `UniqueWithoutIndexConstraints` and `Mutations` slice.

nit: long line


pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_constraint.go line 439 at r20 (raw file):

}

// getIndexIDForValidationForConstraint returns the index ID this check constraint is supposed to

nit: long line


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 346 at r19 (raw file):

	}
	if op.ConstraintID >= tbl.NextConstraintID {
		tbl.NextConstraintID = op.ConstraintID + 1

why are you doing this in this function but not the others?


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 352 at r19 (raw file):

		TableID:      op.TableID,
		ColumnIDs:    op.ColumnIDs,
		Name:         tabledesc.ConstraintNamePlaceholder(op.ConstraintID),

why not use the constraint name?


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 385 at r19 (raw file):

			// Remove the mutation from the mutation slice. The `MakeMutationComplete`
			// call will also mark the above added unique_without_index as VALIDATED.
			// If this is a rollback of a drop, we are trying to add the unique_without_index constraint

nit: long line


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 410 at r19 (raw file):

}

func (m *visitor) MakePublicUniqueWithoutIndexConstraintValidated(

The name of this function doesn't seem to match what it's doing


pkg/sql/schemachanger/scop/mutation.go line 369 at r19 (raw file):

}

// MakeAbsentUniqueWithoutIndexConstraintWriteOnly adds a non-existent unique_without_index constraint

nit: long line


pkg/sql/schemachanger/scpb/elements.proto line 325 at r19 (raw file):

  // Predicate, if non-nil, means a partial uniqueness constraint.
  Expression predicate = 4 [(gogoproto.customname) = "Predicate"];
  // IndexIDForValidation is the index id to hint to the unique_without_index constraint validation SQL query about which index

nit: long line


pkg/sql/schemachanger/scplan/internal/opgen/opgen_unique_without_index_constraint.go line 19 at r19 (raw file):

func init() {
	opRegistry.register((*scpb.UniqueWithoutIndexConstraint)(nil),

I'm not familiar enough with how this works to review this part


pkg/sql/schemachanger/scplan/internal/rules/testdata/deprules line 1447 at r22 (raw file):

    - $next-node[CurrentStatus] = TRANSIENT_DELETE_ONLY
    - descriptorIsNotBeingDropped($prev)
    - joinTargetNode($prev, $prev-target, $prev-node)

I don't know enough about this to review

@Xiang-Gu
Copy link
Contributor Author

With this PR have you added support for all aspects of UNIQUE WITHOUT INDEX or just some? e.g., does this cover adding NOT VALID constraints and/or running VALIDATE on an existing constraint? How about adding them as part of a CREATE TABLE statement or dropping them?

@rytaft Thank you first of all for taking a look at this PR. To answer your question:

  1. This PR does not support NOT VALID. This is a to-do for the team for all kinds of constraints.
  2. We don't support CREATE TABLE in the declarative schema changer yet, so we cannot yet add them as part of a CREATE TABLE.
  3. We don't support DROP CONSTRAINT in the declarative schema changer yet, so we cannot yet drop them in the declarative schema changer. We should (?) be able to drop them in the legacy schema changer though.
  4. Another aspect is ADD COLUMN UNIQUE WITHOUT INDEX. We already support ADD COLUMN in the declarative schema changer. With this PR, I think we can easily add a bit to ADD COLUMN logic to support ADD COLUMN UNIQUE WITHOUT INDEX, which is currently unsupported with the following workaround
ERROR: adding a column marked as UNIQUE WITHOUT INDEX is unsupported
SQLSTATE: 0A000
HINT: add the column first, then run ALTER TABLE ... ADD CONSTRAINT to add a UNIQUE WITHOUT INDEX constraint on the column

Also seems like the change to include indexIDForValidation is mixed in with this change but should probably be its own separate change. It doesn't seem related to this.
This will be the key ingredient to support ADD COLUMN UNIQUE WITHOUT INDEX in the declarative schema changer. Btw, this is something required for (almost all) another constraint.

I will address your code review feedback shortly!

@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch from 03d3059 to 2c68210 Compare January 10, 2023 21:33
@Xiang-Gu Xiang-Gu requested review from a team as code owners January 10, 2023 21:33
@Xiang-Gu Xiang-Gu requested a review from a team January 10, 2023 21:33
Copy link
Contributor Author

@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 @rytaft)


pkg/sql/catalog/rewrite/rewrite.go line 176 at r21 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

nit: long line

done

Code quote:

WithoutIndexConstraints` and `Mutations` slice.

pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_constraint.go line 439 at r20 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

nit: long line

done


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 346 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

why are you doing this in this function but not the others?

I in fact did: This is only required in the "first" operation, which usually has the name of MakeAbsentXxxWriteOnly. I confirmed that we did this for all three constraints we currently support: check, fk, and uwi


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 352 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

why not use the constraint name?

The constraint name itself is modeled as a separate "element" and we will update the name to the right on during the lifecycle of that name element.

Code quote:

	uwi := &descpb.UniqueWithoutIndexConstraint{
		TableID:      op.TableID,

pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 385 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

nit: long line

done

Code quote:

drop, we are trying to add the unique_without_inde

pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 410 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

The name of this function doesn't seem to match what it's doing

You are right. We used to have a more-free-formed naming for those operations/functions. We (the schema team) then decided to make them conform to a certain naming convention. We chose the convention that makes it clear of the affected element's before and after status -- the element status as shown in a new schema changer plan. This operation, in the new schema changer plan's worlds and terminologies, transitioned the UniqueWIthoutIndex element from Public status to Validated status, so I gave this function this name.

What the function actually does, i.e. what a transition in the new schema changer plan's world translates to modifications to the descriptor, is considered a layer below and thus we don't want it to show in the function/operation names. That's my understanding of the rationale behind such a naming convention.


pkg/sql/schemachanger/scop/mutation.go line 369 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

nit: long line

done

Code quote:

ds a non-existent unique_without_index constraint

pkg/sql/schemachanger/scpb/elements.proto line 325 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

nit: long line

done

Code quote:

index id to hint to the unique_without_index cons

pkg/sql/schemachanger/scplan/internal/opgen/opgen_unique_without_index_constraint.go line 19 at r19 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

I'm not familiar enough with how this works to review this part

ack


pkg/sql/schemachanger/scplan/internal/rules/testdata/deprules line 1447 at r22 (raw file):

Previously, rytaft (Rebecca Taft) wrote…

I don't know enough about this to review

ack

@dhartunian dhartunian removed the request for review from a team January 11, 2023 18:44
Copy link
Collaborator

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

Thanks for the info! I will let someone from the schema team sign off on this since I'm not familiar with most of this code.

Reviewed 2 of 7 files at r30, 1 of 1 files at r31, 1 of 1 files at r32.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained


pkg/sql/schemachanger/scexec/scmutationexec/constraint.go line 410 at r19 (raw file):

Previously, Xiang-Gu (Xiang Gu) wrote…

You are right. We used to have a more-free-formed naming for those operations/functions. We (the schema team) then decided to make them conform to a certain naming convention. We chose the convention that makes it clear of the affected element's before and after status -- the element status as shown in a new schema changer plan. This operation, in the new schema changer plan's worlds and terminologies, transitioned the UniqueWIthoutIndex element from Public status to Validated status, so I gave this function this name.

What the function actually does, i.e. what a transition in the new schema changer plan's world translates to modifications to the descriptor, is considered a layer below and thus we don't want it to show in the function/operation names. That's my understanding of the rationale behind such a naming convention.

Thanks for the explanation

Copy link
Contributor

@postamar postamar left a comment

Choose a reason for hiding this comment

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

LGTM but please address my comments in #93068 first before merging. Nicely done!

@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch 2 times, most recently from 925cb01 to f354bd5 Compare January 12, 2023 22:45
@Xiang-Gu Xiang-Gu force-pushed the implement-add-constraint-unique-without-index branch from f354bd5 to edad297 Compare January 12, 2023 23:47
@Xiang-Gu
Copy link
Contributor Author

bors r+

@craig
Copy link
Contributor

craig bot commented Jan 13, 2023

Build succeeded:

@craig craig bot merged commit 45a3723 into cockroachdb:master Jan 13, 2023
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.

4 participants