```
clickhouse-local -n <<<"

DROP TABLE IF EXISTS test_table_join_1;
CREATE TABLE test_table_join_1
(
    id UInt64,
    value String
) ENGINE = TinyLog;

DROP TABLE IF EXISTS test_table_join_2;
CREATE TABLE test_table_join_2
(
    id UInt64,
    value String
) ENGINE = TinyLog;

DROP TABLE IF EXISTS test_table_join_3;
CREATE TABLE test_table_join_3
(
    id UInt64,
    value String
) ENGINE = TinyLog;

DESCRIBE TABLE
(
    SELECT
        test_table_join_1.* APPLY toString,
        test_table_join_2.* APPLY toString,
        test_table_join_3.* APPLY toString
    FROM test_table_join_1 AS t1
    INNER JOIN test_table_join_2 AS t2 ON t1.id = t2.id
    INNER JOIN test_table_join_3 AS t3 ON t2.id = t3.id
)
"
Code: 49. DB::Exception: Logical error: qualified asterisk must have exactly one child: While processing test_table_join_1.* APPLY toString, test_table_join_2.* APPLY toString, test_table_join_3.* APPLY toString: While processing SELECT test_table_join_1.* APPLY toString, test_table_join_2.* APPLY toString, test_table_join_3.* APPLY toString FROM test_table_join_1 AS t1 INNER JOIN test_table_join_2 AS t2 ON t1.id = t2.id INNER JOIN test_table_join_3 AS t3 ON t2.id = t3.id. (LOGICAL_ERROR)
```

https://s3.amazonaws.com/clickhouse-test-reports/0/f84064d05acd76e5098e14f42f15656960f29da6/fuzzer_astfuzzerubsan/report.html
{
    std::vector<const ASTTableExpression *> table_expressions;
    if (!needRewrite(select, table_expressions))
        return;
    auto & src_tables = select.tables()->children;
    size_t tables_count = src_tables.size();
    if (table_expressions.size() != data.tables.size() ||
        tables_count != data.tables.size())
        throw Exception("Inconsistent tables count in JOIN rewriter", ErrorCodes::LOGICAL_ERROR);
    
    {
        ExtractAsterisksVisitor::Data asterisks_data(data.tables);
        ExtractAsterisksVisitor(asterisks_data).visit(select.select());
        if (asterisks_data.new_select_expression_list)
            select.setExpression(ASTSelectQuery::Expression::SELECT, std::move(asterisks_data.new_select_expression_list));
    }
    
    std::vector<ASTIdentifier *> identifiers;
    CollectColumnIdentifiersVisitor::Data data_identifiers(identifiers);
    CollectColumnIdentifiersVisitor(data_identifiers).visit(ast);
    std::vector<ASTIdentifier *> using_identifiers;
    std::vector<std::vector<ASTPtr>> alias_pushdown(tables_count);
    std::unordered_map<String, ASTPtr> on_aliases;
    
    for (size_t table_pos = 0; table_pos < tables_count; ++table_pos)
    {
        auto * table = src_tables[table_pos]->as<ASTTablesInSelectQueryElement>();