**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. 
*   where possible args are file, name, format, structure, types;
        * - param arguments for prepared statements.
        * Split these groups before processing.
        */
    bool in_external_group = false;
    for (int arg_num = 1; arg_num < argc; ++arg_num)
    {
        const char * arg = argv[arg_num];
        if (arg == "--external"sv)
        {
            in_external_group = true;
            external_tables_arguments.emplace_back(Arguments{""}
        }
        /// Options with value after equal sign.
        
            && (0 == strncmp(arg, "--file=", strlen("--file=")) || 0 == strncmp(arg, "--name=", strlen("--name="))
                || 0 == strncmp(arg, "--format=", strlen("--format=")) || 0 == strncmp(arg, "--structure=", strlen("--structure="))
                || 0 == strncmp(arg, "--types=", strlen("--types="))))
        {
            external_tables_arguments.back().emplace_back(arg
        }
        /// Options with value after whitespace.
        
            && (arg == "--file"sv || arg == "--name"sv || arg == "--format"sv
                || arg == "--structure"sv || arg == "--types"sv))
        {
            if (arg_num + 1 < argc)
            {
                external_tables_arguments.back().emplace_back(arg
                ++a