```
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
else if (const auto * columns_regexp_matcher = child->as<ASTColumnsRegexpMatcher>())
            {
                has_asterisks = true;
                for (auto & table_name : data.tables_order)
                    data.addTableColumns(
                        table_name,
                        columns,
                        [&](const String & column_name) { return columns_regexp_matcher->isColumnMatching(column_name); });
                for (const auto & transformer : columns_regexp_matcher->children)
                    IASTColumnsTransformer::transform(transformer, columns);
            }
            else
                data.new_select_expression_list->children.push_back(child);
            data.new_select_expression_list->children.insert(
                data.new_select_expression_list->children.end(),
                std::make_move_iterator(columns.begin()),
                std::make_move_iterator(columns.end()));
        }
        if (!has_asterisks)
            data.new_select_expression_list.reset();
    }
};
struct RewriteTablesVisitorData
{
    using TypeToVisit = ASTTablesInSelectQuery;
    ASTPtr left;
    ASTPtr right;
    bool done = false;
    
    void visit(ASTTablesInSelectQuery &, ASTPtr & ast)