When using the members/all api the same user was returned multiple times
when he was a member of the project/group and also of one of the
ancestor groups.
Now the member is returned only once giving priority to the membership
on the project and maintaining the same behaviour of the members UI.
This commit adds the module `FromUnion`, which provides the class method
`from_union`. This simplifies the process of selecting data from the
result of a UNION, and reduces the likelihood of making mistakes. As a
result, instead of this:
union = Gitlab::SQL::Union.new([foo, bar])
Foo.from("(#{union.to_sql}) #{Foo.table_name}")
We can now write this instead:
Foo.from_union([foo, bar])
This commit also includes some changes to make this new setup work
properly. For example, a bug in Rails 4
(https://github.com/rails/rails/issues/24193) would break the use of
`from("sub-query-here").includes(:relation)` in certain cases. There was
also a CI query which appeared to repeat a lot of conditions from an
outer query on an inner query, which isn't necessary.
Finally, we include a RuboCop cop to ensure developers use this new
module, instead of using Gitlab::SQL::Union directly.
Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/51307
For each member being rendered on
Projects::ProjectMembersController#index, there was a query to the users
table to retrieve the corresponding user:
```
SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1
```
Realized window functions are not available in older MySQL versions
either.
Falling back to DISTINCT ON for postgresql and a convoluted translation
for MySQL.