**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. 
onProfileInfo(packet.profile_info
            return true;
        case Protocol::Server::Totals:
            
                onTotals(packet.block, parsed_query
            return true;
        case Protocol::Server::Extremes:
            
                onExtremes(packet.block, parsed_query
            return true;
        case Protocol::Server::Exception:
            onReceiveExceptionFromServer(std::move(packet.exception)
            return false;
        case Protocol::Server::Log:
            onLogData(packet.block
            return true;
        case Protocol::Server::EndOfStream:
            onEndOfStream(
            return false;
        case Protocol::Server::ProfileEvents:
            onProfileEvents(packet.block
            return true;
        default:
            throw Exception(
                ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from server {}", packet.type, connection->getDescription()
    }
}
void ClientBase::onProgress(const Progress & value)
{
    if (!progress_indication.updateProgress(value))