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

opt: build all partial index predicate expressions in TableMeta #57707

Merged

Conversation

mgartner
Copy link
Collaborator

@mgartner mgartner commented Dec 8, 2020

opt: build all partial index predicate expressions in TableMeta

Previously, partial index predicates were only built and added to
TableMeta.PartialIndexPredicates if the scope of the scan in
Builder.buildScan included all ordinary table columns. This behavior
prevented errors when building partial index predicate expressions for
foriegn key check scans. These scans do not include all columns, so when
building a predicate expression that referenced a table column not
included, optbuilder would err with "column does not exist".

This commit changes this behavior so that partial index predicates are
always built and added to TableMeta.PartialIndexPredicates. In order
to do this, Builder.addPartialIndexPredicatesForTable creates its own
table scope. It also constructs a new scan rather than relying on the
already-built scan. Constructing a scan is required for considering
logical properties while normalizing partial index predicates.

See discussion at #57622
for more context on this change.

Release note: None

optbuilder: reduce redundant building of arbiter filter expressions

Previously, the arbiter predicate provided in the WHERE clause of an
INSERT ... ON CONFLICT statement was rebuilt as a memo.FiltersExpr
repetitively while the optbuilder determined arbiter indexes. Now, the
expression is built only once, reducing work.

Release note: None

@mgartner mgartner requested a review from a team as a code owner December 8, 2020 18:40
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@RaduBerinde RaduBerinde 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 @mgartner, @RaduBerinde, and @rytaft)


pkg/sql/opt/optbuilder/select.go, line 716 at r1 (raw file):

	tableScope := b.allocScope()
	tableScope.appendOrdinaryColumnsFromTable(tabMeta, &tabMeta.Alias)
	tableScope.expr = b.factory.ConstructScan(&memo.ScanPrivate{

Ah.. constructing the extra Scan is unfortunate.. I guess we could get the FDs (memo.MakeTableFuncDep) etc and put them in a FakeRel but I don't know if that saves much.

We could pass an optional scan expression to the function, and have this code use it if its OutputCols contains tableScope.colSet(). Feels a bit hacky but it will save this construction in most cases.

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.

:lgtm:

Reviewed 9 of 9 files at r1, 1 of 1 files at r2.
Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @mgartner)

Copy link
Collaborator Author

@mgartner mgartner 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! 2 of 0 LGTMs obtained (waiting on @RaduBerinde)


pkg/sql/opt/optbuilder/select.go, line 716 at r1 (raw file):

Previously, RaduBerinde wrote…

Ah.. constructing the extra Scan is unfortunate.. I guess we could get the FDs (memo.MakeTableFuncDep) etc and put them in a FakeRel but I don't know if that saves much.

We could pass an optional scan expression to the function, and have this code use it if its OutputCols contains tableScope.colSet(). Feels a bit hacky but it will save this construction in most cases.

In the common case wouldn't the ScanPrivates be the same? ThereforeConstructScan would return the memoized scan instead of building a new one?

Copy link
Collaborator Author

@mgartner mgartner 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! 2 of 0 LGTMs obtained (waiting on @RaduBerinde)


pkg/sql/opt/optbuilder/select.go, line 716 at r1 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

In the common case wouldn't the ScanPrivates be the same? ThereforeConstructScan would return the memoized scan instead of building a new one?

Nevermind... All the flags would have to be the same...

@mgartner mgartner force-pushed the always-build-partial-index-predicates branch from 892673d to d320cf9 Compare December 10, 2020 18:30
Previously, partial index predicates were only built and added to
`TableMeta.PartialIndexPredicates` if the scope of the scan in
`Builder.buildScan` included all ordinary table columns. This behavior
prevented errors when building partial index predicate expressions for
foriegn key check scans. These scans do not include all columns, so when
building a predicate expression that referenced a table column not
included, optbuilder would err with "column does not exist".

This commit changes this behavior so that partial index predicates are
always built and added to `TableMeta.PartialIndexPredicates`. In order
to do this, `Builder.addPartialIndexPredicatesForTable` creates its own
table scope. It also constructs a new scan if the provided scan does not
output all column in the table scope. A scan on the table and its
logical properties are required in order to fully normalize partial
index predicates.

See discussion at cockroachdb#57622
for more context on this change.

Release note: None
Previously, the arbiter predicate provided in the `WHERE` clause of an
`INSERT ... ON CONFLICT` statement was rebuilt as a `memo.FiltersExpr`
repetitively while the optbuilder determined arbiter indexes. Now, the
expression is built only once, reducing work.

Release note: None
@mgartner mgartner force-pushed the always-build-partial-index-predicates branch from d320cf9 to 9cc304b Compare December 10, 2020 18:32
Copy link
Collaborator Author

@mgartner mgartner 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 2 stale) (waiting on @rytaft)


pkg/sql/opt/optbuilder/select.go, line 716 at r1 (raw file):

We could pass an optional scan expression to the function, and have this code use it if its OutputCols contains tableScope.colSet(). Feels a bit hacky but it will save this construction in most cases.

Done. Notice that the size in KB of the memos in the xform/select tests are no longer increased by this PR.

@mgartner
Copy link
Collaborator Author

@RaduBerinde mind taking another look and make sure we're on the same page with this before I merge?

Copy link
Member

@RaduBerinde RaduBerinde 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 (and 1 stale) (waiting on @rytaft)

@mgartner
Copy link
Collaborator Author

TFTRs!

bors r+

@craig
Copy link
Contributor

craig bot commented Dec 11, 2020

Build succeeded:

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