2 columns sample

```sql
CREATE TABLE userid_set(userid UInt64, name String) ENGINE = Set;
INSERT INTO userid_set VALUES (1, 'Mary'),(2, 'Jane'),(3, 'Mary'),(4, 'Jack');

CREATE TABLE userid_test (userid UInt64, name String) ENGINE = MergeTree() PARTITION BY (intDiv(userid, 500)) ORDER BY (userid) SETTINGS index_granularity = 8192;
INSERT INTO userid_test VALUES (1, 'Jack'),(2, 'Mary'),(3, 'Mary'),(4, 'John'),(5, 'Mary');

SELECT * FROM userid_test WHERE (userid, name) IN (userid_set); -- fails

SELECT * FROM userid_test WHERE (name, userid) IN (userid_set); -- works, but order of columns is reversed.

```

3 columns sample
```sql
CREATE TABLE userid_set2(userid UInt64, name String, birthdate Date) ENGINE = Set;
 insert into userid_set2 values (1,'John', '1990-01-01');

WITH  'John' AS name,  toDate('1990-01-01') AS birthdate
SELECT * FROM numbers(10)
WHERE (number, name, birthdate) IN (userid_set2); -- fails

WITH  'John' AS name,  toDate('1990-01-01') AS birthdate
SELECT * FROM numbers(10)
WHERE (birthdate, name, number) IN (userid_set2); -- works, but order of column is reversed
```

*   analyzer.appendSelect(chain);
      *   analyzer.appendOrderBy(chain);
      *   chain.finalize();
      *
      * If only_types = true set, does not execute subqueries in the relevant parts of the query. The actions got this way
      *  shouldn't be executed, they are only needed to get a list of columns with their types.
      */
    
    ArrayJoinActionPtr appendArrayJoin(ExpressionActionsChain & chain, ActionsDAGPtr & before_array_join, bool only_types);
    bool appendJoinLeftKeys(ExpressionActionsChain & chain, bool only_types);
    JoinPtr appendJoin(ExpressionActionsChain & chain, ActionsDAGPtr & converting_join_columns);
    
    
    ActionsDAGPtr appendPrewhere(ExpressionActionsChain & chain, bool only_types);
    bool appendWhere(ExpressionActionsChain & chain, bool only_types);
    bool appendGroupBy(ExpressionActionsChain & chain, bool only_types, bool optimize_aggregation_in_order, ManyExpressionActions &);
    void appendAggregateFunctionsArguments(ExpressionActionsChain & chain, bool only_types);
    void appendWindowFunctionsArguments(ExpressionActionsChain & chain, bool only_types);
    void appendExpressionsAfterWindowFunctions(ExpressionActionsChain & chain, bool only_types);
    void appendSelectSkipWindowExpressions(ExpressionActionsChain::Step & step, ASTPtr const & node);
    void appendGroupByModifiers(ActionsDAGPtr & before_aggregation, ExpressionActionsChain & chain, bool only_types);
    
    bool appendHaving(ExpressionActionsChain & chain, bool only_types);
    
    ActionsDAGPtr appendOrderBy(ExpressionActionsChain & chain, bool only_types, bool optimize_read_in_order, ManyExpressionActions &);
    bool appendLimitBy(ExpressionActionsChain & chain, bool only_types);
    
};
}