**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. 
size_t src_row = it->second;
            dst_array_current_time[dst_row] = src_array_current_time[src_row];
            switch (dst_array_type[dst_row])
            {
                case ProfileEvents::Type::INCREMENT:
                    dst_array_value[dst_row] += src_array_value[src_row];
                    break;
                case ProfileEvents::Type::GAUGE:
                    dst_array_value[dst_row] = src_array_value[src_row];
                    break;
            }
            rows_by_name.erase(it
        }
    }
    /// Copy rows from src that dst does not contains.
    for (const auto & [id, pos] : rows_by_name)
    {
        for (size_t col = 0; col < src.columns( ++col)
        {
            mutable_columns[col]->insert((*src.getByPosition(col).column)[pos]
        }
    }
    dst.setColumns(std::move(mutable_columns)
}
std::atomic_flag exit_on_signal = ATOMIC_FLAG_INIT;
class QueryInterruptHandler : private boost::noncopyable
{
public:
    QueryInterruptHandler() { exit_on_signal.clear( }
    ~QueryInterruptHandler() { exit_on_signal.test_and_set( }