**Use case**

This works:

```
SELECT * FROM hits_100m_obfuscated INTO OUTFILE 'hits.csv' FORMAT CSV
```

But I want this:

```
SELECT * FROM hits_100m_obfuscated INTO OUTFILE 'hits.csv'
```

**Describe the solution you'd like**

Every format can register file extension(s) in format factory.
If format is not specified explicitly, we can detect it automatically by file extension.
It should work for compressed files `hits.csv.gz` as well.

The following extensions should be supported at least:
csv, tsv, parquet, orc, native, json, ndjson, xml, md, avro

**Addition details**

Let's also support omitting the format argument for `file`, `url`, `s3`, `hdfs` table functions. 
out_file_buf.reset(
    }
    if (out_logs_buf)
    {
        out_logs_buf->next(
        out_logs_buf.reset(
    }
    std_out.next(
}
/// Receive the block that serves as an example of the structure of table where data will be inserted.
bool ClientBase::receiveSampleBlock(Block & out, ColumnsDescription & columns_description, ASTPtr parsed_query)
{
    while (true)
    {
        Packet packet = connection->receivePacket(
        switch (packet.type)
        {
            case Protocol::Server::Data:
                out = packet.block;
                return true;
            case Protocol::Server::Exception:
                onReceiveExceptionFromServer(std::move(packet.exception)
                return false;
            case Protocol::Server::Log:
                onLogData(packet.block
                break;
            case Protocol::Server::TableColumns:
                columns_description = ColumnsDescription::parse(packet.multistring_message[1]
                return receiveSampleBlock(out, columns_description, parsed_query
            default: