**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. 
}
            /// Poll for changes after a cancellation check, otherwise it never reached
            /// because of progress updates from server.
            if (connection->poll())
                break;
        }
        if (!receiveAndProcessPacket(parsed_query, cancelled))
            break;
    }
    if (cancelled && is_interactive)
        std::cout << "Query was cancelled." << std::endl;
}
/// Receive a part of the result, or progress info or an exception and process it.
/// Returns true if one should continue receiving packets.
/// Output of result is suppressed if query was cancelled.
bool ClientBase::receiveAndProcessPacket(ASTPtr parsed_query, bool cancelled)
{
    Packet packet = connection->receivePacket(
    switch (packet.type)
    {
        case Protocol::Server::PartUUIDs:
            return true;
        case Protocol::Server::Data:
            
                onData(packet.block, parsed_query
            return true;
        case Protocol::Server::Progress:
            onProgress(packet.progress
            return true;
        case Protocol::Server::ProfileInfo: