```
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
{
    if (!ident.tryGetAlias().empty())
        return;
    if (original_name.empty())
        return;
    if (!restored_names.contains(original_name))
    {
        ident.setAlias(original_name);
        restored_names.emplace(original_name);
    }
    else
    {
        ident.setShortName(original_name);
    }
}
std::vector<TableNeededColumns> normalizeColumnNamesExtractNeeded(
    const std::vector<TableWithColumnNamesAndTypes> & tables,
    const Aliases & aliases,
    const std::vector<ASTIdentifier *> & identifiers,
    const std::unordered_set<ASTIdentifier *> & public_identifiers,
    UniqueShortNames & unique_names)
{
    size_t last_table_pos = tables.size() - 1;
    std::vector<TableNeededColumns> needed_columns;
    needed_columns.reserve(tables.size());
    for (const auto & table : tables)
        needed_columns.push_back(TableNeededColumns{table.table});
    NameSet restored_names;
    for (ASTIdentifier * ident : identifiers)
    {