```
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
continue;
        if (!table->table_join && !table->array_join)
            throw Exception("Joined table expected", ErrorCodes::LOGICAL_ERROR);
        if (table->array_join)
        {
            ++num_array_join;
            continue;
        }
        const auto & join = table->table_join->as<ASTTableJoin &>();
        if (join.kind == JoinKind::Comma)
            throw Exception("COMMA to CROSS JOIN rewriter is not enabled or cannot rewrite query", ErrorCodes::NOT_IMPLEMENTED);
    }
    if (num_tables - num_array_join <= 2)
        return false;
    
    if (num_array_join)
        throw Exception("Multiple JOIN does not support mix with ARRAY JOINs", ErrorCodes::NOT_IMPLEMENTED);
    return true;
}
using RewriteMatcher = OneTypeMatcher<RewriteTablesVisitorData>;
using RewriteVisitor = InDepthNodeVisitor<RewriteMatcher, true>;
using ExtractAsterisksVisitor = ConstInDepthNodeVisitor<ExtractAsterisksMatcher, true>;
struct CollectColumnIdentifiersMatcher
{
    using Visitor = ConstInDepthNodeVisitor<CollectColumnIdentifiersMatcher, true>;
    struct Data
    {
        std::vector<ASTIdentifier *> & identifiers;
        std::vector<std::unordered_set<String>> ignored;
        explicit Data(std::vector<ASTIdentifier *> & identifiers_)