**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. 
ExternalSchemaReaderPtr getExternalSchemaReader(
        const String & name,
        ContextPtr context,
        const std::optional<FormatSettings> & format_settings = std::nullopt) const;
    void registerFileSegmentationEngine(const String & name, FileSegmentationEngine file_segmentation_engine);
    void registerNonTrivialPrefixAndSuffixChecker(const String & name, NonTrivialPrefixAndSuffixChecker non_trivial_prefix_and_suffix_checker);
    
    void registerInputFormat(const String & name, InputCreator input_creator);
    void registerOutputFormat(const String & name, OutputCreator output_creator);
    
    void registerSchemaReader(const String & name, SchemaReaderCreator schema_reader_creator);
    void registerExternalSchemaReader(const String & name, ExternalSchemaReaderCreator external_schema_reader_creator);
    void markOutputFormatSupportsParallelFormatting(const String & name);
    void markFormatAsColumnOriented(const String & name);
    bool checkIfFormatIsColumnOriented(const String & name);
    bool checkIfFormatHasSchemaReader(const String & name);
    bool checkIfFormatHasExternalSchemaReader(const String & name);
    bool checkIfFormatHasAnySchemaReader(const String & name);
    const FormatsDictionary & getAllFormats() const
    {
        return dict;
    }
    bool isInputFormat(const String & name) const;
    bool isOutputFormat(const String & name) const;
private:
    FormatsDictionary dict;
    const Creators & getCreators(const String & name) const;
};
}