* Try to enforce table identification in CollectJoinOnKeysMatcher
* Support filtering conditions in JOIN ON for HashJoin
* Correct handle non equi join
* Update test 00878_join_unexpected_results
* Join on filters calculated as one row before join
* Do not lookup key in hash join if condition for row is not hold
* better
* Support filtering conditions in JOIN ON for MergeJoin
* Support Nullable mask in JOIN ON section
* Fix style in Interpreters/TableJoin.cpp
* Change return type of getColumnAsMask in join_common to ColumnPtr
* Handle Nullable(Nothing) type in JOIN ON section, add test cases
* Fix type cast JoinCommon::getColumnAsMask
* Check type if conditions in JOIN ON section, support functions
* Update tests with JOIN ON
* Style changes, add comments for conditions in JOIN ON section
* Add test cases for join on condtions
* JOIN ON key1 = key2 AND (cond1 OR cond2)
* Remove CollectJoinOnKeysVisitor has_join_keys
* Add test cases for join on nullable/lc conditions
* Fix style
* Change error code 48 to 403 in join on tests
* Fix whitespace
TODO (suggested by Nikolai)
1. Build query plan fro current query (inside storage::read) up to WithMergableState
2. Check, that plan is simple enough: Aggregating - Expression - Filter - ReadFromStorage (or simplier)
3. Check, that filter is the same as filter in projection, and also expression calculates the same aggregation keys as in projection
4. Return WithMergableState if projection applies
3 will be easier to do with ActionsDAG, cause it sees all functions, and dependencies are direct (but it is possible with ExpressionActions also)
Also need to figure out how prewhere works for projections, and
row_filter_policies.
wip