Skip to content

*: Improve constraints retrieval in table descriptor#91704

Merged
craig[bot] merged 3 commits intocockroachdb:masterfrom
Xiang-Gu:add-constraint-interface
Nov 15, 2022
Merged

*: Improve constraints retrieval in table descriptor#91704
craig[bot] merged 3 commits intocockroachdb:masterfrom
Xiang-Gu:add-constraint-interface

Conversation

@Xiang-Gu
Copy link
Copy Markdown
Contributor

@Xiang-Gu Xiang-Gu commented Nov 10, 2022

This PR tries to improve how we retrieve constraints in a table descriptor. Previously,
it was mostly legacy code carries over from a while ago and nothing hasn't really
changed.
The main change is to introduce catalog.Constraint interface, similar to catalog.Index
and catalog.Column, as the preferred interface for constraint in this layer. Previously,
we would directly expose the underlying protobuf descriptor.

Commit 1 (easy): Rename catalog.ConstraintToUpdate to catalog.Constraint.
It's good that we already have an interface that is suitable to be used for our effort.

Commit 2 (easy): Added methods in just renamed catalog.Constraint interface for
index-backed-constraints (i.e. PRIMARY KEY or UNIQUE);

Commit 3 (easy): Let tabledesc.index struct implement catalog.Constraint interface
as we will use it for index-backed-constraints.

Commit 4 (easy): Add a method in catalog.Constraint that gets validity of the constraint.

Commit 5 (moderate): Add logic (ConstraintCache) to pre-compute all constraints in a
table, categorized by type and validity, so that we can readily retrieve them later. This is the same
idea/technique used for managing index and columns (in IndexCache and ColumnCache).

Commit 6 (easy): Introduce the new, preferred methods in catalog.TableDescriptor to
retrieve constraints from a table.

Commit 7 (easy): Refactor signature of the existing FindConstraintWithID method to use
the newly added interface and retrieval methods.

Informs: #90840
(this PR can unblock #90840)

Release note: None

@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@Xiang-Gu Xiang-Gu force-pushed the add-constraint-interface branch 2 times, most recently from 637fa4c to e91fe19 Compare November 11, 2022 19:36
@Xiang-Gu Xiang-Gu marked this pull request as ready for review November 11, 2022 19:37
@Xiang-Gu Xiang-Gu requested a review from a team November 11, 2022 19:37
Copy link
Copy Markdown
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:

Reviewed 6 of 6 files at r1, 4 of 4 files at r2, 2 of 2 files at r3, 4 of 4 files at r4, 4 of 4 files at r5, 9 of 9 files at r6, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @Xiang-Gu)


pkg/sql/catalog/tabledesc/mutation.go line 200 at r3 (raw file):

		return c.UniqueWithoutIndex().Validity
	} else {
		panic("unknown constraint type")

please panic an assertion failed error, the string will get redacted

Copy link
Copy Markdown

@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.

Ok, so, this is sort of OK, but it requires a fair bit of follow-up work, which I'll be happy to do.

// there is one.
UniqueWithoutIndex() descpb.UniqueWithoutIndexConstraint

// PrimaryKey returns the underlying index descriptor backing the UNIQUE constraint,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: fix comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

UniqueWithoutIndex() descpb.UniqueWithoutIndexConstraint

// PrimaryKey returns the underlying index descriptor backing the UNIQUE constraint,
// if there is one.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: can you add a TODO(postamar): return interface instead of protobuf comment here and for Unique() please?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will just do it here myself.

allActiveAndInactiveFKs []catalog.Constraint
allActiveFKs []catalog.Constraint

allUniqueWithoutIndexs []catalog.Constraint
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: s/allUniqueWithoutIndexs/allUniqueWithoutIndexes; same for 2 lines below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

// - VALIDATING when the index is being added (i.e. live on mutation slice with ADD direction);
// - DROPPING when the index is being dropped (i.e. live on mutation slice with DROP direction);
// - UNVALIDATED in no case!
optional ConstraintValidity index_backed_constraint_validity = 9 [(gogoproto.nullable) = false];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm very concerned about this change to the protobuf (the two new fields + two new enum values). It's dangerous because it implies a change in what's serialized to storage. It's also not really necessary, why not modify the index struct in tabledesc to implement catalog.Constraint instead? Everything should be there already.

Is the perceived obstacle to doing this that catalog.Constraint has a ConstraintToUpdateDesc() *descpb.ConstraintToUpdate method? I took a look and it seems to me that it could be removed. It's used for pretty-printing and for accessing the constraint subtypes like c.ConstraintToUpdateDesc().Check and for c.ConstraintToUpdateDesc().ConstraintType.

Copy link
Copy Markdown
Contributor Author

@Xiang-Gu Xiang-Gu Nov 14, 2022

Choose a reason for hiding this comment

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

I will change as your suggested! However, I don't think we can get rid of ConstraintToUpdateDesc() because this is needed if we want to modify the underlying the protobuf. Now with index implementing Constraint, we will need to add another method, maybe called IndexDesc() *descpb.IndexDescriptor, if the to-be-modified constraint is backed by an index.

One such scanrio of needing to modify the underlying protobuf is setting the name of a constraint. This will show up in both RENAME CONSTRAINT or, more generally, the adding/dropping path of a ConstraintName element.

dest = append(dest, c)
constraintIDsInDest[c.GetConstraintID()] = true
return dest
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is it at all possible for a constraint to present itself more than once?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes, I knew of one scenario: when dropping a check constraint, we would find that constraint in the Checks slice, mark its validity to DROPPING without removing it from the Checks slice. We would also enqueue a mutation for this check constraint with DROP direction. Here, this dropping check constraint will be found both in Checks slice and on Mutations slice.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks! I feared it would be something like this.

}

return &c
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This might not have been obvious to you but this function is in the hot path and its current implementation is going to cause noticeable performance regressions.

I'll address this after this merges, it's important but it's not interesting and shouldn't block you from making progress on the declarative schema changer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sgtm, I will leave it as is for this PR.

@Xiang-Gu Xiang-Gu force-pushed the add-constraint-interface branch from e91fe19 to 7e8c489 Compare November 14, 2022 20:26
Copy link
Copy Markdown

@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, nicely done.

@Xiang-Gu Xiang-Gu force-pushed the add-constraint-interface branch from 7e8c489 to b5f89e5 Compare November 14, 2022 22:27
@Xiang-Gu
Copy link
Copy Markdown
Contributor Author

TFTR!

bors r+

@Xiang-Gu
Copy link
Copy Markdown
Contributor Author

bors r-

Some pieces are missing and let me fill them up.

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 14, 2022

Canceled.

This PR renames the following interface and struct:
  1. `catalog.ConstraintToUpdate` interface is now `catalog.Constraint`
  2. `tabledesc.constraintToUpdate` struct is now `tabledesc.constraint`
1. We let `tabledesc.index` struct implement `catalog.Constraint` interface
so that it is used for any index-backed-constraints (PRIMARY KEY or
UNIQUE);

2. We implement a `constraintCache` inside a table wrapper that was
pre-populated and is ready for re-use. It allows us to easily retrieve
various sets of constraints (by kind and/or by validity) from the table.

3. We expose three methods in `catalog.TableDescriptor` interface to
retrieve various constraints in this table using this cache.
This commit refactor `FindConstraintWithID` method inside the
`catalog.TableDescriptor` in the following two ways:
 1. Change the return type to the newly introduced `catalog.Constraint`
    instead of a protobuf struct;
 2. Change the implementation slightly to also search dropping
    constraints. Previously, it will skip those constraints.

The remaining changes in this commit are consequential changes due to
this function signature change. All of them are peripheral and does not
affect functionality.
@Xiang-Gu Xiang-Gu force-pushed the add-constraint-interface branch from b5f89e5 to 25ace40 Compare November 14, 2022 23:05
@Xiang-Gu
Copy link
Copy Markdown
Contributor Author

Now I think it's ready to be merged again!

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 14, 2022

Build failed (retrying...):

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 15, 2022

Build failed (retrying...):

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 15, 2022

Build succeeded:

@craig craig bot merged commit 47c7b3a into cockroachdb:master Nov 15, 2022
@Xiang-Gu Xiang-Gu deleted the add-constraint-interface branch November 15, 2022 15:28
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