**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. 
// We are writing to file, so default format is the same as in non-interactive mode.
                if (is_interactive && is_default_format)
                    current_format = "TabSeparated";
            }
            if (query_with_output->format != nullptr)
            {
                if (has_vertical_output_suffix)
                    throw Exception("Output format already specified", ErrorCodes::CLIENT_OUTPUT_FORMAT_SPECIFIED
                const auto & id = query_with_output->format->as<ASTIdentifier &>(
                current_format = id.name(
            }
        }
        if (has_vertical_output_suffix)
            current_format = "Vertical";
        /// It is not clear how to write progress intermixed with data with parallel formatting.
        /// It may increase code complexity significantly.
        if (!need_render_progress || select_into_file)
            output_format = global_context->getOutputFormatParallelIfPossible(
                current_format, out_file_buf ? *out_file_buf : *out_buf, block
        else
            output_format = global_context->getOutputFormat(
                current_format, out_file_buf ? *out_file_buf : *out_buf, block
        output_format->setAutoFlush(
    }
}
void ClientBase::initLogsOutputStream()
{
    if (!logs_out_stream)
    {