Fixed #21376 -- New implementation for query join promotion logic

This commit introduced a new class JoinPromoter that can be used to
abstract away join promotion problems for complex filter conditions.
Query._add_q() and Query.combine() now use the new class.

Also, added a lot of comments about why join promotion is done the way
it is.

Thanks to Tim Graham for original report and testing the changes, and
for Loic Bistuer for review.
Fixed #11320 -- exclude() too aggressive in join promotion
Removed Query.setup_joins() and join() argument outer_if_first.

Instead always create new joins as OUTER.
Removed non-necessary code in Compiler._setup_joins()