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

Do not use Arel.star when ignored_columns #30980

Merged

Conversation

sobrinho
Copy link
Contributor

Closes #27918

Closes #27914

@rails-bot
Copy link

Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @kaspth (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

This repository is being automatically checked for code quality issues using Code Climate. You can see results for this analysis in the PR status below. Newly introduced issues should be fixed before a Pull Request is considered ready to review.

Please see the contribution instructions for more information.

@sobrinho
Copy link
Contributor Author

cc @rafaelfranca

@sobrinho sobrinho force-pushed the sobrinho/arel-star-ignored-columns branch 4 times, most recently from e956302 to f8bd7e1 Compare October 25, 2017 12:11
@rafaelfranca rafaelfranca assigned rafaelfranca and unassigned kaspth Oct 25, 2017
@rafaelfranca
Copy link
Member

Let me know when the tests are green

@sobrinho sobrinho force-pushed the sobrinho/arel-star-ignored-columns branch 2 times, most recently from ab9fd5b to fe42e50 Compare October 25, 2017 17:55
@sobrinho
Copy link
Contributor Author

@rafaelfranca the failures aren't related to this change anymore (not sure why they are happening at all now, maybe an intermittent failure).

I'm not sure if this is going to the right direction, can you please review the test changes and confirm this is the way to go?

Copy link
Member

@rafaelfranca rafaelfranca left a comment

Choose a reason for hiding this comment

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

Changes looks good to me. Only one question. Restarted the jobs to see if they now pass.

@@ -118,76 +118,76 @@ def test_unscope_after_reordering_and_combining
end

def test_unscope_with_where_attributes
expected = Developer.order("salary DESC").collect(&:name)
received = DeveloperOrderedBySalary.where(name: "David").unscope(where: :name).collect(&:name)
expected = Developer.order("salary DESC").order(:name).collect(&:name)
Copy link
Member

Choose a reason for hiding this comment

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

Do you remember why we need to add a new order here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The build was resulting in a different order between expected and received, I normalized both by using a predictable order.

Not sure why it started to fail in this PR but I have assumed that Postgres changed the order of the results for some reason (there is no guarantee in the order of the results in Postgres unless specified, in that case, if the salary is the same we do not have a guaranteed order of the records [there is but it is the order of the record on the disk that may vary from time to time]).

In the other hand, I'm not sure if this is the real problem but since this PR change should not impact on this test at all I assumed it was that.

Copy link
Contributor

Choose a reason for hiding this comment

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

might be better to do assert_equal(expected.sort, received.sort)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, we've used sort and sort_by for that. 75cfb3d 93c65ae 625bdb1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pretty much the same, should I change it to sort in ruby instead of the database?

Copy link
Member

Choose a reason for hiding this comment

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

I prefer to because of the already existing order that we have on those tests

@sobrinho
Copy link
Contributor Author

@rafaelfranca the build is green now 🤘 :shipit:

assert_match %(EXPLAIN for: SELECT `developers`.* FROM `developers` WHERE `developers`.`id` = 1), explain
assert_match %r(developers |.* const), explain
explain = Author.where(id: 1).explain
assert_match %(EXPLAIN for: SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
Copy link
Member

Choose a reason for hiding this comment

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

Why are you changing mysql2's tests only from Developer to Author?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The original author wanted to keep the EXPLAIN with the STAR and for that, the model had to be changed.

I can update the EXPLAIN test to keep the Developer model and update the regexp to match against the new query.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I think it is better to fix all other explain tests to use Author to not have a fragile test that will have to change every time the list of ignored column at Developers change.

Copy link
Contributor Author

@sobrinho sobrinho Oct 26, 2017

Choose a reason for hiding this comment

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

I'm thinking of creating a specific model for that feature, in that way the model will be exclusive for that feature and won't break anything around that.

Or even use something like that:

test '...' do
  begin
    Developer.ignored_columns = [:first_name, :last_name]

    assertions here
  ensure
    Developer.ignored_columns = []
  end
end

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I think changing to author is a good solution already that doesn't require adding any new code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So change the other specs to use author too?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah 👍

assert_equal 1, scope.where_clause.ast.children.length
assert_equal Developer.where(name: "David"), scope
assert_equal DeveloperCalledJamis.where("salary < 10000").to_a, scope.to_a
Copy link
Member

Choose a reason for hiding this comment

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

Is this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no idea, I left as the original author wrote, I will try to revert that and see what happen.

@sobrinho
Copy link
Contributor Author

@rafaelfranca can you take a look again?

Copy link
Member

@rafaelfranca rafaelfranca left a comment

Choose a reason for hiding this comment

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

👍 Can you squash your commits?

@sobrinho
Copy link
Contributor Author

@rafaelfranca like this?

@sobrinho sobrinho force-pushed the sobrinho/arel-star-ignored-columns branch from ab25bad to 736cbea Compare November 13, 2017 19:04
@rafaelfranca
Copy link
Member

This works, but you could at least three commits in your PR because they were atomic.

maclover7 and others added 3 commits November 13, 2017 17:41
If there are any ignored columns, we will now list out all columns we
want to be returned from the database.

Includes a regression test.
@sobrinho sobrinho force-pushed the sobrinho/arel-star-ignored-columns branch from 736cbea to f8627df Compare November 13, 2017 19:42
@sobrinho
Copy link
Contributor Author

@rafaelfranca done!

@rafaelfranca
Copy link
Member

Thanks! I'll merge in a minute

@rafaelfranca rafaelfranca merged commit f49d594 into rails:master Nov 13, 2017
rafaelfranca added a commit that referenced this pull request Nov 13, 2017
…lumns

Do not use `Arel.star` when `ignored_columns`
@sobrinho sobrinho deleted the sobrinho/arel-star-ignored-columns branch November 13, 2017 21:44
Edouard-chin added a commit to Edouard-chin/rails that referenced this pull request Dec 11, 2017
- rails#30980 introcuded a change to not use `Arel.star` when model have ignored columns, a query used to look like `SELECT *. FROM developers` whereas now it would like `SELECT column1, column2 FROM developers`
  - If a column has the same name has a reserved database specific keyword (such as key, where ...) then the query would fail because the names aren't quoted
- Quoting almost always happen unless we use a `from` clause in the query https://github.com/rails/rails/blob/9965b98dc0d58a86e10b4343bb6e15e01661a8c3/activerecord/lib/active_record/relation/query_methods.rb#L1052
- This PR cast all columns name to symbols in order for the quoting logic to be picked up https://github.com/rails/rails/blob/9965b98dc0d58a86e10b4343bb6e15e01661a8c3/activerecord/lib/active_record/relation/query_methods.rb#L1054-L1055
- A reproduction script can be found here https://gist.github.com/Edouard-chin/f56d464a0adcb76962afc1a9134a1536
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants