```
$ clickhouse client
ClickHouse client version 20.10.1.1-arcadia.
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 20.10.1 revision 54441.

max42-dev.sas.yp-c.yandex.net :) create table T(f Array(Tuple(key String, value UInt8))) engine = Log()

Syntax error: failed at position 34 ('String'):

create table T(f Array(Tuple(key String, value UInt8))) engine = Log()

Expected one of: LIKE, GLOBAL NOT IN, AS, IS, OR, QuestionMark, BETWEEN, NOT LIKE, AND, Comma, alias, IN, ILIKE, Dot, NOT ILIKE, NOT, Arrow, NOT IN, token, GLOBAL IN

max42-dev.sas.yp-c.yandex.net :) create table T(f Array(Tuple(String, UInt8))) engine = Log()                  

CREATE TABLE T
(
    `f` Array(Tuple(String, UInt8))
)
ENGINE = Log()

Ok.

0 rows in set. Elapsed: 0.008 sec. 

max42-dev.sas.yp-c.yandex.net :) create table T2(f Tuple(key String, value UInt8)) engine = Log()

CREATE TABLE T2
(
    `f` Tuple(    key String,     value UInt8)
)
ENGINE = Log()

Ok.

0 rows in set. Elapsed: 0.005 sec. 
```

If I understand correctly, DataType parser allows parsing of nested-like data type specifications (i.e. Typename(f1 T1, f2 T2, ...)) only at the top-level. It makes impossible to enclose named tuple into any kind of other structure, like Array or another Tuple. 

Such option is needed for proper interoperability with third-party applications which impose such data types.
if (ParserKeyword("SIGNED").ignore(pos))
            type_name_suffix = "SIGNED";
        else if (ParserKeyword("UNSIGNED").ignore(pos))
            type_name_suffix = "UNSIGNED";
    }
    if (!type_name_suffix.empty())
        type_name = type_name_upper + " " + type_name_suffix;
    auto function_node = std::make_shared<ASTFunction>();
    function_node->name = type_name;
    if (pos->type != TokenType::OpeningRoundBracket)
    {
        node = function_node;
        return true;
    }
    ++pos;
    
    ParserList args_parser(std::make_unique<ParserExpression>(), std::make_unique<ParserToken>(TokenType::Comma));
    ASTPtr expr_list_args;
    if (!args_parser.parse(pos, expr_list_args, expected))
        return false;
    if (pos->type != TokenType::ClosingRoundBracket)
        return false;
    ++pos;
    function_node->arguments = expr_list_args;
    function_node->children.push_back(function_node->arguments);
    node = function_node;
    return true;
}
}