**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. 
{
public:
    
    
    using ReadCallback = std::function<void()>;
    /** Fast reading data from buffer and save result to memory.
      * Reads at least min_chunk_bytes and some more until the end of the chunk, depends on the format.
      * Used in ParallelParsingBlockInputStream.
      */
    using FileSegmentationEngine = std::function<std::pair<bool, size_t>(
        ReadBuffer & buf,
        DB::Memory<Allocator<false>> & memory,
        size_t min_chunk_bytes)>;
    
    
    using WriteCallback = std::function<void(
        const Columns & columns,
        size_t row)>;
private:
    using InputCreator = std::function<InputFormatPtr(
            ReadBuffer & buf,
            const Block & header,
            const RowInputFormatParams & params,
            const FormatSettings & settings)>;
    using OutputCreator = std::function<OutputFormatPtr(
            WriteBuffer & buf,
            const Block & sample,