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

Improve have_db_index to better handle columns with multiple indexes #1542

Merged
merged 3 commits into from
Mar 7, 2023

Conversation

abrom
Copy link
Contributor

@abrom abrom commented Mar 5, 2023

The have_db_index matcher currently matches on the first index that has the matching column names. But when used with the unique qualifier that can result in the "wrong" index being matched causing the test to fail.

For example, if a column had multiple indexes.. one unique BTree index, and another non-unique partial or GIN index. Using the unique qualifier fail because the non-unique index was identified as the matched_index.

It would appear that the order returned by actual_indexes will be database specific (say by index name) or possibly pseudo-random??

This change applies a "pre sort" of the indexes prior to finding the matching one if the unique qualifier is specified to give the match the best chance of being the "correct" one.

Note that this does of course complicate things if additional qualifiers were to be added because then sort order precedence would need to be considered.

The `have_db_index` matcher currently matches on the first index
that has the matching column names. But when used with the `unique`
qualifier that can result in the "wrong" index being matched causing
the test to fail. For example, one unique BTree index, and another
non-unique partial or GIN index.
@abrom abrom force-pushed the improve-db-index-matcher branch from 51750db to 16f7ed8 Compare March 5, 2023 12:19
Copy link
Collaborator

@mcmire mcmire 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 PR! I like how simple it is. I just had two comments.

Comment on lines 211 to 219
indexes = actual_indexes

if qualifiers.include?(:unique)
indexes.sort_by! do |index|
index.unique == qualifiers[:unique] ? 0 : 1
end
end

indexes
Copy link
Collaborator

Choose a reason for hiding this comment

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

The bang at the end of sort_by modifies the array in place. In-place mutation tends to be useful for performant or complex code, however, given how simple this method is, I wonder if we say things a bit more straightforwardly. What do you think about this?

Suggested change
indexes = actual_indexes
if qualifiers.include?(:unique)
indexes.sort_by! do |index|
index.unique == qualifiers[:unique] ? 0 : 1
end
end
indexes
if qualifiers.include?(:unique)
actual_indexes.sort_by do |index|
index.unique == qualifiers[:unique] ? 0 : 1
end
else
actual_indexes
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. I'd done it using the sort_by! in case there were any new qualifiers added to support applying other sorting to the list. But it can of course be refactored if/when that's the case! Will update.


indexes
end

def actual_indexes
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since we now have a new method called sorted_indexes, what do you think about renaming this to unsorted_indexes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, sure. Sounds good to me

@mcmire mcmire merged commit 195153c into thoughtbot:main Mar 7, 2023
@mcmire
Copy link
Collaborator

mcmire commented Mar 7, 2023

Looks great! Thanks so much!

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.

2 participants