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
```

const NamesAndTypesList & aggregationKeys() const { return aggregation_keys; }
    bool hasConstAggregationKeys() const { return has_const_aggregation_keys; }
    const NamesAndTypesLists & aggregationKeysList() const { return aggregation_keys_list; }
    const AggregateDescriptions & aggregates() const { return aggregate_descriptions; }
    std::unique_ptr<QueryPlan> getJoinedPlan();
    
    const TemporaryTablesMapping & getExternalTables() const { return external_tables; }
    ActionsDAGPtr simpleSelectActions();
    
    void appendSelect(ExpressionActionsChain & chain, bool only_types);
    
    ActionsDAGPtr appendProjectResult(ExpressionActionsChain & chain) const;
    
    void makeSetsForIndex(const ASTPtr & node);
private:
    StorageMetadataPtr metadata_snapshot;
    
    NameSet required_result_columns;
    SelectQueryOptions query_options;
    JoinPtr makeJoin(
        const ASTTablesInSelectQueryElement & join_element,
        const ColumnsWithTypeAndName & left_columns,
        ActionsDAGPtr & left_convert_actions);
    const ASTSelectQuery * getAggregatingQuery() const;
    /** These methods allow you to build a chain of transformations over a block, that receives values in the desired sections of the query.
      *
      * Example usage:
      *   ExpressionActionsChain chain;
      *   analyzer.appendWhere(chain);
      *   chain.addStep();